GNU bug report logs - #58598
[PATCH]parted: acquire flock before modifying the device superblock

Previous Next

Package: parted;

Reported by: "zhanghongtao (A)" <zhanghongtao22 <at> huawei.com>

Date: Mon, 17 Oct 2022 23:04:02 UTC

Severity: normal

Tags: patch

To reply to this bug, email your comments to 58598 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-parted <at> gnu.org:
bug#58598; Package parted. (Mon, 17 Oct 2022 23:04:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to "zhanghongtao (A)" <zhanghongtao22 <at> huawei.com>:
New bug report received and forwarded. Copy sent to bug-parted <at> gnu.org. (Mon, 17 Oct 2022 23:04:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: "zhanghongtao (A)" <zhanghongtao22 <at> huawei.com>
To: <parted-devel <at> alioth-lists.debian.net>, <bug-parted <at> gnu.org>
Cc: linfeilong <at> huawei.com, liuzhiqiang26 <at> huawei.com
Subject: [PATCH]parted: acquire flock before modifying the device superblock
Date: Mon, 17 Oct 2022 21:14:41 +0800
We noticed that systemd has an issue about symlink unreliable caused by
formatting filesystem and systemd operating on same device.
Issue Link: https://github.com/systemd/systemd/issues/23746

According to systemd doc, a BSD flock needs to be acquired before
formatting the device.
Related Link: https://systemd.io/BLOCK_DEVICE_LOCKING/

So we acquire flock after opening the device.
But this patch causes multiple parted processes to fail to run
simultaneously in interactive mode.
Or, can we add an option for lock mode?

Signed-off-by: Hongtao Zhang <zhanghongtao22 <at> huawei.com>
---
 libparted/arch/linux.c | 49 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index f3bf14d..f7645f4 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -22,6 +22,7 @@
 #include <linux/blkpg.h>
 #include <parted/parted.h>
 #include <parted/debug.h>
+#include <sys/file.h>
 #if defined __s390__ || defined __s390x__
 #include <parted/fdasd.h>
 #endif
@@ -1706,6 +1707,50 @@ _device_open_ro (PedDevice* dev)
     return rc;
 }

+static int lock_blkdev (int fd, char *path)
+{
+        int rc, msg = 0;
+
+        /* Try non-block first to provide message */
+        rc = flock(fd, LOCK_EX | LOCK_NB);
+        if (rc == 0)
+                return 0;
+        if (rc != 0 && errno == EWOULDBLOCK) {
+                ped_exception_throw (
+                        PED_EXCEPTION_WARNING,
+                        PED_EXCEPTION_OK,
+                        _("%s: device already locked, "
+                        "waiting to get lock ..."),
+                        path);
+                msg = 1;
+        }
+
+        rc = flock (fd, LOCK_EX);
+        if (rc != 0) {
+                switch (errno) {
+                case EWOULDBLOCK: /* LOCK_NB */
+                        ped_exception_throw (
+                                PED_EXCEPTION_WARNING,
+                                PED_EXCEPTION_OK,
+                                _("%s: device already locked"),
+                                path);
+                        break;
+                default:
+                        ped_exception_throw (
+                                PED_EXCEPTION_WARNING,
+                                PED_EXCEPTION_OK,
+                                _("%s: failed to get lock"),
+                                path);
+                }
+        } else if (msg)
+                ped_exception_throw (
+                        PED_EXCEPTION_WARNING,
+                        PED_EXCEPTION_OK,
+                        _("%s: lock ok"),
+                        path);
+        return rc;
+}
+
 static int
 linux_open (PedDevice* dev)
 {
@@ -1747,6 +1792,10 @@ retry:
                 }
         } else {
                 dev->read_only = 0;
+                if (lock_blkdev (arch_specific->fd, dev->path) != 0) {
+                        close (arch_specific->fd);
+                        return 0;
+                }
         }

         _flush_cache (dev);
--
2.33.0




Information forwarded to bug-parted <at> gnu.org:
bug#58598; Package parted. (Fri, 21 Oct 2022 08:38:01 GMT) Full text and rfc822 format available.

Message #8 received at submit <at> debbugs.gnu.org (full text, mbox):

From: John Gilmore <gnu <at> toad.com>
To: "zhanghongtao (A)" <zhanghongtao22 <at> huawei.com>
Cc: linfeilong <at> huawei.com, parted-devel <at> alioth-lists.debian.net,
 bug-parted <at> gnu.org, liuzhiqiang26 <at> huawei.com
Subject: Re: [parted-devel] [PATCH]parted: acquire flock before modifying the
 device superblock 
Date: Fri, 21 Oct 2022 01:36:53 -0700
Parted shouldn't lock itself (or systemd) out of concurrent access
to the same device.  But if there is a bug relating to concurrent
"formatting a filesystem and systemd", then why not get an flock
just for the duration of formatting a file system?  Formatting
is a write-only operation and there's no point in trying to do two
of them concurrently on the same file system.

	John




This bug report was last modified 2 years and 239 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.