[Parted-commits] GNU Parted Official Repository: Changes to 'master'

Jim Meyering meyering at alioth.debian.org
Fri Apr 30 14:33:00 UTC 2010


 bootstrap.conf                        |    1 
 libparted/arch/linux.c                |   81 ++++++++++++++--------------------
 tests/t4100-dvh-partition-limits.sh   |    7 ++
 tests/t4100-msdos-partition-limits.sh |   10 +++-
 4 files changed, 51 insertions(+), 48 deletions(-)

New commits:
commit 1611f6e9c09d0168f36939e8d22f404cfd9a1f2e
Author: Jim Meyering <meyering at redhat.com>
Date:   Fri Apr 30 15:59:14 2010 +0200

    tests: avoid root-only/XFS limit test failure on 32-bit system
    
    * tests/t4100-msdos-partition-limits.sh: Due to an inherent XFS
    limitation on 32-bit systems, this test would fail a set-up
    file creation step for simulated sector sizes of 4K and up.
    Skip this test in those cases.
    Upon dd failure, propagate its diagnostic to output, to make this
    sort of problem easier to diagnose.
    * tests/t4100-dvh-partition-limits.sh: Likewise.

diff --git a/tests/t4100-dvh-partition-limits.sh b/tests/t4100-dvh-partition-limits.sh
index bf269e7..1016077 100755
--- a/tests/t4100-dvh-partition-limits.sh
+++ b/tests/t4100-dvh-partition-limits.sh
@@ -25,6 +25,13 @@ privileges_required_=1
 require_xfs_
 ss=$sector_size_
 
+# On a 32-bit system, we must skip this test when $ss >= 4096.
+# Otherwise, due to an inherent 32-bit-XFS limit, dd would fail to
+# create the file of size > 16TiB
+if test $(uname -m) != x86_64; then
+  test $ss -le 2048 || exit 77
+fi
+
 ####################################################
 # Create and mount a file system capable of dealing with >=2TB files.
 # We must be able to create a file with an apparent length of 2TB or larger.
diff --git a/tests/t4100-msdos-partition-limits.sh b/tests/t4100-msdos-partition-limits.sh
index b63a534..db98f2e 100755
--- a/tests/t4100-msdos-partition-limits.sh
+++ b/tests/t4100-msdos-partition-limits.sh
@@ -25,6 +25,13 @@ privileges_required_=1
 require_xfs_
 ss=$sector_size_
 
+# On a 32-bit system, we must skip this test when $ss >= 4096.
+# Otherwise, due to an inherent 32-bit-XFS limit, dd would fail to
+# create the file of size > 16TiB
+if test $(uname -m) != x86_64; then
+  test $ss -le 2048 || exit 77
+fi
+
 ####################################################
 # Create and mount a file system capable of dealing with >=2TB files.
 # We must be able to create a file with an apparent length of 2TB or larger.
@@ -59,7 +66,8 @@ do_mkpart()
   start_sector=$1
   end_sector=$2
   # echo '********' $(echo $end_sector - $start_sector + 1 |bc)
-  dd if=/dev/zero of=$dev bs=$ss count=2k seek=$end_sector 2> /dev/null &&
+  dd if=/dev/zero of=$dev bs=$ss count=2k seek=$end_sector 2> dd-err ||
+    { cat dd-err 1>&2; return 1; }
   parted -s $dev mklabel $table_type &&
   parted -s $dev mkpart p xfs ${start_sector}s ${end_sector}s
 }

