mrc0mmand / rpms / libguestfs

Forked from rpms/libguestfs 3 years ago
Clone

Blame SOURCES/0047-daemon-Move-lvmetad-to-early-in-the-appliance-boot-p.patch

e9bfca
From 3ad6840403edac13249d373d29c7d1f72b35c8b0 Mon Sep 17 00:00:00 2001
e9bfca
From: "Richard W.M. Jones" <rjones@redhat.com>
e9bfca
Date: Thu, 24 May 2018 10:24:25 +0100
e9bfca
Subject: [PATCH] daemon: Move lvmetad to early in the appliance boot process.
e9bfca
MIME-Version: 1.0
e9bfca
Content-Type: text/plain; charset=UTF-8
e9bfca
Content-Transfer-Encoding: 8bit
e9bfca
e9bfca
When the daemon starts up it creates a fresh (empty) LVM configuration
e9bfca
and starts up lvmetad (which depends on the LVM configuration).
e9bfca
e9bfca
However this appears to cause problems: Some types of PV seem to
e9bfca
require lvmetad and don't work without it
e9bfca
(https://bugzilla.redhat.com/show_bug.cgi?id=1581810).  If we don't
e9bfca
start lvmetad earlier, the device nodes are not created.
e9bfca
e9bfca
Therefore move the whole initialization step into appliance/init.
e9bfca
e9bfca
Two further changes had to be made:
e9bfca
e9bfca
Now we are using lvmetad all the time, using vgchange is incorrect.
e9bfca
With lvmetad activated early we must use ‘pvscan --cache --activate ay’
e9bfca
to scan all disks for PVs and activate any VGs on them (although the
e9bfca
documentation is complex, confusing and contradictory so I'm not
e9bfca
completely sure about this).
e9bfca
e9bfca
The ‘lvm_system_dir’ local variable in ‘daemon/lvm-filter.c’
e9bfca
previously contained the path of the directory above $LVM_SYSTEM_DIR
e9bfca
(eg. $LVM_SYSTEM_DIR = "/etc/lvm", lvm_system_dir = "/etc").  As this
e9bfca
was highly confusing, I have changed it so the local variable and the
e9bfca
environment variable have identical contents.  This involved removing
e9bfca
the ‘lvm/’ component from a couple of paths since it is now included
e9bfca
in the local variable.
e9bfca
e9bfca
(cherry picked from commit dd162d2cd56a2ecf4bcd40a7f463940eaac875b8)
e9bfca
---
e9bfca
 appliance/init      | 11 +++++-
e9bfca
 daemon/daemon.h     |  4 ---
e9bfca
 daemon/guestfsd.c   |  8 -----
e9bfca
 daemon/lvm-filter.c | 81 +++++++++++++--------------------------------
e9bfca
 4 files changed, 33 insertions(+), 71 deletions(-)
e9bfca
e9bfca
diff --git a/appliance/init b/appliance/init
e9bfca
index 1cd264e08..471d83cae 100755
e9bfca
--- a/appliance/init
e9bfca
+++ b/appliance/init
e9bfca
@@ -130,9 +130,17 @@ echo nameserver 169.254.2.3 > /etc/resolv.conf
e9bfca
 # Scan for MDs but don't run arrays unless all expected drives are present
e9bfca
 mdadm -As --auto=yes --no-degraded
e9bfca
 
e9bfca
+# Set up a clean LVM environment.
e9bfca
+# Empty LVM configuration file means "all defaults".
e9bfca
+mkdir -p /tmp/lvm
e9bfca
+touch /tmp/lvm/lvm.conf
e9bfca
+LVM_SYSTEM_DIR=/tmp/lvm
e9bfca
+export LVM_SYSTEM_DIR
e9bfca
+lvmetad
e9bfca
+
e9bfca
 # Scan for LVM.
e9bfca
 modprobe dm_mod ||:
e9bfca
-lvm vgchange -aay --sysinit
e9bfca
+lvm pvscan --cache --activate ay
e9bfca
 
e9bfca
 # Scan for MDs and run all found arrays even they are in degraded state
e9bfca
 mdadm -As --auto=yes --run
e9bfca
@@ -146,6 +154,7 @@ if test "$guestfs_verbose" = 1 && test "$guestfs_boot_analysis" != 1; then
e9bfca
     ls -lR /dev
e9bfca
     cat /proc/mounts
e9bfca
     cat /proc/mdstat
e9bfca
+    lvm config
e9bfca
     lvm pvs
e9bfca
     lvm vgs
e9bfca
     lvm lvs
e9bfca
diff --git a/daemon/daemon.h b/daemon/daemon.h
e9bfca
index 7958ba781..faaf1237e 100644
e9bfca
--- a/daemon/daemon.h
e9bfca
+++ b/daemon/daemon.h
e9bfca
@@ -249,10 +249,6 @@ extern char *get_blkid_tag (const char *device, const char *tag);
e9bfca
 /* lvm.c */
e9bfca
 extern int lv_canonical (const char *device, char **ret);
e9bfca
 
e9bfca
-/* lvm-filter.c */
e9bfca
-extern void clean_lvm_config (void);
e9bfca
-extern void start_lvmetad (void);
e9bfca
-
e9bfca
 /* zero.c */
e9bfca
 extern void wipe_device_before_mkfs (const char *device);
e9bfca
 
e9bfca
diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c
e9bfca
index 68d3de2ec..ae428e573 100644
e9bfca
--- a/daemon/guestfsd.c
e9bfca
+++ b/daemon/guestfsd.c
e9bfca
@@ -233,14 +233,6 @@ main (int argc, char *argv[])
e9bfca
   _umask (0);
e9bfca
 #endif
e9bfca
 
e9bfca
-  /* Make a private copy of /etc/lvm so we can change the config (see
e9bfca
-   * daemon/lvm-filter.c).
e9bfca
-   */
e9bfca
-  if (!test_mode) {
e9bfca
-    clean_lvm_config ();
e9bfca
-    start_lvmetad ();
e9bfca
-  }
e9bfca
-
e9bfca
   /* Connect to virtio-serial channel. */
e9bfca
   if (!channel)
e9bfca
     channel = VIRTIO_SERIAL_CHANNEL;
e9bfca
diff --git a/daemon/lvm-filter.c b/daemon/lvm-filter.c
e9bfca
index ad85a7cc4..9d877c104 100644
e9bfca
--- a/daemon/lvm-filter.c
e9bfca
+++ b/daemon/lvm-filter.c
e9bfca
@@ -36,71 +36,36 @@
e9bfca
 #include "daemon.h"
e9bfca
 #include "actions.h"
e9bfca
 
e9bfca
-/* This runs during daemon start up and creates a fresh LVM
e9bfca
- * configuration which we can modify as we desire.  LVM allows
e9bfca
- * configuration to be completely empty (meaning "all defaults").
e9bfca
- *
e9bfca
- * The final directory layout is:
e9bfca
- *
e9bfca
- *   /tmp/lvmXXXXXX                 (lvm_system_dir set to this)
e9bfca
- *   /tmp/lvmXXXXXX/lvm             ($LVM_SYSTEM_DIR set to this)
e9bfca
- *   /tmp/lvmXXXXXX/lvm/lvm.conf    (configuration file - initially empty)
e9bfca
- */
e9bfca
-static char lvm_system_dir[] = "/tmp/lvmXXXXXX";
e9bfca
-
e9bfca
-static void rm_lvm_system_dir (void);
e9bfca
 static void debug_lvm_config (void);
e9bfca
 
e9bfca
-void
e9bfca
-clean_lvm_config (void)
e9bfca
-{
e9bfca
-  char env[64], conf[64];
e9bfca
-  FILE *fp;
e9bfca
-
e9bfca
-  if (mkdtemp (lvm_system_dir) == NULL)
e9bfca
-    error (EXIT_FAILURE, errno, "mkdtemp: %s", lvm_system_dir);
e9bfca
-
e9bfca
-  snprintf (env, sizeof env, "%s/lvm", lvm_system_dir);
e9bfca
-  mkdir (env, 0755);
e9bfca
-  snprintf (conf, sizeof conf, "%s/lvm/lvm.conf", lvm_system_dir);
e9bfca
-  fp = fopen (conf, "w");
e9bfca
-  if (fp == NULL) {
e9bfca
-    perror ("clean_lvm_config: cannot create empty lvm.conf");
e9bfca
-    exit (EXIT_FAILURE);
e9bfca
-  }
e9bfca
-  fclose (fp);
e9bfca
-
e9bfca
-  /* Set environment variable so we use the clean configuration. */
e9bfca
-  setenv ("LVM_SYSTEM_DIR", env, 1);
e9bfca
-
e9bfca
-  /* Set a handler to remove the temporary directory at exit. */
e9bfca
-  atexit (rm_lvm_system_dir);
e9bfca
+/* Read LVM_SYSTEM_DIR environment variable, or set it to a default
e9bfca
+ * value if the environment variable is not set.
e9bfca
+ */
e9bfca
+static char *lvm_system_dir;
e9bfca
+static void get_lvm_system_dir (void) __attribute__((constructor));
e9bfca
+static void free_lvm_system_dir (void) __attribute__((destructor));
e9bfca
 
e9bfca
-  debug_lvm_config ();
e9bfca
-}
e9bfca
-
e9bfca
-/* Try to run lvmetad, without failing if it couldn't. */
e9bfca
-void
e9bfca
-start_lvmetad (void)
e9bfca
+static void
e9bfca
+get_lvm_system_dir (void)
e9bfca
 {
e9bfca
-  int r;
e9bfca
+  const char *p;
e9bfca
 
e9bfca
-  if (verbose)
e9bfca
-    printf ("%s\n", "lvmetad");
e9bfca
-  r = system ("lvmetad");
e9bfca
-  if (r == -1)
e9bfca
-    perror ("system/lvmetad");
e9bfca
-  else if (!WIFEXITED (r) || WEXITSTATUS (r) != 0)
e9bfca
-    fprintf (stderr, "warning: lvmetad command failed\n");
e9bfca
+  p = getenv ("LVM_SYSTEM_DIR");
e9bfca
+  if (p) {
e9bfca
+    lvm_system_dir = strdup (p);
e9bfca
+    if (lvm_system_dir == NULL) abort ();
e9bfca
+  }
e9bfca
+  if (!lvm_system_dir) {
e9bfca
+    lvm_system_dir = strdup ("/etc/lvm");
e9bfca
+    if (lvm_system_dir == NULL) abort ();
e9bfca
+  }
e9bfca
+  fprintf (stderr, "lvm_system_dir = %s\n", lvm_system_dir);
e9bfca
 }
e9bfca
 
e9bfca
 static void
e9bfca
-rm_lvm_system_dir (void)
e9bfca
+free_lvm_system_dir (void)
e9bfca
 {
e9bfca
-  char cmd[64];
e9bfca
-
e9bfca
-  snprintf (cmd, sizeof cmd, "rm -rf %s", lvm_system_dir);
e9bfca
-  ignore_value (system (cmd));
e9bfca
+  free (lvm_system_dir);
e9bfca
 }
e9bfca
 
e9bfca
 /* Rewrite the 'filter = [ ... ]' line in lvm.conf. */
e9bfca
@@ -112,7 +77,7 @@ set_filter (char *const *filters)
e9bfca
   FILE *fp;
e9bfca
   size_t i, j;
e9bfca
 
e9bfca
-  if (asprintf (&conf, "%s/lvm/lvm.conf", lvm_system_dir) == -1) {
e9bfca
+  if (asprintf (&conf, "%s/lvm.conf", lvm_system_dir) == -1) {
e9bfca
     reply_with_perror ("asprintf");
e9bfca
     return -1;
e9bfca
   }
e9bfca
@@ -177,7 +142,7 @@ static int
e9bfca
 rescan (void)
e9bfca
 {
e9bfca
   char lvm_cache[64];
e9bfca
-  snprintf (lvm_cache, sizeof lvm_cache, "%s/lvm/cache/.cache", lvm_system_dir);
e9bfca
+  snprintf (lvm_cache, sizeof lvm_cache, "%s/cache/.cache", lvm_system_dir);
e9bfca
 
e9bfca
   unlink (lvm_cache);
e9bfca
 
e9bfca
-- 
3d5c2a
2.17.2
e9bfca