Skip to content

Commit

Permalink
lvm: Updates lvcreate to wipe signatures if supported, fallbacks to o…
Browse files Browse the repository at this point in the history
…ld command if not.

Signed-off-by: tomponline <tomp@tomp.uk>
  • Loading branch information
tomponline committed Mar 26, 2019
1 parent ae6497d commit 99a8edf
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 9 deletions.
33 changes: 26 additions & 7 deletions src/lxc/storage/lvm.c
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down
18 changes: 16 additions & 2 deletions src/lxc/utils.c
Expand Up @@ -1594,7 +1594,7 @@ int lxc_unstack_mountpoint(const char *path, bool lazy)
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];
Expand Down Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions src/lxc/utils.h
Expand Up @@ -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 '/'.
*/
Expand Down

0 comments on commit 99a8edf

Please sign in to comment.