From 16a560397a025d53e4e778aa74791079ef8fec27 Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Wed, 27 Jun 2012 12:46:32 -0400 Subject: [PATCH] Issue BLKRRPART if wiping a device with an existing partition table Signed-off-by: David Zeuthen --- src/udiskslinuxblock.c | 16 ++++++++++++---- src/udiskslinuxblockobject.c | 42 +++++++++++++++++++++++++++++++++++++++--- src/udiskslinuxblockobject.h | 1 + 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/src/udiskslinuxblock.c b/src/udiskslinuxblock.c index f9c88ea..a20396e 100644 --- a/src/udiskslinuxblock.c +++ b/src/udiskslinuxblock.c @@ -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: "); diff --git a/src/udiskslinuxblockobject.c b/src/udiskslinuxblockobject.c index 1de71d1..fc64a05 100644 --- a/src/udiskslinuxblockobject.c +++ b/src/udiskslinuxblockobject.c @@ -30,6 +30,9 @@ #include #include +#include +#include + #include #include #include @@ -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); + } +} diff --git a/src/udiskslinuxblockobject.h b/src/udiskslinuxblockobject.h index 6dcc871..64dce3a 100644 --- a/src/udiskslinuxblockobject.h +++ b/src/udiskslinuxblockobject.h @@ -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 -- 2.7.4