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