All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] grub-1.98: support for partitionable array v1.2
@ 2010-07-20 15:56 Gaëtan Schmidt
  2010-07-20 15:56 ` [PATCH] mdadm 1.2 partitions array ready Gaëtan Schmidt
  2010-07-20 16:08 ` [PATCH] grub-1.98: support for partitionable array v1.2 Colin Watson
  0 siblings, 2 replies; 5+ messages in thread
From: Gaëtan Schmidt @ 2010-07-20 15:56 UTC (permalink / raw)
  To: grub-devel; +Cc: Gaëtan Schmidt

I modify grub2 to understand mdadm 1.2 partition array without the need to map either the metadevice or the partitions in the device.map file. Just the physical devices are required.  As the meta devices are added, they will be recognized automatically. Only raid 1 is supported for the moment but it can be extended to other layouts.

The patches allow an embedded GPT partition table because the metadata superblock is at the beginning of the disk and not at the end like mdadm 1.0.  GPT has its second header at the end. The partition tools will not complain. The first header begins at the first sector of the metadevice. There isn't any conflict.

mdadm 1.1 is not fit to be bootable, its superblock overlaps the boot sector 0. Instead, mdadm 1.2 is 4k behind, so you have enough room for the boot image. Also fdisk will see a unique EFI GPT ee partition. So, the user is warned that the disk isn't empty and has a valid fake dos ee partition.

Parted can be used on the md_dX device to create the embedded GPT partitions table. The first partition nests grub core image.

I don't use mdX and md/X syntaxes. md_dX is more relevant because of the mdadm default 1.x kernel device scheme /dev/md_dX. So there is no possible confusion with mdadm 0.9 devices. (0.9 doesn't support partitions array).

Partitions are named in the grub way: md_dX,Y.

Moreover, partitions can be greater than 2T. Let’s forget dos/bsd partitions table for now and switch to gpt :).

I successully booted from a 80, 250, 500 and 640Go disks with that layout. It will probably work with a 4k block sector ready disk as well. The portion of code that reads/writes block of 4k comes from the mdadm project.

grub-setup.c and grub-probe.c have been heavily altered to understand mdadm 1.2 partitionable array. That means, grub-setup.c does not support embedded core image in the MBR first sectors gap (<64k) anymore.

To avoid any confusion, grub-setup should be renamed grub-mdraid-setup or something like that.

Minor changes have been added. For instance, trailing spaces are removed from the cmdline parser. A lot of superfluous grub_dprintf have been added to understand what is going on.

You can install a gpt bootable partition on a 256Mo and more usb stick with the patched grub2 version I propose.

The patches are based on the grub-1.98 release
(source tarball from http://lists.gnu.org/archive/html/grub-devel/2010-03/msg00017.html).

For the try and fix version of the patches, please forget it. It is really messy. I am using git for the development and i was not able to convert the bzr repository to git, so i don't have a valid tree. Anyway, if you are interested in it, please let me know.

Please note that the bootloader was built from a bootable rescue stick with a working grub2 environment and mdadm binaries, directly on the targeted disks. It was not built from a working linux desktop. So you will stay on the right side.

Usage:

as a prerequisite, assembled md raid1 device w/ at least 4 partitions and a valid gpt label for md_d0. Physical devices are labeled msdos.
for an hd, p1 (grub_bios) 128kiB; p2 (boot), 128MiB; p3 (root) 1024MiB; p4, ...

for a stick w/o md, a grub_bios of 48kiB is enough

The offset of the gpt 1 partition 17kiB (17,4k reported), alignment is the cylinder. Unit is the byte.

ROOT=/new-root

cmd() { echo "$@"; }

fun() {
»···local gpath=${ROOT}/boot/grub

»···[ -d ${gpath} ] || cmd mkdir -p ${gpath}

»···local map="${gpath}/device.map"

»···cmd grub-mkdevicemap --no-floppy --verbose --device-map=${map}

»···sed -i 's/grep -qw/grep -q/' /sbin/grub-install # busybox???

»···modules="biosdisk ext2 part_gpt part_msdos raid mdraid configfile search cat
»···cmd grub-install --root-directory=/ --modules="${modules}" \
»···»···»···»···»··· --grub-setup='/bin/true' --debug '(md_d0)'

»···cmd grub-setup -v -r '(md_d0,2)' -d ${gpath} \
»···»···»···»···»···»···»···»···»··· -b boot.img -c core.img '(md_d0)'

»···cmd mkdir -p ${gpath}/fonts ${gpath}/images &&
»···cmd cp /usr/share/grub/* ${gpath}/fonts

»···$GLOBAL GRUB_DEVICE_BOOT="${mdraid}p2"
»···$GLOBAL GRUB_DEVICE="${mdraid}p3"
»···# need a patch
»···cmd grub-mkconfig --output=${gpath}/grub.cfg
}

grub command,

set root=(md_d0,2)
/boot/vmlinuz root=/dev/md/d0p3 ...

supposing boot is installed in the second partition and rootfs in the third partition.

---

Gaëtan Schmidt (1):
  mdadm 1.2 partitions array ready

 disk/i386/pc/biosdisk.c   |    2 +-
 disk/mdraid_linux.c       |  177 +++++++++++++---
 disk/raid.c               |   52 ++++-
 include/grub/disk.h       |    3 +
 include/grub/raid.h       |    2 +
 kern/device.c             |    4 +
 kern/disk.c               |   17 ++-
 kern/fs.c                 |    6 +
 kern/parser.c             |    8 +-
 normal/main.c             |    6 +
 partmap/apple.c           |    4 +-
 partmap/gpt.c             |    9 +-
 util/deviceiter.c         |   19 ++
 util/getroot.c            |   23 +--
 util/grub-install.in      |    2 +-
 util/grub-mkconfig.in     |   18 ++-
 util/grub-probe.c         |   13 +-
 util/hostdisk.c           |   15 ++-
 util/i386/pc/grub-setup.c |  502 ++++++++++++++++++++++----------------------
 19 files changed, 563 insertions(+), 319 deletions(-)



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] mdadm 1.2 partitions array ready
  2010-07-20 15:56 [PATCH] grub-1.98: support for partitionable array v1.2 Gaëtan Schmidt
@ 2010-07-20 15:56 ` Gaëtan Schmidt
  2010-07-20 16:08 ` [PATCH] grub-1.98: support for partitionable array v1.2 Colin Watson
  1 sibling, 0 replies; 5+ messages in thread
From: Gaëtan Schmidt @ 2010-07-20 15:56 UTC (permalink / raw)
  To: grub-devel; +Cc: Gaëtan Schmidt

	modified:   disk/i386/pc/biosdisk.c
	modified:   disk/mdraid_linux.c
	modified:   disk/raid.c
	modified:   include/grub/disk.h
	modified:   include/grub/raid.h
	modified:   kern/device.c
	modified:   kern/disk.c
	modified:   kern/fs.c
	modified:   kern/parser.c
	modified:   normal/main.c
	modified:   partmap/apple.c
	modified:   partmap/gpt.c
	modified:   util/deviceiter.c
	modified:   util/getroot.c
	modified:   util/grub-install.in
	modified:   util/grub-mkconfig.in
	modified:   util/grub-probe.c
	modified:   util/hostdisk.c
	modified:   util/i386/pc/grub-setup.c

Signed-off-by: Gaëtan Schmidt <jimmy.jazz@gmx.net>
---
 disk/i386/pc/biosdisk.c   |    2 +-
 disk/mdraid_linux.c       |  177 +++++++++++++---
 disk/raid.c               |   52 ++++-
 include/grub/disk.h       |    3 +
 include/grub/raid.h       |    2 +
 kern/device.c             |    4 +
 kern/disk.c               |   17 ++-
 kern/fs.c                 |    6 +
 kern/parser.c             |    8 +-
 normal/main.c             |    6 +
 partmap/apple.c           |    4 +-
 partmap/gpt.c             |    9 +-
 util/deviceiter.c         |   19 ++
 util/getroot.c            |   23 +--
 util/grub-install.in      |    2 +-
 util/grub-mkconfig.in     |   18 ++-
 util/grub-probe.c         |   13 +-
 util/hostdisk.c           |   15 ++-
 util/i386/pc/grub-setup.c |  502 ++++++++++++++++++++++----------------------
 19 files changed, 563 insertions(+), 319 deletions(-)

diff --git a/disk/i386/pc/biosdisk.c b/disk/i386/pc/biosdisk.c
index 94d0e37..4dfc49f 100644
--- a/disk/i386/pc/biosdisk.c
+++ b/disk/i386/pc/biosdisk.c
@@ -108,7 +108,7 @@ grub_biosdisk_open (const char *name, grub_disk_t disk)
     return grub_errno;
 
   disk->has_partitions = ((drive & 0x80) && (drive != cd_drive));
-  disk->id = drive;
+  disk->id = drive % 0x80; /* XXX */
 
   data = (struct grub_biosdisk_data *) grub_zalloc (sizeof (*data));
   if (! data)
diff --git a/disk/mdraid_linux.c b/disk/mdraid_linux.c
index 306c66a..e53085e 100644
--- a/disk/mdraid_linux.c
+++ b/disk/mdraid_linux.c
@@ -159,59 +159,178 @@ struct grub_raid_super_09
   struct grub_raid_disk_09 this_disk;
 } __attribute__ ((packed));
 
+struct grub_raid_super_1
+{
+	    /* constant array information - 128 bytes */
+    grub_uint32_t   magic;      /* MD_SB_MAGIC: 0xa92b4efc - little endian */
+    grub_uint32_t   major_version;  /* 1 */
+    grub_uint32_t   feature_map;    /* 0 for now */
+    grub_uint32_t   pad0;       /* always set to 0 when writing */
+
+    grub_uint8_t    set_uuid[16];   /* user-space generated. */
+    char    set_name[32];   /* set and interpreted by user-space */
+
+    grub_uint64_t   ctime;      /* lo 40 bits are seconds, top 24 are microseconds or 0*/
+    grub_uint32_t   level;      /* -4 (multipath), -1 (linear), 0,1,4,5 */
+    grub_uint32_t   layout;     /* only for raid5 currently */
+    grub_uint64_t   size;       /* used size of component devices, in 512byte sectors */
+
+    grub_uint32_t   chunksize;  /* in 512byte sectors */
+    grub_uint32_t   raid_disks;
+    grub_uint32_t   bitmap_offset;  /* sectors after start of superblock that bitmap starts
+                 * NOTE: signed, so bitmap can be before superblock
+                 * only meaningful of feature_map[0] is set.
+                 */
+
+    /* These are only valid with feature bit '4' */
+    grub_uint32_t   new_level;  /* new level we are reshaping to        */
+    grub_uint64_t   reshape_position;   /* next address in array-space for reshape */
+    grub_uint32_t   delta_disks;    /* change in number of raid_disks       */
+    grub_uint32_t   new_layout; /* new layout                   */
+    grub_uint32_t   new_chunk;  /* new chunk size (bytes)           */
+    grub_uint8_t    pad1[128-124];  /* set to 0 when written */
+
+    /* constant this-device information - 64 bytes */
+    grub_uint64_t   data_offset;    /* sector start of data, often 0 */
+    grub_uint64_t   data_size;  /* sectors in this device that can be used for data */
+    grub_uint64_t   super_offset;   /* sector start of this superblock */
+    grub_uint64_t   recovery_offset;/* sectors before this offset (from data_offset) have been recovered */
+    grub_uint32_t   dev_number; /* permanent identifier of this  device - not role in raid */
+    grub_uint32_t   cnt_corrected_read; /* number of read errors that were corrected by re-writing */
+    grub_uint8_t    device_uuid[16]; /* user-space setable, ignored by kernel */
+    grub_uint8_t    devflags;        /* per-device flags.  Only one defined...*/
+#define WriteMostly1    1        /* mask for writemostly flag in above */
+    grub_uint8_t    pad2[64-57];    /* set to 0 when writing */
+
+    /* array state information - 64 bytes */
+    grub_uint64_t   utime;      /* 40 bits second, 24 btes microseconds */
+    grub_uint64_t   events;     /* incremented when superblock updated */
+    grub_uint64_t   resync_offset;  /* data before this offset (from data_offset) known to be in sync */
+    grub_uint32_t   sb_csum;    /* checksum upto devs[max_dev] */
+    grub_uint32_t   max_dev;    /* size of devs[] array to consider */
+    grub_uint8_t    pad3[64-32];    /* set to 0 when writing */
+
+    /* device state information. Indexed by dev_number.
+     * 2 bytes per device
+     * Note there are no per-device state flags. State information is rolled
+     * into the 'roles' value.  If a device is spare or faulty, then it doesn't
+     * have a meaningful role.
+     */
+    grub_uint16_t   dev_roles[0];   /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
+
+} __attribute__ ((packed));
+
+typedef union __attribute__ ((__transparent_union__)) {
+  struct grub_raid_super_09 v0;
+  struct grub_raid_super_1 v1;
+} grub_raid_super_t;
+
 static grub_err_t
 grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array)
 {
   grub_disk_addr_t sector;
   grub_uint64_t size;
-  struct grub_raid_super_09 sb;
+  grub_raid_super_t sb;
   grub_uint32_t *uuid;
+  int i;
 
   /* The sector where the RAID superblock is stored, if available. */
   size = grub_disk_get_size (disk);
   sector = NEW_SIZE_SECTORS (size);
 
-  if (grub_disk_read (disk, sector, 0, SB_BYTES, &sb))
+  if (grub_disk_read (disk, sector, 0, sizeof(struct grub_raid_super_09), &(sb.v0)))
     return grub_errno;
 
-  /* Look whether there is a RAID superblock. */
-  if (sb.md_magic != SB_MAGIC)
-    return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid");
-
-  /* FIXME: Also support version 1.0. */
-  if (sb.major_version != 0 || sb.minor_version != 90)
-    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-		       "unsupported RAID version: %d.%d",
-		       sb.major_version, sb.minor_version);
-
+  if ((sb.v0).md_magic == SB_MAGIC) {
   /* FIXME: Check the checksum. */
 
   /* Multipath.  */
-  if ((int) sb.level == -4)
-    sb.level = 1;
+  if ((int) (sb.v0).level == -4)
+    (sb.v0).level = 1;
 
-  if (sb.level != 0 && sb.level != 1 && sb.level != 4 &&
-      sb.level != 5 && sb.level != 6 && sb.level != 10)
+  if ((sb.v0).level != 0 && (sb.v0).level != 1 && (sb.v0).level != 4 &&
+      (sb.v0).level != 5 && (sb.v0).level != 6 && (sb.v0).level != 10)
     return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-		       "unsupported RAID level: %d", sb.level);
