backup: Wire up qemu full pull backup commands over QMP
[libvirt/ericb.git] / tests / testutilsqemu.c
blob9ac9f9bd39d5a8612cdf80667941ca73670fb085
1 #include <config.h>
2 #ifdef WITH_QEMU
4 # include "testutilsqemu.h"
5 # include "testutilshostcpus.h"
6 # include "testutils.h"
7 # include "viralloc.h"
8 # include "cpu_conf.h"
9 # include "qemu/qemu_driver.h"
10 # include "qemu/qemu_domain.h"
11 # define LIBVIRT_QEMU_CAPSPRIV_H_ALLOW
12 # include "qemu/qemu_capspriv.h"
13 # include "virstring.h"
14 # include "virfilecache.h"
16 # define VIR_FROM_THIS VIR_FROM_QEMU
18 virCPUDefPtr cpuDefault;
19 virCPUDefPtr cpuHaswell;
20 virCPUDefPtr cpuPower8;
21 virCPUDefPtr cpuPower9;
23 typedef enum {
24 TEST_UTILS_QEMU_BIN_I686,
25 TEST_UTILS_QEMU_BIN_X86_64,
26 TEST_UTILS_QEMU_BIN_AARCH64,
27 TEST_UTILS_QEMU_BIN_ARM,
28 TEST_UTILS_QEMU_BIN_PPC64,
29 TEST_UTILS_QEMU_BIN_PPC,
30 TEST_UTILS_QEMU_BIN_RISCV32,
31 TEST_UTILS_QEMU_BIN_RISCV64,
32 TEST_UTILS_QEMU_BIN_S390X
33 } QEMUBinType;
35 static const char *QEMUBinList[] = {
36 "/usr/bin/qemu-system-i686",
37 "/usr/bin/qemu-system-x86_64",
38 "/usr/bin/qemu-system-aarch64",
39 "/usr/bin/qemu-system-arm",
40 "/usr/bin/qemu-system-ppc64",
41 "/usr/bin/qemu-system-ppc",
42 "/usr/bin/qemu-system-riscv32",
43 "/usr/bin/qemu-system-riscv64",
44 "/usr/bin/qemu-system-s390x"
48 static virCapsGuestMachinePtr *testQemuAllocMachines(int *nmachines)
50 virCapsGuestMachinePtr *machines;
51 static const char *const x86_machines[] = {
52 "pc", "isapc"
55 machines = virCapabilitiesAllocMachines(x86_machines,
56 ARRAY_CARDINALITY(x86_machines));
57 if (machines == NULL)
58 return NULL;
60 *nmachines = ARRAY_CARDINALITY(x86_machines);
62 return machines;
65 /* Newer versions of qemu have versioned machine types to allow
66 * compatibility with older releases.
67 * The 'pc' machine type is an alias of the newest machine type.
69 static virCapsGuestMachinePtr *testQemuAllocNewerMachines(int *nmachines)
71 virCapsGuestMachinePtr *machines;
72 char *canonical;
73 static const char *const x86_machines[] = {
74 "pc-0.11", "pc", "pc-0.10", "isapc"
77 if (VIR_STRDUP(canonical, x86_machines[0]) < 0)
78 return NULL;
80 machines = virCapabilitiesAllocMachines(x86_machines,
81 ARRAY_CARDINALITY(x86_machines));
82 if (machines == NULL) {
83 VIR_FREE(canonical);
84 return NULL;
87 machines[1]->canonical = canonical;
89 *nmachines = ARRAY_CARDINALITY(x86_machines);
91 return machines;
95 static int
96 testQemuAddI686Guest(virCapsPtr caps)
98 int nmachines = 0;
99 virCapsGuestMachinePtr *machines = NULL;
100 virCapsGuestPtr guest;
102 if (!(machines = testQemuAllocMachines(&nmachines)))
103 goto error;
105 if (!(guest = virCapabilitiesAddGuest(caps,
106 VIR_DOMAIN_OSTYPE_HVM,
107 VIR_ARCH_I686,
108 QEMUBinList[TEST_UTILS_QEMU_BIN_I686],
109 NULL,
110 nmachines,
111 machines)))
112 goto error;
114 if (!virCapabilitiesAddGuestFeature(guest, "cpuselection", true, false))
115 goto error;
117 machines = NULL;
119 if (!virCapabilitiesAddGuestDomain(guest,
120 VIR_DOMAIN_VIRT_QEMU,
121 NULL,
122 NULL,
124 NULL))
125 goto error;
127 if (!(machines = testQemuAllocMachines(&nmachines)))
128 goto error;
130 if (!virCapabilitiesAddGuestDomain(guest,
131 VIR_DOMAIN_VIRT_KVM,
132 QEMUBinList[TEST_UTILS_QEMU_BIN_I686],
133 NULL,
134 nmachines,
135 machines))
136 goto error;
138 return 0;
140 error:
141 virCapabilitiesFreeMachines(machines, nmachines);
142 return -1;
146 static int
147 testQemuAddX86_64Guest(virCapsPtr caps)
149 int nmachines = 0;
150 virCapsGuestMachinePtr *machines = NULL;
151 virCapsGuestPtr guest;
153 if (!(machines = testQemuAllocNewerMachines(&nmachines)))
154 goto error;
156 if (!(guest = virCapabilitiesAddGuest(caps,
157 VIR_DOMAIN_OSTYPE_HVM,
158 VIR_ARCH_X86_64,
159 QEMUBinList[TEST_UTILS_QEMU_BIN_X86_64],
160 NULL,
161 nmachines,
162 machines)))
163 goto error;
165 if (!virCapabilitiesAddGuestFeature(guest, "cpuselection", true, false))
166 goto error;
168 machines = NULL;
170 if (!virCapabilitiesAddGuestDomain(guest,
171 VIR_DOMAIN_VIRT_QEMU,
172 NULL,
173 NULL,
175 NULL))
176 goto error;
178 if (!(machines = testQemuAllocMachines(&nmachines)))
179 goto error;
181 if (!virCapabilitiesAddGuestDomain(guest,
182 VIR_DOMAIN_VIRT_KVM,
183 QEMUBinList[TEST_UTILS_QEMU_BIN_X86_64],
184 NULL,
185 nmachines,
186 machines))
187 goto error;
189 machines = NULL;
191 if (!virCapabilitiesAddGuestDomain(guest,
192 VIR_DOMAIN_VIRT_KVM,
193 QEMUBinList[TEST_UTILS_QEMU_BIN_X86_64],
194 NULL,
196 NULL))
197 goto error;
199 return 0;
201 error:
202 virCapabilitiesFreeMachines(machines, nmachines);
203 return -1;
207 static int testQemuAddPPC64Guest(virCapsPtr caps)
209 static const char *machine[] = { "pseries" };
210 virCapsGuestMachinePtr *machines = NULL;
211 virCapsGuestPtr guest;
213 machines = virCapabilitiesAllocMachines(machine, 1);
214 if (!machines)
215 goto error;
217 guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_PPC64,
218 QEMUBinList[TEST_UTILS_QEMU_BIN_PPC64],
219 NULL, 1, machines);
220 if (!guest)
221 goto error;
223 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
224 goto error;
225 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_KVM,
226 NULL, NULL, 0, NULL))
227 goto error;
229 return 0;
231 error:
232 /* No way to free a guest? */
233 virCapabilitiesFreeMachines(machines, 1);
234 return -1;
237 static int testQemuAddPPC64LEGuest(virCapsPtr caps)
239 static const char *machine[] = { "pseries" };
240 virCapsGuestMachinePtr *machines = NULL;
241 virCapsGuestPtr guest;
243 machines = virCapabilitiesAllocMachines(machine, 1);
244 if (!machines)
245 goto error;
247 guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_PPC64LE,
248 QEMUBinList[TEST_UTILS_QEMU_BIN_PPC64],
249 NULL, 1, machines);
250 if (!guest)
251 goto error;
253 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
254 goto error;
255 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_KVM,
256 NULL, NULL, 0, NULL))
257 goto error;
259 return 0;
261 error:
262 /* No way to free a guest? */
263 virCapabilitiesFreeMachines(machines, 1);
264 return -1;
267 static int testQemuAddPPCGuest(virCapsPtr caps)
269 static const char *machine[] = { "g3beige",
270 "mac99",
271 "prep",
272 "ppce500" };
273 virCapsGuestMachinePtr *machines = NULL;
274 virCapsGuestPtr guest;
276 machines = virCapabilitiesAllocMachines(machine, 1);
277 if (!machines)
278 goto error;
280 guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_PPC,
281 QEMUBinList[TEST_UTILS_QEMU_BIN_PPC],
282 NULL, 1, machines);
283 if (!guest)
284 goto error;
286 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
287 goto error;
288 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_KVM,
289 NULL, NULL, 0, NULL))
290 goto error;
292 return 0;
294 error:
295 /* No way to free a guest? */
296 virCapabilitiesFreeMachines(machines, 1);
297 return -1;
300 static int testQemuAddRISCV32Guest(virCapsPtr caps)
302 static const char *names[] = { "spike_v1.10",
303 "spike_v1.9.1",
304 "sifive_e",
305 "virt",
306 "sifive_u" };
307 static const int nmachines = ARRAY_CARDINALITY(names);
308 virCapsGuestMachinePtr *machines = NULL;
309 virCapsGuestPtr guest;
311 machines = virCapabilitiesAllocMachines(names, nmachines);
312 if (!machines)
313 goto error;
315 guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_RISCV32,
316 QEMUBinList[TEST_UTILS_QEMU_BIN_RISCV32],
317 NULL, nmachines, machines);
318 if (!guest)
319 goto error;
321 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
322 goto error;
324 return 0;
326 error:
327 virCapabilitiesFreeMachines(machines, nmachines);
328 return -1;
331 static int testQemuAddRISCV64Guest(virCapsPtr caps)
333 static const char *names[] = { "spike_v1.10",
334 "spike_v1.9.1",
335 "sifive_e",
336 "virt",
337 "sifive_u" };
338 static const int nmachines = ARRAY_CARDINALITY(names);
339 virCapsGuestMachinePtr *machines = NULL;
340 virCapsGuestPtr guest;
342 machines = virCapabilitiesAllocMachines(names, nmachines);
343 if (!machines)
344 goto error;
346 guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_RISCV64,
347 QEMUBinList[TEST_UTILS_QEMU_BIN_RISCV64],
348 NULL, nmachines, machines);
349 if (!guest)
350 goto error;
352 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
353 goto error;
355 return 0;
357 error:
358 virCapabilitiesFreeMachines(machines, nmachines);
359 return -1;
362 static int testQemuAddS390Guest(virCapsPtr caps)
364 static const char *s390_machines[] = { "s390-virtio",
365 "s390-ccw-virtio" };
366 virCapsGuestMachinePtr *machines = NULL;
367 virCapsGuestPtr guest;
369 machines = virCapabilitiesAllocMachines(s390_machines,
370 ARRAY_CARDINALITY(s390_machines));
371 if (!machines)
372 goto error;
374 guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_S390X,
375 QEMUBinList[TEST_UTILS_QEMU_BIN_S390X],
376 NULL,
377 ARRAY_CARDINALITY(s390_machines),
378 machines);
379 if (!guest)
380 goto error;
382 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
383 goto error;
384 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_KVM,
385 NULL, NULL, 0, NULL))
386 goto error;
388 return 0;
390 error:
391 virCapabilitiesFreeMachines(machines, ARRAY_CARDINALITY(s390_machines));
392 return -1;
395 static int testQemuAddArm6Guest(virCapsPtr caps)
397 static const char *machines[] = { "versatilepb" };
398 virCapsGuestMachinePtr *capsmachines = NULL;
399 virCapsGuestPtr guest;
401 capsmachines = virCapabilitiesAllocMachines(machines,
402 ARRAY_CARDINALITY(machines));
403 if (!capsmachines)
404 goto error;
406 guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_ARMV6L,
407 QEMUBinList[TEST_UTILS_QEMU_BIN_ARM],
408 NULL,
409 ARRAY_CARDINALITY(machines),
410 capsmachines);
411 if (!guest)
412 goto error;
414 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
415 goto error;
416 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_KVM,
417 NULL, NULL, 0, NULL))
418 goto error;
420 return 0;
422 error:
423 virCapabilitiesFreeMachines(capsmachines, ARRAY_CARDINALITY(machines));
424 return -1;
427 static int testQemuAddArm7Guest(virCapsPtr caps)
429 static const char *machines[] = { "vexpress-a9",
430 "vexpress-a15",
431 "versatilepb" };
432 virCapsGuestMachinePtr *capsmachines = NULL;
433 virCapsGuestPtr guest;
435 capsmachines = virCapabilitiesAllocMachines(machines,
436 ARRAY_CARDINALITY(machines));
437 if (!capsmachines)
438 goto error;
440 guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_ARMV7L,
441 QEMUBinList[TEST_UTILS_QEMU_BIN_ARM],
442 NULL,
443 ARRAY_CARDINALITY(machines),
444 capsmachines);
445 if (!guest)
446 goto error;
448 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
449 goto error;
450 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_KVM,
451 NULL, NULL, 0, NULL))
452 goto error;
454 return 0;
456 error:
457 virCapabilitiesFreeMachines(capsmachines, ARRAY_CARDINALITY(machines));
458 return -1;
461 static int testQemuAddAARCH64Guest(virCapsPtr caps)
463 static const char *machines[] = { "virt"};
464 virCapsGuestMachinePtr *capsmachines = NULL;
465 virCapsGuestPtr guest;
467 capsmachines = virCapabilitiesAllocMachines(machines,
468 ARRAY_CARDINALITY(machines));
469 if (!capsmachines)
470 goto error;
472 guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_AARCH64,
473 QEMUBinList[TEST_UTILS_QEMU_BIN_AARCH64],
474 NULL,
475 ARRAY_CARDINALITY(machines),
476 capsmachines);
477 if (!guest)
478 goto error;
480 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
481 goto error;
482 if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_KVM,
483 NULL, NULL, 0, NULL))
484 goto error;
486 return 0;
488 error:
489 virCapabilitiesFreeMachines(capsmachines, ARRAY_CARDINALITY(machines));
490 return -1;
493 virCapsPtr testQemuCapsInit(void)
495 virCapsPtr caps;
497 if (!(caps = virCapabilitiesNew(VIR_ARCH_X86_64, false, false)))
498 return NULL;
500 /* Add dummy 'none' security_driver. This is equal to setting
501 * security_driver = "none" in qemu.conf. */
502 if (VIR_ALLOC_N(caps->host.secModels, 1) < 0)
503 goto cleanup;
504 caps->host.nsecModels = 1;
506 if (VIR_STRDUP(caps->host.secModels[0].model, "none") < 0 ||
507 VIR_STRDUP(caps->host.secModels[0].doi, "0") < 0)
508 goto cleanup;
510 if (!(cpuDefault = virCPUDefCopy(&cpuDefaultData)) ||
511 !(cpuHaswell = virCPUDefCopy(&cpuHaswellData)) ||
512 !(cpuPower8 = virCPUDefCopy(&cpuPower8Data)) ||
513 !(cpuPower9 = virCPUDefCopy(&cpuPower9Data)))
514 goto cleanup;
516 qemuTestSetHostCPU(caps, NULL);
519 * Build a NUMA topology with cell_id (NUMA node id
520 * being 3(0 + 3),4(1 + 3), 5 and 6
522 if (virTestCapsBuildNUMATopology(caps, 3) < 0)
523 goto cleanup;
525 if (testQemuAddI686Guest(caps) < 0)
526 goto cleanup;
528 if (testQemuAddX86_64Guest(caps) < 0)
529 goto cleanup;
531 if (testQemuAddPPC64Guest(caps))
532 goto cleanup;
534 if (testQemuAddPPC64LEGuest(caps))
535 goto cleanup;
537 if (testQemuAddPPCGuest(caps))
538 goto cleanup;
540 if (testQemuAddRISCV32Guest(caps) < 0)
541 goto cleanup;
543 if (testQemuAddRISCV64Guest(caps) < 0)
544 goto cleanup;
546 if (testQemuAddS390Guest(caps))
547 goto cleanup;
549 if (testQemuAddArm6Guest(caps))
550 goto cleanup;
552 if (testQemuAddArm7Guest(caps))
553 goto cleanup;
555 if (testQemuAddAARCH64Guest(caps))
556 goto cleanup;
558 if (virTestGetDebug()) {
559 char *caps_str;
561 caps_str = virCapabilitiesFormatXML(caps);
562 if (!caps_str)
563 goto cleanup;
565 VIR_TEST_DEBUG("QEMU driver capabilities:\n%s", caps_str);
567 VIR_FREE(caps_str);
570 return caps;
572 cleanup:
573 caps->host.cpu = NULL;
574 virCPUDefFree(cpuDefault);
575 virCPUDefFree(cpuHaswell);
576 virCPUDefFree(cpuPower8);
577 virObjectUnref(caps);
578 return NULL;
582 void
583 qemuTestSetHostArch(virCapsPtr caps,
584 virArch arch)
586 if (arch == VIR_ARCH_NONE)
587 arch = VIR_ARCH_X86_64;
588 caps->host.arch = arch;
589 qemuTestSetHostCPU(caps, NULL);
593 void
594 qemuTestSetHostCPU(virCapsPtr caps,
595 virCPUDefPtr cpu)
597 virArch arch = caps->host.arch;
599 if (!cpu) {
600 if (ARCH_IS_X86(arch))
601 cpu = cpuDefault;
602 else if (ARCH_IS_PPC64(arch))
603 cpu = cpuPower8;
606 unsetenv("VIR_TEST_MOCK_FAKE_HOST_CPU");
607 if (cpu) {
608 caps->host.arch = cpu->arch;
609 if (cpu->model)
610 setenv("VIR_TEST_MOCK_FAKE_HOST_CPU", cpu->model, 1);
612 caps->host.cpu = cpu;
616 virQEMUCapsPtr
617 qemuTestParseCapabilitiesArch(virArch arch,
618 const char *capsFile)
620 virQEMUCapsPtr qemuCaps = NULL;
622 if (!(qemuCaps = virQEMUCapsNew()) ||
623 virQEMUCapsLoadCache(arch, qemuCaps, capsFile) < 0)
624 goto error;
626 return qemuCaps;
628 error:
629 virObjectUnref(qemuCaps);
630 return NULL;
634 virQEMUCapsPtr
635 qemuTestParseCapabilities(virCapsPtr caps,
636 const char *capsFile)
638 if (!caps)
639 return NULL;
641 return qemuTestParseCapabilitiesArch(caps->host.arch, capsFile);
645 void qemuTestDriverFree(virQEMUDriver *driver)
647 virMutexDestroy(&driver->lock);
648 if (driver->config) {
649 virFileDeleteTree(driver->config->stateDir);
650 virFileDeleteTree(driver->config->configDir);
652 virObjectUnref(driver->qemuCapsCache);
653 virObjectUnref(driver->xmlopt);
654 virObjectUnref(driver->caps);
655 virObjectUnref(driver->config);
656 virObjectUnref(driver->securityManager);
659 int qemuTestCapsCacheInsert(virFileCachePtr cache,
660 virQEMUCapsPtr caps)
662 size_t i;
663 virQEMUCapsPtr tmpCaps;
665 if (caps) {
666 tmpCaps = caps;
667 } else {
668 if (!(tmpCaps = virQEMUCapsNew()))
669 return -ENOMEM;
672 for (i = 0; i < ARRAY_CARDINALITY(QEMUBinList); i++) {
673 virObjectRef(tmpCaps);
674 if (virFileCacheInsertData(cache, QEMUBinList[i], tmpCaps) < 0) {
675 virObjectUnref(tmpCaps);
676 return -1;
680 if (!caps)
681 virObjectUnref(tmpCaps);
683 return 0;
687 # define STATEDIRTEMPLATE abs_builddir "/qemustatedir-XXXXXX"
688 # define CONFIGDIRTEMPLATE abs_builddir "/qemuconfigdir-XXXXXX"
690 int qemuTestDriverInit(virQEMUDriver *driver)
692 virSecurityManagerPtr mgr = NULL;
693 char statedir[] = STATEDIRTEMPLATE;
694 char configdir[] = CONFIGDIRTEMPLATE;
696 memset(driver, 0, sizeof(*driver));
698 if (virMutexInit(&driver->lock) < 0)
699 return -1;
701 driver->config = virQEMUDriverConfigNew(false);
702 if (!driver->config)
703 goto error;
705 /* Do this early so that qemuTestDriverFree() doesn't see (unlink) the real
706 * dirs. */
707 VIR_FREE(driver->config->stateDir);
708 VIR_FREE(driver->config->configDir);
710 /* Overwrite some default paths so it's consistent for tests. */
711 VIR_FREE(driver->config->libDir);
712 VIR_FREE(driver->config->channelTargetDir);
713 if (VIR_STRDUP(driver->config->libDir, "/tmp/lib") < 0 ||
714 VIR_STRDUP(driver->config->channelTargetDir, "/tmp/channel") < 0)
715 goto error;
717 if (!mkdtemp(statedir)) {
718 virFilePrintf(stderr, "Cannot create fake stateDir");
719 goto error;
722 if (VIR_STRDUP(driver->config->stateDir, statedir) < 0) {
723 rmdir(statedir);
724 goto error;
727 if (!mkdtemp(configdir)) {
728 virFilePrintf(stderr, "Cannot create fake configDir");
729 goto error;
732 if (VIR_STRDUP(driver->config->configDir, configdir) < 0) {
733 rmdir(configdir);
734 goto error;
737 driver->caps = testQemuCapsInit();
738 if (!driver->caps)
739 goto error;
741 /* Using /dev/null for libDir and cacheDir automatically produces errors
742 * upon attempt to use any of them */
743 driver->qemuCapsCache = virQEMUCapsCacheNew("/dev/null", "/dev/null", 0, 0);
744 if (!driver->qemuCapsCache)
745 goto error;
747 driver->xmlopt = virQEMUDriverCreateXMLConf(driver);
748 if (!driver->xmlopt)
749 goto error;
751 if (qemuTestCapsCacheInsert(driver->qemuCapsCache, NULL) < 0)
752 goto error;
754 if (!(mgr = virSecurityManagerNew("none", "qemu",
755 VIR_SECURITY_MANAGER_PRIVILEGED)))
756 goto error;
757 if (!(driver->securityManager = virSecurityManagerNewStack(mgr)))
758 goto error;
760 return 0;
762 error:
763 virObjectUnref(mgr);
764 qemuTestDriverFree(driver);
765 return -1;
769 testQemuCapsSetGIC(virQEMUCapsPtr qemuCaps,
770 int gic)
772 virGICCapability *gicCapabilities = NULL;
773 size_t ngicCapabilities = 0;
774 int ret = -1;
776 if (VIR_ALLOC_N(gicCapabilities, 2) < 0)
777 goto out;
779 # define IMPL_BOTH \
780 VIR_GIC_IMPLEMENTATION_KERNEL|VIR_GIC_IMPLEMENTATION_EMULATED
782 if (gic & GIC_V2) {
783 gicCapabilities[ngicCapabilities].version = VIR_GIC_VERSION_2;
784 gicCapabilities[ngicCapabilities].implementation = IMPL_BOTH;
785 ngicCapabilities++;
787 if (gic & GIC_V3) {
788 gicCapabilities[ngicCapabilities].version = VIR_GIC_VERSION_3;
789 gicCapabilities[ngicCapabilities].implementation = IMPL_BOTH;
790 ngicCapabilities++;
793 # undef IMPL_BOTH
795 virQEMUCapsSetGICCapabilities(qemuCaps,
796 gicCapabilities, ngicCapabilities);
798 ret = 0;
800 out:
801 return ret;
804 #endif
807 char *
808 testQemuGetLatestCapsForArch(const char *arch,
809 const char *suffix)
811 struct dirent *ent;
812 DIR *dir = NULL;
813 int rc;
814 char *fullsuffix = NULL;
815 char *tmp = NULL;
816 unsigned long maxver = 0;
817 unsigned long ver;
818 const char *maxname = NULL;
819 char *ret = NULL;
821 if (virAsprintf(&fullsuffix, "%s.%s", arch, suffix) < 0)
822 goto cleanup;
824 if (virDirOpen(&dir, TEST_QEMU_CAPS_PATH) < 0)
825 goto cleanup;
827 while ((rc = virDirRead(dir, &ent, TEST_QEMU_CAPS_PATH)) > 0) {
828 VIR_FREE(tmp);
830 if ((rc = VIR_STRDUP(tmp, STRSKIP(ent->d_name, "caps_"))) < 0)
831 goto cleanup;
833 if (rc == 0)
834 continue;
836 if (!virStringStripSuffix(tmp, fullsuffix))
837 continue;
839 if (virParseVersionString(tmp, &ver, false) < 0) {
840 VIR_TEST_DEBUG("skipping caps file '%s'\n", ent->d_name);
841 continue;
844 if (ver > maxver) {
845 maxname = ent->d_name;
846 maxver = ver;
850 if (rc < 0)
851 goto cleanup;
853 if (!maxname) {
854 VIR_TEST_VERBOSE("failed to find capabilities for '%s' in '%s'\n",
855 arch, TEST_QEMU_CAPS_PATH);
856 goto cleanup;
859 ignore_value(virAsprintf(&ret, "%s/%s", TEST_QEMU_CAPS_PATH, maxname));
861 cleanup:
862 VIR_FREE(tmp);
863 VIR_FREE(fullsuffix);
864 virDirClose(&dir);
865 return ret;
869 virHashTablePtr
870 testQemuGetLatestCaps(void)
872 const char *archs[] = {
873 "aarch64",
874 "ppc64",
875 "riscv64",
876 "s390x",
877 "x86_64",
879 virHashTablePtr capslatest;
880 size_t i;
882 if (!(capslatest = virHashCreate(4, virHashValueFree)))
883 goto error;
885 VIR_TEST_VERBOSE("\n");
887 for (i = 0; i < ARRAY_CARDINALITY(archs); ++i) {
888 char *cap = testQemuGetLatestCapsForArch(archs[i], "xml");
890 if (!cap || virHashAddEntry(capslatest, archs[i], cap) < 0)
891 goto error;
893 VIR_TEST_VERBOSE("latest caps for %s: %s\n", archs[i], cap);
896 VIR_TEST_VERBOSE("\n");
897 return capslatest;
899 error:
900 virHashFree(capslatest);
901 return NULL;
906 testQemuCapsIterate(const char *suffix,
907 testQemuCapsIterateCallback callback,
908 void *opaque)
910 struct dirent *ent;
911 DIR *dir = NULL;
912 int rc;
913 int ret = -1;
915 if (!callback)
916 return 0;
918 if (virDirOpen(&dir, TEST_QEMU_CAPS_PATH) < 0)
919 goto cleanup;
921 while ((rc = virDirRead(dir, &ent, TEST_QEMU_CAPS_PATH)) > 0) {
922 char *tmp = ent->d_name;
923 char *base = NULL;
924 char *archName = NULL;
926 /* Strip the trailing suffix, moving on if it's not present */
927 if (!virStringStripSuffix(tmp, suffix))
928 continue;
930 /* Find the last dot, moving on if none is present */
931 if (!(archName = strrchr(tmp, '.')))
932 continue;
934 /* The base name is everything before the last dot, and
935 * the architecture name everything after it */
936 base = tmp;
937 archName[0] = '\0';
938 archName++;
940 /* Run the user-provided callback */
941 if (callback(base, archName, opaque) < 0)
942 goto cleanup;
945 if (rc < 0)
946 goto cleanup;
948 ret = 0;
950 cleanup:
951 virDirClose(&dir);
953 return ret;
958 testQemuInfoSetArgs(struct testQemuInfo *info,
959 virHashTablePtr capslatest, ...)
961 va_list argptr;
962 testQemuInfoArgName argname;
963 virQEMUCapsPtr qemuCaps = NULL;
964 int gic = GIC_NONE;
965 char *capsarch = NULL;
966 char *capsver = NULL;
967 VIR_AUTOFREE(char *) capsfile = NULL;
968 int flag;
969 int ret = -1;
971 va_start(argptr, capslatest);
972 argname = va_arg(argptr, testQemuInfoArgName);
973 while (argname != ARG_END) {
974 switch (argname) {
975 case ARG_QEMU_CAPS:
976 if (qemuCaps || !(qemuCaps = virQEMUCapsNew()))
977 goto cleanup;
979 while ((flag = va_arg(argptr, int)) < QEMU_CAPS_LAST)
980 virQEMUCapsSet(qemuCaps, flag);
982 /* Some tests are run with NONE capabilities, which is just
983 * another name for QEMU_CAPS_LAST. If that is the case the
984 * arguments look like this :
986 * ARG_QEMU_CAPS, NONE, QEMU_CAPS_LAST, ARG_END
988 * Fetch one argument more and if it is QEMU_CAPS_LAST then
989 * break from the switch() to force getting next argument
990 * in the line. If it is not QEMU_CAPS_LAST then we've
991 * fetched real ARG_* and we must process it.
993 if ((flag = va_arg(argptr, int)) != QEMU_CAPS_LAST) {
994 argname = flag;
995 continue;
998 break;
1000 case ARG_GIC:
1001 gic = va_arg(argptr, int);
1002 break;
1004 case ARG_MIGRATE_FROM:
1005 info->migrateFrom = va_arg(argptr, char *);
1006 break;
1008 case ARG_MIGRATE_FD:
1009 info->migrateFd = va_arg(argptr, int);
1010 break;
1012 case ARG_FLAGS:
1013 info->flags = va_arg(argptr, int);
1014 break;
1016 case ARG_PARSEFLAGS:
1017 info->parseFlags = va_arg(argptr, int);
1018 break;
1020 case ARG_CAPS_ARCH:
1021 capsarch = va_arg(argptr, char *);
1022 break;
1024 case ARG_CAPS_VER:
1025 capsver = va_arg(argptr, char *);
1026 break;
1028 case ARG_END:
1029 default:
1030 fprintf(stderr, "Unexpected test info argument");
1031 goto cleanup;
1034 argname = va_arg(argptr, testQemuInfoArgName);
1037 if (!!capsarch ^ !!capsver) {
1038 fprintf(stderr, "ARG_CAPS_ARCH and ARG_CAPS_VER "
1039 "must be specified together.\n");
1040 goto cleanup;
1043 if (qemuCaps && (capsarch || capsver)) {
1044 fprintf(stderr, "ARG_QEMU_CAPS can not be combined with ARG_CAPS_ARCH "
1045 "or ARG_CAPS_VER\n");
1046 goto cleanup;
1049 if (!qemuCaps && capsarch && capsver) {
1050 bool stripmachinealiases = false;
1052 if (STREQ(capsver, "latest")) {
1053 if (VIR_STRDUP(capsfile, virHashLookup(capslatest, capsarch)) < 0)
1054 goto cleanup;
1055 stripmachinealiases = true;
1056 } else if (virAsprintf(&capsfile, "%s/caps_%s.%s.xml",
1057 TEST_QEMU_CAPS_PATH, capsver, capsarch) < 0) {
1058 goto cleanup;
1061 if (!(qemuCaps = qemuTestParseCapabilitiesArch(virArchFromString(capsarch),
1062 capsfile))) {
1063 goto cleanup;
1066 if (stripmachinealiases)
1067 virQEMUCapsStripMachineAliases(qemuCaps);
1068 info->flags |= FLAG_REAL_CAPS;
1071 if (!qemuCaps) {
1072 fprintf(stderr, "No qemuCaps generated\n");
1073 goto cleanup;
1075 VIR_STEAL_PTR(info->qemuCaps, qemuCaps);
1077 if (gic != GIC_NONE && testQemuCapsSetGIC(info->qemuCaps, gic) < 0)
1078 goto cleanup;
1080 ret = 0;
1082 cleanup:
1083 virObjectUnref(qemuCaps);
1084 va_end(argptr);
1086 return ret;
1090 void
1091 testQemuInfoClear(struct testQemuInfo *info)
1093 VIR_FREE(info->infile);
1094 VIR_FREE(info->outfile);
1095 virObjectUnref(info->qemuCaps);