diff options
author | Tomas Chvatal <scarabeus@gentoo.org> | 2011-09-04 09:17:44 +0000 |
---|---|---|
committer | Tomas Chvatal <scarabeus@gentoo.org> | 2011-09-04 09:17:44 +0000 |
commit | dece88f886c5739eb704e3c484466dbee1f14241 (patch) | |
tree | da63449ac27aea62bf5639b56dd26ee0b7e7aed6 /sys-boot/grub/files/1.99-improve_devmapper.patch | |
parent | Fix compilation on Solaris (diff) | |
download | gentoo-2-dece88f886c5739eb704e3c484466dbee1f14241.tar.gz gentoo-2-dece88f886c5739eb704e3c484466dbee1f14241.tar.bz2 gentoo-2-dece88f886c5739eb704e3c484466dbee1f14241.zip |
Backport patches to fix esissues with non-existant /dev/root. Fixes bug #381491.
(Portage version: 2.2.0_alpha53/cvs/Linux x86_64)
Diffstat (limited to 'sys-boot/grub/files/1.99-improve_devmapper.patch')
-rw-r--r-- | sys-boot/grub/files/1.99-improve_devmapper.patch | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/sys-boot/grub/files/1.99-improve_devmapper.patch b/sys-boot/grub/files/1.99-improve_devmapper.patch new file mode 100644 index 000000000000..5f0a930e3773 --- /dev/null +++ b/sys-boot/grub/files/1.99-improve_devmapper.patch @@ -0,0 +1,279 @@ +--- grub-core/kern/emu/getroot.c 2011-04-21 09:26:29 +0000 ++++ grub-core/kern/emu/getroot.c 2011-05-18 07:35:47 +0000 +@@ -34,6 +34,10 @@ + #include <stdint.h> + #include <grub/util/misc.h> + ++#ifdef HAVE_DEVICE_MAPPER ++# include <libdevmapper.h> ++#endif ++ + #ifdef __GNU__ + #include <hurd.h> + #include <hurd/lookup.h> +@@ -634,32 +638,65 @@ + } + + static int +-grub_util_is_dmraid (const char *os_dev) ++grub_util_is_lvm (const char *os_dev) + { +- if (! strncmp (os_dev, "/dev/mapper/nvidia_", 19)) +- return 1; +- else if (! strncmp (os_dev, "/dev/mapper/isw_", 16)) +- return 1; +- else if (! strncmp (os_dev, "/dev/mapper/hpt37x_", 19)) +- return 1; +- else if (! strncmp (os_dev, "/dev/mapper/hpt45x_", 19)) +- return 1; +- else if (! strncmp (os_dev, "/dev/mapper/via_", 16)) +- return 1; +- else if (! strncmp (os_dev, "/dev/mapper/lsi_", 16)) +- return 1; +- else if (! strncmp (os_dev, "/dev/mapper/pdc_", 16)) +- return 1; +- else if (! strncmp (os_dev, "/dev/mapper/jmicron_", 20)) +- return 1; +- else if (! strncmp (os_dev, "/dev/mapper/asr_", 16)) +- return 1; +- else if (! strncmp (os_dev, "/dev/mapper/sil_", 16)) +- return 1; +- else if (! strncmp (os_dev, "/dev/mapper/ddf1_", 17)) +- return 1; +- +- return 0; ++ if ((strncmp ("/dev/mapper/", os_dev, 12) != 0)) ++ return 0; ++ ++#ifdef HAVE_DEVICE_MAPPER ++ { ++ struct dm_tree *tree; ++ uint32_t maj, min; ++ struct dm_tree_node *node = NULL; ++ const char *node_uuid; ++ struct stat st; ++ ++ if (stat (os_dev, &st) < 0) ++ return 0; ++ ++ tree = dm_tree_create (); ++ if (! tree) ++ { ++ grub_printf ("Failed to create tree\n"); ++ grub_dprintf ("hostdisk", "dm_tree_create failed\n"); ++ return 0; ++ } ++ ++ maj = major (st.st_rdev); ++ min = minor (st.st_rdev); ++ ++ if (! dm_tree_add_dev (tree, maj, min)) ++ { ++ grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n"); ++ dm_tree_free (tree); ++ return 0; ++ } ++ ++ node = dm_tree_find_node (tree, maj, min); ++ if (! node) ++ { ++ grub_dprintf ("hostdisk", "dm_tree_find_node failed\n"); ++ dm_tree_free (tree); ++ return 0; ++ } ++ node_uuid = dm_tree_node_get_uuid (node); ++ if (! node_uuid) ++ { ++ grub_dprintf ("hostdisk", "%s has no DM uuid\n", os_dev); ++ dm_tree_free (tree); ++ return 0; ++ } ++ if (strncmp (node_uuid, "LVM-", 4) != 0) ++ { ++ dm_tree_free (tree); ++ return 0; ++ } ++ dm_tree_free (tree); ++ return 1; ++ } ++#else ++ return 1; ++#endif /* HAVE_DEVICE_MAPPER */ + } + + int +@@ -671,13 +708,11 @@ + return GRUB_DEV_ABSTRACTION_NONE; + + /* Check for LVM. */ +- if (!strncmp (os_dev, "/dev/mapper/", 12) +- && ! grub_util_is_dmraid (os_dev) +- && strncmp (os_dev, "/dev/mapper/mpath", 17) != 0) ++ if (grub_util_is_lvm (os_dev)) + return GRUB_DEV_ABSTRACTION_LVM; + + /* Check for RAID. */ +- if (!strncmp (os_dev, "/dev/md", 7)) ++ if (!strncmp (os_dev, "/dev/md", 7) && ! grub_util_device_is_mapped (os_dev)) + return GRUB_DEV_ABSTRACTION_RAID; + #endif + + +=== modified file 'grub-core/kern/emu/hostdisk.c' +--- grub-core/kern/emu/hostdisk.c 2011-05-09 16:59:35 +0000 ++++ grub-core/kern/emu/hostdisk.c 2011-05-18 07:35:47 +0000 +@@ -24,6 +24,7 @@ + #include <grub/err.h> + #include <grub/emu/misc.h> + #include <grub/emu/hostdisk.h> ++#include <grub/emu/getroot.h> + #include <grub/misc.h> + #include <grub/i18n.h> + #include <grub/list.h> +@@ -331,18 +332,23 @@ + return GRUB_ERR_NONE; + } + ++int ++grub_util_device_is_mapped (const char *dev) ++{ + #ifdef HAVE_DEVICE_MAPPER +-static int +-device_is_mapped (const char *dev) +-{ + struct stat st; + ++ if (!grub_device_mapper_supported ()) ++ return 0; ++ + if (stat (dev, &st) < 0) + return 0; + + return dm_is_dm_major (major (st.st_rdev)); ++#else ++ return 0; ++#endif /* HAVE_DEVICE_MAPPER */ + } +-#endif /* HAVE_DEVICE_MAPPER */ + + #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) + /* FIXME: geom actually gives us the whole container hierarchy. +@@ -418,7 +424,7 @@ + # endif /* !defined(HAVE_DIOCGDINFO) */ + + # ifdef HAVE_DEVICE_MAPPER +- if (grub_device_mapper_supported () && device_is_mapped (dev)) { ++ if (grub_util_device_is_mapped (dev)) { + struct dm_task *task = NULL; + grub_uint64_t start, length; + char *target_type, *params, *space; +@@ -1149,6 +1155,54 @@ + return ret; + } + ++#ifdef HAVE_DEVICE_MAPPER ++static int ++grub_util_get_dm_node_linear_info (const char *dev, ++ int *maj, int *min) ++{ ++ struct dm_task *dmt; ++ void *next = NULL; ++ uint64_t length, start; ++ char *target, *params; ++ char *ptr; ++ int major, minor; ++ ++ dmt = dm_task_create(DM_DEVICE_TABLE); ++ if (!dmt) ++ return 0; ++ ++ if (!dm_task_set_name(dmt, dev)) ++ return 0; ++ dm_task_no_open_count(dmt); ++ if (!dm_task_run(dmt)) ++ return 0; ++ next = dm_get_next_target(dmt, next, &start, &length, ++ &target, ¶ms); ++ if (grub_strcmp (target, "linear") != 0) ++ return 0; ++ major = grub_strtoul (params, &ptr, 10); ++ if (grub_errno) ++ { ++ grub_errno = GRUB_ERR_NONE; ++ return 0; ++ } ++ if (*ptr != ':') ++ return 0; ++ ptr++; ++ minor = grub_strtoul (ptr, 0, 10); ++ if (grub_errno) ++ { ++ grub_errno = GRUB_ERR_NONE; ++ return 0; ++ } ++ if (maj) ++ *maj = major; ++ if (min) ++ *min = minor; ++ return 1; ++} ++#endif ++ + static char * + convert_system_partition_to_system_disk (const char *os_dev, struct stat *st) + { +@@ -1325,9 +1379,39 @@ + node = NULL; + goto devmapper_out; + } +- else if (strncmp (node_uuid, "DMRAID-", 7) != 0) +- { ++ if (strncmp (node_uuid, "LVM-", 4) == 0) ++ { ++ grub_dprintf ("hostdisk", "%s is an LVM\n", path); ++ node = NULL; ++ goto devmapper_out; ++ } ++ if (strncmp (node_uuid, "mpath-", 6) == 0) ++ { ++ /* Multipath partitions have partN-mpath-* UUIDs, and are ++ linear mappings so are handled by ++ grub_util_get_dm_node_linear_info. Multipath disks are not ++ linear mappings and must be handled specially. */ ++ grub_dprintf ("hostdisk", "%s is a multipath disk\n", path); ++ mapper_name = dm_tree_node_get_name (node); ++ goto devmapper_out; ++ } ++ if (strncmp (node_uuid, "DMRAID-", 7) != 0) ++ { ++ int major, minor; ++ const char *node_name; + grub_dprintf ("hostdisk", "%s is not DM-RAID\n", path); ++ ++ if ((node_name = dm_tree_node_get_name (node)) ++ && grub_util_get_dm_node_linear_info (node_name, ++ &major, &minor)) ++ { ++ if (tree) ++ dm_tree_free (tree); ++ free (path); ++ char *ret = grub_find_device (NULL, (major << 8) | minor); ++ return ret; ++ } ++ + node = NULL; + goto devmapper_out; + } + +--- include/grub/emu/misc.h 2010-12-02 13:26:46 +0000 ++++ include/grub/emu/misc.h 2011-05-18 07:35:47 +0000 +@@ -54,6 +54,8 @@ + + char *grub_make_system_path_relative_to_its_root (const char *path) + __attribute__ ((warn_unused_result)); ++int ++grub_util_device_is_mapped (const char *dev); + + void * EXPORT_FUNC(xmalloc) (grub_size_t size) __attribute__ ((warn_unused_result)); + void * EXPORT_FUNC(xrealloc) (void *ptr, grub_size_t size) __attribute__ ((warn_unused_result)); + |