Richard W.M. Jones
2018-May-24 10:42 UTC
[Libguestfs] [PATCH] daemon: Move creating of LVM_SYSTEM_DIR into the appliance/init script.
This patch reworks how we start up LVM and lvmetad. It fixes the problem we had converting a guest which had a peculiar LVM configuration: https://bugzilla.redhat.com/show_bug.cgi?id=1581810#c14 However please note I have NOT yet tested it fully. Rich.
Richard W.M. Jones
2018-May-24 10:42 UTC
[Libguestfs] [PATCH] daemon: Move creating of LVM_SYSTEM_DIR into the appliance/init script.
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
Seemingly Similar Threads
- [PATCH 0/2] daemon: Reimplement handling of lvm.conf and filters.
- [PATCH v2] daemon: Move lvmetad to early in the appliance boot process.
- [PATCH v2 0/4] Improve LVM handling in the appliance
- [PATCH 0/5] Improve LVM handling in the appliance
- [PATCH] daemon: copy entire lvm directory