]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lvm: Updates lvcreate to wipe signatures if supported, fallbacks to old command if... 2911/head
authortomponline <tomp@tomp.uk>
Tue, 19 Mar 2019 18:14:25 +0000 (18:14 +0000)
committertomponline <tomp@tomp.uk>
Tue, 26 Mar 2019 08:44:28 +0000 (08:44 +0000)
Signed-off-by: tomponline <tomp@tomp.uk>
src/lxc/storage/lvm.c
src/lxc/utils.c
src/lxc/utils.h

index 0c580bb4ae0124ce140844e7059485c998731ee5..e30f821609ad1615c7f80899b352921f20df16e5 100644 (file)
@@ -55,6 +55,7 @@ struct lvcreate_args {
        const char *lv;
        const char *thinpool;
        const char *fstype;
+       bool sigwipe;
 
        /* snapshot specific arguments */
        const char *source_lv;
@@ -76,12 +77,19 @@ static int lvm_create_exec_wrapper(void *data)
 
        (void)setenv("LVM_SUPPRESS_FD_WARNINGS", "1", 1);
        if (args->thinpool)
-               execlp("lvcreate", "lvcreate", "-qq", "--thinpool", args->thinpool,
-                      "-V", args->size, args->vg, "-n", args->lv,
-                      (char *)NULL);
+               if(args->sigwipe)
+                       execlp("lvcreate", "lvcreate", "-Wy", "--yes", "--thinpool", args->thinpool,
+                              "-V", args->size, args->vg, "-n", args->lv, (char *)NULL);
+               else
+                       execlp("lvcreate", "lvcreate", "-qq", "--thinpool", args->thinpool,
+                              "-V", args->size, args->vg, "-n", args->lv, (char *)NULL);
        else
-               execlp("lvcreate", "lvcreate", "-qq", "-L", args->size, args->vg, "-n",
-                      args->lv, (char *)NULL);
+               if(args->sigwipe)
+                       execlp("lvcreate", "lvcreate", "-Wy", "--yes", "-L", args->size, args->vg, "-n",
+                              args->lv, (char *)NULL);
+               else
+                       execlp("lvcreate", "lvcreate", "-qq", "-L", args->size, args->vg, "-n",
+                              args->lv, (char *)NULL);
 
        return -1;
 }
@@ -177,11 +185,22 @@ static int do_lvm_create(const char *path, uint64_t size, const char *thinpool)
        cmd_args.vg = vg;
        cmd_args.lv = lv;
        cmd_args.size = sz;
+       cmd_args.sigwipe = true;
        TRACE("Creating new lvm storage volume \"%s\" on volume group \"%s\" "
              "of size \"%s\"", lv, vg, sz);
-       ret = run_command(cmd_output, sizeof(cmd_output),
+       ret = run_command_status(cmd_output, sizeof(cmd_output),
                          lvm_create_exec_wrapper, (void *)&cmd_args);
-       if (ret < 0) {
+
+       /* If lvcreate is old and doesn't support signature wiping, try again without it.
+        * Test for exit code EINVALID_CMD_LINE(3) of lvcreate command.
+        */
+       if (WIFEXITED(ret) && WEXITSTATUS(ret) == 3) {
+               cmd_args.sigwipe = false;
+               ret = run_command(cmd_output, sizeof(cmd_output),
+                             lvm_create_exec_wrapper, (void *)&cmd_args);
+       }
+
+       if (ret != 0) {
                ERROR("Failed to create logical volume \"%s\": %s", lv,
                      cmd_output);
                free(pathdup);
index 0262c7acd448a571b3423d15b4e277e29aad8d72..ea081c566c842e67036f1f1855c17181c720aea4 100644 (file)
@@ -1594,7 +1594,7 @@ pop_stack:
        return umounts;
 }
 
-int run_command(char *buf, size_t buf_size, int (*child_fn)(void *), void *args)
+int run_command_internal(char *buf, size_t buf_size, int (*child_fn)(void *), void *args, bool wait_status)
 {
        pid_t child;
        int ret, fret, pipefd[2];
@@ -1651,13 +1651,27 @@ int run_command(char *buf, size_t buf_size, int (*child_fn)(void *), void *args)
                        buf[bytes - 1] = '\0';
        }
 
-       fret = wait_for_pid(child);
+       if (wait_status)
+               fret = lxc_wait_for_pid_status(child);
+       else
+               fret = wait_for_pid(child);
+
        /* close the read-end of the pipe */
        close(pipefd[0]);
 
        return fret;
 }
 
+int run_command(char *buf, size_t buf_size, int (*child_fn)(void *), void *args)
+{
+    return run_command_internal(buf, buf_size, child_fn, args, false);
+}
+
+int run_command_status(char *buf, size_t buf_size, int (*child_fn)(void *), void *args)
+{
+    return run_command_internal(buf, buf_size, child_fn, args, true);
+}
+
 bool lxc_nic_exists(char *nic)
 {
 #define __LXC_SYS_CLASS_NET_LEN 15 + IFNAMSIZ + 1
index 286baaabcb917a2210c8229772333e1088272c15..747e14b6ef92ae069d0c49d6aedc8d22988d9927 100644 (file)
@@ -201,6 +201,21 @@ extern int lxc_unstack_mountpoint(const char *path, bool lazy);
 extern int run_command(char *buf, size_t buf_size, int (*child_fn)(void *),
                       void *args);
 
+/*
+ * run_command runs a command and collect it's std{err,out} output in buf, returns exit status.
+ *
+ * @param[out] buf     The buffer where the commands std{err,out] output will be
+ *                     read into. If no output was produced, buf will be memset
+ *                     to 0.
+ * @param[in] buf_size The size of buf. This function will reserve one byte for
+ *                     \0-termination.
+ * @param[in] child_fn The function to be run in the child process. This
+ *                     function must exec.
+ * @param[in] args     Arguments to be passed to child_fn.
+ */
+extern int run_command_status(char *buf, size_t buf_size, int (*child_fn)(void *),
+                      void *args);
+
 /* Concatenate all passed-in strings into one path. Do not fail. If any piece
  * is not prefixed with '/', add a '/'.
  */