1 #include <config.h>
2
3 #include <unistd.h>
4
5 #include <sys/types.h>
6 #include <fcntl.h>
7
8 #include "testutils.h"
9
10 #ifdef WITH_QEMU
11
12 # include "datatypes.h"
13 # include "internal.h"
14 # include "virstring.h"
15 # include "conf/domain_conf.h"
16 # include "qemu/qemu_domain.h"
17
18 # include "testutilsqemu.h"
19
20 # define VIR_FROM_THIS VIR_FROM_QEMU
21
22 static virQEMUDriver driver;
23
24 struct testInfo {
25 const char *name;
26 unsigned long long memlock;
27 };
28
29 static int
testCompareMemLock(const void * data)30 testCompareMemLock(const void *data)
31 {
32 const struct testInfo *info = data;
33 g_autoptr(virDomainDef) def = NULL;
34 g_autofree char *xml = NULL;
35
36 xml = g_strdup_printf("%s/qemumemlockdata/qemumemlock-%s.xml", abs_srcdir,
37 info->name);
38
39 if (!(def = virDomainDefParseFile(xml, driver.xmlopt, NULL,
40 VIR_DOMAIN_DEF_PARSE_INACTIVE))) {
41 return -1;
42 }
43
44 return virTestCompareToULL(info->memlock, qemuDomainGetMemLockLimitBytes(def, false));
45 }
46
47 # define FAKEROOTDIRTEMPLATE abs_builddir "/fakerootdir-XXXXXX"
48
49 static int
mymain(void)50 mymain(void)
51 {
52 int ret = 0;
53 g_autofree char *fakerootdir = NULL;
54 g_autoptr(virQEMUCaps) qemuCaps = NULL;
55
56 fakerootdir = g_strdup(FAKEROOTDIRTEMPLATE);
57
58 if (!g_mkdtemp(fakerootdir)) {
59 fprintf(stderr, "Cannot create fakerootdir");
60 abort();
61 }
62
63 g_setenv("LIBVIRT_FAKE_ROOT_DIR", fakerootdir, TRUE);
64
65 if (qemuTestDriverInit(&driver) < 0)
66 return EXIT_FAILURE;
67
68 driver.privileged = true;
69
70 # define DO_TEST(name, memlock) \
71 do { \
72 static struct testInfo info = { \
73 name, memlock \
74 }; \
75 if (virTestRun("QEMU MEMLOCK " name, testCompareMemLock, &info) < 0) \
76 ret = -1; \
77 } while (0)
78
79 /* The tests below make sure that the memory locking limit is being
80 * calculated correctly in a number of situations. Each test is
81 * performed both on x86_64/pc and ppc64/pseries in order to account
82 * for some architecture-specific details.
83 *
84 * kvm: simple KMV guest
85 * tcg: simple TCG guest
86 *
87 * hardlimit: guest where <memtune><hard_limit> has been configured
88 * locked: guest where <memoryBacking><locked> has been enabled
89 * hostdev: guest that has some hostdev assigned
90 *
91 * The remaining tests cover different combinations of the above to
92 * ensure settings are prioritized as expected.
93 */
94
95 qemuTestSetHostArch(&driver, VIR_ARCH_X86_64);
96
97 DO_TEST("pc-kvm", 0);
98 DO_TEST("pc-tcg", 0);
99
100 if (!(qemuCaps = virQEMUCapsNew())) {
101 ret = -1;
102 goto cleanup;
103 }
104
105 virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_VFIO_PCI);
106
107 if (qemuTestCapsCacheInsert(driver.qemuCapsCache, qemuCaps) < 0) {
108 ret = -1;
109 goto cleanup;
110 };
111
112 DO_TEST("pc-hardlimit", 2147483648);
113 DO_TEST("pc-locked", VIR_DOMAIN_MEMORY_PARAM_UNLIMITED);
114 DO_TEST("pc-hostdev", 2147483648);
115
116 DO_TEST("pc-hardlimit+locked", 2147483648);
117 DO_TEST("pc-hardlimit+hostdev", 2147483648);
118 DO_TEST("pc-hardlimit+locked+hostdev", 2147483648);
119 DO_TEST("pc-locked+hostdev", VIR_DOMAIN_MEMORY_PARAM_UNLIMITED);
120
121 qemuTestSetHostArch(&driver, VIR_ARCH_PPC64);
122
123 virQEMUCapsSet(qemuCaps, QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE);
124 if (qemuTestCapsCacheInsert(driver.qemuCapsCache, qemuCaps) < 0) {
125 ret = -1;
126 goto cleanup;
127 };
128
129 DO_TEST("pseries-kvm", 20971520);
130 DO_TEST("pseries-tcg", 0);
131
132 DO_TEST("pseries-hardlimit", 2147483648);
133 DO_TEST("pseries-locked", VIR_DOMAIN_MEMORY_PARAM_UNLIMITED);
134 DO_TEST("pseries-hostdev", 4320133120);
135
136 DO_TEST("pseries-hardlimit+locked", 2147483648);
137 DO_TEST("pseries-hardlimit+hostdev", 2147483648);
138 DO_TEST("pseries-hardlimit+locked+hostdev", 2147483648);
139 DO_TEST("pseries-locked+hostdev", VIR_DOMAIN_MEMORY_PARAM_UNLIMITED);
140
141 cleanup:
142 if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)
143 virFileDeleteTree(fakerootdir);
144
145 qemuTestDriverFree(&driver);
146
147 return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
148 }
149
150 VIR_TEST_MAIN_PRELOAD(mymain,
151 VIR_TEST_MOCK("virpci"),
152 VIR_TEST_MOCK("domaincaps"))
153
154 #else
155
156 int
157 main(void)
158 {
159 return EXIT_AM_SKIP;
160 }
161
162 #endif /* WITH_QEMU */
163