commit 0f850220b3f26bb969a1a7ff78dc550691a89566
Author: Jim Meyering <meyering at redhat.com>
Date:   Fri Apr 30 12:28:16 2010 +0200

    libparted: avoid race in informing the kernel of partition table changes
    
    When sync'ing a partition table change using the latest
    code, sometimes we'd get an unwarranted failure like this:
    
        Warning: Partition(s) 1 on /dev/sdd have been written, but we
        have been unable to inform the kernel of the change, probably because
        it/they are in use.  As a result, the old partition(s) will remain in
        use.  You should reboot now before making further changes.
    
    To be precise, when running the partition-resizing root-only test
    in a loop:
    
        for i in $(seq 240); do make -C tests check VERBOSE=yes \
        TESTS=t3000-resize-fs.sh >& log.$i && printf . || echo $i $?; done
    
    I would typically see about 50% of them fail on a Fedora 13 system.
    It was obvious that this was due to a race condition when I found that
    modifying that tests' parted...resize invocation to go via strace changed
    the timing enough to make the test pass every time.
    
    The fix is to retry the partition-removal step upon any EBUSY failure,
    currently for up to 1 second (retrying up to 100 times, sleeping 10ms
    after each failure).
    
    * libparted/arch/linux.c (_disk_sync_part_table): Allocate "ok" using
    calloc, now that its initial values matter.
    Retry each removal upon EBUSY-failure.
    * bootstrap.conf (gnulib_modules): Use gnulib's usleep module.

diff --git a/bootstrap.conf b/bootstrap.conf
index 6c9287d..4ca51a7 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -58,6 +58,7 @@ gnulib_modules="
 	unlink
 	update-copyright
 	useless-if-before-free
+	usleep
 	vc-list-files
 	version-etc-fsf
 	warnings
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 8116c76..73a8e6f 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -2452,17 +2452,35 @@ _disk_sync_part_table (PedDisk* disk)
         if (lpn < 0)
                 return 0;
         int ret = 0;
-        int *ok = ped_malloc(sizeof(int) * lpn);
+        int *ok = calloc (lpn, sizeof *ok);
         if (!ok)
                 return 0;
         int *errnums = ped_malloc(sizeof(int) * lpn);
         if (!errnums)
                 goto cleanup;
-        int i;
 
-        for (i = 1; i <= lpn; i++) {
-                ok[i - 1] = _blkpg_remove_partition (disk, i);
-                errnums[i - 1] = errno;
+        /* 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] = _blkpg_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++) {

commit 9acc5869985c8616066af4825f52fb6c474f63dd
Author: Jim Meyering <meyering at redhat.com>
Date:   Fri Apr 30 12:01:08 2010 +0200

    libparted: variable renaming, minor "goto" reorg
    
    * libparted/arch/linux.c (_disk_sync_part_table): Rename local array:
    s/rets/ok/, for readability.
    Use only a single label, "cleanup:", rather than two: free_rets
    and free_errnums.

diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index d8f3393..8116c76 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -2452,29 +2452,29 @@ _disk_sync_part_table (PedDisk* disk)
         if (lpn < 0)
                 return 0;
         int ret = 0;
-        int *rets = ped_malloc(sizeof(int) * lpn);
-        if (!rets)
+        int *ok = ped_malloc(sizeof(int) * lpn);
+        if (!ok)
                 return 0;
         int *errnums = ped_malloc(sizeof(int) * lpn);
         if (!errnums)
-                goto free_rets;
+                goto cleanup;
         int i;
 
         for (i = 1; i <= lpn; i++) {
-                rets[i - 1] = _blkpg_remove_partition (disk, i);
+                ok[i - 1] = _blkpg_remove_partition (disk, i);
                 errnums[i - 1] = errno;
         }
 
         for (i = 1; i <= lpn; i++) {
                 const PedPartition *part = ped_disk_get_partition (disk, i);
                 if (part) {
-                        if (!rets[i - 1] && errnums[i - 1] == EBUSY) {
+                        if (!ok[i - 1] && errnums[i - 1] == EBUSY) {
                                 struct hd_geometry geom;
                                 unsigned long long length = 0;
                                 /* get start and length of existing partition */
                                 char *dev_name = _device_get_part_path (disk->dev, i);
                                 if (!dev_name)
-                                        goto free_errnums;
+                                        goto cleanup;
                                 int fd = open (dev_name, O_RDONLY);
                                 if (fd == -1
 				    || ioctl (fd, HDIO_GETGEO, &geom)
@@ -2487,14 +2487,14 @@ _disk_sync_part_table (PedDisk* disk)
                                         if (fd != -1)
                                                 close (fd);
                                         free (dev_name);
-                                        goto free_errnums;
+                                        goto cleanup;
                                 }
                                 free (dev_name);
                                 length /= disk->dev->sector_size;
                                 close (fd);
                                 if (geom.start == part->geom.start
 				    && length == part->geom.length)
-                                        rets[i - 1] = 1;
+                                        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
@@ -2509,7 +2509,7 @@ _disk_sync_part_table (PedDisk* disk)
                                         PED_EXCEPTION_RETRY_CANCEL,
                                         _("Failed to add partition %d (%s)"),
                                         i, strerror (errno));
