Support grub-probe -t drive

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2011-04-21 12:39:31 +02:00
parent 64516e9df6
commit a10e7a5a89
2 changed files with 58 additions and 18 deletions

View file

@ -640,11 +640,11 @@ grub_guess_root_device (const char *dir)
return os_dev; return os_dev;
} }
static int static char *
grub_util_is_lvm (const char *os_dev) get_dm_uuid (const char *os_dev)
{ {
if ((strncmp ("/dev/mapper/", os_dev, 12) != 0)) if ((strncmp ("/dev/mapper/", os_dev, 12) != 0))
return 0; return NULL;
#ifdef HAVE_DEVICE_MAPPER #ifdef HAVE_DEVICE_MAPPER
{ {
@ -652,17 +652,18 @@ grub_util_is_lvm (const char *os_dev)
uint32_t maj, min; uint32_t maj, min;
struct dm_tree_node *node = NULL; struct dm_tree_node *node = NULL;
const char *node_uuid; const char *node_uuid;
char *ret;
struct stat st; struct stat st;
if (stat (os_dev, &st) < 0) if (stat (os_dev, &st) < 0)
return 0; return NULL;
tree = dm_tree_create (); tree = dm_tree_create ();
if (! tree) if (! tree)
{ {
grub_printf ("Failed to create tree\n"); grub_printf ("Failed to create tree\n");
grub_dprintf ("hostdisk", "dm_tree_create failed\n"); grub_dprintf ("hostdisk", "dm_tree_create failed\n");
return 0; return NULL;
} }
maj = major (st.st_rdev); maj = major (st.st_rdev);
@ -672,7 +673,7 @@ grub_util_is_lvm (const char *os_dev)
{ {
grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n"); grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n");
dm_tree_free (tree); dm_tree_free (tree);
return 0; return NULL;
} }
node = dm_tree_find_node (tree, maj, min); node = dm_tree_find_node (tree, maj, min);
@ -680,39 +681,64 @@ grub_util_is_lvm (const char *os_dev)
{ {
grub_dprintf ("hostdisk", "dm_tree_find_node failed\n"); grub_dprintf ("hostdisk", "dm_tree_find_node failed\n");
dm_tree_free (tree); dm_tree_free (tree);
return 0; return NULL;
} }
node_uuid = dm_tree_node_get_uuid (node); node_uuid = dm_tree_node_get_uuid (node);
if (! node_uuid) if (! node_uuid)
{ {
grub_dprintf ("hostdisk", "%s has no DM uuid\n", os_dev); grub_dprintf ("hostdisk", "%s has no DM uuid\n", os_dev);
dm_tree_free (tree); dm_tree_free (tree);
return 0; return NULL;
}
if (strncmp (node_uuid, "LVM-", 4) != 0)
{
dm_tree_free (tree);
return 0;
} }
ret = grub_strdup (node_uuid);
dm_tree_free (tree); dm_tree_free (tree);
return 1; return ret;
} }
#else #else
return 1; return NULL;
#endif /* HAVE_DEVICE_MAPPER */ #endif /* HAVE_DEVICE_MAPPER */
} }
static enum grub_dev_abstraction_types
grub_util_get_dm_abstraction (const char *os_dev)
{
char *uuid;
uuid = get_dm_uuid (os_dev);
if (uuid == NULL)
return GRUB_DEV_ABSTRACTION_NONE;
if (strncmp (uuid, "LVM-", 4) == 0)
{
grub_free (uuid);
return GRUB_DEV_ABSTRACTION_LVM;
}
if (strncmp (uuid, "CRYPT-LUKS1-", 4) == 0)
{
grub_free (uuid);
return GRUB_DEV_ABSTRACTION_LUKS;
}
grub_free (uuid);
return GRUB_DEV_ABSTRACTION_NONE;
}
int int
grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused))) grub_util_get_dev_abstraction (const char *os_dev __attribute__((unused)))
{ {
#ifdef __linux__ #ifdef __linux__
enum grub_dev_abstraction_types ret;
/* User explicitly claims that this drive is visible by BIOS. */ /* User explicitly claims that this drive is visible by BIOS. */
if (grub_util_biosdisk_is_present (os_dev)) if (grub_util_biosdisk_is_present (os_dev))
return GRUB_DEV_ABSTRACTION_NONE; return GRUB_DEV_ABSTRACTION_NONE;
/* Check for LVM. */ /* Check for LVM and LUKS. */
if (grub_util_is_lvm (os_dev)) ret = grub_util_get_dm_abstraction (os_dev);
return GRUB_DEV_ABSTRACTION_LVM;
if (ret != GRUB_DEV_ABSTRACTION_NONE)
return ret;
/* Check for RAID. */ /* Check for RAID. */
if (!strncmp (os_dev, "/dev/md", 7) && ! grub_util_device_is_mapped (os_dev)) if (!strncmp (os_dev, "/dev/md", 7) && ! grub_util_device_is_mapped (os_dev))
@ -830,6 +856,19 @@ grub_util_get_grub_dev (const char *os_dev)
break; break;
case GRUB_DEV_ABSTRACTION_LUKS:
{
char *uuid, *dash;
uuid = get_dm_uuid (os_dev);
dash = grub_strchr (uuid + sizeof ("CRYPT-LUKS1-") - 1, '-');
if (dash)
*dash = 0;
grub_dev = grub_xasprintf ("luksuuid/%s",
uuid + sizeof ("CRYPT-LUKS1-") - 1);
grub_free (uuid);
}
break;
case GRUB_DEV_ABSTRACTION_RAID: case GRUB_DEV_ABSTRACTION_RAID:
if (os_dev[7] == '_' && os_dev[8] == 'd') if (os_dev[7] == '_' && os_dev[8] == 'd')

View file

@ -25,6 +25,7 @@ enum grub_dev_abstraction_types {
GRUB_DEV_ABSTRACTION_NONE, GRUB_DEV_ABSTRACTION_NONE,
GRUB_DEV_ABSTRACTION_LVM, GRUB_DEV_ABSTRACTION_LVM,
GRUB_DEV_ABSTRACTION_RAID, GRUB_DEV_ABSTRACTION_RAID,
GRUB_DEV_ABSTRACTION_LUKS,
}; };
char *grub_find_device (const char *dir, dev_t dev); char *grub_find_device (const char *dir, dev_t dev);