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

Full log


View this message in rfc822 format

From: "zhanghongtao (A)" <zhanghongtao22 <at> huawei.com>
To: parted-devel <at> alioth-lists.debian.net, 58598 <at> debbugs.gnu.org
Cc: linfeilong <at> huawei.com, liuzhiqiang26 <at> huawei.com
Subject: bug#58598: [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




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.