boot from LVM / RAID
PATCH 1/1 boot from LVM / RAID
This patch makes it possible to boot directly from LVM or RAID.
It is archieved by permitting that grub_prefix include a drive component as part of its path. The kernel already knows how to extract root from there, as long as `grub_install_dos_part == -2'.
Signature · 5 lines
Robert Millan <GPLv2> I know my rights; I want my phone call! <DRM> What good is a phone call… if you are unable to speak? (as seen on /.)
2008-06-06 Robert Millan <[email protected]>
Make boot directly from LVM or RAID possible.
* kern/i386/pc/init.c (make_install_device): Remove memdisk check. It is assumed that if we have a memdisk, grub-mkimage has set grub_prefix to include the "(memdisk)" drive in it.
* util/i386/pc/grub-install.in (prefix_drive): New variable. If we need to include a drive in the prefix (because we're installing on LVM or RAID), it is set in this variable.
Include ${grub_prefix} in `--prefix' parameter of ${grub_mkimage} invokation.
* util/i386/pc/grub-mkimage.c (main): If a memdisk was requested, add "(memdisk)" drive explicitly to the beginning of the prefix.
* util/i386/pc/grub-setup.c (setup): Don't write to `install_prefix', since it has been set by grub-mkimage based on request from grub-install, which knows better than anyone else which prefix we need.
kern/i386/pc/init.c renamed from grub2/kern/i386/pc/init.c +1 -6
@@ -64,12 +64,7 @@ make_install_device (void)/* XXX: This should be enough. */ char dev[100 ]; -if (grub_memdisk_image_size) - { -grub_sprintf (dev,"(memdisk)%s" , grub_prefix); -grub_strcpy (grub_prefix, dev); - } -else if (grub_install_dos_part !=-2 ) +if (grub_install_dos_part !=-2 ) {/* If the root drive is not set explicitly, assume that it is identical to the boot drive. */
util/i386/pc/grub-install.in renamed from grub2/util/i386/pc/grub-install.in +9 -1
@@ -231,10 +231,18 @@ partmap_module=`$grub_probe --target=par # Device abstraction module, if any (lvm, raid). devabstraction_module=`$grub_probe --target=abstraction --device ${grub_device}` +if [ "x${devabstraction_module}" = "x" ] ; then + prefix_drive= +else + prefix_drive=`$grub_probe --target=drive --device ${grub_device}` +fi + # _chain is often useful modules="$modules $fs_module $partmap_module biosdisk $devabstraction_module _chain" -$grub_mkimage --output=${grubdir}/core.img --prefix=`make_system_path_relative_to_its_root ${grubdir}`/ $modules || exit 1 +$grub_mkimage --output=${grubdir}/core.img \ + --prefix=${prefix_drive}`make_system_path_relative_to_its_root ${grubdir}`/ \ + $modules || exit 1 # Now perform the installation. $grub_setup --directory=${grubdir} --device-map=${device_map} \
util/i386/pc/grub-mkimage.c renamed from grub2/util/i386/pc/grub-mkimage.c +5 -0
@@ -278,6 +278,11 @@ main (int argc, char *argv[])free (memdisk); memdisk =xstrdup (optarg); + +if (prefix) +free (prefix); + + prefix =xstrdup ("(memdisk)/boot/grub" );break ;case 'h' :
util/i386/pc/grub-setup.c renamed from grub2/util/i386/pc/grub-setup.c +0 -2
@@ -330,7 +330,6 @@ setup (const char *prefix, const char *dgrub_le_to_cpu32 (*install_dos_part),grub_le_to_cpu32 (*install_bsd_part), prefix); -strcpy (install_prefix, prefix);/* Write the core image onto the disk. */ if (grub_disk_write (dest_dev->disk, embed_region.start,0 , core_size, core_img))
@@ -518,7 +517,6 @@ setup (const char *prefix, const char *dgrub_le_to_cpu32 (*install_dos_part),grub_le_to_cpu32 (*install_bsd_part), prefix); -strcpy (install_prefix, prefix);/* Write the first two sectors of the core image onto the disk. */ core_path =grub_util_get_path (dir, core_file);
Quoted 6 lines · Robert Millan
This patch makes it possible to boot directly from LVM or RAID.
It is archieved by permitting that
grub_prefixinclude a drive component as part of its path. The kernel already knows how to extract root from there, as long as `grub_install_dos_part == -2'.
The memdisk part of this was basicaly a bugfix, so I checked it in. The rest seems to duplicate stuff that grub-setup was already doing, and I think I'll have to take a closer look (I'll send another mail about that later).
Signature · 5 lines
Robert Millan <GPLv2> I know my rights; I want my phone call! <DRM> What good is a phone call… if you are unable to speak? (as seen on /.)
new patch (boot from LVM / RAID)
Quoted 4 lines · Robert Millan
The memdisk part of this was basicaly a bugfix, so I checked it in. The rest seems to duplicate stuff that grub-setup was already doing, and I think I'll have to take a closer look (I'll send another mail about that later).
I think I sorted this out. The tip of the iceberg was that grub-setup is prepending a drive to prefix twice when we run LVM on RAID. However, it is actually wrong that grub-setup mangles prefix in first place! core.img might be loaded by other means (e.g. from GRUB Legacy), and then these adjustments have no effect.
I also think it's more flexible if these kind of decisions are taken in a higher layer, so my patch moves this to grub-install, which relies on grub-probe. Then with grub-mkimage being capable of prepending a drive to prefix, there's no need to do it in grub-setup.
This also fixes some minor issues I found along the way.
Any comments?
Signature · 5 lines
Robert Millan <GPLv2> I know my rights; I want my phone call! <DRM> What good is a phone call… if you are unable to speak? (as seen on /.)
Re: new patch (boot from LVM / RAID)
Quoted 2 lines · Robert Millan
Any comments?
Ah, and usually it helps if I remember to attach things :-)
Signature · 5 lines
Robert Millan <GPLv2> I know my rights; I want my phone call! <DRM> What good is a phone call… if you are unable to speak? (as seen on /.)
2008-06-15 Robert Millan <[email protected]>
* util/i386/pc/grub-install.in: If the drive is LVM or RAID, prepend it in prefix.
* util/i386/pc/grub-setup.c (main): Don't handle prefix at all. Set `must_embed' to 1 when root_dev is a RAID device. When dest_dev is a RAID device, run setup() for all members independently on whether LVM abstraction is being used.
(setup): Don't handle prefix at all; let grub-mkimage take care of it. If grub-mkimage has set `*install_dos_part == -2', don't override this value.
Perform *install_dos_part adjustments independently on whether we're embedding or not.
Clarify error message when image is too big for embedding. Remove duplicate *install_dos_part stanza.
util/i386/pc/grub-install.in renamed from grub2/util/i386/pc/grub-install.in +9 -1
@@ -231,10 +231,18 @@ partmap_module=`$grub_probe --target=par # Device abstraction module, if any (lvm, raid). devabstraction_module=`$grub_probe --target=abstraction --device ${grub_device}` +if [ "x${devabstraction_module}" = "x" ] ; then + prefix_drive= +else + prefix_drive=`$grub_probe --target=drive --device ${grub_device}` +fi + # The order in this list is critical. Be careful when modifiing it. modules="$modules $fs_module $partmap_module biosdisk $devabstraction_module" -$grub_mkimage --output=${grubdir}/core.img --prefix=`make_system_path_relative_to_its_root ${grubdir}`/ $modules || exit 1 +$grub_mkimage --output=${grubdir}/core.img \ + --prefix=${prefix_drive}`make_system_path_relative_to_its_root ${grubdir}`/ \ + $modules || exit 1 # Now perform the installation. $grub_setup --directory=${grubdir} --device-map=${device_map} \
util/i386/pc/grub-setup.c renamed from grub2/util/i386/pc/grub-setup.c +47 -94
232 lines not on this page · raw message
Re: new patch (boot from LVM / RAID)
No comment on this? I can't assure you it's 100% bug-free, but I know it fixes existing problems, and I think it's the right way to do it.
If I don't hear any objection, I'll check it in tomorrow.
Quoted 292 lines · Robert Millan
2008-06-15 Robert Millan <[email protected]>
* util/i386/pc/grub-install.in: If the drive is LVM or RAID, prepend it in prefix.
*
util/i386/pc/grub-setup.c(main): Don't handle prefix at all. Set `must_embed' to 1 whenroot_devis a RAID device. Whendest_devis a RAID device, runsetup()for all members independently on whether LVM abstraction is being used.
(setup): Don't handle prefix at all; let grub-mkimage take care of it. If grub-mkimage has set `*install_dos_part == -2', don't override this value.
Perform*install_dos_partadjustments independently on whether we're embedding or not.
Clarify error message when image is too big for embedding. Remove duplicate*install_dos_partstanza.diff -x ChangeLog -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../grub2/util/i386/pc/grub-install.in ./util/i386/pc/grub-install.in
util/i386/pc/grub-install.in renamed from grub2/util/i386/pc/grub-install.in +9
-1@@ -231,10 +231,18 @@ partmap_module=`$grub_probe --target=par # Device abstraction module, if any (lvm, raid). devabstraction_module=`$grub_probe --target=abstraction --device ${grub_device}` +if [ "x${devabstraction_module}" = "x" ] ; then + prefix_drive= +else + prefix_drive=`$grub_probe --target=drive --device ${grub_device}` +fi + # The order in this list is critical. Be careful when modifiing it. modules="$modules $fs_module $partmap_module biosdisk $devabstraction_module" -$grub_mkimage --output=${grubdir}/core.img --prefix=`make_system_path_relative_to_its_root ${grubdir}`/ $modules || exit 1 +$grub_mkimage --output=${grubdir}/core.img \ + --prefix=${prefix_drive}`make_system_path_relative_to_its_root ${grubdir}`/ \ + $modules || exit 1 # Now perform the installation. $grub_setup --directory=${grubdir} --device-map=${device_map} \diff -x ChangeLog -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp
../grub2/util/i386/pc/grub-setup.c./util/i386/pc/grub-setup.cutil/i386/pc/grub-setup.c renamed from grub2/util/i386/pc/grub-setup.c +47
-94@@ -87,7 +87,7 @@ grub_refresh (void) }static void -setup (const char *prefix,const char *dir, +setup (const char *dir,const char *boot_file,const char *core_file,const char *root,const char *dest,int must_embed) {@@ -101,7 +101,6 @@ setup (const char *prefix, const char *dgrub_uint16_t *boot_drive_check;struct boot_blocklist *first_block, *block;grub_int32_t *install_dos_part, *install_bsd_part; -char *install_prefix;char *tmp_img;int i;grub_disk_addr_t first_sector;@@ -234,8 +233,6 @@ setup (const char *prefix, const char *d + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART); install_bsd_part = (grub_int32_t *) (core_img +GRUB_DISK_SECTOR_SIZE +GRUB_KERNEL_MACHINE_INSTALL_BSD_PART ); - install_prefix = (core_img +GRUB_DISK_SECTOR_SIZE - +GRUB_KERNEL_MACHINE_PREFIX );/* Open the root device and the destination device. */ root_dev =grub_device_open (root);@@ -274,6 +271,40 @@ setup (const char *prefix, const char *dif (dest_dev->disk->id &0x80 )/* Replace the jmp (2 bytes) with double nop's. */ *boot_drive_check =0x9090 ; + +/* If we hardcoded drive as part of prefix, we don't want to +override the current setting. */ +if (*install_dos_part !=-2 ) + { +/* Embed information about the installed location. */ +if (root_dev->disk->partition) + { +if (strcmp (root_dev->disk->partition->partmap->name, +"pc_partition_map" ) ==0 ) + { +struct grub_pc_partition *pcdata = + root_dev->disk->partition->data; + *install_dos_part + =grub_cpu_to_le32 (pcdata->dos_part); + *install_bsd_part + =grub_cpu_to_le32 (pcdata->bsd_part); + } +else if (strcmp (root_dev->disk->partition->partmap->name, +"gpt_partition_map" ) ==0 ) + { + *install_dos_part =grub_cpu_to_le32 (root_dev->disk->partition->index); + *install_bsd_part =grub_cpu_to_le32 (-1 ); + } +else +grub_util_error ("No PC style partitions found" ); + } +else + *install_dos_part = *install_bsd_part =grub_cpu_to_le32 (-1 ); + } + +grub_util_info ("dos partition is %d, bsd partition is %d" , +grub_le_to_cpu32 (*install_dos_part), +grub_le_to_cpu32 (*install_bsd_part));/* If the destination device can have partitions and it is the MBR, try to embed the core image into after the MBR. */ @@ -299,39 +330,6 @@ setup (const char *prefix, const char *d block->len =0 ; block->segment =0 ; -/* Embed information about the installed location. */ -if (must_embed) - *install_dos_part = *install_bsd_part =grub_cpu_to_le32 (-2 ); -else if (root_dev->disk->partition) - { -if (strcmp (root_dev->disk->partition->partmap->name, -"pc_partition_map" ) ==0 ) - { -struct grub_pc_partition *pcdata = - root_dev->disk->partition->data; - *install_dos_part - =grub_cpu_to_le32 (pcdata->dos_part); - *install_bsd_part - =grub_cpu_to_le32 (pcdata->bsd_part); - } -else if (strcmp (root_dev->disk->partition->partmap->name, -"gpt_partition_map" ) ==0 ) - { - *install_dos_part =grub_cpu_to_le32 (root_dev->disk->partition->index); - *install_bsd_part =grub_cpu_to_le32 (-1 ); - } -else -grub_util_error ("No PC style partitions found" ); - } -else - *install_dos_part = *install_bsd_part =grub_cpu_to_le32 (-1 ); - -grub_util_info ("dos partition is %d, bsd partition is %d, prefix is %s" , -grub_le_to_cpu32 (*install_dos_part), -grub_le_to_cpu32 (*install_bsd_part), - prefix); -strcpy (install_prefix, prefix); -/* 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);@@ -362,7 +360,7 @@ setup (const char *prefix, const char *d able_to_embed =0 ;if (must_embed && ! able_to_embed) -grub_util_error ("Can't embed the core image, but this is required when\n" +grub_util_error ("Core image is too big for embedding, but this is required when\n" "the root device is on a RAID array or LVM volume." );/* The core image must be put on a filesystem unfortunately. */ @@ -370,7 +368,7 @@ setup (const char *prefix, const char *d/* Make sure that GRUB reads the identical image as the OS. */ tmp_img =xmalloc (core_size); - core_path =grub_util_get_path (prefix, core_file); + core_path =grub_util_get_path (DEFAULT_DIRECTORY "core.img" , core_file);/* It is a Good Thing to sync two times. */ sync ();@@ -488,38 +486,6 @@ setup (const char *prefix, const char *dthe boot device. */ *root_drive =0xFF ; -/* Embed information about the installed location. */ -if (root_dev->disk->partition) - { -struct grub_pc_partition *pcdata = - root_dev->disk->partition->data; - -if (strcmp (root_dev->disk->partition->partmap->name, -"pc_partition_map" ) ==0 ) - { - *install_dos_part - =grub_cpu_to_le32 (pcdata->dos_part); - *install_bsd_part - =grub_cpu_to_le32 (pcdata->bsd_part); - } -else if (strcmp (root_dev->disk->partition->partmap->name, -"gpt_partition_map" ) ==0 ) - { - *install_dos_part =grub_cpu_to_le32 (root_dev->disk->partition->index); - *install_bsd_part =grub_cpu_to_le32 (-1 ); - } -else -grub_util_error ("No PC style partitions found" ); - } -else - *install_dos_part = *install_bsd_part =grub_cpu_to_le32 (-1 ); - -grub_util_info ("dos partition is %d, bsd partition is %d, prefix is %s" , -grub_le_to_cpu32 (*install_dos_part), -grub_le_to_cpu32 (*install_bsd_part), - prefix); -strcpy (install_prefix, prefix); -/* Write the first two sectors of the core image onto the disk. */ core_path =grub_util_get_path (dir, core_file);grub_util_info ("opening the core image `%s'" , core_path);@@ -608,7 +574,6 @@ main (int argc, char *argv[])char *dir =0 ;char *dev_map =0 ;char *root_dev =0 ; -char *prefix;char *dest_dev;int must_embed =0 ;@@ -714,8 +679,6 @@ main (int argc, char *argv[])/* For simplicity. */ dest_dev =xstrdup (dest_dev); - prefix =grub_get_prefix (dir ? :DEFAULT_DIRECTORY ); -if (root_dev) {char *tmp =get_device_name (root_dev);@@ -740,44 +703,35 @@ main (int argc, char *argv[])#ifdef __linux__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' ) { -char *newprefix; +/* FIXME: we can avoid this on RAID1. */ must_embed =1 ; - - newprefix =xmalloc (1 +strlen (root_dev) +1 +strlen (prefix) +1 ); -sprintf (newprefix,"(%s)%s" , root_dev, prefix); -free (prefix); - prefix = newprefix; } -else if (dest_dev[0 ] =='m' && dest_dev[1 ] =='d' - && dest_dev[2 ] >='0' && dest_dev[2 ] <='9' ) + +if (dest_dev[0 ] =='m' && dest_dev[1 ] =='d' + && dest_dev[2 ] >='0' && dest_dev[2 ] <='9' ) {char **devicelist; -char *raid_prefix;int i; - raid_prefix =xmalloc (1 +strlen (dest_dev) +1 +strlen (prefix) +1 ); - -sprintf (raid_prefix,"(%s)%s" , dest_dev, prefix); - devicelist =grub_util_raid_getmembers (dest_dev);for (i =0 ; devicelist[i]; i++) { -setup (raid_prefix, - dir ? :DEFAULT_DIRECTORY , +setup (dir ? :DEFAULT_DIRECTORY , boot_file ? :DEFAULT_BOOT_FILE , core_file ? :DEFAULT_CORE_FILE , root_dev,grub_util_get_grub_dev (devicelist[i]),1 ); } - -free (raid_prefix); } else#endif /* Do the real work. */ -setup (prefix, - dir ? :DEFAULT_DIRECTORY , +setup (dir ? :DEFAULT_DIRECTORY , boot_file ? :DEFAULT_BOOT_FILE , core_file ? :DEFAULT_CORE_FILE , root_dev, dest_dev, must_embed);@@ -791,7 +745,6 @@ main (int argc, char *argv[])free (dir);free (dev_map);free (root_dev); -free (prefix);free (dest_dev);return 0 ;_______________________________________________
Grub-devel mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/grub-devel
Signature · 5 lines
Robert Millan <GPLv2> I know my rights; I want my phone call! <DRM> What good is a phone call… if you are unable to speak? (as seen on /.)
Re: new patch (boot from LVM / RAID)
Quoted 5 lines · Robert Millan
No comment on this? I can't assure you it's 100% bug-free, but I know it fixes existing problems, and I think it's the right way to do it.
If I don't hear any objection, I'll check it in tomorrow.
In it went :-)
Signature · 5 lines
Robert Millan <GPLv2> I know my rights; I want my phone call! <DRM> What good is a phone call… if you are unable to speak? (as seen on /.)
Re: new patch (boot from LVM / RAID)
In reply to Robert MillanQuoted 5 lines · Robert Millan
No comment on this? I can't assure you it's 100% bug-free, but I know it fixes existing problems, and I think it's the right way to do it.
If I don't hear any objection, I'll check it in tomorrow.
Hi Robert,
For for replying so late, but I was travelling the whole week and did not read my mail during that time. You probably checked it in by now, I will have a look at it as soon as I can and give you feedback.
Kind regards,
Michael