[gparted/dev-busy] Wait for udev change on /dev/DISK when erasing signatures (#83)



commit c68ede42f61bd43eacb6eb6f35dedb2d0b49a608
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Mon Feb 3 08:12:08 2020 +0000

    Wait for udev change on /dev/DISK when erasing signatures (#83)
    
    A user reported that formatting a whole disk device with a file system
    failed like this:
    
        Format /dev/sdd as ext4                                    (ERROR)
        + calibrate /dev/sdd                                       (SUCCESS)
            path: /dev/sdd (device)
            start: 0
            end: 15633407
            size: 15633408 (7.45 GiB)
        + clear old file system signatures in /dev/sdd             (SUCCESS)
          + write 512.00 KiB of zeros at byte offset 0             (SUCCESS)
          + write 4.00 KiB of zeros at byte offset 67108864        (SUCCESS)
          + write 512.00 KiB of zeros at byte offset 8003780608    (SUCCESS)
          + write 4.00 KiB of zeros at byte offset 8004239360      (SUCCESS)
          + write 8.00 KiB of zeros at byte offset 8004296704      (SUCCESS)
          + flush operating system cache of /dev/sdd               (SUCCESS)
        + create new ext4 file system                              (ERROR)
          + mkfs.ext4 -F -O ^64bit -L '' '/dev/sdd'                (ERROR)
            mke2fs 1.44.1 (24-Mar-2018)
            /dev/sdd is apparently in use by the system; will not make a filesystem here!
    
    Opening the whole disk block device exclusively causes mkfs.ext4 to
    report that error like this:
    
        # python
        >>> import os
        >>> f = os.open('/dev/sdb',os.O_RDONLY|os.O_EXCL)
        >>> ^Z
        [1]+  Stopped                 python
        # mkfs.ext4 -F -O ^64bit -L '' '/dev/sdb'
        mke2fs 1.42.9 (28-Dec-2013)
        /dev/sdb is apparently in use by the system; will not make a filesystem here!
        # echo $?
        1
    
    I have not been able to reproduce this error, but with debugging and
    sleeping in GParted, stracing GParted and using 'udevadm monitor' to
    watch udev events the following sequence of events is seen:
    
      gparted    |format(partition, operationdetail)
      gparted    |  erase_filesystem_signatures(partition, operationdetail)
      gparted    |    get_device(device_path="/dev/sdb", lp_device, flush=false)
      gparted    |      ped_device_get("/dev/sdb")
      libparted  |        open("/dev/sdb", O_RDONLY) = 11
      libparted  |        close(11)
      gparted    |    ped_device_open(lp_device)
      libparted  |      open("/dev/sdb", O_RDWR) = 11
      gparted    |    ped_device_sync(lp_device)
      libparted  |      ioctl(11, BLKFLSBUF)
      gparted    |    ped_device_close()
      libparted  |      close(11)
      udev(async)|        KERNEL change /devices/.../sdb (block)
      udev(async)|        UDEV   change /devices/.../sdb (block)
      gparted    |  set_partition_type(partition, operationdetail)
      gparted    |  create_filesystem(partition, operationdetail)
      gparted    |    ext2::create(partition, operationdetail)
      gparted    |      FileSystem::execute_command("mkfs.ext4 -F -O ^64bit -L '' '/dev/sdb')
    
    So it is assumed that the processing of the udev change rule after
    closing the block device in erase_filesystem_signatures() overlaps with
    the execution mkfs.ext4 and causes the seen error.  Fix by waiting for
    those udev events to complete as was previously done by commits [1][2]
    [3].
    
    Also note that this is specific to creating file systems on and
    formatting unpartitioned whole disk devices because set_partition_type()
    is a no-operation.  Where as on a partitioned device
    set_partition_type() calls commit() which already waits for udev rules
    to complete [3].
    
    [1] 50c8924a8e4d9cc96a2ea45f13291114402affee
        Wait for udev to recreate /dev/PTN entries when querying partition
        FSs (!46)
    [2] 4f6c312e3bc68cafb5e6035fd4a5b5bbbfcea992
        Wait for udev change on /dev/DISK when querying whole device FS
        (!46)
    [3] 2f53876c0fc8bceddabe739c298e19e7939d9ad7
        Wait for the kernel and udev to settle partitions for a second time
        (#790418)
    
    Closes #83 - /dev/sdd is apparently in use by the system; will not make
                 a filesystem here!

 src/GParted_Core.cc | 7 +++++++
 1 file changed, 7 insertions(+)
---
diff --git a/src/GParted_Core.cc b/src/GParted_Core.cc
index 85d62a99..7229a2a4 100644
--- a/src/GParted_Core.cc
+++ b/src/GParted_Core.cc
@@ -3872,6 +3872,13 @@ bool GParted_Core::erase_filesystem_signatures( const Partition & partition, Ope
                {
                        flush_success = ped_device_sync( lp_device ) ;
                        ped_device_close( lp_device ) ;
+
+                       // (#83) Wait for udev rules to complete after this
+                       // ped_device_close() to avoid busy /dev/DISK entry when running
+                       // following file system specific manipulation commands on the
+                       // whole disk device in format(), after this
+                       // erase_filesystem_signatures().
+                       settle_device(SETTLE_DEVICE_APPLY_MAX_WAIT_SECONDS);
                }
                od.get_last_child().set_success_and_capture_errors( flush_success );
                overall_success &= flush_success ;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]