-                                goto free_errnums;
+                                goto cleanup;
                         }
                 }
         }
@@ -2517,12 +2517,12 @@ _disk_sync_part_table (PedDisk* disk)
         char *bad_part_list = NULL;
         /* now warn about any errors */
         for (i = 1; i <= lpn; i++) {
-		if (rets[i - 1] || errnums[i - 1] == ENXIO)
+		if (ok[i - 1] || errnums[i - 1] == ENXIO)
 			continue;
 		if (bad_part_list == NULL) {
 			  bad_part_list = malloc (lpn * 5);
 			  if (!bad_part_list)
-				  goto free_errnums;
+				  goto cleanup;
 			  bad_part_list[0] = 0;
 		}
 		sprintf (bad_part_list + strlen (bad_part_list), "%d, ", i);
@@ -2543,10 +2543,9 @@ _disk_sync_part_table (PedDisk* disk)
                         ret = 1;
 		free (bad_part_list);
         }
- free_errnums:
+ cleanup:
         free (errnums);
- free_rets:
-        free (rets);
+        free (ok);
         return ret;
 }
 

commit 1223b9fc07859cb619c80dc057bd05458f9b5669
Author: Jim Meyering <meyering at redhat.com>
Date:   Fri Apr 30 11:45:51 2010 +0200

    libparted: remove now-worse-than-useless _kernel_reread_part_table
    
    Now that we're using BLKPG properly, there's no point in using the
    less-functional BLKRRPART ioctl to make the kernel reread the partition
    table.
    More importantly, this function would fail when any partition is in
    use, in spite of our having carefully vetted them via BLKPG ioctls.
    * libparted/arch/linux.c (_kernel_reread_part_table): Remove function.
    (linux_disk_commit): Don't call it.

diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 988fde7..d8f3393 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -2760,34 +2760,6 @@ _dm_reread_part_table (PedDisk* disk)
 #endif
 
 static int
-_kernel_reread_part_table (PedDevice* dev)
-{
-        LinuxSpecific*  arch_specific = LINUX_SPECIFIC (dev);
-        int             retry_count = 9;
-
-        sync();
-        while (ioctl (arch_specific->fd, BLKRRPART)) {
-                retry_count--;
-                sync();
-                if (retry_count == 3)
-                        sleep(1); /* Pause to allow system to settle */
-
-                if (!retry_count) {
-                        ped_exception_throw (
-                                PED_EXCEPTION_WARNING,
-                                PED_EXCEPTION_IGNORE,
-                        _("WARNING: the kernel failed to re-read the partition "
-                          "table on %s (%s).  As a result, it may not "
-                          "reflect all of your changes until after reboot."),
-                                dev->path, strerror (errno));
-                        return 0;
-                }
-        }
-
-        return 1;
-}
-
-static int
 _have_blkpg ()
 {
         static int have_blkpg = -1;
@@ -2825,8 +2797,6 @@ linux_disk_commit (PedDisk* disk)
 			  ok = 0;
 		}
 
-		if (!_kernel_reread_part_table (disk->dev))
-			ok = 0;
                 return ok;
         }
 



More information about the Parted-commits mailing list