]> xenbits.xensource.com Git - libvirt.git/commitdiff
Currently libvirt can race with udev
authorChris Lalancette <clalance@redhat.com>
Fri, 28 Nov 2008 07:42:21 +0000 (07:42 +0000)
committerChris Lalancette <clalance@redhat.com>
Fri, 28 Nov 2008 07:42:21 +0000 (07:42 +0000)
creation of /dev/disk/by-{id,path}, so if we fail to open the directory, retry
up to 5 seconds.  This is only likely to happen on hosts that are:

1) diskless (so /dev/disk/by-{id,path} doesn't exist already), and
2) slow, and/or heavily loaded (meaning that udev can take some time to create
the /dev nodes).

Signed-off-by: Chris Lalancette <clalance@redhat.com>
ChangeLog
src/storage_backend.c

index ab1593e2b3379037c3cf71a5ed6c756867fbdc98..20d0a379d60bd1cc988160eb23c9805811c9b6e1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Fri Nov 28 08:40:00 CET 2008 Chris Lalancette <clalance@redhat.com>
+       * src/storage_backend.c: Wait up to 5 seconds for
+       /dev/disk/by-{id,path} to exist in virStorageBackendStablePath
+
 Thu Nov 27 17:15:10 CET 2008 Daniel Veillard <veillard@redhat.com>
 
        * src/xen_unified.c: use preferably xend method to update
index c4396e120a4044204784c59bea289bdb2bcc1009..9266e5cdc6ea13b0f853566bdfa20eac8fea523a 100644 (file)
@@ -291,6 +291,7 @@ virStorageBackendStablePath(virConnectPtr conn,
     DIR *dh;
     struct dirent *dent;
     char *stablepath;
+    int opentries = 0;
 
     /* Short circuit if pool has no target, or if its /dev */
     if (pool->def->target.path == NULL ||
@@ -304,12 +305,17 @@ virStorageBackendStablePath(virConnectPtr conn,
     if (!STRPREFIX(pool->def->target.path, "/dev"))
         goto ret_strdup;
 
-    /* The pool is pointing somewhere like /dev/disk/by-path
-     * or /dev/disk/by-id, so we need to check all symlinks in
-     * the target directory and figure out which one points
-     * to this device node
+    /* We loop here because /dev/disk/by-{id,path} may not have existed
+     * before we started this operation, so we have to give it some time to
+     * get created.
      */
+ reopen:
     if ((dh = opendir(pool->def->target.path)) == NULL) {
+        opentries++;
+        if (errno == ENOENT && opentries < 50) {
+            usleep(100 * 1000);
+            goto reopen;
+        }
         virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
                               _("cannot read dir %s: %s"),
                               pool->def->target.path,
@@ -317,6 +323,11 @@ virStorageBackendStablePath(virConnectPtr conn,
         return NULL;
     }
 
+    /* The pool is pointing somewhere like /dev/disk/by-path
+     * or /dev/disk/by-id, so we need to check all symlinks in
+     * the target directory and figure out which one points
+     * to this device node
+     */
     while ((dent = readdir(dh)) != NULL) {
         if (dent->d_name[0] == '.')
             continue;