From 65b4742cd70d15d41483582b454f21144b9ba60e Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Fri, 22 Apr 2011 02:46:36 +0200 Subject: [PATCH] Add lost lvm/ prefix. Autoadd lvm subdevices. --- grub-core/disk/lvm.c | 20 ++++++ grub-core/kern/emu/getroot.c | 120 ++++++++++++++++++++++++++--------- include/grub/emu/hostdisk.h | 1 + 3 files changed, 111 insertions(+), 30 deletions(-) diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c index c430f596d..d104be750 100644 --- a/grub-core/disk/lvm.c +++ b/grub-core/disk/lvm.c @@ -26,6 +26,7 @@ #ifdef GRUB_UTIL #include +#include #endif GRUB_MOD_LICENSE ("GPLv3+"); @@ -197,6 +198,16 @@ grub_lvm_open (const char *name, grub_disk_t disk, if (! lv && !scan_depth && pull == (explicit ? GRUB_DISK_PULL_RESCAN : GRUB_DISK_PULL_RESCAN_UNTYPED)) { +#ifdef GRUB_UTIL + if (explicit) + { + char buf[grub_strlen (name) + sizeof ("/dev/mapper/")]; + grub_memcpy (buf, "/dev/mapper/", sizeof ("/dev/mapper/")); + grub_strcpy (buf + sizeof ("/dev/mapper/") - 1, + name + sizeof ("lvm/") - 1); + grub_util_pull_device (buf); + } +#endif scan_for = name; scan_depth++; grub_device_iterate (&grub_lvm_scan_device); @@ -685,7 +696,11 @@ grub_lvm_scan_device (const char *name) s = q - p; lv->name = grub_strndup (p, s); + if (!lv->name) + goto lvs_fail; lv->compatname = grub_malloc (vgname_len + 1 + s + 1); + if (!lv->compatname) + goto lvs_fail; grub_memcpy (lv->compatname, vgname, vgname_len); lv->compatname[vgname_len] = '-'; grub_memcpy (lv->compatname + vgname_len + 1, p, s); @@ -696,7 +711,12 @@ grub_lvm_scan_device (const char *name) char *optr; lv->fullname = grub_malloc (sizeof("lvm/") + 2 * vgname_len + 1 + 2 * s + 1); + if (!lv->fullname) + goto lvs_fail; + optr = lv->fullname; + grub_memcpy (optr, "lvm/", sizeof ("lvm/") - 1); + optr += sizeof ("lvm/") - 1; for (iptr = vgname; iptr < vgname + vgname_len; iptr++) { *optr++ = *iptr; diff --git a/grub-core/kern/emu/getroot.c b/grub-core/kern/emu/getroot.c index dd277d705..474bb42bc 100644 --- a/grub-core/kern/emu/getroot.c +++ b/grub-core/kern/emu/getroot.c @@ -640,6 +640,56 @@ grub_guess_root_device (const char *dir) return os_dev; } +#ifdef HAVE_DEVICE_MAPPER + +static int +grub_util_open_dm (const char *os_dev, struct dm_tree **tree, + struct dm_tree_node **node) +{ + uint32_t maj, min; + struct stat st; + + *node = NULL; + *tree = NULL; + + if ((strncmp ("/dev/mapper/", os_dev, 12) != 0)) + return 0; + + 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); + *tree = NULL; + 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); + *tree = NULL; + return 0; + } + return 1; +} + +#endif + static int grub_util_is_lvm (const char *os_dev) { @@ -648,40 +698,13 @@ grub_util_is_lvm (const char *os_dev) #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; + struct dm_tree *tree; + struct dm_tree_node *node; - if (stat (os_dev, &st) < 0) + if (!grub_util_open_dm (os_dev, &tree, &node)) 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) { @@ -804,6 +827,43 @@ out: } #endif /* __linux__ */ +void +grub_util_pull_device (const char *os_dev) +{ + switch (grub_util_get_dev_abstraction (os_dev)) + { + case GRUB_DEV_ABSTRACTION_LVM: +#ifdef HAVE_DEVICE_MAPPER + { + struct dm_tree *tree; + struct dm_tree_node *node; + struct dm_tree_node *child; + void *handle = NULL; + + if (!grub_util_open_dm (os_dev, &tree, &node)) + return; + + while ((child = dm_tree_next_child (&handle, node, 0))) + { + const struct dm_info *dm = dm_tree_node_get_info (child); + char *subdev; + if (!dm) + continue; + subdev = grub_find_device ("/dev", makedev (dm->major, dm->minor)); + if (subdev) + grub_util_pull_device (subdev); + } + dm_tree_free (tree); + return; + } +#endif + + default: /* GRUB_DEV_ABSTRACTION_NONE */ + grub_util_biosdisk_get_grub_dev (os_dev); + return; + } +} + char * grub_util_get_grub_dev (const char *os_dev) { diff --git a/include/grub/emu/hostdisk.h b/include/grub/emu/hostdisk.h index 842dff496..803c0f755 100644 --- a/include/grub/emu/hostdisk.h +++ b/include/grub/emu/hostdisk.h @@ -29,5 +29,6 @@ const char *grub_util_biosdisk_get_osdev (grub_disk_t disk); int grub_util_biosdisk_is_present (const char *name); int grub_util_biosdisk_is_floppy (grub_disk_t disk); grub_err_t grub_util_biosdisk_flush (struct grub_disk *disk); +void grub_util_pull_device (const char *osname); #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */