const char *lv;
const char *thinpool;
const char *fstype;
+ bool sigwipe;
/* snapshot specific arguments */
const char *source_lv;
(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;
}
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);
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];
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
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 '/'.
*/