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