2 * Copyright (C) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
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/>.
18 * Author: Chunyan Liu <cyliu@suse.com>
23 #include "testutils.h"
29 # include <sys/types.h>
30 # include <sys/stat.h>
31 # include <sys/ioctl.h>
34 # include "virhostdev.h"
36 # define VIR_FROM_THIS VIR_FROM_NONE
38 VIR_LOG_INIT("tests.hostdevtest");
40 # define CHECK_LIST_COUNT(list, cnt) \
41 if ((count = virPCIDeviceListCount(list)) != cnt) { \
42 virReportError(VIR_ERR_INTERNAL_ERROR, \
43 "Unexpected count of items in " #list ": %d, " \
44 "expecting %zu", count, (size_t) cnt); \
48 # define TEST_STATE_DIR abs_builddir "/hostdevmgr"
49 static const char *drv_name = "test_driver";
50 static const char *dom_name = "test_domain";
51 static const unsigned char *uuid =
52 (unsigned char *)("f92360b0-2541-8791-fb32-d1f838811541");
53 static int nhostdevs = 3;
54 static virDomainHostdevDefPtr hostdevs[] = {NULL, NULL, NULL};
55 static virPCIDevicePtr dev[] = {NULL, NULL, NULL};
56 static virHostdevManagerPtr mgr = NULL;
62 for (i = 0; i < nhostdevs; i++) {
63 virPCIDeviceFree(dev[i]);
64 virDomainHostdevDefFree(hostdevs[i]);
68 if (mgr->stateDir && !getenv("LIBVIRT_SKIP_CLEANUP"))
69 virFileDeleteTree(mgr->stateDir);
71 virObjectUnref(mgr->activePCIHostdevs);
72 virObjectUnref(mgr->inactivePCIHostdevs);
73 virObjectUnref(mgr->activeUSBHostdevs);
74 VIR_FREE(mgr->stateDir);
84 for (i = 0; i < nhostdevs; i++) {
85 virDomainHostdevSubsys subsys;
86 hostdevs[i] = virDomainHostdevDefAlloc();
89 hostdevs[i]->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
90 subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
91 subsys.u.pci.addr.domain = 0;
92 subsys.u.pci.addr.bus = 0;
93 subsys.u.pci.addr.slot = i + 1;
94 subsys.u.pci.addr.function = 0;
95 subsys.u.pci.backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM;
96 hostdevs[i]->source.subsys = subsys;
99 for (i = 0; i < nhostdevs; i++) {
100 if (!(dev[i] = virPCIDeviceNew(0, 0, i + 1, 0)) ||
101 virPCIDeviceSetStubDriver(dev[i], "pci-stub") < 0)
105 if (VIR_ALLOC(mgr) < 0)
107 if ((mgr->activePCIHostdevs = virPCIDeviceListNew()) == NULL)
109 if ((mgr->activeUSBHostdevs = virUSBDeviceListNew()) == NULL)
111 if ((mgr->inactivePCIHostdevs = virPCIDeviceListNew()) == NULL)
113 if ((mgr->activeSCSIHostdevs = virSCSIDeviceListNew()) == NULL)
115 if (VIR_STRDUP(mgr->stateDir, TEST_STATE_DIR) < 0)
117 if (virFileMakePath(mgr->stateDir) < 0)
127 # if HAVE_LINUX_KVM_H
128 # include <linux/kvm.h>
130 virHostdevHostSupportsPassthroughKVM(void)
135 if ((kvmfd = open("/dev/kvm", O_RDONLY)) < 0)
138 # ifdef KVM_CAP_IOMMU
139 if ((ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_IOMMU)) <= 0)
146 VIR_FORCE_CLOSE(kvmfd);
152 virHostdevHostSupportsPassthroughKVM(void)
159 testVirHostdevPreparePCIHostdevs_unmanaged(const void *oaque ATTRIBUTE_UNUSED)
163 int count, count1, count2;
165 for (i = 0; i < nhostdevs; i++)
166 hostdevs[i]->managed = false;
168 count1 = virPCIDeviceListCount(mgr->activePCIHostdevs);
169 count2 = virPCIDeviceListCount(mgr->inactivePCIHostdevs);
171 /* Test normal functionality */
172 VIR_DEBUG("Test 0 hostdevs\n");
173 if (virHostdevPreparePCIDevices(mgr, drv_name, dom_name, uuid,
176 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1);
178 /* Test unmanaged hostdevs */
179 VIR_DEBUG("Test >=1 unmanaged hostdevs\n");
180 if (virHostdevPreparePCIDevices(mgr, drv_name, dom_name, uuid,
181 hostdevs, nhostdevs, 0) < 0)
183 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1 + 3);
184 CHECK_LIST_COUNT(mgr->inactivePCIHostdevs, count2 - 3);
187 count1 = virPCIDeviceListCount(mgr->activePCIHostdevs);
188 count2 = virPCIDeviceListCount(mgr->inactivePCIHostdevs);
189 VIR_DEBUG("Test: prepare same hostdevs for same driver/domain again\n");
190 if (!virHostdevPreparePCIDevices(mgr, drv_name, dom_name, uuid,
193 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1);
194 CHECK_LIST_COUNT(mgr->inactivePCIHostdevs, count2);
196 VIR_DEBUG("Test: prepare same hostdevs for same driver, diff domain again\n");
197 if (!virHostdevPreparePCIDevices(mgr, drv_name, "test_domain1", uuid,
200 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1);
201 CHECK_LIST_COUNT(mgr->inactivePCIHostdevs, count2);
203 VIR_DEBUG("Test: prepare same hostdevs for diff driver/domain again\n");
204 if (!virHostdevPreparePCIDevices(mgr, "test_driver1", dom_name, uuid,
207 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1);
208 CHECK_LIST_COUNT(mgr->inactivePCIHostdevs, count2);
218 testVirHostdevReAttachPCIHostdevs_unmanaged(const void *oaque ATTRIBUTE_UNUSED)
222 int count, count1, count2;
224 for (i = 0; i < nhostdevs; i++) {
225 if (hostdevs[i]->managed != false) {
226 VIR_DEBUG("invalid test\n");
231 count1 = virPCIDeviceListCount(mgr->activePCIHostdevs);
232 count2 = virPCIDeviceListCount(mgr->inactivePCIHostdevs);
234 VIR_DEBUG("Test 0 hostdevs\n");
235 virHostdevReAttachPCIDevices(mgr, drv_name, dom_name, NULL, 0, NULL);
236 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1);
238 VIR_DEBUG("Test >=1 unmanaged hostdevs\n");
239 virHostdevReAttachPCIDevices(mgr, drv_name, dom_name,
240 hostdevs, nhostdevs, NULL);
241 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1 - 3);
242 CHECK_LIST_COUNT(mgr->inactivePCIHostdevs, count2 + 3);
252 testVirHostdevPreparePCIHostdevs_managed(const void *oaque ATTRIBUTE_UNUSED)
258 for (i = 0; i < nhostdevs; i++)
259 hostdevs[i]->managed = true;
261 count1 = virPCIDeviceListCount(mgr->activePCIHostdevs);
263 /* Test normal functionality */
264 VIR_DEBUG("Test >=1 hostdevs\n");
265 if (virHostdevPreparePCIDevices(mgr, drv_name, dom_name, uuid,
266 hostdevs, nhostdevs, 0) < 0)
268 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1 + 3);
271 count1 = virPCIDeviceListCount(mgr->activePCIHostdevs);
272 VIR_DEBUG("Test: prepare same hostdevs for same driver/domain again\n");
273 if (!virHostdevPreparePCIDevices(mgr, drv_name, dom_name, uuid,
276 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1);
278 VIR_DEBUG("Test: prepare same hostdevs for same driver, diff domain again\n");
279 if (!virHostdevPreparePCIDevices(mgr, drv_name, "test_domain1", uuid,
282 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1);
284 VIR_DEBUG("Test: prepare same hostdevs for diff driver/domain again\n");
285 if (!virHostdevPreparePCIDevices(mgr, "test_driver1", dom_name, uuid,
288 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1);
298 testVirHostdevReAttachPCIHostdevs_managed(const void *oaque ATTRIBUTE_UNUSED)
304 for (i = 0; i < nhostdevs; i++) {
305 if (hostdevs[i]->managed != true) {
306 VIR_DEBUG("invalid test\n");
311 count1 = virPCIDeviceListCount(mgr->activePCIHostdevs);
313 VIR_DEBUG("Test 0 hostdevs\n");
314 virHostdevReAttachPCIDevices(mgr, drv_name, dom_name, NULL, 0, NULL);
315 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1);
317 VIR_DEBUG("Test >=1 hostdevs\n");
318 virHostdevReAttachPCIDevices(mgr, drv_name, dom_name,
319 hostdevs, nhostdevs, NULL);
320 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1 - 3);
330 testVirHostdevDetachPCINodeDevice(const void *oaque ATTRIBUTE_UNUSED)
336 for (i = 0; i < nhostdevs; i++) {
337 count1 = virPCIDeviceListCount(mgr->inactivePCIHostdevs);
338 if (virHostdevPCINodeDeviceDetach(mgr, dev[i]) < 0)
340 CHECK_LIST_COUNT(mgr->inactivePCIHostdevs, count1 + 1);
349 testVirHostdevResetPCINodeDevice(const void *oaque ATTRIBUTE_UNUSED)
354 for (i = 0; i < nhostdevs; i++) {
355 if (virHostdevPCINodeDeviceReset(mgr, dev[i]) < 0)
367 testVirHostdevReAttachPCINodeDevice(const void *oaque ATTRIBUTE_UNUSED)
373 for (i = 0; i < nhostdevs; i++) {
374 count1 = virPCIDeviceListCount(mgr->inactivePCIHostdevs);
375 if (virHostdevPCINodeDeviceReAttach(mgr, dev[i]) < 0)
377 CHECK_LIST_COUNT(mgr->inactivePCIHostdevs, count1 - 1);
388 testVirHostdevUpdateActivePCIHostdevs(const void *oaque ATTRIBUTE_UNUSED)
393 count1 = virPCIDeviceListCount(mgr->activePCIHostdevs);
395 VIR_DEBUG("Test 0 hostdevs\n");
396 if (virHostdevUpdateActivePCIDevices(mgr, NULL, 0,
397 drv_name, dom_name) < 0)
399 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1);
401 VIR_DEBUG("Test >=1 hostdevs\n");
402 if (virHostdevUpdateActivePCIDevices(mgr, hostdevs, nhostdevs,
403 drv_name, dom_name) < 0)
405 CHECK_LIST_COUNT(mgr->activePCIHostdevs, count1 + 3);
413 # define FAKESYSFSDIRTEMPLATE abs_builddir "/fakesysfsdir-XXXXXX"
421 if (VIR_STRDUP_QUIET(fakesysfsdir, FAKESYSFSDIRTEMPLATE) < 0) {
422 fprintf(stderr, "Out of memory\n");
426 if (!mkdtemp(fakesysfsdir)) {
427 fprintf(stderr, "Cannot create fakesysfsdir");
431 setenv("LIBVIRT_FAKE_SYSFS_DIR", fakesysfsdir, 1);
433 # define DO_TEST(fnc) \
435 VIR_DEBUG("\nTesting: %s", #fnc); \
436 if (virtTestRun(#fnc, fnc, NULL) < 0) \
441 fprintf(stderr, "Init data structures failed.");
443 DO_TEST(testVirHostdevDetachPCINodeDevice);
444 if (virHostdevHostSupportsPassthroughKVM()) {
445 /* following tests would check KVM support */
446 DO_TEST(testVirHostdevPreparePCIHostdevs_unmanaged);
447 DO_TEST(testVirHostdevReAttachPCIHostdevs_unmanaged);
449 DO_TEST(testVirHostdevResetPCINodeDevice);
450 DO_TEST(testVirHostdevReAttachPCINodeDevice);
451 if (virHostdevHostSupportsPassthroughKVM()) {
452 /* following tests would check KVM support */
453 DO_TEST(testVirHostdevPreparePCIHostdevs_managed);
454 DO_TEST(testVirHostdevReAttachPCIHostdevs_managed);
456 DO_TEST(testVirHostdevUpdateActivePCIHostdevs);
460 if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)
461 virFileDeleteTree(fakesysfsdir);
463 VIR_FREE(fakesysfsdir);
465 return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
468 VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virpcimock.so")