virpcitest: Introduce testVirPCIDeviceReset

This addition, however, requires some refactoring to be done.  First of
all, to match the best practice we should detach the device prior
resetting it. That's why testVirPCIDeviceDetach is detaching all devices
within 0000:00:01.0 and 0000:00:03.0 range. Then, the brand new test
will reset the 0000:00:02.0 device, so the last testVirPCIDeviceReattach
can reattach all the devices back.

In order to perform a PCI device reset, the dummy config file is not
sufficient anymore and must be replaced with real PCI config (binary
mess). Such config files are to be stored under tests/virpcitestdata/
and ought to have '.config' suffix.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Michal Privoznik 2013-11-05 15:07:49 +01:00
parent 12dc729a71
commit 21685c955e
6 changed files with 116 additions and 71 deletions

2
cfg.mk
View File

@ -971,7 +971,7 @@ exclude_file_name_regexp--sc_prohibit_close = \
(\.p[yl]$$|^docs/|^(src/util/virfile\.c|src/libvirt\.c|tests/vir(cgroup|pci)mock\.c)$$)
exclude_file_name_regexp--sc_prohibit_empty_lines_at_EOF = \
(^tests/(qemuhelp|nodeinfo)data/|\.(gif|ico|png|diff)$$)
(^tests/(qemuhelp|nodeinfo|virpcitest)data/|\.(gif|ico|png|diff)$$)
_src2=src/(util/vircommand|libvirt|lxc/lxc_controller|locking/lock_daemon)
exclude_file_name_regexp--sc_prohibit_fork_wrappers = \

View File

