Issue BLKRRPART if wiping a device with an existing partition table
authorDavid Zeuthen <zeuthen@gmail.com>
Wed, 27 Jun 2012 16:46:32 +0000 (12:46 -0400)
committerDavid Zeuthen <zeuthen@gmail.com>
Wed, 27 Jun 2012 16:46:32 +0000 (12:46 -0400)
Signed-off-by: David Zeuthen <zeuthen@gmail.com>
src/udiskslinuxblock.c
src/udiskslinuxblockobject.c
src/udiskslinuxblockobject.h

index f9c88ea..a20396e 100644 (file)
@@ -1859,6 +1859,7 @@ handle_format (UDisksBlock           *block,
   gchar *mapped_name = NULL;
   const gchar *label = NULL;
   gchar *escaped_device = NULL;
+  gboolean was_partitioned = FALSE;
 
   error = NULL;
   object = udisks_daemon_util_dup_object (block, &error);
@@ -1939,9 +1940,9 @@ handle_format (UDisksBlock           *block,
 
   escaped_device = udisks_daemon_util_escape_and_quote (udisks_block_get_device (block));
 
-  /* First wipe the device */
-  wait_data = g_new0 (FormatWaitData, 1);
-  wait_data->object = object;
+  was_partitioned = (udisks_object_peek_partition_table (object) != NULL);
+
+  /* First wipe the device... */
   if (!udisks_daemon_launch_spawned_job_sync (daemon,
                                               object,
                                               "format-erase", caller_uid,
@@ -1962,11 +1963,18 @@ handle_format (UDisksBlock           *block,
       g_free (error_message);
       goto out;
     }
+  /* ...then wait until this change has taken effect */
+  wait_data = g_new0 (FormatWaitData, 1);
+  wait_data->object = object;
+  wait_data->type = "empty";
+  udisks_linux_block_object_trigger_uevent (UDISKS_LINUX_BLOCK_OBJECT (object));
+  if (was_partitioned)
+    udisks_linux_block_object_reread_partition_table (UDISKS_LINUX_BLOCK_OBJECT (object));
   if (udisks_daemon_wait_for_object_sync (daemon,
                                           wait_for_filesystem,
                                           wait_data,
                                           NULL,
-                                          30,
+                                          15,
                                           &error) == NULL)
     {
       g_prefix_error (&error, "Error synchronizing after initial wipe: ");
index 1de71d1..fc64a05 100644 (file)
@@ -30,6 +30,9 @@
 #include <grp.h>
 #include <mntent.h>
 
+#include <sys/ioctl.h>
+#include <linux/fs.h>
+
 #include <string.h>
 #include <stdlib.h>
 #include <glib/gstdio.h>
@@ -785,9 +788,7 @@ on_mount_monitor_mount_removed (UDisksMountMonitor  *monitor,
  *
  * The triggered event will bubble up from the kernel through the udev
  * stack and will eventually be received by the udisks daemon process
- * itself.
- *
- * This method does not wait for the event to be received.
+ * itself. This method does not wait for the event to be received.
  */
 void
 udisks_linux_block_object_trigger_uevent (UDisksLinuxBlockObject *object)
@@ -820,3 +821,38 @@ udisks_linux_block_object_trigger_uevent (UDisksLinuxBlockObject *object)
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
+
+/**
+ * udisks_linux_block_object_reread_partition_table:
+ * @object: A #UDisksLinuxBlockObject.
+ *
+ * Requests the kernel to re-read the partition table for @object.
+ *
+ * The events from any change this may cause will bubble up from the
+ * kernel through the udev stack and will eventually be received by
+ * the udisks daemon process itself. This method does not wait for the
+ * event to be received.
+ */
+void
+udisks_linux_block_object_reread_partition_table (UDisksLinuxBlockObject *object)
+{
+  const gchar *device_file;
+  gint fd;
+
+  g_return_if_fail (UDISKS_IS_LINUX_BLOCK_OBJECT (object));
+
+  device_file = g_udev_device_get_device_file (object->device);
+  fd = open (device_file, O_RDONLY);
+  if (fd == -1)
+    {
+      udisks_warning ("Error opening %s: %m", device_file);
+    }
+  else
+    {
+      if (ioctl (fd, BLKRRPART) != 0)
+        {
+          udisks_warning ("Error issuing BLKRRPART to %s: %m", device_file);
+        }
+      close (fd);
+    }
+}
index 6dcc871..64dce3a 100644 (file)
@@ -40,6 +40,7 @@ UDisksDaemon             *udisks_linux_block_object_get_daemon (UDisksLinuxBlock
 GUdevDevice              *udisks_linux_block_object_get_device (UDisksLinuxBlockObject  *object);
 
 void                      udisks_linux_block_object_trigger_uevent (UDisksLinuxBlockObject  *object);
+void                      udisks_linux_block_object_reread_partition_table (UDisksLinuxBlockObject *object);
 
 G_END_DECLS