From e821de2c5a7e3d9f122f7f30e4e97edc30d6506a Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Nov 27 2013 22:06:15 +0000 Subject: tests: fix virpcitest with read-only srcdir 'make distcheck' has been broken since commit 21685c9; basically, it emulates the case of a read-only $(srcdir) (such as building from a tarball exploded onto a CD-ROM), but we were creating our fake pci device as a symlink into $(srcdir) and failing when that requires opening the config file for writing: 3) testVirPCIDeviceReset ... libvirt: error : Failed to open config space file '/sys/bus/pci/devices/0000:00:01.0/config': Permission denied Fix it by copying rather than symlinking. * tests/virpcimock.c (make_file): Add parameter to allow binary creation; adjust all callers. (pci_device_new_from_stub): Copy rather than symlink. Signed-off-by: Eric Blake --- diff --git a/tests/virpcimock.c b/tests/virpcimock.c index 48d5f16..a5cef46 100644 --- a/tests/virpcimock.c +++ b/tests/virpcimock.c @@ -154,10 +154,13 @@ static int pci_driver_handle_remove_id(const char *path); static void make_file(const char *path, const char *name, - const char *value) + const char *value, + ssize_t len) { int fd = -1; char *filepath = NULL; + if (value && len == -1) + len = strlen(value); if (virAsprintfQuiet(&filepath, "%s/%s", path, name) < 0) ABORT_OOM(); @@ -165,7 +168,7 @@ make_file(const char *path, if ((fd = realopen(filepath, O_CREAT|O_WRONLY, 0666)) < 0) ABORT("Unable to open: %s", filepath); - if (value && safewrite(fd, value, strlen(value)) != strlen(value)) + if (value && safewrite(fd, value, len) != len) ABORT("Unable to write: %s", filepath); VIR_FORCE_CLOSE(fd); @@ -302,7 +305,7 @@ pci_device_new_from_stub(const struct pciDevice *data) { struct pciDevice *dev; char *devpath; - char *configSrc, *configDst; + char *configSrc; char tmp[32]; struct stat sb; @@ -321,25 +324,32 @@ pci_device_new_from_stub(const struct pciDevice *data) * 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); + /* On success, copy @configSrc into the destination (a copy, + * rather than a symlink, is required since we write into the + * file, and parallel VPATH builds must not stomp on the + * original; besides, 'make distcheck' requires the original + * to be read-only */ + char *buf; + ssize_t len; + + if ((len = virFileReadAll(configSrc, 4096, &buf)) < 0) + ABORT("Unable to read config file '%s'", configSrc); + + make_file(devpath, "config", buf, len); + VIR_FREE(buf); } 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", -1); } if (snprintf(tmp, sizeof(tmp), "0x%.4x", dev->vendor) < 0) ABORT("@tmp overflow"); - make_file(devpath, "vendor", tmp); + make_file(devpath, "vendor", tmp, -1); if (snprintf(tmp, sizeof(tmp), "0x%.4x", dev->device) < 0) ABORT("@tmp overflow"); - make_file(devpath, "device", tmp); + make_file(devpath, "device", tmp, -1); if (pci_device_autobind(dev) < 0) ABORT("Unable to bind: %s", data->id); @@ -348,6 +358,7 @@ pci_device_new_from_stub(const struct pciDevice *data) ABORT_OOM(); VIR_FREE(devpath); + VIR_FREE(configSrc); } static struct pciDevice * @@ -425,10 +436,10 @@ pci_driver_new(const char *name, ...) va_end(args); - make_file(driverpath, "bind", NULL); - make_file(driverpath, "unbind", NULL); - make_file(driverpath, "new_id", NULL); - make_file(driverpath, "remove_id", NULL); + make_file(driverpath, "bind", NULL, -1); + make_file(driverpath, "unbind", NULL, -1); + make_file(driverpath, "new_id", NULL, -1); + make_file(driverpath, "remove_id", NULL, -1); if (VIR_APPEND_ELEMENT_QUIET(pciDrivers, nPciDrivers, driver) < 0) ABORT_OOM();