#ifdef GRUB_UTIL
#include <grub/emu/misc.h>
+#include <grub/emu/hostdisk.h>
#endif
GRUB_MOD_LICENSE ("GPLv3+");
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);
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);
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;
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)
{
#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)
{
}
#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)
{