Handle the case of partitioned LVM properly.

* grub-core/kern/emu/hostdisk.c (grub_util_get_dm_node_linear_info):
	Stop on meeting LVM, mpath or DMRAID.
	(grub_hostdisk_os_dev_to_grub_drive): Canonicalize os device.
	(read_device_map): Likewise.
	* util/getroot.c (convert_system_partition_to_system_disk): Assume that
	device is full disk rather than erroring out on LVM and similar cases.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2013-09-19 08:48:54 +02:00
parent 5307078763
commit 386701a8fe
3 changed files with 48 additions and 20 deletions

View file

@ -3,6 +3,17 @@
* docs/grub.texi (Networking commands): Add documentation for * docs/grub.texi (Networking commands): Add documentation for
network related commands. network related commands.
2013-09-19 Vladimir Serbinenko <phcoder@gmail.com>
Handle the case of partitioned LVM properly.
* grub-core/kern/emu/hostdisk.c (grub_util_get_dm_node_linear_info):
Stop on meeting LVM, mpath or DMRAID.
(grub_hostdisk_os_dev_to_grub_drive): Canonicalize os device.
(read_device_map): Likewise.
* util/getroot.c (convert_system_partition_to_system_disk): Assume that
device is full disk rather than erroring out on LVM and similar cases.
2013-09-18 Vladimir Serbinenko <phcoder@gmail.com> 2013-09-18 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub-mkconfig_lib.in: Keep supplied pkgdatadir if any. * util/grub-mkconfig_lib.in: Keep supplied pkgdatadir if any.

View file

@ -541,6 +541,7 @@ grub_util_get_dm_node_linear_info (const char *dev,
int major = 0, minor = 0; int major = 0, minor = 0;
int first = 1; int first = 1;
grub_disk_addr_t partstart = 0; grub_disk_addr_t partstart = 0;
const char *node_uuid;
while (1) while (1)
{ {
@ -560,6 +561,15 @@ grub_util_get_dm_node_linear_info (const char *dev,
dm_task_destroy (dmt); dm_task_destroy (dmt);
break; break;
} }
node_uuid = dm_task_get_uuid (dmt);
if (node_uuid && (strncmp (node_uuid, "LVM-", 4) == 0
|| strncmp (node_uuid, "mpath-", 6) == 0
|| strncmp (node_uuid, "DMRAID-", 7) == 0))
{
dm_task_destroy (dmt);
break;
}
next = dm_get_next_target(dmt, next, &start, &length, next = dm_get_next_target(dmt, next, &start, &length,
&target, &params); &target, &params);
if (grub_strcmp (target, "linear") != 0) if (grub_strcmp (target, "linear") != 0)
@ -920,21 +930,32 @@ const char *
grub_hostdisk_os_dev_to_grub_drive (const char *os_disk, int add) grub_hostdisk_os_dev_to_grub_drive (const char *os_disk, int add)
{ {
unsigned int i; unsigned int i;
char *canon;
canon = canonicalize_file_name (os_disk);
if (!canon)
canon = xstrdup (os_disk);
for (i = 0; i < ARRAY_SIZE (map); i++) for (i = 0; i < ARRAY_SIZE (map); i++)
if (! map[i].device) if (! map[i].device)
break; break;
else if (strcmp (map[i].device, os_disk) == 0) else if (strcmp (map[i].device, canon) == 0)
{
free (canon);
return map[i].drive; return map[i].drive;
}
if (!add) if (!add)
{
free (canon);
return NULL; return NULL;
}
if (i == ARRAY_SIZE (map)) if (i == ARRAY_SIZE (map))
/* TRANSLATORS: it refers to the lack of free slots. */ /* TRANSLATORS: it refers to the lack of free slots. */
grub_util_error ("%s", _("device count exceeds limit")); grub_util_error ("%s", _("device count exceeds limit"));
map[i].device = xstrdup (os_disk); map[i].device = canon;
map[i].drive = xmalloc (sizeof ("hostdisk/") + strlen (os_disk)); map[i].drive = xmalloc (sizeof ("hostdisk/") + strlen (os_disk));
strcpy (map[i].drive, "hostdisk/"); strcpy (map[i].drive, "hostdisk/");
strcpy (map[i].drive + sizeof ("hostdisk/") - 1, os_disk); strcpy (map[i].drive + sizeof ("hostdisk/") - 1, os_disk);
@ -1433,19 +1454,13 @@ read_device_map (const char *dev_map)
continue; continue;
} }
#ifdef __linux__
/* On Linux, the devfs uses symbolic links horribly, and that /* On Linux, the devfs uses symbolic links horribly, and that
confuses the interface very much, so use realpath to expand confuses the interface very much, so use realpath to expand
symbolic links. Leave /dev/mapper/ alone, though. */ symbolic links. */
if (strncmp (p, "/dev/mapper/", 12) != 0) map[drive].device = canonicalize_file_name (p);
{ if (! map[drive].device)
map[drive].device = xmalloc (PATH_MAX);
if (! realpath (p, map[drive].device))
grub_util_error (_("failed to get canonical path of `%s'"), p);
}
else
#endif
map[drive].device = xstrdup (p); map[drive].device = xstrdup (p);
if (!map[drive].drive) if (!map[drive].drive)
{ {
char c; char c;
@ -1467,6 +1482,9 @@ read_device_map (const char *dev_map)
*drive_p = c; *drive_p = c;
} }
grub_util_info ("adding `%s' -> `%s' from device.map", map[drive].drive,
map[drive].device);
flush_initial_buffer (map[drive].device); flush_initial_buffer (map[drive].device);
} }

View file

@ -1977,13 +1977,11 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st,
if (! node_uuid) if (! node_uuid)
{ {
grub_util_info ("%s has no DM uuid", path); grub_util_info ("%s has no DM uuid", path);
node = NULL;
goto devmapper_out; goto devmapper_out;
} }
if (strncmp (node_uuid, "LVM-", 4) == 0) if (strncmp (node_uuid, "LVM-", 4) == 0)
{ {
grub_util_info ("%s is an LVM", path); grub_util_info ("%s is an LVM", path);
node = NULL;
goto devmapper_out; goto devmapper_out;
} }
if (strncmp (node_uuid, "mpath-", 6) == 0) if (strncmp (node_uuid, "mpath-", 6) == 0)
@ -1993,7 +1991,6 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st,
grub_util_get_dm_node_linear_info. Multipath disks are not grub_util_get_dm_node_linear_info. Multipath disks are not
linear mappings and must be handled specially. */ linear mappings and must be handled specially. */
grub_util_info ("%s is a multipath disk", path); grub_util_info ("%s is a multipath disk", path);
mapper_name = dm_tree_node_get_name (node);
goto devmapper_out; goto devmapper_out;
} }
if (strncmp (node_uuid, "DMRAID-", 7) != 0) if (strncmp (node_uuid, "DMRAID-", 7) != 0)
@ -2015,7 +2012,6 @@ convert_system_partition_to_system_disk (const char *os_dev, struct stat *st,
return ret; return ret;
} }
node = NULL;
goto devmapper_out; goto devmapper_out;
} }
@ -2527,7 +2523,10 @@ grub_util_biosdisk_is_present (const char *os_dev)
if (stat (os_dev, &st) < 0) if (stat (os_dev, &st) < 0)
return 0; return 0;
return find_system_device (os_dev, &st, 1, 0) != NULL; int ret= (find_system_device (os_dev, &st, 1, 0) != NULL);
grub_util_info ((ret ? "%s is present" : "%s is not present"),
os_dev);
return ret;
} }
char * char *