summaryrefslogtreecommitdiff
path: root/src/sysext
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2022-04-07 16:09:45 +0200
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-04-10 22:52:29 +0900
commit41bc484906e973f6c91f8398a3ba309b7ee16f5a (patch)
tree57fad1132c0a90f01e527ac948f898ddea9863a4 /src/sysext
parent345418a9e67a5f5f86901b2e1f86f52526ca7ba1 (diff)
downloadsystemd-41bc484906e973f6c91f8398a3ba309b7ee16f5a.tar.gz
tree-wide: take BSD lock on loopback devices we dissect/mount/operate on
So here's something we should always keep in mind: systemd-udevd actually does *two* things with BSD file locks on block devices: 1. While it probes a device it takes a LOCK_SH lock. Thus everyone else taking a LOCK_EX lock will temporarily block udev from probing devices, which is good when making changes to it. 2. Whenever a device is closed after write (detected via inotify), udevd will issue BLKRRPART (requesting the kernel to reread the partition table). It does this while holding a LOCK_EX lock on the block device. Thus anyone else taking LOCK_SH or LOCK_EX will temporarily block udevd from issuing that ioctl. And that's quite relevant, since the kernel will temporarily flush out all partitions while re-reading the partition table and then create them anew. Thus it is smart to take LOCK_SH when dissecting a block device to ensure that no BLKRRPART is issued in the background, until we mounted the devices.
Diffstat (limited to 'src/sysext')
-rw-r--r--src/sysext/sysext.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c
index 6d4df0afd2..ccc0bd2687 100644
--- a/src/sysext/sysext.c
+++ b/src/sysext/sysext.c
@@ -533,6 +533,10 @@ static int merge_subprocess(Hashmap *images, const char *workspace) {
if (r < 0)
return log_error_errno(r, "Failed to set up loopback device for %s: %m", img->path);
+ r = loop_device_flock(d, LOCK_SH);
+ if (r < 0)
+ return log_error_errno(r, "Failed to lock loopback device: %m");
+
r = dissect_image_and_warn(
d->fd,
img->path,