-
-  array->number = sb.md_minor;
-  array->level = sb.level;
-  array->layout = sb.layout;
-  array->total_devs = sb.raid_disks;
-  array->disk_size = (sb.size) ? sb.size * 2 : sector;
-  array->chunk_size = sb.chunk_size >> 9;
-  array->index = sb.this_disk.number;
+		       "Unsupported RAID level: %d", (sb.v0).level);
+
+    array->version = (sb.v0).major_version;
+    array->data_offset = 0;
+    array->number = (sb.v0).md_minor;
+    array->level = (sb.v0).level;
+    array->layout = (sb.v0).layout;
+    array->total_devs = (sb.v0).raid_disks;
+    array->disk_size = ((sb.v0).size) ? (sb.v0).size * 2 : sector;
+    array->chunk_size = (sb.v0).chunk_size >> 9;
+    array->index = (sb.v0).this_disk.number;
+    array->uuid_len = 16;
+    array->uuid = grub_malloc (16);
+    if (!array->uuid)
+      return grub_errno;
+
+    uuid = (grub_uint32_t *) array->uuid;
+    uuid[0] = (sb.v0).set_uuid0;
+    uuid[1] = (sb.v0).set_uuid1;
+    uuid[2] = (sb.v0).set_uuid2;
+    uuid[3] = (sb.v0).set_uuid3;
+
+  }
+  else {
+
+  /* Look whether there is a RAID superblock. */
+	grub_dprintf ("mdraid", "No signature found for %s at sector 0x%llx\n", disk->name, (unsigned long long) sector);
+
+	sector = SB_SECTORS;
+
+	if (grub_disk_read (disk, sector, 0, sizeof (struct grub_raid_super_1), &(sb.v1)))
+		  return grub_errno;
+
+  	if (grub_le_to_cpu32((sb.v1).magic) != SB_MAGIC)
+    	return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid");
+
+	grub_dprintf ("mdraid", "Signature found for %s at sector 0x%llx\n", disk->name, (unsigned long long) sector);
+
+	if ((int) grub_le_to_cpu32((sb.v1).level) == -4)
+		(sb.v1).level = 1;
+
+	switch(grub_le_to_cpu32((sb.v1).level)) {
+		case 0:
+		case 1:
+		case 4:
+		case 5:
+		case 6:
+		case 10:
+			break;
+		default:
+    		return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "Unsupported RAID level: %d", grub_le_to_cpu32((sb.v1).level));
+	}
+
+  	array->version = grub_le_to_cpu32((sb.v1).major_version);
+  	array->data_offset = grub_le_to_cpu64((sb.v1).data_offset);
+  	/* array->number = grub_le_to_cpu32((sb.v1).dev_number); */
+  	array->number = 0;
+  	array->level = grub_le_to_cpu32((sb.v1).level);
+  	array->layout = grub_le_to_cpu32((sb.v1).layout);
+  	array->total_devs = grub_le_to_cpu32((sb.v1).raid_disks);
+  	array->disk_size = grub_le_to_cpu64((sb.v1).size);
+  	array->chunk_size = grub_le_to_cpu32((sb.v1).chunksize)*512;
+  	/* array->index = grub_le_to_cpu32((sb.v1).dev_number);  dev_number could be anything >=0 */
+  	array->index = disk->id; /* gives many prbs when id isn't modulo 0x80, devices are counted from 0 */
   array->uuid_len = 16;
   array->uuid = grub_malloc (16);
   if (!array->uuid)
     return grub_errno;
 
   uuid = (grub_uint32_t *) array->uuid;
-  uuid[0] = sb.set_uuid0;
-  uuid[1] = sb.set_uuid1;
-  uuid[2] = sb.set_uuid2;
-  uuid[3] = sb.set_uuid3;
+
+	for (i = 0; i < 4; i++)
+  		uuid[i] = (sb.v1).set_uuid[i];
+
+	grub_dprintf ("mdraid", "(sb.v1).data_offset=%lld\n", (long long int) grub_le_to_cpu64((sb.v1).data_offset));
+	grub_dprintf ("mdraid", "array->number=%d ((sb.v1).dev_number=%ld)\n",
+		       	array->number, grub_le_to_cpu64((sb.v1).dev_number));
+  }
+
+  grub_dprintf("mdraid", "Found RAID %d, vers. %d\n", (int) array->level, array->version);
 
   return 0;
 }
diff --git a/disk/raid.c b/disk/raid.c
index 2d544af..dce4a44 100644
--- a/disk/raid.c
+++ b/disk/raid.c
@@ -23,6 +23,9 @@
 #include <grub/err.h>
 #include <grub/misc.h>
 #include <grub/raid.h>
+#if 0 && ! defined (GRUB_UTIL)
+#include <grub/env.h>
+#endif
 
 /* Linked list of RAID arrays. */
 static struct grub_raid_array *array_list;
