[libvirt] [PATCH]: Give /dev/disk/by-{id,path} a chance to exist

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



All,
    When refreshing a storage pool (say, an iSCSI pool), one of the things it
does is to generate the stable path for each of the LUNs via
virStorageBackendStablePath.  That, in turn, has the following code:

    /* 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
     */
    if ((dh = opendir(pool->def->target.path)) == NULL) {
         virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
                               _("cannot read dir %s: %s"),
                               pool->def->target.path,
                               strerror(errno));
         return NULL;
     }

For a normal machine, that code is totally legit; /dev/disk/by-{id,path} almost
certainly exists because of your hard drive, etc.  However, this may not be the
case in the stateless ovirt environment, since /dev/disk/by-{id,path} is created
on-demand by udev.  It's basically a race between udev creating the directory
and libvirt scanning the directory.
     The following patch just adds a retry to the code above so that if it
doesn't exist when we first get there, we give it time to come into being.  If
it still hasn't shown up 5 seconds after we started, we give up and throw the error.

Signed-off-by: Chris Lalancette <clalance@xxxxxxxxxx>

Index: src/storage_backend.c
===================================================================
RCS file: /data/cvs/libvirt/src/storage_backend.c,v
retrieving revision 1.29
diff -u -r1.29 storage_backend.c
--- a/src/storage_backend.c	17 Nov 2008 11:19:33 -0000	1.29
+++ b/src/storage_backend.c	25 Nov 2008 15:14:20 -0000
@@ -291,6 +291,7 @@
     DIR *dh;
     struct dirent *dent;
     char *stablepath;
+    int opentries;
 
     /* Short circuit if pool has no target, or if its /dev */
     if (pool->def->target.path == NULL ||
@@ -304,19 +305,33 @@
     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.
      */
-    if ((dh = opendir(pool->def->target.path)) == NULL) {
+    dh = NULL;
+    opentries = 0;
+    while (opentries < 50) {
+        if ((dh = opendir(pool->def->target.path)) != NULL)
+            break;
+
+        usleep(100 * 1000);
+        opentries++;
+    }
+
+    if (dh == NULL) {
         virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
                               _("cannot read dir %s: %s"),
                               pool->def->target.path,
                               strerror(errno));
         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;
--
Libvir-list mailing list
Libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]