static int virNetSocketForkDaemon(const char *binary) { int ret; virCommandPtr cmd = virCommandNewArgList(binary, "--timeout=30", NULL); virCommandAddEnvPassCommon(cmd); virCommandClearCaps(cmd); virCommandDaemonize(cmd); ret = virCommandRun(cmd, NULL); virCommandFree(cmd); return ret; }
int qemuCapsProbeCPUModels(const char *qemu, virBitmapPtr qemuCaps, const char *arch, unsigned int *count, const char ***cpus) { char *output = NULL; int ret = -1; qemuCapsParseCPUModels parse; virCommandPtr cmd; if (count) *count = 0; if (cpus) *cpus = NULL; if (STREQ(arch, "i686") || STREQ(arch, "x86_64")) parse = qemuCapsParseX86Models; else if (STREQ(arch, "ppc64")) parse = qemuCapsParsePPCModels; else { VIR_DEBUG("don't know how to parse %s CPU models", arch); return 0; } cmd = virCommandNewArgList(qemu, "-cpu", "?", NULL); if (qemuCapsGet(qemuCaps, QEMU_CAPS_NODEFCONFIG)) virCommandAddArg(cmd, "-nodefconfig"); virCommandAddEnvPassCommon(cmd); virCommandSetOutputBuffer(cmd, &output); virCommandClearCaps(cmd); if (virCommandRun(cmd, NULL) < 0) goto cleanup; if (parse(output, count, cpus) < 0) goto cleanup; ret = 0; cleanup: VIR_FREE(output); virCommandFree(cmd); return ret; }
int qemuCapsProbeMachineTypes(const char *binary, virCapsGuestMachinePtr **machines, int *nmachines) { char *output; int ret = -1; virCommandPtr cmd; int status; /* Make sure the binary we are about to try exec'ing exists. * Technically we could catch the exec() failure, but that's * in a sub-process so it's hard to feed back a useful error. */ if (!virFileIsExecutable(binary)) { virReportSystemError(errno, _("Cannot find QEMU binary %s"), binary); return -1; } cmd = virCommandNewArgList(binary, "-M", "?", NULL); virCommandAddEnvPassCommon(cmd); virCommandSetOutputBuffer(cmd, &output); virCommandClearCaps(cmd); /* Ignore failure from older qemu that did not understand '-M ?'. */ if (virCommandRun(cmd, &status) < 0) goto cleanup; if (qemuCapsParseMachineTypesStr(output, machines, nmachines) < 0) goto cleanup; ret = 0; cleanup: VIR_FREE(output); virCommandFree(cmd); return ret; }
/* * Constructs a argv suitable for launching uml with config defined * for a given virtual machine. */ virCommandPtr umlBuildCommandLine(virConnectPtr conn, struct uml_driver *driver, virDomainObjPtr vm) { size_t i, j; virCommandPtr cmd; cmd = virCommandNew(vm->def->os.kernel); virCommandAddEnvPassCommon(cmd); //virCommandAddArgPair(cmd, "con0", "fd:0,fd:1"); virCommandAddArgFormat(cmd, "mem=%lluK", vm->def->mem.cur_balloon); virCommandAddArgPair(cmd, "umid", vm->def->name); virCommandAddArgPair(cmd, "uml_dir", driver->monitorDir); if (vm->def->os.root) virCommandAddArgPair(cmd, "root", vm->def->os.root); for (i = 0; i < vm->def->ndisks; i++) { virDomainDiskDefPtr disk = vm->def->disks[i]; if (!STRPREFIX(disk->dst, "ubd")) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unsupported disk type '%s'"), disk->dst); goto error; } virCommandAddArgPair(cmd, disk->dst, virDomainDiskGetSource(disk)); } for (i = 0; i < vm->def->nnets; i++) { char *ret = umlBuildCommandLineNet(conn, vm->def, vm->def->nets[i], i); if (!ret) goto error; virCommandAddArg(cmd, ret); VIR_FREE(ret); } for (i = 0; i < UML_MAX_CHAR_DEVICE; i++) { virDomainChrDefPtr chr = NULL; char *ret = NULL; for (j = 0; j < vm->def->nconsoles; j++) if (vm->def->consoles[j]->target.port == i) chr = vm->def->consoles[j]; if (chr) ret = umlBuildCommandLineChr(chr, "con", cmd); if (!ret) if (virAsprintf(&ret, "con%zu=none", i) < 0) goto error; virCommandAddArg(cmd, ret); VIR_FREE(ret); } for (i = 0; i < UML_MAX_CHAR_DEVICE; i++) { virDomainChrDefPtr chr = NULL; char *ret = NULL; for (j = 0; j < vm->def->nserials; j++) if (vm->def->serials[j]->target.port == i) chr = vm->def->serials[j]; if (chr) ret = umlBuildCommandLineChr(chr, "ssl", cmd); if (!ret) if (virAsprintf(&ret, "ssl%zu=none", i) < 0) goto error; virCommandAddArg(cmd, ret); VIR_FREE(ret); } if (vm->def->os.cmdline) { char *args, *next_arg; char *cmdline; if (VIR_STRDUP(cmdline, vm->def->os.cmdline) < 0) goto error; args = cmdline; while (*args == ' ') args++; while (*args) { next_arg = umlNextArg(args); virCommandAddArg(cmd, args); args = next_arg; } VIR_FREE(cmdline); } return cmd; error: virCommandFree(cmd); return NULL; }
static int dnsmasqCapsRefreshInternal(dnsmasqCapsPtr caps, bool force) { int ret = -1; struct stat sb; virCommandPtr cmd = NULL; char *help = NULL, *version = NULL, *complete = NULL; if (!caps || caps->noRefresh) return 0; if (stat(caps->binaryPath, &sb) < 0) { virReportSystemError(errno, _("Cannot check dnsmasq binary %s"), caps->binaryPath); return -1; } if (!force && caps->mtime == sb.st_mtime) return 0; caps->mtime = sb.st_mtime; /* Make sure the binary we are about to try exec'ing exists. * Technically we could catch the exec() failure, but that's * in a sub-process so it's hard to feed back a useful error. */ if (!virFileIsExecutable(caps->binaryPath)) { virReportSystemError(errno, _("dnsmasq binary %s is not executable"), caps->binaryPath); goto cleanup; } cmd = virCommandNewArgList(caps->binaryPath, "--version", NULL); virCommandSetOutputBuffer(cmd, &version); virCommandAddEnvPassCommon(cmd); virCommandClearCaps(cmd); if (virCommandRun(cmd, NULL) < 0) { virReportSystemError(errno, _("failed to run '%s --version': %s"), caps->binaryPath, version); goto cleanup; } virCommandFree(cmd); cmd = virCommandNewArgList(caps->binaryPath, "--help", NULL); virCommandSetOutputBuffer(cmd, &help); virCommandAddEnvPassCommon(cmd); virCommandClearCaps(cmd); if (virCommandRun(cmd, NULL) < 0) { virReportSystemError(errno, _("failed to run '%s --help': %s"), caps->binaryPath, help); goto cleanup; } if (virAsprintf(&complete, "%s\n%s", version, help) < 0) goto cleanup; ret = dnsmasqCapsSetFromBuffer(caps, complete); cleanup: virCommandFree(cmd); VIR_FREE(help); VIR_FREE(version); VIR_FREE(complete); return ret; }
/** * virHookCall: * @driver: the driver number (from virHookDriver enum) * @id: an id for the object '-' if non available for example on daemon hooks * @op: the operation on the id e.g. VIR_HOOK_QEMU_OP_START * @sub_op: a sub_operation, currently unused * @extra: optional string information * @input: extra input given to the script on stdin * @output: optional address of variable to store malloced result buffer * * Implement a hook call, where the external script for the driver is * called with the given information. This is a synchronous call, we wait for * execution completion. If @output is non-NULL, *output is guaranteed to be * allocated after successful virHookCall, and is best-effort allocated after * failed virHookCall; the caller is responsible for freeing *output. * * Returns: 0 if the execution succeeded, 1 if the script was not found or * invalid parameters, and -1 if script returned an error */ int virHookCall(int driver, const char *id, int op, int sub_op, const char *extra, const char *input, char **output) { int ret; int exitstatus; char *path; virCommandPtr cmd; const char *drvstr; const char *opstr; const char *subopstr; if (output) *output = NULL; if ((driver < VIR_HOOK_DRIVER_DAEMON) || (driver >= VIR_HOOK_DRIVER_LAST)) return 1; /* * We cache the availability of the script to minimize impact at * runtime if no script is defined, this is being reset on SIGHUP */ if ((virHooksFound == -1) || ((driver == VIR_HOOK_DRIVER_DAEMON) && (op == VIR_HOOK_DAEMON_OP_RELOAD || op == VIR_HOOK_DAEMON_OP_SHUTDOWN))) virHookInitialize(); if ((virHooksFound & (1 << driver)) == 0) return 1; drvstr = virHookDriverTypeToString(driver); opstr = NULL; switch (driver) { case VIR_HOOK_DRIVER_DAEMON: opstr = virHookDaemonOpTypeToString(op); break; case VIR_HOOK_DRIVER_QEMU: opstr = virHookQemuOpTypeToString(op); break; case VIR_HOOK_DRIVER_LXC: opstr = virHookLxcOpTypeToString(op); break; } if (opstr == NULL) { virHookReportError(VIR_ERR_INTERNAL_ERROR, _("Hook for %s, failed to find operation #%d"), drvstr, op); return 1; } subopstr = virHookSubopTypeToString(sub_op); if (subopstr == NULL) subopstr = "-"; if (extra == NULL) extra = "-"; ret = virBuildPath(&path, LIBVIRT_HOOK_DIR, drvstr); if ((ret < 0) || (path == NULL)) { virHookReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to build path for %s hook"), drvstr); return -1; } cmd = virCommandNewArgList(path, id, opstr, subopstr, extra, NULL); virCommandAddEnvPassCommon(cmd); if (input) virCommandSetInputBuffer(cmd, input); if (output) virCommandSetOutputBuffer(cmd, output); ret = virCommandRun(cmd, &exitstatus); if (ret == 0 && exitstatus != 0) { virHookReportError(VIR_ERR_HOOK_SCRIPT_FAILED, _("Hook script %s %s failed with error code %d"), path, drvstr, exitstatus); ret = -1; } virCommandFree(cmd); VIR_FREE(path); return ret; }
/** * virHookCall: * @driver: the driver number (from virHookDriver enum) * @id: an id for the object '-' if non available for example on daemon hooks * @op: the operation on the id e.g. VIR_HOOK_QEMU_OP_START * @sub_op: a sub_operation, currently unused * @extra: optional string information * @input: extra input given to the script on stdin * @output: optional address of variable to store malloced result buffer * * Implement a hook call, where the external script for the driver is * called with the given information. This is a synchronous call, we wait for * execution completion. If @output is non-NULL, *output is guaranteed to be * allocated after successful virHookCall, and is best-effort allocated after * failed virHookCall; the caller is responsible for freeing *output. * * Returns: 0 if the execution succeeded, 1 if the script was not found or * invalid parameters, and -1 if script returned an error */ int virHookCall(int driver, const char *id, int op, int sub_op, const char *extra, const char *input, char **output) { int ret; char *path; virCommandPtr cmd; const char *drvstr; const char *opstr; const char *subopstr; if (output) *output = NULL; if ((driver < VIR_HOOK_DRIVER_DAEMON) || (driver >= VIR_HOOK_DRIVER_LAST)) return 1; /* * We cache the availability of the script to minimize impact at * runtime if no script is defined, this is being reset on SIGHUP */ if ((virHooksFound == -1) || ((driver == VIR_HOOK_DRIVER_DAEMON) && (op == VIR_HOOK_DAEMON_OP_RELOAD || op == VIR_HOOK_DAEMON_OP_SHUTDOWN))) virHookInitialize(); if ((virHooksFound & (1 << driver)) == 0) return 1; drvstr = virHookDriverTypeToString(driver); opstr = NULL; switch (driver) { case VIR_HOOK_DRIVER_DAEMON: opstr = virHookDaemonOpTypeToString(op); break; case VIR_HOOK_DRIVER_QEMU: opstr = virHookQemuOpTypeToString(op); break; case VIR_HOOK_DRIVER_LXC: opstr = virHookLxcOpTypeToString(op); break; case VIR_HOOK_DRIVER_NETWORK: opstr = virHookNetworkOpTypeToString(op); } if (opstr == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Hook for %s, failed to find operation #%d"), drvstr, op); return 1; } subopstr = virHookSubopTypeToString(sub_op); if (subopstr == NULL) subopstr = "-"; if (extra == NULL) extra = "-"; if (virBuildPath(&path, LIBVIRT_HOOK_DIR, drvstr) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to build path for %s hook"), drvstr); return -1; } VIR_DEBUG("Calling hook opstr=%s subopstr=%s extra=%s", opstr, subopstr, extra); cmd = virCommandNewArgList(path, id, opstr, subopstr, extra, NULL); virCommandAddEnvPassCommon(cmd); if (input) virCommandSetInputBuffer(cmd, input); if (output) virCommandSetOutputBuffer(cmd, output); ret = virCommandRun(cmd, NULL); if (ret < 0) { /* Convert INTERNAL_ERROR into known error. */ virErrorPtr err = virGetLastError(); virReportError(VIR_ERR_HOOK_SCRIPT_FAILED, "%s", err ? err->message : _("unknown error")); } virCommandFree(cmd); VIR_FREE(path); return ret; }