]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Add lost lvm/ prefix. Autoadd lvm subdevices.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 22 Apr 2011 00:46:36 +0000 (02:46 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 22 Apr 2011 00:46:36 +0000 (02:46 +0200)
grub-core/disk/lvm.c
grub-core/kern/emu/getroot.c
include/grub/emu/hostdisk.h

index c430f596deeb43f40132e30c1270652b1ff49e2a..d104be7508d36b3691e6ba8885c760ce184ad4e8 100644 (file)
@@ -26,6 +26,7 @@
 
 #ifdef GRUB_UTIL
 #include <grub/emu/misc.h>
+#include <grub/emu/hostdisk.h>
 #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;
index dd277d705ee575daad5f3b4a42026a63e8e27f5b..474bb42bcea7f2168ec75bcfa54602d0ea2f32ca 100644 (file)
@@ -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)
 {
index 842dff496f8c4462694c70ffa6f5084d38d0b523..803c0f755b1ef1e0bc28145316c388744e49cf4f 100644 (file)
@@ -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 */