if BLKRRPART fails with EBUSY, just try a few more times
authorDavid Zeuthen <davidz@redhat.com>
Mon, 30 Mar 2009 19:49:47 +0000 (15:49 -0400)
committerDavid Zeuthen <davidz@redhat.com>
Mon, 30 Mar 2009 19:49:47 +0000 (15:49 -0400)
See http://bugs.freedesktop.org/show_bug.cgi?id=20813 for details.

src/job-create-partition-table.c
src/job-shared.h

index 165859f..542ed35 100644 (file)
@@ -43,7 +43,6 @@
 int
 main (int argc, char **argv)
 {
-        int fd;
         int ret;
         const char *device;
         const char *scheme;
@@ -108,20 +107,11 @@ main (int argc, char **argv)
                         ret = 0;
         }
 
-        /* either way, we've got this far.. signal the kernel to reread the partition table */
-        fd = open (device, O_RDONLY);
-        if (fd < 0) {
-                g_printerr ("cannot open %s (for BLKRRPART): %m\n", device);
+        /* reread partition table */
+        if (!reread_partition_table (device)) {
                 ret = 1;
                 goto out;
         }
-        if (ioctl (fd, BLKRRPART) != 0) {
-                close (fd);
-                g_printerr ("BLKRRPART ioctl failed for %s: %m\n", device);
-                ret = 1;
-                goto out;
-        }
-        close (fd);
 
 out:
         g_free (erase);
index 6fad7b8..24d4e17 100644 (file)
@@ -333,5 +333,39 @@ out:
         return ret;
 }
 
+static inline gboolean
+reread_partition_table (const gchar *device_file)
+{
+        gint fd;
+        gboolean ret;
+        guint num_retries;
+
+        ret = FALSE;
+        num_retries = 0;
+
+        fd = open (device_file, O_RDONLY);
+        if (fd < 0) {
+                g_printerr ("cannot open %s (for BLKRRPART): %m\n", device_file);
+                goto out;
+        }
+ try_again:
+        if (ioctl (fd, BLKRRPART) != 0) {
+                if (errno == EBUSY && num_retries < 20) {
+                        usleep (250 * 1000);
+                        num_retries++;
+                        goto try_again;
+                }
+                close (fd);
+                g_printerr ("BLKRRPART ioctl failed for %s: %m\n", device_file);
+                goto out;
+        }
+        close (fd);
+
+        ret = TRUE;
+
+ out:
+        return ret;
+}
+
 
 #endif /* __JOB_SHARED_H__ */