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