/** * virStorageBackendZFSVolModeNeeded: * * Checks if it's necessary to specify 'volmode' (i.e. that * we're working with BSD ZFS implementation). * * Returns 1 if 'volmode' is need, 0 if not needed, -1 on error */ static int virStorageBackendZFSVolModeNeeded(void) { virCommandPtr cmd = NULL; int ret = -1, exit = -1; char *error = NULL; /* 'zfs get' without arguments prints out * usage information to stderr, including * list of supported options, and exits with * exit code 2 */ cmd = virCommandNewArgList(ZFS, "get", NULL); virCommandAddEnvString(cmd, "LC_ALL=C"); virCommandSetErrorBuffer(cmd, &error); ret = virCommandRun(cmd, &exit); if ((ret < 0) || (exit != 2)) { VIR_WARN("Command 'zfs get' either failed " "to run or exited with unexpected status"); goto cleanup; } if (strstr(error, " volmode ")) ret = 1; else ret = 0; cleanup: virCommandFree(cmd); VIR_FREE(error); return ret; }
int virBhyveProbeCaps(unsigned int *caps) { char *binary, *help; virCommandPtr cmd = NULL; int ret = 0, exit; binary = virFindFileInPath("bhyve"); if (binary == NULL) goto out; if (!virFileIsExecutable(binary)) goto out; cmd = virCommandNew(binary); virCommandAddArg(cmd, "-h"); virCommandSetErrorBuffer(cmd, &help); if (virCommandRun(cmd, &exit) < 0) { ret = -1; goto out; } if (strstr(help, "-u:") != NULL) *caps |= BHYVE_CAP_RTC_UTC; out: VIR_FREE(help); virCommandFree(cmd); VIR_FREE(binary); return ret; }
int vmwareExtractVersion(struct vmware_driver *driver) { int ret = -1; virCommandPtr cmd = NULL; char * outbuf = NULL; char *bin = NULL; char *vmwarePath = NULL; if ((vmwarePath = mdir_name(driver->vmrun)) == NULL) goto cleanup; switch (driver->type) { case VMWARE_DRIVER_PLAYER: if (virAsprintf(&bin, "%s/%s", vmwarePath, "vmplayer") < 0) goto cleanup; break; case VMWARE_DRIVER_WORKSTATION: if (virAsprintf(&bin, "%s/%s", vmwarePath, "vmware") < 0) goto cleanup; break; case VMWARE_DRIVER_FUSION: if (virAsprintf(&bin, "%s/%s", vmwarePath, "vmware-vmx") < 0) goto cleanup; break; default: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("invalid driver type for version detection")); goto cleanup; } cmd = virCommandNewArgList(bin, "-v", NULL); virCommandSetOutputBuffer(cmd, &outbuf); virCommandSetErrorBuffer(cmd, &outbuf); if (virCommandRun(cmd, NULL) < 0) goto cleanup; if (vmwareParseVersionStr(driver->type, outbuf, &driver->version) < 0) goto cleanup; ret = 0; cleanup: virCommandFree(cmd); VIR_FREE(outbuf); VIR_FREE(bin); VIR_FREE(vmwarePath); return ret; }
char * virISCSIGetSession(const char *devpath, bool probe) { /* * # iscsiadm --mode session * tcp: [1] 192.168.122.170:3260,1 demo-tgt-b * tcp: [2] 192.168.122.170:3260,1 demo-tgt-a * * Pull out 2nd and 4th fields */ const char *regexes[] = { "^tcp:\\s+\\[(\\S+)\\]\\s+\\S+\\s+(\\S+).*$" }; int vars[] = { 2, }; struct virISCSISessionData cbdata = { .session = NULL, .devpath = devpath, }; char *error = NULL; int exitstatus = 0; virCommandPtr cmd = virCommandNewArgList(ISCSIADM, "--mode", "session", NULL); virCommandSetErrorBuffer(cmd, &error); if (virCommandRunRegex(cmd, 1, regexes, vars, virISCSIExtractSession, &cbdata, NULL, &exitstatus) < 0) goto cleanup; if (cbdata.session == NULL && !probe) virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find iscsiadm session: %s"), NULLSTR(error)); cleanup: VIR_FREE(error); virCommandFree(cmd); return cbdata.session; }
/* * qemuTPMEmulatorStop * @swtpmStateDir: A directory where the socket is located * @shortName: short and unique name of the domain * * Gracefully stop the swptm */ static void qemuTPMEmulatorStop(const char *swtpmStateDir, const char *shortName) { virCommandPtr cmd; char *pathname; char *errbuf = NULL; if (qemuTPMEmulatorInit() < 0) return; if (!(pathname = qemuTPMCreateEmulatorSocket(swtpmStateDir, shortName))) return; if (!virFileExists(pathname)) goto cleanup; cmd = virCommandNew(swtpm_ioctl); if (!cmd) goto cleanup; virCommandAddArgList(cmd, "--unix", pathname, "-s", NULL); virCommandSetErrorBuffer(cmd, &errbuf); ignore_value(virCommandRun(cmd, NULL)); virCommandFree(cmd); /* clean up the socket */ unlink(pathname); cleanup: VIR_FREE(pathname); VIR_FREE(errbuf); }
/** * qemuCreateInBridgePortWithHelper: * @cfg: the configuration object in which the helper name is looked up * @brname: the bridge name * @ifname: the returned interface name * @macaddr: the returned MAC address * @tapfd: file descriptor return value for the new tap device * @flags: OR of virNetDevTapCreateFlags: * VIR_NETDEV_TAP_CREATE_VNET_HDR * - Enable IFF_VNET_HDR on the tap device * * This function creates a new tap device on a bridge using an external * helper. The final name for the bridge will be stored in @ifname. * * Returns 0 in case of success or -1 on failure */ static int qemuCreateInBridgePortWithHelper(virQEMUDriverConfigPtr cfg, const char *brname, char **ifname, int *tapfd, unsigned int flags) { virCommandPtr cmd; char *errbuf = NULL, *cmdstr = NULL; int pair[2] = { -1, -1 }; if ((flags & ~VIR_NETDEV_TAP_CREATE_VNET_HDR) != VIR_NETDEV_TAP_CREATE_IFUP) return -1; if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) < 0) { virReportSystemError(errno, "%s", _("failed to create socket")); return -1; } if (!virFileIsExecutable(cfg->bridgeHelperName)) { virReportSystemError(errno, _("'%s' is not a suitable bridge helper"), cfg->bridgeHelperName); return -1; } cmd = virCommandNew(cfg->bridgeHelperName); if (flags & VIR_NETDEV_TAP_CREATE_VNET_HDR) virCommandAddArgFormat(cmd, "--use-vnet"); virCommandAddArgFormat(cmd, "--br=%s", brname); virCommandAddArgFormat(cmd, "--fd=%d", pair[1]); virCommandSetErrorBuffer(cmd, &errbuf); virCommandDoAsyncIO(cmd); virCommandPassFD(cmd, pair[1], VIR_COMMAND_PASS_FD_CLOSE_PARENT); virCommandClearCaps(cmd); #ifdef CAP_NET_ADMIN virCommandAllowCap(cmd, CAP_NET_ADMIN); #endif if (virCommandRunAsync(cmd, NULL) < 0) { *tapfd = -1; goto cleanup; } do { *tapfd = recvfd(pair[0], 0); } while (*tapfd < 0 && errno == EINTR); if (*tapfd < 0) { char ebuf[1024]; char *errstr = NULL; if (!(cmdstr = virCommandToString(cmd))) goto cleanup; virCommandAbort(cmd); if (errbuf && *errbuf && virAsprintf(&errstr, "\nstderr=%s", errbuf) < 0) goto cleanup; virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: failed to communicate with bridge helper: %s%s"), cmdstr, virStrerror(errno, ebuf, sizeof(ebuf)), errstr ? errstr : ""); VIR_FREE(errstr); goto cleanup; } if (virNetDevTapGetName(*tapfd, ifname) < 0 || virCommandWait(cmd, NULL) < 0) { VIR_FORCE_CLOSE(*tapfd); *tapfd = -1; } cleanup: VIR_FREE(cmdstr); VIR_FREE(errbuf); virCommandFree(cmd); VIR_FORCE_CLOSE(pair[0]); return *tapfd < 0 ? -1 : 0; }
/* * qemuExtTPMStartEmulator: * * @driver: QEMU driver * @def: domain definition * @logCtxt: log context * * Start the external TPM Emulator: * - have the command line built * - start the external TPM Emulator and sync with it before QEMU start */ static int qemuExtTPMStartEmulator(virQEMUDriverPtr driver, virDomainDefPtr def, qemuDomainLogContextPtr logCtxt) { int ret = -1; virCommandPtr cmd = NULL; int exitstatus = 0; char *errbuf = NULL; virQEMUDriverConfigPtr cfg; virDomainTPMDefPtr tpm = def->tpm; char *shortName = virDomainDefGetShortName(def); int cmdret = 0, timeout, rc; pid_t pid; if (!shortName) return -1; cfg = virQEMUDriverGetConfig(driver); /* stop any left-over TPM emulator for this VM */ qemuTPMEmulatorStop(cfg->swtpmStateDir, shortName); if (!(cmd = qemuTPMEmulatorBuildCommand(tpm, def->name, def->uuid, driver->privileged, cfg->swtpm_user, cfg->swtpm_group, cfg->swtpmStateDir, shortName))) goto cleanup; if (qemuExtDeviceLogCommand(logCtxt, cmd, "TPM Emulator") < 0) goto cleanup; virCommandSetErrorBuffer(cmd, &errbuf); if (qemuSecurityStartTPMEmulator(driver, def, cmd, cfg->swtpm_user, cfg->swtpm_group, &exitstatus, &cmdret) < 0) goto cleanup; if (cmdret < 0 || exitstatus != 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not start 'swtpm'. exitstatus: %d, " "error: %s"), exitstatus, errbuf); goto cleanup; } /* check that the swtpm has written its pid into the file */ timeout = 1000; /* ms */ while (timeout > 0) { rc = qemuTPMEmulatorGetPid(cfg->swtpmStateDir, shortName, &pid); if (rc < 0) { timeout -= 50; usleep(50 * 1000); continue; } if (rc == 0 && pid == (pid_t)-1) goto error; break; } if (timeout <= 0) goto error; ret = 0; cleanup: VIR_FREE(shortName); VIR_FREE(errbuf); virCommandFree(cmd); virObjectUnref(cfg); return ret; error: virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("swtpm failed to start")); goto cleanup; }