@@ -80,6 +83,8 @@ grub_raid_iterate (int (*hook) (const char *name))
 
   for (array = array_list; array != NULL; array = array->next)
     {
+      grub_dprintf ("raid", "iterate(%s)\n", array->name);
+
       if (grub_is_array_readable (array))
 	if (hook (array->name))
 	  return 1;
@@ -130,8 +135,8 @@ grub_raid_open (const char *name, grub_disk_t disk)
   disk->id = array->number;
   disk->data = array;
 
-  grub_dprintf ("raid", "%s: total_devs=%d, disk_size=%lld\n", name,
-		array->total_devs, (unsigned long long) array->disk_size);
+  grub_dprintf ("raid", "%s: total_devs=%d, disk_size=%lld, number=%lu\n", name,
+                array->total_devs, (unsigned long long) array->disk_size, disk->id);
 
   switch (array->level)
     {
@@ -195,6 +200,13 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
   struct grub_raid_array *array = disk->data;
   grub_err_t err = 0;
 
+  grub_dprintf ("raid", "idx %d, devs %d, vers %d, layout %d, data@0x%llx, chunk %lu\n",
+		  array->index, array->total_devs, array->version, array->layout,
+		  (unsigned long long) array->data_offset, (unsigned long) array->chunk_size);
+  grub_dprintf("raid", "\tread('%s', 0x%lx, 0x%lx)\n",disk->name, (unsigned long) sector, (unsigned long) size);
+
+  sector += array->data_offset;
+
   switch (array->level)
     {
     case 0:
@@ -226,9 +238,11 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
             far_ofs *= array->chunk_size;
           }
 
+        grub_dprintf("raid", "\tdivmod64(%lld,%d,?)\n",
+			(unsigned long long) read_sector * near,array->total_devs);
         read_sector = grub_divmod64 (read_sector * near, array->total_devs,
                                      &disknr);
-
+        grub_dprintf("raid", "read sector %ld, devs %d, disknr %d\n",(unsigned long) read_sector,array->total_devs,disknr);
         ofs *= array->chunk_size;
         read_sector *= ofs;
 
@@ -250,6 +264,7 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
                   {
                     if (array->device[k])
                       {
+                        grub_dprintf("raid", "read physical device '%s' %d\n",array->device[k]->name, k);
                         if (grub_errno == GRUB_ERR_READ_ERROR)
                           grub_errno = GRUB_ERR_NONE;
 
@@ -479,6 +494,14 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
 {
   struct grub_raid_array *array = 0, *p;
 
+#if 0 && ! defined (GRUB_UTIL)
+  grub_env_set("debug","raid");
+#endif
+  grub_dprintf ("raid", "See whether the device is part of an array\n");
+  if (disk->dev->id == GRUB_DISK_DEVICE_RAID_ID ) {
+	  grub_dprintf ("raid", "Already a raid array!\n");
+	  return 0;
+  }
   /* See whether the device is part of an array we have already seen a
      device from. */
   for (p = array_list; p != NULL; p = p->next)
@@ -497,13 +520,13 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
           /* We found more members of the array than the array
              actually has according to its superblock.  This shouldn't
              happen normally.  */
-          grub_dprintf ("raid", "array->nr_devs > array->total_devs (%d)?!?",
+          grub_dprintf ("raid", "array->nr_devs > array->total_devs (%d)?!?\n",
 			array->total_devs);
 
         if (array->device[new_array->index] != NULL)
           /* We found multiple devices with the same number. Again,
              this shouldn't happen.*/
-          grub_dprintf ("raid", "Found two disks with the number %d?!?",
+          grub_dprintf ("raid", "Found two disks with the number %d?!?\n",
 			new_array->number);
 
         if (new_array->disk_size < array->disk_size)
@@ -565,7 +588,12 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
           return grub_errno;
         }
 
-      grub_dprintf ("raid", "Found array %s (%s)\n", array->name,
+      if (array->version == 1)
+          array->name = grub_xasprintf ("md_d%d", array->number);
+      else
+          array->name = grub_xasprintf ("md%d", array->number);
+
+      grub_dprintf ("raid", "Found array %s (scanner is %s)\n", array->name,
                     scanner_name);
 
       /* Add our new array to the list.  */
@@ -574,10 +602,17 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
 
       /* RAID 1 doesn't use a chunksize but code assumes one so set
 	 one. */
-      if (array->level == 1)
+      if (array->level == 1) {
 	array->chunk_size = 64;
+        grub_dprintf ("raid", "warning: chunk size is forced to %lu\n", (unsigned long) array->chunk_size);
+      }
     }
 
+  grub_dprintf ("raid", "Add device '%s', id %lu to the array %s at index %d\n",
+		  disk->name, disk->id, array->name, new_array->index);
+#if 0 && ! defined (GRUB_UTIL)
+  grub_dprintf ("device '%s' at position %d is id %lu\n", disk->name, new_array->index, disk->id);
+#endif
   /* Add the device to the array. */
   array->device[new_array->index] = disk;
   array->nr_devs++;
@@ -633,6 +668,9 @@ grub_raid_register (grub_raid_t raid)
 	  (! insert_array (disk, &array, grub_raid_list->name)))
 	return 0;
 
+      if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
+        grub_dprintf ("raid", "'%s' is not a raid device\n", name);
+
       /* This error usually means it's not raid, no need to display
 	 it.  */
       if (grub_errno != GRUB_ERR_OUT_OF_RANGE)
diff --git a/include/grub/disk.h b/include/grub/disk.h
index e60b1f3..92c73a1 100644
--- a/include/grub/disk.h
+++ b/include/grub/disk.h
@@ -105,6 +105,9 @@ struct grub_disk
   /* The id used by the disk cache manager.  */
   unsigned long id;
 
+  /* The start of data.  */
+  grub_uint64_t data_offset;
+
   /* The partition information. This is machine-specific.  */
   struct grub_partition *partition;
 
diff --git a/include/grub/raid.h b/include/grub/raid.h
index 8fa4c38..848040c 100644
--- a/include/grub/raid.h
+++ b/include/grub/raid.h
@@ -34,6 +34,8 @@
 
 struct grub_raid_array
 {
+  unsigned int version;
+  grub_disk_addr_t data_offset;
   int number;              /* The device number, taken from md_minor so we
 			      are consistent with the device name in
 			      Linux. */
diff --git a/kern/device.c b/kern/device.c
index cd019fd..5b96528 100644
--- a/kern/device.c
+++ b/kern/device.c
@@ -100,6 +100,8 @@ grub_device_iterate (int (*hook) (const char *name))
       if (! dev)
 	return 0;
 
+      grub_dprintf("device","iterate_disk(%s)\n", disk_name);
+
       if (dev->disk && dev->disk->has_partitions)
 	{
 	  struct part_ent *p;
@@ -146,6 +148,8 @@ grub_device_iterate (int (*hook) (const char *name))
 	  return 1;
 	}
 
+      grub_dprintf ("device","iterate_partition(%s,%s)\n", disk->name, partition_name);
+
       p->name = grub_xasprintf ("%s,%s", disk->name, partition_name);
       if (!p->name)
 	{
diff --git a/kern/disk.c b/kern/disk.c
index 5c30e17..d77f9e0 100644
--- a/kern/disk.c
+++ b/kern/disk.c
@@ -24,6 +24,7 @@
 #include <grub/misc.h>
 #include <grub/time.h>
 #include <grub/file.h>
+#include <grub/raid.h>
 
 #define	GRUB_CACHE_TIMEOUT	2
 
@@ -386,6 +387,9 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
   char *tmp_buf;
   unsigned real_offset;
 
+  grub_dprintf ("disk", "\tReading '%s' @ sector 0x%llx:0x%x, len %llu, buf %p)\n", disk->name,
+		  (unsigned long long) sector, (unsigned int) offset, (unsigned long long) size, buf);
+
   /* First of all, check if the region is within the disk.  */
   if (grub_disk_adjust_range (disk, &sector, &offset, size) != GRUB_ERR_NONE)
     {
@@ -398,6 +402,8 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
 
   real_offset = offset;
 
+  grub_dprintf ("disk", "\tAdjust range to 0x%llx:0x%x\n", (unsigned long long) sector, (unsigned) real_offset);
+
   /* Allocate a temporary buffer.  */
   tmp_buf = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
   if (! tmp_buf)
@@ -430,6 +436,10 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
       else
 	{
 	  /* Otherwise read data from the disk actually.  */
+	  grub_dprintf ("disk", "\tread data from '%s' (%s) id=%lu at 0x%llx of size %d into cache %p\n",
+			  disk->name, disk->dev->name, disk->id,
+			  (unsigned long long )start_sector, GRUB_DISK_CACHE_SIZE, tmp_buf);
+
 	  if (start_sector + GRUB_DISK_CACHE_SIZE > disk->total_sectors
 	      || (disk->dev->read) (disk, start_sector,
 				    GRUB_DISK_CACHE_SIZE, tmp_buf)
@@ -450,6 +460,8 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
 
 	      tmp_buf = p;
 
+	      grub_dprintf ("disk", "\tread retry: sector 0x%llx len %d, cache %p\n",
+			      (unsigned long long ) sector, num, tmp_buf);
 	      if ((disk->dev->read) (disk, sector, num, tmp_buf))
 		{
 		  grub_error_push ();
@@ -465,13 +477,14 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
 		while (size)
 		  {
 		    grub_size_t to_read = (size > GRUB_DISK_SECTOR_SIZE) ? GRUB_DISK_SECTOR_SIZE : size;
+	            grub_dprintf ("disk", "\tcall read hook\n");
 		    (disk->read_hook) (sector, real_offset,
 				       to_read);
 		    if (grub_errno != GRUB_ERR_NONE)
 		      goto finish;
 
 		    sector++;
-		    size -= to_read - real_offset;
+		    size -= to_read - real_offset; /* size -= GRUB_DISK_SECTOR_SIZE - real_offset; */
 		    real_offset = 0;
 		  }
 
@@ -511,10 +524,12 @@ grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
       buf = (char *) buf + len;
       size -= len;
       real_offset = 0;
+      grub_dprintf ("disk", "\tremains %lu bytes to read...\n", (unsigned long) size);
     }
 
  finish:
 
+  grub_dprintf ("disk", "End reading `%s'...\n", disk->name);
   grub_free (tmp_buf);
 
   return grub_errno;
diff --git a/kern/fs.c b/kern/fs.c
index 0c45637..7f2972a 100644
--- a/kern/fs.c
+++ b/kern/fs.c
@@ -26,6 +26,7 @@
 #include <grub/types.h>
 #include <grub/mm.h>
 #include <grub/term.h>
+#include <grub/partition.h>
 
 static grub_fs_t grub_fs_list;
 
@@ -76,6 +77,11 @@ grub_fs_probe (grub_device_t device)
 
   if (device->disk)
     {
+      grub_dprintf ("fs", "Probe device %s (data offset %lu)...\n", device->disk->name, device->disk->data_offset);
+      grub_dprintf ("fs", "\tdevice has%s partition(s)\n", device->disk->has_partitions ? "": "n't");
+      if (device->disk->partition)
+        grub_dprintf ("fs", "\tpartition offset %lu\n", ((grub_partition_t) device->disk->partition)->offset);
+
       /* Make it sure not to have an infinite recursive calls.  */
       static int count = 0;
 
diff --git a/kern/parser.c b/kern/parser.c
index dd4608b..26e9c57 100644
--- a/kern/parser.c
+++ b/kern/parser.c
@@ -249,8 +249,12 @@ grub_parser_execute (char *source)
 	}
 
       p = grub_strchr (source, '\n');
-      if (p)
-	*p = 0;
+      if (p) {
+	char *c = p - 1;
+	/* sweep away trailing spaces */
+	for (; c >= source && grub_isspace(*c); c--);
+	*++c = 0;
+      }
 
       *line = grub_strdup (source);
       if (p)
diff --git a/normal/main.c b/normal/main.c
index 5a54674..7e3d086 100644
--- a/normal/main.c
+++ b/normal/main.c
@@ -110,8 +110,14 @@ grub_file_getline (grub_file_t file)
 	}
     }
 
+  /* GROSS: Get Rid Of Space Series */
+  while (pos > 0 && grub_isspace(cmdline[pos - 1])) {
+    pos--;
+  }
+
   cmdline[pos] = '\0';
 
+
   /* If the buffer is empty, don't return anything at all.  */
   if (pos == 0)
     {
diff --git a/partmap/apple.c b/partmap/apple.c
index a1a645a..7fc55f9 100644
--- a/partmap/apple.c
+++ b/partmap/apple.c
@@ -121,7 +121,7 @@ apple_partition_map_iterate (grub_disk_t disk,
   if (grub_be_to_cpu16 (aheader.magic) != GRUB_APPLE_HEADER_MAGIC)
     {
       grub_dprintf ("partition",
-		    "bad magic (found 0x%x; wanted 0x%x\n",
+		    "bad magic (found 0x%x; wanted 0x%x)\n",
 		    grub_be_to_cpu16 (aheader.magic),
 		    GRUB_APPLE_HEADER_MAGIC);
       goto fail;
@@ -139,7 +139,7 @@ apple_partition_map_iterate (grub_disk_t disk,
       if (grub_be_to_cpu16 (apart.magic) != GRUB_APPLE_PART_MAGIC)
 	{
 	  grub_dprintf ("partition",
-			"partition %d: bad magic (found 0x%x; wanted 0x%x\n",
+			"partition %d: bad magic (found 0x%x; wanted 0x%x)\n",
 			partno, grub_be_to_cpu16 (apart.magic),
 			GRUB_APPLE_PART_MAGIC);
 	  break;
diff --git a/partmap/gpt.c b/partmap/gpt.c
index cb1229b..9caabcc 100644
--- a/partmap/gpt.c
+++ b/partmap/gpt.c
@@ -24,6 +24,7 @@
 #include <grub/dl.h>
 #include <grub/msdos_partition.h>
 #include <grub/gpt_partition.h>
+#include <grub/raid.h>
 
 static grub_uint8_t grub_gpt_magic[8] =
   {
@@ -58,6 +59,8 @@ gpt_partition_map_iterate (grub_disk_t disk,
   if (grub_disk_read (&raw, 0, 0, sizeof (mbr), &mbr))
     return grub_errno;
 
+  grub_dprintf ("gpt", "Read the protective MBR of %s\n", disk->name);
+
   /* Check if it is valid.  */
   if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE))
     return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
@@ -73,7 +76,7 @@ gpt_partition_map_iterate (grub_disk_t disk,
   if (grub_memcmp (gpt.magic, grub_gpt_magic, sizeof (grub_gpt_magic)))
     return grub_error (GRUB_ERR_BAD_PART_TABLE, "no valid GPT header");
 
-  grub_dprintf ("gpt", "Read a valid GPT header\n");
+  grub_dprintf ("gpt", "Found a valid GPT header at sector 0x%x\n", 1);
 
   entries = grub_le_to_cpu64 (gpt.partitions);
   for (i = 0; i < grub_le_to_cpu32 (gpt.maxpart); i++)
@@ -101,6 +104,7 @@ gpt_partition_map_iterate (grub_disk_t disk,
 	  if (hook (disk, &part))
 	    return 1;
 	}
+      else grub_dprintf ("gpt", "GPT entry %d: empty\n", i);
 
       last_offset += grub_le_to_cpu32 (gpt.partentry_size);
       if (last_offset == GRUB_DISK_SECTOR_SIZE)
@@ -110,6 +114,8 @@ gpt_partition_map_iterate (grub_disk_t disk,
 	}
     }
 
+    grub_dprintf ("gpt", "GPT last partition %d reached\n", gpt.maxpart - 1);
+
   return 0;
 }
 
@@ -126,6 +132,7 @@ gpt_partition_map_probe (grub_disk_t disk, const char *str)
   int find_func (grub_disk_t d __attribute__ ((unused)),
 		 const grub_partition_t partition)
     {
+    grub_dprintf ("gpt", "find_func() partition %d == %d\n", partnum, partition->index);
       if (partnum == partition->index)
 	{
 	  p = (grub_partition_t) grub_malloc (sizeof (*p));
diff --git a/util/deviceiter.c b/util/deviceiter.c
index b0a9e13..37d2d16 100644
--- a/util/deviceiter.c
+++ b/util/deviceiter.c
@@ -283,6 +283,12 @@ get_virtio_disk_name (char *name, int unit)
 }
 
 static void
+get_mdraid_disk_name (char *name, int unit)
+{
+  sprintf (name, "/dev/md_d%d", unit);
+}
+
+static void
 get_dac960_disk_name (char *name, int controller, int drive)
 {
   sprintf (name, "/dev/rd/c%dd%d", controller, drive);
@@ -485,7 +491,20 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
 	    return;
 	}
     }
+#if 0
+  /* MDRAID disks.  */
+  for (i = 0; i < 8; i++)
+    {
+      char name[20];
 
+      get_mdraid_disk_name (name, i);
+      if (check_device (name))
+	{
+	  if (hook (name, 0))
+	    return;
+        }
+    }
+#endif
   /* ATARAID disks.  */
   for (i = 0; i < 8; i++)
     {
diff --git a/util/getroot.c b/util/getroot.c
index 8239363..090a8ae 100644
--- a/util/getroot.c
+++ b/util/getroot.c
@@ -535,34 +535,19 @@ grub_util_get_grub_dev (const char *os_dev)
 
     case GRUB_DEV_ABSTRACTION_RAID:
 
-      if (os_dev[7] == '_' && os_dev[8] == 'd')
+      if ((os_dev[7] == '_' || os_dev[7] == '/') && os_dev[8] == 'd')
 	{
-	  /* This a partitionable RAID device of the form /dev/md_dNNpMM. */
+	  /* This a partitionable RAID device of the form /dev/md[/_]dNNpMM. */
 
 	  char *p, *q;
 
-	  p = strdup (os_dev + sizeof ("/dev/md_d") - 1);
+	  p = strdup (&os_dev[9]);
 
 	  q = strchr (p, 'p');
 	  if (q)
 	    *q = ',';
 
-	  grub_dev = xasprintf ("md%s", p);
-	  free (p);
-	}
-      else if (os_dev[7] == '/' && os_dev[8] == 'd')
-	{
-	  /* This a partitionable RAID device of the form /dev/md/dNNpMM. */
-
-	  char *p, *q;
-
-	  p = strdup (os_dev + sizeof ("/dev/md/d") - 1);
-
-	  q = strchr (p, 'p');
-	  if (q)
-	    *q = ',';
-
-	  grub_dev = xasprintf ("md%s", p);
+	  grub_dev = xasprintf ("md_d%s", p);
 	  free (p);
 	}
       else if (os_dev[7] >= '0' && os_dev[7] <= '9')
diff --git a/util/grub-install.in b/util/grub-install.in
index bb323d7..6d08929 100644
--- a/util/grub-install.in
+++ b/util/grub-install.in
@@ -306,7 +306,7 @@ config_opt=
 
 if [ "x${devabstraction_module}" = "x" ] ; then
     if [ x"${install_device}" != x ]; then
-      if echo "${install_device}" | grep -qx "(.*)" ; then
+      if echo "${install_device}" | grep -q "(.*)" ; then
         install_drive="${install_device}"
       else
         install_drive="`$grub_probe --target=drive --device ${install_device}`"
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
index daa110b..ffd925b 100644
--- a/util/grub-mkconfig.in
+++ b/util/grub-mkconfig.in
@@ -44,6 +44,7 @@ Generate a grub config file
   -o, --output=FILE       output generated config to FILE [default=stdout]
   -h, --help              print this message and exit
   -v, --version           print the version information and exit
+  -t, --target=PATH       mountpoint of target device
 
 Report bugs to <bug-grub@gnu.org>.
 EOF
@@ -62,6 +63,9 @@ for option in "$@"; do
 	shift
 	grub_cfg=$1
 	;;
+    --target=*)
+	ROOT=`echo "$option" | sed 's/--target=//'`
+	;;
     --output=*)
 	grub_cfg=`echo "$option" | sed 's/--output=//'`
 	;;
@@ -118,17 +122,25 @@ if test -e ${grub_prefix}/device.map ; then : ; else
   ${grub_mkdevicemap}
 fi
 
+if test -f ${sysconfdir}/default/grub ; then
+  . ${sysconfdir}/default/grub
+fi
+
+if [ -z "${GRUB_DEVICE}" ]; then
 # Device containing our userland.  Typically used for root= parameter.
-GRUB_DEVICE="`${grub_probe} --target=device /`"
+  GRUB_DEVICE="`${grub_probe} --target=device ${ROOT}/`"
+fi
 GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true
 
+if [ -z "${GRUB_DEVICE_BOOT}" ]; then
 # Device containing our /boot partition.  Usually the same as GRUB_DEVICE.
-GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`"
+  GRUB_DEVICE_BOOT="`${grub_probe} --target=device ${ROOT}/boot`"
+fi
 GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true
 
 # Filesystem for the device containing our userland.  Used for stuff like
 # choosing Hurd filesystem module.
-GRUB_FS="`${grub_probe} --target=fs / 2> /dev/null || echo unknown`"
+GRUB_FS="`${grub_probe} --target=fs ${ROOT}/ 2> /dev/null || echo unknown`"
 
 if test -f ${sysconfdir}/default/grub ; then
   . ${sysconfdir}/default/grub
diff --git a/util/grub-probe.c b/util/grub-probe.c
index ba2fe4c..4b5a876 100644
--- a/util/grub-probe.c
+++ b/util/grub-probe.c
@@ -99,9 +99,11 @@ probe_raid_level (grub_disk_t disk)
   if (!disk)
     return -1;
 
+  grub_util_info("disk->name=%s disk->dev->id=%d\n", disk->name, disk->dev->id);
   if (disk->dev->id != GRUB_DISK_DEVICE_RAID_ID)
     return -1;
 
+  grub_util_info("disk->name=%s disk->data->level=%d\n", disk->name, ((struct grub_raid_array *) disk->data)->level);
   return ((struct grub_raid_array *) disk->data)->level;
 }
 
@@ -161,6 +163,7 @@ probe (const char *path, char *device_name)
       int raid_level;
 
       raid_level = probe_raid_level (dev->disk);
+      grub_util_info ("raid_level=%d", raid_level);
       if (raid_level >= 0)
 	{
 	  is_raid = 1;
@@ -168,10 +171,12 @@ probe (const char *path, char *device_name)
 	  is_raid6 |= (raid_level == 6);
 	}
 
-      if ((is_lvm) && (dev->disk->dev->memberlist))
+      if (!is_raid && dev->disk->dev->memberlist)
 	list = dev->disk->dev->memberlist (dev->disk);
+
       while (list)
 	{
+          grub_util_info ("list->disk->name=%s", list->disk->name);
 	  raid_level = probe_raid_level (list->disk);
 	  if (raid_level >= 0)
 	    {
@@ -210,6 +215,9 @@ probe (const char *path, char *device_name)
       /* Check if dev->disk itself is contained in a partmap.  */
       probe_partmap (dev->disk);
 
+      if (dev->disk->dev->id == GRUB_DISK_DEVICE_RAID_ID && dev->disk->data_offset > 0)
+        goto end;
+
       /* In case of LVM/RAID, check the member devices as well.  */
       if (dev->disk->dev->memberlist)
 	list = dev->disk->dev->memberlist (dev->disk);
@@ -402,6 +410,9 @@ main (int argc, char *argv[])
 	  }
     }
 
+  /* in case we are in debug mode */
+  grub_env_set ("debug", "");
+
   if (verbosity > 1)
     grub_env_set ("debug", "all");
 
diff --git a/util/hostdisk.c b/util/hostdisk.c
index 98d3d53..46c7d29 100644
--- a/util/hostdisk.c
+++ b/util/hostdisk.c
@@ -121,7 +121,7 @@ have_devfs (void)
 }
 #endif /* __linux__ */
 
-static int
+int
 find_grub_drive (const char *name)
 {
   unsigned int i;
@@ -335,6 +335,8 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags)
     int is_partition = 0;
     char dev[PATH_MAX];
 
+    grub_dprintf ("hostdisk", "opening device '%s', map[%ld]\n", map[disk->id].device, disk->id);
+
     strcpy (dev, map[disk->id].device);
     if (disk->partition && sector >= disk->partition->start
 	&& strncmp (map[disk->id].device, "/dev/", 5) == 0)
@@ -797,6 +799,17 @@ convert_system_partition_to_system_disk (const char *os_dev)
 	  return path;
 	}
 
+      /* If this is a md Raid Array.  */
+      if (!strncmp ("md/d", p, 4) || !strncmp ("md_d", p, 4))
+	{
+	  /* /dev/md[_/]d[0-9]+(p[0-9]+)? */
+	  p = strchr (p, 'p');
+	  if (p)
+	    *p = '\0';
+grub_dprintf("hostdisk", "path=%s\n", path);
+	  return path;
+	}
+
       /* If this is a Compaq Intelligent Drive Array.  */
       if (strncmp ("ida/c", p, sizeof ("ida/c") - 1) == 0)
 	{
diff --git a/util/i386/pc/grub-setup.c b/util/i386/pc/grub-setup.c
index 4e2517e..5c59cca 100644
--- a/util/i386/pc/grub-setup.c
+++ b/util/i386/pc/grub-setup.c
@@ -34,10 +34,11 @@
 #include <grub/term.h>
 #include <grub/i18n.h>
 #include <grub/util/raid.h>
+#include <grub/raid.h>
 #include <grub/util/lvm.h>
 #include <grub/util/getroot.h>
 
-static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT;
+#include <grub/mm.h>
 
 #include <grub_setup_init.h>
 
@@ -50,8 +51,12 @@ static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot = GRUB_GPT_P
 #include <dirent.h>
 #include <assert.h>
 #include "progname.h"
+#include <grub/util/getroot.h>
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+#include <fcntl.h>
+
 
-#define _GNU_SOURCE	1
 #include <getopt.h>
 
 #define DEFAULT_BOOT_FILE	"boot.img"
@@ -78,17 +83,49 @@ grub_refresh (void)
   fflush (stdout);
 }
 
+/* awrite() comes from the MDADM project (http://neil.brown.name/blog/mdadm). */
+static char abuf[4096+4096];
+static int awrite(int fd, void *buf, int len) {
+  /* aligned write.
+    * On devices with a 4K sector size, we need to write
+    * the full sector.  We pre-read if the sector is larger
+    * than the write.
+    * The address must be sector-aligned.
+    */
+  int bsize;
+  char *b;
+  int n;
+  if(ioctl(fd, BLKSSZGET, &bsize) != 0 ||
+      bsize <= len)
+          return write(fd, buf, len);
+  if(bsize > 4096)
+          return -1;
+  b =(char*)(((long)(abuf+4096))&~4095UL);
+
+  n = read(fd, b, bsize);
+  if(n <= 0)
+          return n;
+  lseek(fd, -n, 1);
+  memcpy(b, buf, len);
+  n = write(fd, b, bsize);
+  if(n <= 0)
+          return n;
+  lseek(fd, len - n, 1);
+  return len;
+}
+
 static void
 setup (const char *dir,
        const char *boot_file, const char *core_file,
-       const char *root, const char *dest, int must_embed, int force, int fs_probe)
+       const char *root, const char *dest, int must_embed __attribute__ ((unused)), int force __attribute__ ((unused)), int fs_probe)
 {
-  char *boot_path, *core_path, *core_path_dev, *core_path_dev_full;
+  char *boot_path, *core_path;
   char *boot_img, *core_img;
   size_t boot_size, core_size;
   grub_uint16_t core_sectors;
   grub_device_t root_dev, dest_dev;
-  const char *dest_partmap;
+  grub_disk_t disk;
+  const char *partmap;
   grub_uint8_t *boot_drive;
   grub_disk_addr_t *kernel_sector;
   grub_uint16_t *boot_drive_check;
@@ -96,52 +133,18 @@ setup (const char *dir,
   grub_int32_t *install_dos_part, *install_bsd_part;
   grub_int32_t dos_part, bsd_part;
   char *tmp_img;
-  int i;
-  grub_disk_addr_t first_sector;
-  grub_uint16_t current_segment
-    = GRUB_BOOT_MACHINE_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4);
-  grub_uint16_t last_length = GRUB_DISK_SECTOR_SIZE;
-  grub_file_t file;
-  FILE *fp;
-  struct { grub_uint64_t start; grub_uint64_t end; } embed_region;
-  embed_region.start = embed_region.end = ~0UL;
-
-  auto void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector, unsigned offset,
-			       unsigned length);
-  auto void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector, unsigned offset,
-			     unsigned length);
-
-  auto int NESTED_FUNC_ATTR find_usable_region_msdos (grub_disk_t disk,
-						      const grub_partition_t p);
-  int NESTED_FUNC_ATTR find_usable_region_msdos (grub_disk_t disk __attribute__ ((unused)),
-						 const grub_partition_t p)
-    {
-      struct grub_msdos_partition *pcdata = p->data;
-
-      /* There's always an embed region, and it starts right after the MBR.  */
-      embed_region.start = 1;
+  grub_disk_addr_t first_sector = 0;
+  struct { grub_uint64_t start; grub_uint64_t end; int index;} embed_region = { ~0UL, ~0UL, 0 };
 
-      /* For its end offset, include as many dummy partitions as we can.  */
-      if (! grub_msdos_partition_is_empty (pcdata->dos_type)
-	  && ! grub_msdos_partition_is_bsd (pcdata->dos_type)
-	  && embed_region.end > p->start)
-	embed_region.end = p->start;
-
-      return 0;
-    }
-
-  auto int NESTED_FUNC_ATTR find_usable_region_gpt (grub_disk_t disk,
-						    const grub_partition_t p);
-  int NESTED_FUNC_ATTR find_usable_region_gpt (grub_disk_t disk __attribute__ ((unused)),
-					       const grub_partition_t p)
-    {
+  auto int NESTED_FUNC_ATTR
+  part_gpt(grub_disk_t d __attribute__((unused)), const grub_partition_t p) {
       struct grub_gpt_partentry *gptdata = p->data;
+    grub_gpt_part_type_t grub_bios = GRUB_GPT_PARTITION_TYPE_BIOS_BOOT;
 
-      /* If there's an embed region, it is in a dedicated partition.  */
-      if (! memcmp (&gptdata->type, &grub_gpt_partition_type_bios_boot, 16))
-	{
+    if(!memcmp(&gptdata->type, &grub_bios, 16)) {
 	  embed_region.start = p->start;
 	  embed_region.end = p->start + p->len;
+      embed_region.index = p->index + 1;
 
 	  return 1;
 	}
@@ -149,48 +152,25 @@ setup (const char *dir,
       return 0;
     }
 
-  void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector, unsigned offset,
-			  unsigned length)
-    {
-      grub_util_info ("the first sector is <%llu,%u,%u>",
-		      sector, offset, length);
-
-      if (offset != 0 || length != GRUB_DISK_SECTOR_SIZE)
-	grub_util_error (_("the first sector of the core file is not sector-aligned"));
-
-      first_sector = sector;
-    }
-
-  void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector, unsigned offset,
-			unsigned length)
-    {
-      struct grub_boot_blocklist *prev = block + 1;
+  auto int NESTED_FUNC_ATTR
+  part_msdos(grub_disk_t d __attribute__((unused)),const grub_partition_t p){
+    struct grub_msdos_partition *pcdata = p->data;
 
-      grub_util_info ("saving <%llu,%u,%u> with the segment 0x%x",
-		      sector, offset, length, (unsigned) current_segment);
+    /* There's always an embed region, and it starts right after the MBR */
+    embed_region.start = 1;
 
-      if (offset != 0 || last_length != GRUB_DISK_SECTOR_SIZE)
-	grub_util_error (_("non-sector-aligned data is found in the core file"));
+    /* For its end offset, include as many dummy partitions as we can */
+    if(grub_msdos_partition_is_empty(pcdata->dos_type))
+      return 0;
 
-      if (block != first_block
-	  && (grub_le_to_cpu64 (prev->start)
-	      + grub_le_to_cpu16 (prev->len)) == sector)
-	prev->len = grub_cpu_to_le16 (grub_le_to_cpu16 (prev->len) + 1);
-      else
-	{
-	  block->start = grub_cpu_to_le64 (sector);
-	  block->len = grub_cpu_to_le16 (1);
-	  block->segment = grub_cpu_to_le16 (current_segment);
+    if(embed_region.end > p->start) {
+      embed_region.end = p->start;
 
-	  block--;
-	  if (block->len)
-	    grub_util_error (_("the sectors of the core file are too fragmented"));
+      return 1;
 	}
 
-      last_length = length;
-      current_segment += GRUB_DISK_SECTOR_SIZE >> 4;
+    return 0;
     }
-
   /* Read the boot image by the OS service.  */
   boot_path = grub_util_get_path (dir, boot_file);
   boot_size = grub_util_get_image_size (boot_path);
@@ -241,9 +221,11 @@ setup (const char *dir,
   if (grub_env_set ("root", root) != GRUB_ERR_NONE)
     grub_util_error ("%s", grub_errmsg);
 
+  disk = dest_dev->disk;
+
   /* Read the original sector from the disk.  */
   tmp_img = xmalloc (GRUB_DISK_SECTOR_SIZE);
-  if (grub_disk_read (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, tmp_img))
+  if (grub_disk_read (disk, 0, 0, GRUB_DISK_SECTOR_SIZE, tmp_img))
     grub_util_error ("%s", grub_errmsg);
 
   if (dest_dev->disk->partition && fs_probe)
@@ -268,7 +250,7 @@ setup (const char *dir,
 	  GRUB_BOOT_MACHINE_BPB_END - GRUB_BOOT_MACHINE_BPB_START);
 
   /* Copy the possible partition table.  */
-  if (dest_dev->disk->has_partitions)
+  if (disk->has_partitions)
     memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC,
 	    tmp_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC,
 	    GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC);
@@ -278,7 +260,7 @@ setup (const char *dir,
   /* If DEST_DRIVE is a hard disk, enable the workaround, which is
      for buggy BIOSes which don't pass boot drive correctly. Instead,
      they pass 0x00 or 0x01 even when booted from 0x80.  */
-  if (dest_dev->disk->id & 0x80)
+  if (disk->id & 0x80)
     /* Replace the jmp (2 bytes) with double nop's.  */
     *boot_drive_check = 0x9090;
 
@@ -311,23 +293,23 @@ setup (const char *dir,
     }
   else
     {
+      grub_util_info ("drive is part of prefix");
       dos_part = grub_le_to_cpu32 (*install_dos_part);
       bsd_part = grub_le_to_cpu32 (*install_bsd_part);
     }
 
-  grub_util_info ("dos partition is %d, bsd partition is %d",
-		  dos_part, bsd_part);
+  grub_util_info ("DOS partition is %d, BSD partition is %d", dos_part, bsd_part);
 
-  if (! dest_dev->disk->has_partitions)
+  if (! disk->has_partitions)
     {
       grub_util_warn (_("Attempting to install GRUB to a partitionless disk.  This is a BAD idea."));
-      goto unable_to_embed;
+      goto finish;
     }
 
-  if (dest_dev->disk->partition)
+  if (disk->partition)
     {
       grub_util_warn (_("Attempting to install GRUB to a partition instead of the MBR.  This is a BAD idea."));
-      goto unable_to_embed;
+      goto finish;
     }
 
   /* Unlike root_dev, with dest_dev we're interested in the partition map even
@@ -337,51 +319,68 @@ setup (const char *dir,
   int NESTED_FUNC_ATTR identify_partmap (grub_disk_t disk __attribute__ ((unused)),
 					 const grub_partition_t p)
     {
-      dest_partmap = p->partmap->name;
+      partmap = p->partmap->name;
       return 1;
     }
-  dest_partmap = 0;
-  grub_partition_iterate (dest_dev->disk, identify_partmap);
 
-  if (! dest_partmap)
-    {
-      grub_util_warn (_("Attempting to install GRUB to a partitionless disk.  This is a BAD idea."));
-      goto unable_to_embed;
+
+  partmap = 0;
+  grub_partition_iterate (disk, identify_partmap);
+
+  if (! partmap) {
+      grub_util_warn ("Attempting to install GRUB to a partitionless disk %s", disk->name);
+      goto finish;
     }
 
-  if (strcmp (dest_partmap, "part_msdos") == 0)
-    grub_partition_iterate (dest_dev->disk, find_usable_region_msdos);
-  else if (strcmp (dest_partmap, "part_gpt") == 0)
-    grub_partition_iterate (dest_dev->disk, find_usable_region_gpt);
-  else
-    grub_util_error (_("No DOS-style partitions found"));
+  grub_util_info ("%s: identified partmap %s\n", disk->name, partmap);
+
+  grub_util_info ("Scanning device %s for usable region (data offset=%lu)...\n", disk->name, disk->data_offset);
+
+  int(*find)(grub_disk_t d, const grub_partition_t p);
+
+  find =(strcmp(partmap, "part_msdos")? part_gpt : part_msdos);
+  grub_partition_iterate(disk, find);
 
   if (embed_region.end == embed_region.start)
     {
-      if (! strcmp (dest_partmap, "part_msdos"))
+      if (! strcmp (partmap, "part_msdos"))
 	grub_util_warn (_("This msdos-style partition label has no post-MBR gap; embedding won't be possible!"));
       else
 	grub_util_warn (_("This GPT partition label has no BIOS Boot Partition; embedding won't be possible!"));
-      goto unable_to_embed;
+      goto finish;
     }
 
   if ((unsigned long) core_sectors > embed_region.end - embed_region.start)
     {
       if (core_sectors > 62)
 	grub_util_warn (_("Your core.img is unusually large.  It won't fit in the embedding area."));
-      else /* embed_region.end - embed_region.start < 62 */
+      else if (embed_region.end - embed_region.start < 62)
 	grub_util_warn (_("Your embedding area is unusually small.  core.img won't fit in it."));
-      goto unable_to_embed;
+      else
+        grub_util_warn ("Embedding area is too small for core.img.");
+      goto finish;
     }
 
+    if (!embed_region.index)
+      grub_util_info ("Embedding area of %s is right after MBR", disk->name);
+    else
+      grub_util_info ("Embedding area of %s is GPT BIOS partition %d", disk->name, embed_region.index);
+
+    if (disk->dev->id == GRUB_DISK_DEVICE_RAID_ID) {
+      struct grub_raid_array *array = disk->data;
+
+      first_sector = array->data_offset;
+      grub_util_info ("disk %s is a raid device\n", disk->name);
+    }
+
+    grub_util_info ("first data sector for %s is %ld\n", disk->name, first_sector);
 
-  grub_util_info ("the core image will be embedded at sector 0x%llx", embed_region.start);
 
   *install_dos_part = grub_cpu_to_le32 (dos_part);
   *install_bsd_part = grub_cpu_to_le32 (bsd_part);
 
   /* The first blocklist contains the whole sectors.  */
-  first_block->start = grub_cpu_to_le64 (embed_region.start + 1);
+  first_block->start = grub_cpu_to_le64 (embed_region.start + first_sector + 1);
 
   /* These are filled elsewhere.  Verify them just in case.  */
   assert (first_block->len == grub_host_to_target16 (core_sectors - 1));
@@ -394,165 +393,179 @@ setup (const char *dir,
   block->len = 0;
   block->segment = 0;
 
-  /* Write the core image onto the disk.  */
-  if (grub_disk_write (dest_dev->disk, embed_region.start, 0, core_size, core_img))
-    grub_util_error ("%s", grub_errmsg);
 
-  /* FIXME: can this be skipped?  */
-  *boot_drive = 0xFF;
-
-  *kernel_sector = grub_cpu_to_le64 (embed_region.start);
-
-  /* Write the boot image onto the disk.  */
-  if (grub_disk_write (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE,
-		       boot_img))
-    grub_util_error ("%s", grub_errmsg);
+  int fd;
+  char *os_dev = NULL;
+  int drive;
 
-  goto finish;
+  extern int find_grub_drive (const char *);
+  extern struct {
+    char *drive;
+    char *device;
+  } map[256];
 
-unable_to_embed:
+  char *partname = NULL;
+  char *p;
 
-  if (must_embed)
-    grub_util_error (_("embedding is not possible, but this is required when "
-		       "the root device is on a RAID array or LVM volume"));
+  drive = find_grub_drive(disk->name);
 
-  grub_util_warn (_("Embedding is not possible.  GRUB can only be installed in this "
-		    "setup by using blocklists.  However, blocklists are UNRELIABLE and "
-		    "its use is discouraged."));
-  if (! force)
-    grub_util_error (_("if you really want blocklists, use --force"));
+  if (drive < 0) {
 
-  /* Make sure that GRUB reads the identical image as the OS.  */
-  tmp_img = xmalloc (core_size);
-  core_path_dev_full = grub_util_get_path (dir, core_file);
-  core_path_dev = make_system_path_relative_to_its_root (core_path_dev_full);
-  free (core_path_dev_full);
+    if (embed_region.index)
+      partname = xasprintf ("%s,%d", disk->name, embed_region.index);
+    else
+      partname = xasprintf ("%s", disk->name);
 
-  /* It is a Good Thing to sync two times.  */
-  sync ();
-  sync ();
+    os_dev = xasprintf ("/dev/%s", partname);
+    p = strchr (os_dev, ',');
+    if (p) *p = 'p';
 
-#define MAX_TRIES	5
+    grub_util_info ("%s (%s) is a md%c RAID array, also no mapping is needed for it.",
+		    os_dev, partname, (p)? *p:' ');
+  }
+  else {
+    os_dev = grub_malloc (PATH_MAX);
 
-  for (i = 0; i < MAX_TRIES; i++)
-    {
-      grub_util_info ((i == 0) ? _("attempting to read the core image `%s' from GRUB")
-		      : _("attempting to read the core image `%s' from GRUB again"),
-		      core_path_dev);
+    strcpy(os_dev, map[drive].device);
 
-      grub_disk_cache_invalidate_all ();
+    if (embed_region.index) {
+      size_t len = strlen (map[drive].device);
+      const char *format;
 
-      file = grub_file_open (core_path_dev);
-      if (file)
-	{
-	  if (grub_file_size (file) != core_size)
-	    grub_util_info ("succeeded in opening the core image but the size is different (%d != %d)",
-			    (int) grub_file_size (file), (int) core_size);
-	  else if (grub_file_read (file, tmp_img, core_size)
-		   != (grub_ssize_t) core_size)
-	    grub_util_info ("succeeded in opening the core image but cannot read %d bytes",
-			    (int) core_size);
-	  else if (memcmp (core_img, tmp_img, core_size) != 0)
-	    {
-#if 0
-	      FILE *dump;
-	      FILE *dump2;
-
-	      dump = fopen ("dump.img", "wb");
-	      if (dump)
-		{
-		  fwrite (tmp_img, 1, core_size, dump);
-		  fclose (dump);
+      if (strcmp (os_dev + len - 5, "/disc") == 0) {
+        p = os_dev + len - 4;
+        format = "part%d";
+      }
+      else if (os_dev[len - 1] >= '0' && os_dev[len - 1] <= '9') {
+        p = os_dev + len;
+        format = "p%d";
+      }
+      else {
+        p = os_dev + len;
+        format = "%d";
 		}
 
-	      dump2 = fopen ("dump2.img", "wb");
-	      if (dump2)
-		{
-		  fwrite (core_img, 1, core_size, dump2);
-		  fclose (dump2);
+      sprintf (p, format, embed_region.index);
+    }
 		}
 
-#endif
-	      grub_util_info ("succeeded in opening the core image but the data is different");
+  if (partname)
+    free(partname);
+
+  fprintf(stderr, "Opening %s\n", os_dev);
+
+  fd = open(os_dev, O_RDWR);
+  if(fd < 0) {
+    fprintf(stderr, "open(): invalid device %s\n",os_dev);
+    exit(4);
 	    }
-	  else
-	    {
-	      grub_file_close (file);
-	      break;
+
+  free (os_dev);
+
+  if (!embed_region.index) {
+    off_t offset = embed_region.start * GRUB_DISK_SECTOR_SIZE;
+    if (lseek(fd, offset , SEEK_SET) != offset) {
+      fprintf(stderr, "lseek(): unable to seek\n");
+      exit(4);
 	    }
 
-	  grub_file_close (file);
+    grub_util_info ("Write the core image (%d bytes) after the MBR", core_size);
 	}
       else
-	grub_util_info ("couldn't open the core image");
+    grub_util_info ("Write the core image (%d bytes) into partition %d", core_size, embed_region.index);
 
-      if (grub_errno)
-	grub_util_info ("error message = %s", grub_errmsg);
+  /* Write the core image onto the disk.  */
+  if (awrite (fd, core_img, core_size) != (int) core_size)
+    grub_util_error ("%s", grub_errmsg);
 
-      grub_errno = GRUB_ERR_NONE;
-      sync ();
-      sleep (1);
-    }
+  close(fd);
 
-  if (i == MAX_TRIES)
-    grub_util_error (_("cannot read `%s' correctly"), core_path_dev);
+  /* Write the boot image onto the disk.  */
+  /* FIXME: can this be skipped?  */
+  *boot_drive = 0xFF;
 
-  /* Clean out the blocklists.  */
-  block = first_block;
-  while (block->len)
-    {
-      block->start = 0;
-      block->len = 0;
-      block->segment = 0;
+  *kernel_sector = grub_cpu_to_le64 (embed_region.start + first_sector);
+
+  grub_util_info ("Copy the boot image (%d bytes) into the legacy MBR", boot_size);
+
+  grub_disk_memberlist_t list = NULL;
+
+  if (disk->dev->id == GRUB_DISK_DEVICE_RAID_ID) {
+    grub_disk_memberlist_t tmp;
 
-      block--;
+    grub_util_info ("disk %s is a raid\n", disk->name);
 
-      if ((char *) block <= core_img)
-	grub_util_error (_("no terminator in the core image"));
+    if (disk->dev->memberlist)
+      list = disk->dev->memberlist (disk);
+
+    while (list)
+    {
+      grub_util_info ("list->disk->name=%s", list->disk->name);
+      drive = find_grub_drive (list->disk->name);
+      if (drive < 0) {
+        grub_util_warn ("no mapping exists for %s", list->disk->name);
+        continue;
+      }
+      else {
+        grub_util_info ("found array %s", list->disk->name);
+
+        os_dev = strdup(map[drive].device);
+
+        fprintf(stderr, "Opening %s\n", os_dev);
+
+        fd = open(os_dev, O_RDWR);
+        if(fd < 0) {
+          grub_util_warn("invalid device %s\n",os_dev);
+          exit(4);
     }
 
-  /* Now read the core image to determine where the sectors are.  */
-  file = grub_file_open (core_path_dev);
-  if (! file)
+        grub_util_info ("Copy the boot image into the legacy MBR of %s\n", os_dev);
+
+        free (os_dev);
+
+        /* Write the boot image onto the disk.  */
+        if (awrite (fd, boot_img, boot_size) != (int) boot_size)
     grub_util_error ("%s", grub_errmsg);
 
-  file->read_hook = save_first_sector;
-  if (grub_file_read (file, tmp_img, GRUB_DISK_SECTOR_SIZE)
-      != GRUB_DISK_SECTOR_SIZE)
-    grub_util_error (_("failed to read the first sector of the core image"));
+      }
 
-  block = first_block;
-  file->read_hook = save_blocklists;
-  if (grub_file_read (file, tmp_img, core_size - GRUB_DISK_SECTOR_SIZE)
-      != (grub_ssize_t) core_size - GRUB_DISK_SECTOR_SIZE)
-    grub_util_error (_("failed to read the rest sectors of the core image"));
+      tmp = list->next;
+      free (list);
+      list = tmp;
+    }
 
-  grub_file_close (file);
+    goto finish;
+  }
 
-  free (core_path_dev);
-  free (tmp_img);
+  drive = find_grub_drive(disk->name);
 
-  *kernel_sector = grub_cpu_to_le64 (first_sector);
+  if (drive < 0) {
+    grub_util_warn ("no mapping exists for %s", disk->name);
+    goto finish;
+  }
 
-  /* FIXME: can this be skipped?  */
-  *boot_drive = 0xFF;
+  grub_util_info ("found device %s", disk->name);
 
-  *install_dos_part = grub_cpu_to_le32 (dos_part);
-  *install_bsd_part = grub_cpu_to_le32 (bsd_part);
+  os_dev = strdup(map[drive].device);
+
+  fprintf(stderr, "Opening %s\n", os_dev);
+
+  fd = open(os_dev, O_RDWR);
+  if(fd < 0) {
+    grub_util_warn("invalid device %s\n",os_dev);
+    exit(4);
+  }
 
-  /* Write the first two sectors of the core image onto the disk.  */
-  grub_util_info ("opening the core image `%s'", core_path);
-  fp = fopen (core_path, "r+b");
-  if (! fp)
-    grub_util_error (_("cannot open `%s'"), core_path);
+  grub_util_info ("Copy the boot image into the legacy MBR of %s\n", os_dev);
 
-  grub_util_write_image (core_img, GRUB_DISK_SECTOR_SIZE * 2, fp);
-  fclose (fp);
+  free (os_dev);
 
   /* Write the boot image onto the disk.  */
-  if (grub_disk_write (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, boot_img))
+  if (awrite (fd, boot_img, boot_size) != (int) boot_size)
     grub_util_error ("%s", grub_errmsg);
 
+  close(fd);
+
  finish:
 
   /* Sync is a Good Thing.  */
@@ -710,6 +723,9 @@ main (int argc, char *argv[])
 	  }
     }
 
+  /* if we have forced the debug mode in the code */
+  grub_env_set ("debug", "");
+
   if (verbosity > 1)
     grub_env_set ("debug", "all");
 
@@ -727,7 +743,7 @@ main (int argc, char *argv[])
     }
 
   /* Initialize the emulated biosdisk driver.  */
-  grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP);
+  grub_util_biosdisk_init (dev_map ? dev_map : DEFAULT_DEVICE_MAP);
 
   /* Initialize all modules. */
   grub_init_all ();
@@ -760,7 +776,7 @@ main (int argc, char *argv[])
     }
   else
     {
-      root_dev = grub_util_get_grub_dev (grub_guess_root_device (dir ? : DEFAULT_DIRECTORY));
+      root_dev = grub_util_get_grub_dev (grub_guess_root_device (dir ? dir : DEFAULT_DIRECTORY));
       if (! root_dev)
 	{
 	  grub_util_info ("guessing the root device failed, because of `%s'",
@@ -773,35 +789,18 @@ main (int argc, char *argv[])
   if (grub_util_lvm_isvolume (root_dev))
     must_embed = 1;
 
-  if (root_dev[0] == 'm' && root_dev[1] == 'd'
-      && root_dev[2] >= '0' && root_dev[2] <= '9')
-    {
+  if (root_dev[0] == 'm' && root_dev[1] == 'd') {
+    int i = (root_dev[2] == '_')? 2 : 3;
+    if ( root_dev[i] >= '0' && root_dev[i] <= '9')
       /* FIXME: we can avoid this on RAID1.  */
       must_embed = 1;
     }
 
-  if (dest_dev[0] == 'm' && dest_dev[1] == 'd'
-      && dest_dev[2] >= '0' && dest_dev[2] <= '9')
-    {
-      char **devicelist;
-      int i;
-
-      devicelist = grub_util_raid_getmembers (dest_dev);
-
-      for (i = 0; devicelist[i]; i++)
-	{
-	  setup (dir ? : DEFAULT_DIRECTORY,
-		 boot_file ? : DEFAULT_BOOT_FILE,
-		 core_file ? : DEFAULT_CORE_FILE,
-		 root_dev, grub_util_get_grub_dev (devicelist[i]), 1, force, fs_probe);
-	}
-    }
-  else
 #endif
   /* Do the real work.  */
-    setup (dir ? : DEFAULT_DIRECTORY,
-	   boot_file ? : DEFAULT_BOOT_FILE,
-	   core_file ? : DEFAULT_CORE_FILE,
+    setup (dir ? dir : DEFAULT_DIRECTORY,
+	   boot_file ? boot_file : DEFAULT_BOOT_FILE,
+	   core_file ? core_file : DEFAULT_CORE_FILE,
 	   root_dev, dest_dev, must_embed, force, fs_probe);
 
   /* Free resources.  */
@@ -817,3 +816,4 @@ main (int argc, char *argv[])
 
   return 0;
 }
+
-- 
1.7.1.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] grub-1.98: support for partitionable array v1.2
  2010-07-20 15:56 [PATCH] grub-1.98: support for partitionable array v1.2 Gaëtan Schmidt
  2010-07-20 15:56 ` [PATCH] mdadm 1.2 partitions array ready Gaëtan Schmidt
@ 2010-07-20 16:08 ` Colin Watson
  2010-07-20 18:38   ` Jimmy.Jazz
  1 sibling, 1 reply; 5+ messages in thread
From: Colin Watson @ 2010-07-20 16:08 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: Gaëtan Schmidt

On Tue, Jul 20, 2010 at 05:56:46PM +0200, Gaëtan Schmidt wrote:
> I modify grub2 to understand mdadm 1.2 partition array without the
> need to map either the metadevice or the partitions in the device.map
> file. Just the physical devices are required.  As the meta devices are
> added, they will be recognized automatically. Only raid 1 is supported
> for the moment but it can be extended to other layouts.

You've sent this *just* after I committed patches to trunk to understand
mdadm 1.x metadata.  Could you please look at trunk instead of 1.98?

> mdadm 1.1 is not fit to be bootable, its superblock overlaps the boot
> sector 0.

Only if you RAID entire disk devices; it works fine if you RAID
partitions.

> I don't use mdX and md/X syntaxes. md_dX is more relevant because of
> the mdadm default 1.x kernel device scheme /dev/md_dX.

We already discussed this and agreed to use md/*.  The current mdadm(8)
says:

  From kernel version, 2.6.28 the "non-partitioned array" can actually
  be partitioned.  So the "md_dNN" names are no longer needed, and
  partitions such as "/dev/mdNNpXX" are possible.

I prefer the explicit namespacing of md/*, and it makes it easier to
support named arrays in a clear way.

> grub-setup.c and grub-probe.c have been heavily altered to understand
> mdadm 1.2 partitionable array. That means, grub-setup.c does not
> support embedded core image in the MBR first sectors gap (<64k)
> anymore.
> 
> To avoid any confusion, grub-setup should be renamed grub-mdraid-setup
> or something like that.

No renames were necessary with the branch recently merged into trunk.
If you need further work to support partitionable arrays, then let's
discuss that; I don't think it's desirable to create a forked version of
grub-setup or grub-probe, though.

> For the try and fix version of the patches, please forget it. It is
> really messy. I am using git for the development and i was not able to
> convert the bzr repository to git, so i don't have a valid tree.
> Anyway, if you are interested in it, please let me know.

Just use bzr instead. :-)

Regards,

-- 
Colin Watson                                       [cjwatson@ubuntu.com]


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] grub-1.98: support for partitionable array v1.2
  2010-07-20 16:08 ` [PATCH] grub-1.98: support for partitionable array v1.2 Colin Watson
@ 2010-07-20 18:38   ` Jimmy.Jazz
  2011-04-01 18:46     ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 1 reply; 5+ messages in thread
From: Jimmy.Jazz @ 2010-07-20 18:38 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: Colin Watson

 Le 20/07/2010 18:08, Colin Watson a écrit :
> On Tue, Jul 20, 2010 at 05:56:46PM +0200, Gaëtan Schmidt wrote:
>> I modify grub2 to understand mdadm 1.2 partition array without the
>> need to map either the metadevice or the partitions in the device.map
>> file. Just the physical devices are required.  As the meta devices are
>> added, they will be recognized automatically. Only raid 1 is supported
>> for the moment but it can be extended to other layouts.
> You've sent this *just* after I committed patches to trunk to understand
> mdadm 1.x metadata.  Could you please look at trunk instead of 1.98?
>

It looks like I hurt your feelings. Sorry for that. For the patches I
propose, better late than never :)
Anyway, I appreciate your implication in the grub project.

>> mdadm 1.1 is not fit to be bootable, its superblock overlaps the boot
>> sector 0.
> Only if you RAID entire disk devices; it works fine if you RAID
> partitions.
>

That is the main difference and here the patches i *propose* come in handy.
You don't have to repartition or reinstall grub on the failed disk. Just
add the spare and let's go.
It is more like a fake raid but harder to implement w/o scripts.

>> I don't use mdX and md/X syntaxes. md_dX is more relevant because of
>> the mdadm default 1.x kernel device scheme /dev/md_dX.
> We already discussed this and agreed to use md/*.  The current mdadm(8)
> says:
>
>   From kernel version, 2.6.28 the "non-partitioned array" can actually
>   be partitioned.  So the "md_dNN" names are no longer needed, and
>   partitions such as "/dev/mdNNpXX" are possible.
>
> I prefer the explicit namespacing of md/*, and it makes it easier to
> support named arrays in a clear way.
>

That's just about cosmetic. You don't need to declare md partitions or
whatever at all in device.map.
It's just the way it appears in grub.cfg but the names have to be
different from 0.9 arrays' names.

>> grub-setup.c and grub-probe.c have been heavily altered to understand
>> mdadm 1.2 partitionable array. That means, grub-setup.c does not
>> support embedded core image in the MBR first sectors gap (<64k)
>> anymore.
>>
>> To avoid any confusion, grub-setup should be renamed grub-mdraid-setup
>> or something like that.
> No renames were necessary with the branch recently merged into trunk.
> If you need further work to support partitionable arrays, then let's
> discuss that; I don't think it's desirable to create a forked version of
> grub-setup or grub-probe, though.
>

Sorry you did not read the code here

>> For the try and fix version of the patches, please forget it. It is
>> really messy. I am using git for the development and i was not able to
>> convert the bzr repository to git, so i don't have a valid tree.
>> Anyway, if you are interested in it, please let me know.
> Just use bzr instead. :-)
>

IMHO, that's not the best way to spread a project in the community. But
you know now the reason why I'm using grub tarball and delayed so long
to share the patches. Also they need to be reviewed.

> Regards,
>

Jj



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] grub-1.98: support for partitionable array v1.2
  2010-07-20 18:38   ` Jimmy.Jazz
@ 2011-04-01 18:46     ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 0 replies; 5+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2011-04-01 18:46 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: Jimmy.Jazz

[-- Attachment #1: Type: text/plain, Size: 667 bytes --]

On 20.07.2010 20:38, Jimmy.Jazz@gmx.net wrote:
> That is the main difference and here the patches i *propose* come in handy.
> You don't have to repartition or reinstall grub on the failed disk. Just
> add the spare and let's go.
>   
You can't just tell: "Let's try install to XYZ". It needs to be first
made sure that it's safe.
> Also they [patches] need to be reviewed.
I've looked into them and it seems that they don't offer anything
compared to Colin's and they contain too much pure debug changes. If you
disagree please clean up the parts which you consider of use and rebased
on trunk

-- 
Regards
Vladimir 'φ-coder/phcoder' Serbinenko



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-04-01 18:46 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-20 15:56 [PATCH] grub-1.98: support for partitionable array v1.2 Gaëtan Schmidt
2010-07-20 15:56 ` [PATCH] mdadm 1.2 partitions array ready Gaëtan Schmidt
2010-07-20 16:08 ` [PATCH] grub-1.98: support for partitionable array v1.2 Colin Watson
2010-07-20 18:38   ` Jimmy.Jazz
2011-04-01 18:46     ` Vladimir 'φ-coder/phcoder' Serbinenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.