Subject: bug#15491: closed (Re: bug#15299: [PATCH 1/9] parted: fix EOF and ctrl-c handling)

From: [email-masked] (GNU bug Tracking System)
Date: Sun, 24 Nov 2013 03:01:04 +0000

Your bug report

#15491: [PATCH] libparted: avoid disturbing partitions

which was filed against the parted package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
15491: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=15491
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#15299: [PATCH 1/9] parted: fix EOF and ctrl-c handling
From: Phillip Susi <[email-masked]>
To: [email-masked], [email-masked], [email-masked]
Date: Sat, 23 Nov 2013 22:00:04 -0500
List-Id: <debbugs-submit.debbugs.gnu.org>

Patches pushed.

Subject: [PATCH] libparted: avoid disturbing partitions
From: Phillip Susi <[email-masked]>
To: [email-masked]
Date: Sun, 29 Sep 2013 22:18:54 -0400
List-Id: <debbugs-submit.debbugs.gnu.org>

The partition sync logic was first removing all
partitions, then trying to re-add them.  This resulted in many
udev events triggering annoying behavior like auto mounting.
Refactor the code to avoid removing and re-adding unmodified
partitions.
---
 libparted/arch/linux.c | 69 +++++++++++++++++++++++---------------------------
 1 file changed, 31 insertions(+), 38 deletions(-)

diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 4b1b438..d3a03d6 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -2670,6 +2670,11 @@ _dm_get_partition_start_and_length(PedPartition const *part,
                 return 0;
         char *path = _device_get_part_path (part->disk->dev, part->num);
         PED_ASSERT(path);
+        /* libdevmapper likes to complain on stderr instead of quietly
+           returning ENOENT or ENXIO, so try to stat first */
+        struct stat st;
+        if (stat(path, &st))
+                goto err;
         dm_task_set_name(task, path);
         if (!dm_task_run(task))
                 goto err;
@@ -2806,50 +2811,38 @@ _disk_sync_part_table (PedDisk* disk)
         if (!errnums)
                 goto cleanup;
 
-        /* Attempt to remove each and every partition, retrying for
-           up to max_sleep_seconds upon any failure due to EBUSY. */
-        unsigned int sleep_microseconds = 10000;
-        unsigned int max_sleep_seconds = 1;
-        unsigned int n_sleep = (max_sleep_seconds
-                                * 1000000 / sleep_microseconds);
         int i;
-        for (i = 0; i < n_sleep; i++) {
-	    if (i)
-		usleep (sleep_microseconds);
-            bool busy = false;
-            int j;
-            for (j = 0; j < lpn; j++) {
-                if (!ok[j]) {
-                    ok[j] = remove_partition (disk, j + 1);
-                    errnums[j] = errno;
-                    if (!ok[j] && errnums[j] == EBUSY)
-                        busy = true;
-                }
-            }
-            if (!busy)
-                break;
-        }
-
         for (i = 1; i <= lpn; i++) {
                 PedPartition *part = ped_disk_get_partition (disk, i);
                 if (part) {
-                        if (!ok[i - 1] && errnums[i - 1] == EBUSY) {
-                                unsigned long long length;
-                                unsigned long long start;
-                                /* get start and length of existing partition */
-                                if (!get_partition_start_and_length(part,
-                                                                    &start, &length))
-                                        goto cleanup;
-                                if (start == part->geom.start
-				    && length == part->geom.length)
-                                        ok[i - 1] = 1;
-                                /* If the new partition is unchanged and the
-				   existing one was not removed because it was
-				   in use, then reset the error flag and do not
-				   try to add it since it is already there.  */
+                        unsigned long long length;
+                        unsigned long long start;
+                        /* get start and length of existing partition */
+                        if (get_partition_start_and_length(part,
+                                                            &start, &length)
+                            && start == part->geom.start
+                            && length == part->geom.length) {
+                                ok[i - 1] = 1;
+                                /* partition is unchanged, so nothing to do */
                                 continue;
                         }
-
+                }
+                /* Attempt to remove the partition, retrying for
+                   up to max_sleep_seconds upon any failure due to EBUSY. */
+                unsigned int sleep_microseconds = 10000;
+                unsigned int max_sleep_seconds = 1;
+                unsigned int n_sleep = (max_sleep_seconds
+                                        * 1000000 / sleep_microseconds);
+                do {
+                        ok[i - 1] = remove_partition (disk, i);
+                        errnums[i - 1] = errno;
+                        if (ok[i - 1] || errnums[i - 1] != EBUSY)
+                                break;
+                        usleep (sleep_microseconds);
+                } while (n_sleep--);
+                if (!ok[i - 1] && errnums[i - 1] == ENXIO)
+                        ok[i - 1] = 1; /* it already doesn't exist */
+                if (part && ok[i - 1]) {
                         /* add the (possibly modified or new) partition */
                         if (!add_partition (disk, part)) {
                                 ok[i - 1] = 0;
-- 
1.8.1.2