2 * Copyright (C) 2013, 2014 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see
16 * <http://www.gnu.org/licenses/>.
21 #include "testutils.h"
25 # include <sys/types.h>
26 # include <sys/stat.h>
30 # define VIR_FROM_THIS VIR_FROM_NONE
33 testVirPCIDeviceCheckDriver(virPCIDevicePtr dev
, const char *expected
)
39 if (virPCIDeviceGetDriverPathAndName(dev
, &path
, &driver
) < 0)
42 if (STRNEQ_NULLABLE(driver
, expected
)) {
43 virReportError(VIR_ERR_INTERNAL_ERROR
,
44 "PCI device %s driver mismatch: %s, expecting %s",
45 virPCIDeviceGetName(dev
), NULLSTR(driver
),
58 testVirPCIDeviceNew(const void *opaque ATTRIBUTE_UNUSED
)
64 if (!(dev
= virPCIDeviceNew(0, 0, 0, 0)))
67 devName
= virPCIDeviceGetName(dev
);
68 if (STRNEQ(devName
, "0000:00:00.0")) {
69 virReportError(VIR_ERR_INTERNAL_ERROR
,
70 "PCI device name mismatch: %s, expecting %s",
71 devName
, "0000:00:00.0");
77 virPCIDeviceFree(dev
);
81 # define CHECK_LIST_COUNT(list, cnt) \
82 if ((count = virPCIDeviceListCount(list)) != cnt) { \
83 virReportError(VIR_ERR_INTERNAL_ERROR, \
84 "Unexpected count of items in " #list ": %d, " \
85 "expecting %zu", count, (size_t) cnt); \
90 testVirPCIDeviceDetach(const void *opaque ATTRIBUTE_UNUSED
)
93 virPCIDevicePtr dev
[] = {NULL
, NULL
, NULL
};
94 size_t i
, nDev
= ARRAY_CARDINALITY(dev
);
95 virPCIDeviceListPtr activeDevs
= NULL
, inactiveDevs
= NULL
;
98 if (!(activeDevs
= virPCIDeviceListNew()) ||
99 !(inactiveDevs
= virPCIDeviceListNew()))
102 CHECK_LIST_COUNT(activeDevs
, 0);
103 CHECK_LIST_COUNT(inactiveDevs
, 0);
105 for (i
= 0; i
< nDev
; i
++) {
106 if (!(dev
[i
] = virPCIDeviceNew(0, 0, i
+ 1, 0)))
109 virPCIDeviceSetStubDriver(dev
[i
], VIR_PCI_STUB_DRIVER_VFIO
);
111 if (virPCIDeviceDetach(dev
[i
], activeDevs
, inactiveDevs
) < 0)
114 if (testVirPCIDeviceCheckDriver(dev
[i
], "vfio-pci") < 0)
117 CHECK_LIST_COUNT(activeDevs
, 0);
118 CHECK_LIST_COUNT(inactiveDevs
, i
+ 1);
123 for (i
= 0; i
< nDev
; i
++)
124 virPCIDeviceFree(dev
[i
]);
125 virObjectUnref(activeDevs
);
126 virObjectUnref(inactiveDevs
);
131 testVirPCIDeviceReset(const void *opaque ATTRIBUTE_UNUSED
)
134 virPCIDevicePtr dev
[] = {NULL
, NULL
, NULL
};
135 size_t i
, nDev
= ARRAY_CARDINALITY(dev
);
136 virPCIDeviceListPtr activeDevs
= NULL
, inactiveDevs
= NULL
;
139 if (!(activeDevs
= virPCIDeviceListNew()) ||
140 !(inactiveDevs
= virPCIDeviceListNew()))
143 CHECK_LIST_COUNT(activeDevs
, 0);
144 CHECK_LIST_COUNT(inactiveDevs
, 0);
146 for (i
= 0; i
< nDev
; i
++) {
147 if (!(dev
[i
] = virPCIDeviceNew(0, 0, i
+ 1, 0)))
150 virPCIDeviceSetStubDriver(dev
[i
], VIR_PCI_STUB_DRIVER_VFIO
);
152 if (virPCIDeviceReset(dev
[i
], activeDevs
, inactiveDevs
) < 0)
158 for (i
= 0; i
< nDev
; i
++)
159 virPCIDeviceFree(dev
[i
]);
160 virObjectUnref(activeDevs
);
161 virObjectUnref(inactiveDevs
);
166 testVirPCIDeviceReattach(const void *opaque ATTRIBUTE_UNUSED
)
169 virPCIDevicePtr dev
[] = {NULL
, NULL
, NULL
};
170 size_t i
, nDev
= ARRAY_CARDINALITY(dev
);
171 virPCIDeviceListPtr activeDevs
= NULL
, inactiveDevs
= NULL
;
174 if (!(activeDevs
= virPCIDeviceListNew()) ||
175 !(inactiveDevs
= virPCIDeviceListNew()))
178 for (i
= 0; i
< nDev
; i
++) {
179 if (!(dev
[i
] = virPCIDeviceNew(0, 0, i
+ 1, 0)))
182 if (virPCIDeviceListAdd(inactiveDevs
, dev
[i
]) < 0) {
183 virPCIDeviceFree(dev
[i
]);
187 CHECK_LIST_COUNT(activeDevs
, 0);
188 CHECK_LIST_COUNT(inactiveDevs
, i
+ 1);
190 virPCIDeviceSetStubDriver(dev
[i
], VIR_PCI_STUB_DRIVER_VFIO
);
193 CHECK_LIST_COUNT(activeDevs
, 0);
194 CHECK_LIST_COUNT(inactiveDevs
, nDev
);
196 for (i
= 0; i
< nDev
; i
++) {
197 if (virPCIDeviceReattach(dev
[i
], activeDevs
, inactiveDevs
) < 0)
200 CHECK_LIST_COUNT(activeDevs
, 0);
201 CHECK_LIST_COUNT(inactiveDevs
, nDev
- i
- 1);
206 virObjectUnref(activeDevs
);
207 virObjectUnref(inactiveDevs
);
211 struct testPCIDevData
{
215 unsigned int function
;
220 testVirPCIDeviceIsAssignable(const void *opaque
)
222 const struct testPCIDevData
*data
= opaque
;
226 if (!(dev
= virPCIDeviceNew(data
->domain
, data
->bus
, data
->slot
, data
->function
)))
229 if (virPCIDeviceIsAssignable(dev
, true))
232 virPCIDeviceFree(dev
);
238 testVirPCIDeviceDetachSingle(const void *opaque
)
240 const struct testPCIDevData
*data
= opaque
;
244 dev
= virPCIDeviceNew(data
->domain
, data
->bus
, data
->slot
, data
->function
);
248 virPCIDeviceSetStubDriver(dev
, VIR_PCI_STUB_DRIVER_VFIO
);
250 if (virPCIDeviceDetach(dev
, NULL
, NULL
) < 0)
255 virPCIDeviceFree(dev
);
260 testVirPCIDeviceReattachSingle(const void *opaque
)
262 const struct testPCIDevData
*data
= opaque
;
266 dev
= virPCIDeviceNew(data
->domain
, data
->bus
, data
->slot
, data
->function
);
270 virPCIDeviceSetUnbindFromStub(dev
, true);
271 virPCIDeviceSetRemoveSlot(dev
, true);
272 virPCIDeviceSetReprobe(dev
, true);
274 if (virPCIDeviceReattach(dev
, NULL
, NULL
) < 0)
279 virPCIDeviceFree(dev
);
284 testVirPCIDeviceCheckDriverTest(const void *opaque
)
286 const struct testPCIDevData
*data
= opaque
;
290 dev
= virPCIDeviceNew(data
->domain
, data
->bus
, data
->slot
, data
->function
);
294 if (testVirPCIDeviceCheckDriver(dev
, data
->driver
) < 0)
299 virPCIDeviceFree(dev
);
304 testVirPCIDeviceUnbind(const void *opaque
)
306 const struct testPCIDevData
*data
= opaque
;
310 dev
= virPCIDeviceNew(data
->domain
, data
->bus
, data
->slot
, data
->function
);
314 if (virPCIDeviceUnbind(dev
) < 0)
319 virPCIDeviceFree(dev
);
323 # define FAKEROOTDIRTEMPLATE abs_builddir "/fakerootdir-XXXXXX"
331 if (VIR_STRDUP_QUIET(fakerootdir
, FAKEROOTDIRTEMPLATE
) < 0) {
332 VIR_TEST_DEBUG("Out of memory\n");
336 if (!mkdtemp(fakerootdir
)) {
337 VIR_TEST_DEBUG("Cannot create fakerootdir");
341 setenv("LIBVIRT_FAKE_ROOT_DIR", fakerootdir
, 1);
343 # define DO_TEST(fnc) \
345 if (virTestRun(#fnc, fnc, NULL) < 0) \
349 # define DO_TEST_PCI(fnc, domain, bus, slot, function) \
351 struct testPCIDevData data = { \
352 domain, bus, slot, function, NULL \
354 char *label = NULL; \
355 if (virAsprintf(&label, "%s(%04x:%02x:%02x.%x)", \
356 #fnc, domain, bus, slot, function) < 0) { \
360 if (virTestRun(label, fnc, &data) < 0) \
365 # define DO_TEST_PCI_DRIVER(domain, bus, slot, function, driver) \
367 struct testPCIDevData data = { \
368 domain, bus, slot, function, driver \
370 char *label = NULL; \
371 if (virAsprintf(&label, "PCI driver %04x:%02x:%02x.%x is %s", \
372 domain, bus, slot, function, \
373 NULLSTR(driver)) < 0) { \
377 if (virTestRun(label, testVirPCIDeviceCheckDriverTest, \
383 /* Changes made to individual devices are persistent and the
384 * tests often rely on the state set by previous tests.
387 DO_TEST(testVirPCIDeviceNew
);
388 DO_TEST(testVirPCIDeviceDetach
);
389 DO_TEST(testVirPCIDeviceReset
);
390 DO_TEST(testVirPCIDeviceReattach
);
391 DO_TEST_PCI(testVirPCIDeviceIsAssignable
, 5, 0x90, 1, 0);
392 DO_TEST_PCI(testVirPCIDeviceIsAssignable
, 1, 1, 0, 0);
394 /* Reattach a device already bound to non-stub a driver */
395 DO_TEST_PCI_DRIVER(0, 0x0a, 1, 0, "i915");
396 DO_TEST_PCI(testVirPCIDeviceReattachSingle
, 0, 0x0a, 1, 0);
397 DO_TEST_PCI_DRIVER(0, 0x0a, 1, 0, "i915");
399 /* Reattach an unbound device */
400 DO_TEST_PCI(testVirPCIDeviceUnbind
, 0, 0x0a, 1, 0);
401 DO_TEST_PCI_DRIVER(0, 0x0a, 1, 0, NULL
);
402 DO_TEST_PCI(testVirPCIDeviceReattachSingle
, 0, 0x0a, 1, 0);
403 DO_TEST_PCI_DRIVER(0, 0x0a, 1, 0, "i915");
405 /* Detach an unbound device */
406 DO_TEST_PCI_DRIVER(0, 0x0a, 2, 0, NULL
);
407 DO_TEST_PCI(testVirPCIDeviceDetachSingle
, 0, 0x0a, 2, 0);
408 DO_TEST_PCI_DRIVER(0, 0x0a, 2, 0, "vfio-pci");
410 /* Reattach an unknown unbound device */
411 DO_TEST_PCI_DRIVER(0, 0x0a, 3, 0, NULL
);
412 DO_TEST_PCI(testVirPCIDeviceReattachSingle
, 0, 0x0a, 3, 0);
413 DO_TEST_PCI_DRIVER(0, 0x0a, 3, 0, NULL
);
415 if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL
)
416 virFileDeleteTree(fakerootdir
);
418 VIR_FREE(fakerootdir
);
420 return ret
== 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;
423 VIR_TEST_MAIN_PRELOAD(mymain
, abs_builddir
"/.libs/virpcimock.so")