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; }
static int virStorageBackendZFSBuildPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, unsigned int flags) { virCommandPtr cmd = NULL; size_t i; int ret = -1; virCheckFlags(0, -1); if (pool->def->source.ndevice == 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("missing source devices")); return -1; } cmd = virCommandNewArgList(ZPOOL, "create", pool->def->source.name, NULL); for (i = 0; i < pool->def->source.ndevice; i++) virCommandAddArg(cmd, pool->def->source.devices[i].path); if (virCommandRun(cmd, NULL) < 0) goto cleanup; ret = 0; cleanup: virCommandFree(cmd); return ret; }
static int bhyveBuildConsoleArgStr(const virDomainDef *def, virCommandPtr cmd) { virDomainChrDefPtr chr = NULL; if (!def->nserials) return 0; chr = def->serials[0]; if (chr->source.type != VIR_DOMAIN_CHR_TYPE_NMDM) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("only nmdm console types are supported")); return -1; } /* bhyve supports only two ports: com1 and com2 */ if (chr->target.port > 2) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("only two serial ports are supported")); return -1; } virCommandAddArgList(cmd, "-s", "1,lpc", NULL); virCommandAddArg(cmd, "-l"); virCommandAddArgFormat(cmd, "com%d,%s", chr->target.port + 1, chr->source.data.file.path); 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; }
void virStorageBackendSheepdogAddHostArg(virCommandPtr cmd, virStoragePoolObjPtr pool) { const char *address = "localhost"; int port = 7000; if (pool->def->source.nhost > 0) { if (pool->def->source.hosts[0].name != NULL) address = pool->def->source.hosts[0].name; if (pool->def->source.hosts[0].port) port = pool->def->source.hosts[0].port; } virCommandAddArg(cmd, "-a"); virCommandAddArgFormat(cmd, "%s", address); virCommandAddArg(cmd, "-p"); virCommandAddArgFormat(cmd, "%d", port); }
/* virPolkitAgentCreate: * * Allocate and setup a polkit agent * * Returns a virCommandPtr on success and NULL on failure */ virPolkitAgentPtr virPolkitAgentCreate(void) { virPolkitAgentPtr agent = NULL; int pipe_fd[2] = {-1, -1}; struct pollfd pollfd; int outfd = STDOUT_FILENO; int errfd = STDERR_FILENO; if (!isatty(STDIN_FILENO)) goto error; if (pipe2(pipe_fd, 0) < 0) goto error; if (VIR_ALLOC(agent) < 0) goto error; agent->cmd = virCommandNewArgList(PKTTYAGENT, "--process", NULL); virCommandAddArgFormat(agent->cmd, "%lld", (long long int) getpid()); virCommandAddArg(agent->cmd, "--notify-fd"); virCommandAddArgFormat(agent->cmd, "%d", pipe_fd[1]); virCommandAddArg(agent->cmd, "--fallback"); virCommandSetInputFD(agent->cmd, STDIN_FILENO); virCommandSetOutputFD(agent->cmd, &outfd); virCommandSetErrorFD(agent->cmd, &errfd); virCommandPassFD(agent->cmd, pipe_fd[1], VIR_COMMAND_PASS_FD_CLOSE_PARENT); if (virCommandRunAsync(agent->cmd, NULL) < 0) goto error; pollfd.fd = pipe_fd[0]; pollfd.events = POLLHUP; if (poll(&pollfd, 1, -1) < 0) goto error; return agent; error: VIR_FORCE_CLOSE(pipe_fd[0]); VIR_FORCE_CLOSE(pipe_fd[1]); virPolkitAgentDestroy(agent); return NULL; }
static int ATTRIBUTE_SENTINEL iptablesAddRemoveRule(iptRules *rules, int family, int action, const char *arg, ...) { va_list args; virCommandPtr cmd = NULL; const char *s; cmd = iptablesCommandNew(rules, family, action); virCommandAddArg(cmd, arg); va_start(args, arg); while ((s = va_arg(args, const char *))) virCommandAddArg(cmd, s); va_end(args); return iptablesCommandRunAndFree(cmd); }
virCommandPtr virBhyveProcessBuildBhyveCmd(bhyveConnPtr driver ATTRIBUTE_UNUSED, virDomainObjPtr vm) { /* * /usr/sbin/bhyve -c 2 -m 256 -AI -H -P \ * -s 0:0,hostbridge \ * -s 1:0,virtio-net,tap0 \ * -s 2:0,ahci-hd,${IMG} \ * -S 31,uart,stdio \ * vm0 */ virCommandPtr cmd = virCommandNew(BHYVE); /* CPUs */ virCommandAddArg(cmd, "-c"); virCommandAddArgFormat(cmd, "%d", vm->def->vcpus); /* Memory */ virCommandAddArg(cmd, "-m"); virCommandAddArgFormat(cmd, "%llu", VIR_DIV_UP(vm->def->mem.max_balloon, 1024)); /* Options */ if (vm->def->features[VIR_DOMAIN_FEATURE_ACPI] == VIR_DOMAIN_FEATURE_STATE_ON) virCommandAddArg(cmd, "-A"); /* Create an ACPI table */ if (vm->def->features[VIR_DOMAIN_FEATURE_APIC] == VIR_DOMAIN_FEATURE_STATE_ON) virCommandAddArg(cmd, "-I"); /* Present ioapic to the guest */ /* Clarification about -H and -P flags from Peter Grehan: * -H and -P flags force the guest to exit when it executes IA32 HLT and PAUSE * instructions respectively. * * For the HLT exit, bhyve uses that to infer that the guest is idling and can * be put to sleep until an external event arrives. If this option is not used, * the guest will always use 100% of CPU on the host. * * The PAUSE exit is most useful when there are large numbers of guest VMs running, * since it forces the guest to exit when it spins on a lock acquisition. */ virCommandAddArg(cmd, "-H"); /* vmexit from guest on hlt */ virCommandAddArg(cmd, "-P"); /* vmexit from guest on pause */ virCommandAddArgList(cmd, "-s", "0:0,hostbridge", NULL); /* Devices */ if (bhyveBuildNetArgStr(vm->def, cmd) < 0) goto error; if (bhyveBuildDiskArgStr(vm->def, cmd) < 0) goto error; if (bhyveBuildConsoleArgStr(vm->def, cmd) < 0) goto error; virCommandAddArg(cmd, vm->def->name); return cmd; error: virCommandFree(cmd); return NULL; }
virCommandPtr virBhyveProcessBuildLoadCmd(bhyveConnPtr driver ATTRIBUTE_UNUSED, virDomainObjPtr vm) { virCommandPtr cmd; virDomainDiskDefPtr disk; if (vm->def->ndisks != 1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("domain should have one and only one disk defined")); return NULL; } disk = vm->def->disks[0]; if (disk->device != VIR_DOMAIN_DISK_DEVICE_DISK) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("unsupported disk device")); return NULL; } if (disk->type != VIR_DOMAIN_DISK_TYPE_FILE) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("unsupported disk type")); return NULL; } cmd = virCommandNew(BHYVELOAD); /* Memory */ virCommandAddArg(cmd, "-m"); virCommandAddArgFormat(cmd, "%llu", VIR_DIV_UP(vm->def->mem.max_balloon, 1024)); /* Image path */ virCommandAddArg(cmd, "-d"); virCommandAddArg(cmd, disk->src); /* VM name */ virCommandAddArg(cmd, vm->def->name); return cmd; }
virCommandPtr virBhyveProcessBuildDestroyCmd(bhyveConnPtr driver ATTRIBUTE_UNUSED, virDomainObjPtr vm) { virCommandPtr cmd = virCommandNew(BHYVECTL); virCommandAddArg(cmd, "--destroy"); virCommandAddArgPair(cmd, "--vm", vm->def->name); return cmd; }
/* * Create a new command with a NULL terminated * list of args, starting with the binary to run */ virCommandPtr virCommandNewArgList(const char *binary, ...) { virCommandPtr cmd = virCommandNew(binary); va_list list; const char *arg; if (!cmd || cmd->has_error) return NULL; va_start(list, binary); while ((arg = va_arg(list, const char *)) != NULL) virCommandAddArg(cmd, arg); va_end(list); return cmd; }
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; }
static int bhyveBuildDiskArgStr(const virDomainDef *def, virCommandPtr cmd) { virDomainDiskDefPtr disk; const char *bus_type; if (def->ndisks != 1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("domain should have one and only one disk defined")); return -1; } disk = def->disks[0]; switch (disk->bus) { case VIR_DOMAIN_DISK_BUS_SATA: bus_type = "ahci-hd"; break; case VIR_DOMAIN_DISK_BUS_VIRTIO: bus_type = "virtio-blk"; break; default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("unsupported disk bus type")); return -1; } if (disk->device != VIR_DOMAIN_DISK_DEVICE_DISK) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("unsupported disk device")); return -1; } if (virDomainDiskGetType(disk) != VIR_STORAGE_TYPE_FILE) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("unsupported disk type")); return -1; } virCommandAddArg(cmd, "-s"); virCommandAddArgFormat(cmd, "2:0,%s,%s", bus_type, virDomainDiskGetSource(disk)); return 0; }
static int bhyveBuildDiskArgStr(const virDomainDef *def, virCommandPtr cmd) { virDomainDiskDefPtr disk; if (def->ndisks != 1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("domain should have one and only one disk defined")); return -1; } disk = def->disks[0]; if (disk->bus != VIR_DOMAIN_DISK_BUS_SATA) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("unsupported disk bus type")); return -1; } if (disk->device != VIR_DOMAIN_DISK_DEVICE_DISK) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("unsupported disk device")); return -1; } if (disk->type != VIR_DOMAIN_DISK_TYPE_FILE) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("unsupported disk type")); return -1; } virCommandAddArg(cmd, "-s"); virCommandAddArgFormat(cmd, "2:0,ahci-hd,%s", disk->src); return 0; }
static int virStorageBackendZFSCreateVol(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolObjPtr pool, virStorageVolDefPtr vol) { virCommandPtr cmd = NULL; int ret = -1; int volmode_needed = -1; if (vol->target.format != VIR_STORAGE_FILE_RAW) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("only RAW volumes are supported by this storage pool")); return -1; } if (vol->target.encryption != NULL) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("storage pool does not support encrypted " "volumes")); return -1; } vol->type = VIR_STORAGE_VOL_BLOCK; VIR_FREE(vol->target.path); if (virAsprintf(&vol->target.path, "%s/%s", pool->def->target.path, vol->name) == -1) return -1; if (VIR_STRDUP(vol->key, vol->target.path) < 0) goto cleanup; volmode_needed = virStorageBackendZFSVolModeNeeded(); if (volmode_needed < 0) goto cleanup; /** * $ zfs create -o volmode=dev -V 10240K test/volname * * -o volmode=dev -- we want to get volumes exposed as cdev * devices. If we don't specify that zfs * will lookup vfs.zfs.vol.mode sysctl value * -V -- tells to create a volume with the specified size */ cmd = virCommandNewArgList(ZFS, "create", NULL); if (volmode_needed) virCommandAddArgList(cmd, "-o", "volmode=dev", NULL); virCommandAddArg(cmd, "-V"); virCommandAddArgFormat(cmd, "%lluK", VIR_DIV_UP(vol->target.capacity, 1024)); virCommandAddArgFormat(cmd, "%s/%s", pool->def->source.name, vol->name); if (virCommandRun(cmd, NULL) < 0) goto cleanup; if (virStorageBackendZFSFindVols(pool, vol) < 0) goto cleanup; ret = 0; cleanup: virCommandFree(cmd); return ret; }
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; }
/** * virNetDevOpenvswitchAddPort: * @brname: the bridge name * @ifname: the network interface name * @macaddr: the mac address of the virtual interface * @vmuuid: the Domain UUID that has this interface * @ovsport: the ovs specific fields * * Add an interface to the OVS bridge * * Returns 0 in case of success or -1 in case of failure. */ int virNetDevOpenvswitchAddPort(const char *brname, const char *ifname, const virMacAddr *macaddr, const unsigned char *vmuuid, virNetDevVPortProfilePtr ovsport, virNetDevVlanPtr virtVlan) { int ret = -1; size_t i = 0; virCommandPtr cmd = NULL; char macaddrstr[VIR_MAC_STRING_BUFLEN]; char ifuuidstr[VIR_UUID_STRING_BUFLEN]; char vmuuidstr[VIR_UUID_STRING_BUFLEN]; char *attachedmac_ex_id = NULL; char *ifaceid_ex_id = NULL; char *profile_ex_id = NULL; char *vmid_ex_id = NULL; virBuffer buf = VIR_BUFFER_INITIALIZER; virMacAddrFormat(macaddr, macaddrstr); virUUIDFormat(ovsport->interfaceID, ifuuidstr); virUUIDFormat(vmuuid, vmuuidstr); if (virAsprintf(&attachedmac_ex_id, "external-ids:attached-mac=\"%s\"", macaddrstr) < 0) goto cleanup; if (virAsprintf(&ifaceid_ex_id, "external-ids:iface-id=\"%s\"", ifuuidstr) < 0) goto cleanup; if (virAsprintf(&vmid_ex_id, "external-ids:vm-id=\"%s\"", vmuuidstr) < 0) goto cleanup; if (ovsport->profileID[0] != '\0') { if (virAsprintf(&profile_ex_id, "external-ids:port-profile=\"%s\"", ovsport->profileID) < 0) goto cleanup; } cmd = virCommandNew(OVSVSCTL); virCommandAddArgList(cmd, "--timeout=5", "--", "--if-exists", "del-port", ifname, "--", "add-port", brname, ifname, NULL); if (virtVlan && virtVlan->nTags > 0) { switch (virtVlan->nativeMode) { case VIR_NATIVE_VLAN_MODE_TAGGED: virCommandAddArg(cmd, "vlan_mode=native-tagged"); virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag); break; case VIR_NATIVE_VLAN_MODE_UNTAGGED: virCommandAddArg(cmd, "vlan_mode=native-untagged"); virCommandAddArgFormat(cmd, "tag=%d", virtVlan->nativeTag); break; case VIR_NATIVE_VLAN_MODE_DEFAULT: default: break; } if (virtVlan->trunk) { virBufferAddLit(&buf, "trunk="); /* * Trunk ports have at least one VLAN. Do the first one * outside the "for" loop so we can put a "," at the * start of the for loop if there are more than one VLANs * on this trunk port. */ virBufferAsprintf(&buf, "%d", virtVlan->tag[i]); for (i = 1; i < virtVlan->nTags; i++) { virBufferAddLit(&buf, ","); virBufferAsprintf(&buf, "%d", virtVlan->tag[i]); } if (virBufferCheckError(&buf) < 0) goto cleanup; virCommandAddArg(cmd, virBufferCurrentContent(&buf)); } else if (virtVlan->nTags) { virCommandAddArgFormat(cmd, "tag=%d", virtVlan->tag[0]); } } if (ovsport->profileID[0] == '\0') { virCommandAddArgList(cmd, "--", "set", "Interface", ifname, attachedmac_ex_id, "--", "set", "Interface", ifname, ifaceid_ex_id, "--", "set", "Interface", ifname, vmid_ex_id, "--", "set", "Interface", ifname, "external-ids:iface-status=active", NULL); } else { virCommandAddArgList(cmd, "--", "set", "Interface", ifname, attachedmac_ex_id, "--", "set", "Interface", ifname, ifaceid_ex_id, "--", "set", "Interface", ifname, vmid_ex_id, "--", "set", "Interface", ifname, profile_ex_id, "--", "set", "Interface", ifname, "external-ids:iface-status=active", NULL); } if (virCommandRun(cmd, NULL) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to add port %s to OVS bridge %s"), ifname, brname); goto cleanup; } ret = 0; cleanup: virBufferFreeAndReset(&buf); VIR_FREE(attachedmac_ex_id); VIR_FREE(ifaceid_ex_id); VIR_FREE(vmid_ex_id); VIR_FREE(profile_ex_id); virCommandFree(cmd); return ret; }
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; }
/* * 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 virCommandPtr virLXCProcessBuildControllerCmd(virLXCDriverPtr driver, virDomainObjPtr vm, int nveths, char **veths, int *ttyFDs, size_t nttyFDs, int *files, size_t nfiles, int handshakefd) { size_t i; char *filterstr; char *outputstr; virCommandPtr cmd; virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver); cmd = virCommandNew(vm->def->emulator); /* The controller may call ip command, so we have to retain PATH. */ virCommandAddEnvPassBlockSUID(cmd, "PATH", "/bin:/usr/bin"); virCommandAddEnvFormat(cmd, "LIBVIRT_DEBUG=%d", virLogGetDefaultPriority()); if (virLogGetNbFilters() > 0) { filterstr = virLogGetFilters(); if (!filterstr) { virReportOOMError(); goto cleanup; } virCommandAddEnvPair(cmd, "LIBVIRT_LOG_FILTERS", filterstr); VIR_FREE(filterstr); } if (cfg->log_libvirtd) { if (virLogGetNbOutputs() > 0) { outputstr = virLogGetOutputs(); if (!outputstr) { virReportOOMError(); goto cleanup; } virCommandAddEnvPair(cmd, "LIBVIRT_LOG_OUTPUTS", outputstr); VIR_FREE(outputstr); } } else { virCommandAddEnvFormat(cmd, "LIBVIRT_LOG_OUTPUTS=%d:stderr", virLogGetDefaultPriority()); } virCommandAddArgList(cmd, "--name", vm->def->name, NULL); for (i = 0; i < nttyFDs; i++) { virCommandAddArg(cmd, "--console"); virCommandAddArgFormat(cmd, "%d", ttyFDs[i]); virCommandPassFD(cmd, ttyFDs[i], 0); } for (i = 0; i < nfiles; i++) { virCommandAddArg(cmd, "--passfd"); virCommandAddArgFormat(cmd, "%d", files[i]); virCommandPassFD(cmd, files[i], 0); } virCommandAddArgPair(cmd, "--security", virSecurityManagerGetModel(driver->securityManager)); virCommandAddArg(cmd, "--handshake"); virCommandAddArgFormat(cmd, "%d", handshakefd); virCommandAddArg(cmd, "--background"); for (i = 0; i < nveths; i++) { virCommandAddArgList(cmd, "--veth", veths[i], NULL); } virCommandPassFD(cmd, handshakefd, 0); return cmd; cleanup: virCommandFree(cmd); virObjectUnref(cfg); return NULL; }
/* * qemuTPMEmulatorBuildCommand: * * @tpm: TPM definition * @vmname: The name of the VM * @vmuuid: The UUID of the VM * @privileged: whether we are running in privileged mode * @swtpm_user: The uid for the swtpm to run as (drop privileges to from root) * @swtpm_group: The gid for the swtpm to run as * @swtpmStateDir: the directory where swtpm writes the pid file and creates the * Unix socket * @shortName: the short name of the VM * * Create the virCommand use for starting the emulator * Do some initializations on the way, such as creation of storage * and emulator setup. */ static virCommandPtr qemuTPMEmulatorBuildCommand(virDomainTPMDefPtr tpm, const char *vmname, const unsigned char *vmuuid, bool privileged, uid_t swtpm_user, gid_t swtpm_group, const char *swtpmStateDir, const char *shortName) { virCommandPtr cmd = NULL; bool created = false; char *pidfile; if (qemuTPMCreateEmulatorStorage(tpm->data.emulator.storagepath, &created, swtpm_user, swtpm_group) < 0) return NULL; if (created && qemuTPMEmulatorRunSetup(tpm->data.emulator.storagepath, vmname, vmuuid, privileged, swtpm_user, swtpm_group, tpm->data.emulator.logfile, tpm->version) < 0) goto error; unlink(tpm->data.emulator.source.data.nix.path); cmd = virCommandNew(swtpm_path); if (!cmd) goto error; virCommandClearCaps(cmd); virCommandAddArgList(cmd, "socket", "--daemon", "--ctrl", NULL); virCommandAddArgFormat(cmd, "type=unixio,path=%s,mode=0600", tpm->data.emulator.source.data.nix.path); virCommandAddArg(cmd, "--tpmstate"); virCommandAddArgFormat(cmd, "dir=%s,mode=0600", tpm->data.emulator.storagepath); virCommandAddArg(cmd, "--log"); virCommandAddArgFormat(cmd, "file=%s", tpm->data.emulator.logfile); virCommandSetUID(cmd, swtpm_user); virCommandSetGID(cmd, swtpm_group); switch (tpm->version) { case VIR_DOMAIN_TPM_VERSION_1_2: break; case VIR_DOMAIN_TPM_VERSION_2_0: virCommandAddArg(cmd, "--tpm2"); break; case VIR_DOMAIN_TPM_VERSION_DEFAULT: case VIR_DOMAIN_TPM_VERSION_LAST: break; } if (!(pidfile = qemuTPMEmulatorCreatePidFilename(swtpmStateDir, shortName))) goto error; virCommandAddArg(cmd, "--pid"); virCommandAddArgFormat(cmd, "file=%s", pidfile); VIR_FREE(pidfile); return cmd; error: if (created) qemuTPMDeleteEmulatorStorage(tpm); virCommandFree(cmd); return NULL; }
static int bhyveBuildNetArgStr(const virDomainDef *def, virDomainNetDefPtr net, virCommandPtr cmd, bool dryRun) { char macaddr[VIR_MAC_STRING_BUFLEN]; char *realifname = NULL; char *brname = NULL; int actualType = virDomainNetGetActualType(net); if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) { if (VIR_STRDUP(brname, virDomainNetGetActualBridgeName(net)) < 0) return -1; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Network type %d is not supported"), virDomainNetGetActualType(net)); return -1; } if (!net->ifname || STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) || strchr(net->ifname, '%')) { VIR_FREE(net->ifname); if (VIR_STRDUP(net->ifname, VIR_NET_GENERATED_PREFIX "%d") < 0) { VIR_FREE(brname); return -1; } } if (!dryRun) { if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac, def->uuid, NULL, NULL, 0, virDomainNetGetActualVirtPortProfile(net), virDomainNetGetActualVlan(net), VIR_NETDEV_TAP_CREATE_IFUP | VIR_NETDEV_TAP_CREATE_PERSIST) < 0) { VIR_FREE(net->ifname); VIR_FREE(brname); return -1; } realifname = virNetDevTapGetRealDeviceName(net->ifname); if (realifname == NULL) { VIR_FREE(net->ifname); VIR_FREE(brname); return -1; } VIR_DEBUG("%s -> %s", net->ifname, realifname); /* hack on top of other hack: we need to set * interface to 'UP' again after re-opening to find its * name */ if (virNetDevSetOnline(net->ifname, true) != 0) { VIR_FREE(realifname); VIR_FREE(net->ifname); VIR_FREE(brname); return -1; } } else { if (VIR_STRDUP(realifname, "tap0") < 0) return -1; } virCommandAddArg(cmd, "-s"); virCommandAddArgFormat(cmd, "%d:0,virtio-net,%s,mac=%s", net->info.addr.pci.slot, realifname, virMacAddrFormat(&net->mac, macaddr)); VIR_FREE(realifname); return 0; }
static int bhyveBuildNetArgStr(const virDomainDef *def, virCommandPtr cmd) { virDomainNetDefPtr net = NULL; char *brname = NULL; char *realifname = NULL; int *tapfd = NULL; if (def->nnets != 1) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("domain should have one and only one net defined")); return -1; } net = def->nets[0]; if (net) { int actualType = virDomainNetGetActualType(net); if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) { if (VIR_STRDUP(brname, virDomainNetGetActualBridgeName(net)) < 0) return -1; } else { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Network type %d is not supported"), virDomainNetGetActualType(net)); return -1; } if (!net->ifname || STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) || strchr(net->ifname, '%')) { VIR_FREE(net->ifname); if (VIR_STRDUP(net->ifname, VIR_NET_GENERATED_PREFIX "%d") < 0) { VIR_FREE(brname); return -1; } } if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac, def->uuid, tapfd, 1, virDomainNetGetActualVirtPortProfile(net), virDomainNetGetActualVlan(net), VIR_NETDEV_TAP_CREATE_IFUP | VIR_NETDEV_TAP_CREATE_PERSIST) < 0) { VIR_FREE(net->ifname); VIR_FREE(brname); return -1; } } realifname = virBhyveTapGetRealDeviceName(net->ifname); if (realifname == NULL) { VIR_FREE(net->ifname); VIR_FREE(brname); return -1; } VIR_DEBUG("%s -> %s", net->ifname, realifname); /* hack on top of other hack: we need to set * interface to 'UP' again after re-opening to find its * name */ if (virNetDevSetOnline(net->ifname, true) != 0) { VIR_FREE(net->ifname); VIR_FREE(brname); return -1; } virCommandAddArgList(cmd, "-s", "0:0,hostbridge", NULL); virCommandAddArg(cmd, "-s"); virCommandAddArgFormat(cmd, "1:0,virtio-net,%s", realifname); return 0; }