[libvirt] [PATCH] tests: fix virpcitest with read-only srcdir

Eric Blake eblake at redhat.com
Wed Nov 27 22:11:52 UTC 2013


'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 <eblake at redhat.com>
---

Pushing under the build-breaker rule, as an alternative
to the earlier attempt that I nak'ed:
https://www.redhat.com/archives/libvir-list/2013-November/msg00999.html

 tests/virpcimock.c | 43 +++++++++++++++++++++++++++----------------
 1 file changed, 27 insertions(+), 16 deletions(-)

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();
-- 
1.8.3.1




More information about the libvir-list mailing list