/* * qemuTPMEmulatorInit * * Initialize the Emulator functions by searching for necessary * executables that we will use to start and setup the swtpm */ static int qemuTPMEmulatorInit(void) { if (!swtpm_path) { swtpm_path = virFindFileInPath("swtpm"); if (!swtpm_path) { virReportSystemError(ENOENT, "%s", _("Unable to find 'swtpm' binary in $PATH")); return -1; } if (!virFileIsExecutable(swtpm_path)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("TPM emulator %s is not an executable"), swtpm_path); VIR_FREE(swtpm_path); return -1; } } if (!swtpm_setup) { swtpm_setup = virFindFileInPath("swtpm_setup"); if (!swtpm_setup) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not find 'swtpm_setup' in PATH")); return -1; } if (!virFileIsExecutable(swtpm_setup)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("'%s' is not an executable"), swtpm_setup); VIR_FREE(swtpm_setup); return -1; } } if (!swtpm_ioctl) { swtpm_ioctl = virFindFileInPath("swtpm_ioctl"); if (!swtpm_ioctl) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not find swtpm_ioctl in PATH")); return -1; } if (!virFileIsExecutable(swtpm_ioctl)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("swtpm_ioctl program %s is not an executable"), swtpm_ioctl); VIR_FREE(swtpm_ioctl); return -1; } } return 0; }
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 virBhyveProbeGrubCaps(virBhyveGrubCapsFlags *caps) { char *binary, *help; virCommandPtr cmd; int ret, exit; ret = 0; *caps = 0; cmd = NULL; help = NULL; binary = virFindFileInPath("grub-bhyve"); if (binary == NULL) goto out; if (!virFileIsExecutable(binary)) goto out; cmd = virCommandNew(binary); virCommandAddArg(cmd, "--help"); virCommandSetOutputBuffer(cmd, &help); if (virCommandRun(cmd, &exit) < 0) { ret = -1; goto out; } if (strstr(help, "--cons-dev") != NULL) *caps |= BHYVE_GRUB_CAP_CONSDEV; out: VIR_FREE(help); virCommandFree(cmd); VIR_FREE(binary); return ret; }
virSysinfoDefPtr virSysinfoRead(void) { char *path; virSysinfoDefPtr ret = NULL; char *outbuf = NULL; virCommandPtr cmd; path = virFindFileInPath(SYSINFO_SMBIOS_DECODER); if (path == NULL) { virSmbiosReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to find path for %s binary"), SYSINFO_SMBIOS_DECODER); return NULL; } cmd = virCommandNewArgList(path, "-q", "-t", "0,1,4,17", NULL); VIR_FREE(path); virCommandSetOutputBuffer(cmd, &outbuf); if (virCommandRun(cmd, NULL) < 0) { virSmbiosReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to execute command %s"), path); goto cleanup; } if (VIR_ALLOC(ret) < 0) goto no_memory; ret->type = VIR_SYSINFO_SMBIOS; if (virSysinfoParseBIOS(outbuf, ret) < 0) goto no_memory; if (virSysinfoParseSystem(outbuf, ret) < 0) goto no_memory; ret->nprocessor = 0; ret->processor = NULL; if (virSysinfoParseProcessor(outbuf, ret) < 0) goto no_memory; ret->nmemory = 0; ret->memory = NULL; if (virSysinfoParseMemory(outbuf, ret) < 0) goto no_memory; cleanup: VIR_FREE(outbuf); virCommandFree(cmd); return ret; no_memory: virReportOOMError(); virSysinfoDefFree(ret); ret = NULL; goto cleanup; }
static int virIpTablesOnceInit(void) { virCommandPtr cmd; int status; #if HAVE_FIREWALLD firewall_cmd_path = virFindFileInPath("firewall-cmd"); if (!firewall_cmd_path) { VIR_INFO("firewall-cmd not found on system. " "firewalld support disabled for iptables."); } else { cmd = virCommandNew(firewall_cmd_path); virCommandAddArgList(cmd, "--state", NULL); /* don't log non-zero status */ if (virCommandRun(cmd, &status) < 0 || status != 0) { VIR_INFO("firewall-cmd found but disabled for iptables"); VIR_FREE(firewall_cmd_path); firewall_cmd_path = NULL; } else { VIR_INFO("using firewalld for iptables commands"); } virCommandFree(cmd); } if (firewall_cmd_path) return 0; #endif cmd = virCommandNew(IPTABLES_PATH); virCommandAddArgList(cmd, "-w", "-L", "-n", NULL); /* don't log non-zero status */ if (virCommandRun(cmd, &status) < 0 || status != 0) { VIR_INFO("xtables locking not supported by your iptables"); } else { VIR_INFO("using xtables locking for iptables"); iptables_supports_xlock = true; } virCommandFree(cmd); return 0; }
static int virEbTablesOnceInit(void) { firewall_cmd_path = virFindFileInPath("firewall-cmd"); if (!firewall_cmd_path) { VIR_INFO("firewall-cmd not found on system. " "firewalld support disabled for ebtables."); } else { virCommandPtr cmd = virCommandNew(firewall_cmd_path); int status; virCommandAddArgList(cmd, "--state", NULL); if (virCommandRun(cmd, &status) < 0 || status != 0) { VIR_INFO("firewall-cmd found but disabled for ebtables"); VIR_FREE(firewall_cmd_path); firewall_cmd_path = NULL; } else { VIR_INFO("using firewalld for ebtables commands"); } virCommandFree(cmd); } return 0; }
static int testPrepImages(void) { int ret = EXIT_FAILURE; virCommandPtr cmd = NULL; qemuimg = virFindFileInPath("kvm-img"); if (!qemuimg) qemuimg = virFindFileInPath("qemu-img"); if (!qemuimg) goto skip; if (virAsprintf(&absraw, "%s/raw", datadir) < 0 || virAsprintf(&absqcow2, "%s/qcow2", datadir) < 0 || virAsprintf(&abswrap, "%s/wrap", datadir) < 0 || virAsprintf(&absqed, "%s/qed", datadir) < 0 || virAsprintf(&abslink2, "%s/sub/link2", datadir) < 0) { virReportOOMError(); goto cleanup; } if (virFileMakePath(datadir "/sub") < 0) { fprintf(stderr, "unable to create directory %s\n", datadir "/sub"); goto cleanup; } if (chdir(datadir) < 0) { fprintf(stderr, "unable to test relative backing chains\n"); goto cleanup; } /* I'm lazy enough to use a shell one-liner instead of open/write/close */ virCommandFree(cmd); cmd = virCommandNewArgList("sh", "-c", "printf %1024d 0 > raw", NULL); if (virCommandRun(cmd, NULL) < 0) { fprintf(stderr, "unable to create raw file\n"); goto cleanup; } if (!(canonraw = canonicalize_file_name(absraw))) { virReportOOMError(); goto cleanup; } /* Create a qcow2 wrapping relative raw; later on, we modify its * metadata to test other configurations */ virCommandFree(cmd); cmd = virCommandNewArgList(qemuimg, "create", "-f", "qcow2", "-obacking_file=raw,backing_fmt=raw", "qcow2", NULL); if (virCommandRun(cmd, NULL) < 0) goto skip; /* Make sure our later uses of 'qemu-img rebase' will work */ virCommandFree(cmd); cmd = virCommandNewArgList(qemuimg, "rebase", "-u", "-f", "qcow2", "-F", "raw", "-b", "raw", "qcow2", NULL); if (virCommandRun(cmd, NULL) < 0) goto skip; if (!(canonqcow2 = canonicalize_file_name(absqcow2))) { virReportOOMError(); goto cleanup; } /* Create a second qcow2 wrapping the first, to be sure that we * can correctly avoid insecure probing. */ virCommandFree(cmd); cmd = virCommandNewArgList(qemuimg, "create", "-f", "qcow2", NULL); virCommandAddArgFormat(cmd, "-obacking_file=%s,backing_fmt=qcow2", absqcow2); virCommandAddArg(cmd, "wrap"); if (virCommandRun(cmd, NULL) < 0) goto skip; /* Create a qed file. */ virCommandFree(cmd); cmd = virCommandNewArgList(qemuimg, "create", "-f", "qed", NULL); virCommandAddArgFormat(cmd, "-obacking_file=%s,backing_fmt=raw", absraw); virCommandAddArg(cmd, "qed"); if (virCommandRun(cmd, NULL) < 0) goto skip; /* Create some symlinks in a sub-directory. */ if (symlink("../qcow2", datadir "/sub/link1") < 0 || symlink("../wrap", datadir "/sub/link2") < 0) { fprintf(stderr, "unable to create symlink"); goto cleanup; } ret = 0; cleanup: virCommandFree(cmd); if (ret) testCleanupImages(); return ret; skip: fputs("qemu-img is too old; skipping this test\n", stderr); ret = EXIT_AM_SKIP; goto cleanup; }
static int qemuCapsInitGuest(virCapsPtr caps, virCapsPtr old_caps, const char *hostmachine, const struct qemu_arch_info *info, int hvm) { virCapsGuestPtr guest; int i; int haskvm = 0; int haskqemu = 0; char *kvmbin = NULL; char *binary = NULL; time_t binary_mtime; virCapsGuestMachinePtr *machines = NULL; int nmachines = 0; struct stat st; unsigned int ncpus; virBitmapPtr qemuCaps = NULL; int ret = -1; /* Check for existance of base emulator, or alternate base * which can be used with magic cpu choice */ binary = virFindFileInPath(info->binary); if (binary == NULL || !virFileIsExecutable(binary)) { VIR_FREE(binary); binary = virFindFileInPath(info->altbinary); } /* Can use acceleration for KVM/KQEMU if * - host & guest arches match * Or * - hostarch is x86_64 and guest arch is i686 * The latter simply needs "-cpu qemu32" */ if (STREQ(info->arch, hostmachine) || (STREQ(hostmachine, "x86_64") && STREQ(info->arch, "i686"))) { if (access("/dev/kvm", F_OK) == 0) { const char *const kvmbins[] = { "/usr/libexec/qemu-kvm", /* RHEL */ "qemu-kvm", /* Fedora */ "kvm" }; /* Upstream .spec */ for (i = 0; i < ARRAY_CARDINALITY(kvmbins); ++i) { kvmbin = virFindFileInPath(kvmbins[i]); if (!kvmbin) continue; haskvm = 1; if (!binary) binary = kvmbin; break; } } if (access("/dev/kqemu", F_OK) == 0) haskqemu = 1; } if (!binary) return 0; /* Ignore binary if extracting version info fails */ if (qemuCapsExtractVersionInfo(binary, info->arch, NULL, &qemuCaps) < 0) { ret = 0; goto cleanup; } if (stat(binary, &st) == 0) { binary_mtime = st.st_mtime; } else { char ebuf[1024]; VIR_WARN("Failed to stat %s, most peculiar : %s", binary, virStrerror(errno, ebuf, sizeof(ebuf))); binary_mtime = 0; } if (info->machine) { virCapsGuestMachinePtr machine; if (VIR_ALLOC(machine) < 0) { goto no_memory; } if (!(machine->name = strdup(info->machine))) { VIR_FREE(machine); goto no_memory; } nmachines = 1; if (VIR_ALLOC_N(machines, nmachines) < 0) { VIR_FREE(machine->name); VIR_FREE(machine); goto no_memory; } machines[0] = machine; } else { int probe = 1; if (old_caps && binary_mtime) probe = !qemuCapsGetOldMachines(hvm ? "hvm" : "xen", info->arch, info->wordsize, binary, binary_mtime, old_caps, &machines, &nmachines); if (probe && qemuCapsProbeMachineTypes(binary, &machines, &nmachines) < 0) goto error; } /* We register kvm as the base emulator too, since we can * just give -no-kvm to disable acceleration if required */ if ((guest = virCapabilitiesAddGuest(caps, hvm ? "hvm" : "xen", info->arch, info->wordsize, binary, NULL, nmachines, machines)) == NULL) goto error; machines = NULL; nmachines = 0; guest->arch.defaultInfo.emulator_mtime = binary_mtime; if (caps->host.cpu && qemuCapsProbeCPUModels(binary, NULL, info->arch, &ncpus, NULL) == 0 && ncpus > 0 && !virCapabilitiesAddGuestFeature(guest, "cpuselection", 1, 0)) goto error; if (qemuCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX) && !virCapabilitiesAddGuestFeature(guest, "deviceboot", 1, 0)) goto error; if (hvm) { if (virCapabilitiesAddGuestDomain(guest, "qemu", NULL, NULL, 0, NULL) == NULL) goto error; if (haskqemu && virCapabilitiesAddGuestDomain(guest, "kqemu", NULL, NULL, 0, NULL) == NULL) goto error; if (haskvm) { virCapsGuestDomainPtr dom; if (stat(kvmbin, &st) == 0) { binary_mtime = st.st_mtime; } else { char ebuf[1024]; VIR_WARN("Failed to stat %s, most peculiar : %s", binary, virStrerror(errno, ebuf, sizeof(ebuf))); binary_mtime = 0; } if (!STREQ(binary, kvmbin)) { int probe = 1; if (old_caps && binary_mtime) probe = !qemuCapsGetOldMachines("hvm", info->arch, info->wordsize, kvmbin, binary_mtime, old_caps, &machines, &nmachines); if (probe && qemuCapsProbeMachineTypes(kvmbin, &machines, &nmachines) < 0) goto error; } if ((dom = virCapabilitiesAddGuestDomain(guest, "kvm", kvmbin, NULL, nmachines, machines)) == NULL) { goto error; } machines = NULL; nmachines = 0; dom->info.emulator_mtime = binary_mtime; } } else { if (virCapabilitiesAddGuestDomain(guest, "kvm", NULL, NULL, 0, NULL) == NULL) goto error; } if (info->nflags) { for (i = 0 ; i < info->nflags ; i++) { if (virCapabilitiesAddGuestFeature(guest, info->flags[i].name, info->flags[i].default_on, info->flags[i].toggle) == NULL) goto error; } } ret = 0; cleanup: if (binary == kvmbin) { /* don't double free */ VIR_FREE(binary); } else { VIR_FREE(binary); VIR_FREE(kvmbin); } qemuCapsFree(qemuCaps); return ret; no_memory: virReportOOMError(); error: virCapabilitiesFreeMachines(machines, nmachines); goto cleanup; }
static int testPrepImages(void) { int ret = EXIT_FAILURE; virCommandPtr cmd = NULL; char *buf = NULL; bool compat = false; qemuimg = virFindFileInPath("kvm-img"); if (!qemuimg) qemuimg = virFindFileInPath("qemu-img"); if (!qemuimg) goto skip; /* Clean up from any earlier failed tests */ virFileDeleteTree(datadir); /* See if qemu-img supports '-o compat=xxx'. If so, we force the * use of both v2 and v3 files; if not, it is v2 only but the test * still works. */ cmd = virCommandNewArgList(qemuimg, "create", "-f", "qcow2", "-o?", "/dev/null", NULL); virCommandSetOutputBuffer(cmd, &buf); if (virCommandRun(cmd, NULL) < 0) goto skip; if (strstr(buf, "compat ")) compat = true; VIR_FREE(buf); if (virAsprintf(&absraw, "%s/raw", datadir) < 0 || virAsprintf(&absqcow2, "%s/qcow2", datadir) < 0 || virAsprintf(&abswrap, "%s/wrap", datadir) < 0 || virAsprintf(&absqed, "%s/qed", datadir) < 0 || virAsprintf(&absdir, "%s/dir", datadir) < 0 || virAsprintf(&abslink2, "%s/sub/link2", datadir) < 0) goto cleanup; if (virFileMakePath(datadir "/sub") < 0) { fprintf(stderr, "unable to create directory %s\n", datadir "/sub"); goto cleanup; } if (virFileMakePath(datadir "/dir") < 0) { fprintf(stderr, "unable to create directory %s\n", datadir "/dir"); goto cleanup; } if (!(canondir = canonicalize_file_name(absdir))) { virReportOOMError(); goto cleanup; } if (chdir(datadir) < 0) { fprintf(stderr, "unable to test relative backing chains\n"); goto cleanup; } if (virAsprintf(&buf, "%1024d", 0) < 0 || virFileWriteStr("raw", buf, 0600) < 0) { fprintf(stderr, "unable to create raw file\n"); goto cleanup; } if (!(canonraw = canonicalize_file_name(absraw))) { virReportOOMError(); goto cleanup; } /* Create a qcow2 wrapping relative raw; later on, we modify its * metadata to test other configurations */ virCommandFree(cmd); cmd = virCommandNewArgList(qemuimg, "create", "-f", "qcow2", NULL); virCommandAddArgFormat(cmd, "-obacking_file=raw,backing_fmt=raw%s", compat ? ",compat=0.10" : ""); virCommandAddArg(cmd, "qcow2"); if (virCommandRun(cmd, NULL) < 0) goto skip; /* Make sure our later uses of 'qemu-img rebase' will work */ virCommandFree(cmd); cmd = virCommandNewArgList(qemuimg, "rebase", "-u", "-f", "qcow2", "-F", "raw", "-b", "raw", "qcow2", NULL); if (virCommandRun(cmd, NULL) < 0) goto skip; if (!(canonqcow2 = canonicalize_file_name(absqcow2))) { virReportOOMError(); goto cleanup; } /* Create a second qcow2 wrapping the first, to be sure that we * can correctly avoid insecure probing. */ virCommandFree(cmd); cmd = virCommandNewArgList(qemuimg, "create", "-f", "qcow2", NULL); virCommandAddArgFormat(cmd, "-obacking_file=%s,backing_fmt=qcow2%s", absqcow2, compat ? ",compat=1.1" : ""); virCommandAddArg(cmd, "wrap"); if (virCommandRun(cmd, NULL) < 0) goto skip; if (!(canonwrap = canonicalize_file_name(abswrap))) { virReportOOMError(); goto cleanup; } /* Create a qed file. */ virCommandFree(cmd); cmd = virCommandNewArgList(qemuimg, "create", "-f", "qed", NULL); virCommandAddArgFormat(cmd, "-obacking_file=%s,backing_fmt=raw", absraw); virCommandAddArg(cmd, "qed"); if (virCommandRun(cmd, NULL) < 0) goto skip; if (!(canonqed = canonicalize_file_name(absqed))) { virReportOOMError(); goto cleanup; } #ifdef HAVE_SYMLINK /* Create some symlinks in a sub-directory. */ if (symlink("../qcow2", datadir "/sub/link1") < 0 || symlink("../wrap", datadir "/sub/link2") < 0) { fprintf(stderr, "unable to create symlink"); goto cleanup; } #endif ret = 0; cleanup: VIR_FREE(buf); virCommandFree(cmd); if (ret) testCleanupImages(); return ret; skip: fputs("qemu-img is too old; skipping this test\n", stderr); ret = EXIT_AM_SKIP; goto cleanup; }
static virDrvOpenStatus vmwareOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, unsigned int flags) { struct vmware_driver *driver; char * vmrun = NULL; virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); if (conn->uri == NULL) { /* @TODO accept */ return VIR_DRV_OPEN_DECLINED; } else { if (conn->uri->scheme == NULL || (STRNEQ(conn->uri->scheme, "vmwareplayer") && STRNEQ(conn->uri->scheme, "vmwarews"))) return VIR_DRV_OPEN_DECLINED; /* If server name is given, its for remote driver */ if (conn->uri->server != NULL) return VIR_DRV_OPEN_DECLINED; /* If path isn't /session, then they typoed, so tell them correct path */ if (conn->uri->path == NULL || STRNEQ(conn->uri->path, "/session")) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unexpected VMware URI path '%s', try vmwareplayer:///session or vmwarews:///session"), NULLSTR(conn->uri->path)); return VIR_DRV_OPEN_ERROR; } } /* We now know the URI is definitely for this driver, so beyond * here, don't return DECLINED, always use ERROR */ vmrun = virFindFileInPath(VMRUN); if (vmrun == NULL) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s utility is missing"), VMRUN); return VIR_DRV_OPEN_ERROR; } else { VIR_FREE(vmrun); } if (VIR_ALLOC(driver) < 0) { virReportOOMError(); return VIR_DRV_OPEN_ERROR; } if (virMutexInit(&driver->lock) < 0) goto cleanup; driver->type = STRNEQ(conn->uri->scheme, "vmwareplayer") ? TYPE_WORKSTATION : TYPE_PLAYER; if (!(driver->domains = virDomainObjListNew())) goto cleanup; if (!(driver->caps = vmwareCapsInit())) goto cleanup; driver->caps->privateDataAllocFunc = vmwareDataAllocFunc; driver->caps->privateDataFreeFunc = vmwareDataFreeFunc; if (vmwareLoadDomains(driver) < 0) goto cleanup; if (vmwareExtractVersion(driver) < 0) goto cleanup; conn->privateData = driver; return VIR_DRV_OPEN_SUCCESS; cleanup: vmwareFreeDriver(driver); return VIR_DRV_OPEN_ERROR; };