Add lost lvm/ prefix. Autoadd lvm subdevices.

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-04-22 02:46:36 +02:00
parent c0c837c10b
commit 65b4742cd7
3 changed files with 111 additions and 30 deletions

View file

@ -26,6 +26,7 @@
#ifdef GRUB_UTIL #ifdef GRUB_UTIL
#include <grub/emu/misc.h> #include <grub/emu/misc.h>
#include <grub/emu/hostdisk.h>
#endif #endif
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -197,6 +198,16 @@ grub_lvm_open (const char *name, grub_disk_t disk,
if (! lv && !scan_depth && if (! lv && !scan_depth &&
pull == (explicit ? GRUB_DISK_PULL_RESCAN : GRUB_DISK_PULL_RESCAN_UNTYPED)) 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_for = name;
scan_depth++; scan_depth++;
grub_device_iterate (&grub_lvm_scan_device); grub_device_iterate (&grub_lvm_scan_device);
@ -685,7 +696,11 @@ grub_lvm_scan_device (const char *name)
s = q - p; s = q - p;
lv->name = grub_strndup (p, s); lv->name = grub_strndup (p, s);
if (!lv->name)
goto lvs_fail;
lv->compatname = grub_malloc (vgname_len + 1 + s + 1); lv->compatname = grub_malloc (vgname_len + 1 + s + 1);
if (!lv->compatname)
goto lvs_fail;
grub_memcpy (lv->compatname, vgname, vgname_len); grub_memcpy (lv->compatname, vgname, vgname_len);
lv->compatname[vgname_len] = '-'; lv->compatname[vgname_len] = '-';
grub_memcpy (lv->compatname + vgname_len + 1, p, s); grub_memcpy (lv->compatname + vgname_len + 1, p, s);
@ -696,7 +711,12 @@ grub_lvm_scan_device (const char *name)
char *optr; char *optr;
lv->fullname = grub_malloc (sizeof("lvm/") + 2 * vgname_len lv->fullname = grub_malloc (sizeof("lvm/") + 2 * vgname_len
+ 1 + 2 * s + 1); + 1 + 2 * s + 1);
if (!lv->fullname)
goto lvs_fail;
optr = lv->fullname; optr = lv->fullname;
grub_memcpy (optr, "lvm/", sizeof ("lvm/") - 1);
optr += sizeof ("lvm/") - 1;
for (iptr = vgname; iptr < vgname + vgname_len; iptr++) for (iptr = vgname; iptr < vgname + vgname_len; iptr++)
{ {
*optr++ = *iptr; *optr++ = *iptr;

View file

@ -640,6 +640,56 @@ grub_guess_root_device (const char *dir)
return os_dev; 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 static int
grub_util_is_lvm (const char *os_dev) grub_util_is_lvm (const char *os_dev)
{ {
@ -648,40 +698,13 @@ grub_util_is_lvm (const char *os_dev)
#ifdef HAVE_DEVICE_MAPPER #ifdef HAVE_DEVICE_MAPPER
{ {
struct dm_tree *tree;
uint32_t maj, min;
struct dm_tree_node *node = NULL;
const char *node_uuid; 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; 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); node_uuid = dm_tree_node_get_uuid (node);
if (! node_uuid) if (! node_uuid)
{ {
@ -804,6 +827,43 @@ out:
} }
#endif /* __linux__ */ #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 * char *
grub_util_get_grub_dev (const char *os_dev) grub_util_get_grub_dev (const char *os_dev)
{ {

View 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_present (const char *name);
int grub_util_biosdisk_is_floppy (grub_disk_t disk); int grub_util_biosdisk_is_floppy (grub_disk_t disk);
grub_err_t grub_util_biosdisk_flush (struct grub_disk *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 */ #endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */