From 49818a594a0d4b19761d72bc9fb3e8092fde3b53 Mon Sep 17 00:00:00 2001 From: Vladimir 'phcoder' Serbinenko Date: Thu, 11 Apr 2013 00:08:27 +0200 Subject: [PATCH] Fix missing PVs if they don't contain "interesting" LV. Closes #38677. Fix few warining messages and leaks while on it. --- ChangeLog | 5 +++ grub-core/disk/diskfilter.c | 12 +----- grub-core/kern/emu/hostdisk.c | 4 +- util/getroot.c | 79 +++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index fd9c082cd..602fc9b3f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-04-11 Vladimir Serbinenko + + Fix missing PVs if they don't contain "interesting" LV. Closes #38677. + Fix few warining messages and leaks while on it. + 2013-04-09 Andrey Borzenkov * autogen.sh: Use "-h", not "-f", to test for existence of symbolic diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c index 2ff47e911..c4eb97eb7 100644 --- a/grub-core/disk/diskfilter.c +++ b/grub-core/disk/diskfilter.c @@ -199,16 +199,8 @@ scan_disk (const char *name, int accept_diskfilter) scan_depth--; return 0; } - if (scan_disk_partition_iter (disk, 0, (void *) name)) - { - scan_depth--; - return 1; - } - if (grub_partition_iterate (disk, scan_disk_partition_iter, (void *) name)) - { - scan_depth--; - return 1; - } + scan_disk_partition_iter (disk, 0, (void *) name); + grub_partition_iterate (disk, scan_disk_partition_iter, (void *) name); grub_disk_close (disk); scan_depth--; return 0; diff --git a/grub-core/kern/emu/hostdisk.c b/grub-core/kern/emu/hostdisk.c index 62a579bdd..4a5eee094 100644 --- a/grub-core/kern/emu/hostdisk.c +++ b/grub-core/kern/emu/hostdisk.c @@ -431,7 +431,7 @@ grub_util_get_dm_node_linear_info (const char *dev, uint64_t length, start; char *target, *params; char *ptr; - int major, minor; + int major = 0, minor = 0; int first = 1; grub_disk_addr_t partstart = 0; @@ -497,6 +497,8 @@ grub_util_get_dm_node_linear_info (const char *dev, dm_task_destroy (dmt); first = 0; + if (!dm_is_dm_major (major)) + break; } if (first) return 0; diff --git a/util/getroot.c b/util/getroot.c index 654d1e138..f65fd1ec5 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -243,6 +243,13 @@ exec_pipe (char **argv, int *fd) else if (mdadm_pid == 0) { /* Child. */ + + /* Close fd's. */ +#ifdef HAVE_DEVICE_MAPPER + dm_lib_release (); +#endif + grub_diskfilter_fini (); + /* Ensure child is not localised. */ setenv ("LC_ALL", "C", 1); @@ -1315,6 +1322,76 @@ grub_util_get_dev_abstraction (const char *os_dev) return GRUB_DEV_ABSTRACTION_NONE; } +static void +pull_lvm_by_command (const char *os_dev) +{ + char *argv[6]; + int fd; + pid_t pid; + FILE *mdadm; + char *buf = NULL; + size_t len = 0; + char *vgname; + const char *iptr; + char *optr; + + if (strncmp (os_dev, "/dev/mapper/", sizeof ("/dev/mapper/") - 1) + != 0) + return; + + vgname = xmalloc (strlen (os_dev + sizeof ("/dev/mapper/") - 1) + 1); + for (iptr = os_dev + sizeof ("/dev/mapper/") - 1, optr = vgname; *iptr; ) + if (*iptr != '-') + *optr++ = *iptr++; + else if (iptr[0] == '-' && iptr[1] == '-') + { + iptr += 2; + *optr++ = '-'; + } + else + break; + *optr = '\0'; + + /* execvp has inconvenient types, hence the casts. None of these + strings will actually be modified. */ + argv[0] = (char *) "vgs"; + argv[1] = (char *) "--options"; + argv[2] = (char *) "pv_name"; + argv[3] = (char *) "--noheadings"; + argv[4] = vgname; + argv[5] = NULL; + + pid = exec_pipe (argv, &fd); + free (vgname); + + if (!pid) + return; + + /* Parent. Read mdadm's output. */ + mdadm = fdopen (fd, "r"); + if (! mdadm) + { + grub_util_warn (_("Unable to open stream from %s: %s"), + "vgs", strerror (errno)); + goto out; + } + + while (getline (&buf, &len, mdadm) > 0) + { + char *ptr; + for (ptr = buf; ptr < buf + 2 && *ptr == ' '; ptr++); + if (*ptr == '\0') + continue; + *(ptr + strlen (ptr) - 1) = '\0'; + grub_util_pull_device (ptr); + } + +out: + close (fd); + waitpid (pid, NULL, 0); + free (buf); +} + #ifdef __linux__ static char * get_mdadm_uuid (const char *os_dev) @@ -1538,6 +1615,8 @@ grub_util_pull_device (const char *os_dev) break; case GRUB_DEV_ABSTRACTION_LVM: + pull_lvm_by_command (os_dev); + /* Fallthrough in case that lvm-tools are unavailable. */ case GRUB_DEV_ABSTRACTION_LUKS: #ifdef HAVE_DEVICE_MAPPER {