mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 11:35:19 +00:00
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:
parent
12dc729a71
commit
21685c955e
2
cfg.mk
2
cfg.mk
@ -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)$$)
|
(\.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 = \
|
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)
|
_src2=src/(util/vircommand|libvirt|lxc/lxc_controller|locking/lock_daemon)
|
||||||
exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
|
exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
|
||||||
|
@ -302,9 +302,12 @@ pci_device_new_from_stub(const struct pciDevice *data)
|
|||||||
{
|
{
|
||||||
struct pciDevice *dev;
|
struct pciDevice *dev;
|
||||||
char *devpath;
|
char *devpath;
|
||||||
|
char *configSrc, *configDst;
|
||||||
char tmp[32];
|
char tmp[32];
|
||||||
|
struct stat sb;
|
||||||
|
|
||||||
if (VIR_ALLOC_QUIET(dev) < 0 ||
|
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)
|
virAsprintfQuiet(&devpath, "%s/devices/%s", fakesysfsdir, data->id) < 0)
|
||||||
ABORT_OOM();
|
ABORT_OOM();
|
||||||
|
|
||||||
@ -313,7 +316,21 @@ pci_device_new_from_stub(const struct pciDevice *data)
|
|||||||
if (virFileMakePath(devpath) < 0)
|
if (virFileMakePath(devpath) < 0)
|
||||||
ABORT("Unable to create: %s", devpath);
|
ABORT("Unable to create: %s", devpath);
|
||||||
|
|
||||||
|
/* 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");
|
make_file(devpath, "config", "some dummy config");
|
||||||
|
}
|
||||||
|
|
||||||
if (snprintf(tmp, sizeof(tmp), "0x%.4x", dev->vendor) < 0)
|
if (snprintf(tmp, sizeof(tmp), "0x%.4x", dev->vendor) < 0)
|
||||||
ABORT("@tmp overflow");
|
ABORT("@tmp overflow");
|
||||||
|
@ -61,7 +61,7 @@ cleanup:
|
|||||||
if ((count = virPCIDeviceListCount(list)) != cnt) { \
|
if ((count = virPCIDeviceListCount(list)) != cnt) { \
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, \
|
virReportError(VIR_ERR_INTERNAL_ERROR, \
|
||||||
"Unexpected count of items in " #list ": %d, " \
|
"Unexpected count of items in " #list ": %d, " \
|
||||||
"expecting " #cnt, count); \
|
"expecting %zu", count, (size_t) cnt); \
|
||||||
goto cleanup; \
|
goto cleanup; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,39 +69,115 @@ static int
|
|||||||
testVirPCIDeviceDetach(const void *oaque ATTRIBUTE_UNUSED)
|
testVirPCIDeviceDetach(const void *oaque ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
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;
|
virPCIDeviceListPtr activeDevs = NULL, inactiveDevs = NULL;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
if (!(dev = virPCIDeviceNew(0, 0, 1, 0)) ||
|
if (!(activeDevs = virPCIDeviceListNew()) ||
|
||||||
!(unbindedDev = virPCIDeviceNew(0, 0, 3, 0)) ||
|
|
||||||
!(activeDevs = virPCIDeviceListNew()) ||
|
|
||||||
!(inactiveDevs = virPCIDeviceListNew()))
|
!(inactiveDevs = virPCIDeviceListNew()))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
CHECK_LIST_COUNT(activeDevs, 0);
|
CHECK_LIST_COUNT(activeDevs, 0);
|
||||||
CHECK_LIST_COUNT(inactiveDevs, 0);
|
CHECK_LIST_COUNT(inactiveDevs, 0);
|
||||||
|
|
||||||
if (virPCIDeviceSetStubDriver(dev, "pci-stub") < 0 ||
|
for (i = 0; i < nDev; i++) {
|
||||||
virPCIDeviceSetStubDriver(unbindedDev, "pci-stub") < 0)
|
if (!(dev[i] = virPCIDeviceNew(0, 0, i + 1, 0)) ||
|
||||||
|
virPCIDeviceSetStubDriver(dev[i], "pci-stub") < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virPCIDeviceDetach(dev, activeDevs, inactiveDevs) < 0)
|
if (virPCIDeviceDetach(dev[i], activeDevs, inactiveDevs) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
CHECK_LIST_COUNT(activeDevs, 0);
|
CHECK_LIST_COUNT(activeDevs, 0);
|
||||||
CHECK_LIST_COUNT(inactiveDevs, 1);
|
CHECK_LIST_COUNT(inactiveDevs, i + 1);
|
||||||
|
}
|
||||||
if (virPCIDeviceDetach(unbindedDev, activeDevs, inactiveDevs) < 0)
|
|
||||||
goto cleanup;
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
CHECK_LIST_COUNT(activeDevs, 0);
|
for (i = 0; i < nDev; i++)
|
||||||
CHECK_LIST_COUNT(inactiveDevs, 2);
|
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;
|
ret = 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
virPCIDeviceFree(dev);
|
|
||||||
virPCIDeviceFree(unbindedDev);
|
|
||||||
virObjectUnref(activeDevs);
|
virObjectUnref(activeDevs);
|
||||||
virObjectUnref(inactiveDevs);
|
virObjectUnref(inactiveDevs);
|
||||||
return ret;
|
return ret;
|
||||||
@ -109,55 +185,6 @@ cleanup:
|
|||||||
|
|
||||||
# define FAKESYSFSDIRTEMPLATE abs_builddir "/fakesysfsdir-XXXXXX"
|
# 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
|
static int
|
||||||
mymain(void)
|
mymain(void)
|
||||||
{
|
{
|
||||||
@ -184,6 +211,7 @@ mymain(void)
|
|||||||
|
|
||||||
DO_TEST(testVirPCIDeviceNew);
|
DO_TEST(testVirPCIDeviceNew);
|
||||||
DO_TEST(testVirPCIDeviceDetach);
|
DO_TEST(testVirPCIDeviceDetach);
|
||||||
|
DO_TEST(testVirPCIDeviceReset);
|
||||||
DO_TEST(testVirPCIDeviceReattach);
|
DO_TEST(testVirPCIDeviceReattach);
|
||||||
|
|
||||||
if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)
|
if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)
|
||||||
|
BIN
tests/virpcitestdata/0000:00:01.0.config
Normal file
BIN
tests/virpcitestdata/0000:00:01.0.config
Normal file
Binary file not shown.
BIN
tests/virpcitestdata/0000:00:02.0.config
Normal file
BIN
tests/virpcitestdata/0000:00:02.0.config
Normal file
Binary file not shown.
BIN
tests/virpcitestdata/0000:00:03.0.config
Normal file
BIN
tests/virpcitestdata/0000:00:03.0.config
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user