static int qemuHotplugCreateObjects(virDomainXMLOptionPtr xmlopt, virDomainObjPtr *vm, const char *filename) { int ret = -1; qemuDomainObjPrivatePtr priv = NULL; if (!(*vm = virDomainObjNew(xmlopt))) goto cleanup; if (!((*vm)->def = virDomainDefParseFile(filename, driver.caps, driver.xmlopt, QEMU_EXPECTED_VIRT_TYPES, 0))) goto cleanup; priv = (*vm)->privateData; if (!(priv->qemuCaps = virQEMUCapsNew())) goto cleanup; /* for attach & detach qemu must support -device */ virQEMUCapsSet(priv->qemuCaps, QEMU_CAPS_DEVICE); ret = 0; cleanup: return ret; }
static int testCompareFiles(const char *xml, const char *sexpr) { char *gotsexpr = NULL; int ret = -1; virDomainDefPtr def = NULL; if (!(def = virDomainDefParseFile(xml, caps, xmlopt, NULL, VIR_DOMAIN_DEF_PARSE_INACTIVE))) goto fail; if (!virDomainDefCheckABIStability(def, def, xmlopt)) { fprintf(stderr, "ABI stability check failed on %s", xml); goto fail; } if (!(gotsexpr = xenFormatSxpr(NULL, def))) goto fail; if (virTestCompareToFile(gotsexpr, sexpr) < 0) goto fail; ret = 0; fail: VIR_FREE(gotsexpr); virDomainDefFree(def); return ret; }
static int testCompareXMLToArgvFiles(const char *xml, const char *cmdline, const char *ldcmdline, const char *dmcmdline) { char *actualargv = NULL, *actualld = NULL, *actualdm = NULL; virDomainDefPtr vmdef = NULL; virCommandPtr cmd = NULL, ldcmd = NULL; virConnectPtr conn; int ret = -1; if (!(conn = virGetConnect())) goto out; if (!(vmdef = virDomainDefParseFile(xml, driver.caps, driver.xmlopt, VIR_DOMAIN_DEF_PARSE_INACTIVE))) goto out; conn->privateData = &driver; if (!(cmd = virBhyveProcessBuildBhyveCmd(conn, vmdef, false))) goto out; if (!(actualargv = virCommandToString(cmd))) goto out; if (!(ldcmd = virBhyveProcessBuildLoadCmd(conn, vmdef, "<device.map>", &actualdm))) goto out; if (actualdm != NULL) virTrimSpaces(actualdm, NULL); if (!(actualld = virCommandToString(ldcmd))) goto out; if (virtTestCompareToFile(actualargv, cmdline) < 0) goto out; if (virtTestCompareToFile(actualld, ldcmdline) < 0) goto out; if (virFileExists(dmcmdline) || actualdm) { if (virtTestCompareToFile(actualdm, dmcmdline) < 0) goto out; } ret = 0; out: VIR_FREE(actualargv); VIR_FREE(actualld); VIR_FREE(actualdm); virCommandFree(cmd); virCommandFree(ldcmd); virDomainDefFree(vmdef); return ret; }
static int testCompareParseXML(const char *xmcfg, const char *xml) { char *gotxmcfgData = NULL; virConfPtr conf = NULL; int ret = -1; virConnectPtr conn = NULL; int wrote = 4096; struct _xenUnifiedPrivate priv; virDomainDefPtr def = NULL; if (VIR_ALLOC_N(gotxmcfgData, wrote) < 0) goto fail; conn = virGetConnect(); if (!conn) goto fail; /* Many puppies died to bring you this code. */ priv.caps = caps; conn->privateData = &priv; if (!(def = virDomainDefParseFile(xml, caps, xmlopt, NULL, VIR_DOMAIN_DEF_PARSE_INACTIVE))) goto fail; if (!virDomainDefCheckABIStability(def, def, xmlopt)) { fprintf(stderr, "ABI stability check failed on %s", xml); goto fail; } if (!(conf = xenFormatXM(conn, def))) goto fail; if (virConfWriteMem(gotxmcfgData, &wrote, conf) < 0) goto fail; gotxmcfgData[wrote] = '\0'; if (virTestCompareToFile(gotxmcfgData, xmcfg) < 0) goto fail; ret = 0; fail: VIR_FREE(gotxmcfgData); if (conf) virConfFree(conf); virDomainDefFree(def); virObjectUnref(conn); return ret; }
static virDomainDefPtr testSELinuxLoadDef(const char *testname) { char *xmlfile = NULL; virDomainDefPtr def = NULL; size_t i; if (virAsprintf(&xmlfile, "%s/securityselinuxlabeldata/%s.xml", abs_srcdir, testname) < 0) goto cleanup; if (!(def = virDomainDefParseFile(xmlfile, driver.caps, driver.xmlopt, NULL, 0))) goto cleanup; for (i = 0; i < def->ndisks; i++) { if (def->disks[i]->src->type != VIR_STORAGE_TYPE_FILE && def->disks[i]->src->type != VIR_STORAGE_TYPE_BLOCK) continue; if (testSELinuxMungePath(&def->disks[i]->src->path) < 0) goto cleanup; } for (i = 0; i < def->nserials; i++) { if (def->serials[i]->source->type != VIR_DOMAIN_CHR_TYPE_FILE && def->serials[i]->source->type != VIR_DOMAIN_CHR_TYPE_PIPE && def->serials[i]->source->type != VIR_DOMAIN_CHR_TYPE_DEV && def->serials[i]->source->type != VIR_DOMAIN_CHR_TYPE_UNIX) continue; if (def->serials[i]->source->type == VIR_DOMAIN_CHR_TYPE_UNIX) { if (testSELinuxMungePath(&def->serials[i]->source->data.nix.path) < 0) goto cleanup; } else { if (testSELinuxMungePath(&def->serials[i]->source->data.file.path) < 0) goto cleanup; } } if (def->os.kernel && testSELinuxMungePath(&def->os.kernel) < 0) goto cleanup; if (def->os.initrd && testSELinuxMungePath(&def->os.initrd) < 0) goto cleanup; cleanup: VIR_FREE(xmlfile); return def; }
static int testCompareXMLToArgvFiles(const char *xml, const char *cmdline) { char *expectargv = NULL; int len; char *actualargv = NULL; virDomainDefPtr vmdef = NULL; virDomainObj vm; virCommandPtr cmd = NULL; virConnectPtr conn; int ret = -1; if (!(conn = virGetConnect())) goto out; if (!(vmdef = virDomainDefParseFile(xml, driver.caps, driver.xmlopt, 1 << VIR_DOMAIN_VIRT_BHYVE, VIR_DOMAIN_XML_INACTIVE))) goto out; vm.def = vmdef; if (!(cmd = virBhyveProcessBuildBhyveCmd(conn, vmdef, false))) goto out; if (!(actualargv = virCommandToString(cmd))) goto out; len = virtTestLoadFile(cmdline, &expectargv); if (len < 0) goto out; if (len && expectargv[len - 1] == '\n') expectargv[len - 1] = '\0'; if (STRNEQ(expectargv, actualargv)) { virtTestDifference(stderr, expectargv, actualargv); goto out; } ret = 0; out: VIR_FREE(expectargv); VIR_FREE(actualargv); virCommandFree(cmd); virDomainDefFree(vmdef); return ret; }
/* * Parses domXML to virDomainDef object, which is then converted to xl.cfg(5) * config and compared with expected config. */ static int testCompareParseXML(const char *xlcfg, const char *xml) { char *gotxlcfgData = NULL; virConfPtr conf = NULL; virConnectPtr conn = NULL; int wrote = 4096; int ret = -1; virDomainDefPtr def = NULL; if (VIR_ALLOC_N(gotxlcfgData, wrote) < 0) goto fail; conn = virGetConnect(); if (!conn) goto fail; if (!(def = virDomainDefParseFile(xml, caps, xmlopt, VIR_DOMAIN_XML_INACTIVE))) goto fail; if (!virDomainDefCheckABIStability(def, def)) { fprintf(stderr, "ABI stability check failed on %s", xml); goto fail; } if (!(conf = xenFormatXL(def, conn))) goto fail; if (virConfWriteMem(gotxlcfgData, &wrote, conf) < 0) goto fail; gotxlcfgData[wrote] = '\0'; if (virtTestCompareToFile(gotxlcfgData, xlcfg) < 0) goto fail; ret = 0; fail: VIR_FREE(gotxlcfgData); if (conf) virConfFree(conf); virDomainDefFree(def); virObjectUnref(conn); return ret; }
static virLXCControllerPtr virLXCControllerNew(const char *name) { virLXCControllerPtr ctrl = NULL; virCapsPtr caps = NULL; char *configFile = NULL; if (VIR_ALLOC(ctrl) < 0) goto no_memory; ctrl->timerShutdown = -1; ctrl->firstClient = true; if (!(ctrl->name = strdup(name))) goto no_memory; if ((caps = lxcCapsInit(NULL)) == NULL) goto error; if ((configFile = virDomainConfigFile(LXC_STATE_DIR, ctrl->name)) == NULL) goto error; if ((ctrl->def = virDomainDefParseFile(caps, configFile, 1 << VIR_DOMAIN_VIRT_LXC, 0)) == NULL) goto error; if ((ctrl->timerShutdown = virEventAddTimeout(-1, virLXCControllerQuitTimer, ctrl, NULL)) < 0) goto error; cleanup: VIR_FREE(configFile); virObjectUnref(caps); return ctrl; no_memory: virReportOOMError(); error: virLXCControllerFree(ctrl); ctrl = NULL; goto cleanup; }
static int testCompareXMLToArgvFiles(const char *xml, const char *cmdline, virBitmapPtr extraFlags, const char *migrateFrom, int migrateFd, bool json, bool expectError) { char *expectargv = NULL; int len; char *actualargv = NULL; int ret = -1; virDomainDefPtr vmdef = NULL; virDomainChrSourceDef monitor_chr; virConnectPtr conn; char *log = NULL; char *emulator = NULL; virCommandPtr cmd = NULL; if (!(conn = virGetConnect())) goto fail; len = virtTestLoadFile(cmdline, &expectargv); if (len < 0) goto fail; if (len && expectargv[len - 1] == '\n') expectargv[len - 1] = '\0'; if (!(vmdef = virDomainDefParseFile(driver.caps, xml, QEMU_EXPECTED_VIRT_TYPES, VIR_DOMAIN_XML_INACTIVE))) goto fail; /* * For test purposes, we may want to fake emulator's output by providing * our own script instead of a real emulator. For this to work we need to * specify a relative path in <emulator/> element, which, however, is not * allowed by RelaxNG schema for domain XML. To work around it we add an * extra '/' at the beginning of relative emulator path so that it looks * like, e.g., "/./qemu.sh" or "/../emulator/qemu.sh" instead of * "./qemu.sh" or "../emulator/qemu.sh" respectively. The following code * detects such paths, strips the extra '/' and makes the path absolute. */ if (vmdef->emulator && STRPREFIX(vmdef->emulator, "/.")) { if (!(emulator = strdup(vmdef->emulator + 1))) goto fail; free(vmdef->emulator); vmdef->emulator = NULL; if (virAsprintf(&vmdef->emulator, "%s/qemuxml2argvdata/%s", abs_srcdir, emulator) < 0) goto fail; } if (qemuCapsGet(extraFlags, QEMU_CAPS_DOMID)) vmdef->id = 6; else vmdef->id = -1; memset(&monitor_chr, 0, sizeof(monitor_chr)); monitor_chr.type = VIR_DOMAIN_CHR_TYPE_UNIX; monitor_chr.data.nix.path = (char *)"/tmp/test-monitor"; monitor_chr.data.nix.listen = true; qemuCapsSetList(extraFlags, QEMU_CAPS_VNC_COLON, QEMU_CAPS_NO_REBOOT, QEMU_CAPS_LAST); if (qemudCanonicalizeMachine(&driver, vmdef) < 0) goto fail; if (qemuCapsGet(extraFlags, QEMU_CAPS_DEVICE)) { qemuDomainPCIAddressSetPtr pciaddrs; if (!(pciaddrs = qemuDomainPCIAddressSetCreate(vmdef))) goto fail; if (qemuAssignDevicePCISlots(vmdef, pciaddrs) < 0) goto fail; qemuDomainPCIAddressSetFree(pciaddrs); } free(virtTestLogContentAndReset()); virResetLastError(); /* We do not call qemuCapsExtractVersionInfo() before calling * qemuBuildCommandLine(), so we should set QEMU_CAPS_PCI_MULTIBUS for * x86_64 and i686 architectures here. */ if (STREQLEN(vmdef->os.arch, "x86_64", 6) || STREQLEN(vmdef->os.arch, "i686", 4)) { qemuCapsSet(extraFlags, QEMU_CAPS_PCI_MULTIBUS); } if (qemuAssignDeviceAliases(vmdef, extraFlags) < 0) goto fail; if (!(cmd = qemuBuildCommandLine(conn, &driver, vmdef, &monitor_chr, json, extraFlags, migrateFrom, migrateFd, NULL, VIR_VM_OP_NO_OP))) goto fail; if (!!virGetLastError() != expectError) { if (virTestGetDebug() && (log = virtTestLogContentAndReset())) fprintf(stderr, "\n%s", log); goto fail; } if (expectError) { /* need to suppress the errors */ virResetLastError(); } if (!(actualargv = virCommandToString(cmd))) goto fail; if (emulator) { /* Skip the abs_srcdir portion of replacement emulator. */ char *start_skip = strstr(actualargv, abs_srcdir); char *end_skip = strstr(actualargv, emulator); if (!start_skip || !end_skip) goto fail; memmove(start_skip, end_skip, strlen(end_skip) + 1); } if (STRNEQ(expectargv, actualargv)) { virtTestDifference(stderr, expectargv, actualargv); goto fail; } ret = 0; fail: free(log); free(emulator); free(expectargv); free(actualargv); virCommandFree(cmd); virDomainDefFree(vmdef); virUnrefConnect(conn); return ret; }
static int testCompareXMLToArgvFiles(const char *xml, const char *cmdline, virQEMUCapsPtr extraFlags, const char *migrateFrom, int migrateFd, bool json, bool expectError) { char *expectargv = NULL; int len; char *actualargv = NULL; int ret = -1; virDomainDefPtr vmdef = NULL; virDomainChrSourceDef monitor_chr; virConnectPtr conn; char *log = NULL; char *emulator = NULL; virCommandPtr cmd = NULL; if (!(conn = virGetConnect())) goto fail; len = virtTestLoadFile(cmdline, &expectargv); if (len < 0) goto fail; if (len && expectargv[len - 1] == '\n') expectargv[len - 1] = '\0'; if (!(vmdef = virDomainDefParseFile(xml, driver.caps, driver.xmlopt, QEMU_EXPECTED_VIRT_TYPES, VIR_DOMAIN_XML_INACTIVE))) goto fail; /* * For test purposes, we may want to fake emulator's output by providing * our own script instead of a real emulator. For this to work we need to * specify a relative path in <emulator/> element, which, however, is not * allowed by RelaxNG schema for domain XML. To work around it we add an * extra '/' at the beginning of relative emulator path so that it looks * like, e.g., "/./qemu.sh" or "/../emulator/qemu.sh" instead of * "./qemu.sh" or "../emulator/qemu.sh" respectively. The following code * detects such paths, strips the extra '/' and makes the path absolute. */ if (vmdef->emulator && STRPREFIX(vmdef->emulator, "/.")) { if (VIR_STRDUP(emulator, vmdef->emulator + 1) < 0) goto fail; VIR_FREE(vmdef->emulator); vmdef->emulator = NULL; if (virAsprintf(&vmdef->emulator, "%s/qemuxml2argvdata/%s", abs_srcdir, emulator) < 0) goto fail; } if (virQEMUCapsGet(extraFlags, QEMU_CAPS_DOMID)) vmdef->id = 6; else vmdef->id = -1; memset(&monitor_chr, 0, sizeof(monitor_chr)); monitor_chr.type = VIR_DOMAIN_CHR_TYPE_UNIX; monitor_chr.data.nix.path = (char *)"/tmp/test-monitor"; monitor_chr.data.nix.listen = true; virQEMUCapsSetList(extraFlags, QEMU_CAPS_VNC_COLON, QEMU_CAPS_NO_REBOOT, QEMU_CAPS_NO_ACPI, QEMU_CAPS_LAST); if (virQEMUCapsGet(extraFlags, QEMU_CAPS_DEVICE)) qemuDomainAssignAddresses(vmdef, extraFlags, NULL); log = virtTestLogContentAndReset(); VIR_FREE(log); virResetLastError(); if (vmdef->os.arch == VIR_ARCH_X86_64 || vmdef->os.arch == VIR_ARCH_I686) { virQEMUCapsSet(extraFlags, QEMU_CAPS_PCI_MULTIBUS); } if (qemuAssignDeviceAliases(vmdef, extraFlags) < 0) goto fail; if (!(cmd = qemuBuildCommandLine(conn, &driver, vmdef, &monitor_chr, json, extraFlags, migrateFrom, migrateFd, NULL, VIR_NETDEV_VPORT_PROFILE_OP_NO_OP, &testCallbacks))) goto fail; if (!!virGetLastError() != expectError) { if (virTestGetDebug() && (log = virtTestLogContentAndReset())) fprintf(stderr, "\n%s", log); goto fail; } if (expectError) { /* need to suppress the errors */ virResetLastError(); } if (!(actualargv = virCommandToString(cmd))) goto fail; if (emulator) { /* Skip the abs_srcdir portion of replacement emulator. */ char *start_skip = strstr(actualargv, abs_srcdir); char *end_skip = strstr(actualargv, emulator); if (!start_skip || !end_skip) goto fail; memmove(start_skip, end_skip, strlen(end_skip) + 1); } if (STRNEQ(expectargv, actualargv)) { virtTestDifference(stderr, expectargv, actualargv); goto fail; } ret = 0; fail: VIR_FREE(log); VIR_FREE(emulator); VIR_FREE(expectargv); VIR_FREE(actualargv); virCommandFree(cmd); virDomainDefFree(vmdef); virObjectUnref(conn); return ret; }
int main(int argc, char *argv[]) { pid_t pid; int rc = 1; int client; char *name = NULL; int nveths = 0; char **veths = NULL; int monitor = -1; int appPty = -1; int bg = 0; virCapsPtr caps = NULL; virDomainDefPtr def = NULL; char *configFile = NULL; char *sockpath = NULL; const struct option options[] = { { "background", 0, NULL, 'b' }, { "name", 1, NULL, 'n' }, { "veth", 1, NULL, 'v' }, { "console", 1, NULL, 'c' }, { "help", 0, NULL, 'h' }, { 0, 0, 0, 0 }, }; if (setlocale(LC_ALL, "") == NULL || bindtextdomain(PACKAGE, LOCALEDIR) == NULL || textdomain(PACKAGE) == NULL) { fprintf(stderr, _("%s: initialization failed\n"), argv[0]); exit(EXIT_FAILURE); } while (1) { int c; c = getopt_long(argc, argv, "dn:v:m:c:h", options, NULL); if (c == -1) break; switch (c) { case 'b': bg = 1; break; case 'n': if ((name = strdup(optarg)) == NULL) { virReportOOMError(); goto cleanup; } break; case 'v': if (VIR_REALLOC_N(veths, nveths+1) < 0) { virReportOOMError(); goto cleanup; } if ((veths[nveths++] = strdup(optarg)) == NULL) { virReportOOMError(); goto cleanup; } break; case 'c': if (virStrToLong_i(optarg, NULL, 10, &appPty) < 0) { fprintf(stderr, "malformed --console argument '%s'", optarg); goto cleanup; } break; case 'h': case '?': fprintf(stderr, "\n"); fprintf(stderr, "syntax: %s [OPTIONS]\n", argv[0]); fprintf(stderr, "\n"); fprintf(stderr, "Options\n"); fprintf(stderr, "\n"); fprintf(stderr, " -b, --background\n"); fprintf(stderr, " -n NAME, --name NAME\n"); fprintf(stderr, " -c FD, --console FD\n"); fprintf(stderr, " -v VETH, --veth VETH\n"); fprintf(stderr, " -h, --help\n"); fprintf(stderr, "\n"); goto cleanup; } } if (name == NULL) { fprintf(stderr, "%s: missing --name argument for configuration\n", argv[0]); goto cleanup; } if (appPty < 0) { fprintf(stderr, "%s: missing --console argument for container PTY\n", argv[0]); goto cleanup; } if (getuid() != 0) { fprintf(stderr, "%s: must be run as the 'root' user\n", argv[0]); goto cleanup; } if ((caps = lxcCapsInit()) == NULL) goto cleanup; if ((configFile = virDomainConfigFile(LXC_STATE_DIR, name)) == NULL) goto cleanup; if ((def = virDomainDefParseFile(caps, configFile, VIR_DOMAIN_XML_INACTIVE)) == NULL) goto cleanup; if (def->nnets != nveths) { fprintf(stderr, "%s: expecting %d veths, but got %d\n", argv[0], def->nnets, nveths); goto cleanup; } if ((sockpath = lxcMonitorPath(def)) == NULL) goto cleanup; if ((monitor = lxcMonitorServer(sockpath)) < 0) goto cleanup; if (bg) { if ((pid = fork()) < 0) goto cleanup; if (pid > 0) { if ((rc = virFileWritePid(LXC_STATE_DIR, name, pid)) != 0) { virReportSystemError(rc, _("Unable to write pid file '%s/%s.pid'"), LXC_STATE_DIR, name); _exit(1); } /* First child now exits, allowing original caller * (ie libvirtd's LXC driver to complete their * waitpid & continue */ _exit(0); } /* Don't hold onto any cwd we inherit from libvirtd either */ if (chdir("/") < 0) { virReportSystemError(errno, "%s", _("Unable to change to root dir")); goto cleanup; } if (setsid() < 0) { virReportSystemError(errno, "%s", _("Unable to become session leader")); goto cleanup; } } /* Initialize logging */ virLogSetFromEnv(); /* Accept initial client which is the libvirtd daemon */ if ((client = accept(monitor, NULL, 0)) < 0) { virReportSystemError(errno, "%s", _("Failed to accept a connection from driver")); goto cleanup; } rc = lxcControllerRun(def, nveths, veths, monitor, client, appPty); cleanup: if (def) virFileDeletePid(LXC_STATE_DIR, def->name); lxcControllerCleanupInterfaces(nveths, veths); if (sockpath) unlink(sockpath); VIR_FREE(sockpath); return rc; }
static int testCompareXMLToArgvFiles(const char *xml, const char *cmd, unsigned long long extraFlags, const char *migrateFrom) { char argvData[MAX_FILE]; char *expectargv = &(argvData[0]); char *actualargv = NULL; const char **argv = NULL; const char **qenv = NULL; const char **tmp = NULL; int ret = -1, len; unsigned long long flags; virDomainDefPtr vmdef = NULL; virDomainChrDef monitor_chr; virConnectPtr conn; if (!(conn = virGetConnect())) goto fail; if (virtTestLoadFile(cmd, &expectargv, MAX_FILE) < 0) goto fail; if (!(vmdef = virDomainDefParseFile(driver.caps, xml, VIR_DOMAIN_XML_INACTIVE))) goto fail; if (extraFlags & QEMUD_CMD_FLAG_DOMID) vmdef->id = 6; else vmdef->id = -1; memset(&monitor_chr, 0, sizeof(monitor_chr)); monitor_chr.type = VIR_DOMAIN_CHR_TYPE_UNIX; monitor_chr.data.nix.path = (char *)"/tmp/test-monitor"; monitor_chr.data.nix.listen = 1; if (!(monitor_chr.info.alias = strdup("monitor"))) goto fail; flags = QEMUD_CMD_FLAG_VNC_COLON | QEMUD_CMD_FLAG_NO_REBOOT | extraFlags; if (qemudCanonicalizeMachine(&driver, vmdef) < 0) goto fail; if (flags & QEMUD_CMD_FLAG_DEVICE) { qemuDomainPCIAddressSetPtr pciaddrs; if (!(pciaddrs = qemuDomainPCIAddressSetCreate(vmdef))) goto fail; if (qemuAssignDevicePCISlots(vmdef, pciaddrs) < 0) goto fail; qemuDomainPCIAddressSetFree(pciaddrs); } if (qemudBuildCommandLine(conn, &driver, vmdef, &monitor_chr, 0, flags, &argv, &qenv, NULL, NULL, migrateFrom, NULL) < 0) goto fail; len = 1; /* for trailing newline */ tmp = qenv; while (*tmp) { len += strlen(*tmp) + 1; tmp++; } tmp = argv; while (*tmp) { len += strlen(*tmp) + 1; tmp++; } if ((actualargv = malloc(sizeof(*actualargv)*len)) == NULL) goto fail; actualargv[0] = '\0'; tmp = qenv; while (*tmp) { if (actualargv[0]) strcat(actualargv, " "); strcat(actualargv, *tmp); tmp++; } tmp = argv; while (*tmp) { if (actualargv[0]) strcat(actualargv, " "); strcat(actualargv, *tmp); tmp++; } strcat(actualargv, "\n"); if (STRNEQ(expectargv, actualargv)) { virtTestDifference(stderr, expectargv, actualargv); goto fail; } ret = 0; fail: free(actualargv); if (argv) { tmp = argv; while (*tmp) { free(*(char**)tmp); tmp++; } free(argv); } if (qenv) { tmp = qenv; while (*tmp) { free(*(char**)tmp); tmp++; } free(qenv); } virDomainDefFree(vmdef); virUnrefConnect(conn); return ret; }
static int testCompareXMLToArgvFiles(const char *xml, const char *cmdline, virQEMUCapsPtr extraFlags, const char *migrateFrom, int migrateFd, virQemuXML2ArgvTestFlags flags) { char *expectargv = NULL; int len; char *actualargv = NULL; int ret = -1; virDomainDefPtr vmdef = NULL; virDomainChrSourceDef monitor_chr; virConnectPtr conn; char *log = NULL; virCommandPtr cmd = NULL; if (!(conn = virGetConnect())) goto out; conn->secretDriver = &fakeSecretDriver; if (!(vmdef = virDomainDefParseFile(xml, driver.caps, driver.xmlopt, QEMU_EXPECTED_VIRT_TYPES, VIR_DOMAIN_XML_INACTIVE))) { if (flags & FLAG_EXPECT_PARSE_ERROR) goto ok; goto out; } if (virQEMUCapsGet(extraFlags, QEMU_CAPS_DOMID)) vmdef->id = 6; else vmdef->id = -1; memset(&monitor_chr, 0, sizeof(monitor_chr)); monitor_chr.type = VIR_DOMAIN_CHR_TYPE_UNIX; monitor_chr.data.nix.path = (char *)"/tmp/test-monitor"; monitor_chr.data.nix.listen = true; virQEMUCapsSetList(extraFlags, QEMU_CAPS_VNC_COLON, QEMU_CAPS_NO_REBOOT, QEMU_CAPS_NO_ACPI, QEMU_CAPS_LAST); if (STREQ(vmdef->os.machine, "pc") && STREQ(vmdef->emulator, "/usr/bin/qemu-system-x86_64")) { VIR_FREE(vmdef->os.machine); if (VIR_STRDUP(vmdef->os.machine, "pc-0.11") < 0) goto out; } if (virQEMUCapsGet(extraFlags, QEMU_CAPS_DEVICE)) { if (qemuDomainAssignAddresses(vmdef, extraFlags, NULL)) { if (flags & FLAG_EXPECT_ERROR) goto ok; goto out; } } log = virtTestLogContentAndReset(); VIR_FREE(log); virResetLastError(); if (vmdef->os.arch == VIR_ARCH_X86_64 || vmdef->os.arch == VIR_ARCH_I686) { virQEMUCapsSet(extraFlags, QEMU_CAPS_PCI_MULTIBUS); } if (qemuAssignDeviceAliases(vmdef, extraFlags) < 0) goto out; if (!(cmd = qemuBuildCommandLine(conn, &driver, vmdef, &monitor_chr, (flags & FLAG_JSON), extraFlags, migrateFrom, migrateFd, NULL, VIR_NETDEV_VPORT_PROFILE_OP_NO_OP, &testCallbacks))) { if (flags & FLAG_EXPECT_FAILURE) { ret = 0; if (virTestGetDebug() > 1) fprintf(stderr, "Got expected error: %s\n", virGetLastErrorMessage()); virResetLastError(); } goto out; } else if (flags & FLAG_EXPECT_FAILURE) { if (virTestGetDebug()) fprintf(stderr, "qemuBuildCommandLine should have failed\n"); goto out; } if (!!virGetLastError() != !!(flags & FLAG_EXPECT_ERROR)) { if (virTestGetDebug() && (log = virtTestLogContentAndReset())) fprintf(stderr, "\n%s", log); goto out; } if (!(actualargv = virCommandToString(cmd))) goto out; len = virtTestLoadFile(cmdline, &expectargv); if (len < 0) goto out; if (len && expectargv[len - 1] == '\n') expectargv[len - 1] = '\0'; if (STRNEQ(expectargv, actualargv)) { virtTestDifference(stderr, expectargv, actualargv); goto out; } ok: if (flags & FLAG_EXPECT_ERROR) { /* need to suppress the errors */ virResetLastError(); } ret = 0; out: VIR_FREE(log); VIR_FREE(expectargv); VIR_FREE(actualargv); virCommandFree(cmd); virDomainDefFree(vmdef); virObjectUnref(conn); return ret; }
static int testQemuAgentGetFSInfo(const void *data) { virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data; qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt); char *domain_filename = NULL; virDomainDefPtr def = NULL; virDomainFSInfoPtr *info = NULL; int ret = -1, ninfo = 0, i; if (!test) return -1; if (virAsprintf(&domain_filename, "%s/qemuagentdata/fsinfo.xml", abs_srcdir) < 0) goto cleanup; if (!(def = virDomainDefParseFile(domain_filename, driver.caps, xmlopt, NULL, VIR_DOMAIN_DEF_PARSE_INACTIVE))) goto cleanup; if (qemuMonitorTestAddAgentSyncResponse(test) < 0) goto cleanup; if (qemuMonitorTestAddItem(test, "guest-get-fsinfo", "{\"return\": [" " {\"name\": \"sda1\", \"mountpoint\": \"/\"," " \"disk\": [" " {\"bus-type\": \"ide\"," " \"bus\": 1, \"unit\": 0," " \"pci-controller\": {" " \"bus\": 0, \"slot\": 1," " \"domain\": 0, \"function\": 1}," " \"target\": 0}]," " \"type\": \"ext4\"}," " {\"name\": \"dm-1\"," " \"mountpoint\": \"/opt\"," " \"disk\": [" " {\"bus-type\": \"virtio\"," " \"bus\": 0, \"unit\": 0," " \"pci-controller\": {" " \"bus\": 0, \"slot\": 6," " \"domain\": 0, \"function\": 0}," " \"target\": 0}," " {\"bus-type\": \"virtio\"," " \"bus\": 0, \"unit\": 0," " \"pci-controller\": {" " \"bus\": 0, \"slot\": 7," " \"domain\": 0, \"function\": 0}," " \"target\": 0}]," " \"type\": \"vfat\"}," " {\"name\": \"sdb1\"," " \"mountpoint\": \"/mnt/disk\"," " \"disk\": [], \"type\": \"xfs\"}]}") < 0) goto cleanup; if ((ninfo = qemuAgentGetFSInfo(qemuMonitorTestGetAgent(test), &info, def)) < 0) goto cleanup; if (ninfo != 3) { virReportError(VIR_ERR_INTERNAL_ERROR, "expected 3 filesystems information, got %d", ninfo); ret = -1; goto cleanup; } if (STRNEQ(info[2]->name, "sda1") || STRNEQ(info[2]->mountpoint, "/") || STRNEQ(info[2]->fstype, "ext4") || info[2]->ndevAlias != 1 || !info[2]->devAlias || !info[2]->devAlias[0] || STRNEQ(info[2]->devAlias[0], "hdc")) { virReportError(VIR_ERR_INTERNAL_ERROR, "unexpected filesystems information returned for sda1 (%s,%s)", info[2]->name, info[2]->devAlias ? info[2]->devAlias[0] : "null"); ret = -1; goto cleanup; } if (STRNEQ(info[1]->name, "dm-1") || STRNEQ(info[1]->mountpoint, "/opt") || STRNEQ(info[1]->fstype, "vfat") || info[1]->ndevAlias != 2 || !info[1]->devAlias || !info[1]->devAlias[0] || !info[1]->devAlias[1] || STRNEQ(info[1]->devAlias[0], "vda") || STRNEQ(info[1]->devAlias[1], "vdb")) { virReportError(VIR_ERR_INTERNAL_ERROR, "unexpected filesystems information returned for dm-1 (%s,%s)", info[0]->name, info[0]->devAlias ? info[0]->devAlias[0] : "null"); ret = -1; goto cleanup; } if (STRNEQ(info[0]->name, "sdb1") || STRNEQ(info[0]->mountpoint, "/mnt/disk") || STRNEQ(info[0]->fstype, "xfs") || info[0]->ndevAlias != 0 || info[0]->devAlias) { virReportError(VIR_ERR_INTERNAL_ERROR, "unexpected filesystems information returned for sdb1 (%s,%s)", info[0]->name, info[0]->devAlias ? info[0]->devAlias[0] : "null"); ret = -1; goto cleanup; } if (qemuMonitorTestAddAgentSyncResponse(test) < 0) goto cleanup; if (qemuMonitorTestAddItem(test, "guest-get-fsinfo", "{\"error\":" " {\"class\":\"CommandDisabled\"," " \"desc\":\"The command guest-get-fsinfo " "has been disabled for " "this instance\"," " \"data\":{\"name\":\"guest-get-fsinfo\"}" " }" "}") < 0) goto cleanup; if (qemuAgentGetFSInfo(qemuMonitorTestGetAgent(test), &info, def) != -1) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", "agent get-fsinfo command should have failed"); goto cleanup; } ret = 0; cleanup: for (i = 0; i < ninfo; i++) virDomainFSInfoFree(info[i]); VIR_FREE(info); VIR_FREE(domain_filename); virDomainDefFree(def); qemuMonitorTestFree(test); return ret; }