]> xenbits.xensource.com Git - libvirt.git/commitdiff
Instead of relying solely on polling for /dev devices to appear in libvirt, we
authorChris Lalancette <clalance@redhat.com>
Fri, 28 Nov 2008 07:50:20 +0000 (07:50 +0000)
committerChris Lalancette <clalance@redhat.com>
Fri, 28 Nov 2008 07:50:20 +0000 (07:50 +0000)
really should be synchronizing against udev.  This is generally done by a call
to udevsettle, which is exactly what this patch implements for the storage
backends that are likely to create new /dev nodes.  I believe I've read that
even after udevsettle, you are not guaranteed that devices are all the way
created, so we still need the polling in the rest of the sources, but this
should give us a much better chance of things existing as we expect.

Signed-off-by: Chris Lalancette <clalance@redhat.com>
configure.in
src/storage_backend.c
src/storage_backend.h
src/storage_backend_disk.c
src/storage_backend_iscsi.c
src/storage_backend_logical.c

index 30929ee618a0db759cdca589d2476a164d231e51..5359433a1f0280a54923ddc22ec11d4a7c3d52e0 100644 (file)
@@ -115,11 +115,17 @@ AC_PATH_PROG([DNSMASQ], [dnsmasq], [dnsmasq],
        [/sbin:/usr/sbin:/usr/local/sbin:$PATH])
 AC_PATH_PROG([BRCTL], [brctl], [brctl],
        [/sbin:/usr/sbin:/usr/local/sbin:$PATH])
+AC_PATH_PROG([UDEVADM], [udevadm], [],
+       [/sbin:/usr/sbin:/usr/local/sbin:$PATH])
 
 AC_DEFINE_UNQUOTED([DNSMASQ],["$DNSMASQ"],
         [Location or name of the dnsmasq program])
 AC_DEFINE_UNQUOTED([BRCTL],["$BRCTL"],
         [Location or name of the brctl program (see bridge-utils)])
+if test -n "$UDEVADM"; then
+  AC_DEFINE_UNQUOTED([UDEVADM],["$UDEVADM"],
+        [Location or name of the udevadm program])
+fi
 
 dnl Specific dir for HTML output ?
 AC_ARG_WITH([html-dir], [AC_HELP_STRING([--with-html-dir=path],
index 9266e5cdc6ea13b0f853566bdfa20eac8fea523a..6b4fa818cb6f4b31c05f9b7fcdeb182da0d272b9 100644 (file)
@@ -270,6 +270,27 @@ virStorageBackendUpdateVolInfoFD(virConnectPtr conn,
     return 0;
 }
 
+#ifdef UDEVADM
+void virStorageBackendWaitForDevices(virConnectPtr conn)
+{
+    const char *const settleprog[] = { UDEVADM, "settle", NULL };
+    int exitstatus;
+
+    if (access(UDEVADM, X_OK) != 0)
+        return;
+
+    /*
+     * NOTE: we ignore errors here; this is just to make sure that any device
+     * nodes that are being created finish before we try to scan them.
+     * If this fails for any reason, we still have the backup of polling for
+     * 5 seconds for device nodes.
+     */
+    virRun(conn, settleprog, &exitstatus);
+}
+#else
+void virStorageBackendWaitForDevices(virConnectPtr conn ATTRIBUTE_UNUSED) {}
+#endif
+
 /*
  * Given a volume path directly in /dev/XXX, iterate over the
  * entries in the directory pool->def->target.path and find the
index 7904d9d061d8c764ea836638435d2cdd52644b6d..06f6979ad9cc180a69789d439b631224bea26ebf 100644 (file)
@@ -69,6 +69,8 @@ int virStorageBackendUpdateVolInfoFD(virConnectPtr conn,
                                      int fd,
                                      int withCapacity);
 
+void virStorageBackendWaitForDevices(virConnectPtr conn);
+
 char *virStorageBackendStablePath(virConnectPtr conn,
                                   virStoragePoolObjPtr pool,
                                   const char *devpath);
index 458e30773c2772f230eb62f36d5325608a378b9f..127e02c4a350439858ebb31675de2c2f79b9e4b5 100644 (file)
@@ -262,6 +262,8 @@ virStorageBackendDiskRefreshPool(virConnectPtr conn,
     VIR_FREE(pool->def->source.devices[0].freeExtents);
     pool->def->source.devices[0].nfreeExtent = 0;
 
+    virStorageBackendWaitForDevices(conn);
+
     return virStorageBackendDiskReadPartitions(conn, pool, NULL);
 }
 
index 54a6409e0a7bb5ed77e9ffa6aef163624a8cf6ff..b347fa9308a7e06640c7bcc88a6576db44024ea5 100644 (file)
@@ -603,6 +603,8 @@ virStorageBackendISCSIRefreshPool(virConnectPtr conn,
 
     pool->def->allocation = pool->def->capacity = pool->def->available = 0;
 
+    virStorageBackendWaitForDevices(conn);
+
     if ((session = virStorageBackendISCSISession(conn, pool)) == NULL)
         goto cleanup;
     if (virStorageBackendISCSIRescanLUNs(conn, pool, session) < 0)
index ee8e8f84d2fa94ef3931893fc2abc61cecdd1c5f..a358c4320645358cf091cac2d0cabae3a971c025 100644 (file)
@@ -470,6 +470,8 @@ virStorageBackendLogicalRefreshPool(virConnectPtr conn,
     };
     int exitstatus;
 
+    virStorageBackendWaitForDevices(conn);
+
     /* Get list of all logical volumes */
     if (virStorageBackendLogicalFindLVs(conn, pool, NULL) < 0) {
         virStoragePoolObjClearVols(pool);