0b7af917e2
- Drop patches incorporated into upstream - Still adds the various DASD patches
142 lines
6.2 KiB
Diff
142 lines
6.2 KiB
Diff
From 5910f1bc983fbab31f9ec86a7166feee4869c21a Mon Sep 17 00:00:00 2001
|
|
From: Phillip Susi <psusi@ubuntu.com>
|
|
Date: Sun, 29 Sep 2013 12:38:29 -0400
|
|
Subject: [PATCH 62/89] libparted: avoid disturbing partitions
|
|
|
|
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.
|
|
---
|
|
NEWS | 3 ++
|
|
libparted/arch/linux.c | 84 ++++++++++++++++++++++++++++----------------------
|
|
2 files changed, 50 insertions(+), 37 deletions(-)
|
|
|
|
diff --git a/NEWS b/NEWS
|
|
index 6538c96..cb725e7 100644
|
|
--- a/NEWS
|
|
+++ b/NEWS
|
|
@@ -10,6 +10,9 @@ GNU parted NEWS -*- outline -*-
|
|
|
|
** Bug Fixes
|
|
|
|
+ Avoid generating udev add/remove events for all unmodified partitions
|
|
+ when writing a new table.
|
|
+
|
|
Fix cache coherency issue by flushing partition block devices.
|
|
This had been mistakenly disabled in parted 2.0, and resulted
|
|
in parted sometimes identifying the previous filesystem type
|
|
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
|
|
index 4b1b438..f43eae1 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,55 @@ _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;
|
|
+ /* remove old partitions first */
|
|
+ for (i = 1; i <= lpn; i++) {
|
|
+ PedPartition *part = ped_disk_get_partition (disk, i);
|
|
+ if (part) {
|
|
+ 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;
|
|
+ continue;
|
|
+ }
|
|
}
|
|
- }
|
|
- 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.5.3
|
|
|