[Libguestfs] [PATCH] daemon: Move creating of LVM_SYSTEM_DIR into the appliance/init script.

Richard W.M. Jones rjones at redhat.com
Thu May 24 10:42:56 UTC 2018


When the daemon starts up it creates a fresh (empty) LVM configuration
and starts up lvmetad (which depends on the LVM configuration).

However this appears to cause problems: Some types of PV seem to
require lvmetad and don't work without it
(https://bugzilla.redhat.com/show_bug.cgi?id=1581810).  If we don't
start lvmetad earlier, the device nodes are not created.

Therefore move the whole initialization step into appliance/init.

Furthermore, using vgchange is now incorrect.  With lvmetad activated
early we must use ‘pvscan --cache --activate ay’ to scan all disks for
PVs and activate any VGs on them (although the documentation is
complex, confusing and contradictory so I'm not completely sure about
this).
---
 appliance/init      | 11 ++++++++-
 daemon/daemon.h     |  4 ---
 daemon/guestfsd.c   |  8 ------
 daemon/lvm-filter.c | 71 ++++++++---------------------------------------------
 4 files changed, 20 insertions(+), 74 deletions(-)

diff --git a/appliance/init b/appliance/init
index 6a61a8d6e..4f2b55822 100755
--- a/appliance/init
+++ b/appliance/init
@@ -133,9 +133,17 @@ fi
 # Scan for MDs but don't run arrays unless all expected drives are present
 mdadm -As --auto=yes --no-degraded
 
+# Set up a clean LVM environment.
+# Empty LVM configuration file means "all defaults".
+mkdir -p /tmp/lvm
+touch /tmp/lvm/lvm.conf
+LVM_SYSTEM_DIR=/tmp/lvm
+export LVM_SYSTEM_DIR
+lvmetad
+
 # Scan for LVM.
 modprobe dm_mod ||:
-lvm vgchange -aay --sysinit
+lvm pvscan --cache --activate ay
 
 # Scan for MDs and run all found arrays even they are in degraded state
 mdadm -As --auto=yes --run
@@ -149,6 +157,7 @@ if test "$guestfs_verbose" = 1 && test "$guestfs_boot_analysis" != 1; then
     ls -lR /dev
     cat /proc/mounts
     cat /proc/mdstat
+    lvm config
     lvm pvs
     lvm vgs
     lvm lvs
diff --git a/daemon/daemon.h b/daemon/daemon.h
index 7958ba781..faaf1237e 100644
--- a/daemon/daemon.h
+++ b/daemon/daemon.h
@@ -249,10 +249,6 @@ extern char *get_blkid_tag (const char *device, const char *tag);
 /* lvm.c */
 extern int lv_canonical (const char *device, char **ret);
 
-/* lvm-filter.c */
-extern void clean_lvm_config (void);
-extern void start_lvmetad (void);
-
 /* zero.c */
 extern void wipe_device_before_mkfs (const char *device);
 
diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c
index 68d3de2ec..ae428e573 100644
--- a/daemon/guestfsd.c
+++ b/daemon/guestfsd.c
@@ -233,14 +233,6 @@ main (int argc, char *argv[])
   _umask (0);
 #endif
 
-  /* Make a private copy of /etc/lvm so we can change the config (see
-   * daemon/lvm-filter.c).
-   */
-  if (!test_mode) {
-    clean_lvm_config ();
-    start_lvmetad ();
-  }
-
   /* Connect to virtio-serial channel. */
   if (!channel)
     channel = VIRTIO_SERIAL_CHANNEL;
diff --git a/daemon/lvm-filter.c b/daemon/lvm-filter.c
index ad85a7cc4..4764688cf 100644
--- a/daemon/lvm-filter.c
+++ b/daemon/lvm-filter.c
@@ -36,71 +36,20 @@
 #include "daemon.h"
 #include "actions.h"
 
-/* This runs during daemon start up and creates a fresh LVM
- * configuration which we can modify as we desire.  LVM allows
- * configuration to be completely empty (meaning "all defaults").
- *
- * The final directory layout is:
- *
- *   /tmp/lvmXXXXXX                 (lvm_system_dir set to this)
- *   /tmp/lvmXXXXXX/lvm             ($LVM_SYSTEM_DIR set to this)
- *   /tmp/lvmXXXXXX/lvm/lvm.conf    (configuration file - initially empty)
- */
-static char lvm_system_dir[] = "/tmp/lvmXXXXXX";
-
-static void rm_lvm_system_dir (void);
 static void debug_lvm_config (void);
 
-void
-clean_lvm_config (void)
-{
-  char env[64], conf[64];
-  FILE *fp;
-
-  if (mkdtemp (lvm_system_dir) == NULL)
-    error (EXIT_FAILURE, errno, "mkdtemp: %s", lvm_system_dir);
-
-  snprintf (env, sizeof env, "%s/lvm", lvm_system_dir);
-  mkdir (env, 0755);
-  snprintf (conf, sizeof conf, "%s/lvm/lvm.conf", lvm_system_dir);
-  fp = fopen (conf, "w");
-  if (fp == NULL) {
-    perror ("clean_lvm_config: cannot create empty lvm.conf");
-    exit (EXIT_FAILURE);
-  }
-  fclose (fp);
-
-  /* Set environment variable so we use the clean configuration. */
-  setenv ("LVM_SYSTEM_DIR", env, 1);
-
-  /* Set a handler to remove the temporary directory at exit. */
-  atexit (rm_lvm_system_dir);
-
-  debug_lvm_config ();
-}
-
-/* Try to run lvmetad, without failing if it couldn't. */
-void
-start_lvmetad (void)
-{
-  int r;
-
-  if (verbose)
-    printf ("%s\n", "lvmetad");
-  r = system ("lvmetad");
-  if (r == -1)
-    perror ("system/lvmetad");
-  else if (!WIFEXITED (r) || WEXITSTATUS (r) != 0)
-    fprintf (stderr, "warning: lvmetad command failed\n");
-}
-
+/* Read LVM_SYSTEM_DIR environment variable, or set it to a
+ * default value if the environment variable is not set.
+ */
+static const char *lvm_system_dir;
+static void get_lvm_system_dir (void) __attribute__((constructor));
 static void
-rm_lvm_system_dir (void)
+get_lvm_system_dir (void)
 {
-  char cmd[64];
-
-  snprintf (cmd, sizeof cmd, "rm -rf %s", lvm_system_dir);
-  ignore_value (system (cmd));
+  lvm_system_dir = getenv ("LVM_SYSTEM_DIR");
+  if (!lvm_system_dir)
+    lvm_system_dir = "/etc/lvm";
+  fprintf (stderr, "lvm_system_dir = %s\n", lvm_system_dir);
 }
 
 /* Rewrite the 'filter = [ ... ]' line in lvm.conf. */
-- 
2.16.2




More information about the Libguestfs mailing list