@ -302,9 +302,12 @@ pci_device_new_from_stub(const struct pciDevice *data)
{
struct pciDevice *dev;
char *devpath;
char *configSrc, *configDst;
char tmp[32];
struct stat sb;
if (VIR_ALLOC_QUIET(dev) < 0 ||
virAsprintfQuiet(&configSrc, "%s/virpcitestdata/%s.config", abs_builddir, data->id) < 0 ||
virAsprintfQuiet(&devpath, "%s/devices/%s", fakesysfsdir, data->id) < 0)
ABORT_OOM();
@ -313,7 +316,21 @@ pci_device_new_from_stub(const struct pciDevice *data)
if (virFileMakePath(devpath) < 0)
ABORT("Unable to create: %s", devpath);
make_file(devpath, "config", "some dummy config");
/* If there is a config file for the device within virpcitestdata dir,
* symlink it. Otherwise create a dummy config file. */
if ((realstat && realstat(configSrc, &sb) == 0) ||
(real__xstat && real__xstat(_STAT_VER, configSrc, &sb) == 0)) {
/* On success make symlink to @configSrc */
if (virAsprintfQuiet(&configDst, "%s/config", devpath) < 0)
ABORT_OOM();
if (symlink(configSrc, configDst) < 0)
ABORT("Unable to create symlink: %s", configDst);
} else {
/* If there's no config data in the virpcitestdata dir, create a dummy
* config file */
make_file(devpath, "config", "some dummy config");
}
if (snprintf(tmp, sizeof(tmp), "0x%.4x", dev->vendor) < 0)
ABORT("@tmp overflow");

View File

@ -61,7 +61,7 @@ cleanup:
if ((count = virPCIDeviceListCount(list)) != cnt) { \
virReportError(VIR_ERR_INTERNAL_ERROR, \
"Unexpected count of items in " #list ": %d, " \
"expecting " #cnt, count); \
"expecting %zu", count, (size_t) cnt); \
goto cleanup; \
}
@ -69,39 +69,115 @@ static int
testVirPCIDeviceDetach(const void *oaque ATTRIBUTE_UNUSED)
{
int ret = -1;
virPCIDevicePtr dev = NULL, unbindedDev = NULL;
virPCIDevicePtr dev[] = {NULL, NULL, NULL};
size_t i, nDev = ARRAY_CARDINALITY(dev);
virPCIDeviceListPtr activeDevs = NULL, inactiveDevs = NULL;
int count;
if (!(dev = virPCIDeviceNew(0, 0, 1, 0)) ||
!(unbindedDev = virPCIDeviceNew(0, 0, 3, 0)) ||
!(activeDevs = virPCIDeviceListNew()) ||
if (!(activeDevs = virPCIDeviceListNew()) ||
!(inactiveDevs = virPCIDeviceListNew()))
goto cleanup;
CHECK_LIST_COUNT(activeDevs, 0);
CHECK_LIST_COUNT(inactiveDevs, 0);
if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0 ||
virPCIDeviceSetStubDriver(unbindedDev, "pci-stub") < 0)
goto cleanup;
for (i = 0; i < nDev; i++) {
if (!(dev[i] = virPCIDeviceNew(0, 0, i + 1, 0)) ||
virPCIDeviceSetStubDriver(dev[i], "pci-stub") < 0)
goto cleanup;
if (virPCIDeviceDetach(dev, activeDevs, inactiveDevs) < 0)
goto cleanup;
if (virPCIDeviceDetach(dev[i], activeDevs, inactiveDevs) < 0)
goto cleanup;
CHECK_LIST_COUNT(activeDevs, 0);
CHECK_LIST_COUNT(inactiveDevs, 1);
if (virPCIDeviceDetach(unbindedDev, activeDevs, inactiveDevs) < 0)
goto cleanup;
CHECK_LIST_COUNT(activeDevs, 0);
CHECK_LIST_COUNT(inactiveDevs, 2);
CHECK_LIST_COUNT(activeDevs, 0);
CHECK_LIST_COUNT(inactiveDevs, i + 1);
}
ret = 0;
cleanup:
for (i = 0; i < nDev; i++)
virPCIDeviceFree(dev[i]);
virObjectUnref(activeDevs);
virObjectUnref(inactiveDevs);
return ret;
}
static int
testVirPCIDeviceReset(const void *opaque ATTRIBUTE_UNUSED)
{
int ret = -1;
virPCIDevicePtr dev[] = {NULL, NULL, NULL};
size_t i, nDev = ARRAY_CARDINALITY(dev);
virPCIDeviceListPtr activeDevs = NULL, inactiveDevs = NULL;
int count;
if (!(activeDevs = virPCIDeviceListNew()) ||
!(inactiveDevs = virPCIDeviceListNew()))
goto cleanup;
CHECK_LIST_COUNT(activeDevs, 0);
CHECK_LIST_COUNT(inactiveDevs, 0);
for (i = 0; i < nDev; i++) {
if (!(dev[i] = virPCIDeviceNew(0, 0, i + 1, 0)) ||
virPCIDeviceSetStubDriver(dev[i], "pci-stub") < 0)
goto cleanup;
if (virPCIDeviceReset(dev[i], activeDevs, inactiveDevs) < 0)
goto cleanup;
}
ret = 0;
cleanup:
for (i = 0; i < nDev; i++)
virPCIDeviceFree(dev[i]);
virObjectUnref(activeDevs);
virObjectUnref(inactiveDevs);
return ret;
}
static int
testVirPCIDeviceReattach(const void *opaque ATTRIBUTE_UNUSED)
{
int ret = -1;
virPCIDevicePtr dev[] = {NULL, NULL, NULL};
size_t i, nDev = ARRAY_CARDINALITY(dev);
virPCIDeviceListPtr activeDevs = NULL, inactiveDevs = NULL;
int count;
if (!(activeDevs = virPCIDeviceListNew()) ||
!(inactiveDevs = virPCIDeviceListNew()))
goto cleanup;
for (i = 0; i < nDev; i++) {
if (!(dev[i] = virPCIDeviceNew(0, 0, i + 1, 0)))
goto cleanup;
if (virPCIDeviceListAdd(inactiveDevs, dev[i]) < 0) {
virPCIDeviceFree(dev[i]);
goto cleanup;
}
CHECK_LIST_COUNT(activeDevs, 0);
CHECK_LIST_COUNT(inactiveDevs, i + 1);
if (virPCIDeviceSetStubDriver(dev[i], "pci-stub") < 0)
goto cleanup;
}
CHECK_LIST_COUNT(activeDevs, 0);
CHECK_LIST_COUNT(inactiveDevs, nDev);
for (i = 0; i < nDev; i++) {
if (virPCIDeviceReattach(dev[i], activeDevs, inactiveDevs) < 0)
goto cleanup;
CHECK_LIST_COUNT(activeDevs, 0);
CHECK_LIST_COUNT(inactiveDevs, nDev - i - 1);
}
ret = 0;
cleanup:
virPCIDeviceFree(dev);
virPCIDeviceFree(unbindedDev);
virObjectUnref(activeDevs);
virObjectUnref(inactiveDevs);
return ret;
@ -109,55 +185,6 @@ cleanup:
# define FAKESYSFSDIRTEMPLATE abs_builddir "/fakesysfsdir-XXXXXX"
static int
testVirPCIDeviceReattach(const void *oaque ATTRIBUTE_UNUSED)
{
int ret = -1;
virPCIDevicePtr dev = NULL, unbindedDev = NULL;
virPCIDeviceListPtr activeDevs = NULL, inactiveDevs = NULL;
int count;
if (!(dev = virPCIDeviceNew(0, 0, 1, 0)) ||
!(unbindedDev = virPCIDeviceNew(0, 0, 3, 0)) ||
!(activeDevs = virPCIDeviceListNew()) ||
!(inactiveDevs = virPCIDeviceListNew()))
goto cleanup;
if (virPCIDeviceListAdd(inactiveDevs, dev) < 0) {
virPCIDeviceFree(dev);
virPCIDeviceFree(unbindedDev);
goto cleanup;
}
if (virPCIDeviceListAdd(inactiveDevs, unbindedDev) < 0) {
virPCIDeviceFree(unbindedDev);
goto cleanup;
}
CHECK_LIST_COUNT(activeDevs, 0);
CHECK_LIST_COUNT(inactiveDevs, 2);
if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0)
goto cleanup;
if (virPCIDeviceReattach(dev, activeDevs, inactiveDevs) < 0)
goto cleanup;
CHECK_LIST_COUNT(activeDevs, 0);
CHECK_LIST_COUNT(inactiveDevs, 1);
if (virPCIDeviceReattach(unbindedDev, activeDevs, inactiveDevs) < 0)
goto cleanup;
CHECK_LIST_COUNT(activeDevs, 0);
CHECK_LIST_COUNT(inactiveDevs, 0);
ret = 0;
cleanup:
virObjectUnref(activeDevs);
virObjectUnref(inactiveDevs);
return ret;
}
static int
mymain(void)
{
@ -184,6 +211,7 @@ mymain(void)
DO_TEST(testVirPCIDeviceNew);
DO_TEST(testVirPCIDeviceDetach);
DO_TEST(testVirPCIDeviceReset);
DO_TEST(testVirPCIDeviceReattach);
if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)

Binary file not shown.

Binary file not shown.

Binary file not shown.