/* * Execute and wait for external command */ int exec_cmd(struct cmd_context *cmd, const char *const argv[], int *rstatus) { pid_t pid; int status; char buf[PATH_MAX * 2]; log_verbose("Executing: %s", _verbose_args(argv, buf, sizeof(buf))); if ((pid = fork()) == -1) { log_error("fork failed: %s", strerror(errno)); return 0; } if (!pid) { /* Child */ reset_locking(); dev_close_all(); /* FIXME Fix effect of reset_locking on cache then include this */ /* destroy_toolcontext(cmd); */ /* FIXME Use execve directly */ execvp(argv[0], (char **const) argv); log_sys_error("execvp", argv[0]); _exit(errno); } if (rstatus) *rstatus = -1; /* Parent */ if (wait4(pid, &status, 0, NULL) != pid) { log_error("wait4 child process %u failed: %s", pid, strerror(errno)); return 0; } if (!WIFEXITED(status)) { log_error("Child %u exited abnormally", pid); return 0; } if (WEXITSTATUS(status)) { if (rstatus) { *rstatus = WEXITSTATUS(status); log_verbose("%s failed: %u", argv[0], *rstatus); } else log_error("%s failed: %u", argv[0], WEXITSTATUS(status)); return 0; } if (rstatus) *rstatus = 0; return 1; }
static struct volume_group *_get_vg(struct cmd_context *cmd, const char *vgname) { dev_close_all(); return vg_read_for_update(cmd, vgname, NULL, 0); }