From: tomponline Date: Tue, 19 Mar 2019 18:14:25 +0000 (+0000) Subject: lvm: Updates lvcreate to wipe signatures if supported, fallbacks to old command if... X-Git-Tag: lxc-3.2.0~111^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=99a8edfc3a616cefeb334fa5d045fd1ab365e32d;p=thirdparty%2Flxc.git lvm: Updates lvcreate to wipe signatures if supported, fallbacks to old command if not. Signed-off-by: tomponline --- diff --git a/src/lxc/storage/lvm.c b/src/lxc/storage/lvm.c index 0c580bb4a..e30f82160 100644 --- a/src/lxc/storage/lvm.c +++ b/src/lxc/storage/lvm.c @@ -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); diff --git a/src/lxc/utils.c b/src/lxc/utils.c index 0262c7acd..ea081c566 100644 --- a/src/lxc/utils.c +++ b/src/lxc/utils.c @@ -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 diff --git a/src/lxc/utils.h b/src/lxc/utils.h index 286baaabc..747e14b6e 100644 --- a/src/lxc/utils.h +++ b/src/lxc/utils.h @@ -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 '/'. */