]>
Commit | Line | Data |
---|---|---|
c3e270f4 FB |
1 | --- |
2 | title: Locking Block Device Access | |
4cdca0af | 3 | category: Interfaces |
c3e270f4 FB |
4 | --- |
5 | ||
ecb1a44c LP |
6 | # Locking Block Device Access |
7 | ||
8 | *TL;DR: Use BSD file locks | |
9 | [(`flock(2)`)](http://man7.org/linux/man-pages/man2/flock.2.html) on block | |
10 | device nodes to synchronize access for partitioning and file system formatting | |
11 | tools.* | |
12 | ||
13 | `systemd-udevd` probes all block devices showing up for file system superblock | |
14 | and partition table information (utilizing `libblkid`). If another program | |
15 | concurrently modifies a superblock or partition table this probing might be | |
16 | affected, which is bad in itself, but also might in turn result in undesired | |
17 | effects in programs subscribing to `udev` events. | |
18 | ||
19 | Applications manipulating a block device can temporarily stop `systemd-udevd` | |
20 | from processing rules on it — and thus bar it from probing the device — by | |
21 | taking a BSD file lock on the block device node. Specifically, whenever | |
22 | `systemd-udevd` starts processing a block device it takes a `LOCK_SH|LOCK_NB` | |
23 | lock using [`flock(2)`](http://man7.org/linux/man-pages/man2/flock.2.html) on | |
24 | the main block device (i.e. never on any partition block device, but on the | |
25 | device the partition belongs to). If this lock cannot be taken (i.e. `flock()` | |
26 | returns `EBUSY`), it refrains from processing the device. If it manages to take | |
27 | the lock it is kept for the entire time the device is processed. | |
28 | ||
29 | Note that `systemd-udevd` also watches all block device nodes it manages for | |
30 | `inotify()` `IN_CLOSE` events: whenever such an event is seen, this is used as | |
31 | trigger to re-run the rule-set for the device. | |
32 | ||
33 | These two concepts allow tools such as disk partitioners or file system | |
34 | formatting tools to safely and easily take exclusive ownership of a block | |
35 | device while operating: before starting work on the block device, they should | |
36 | take an `LOCK_EX` lock on it. This has two effects: first of all, in case | |
37 | `systemd-udevd` is still processing the device the tool will wait for it to | |
d238709c | 38 | finish. Second, after the lock is taken, it can be sure that |
ecb1a44c LP |
39 | `systemd-udevd` will refrain from processing the block device, and thus all |
40 | other client applications subscribed to it won't get device notifications from | |
41 | potentially half-written data either. After the operation is complete the | |
42 | partitioner/formatter can simply close the device node. This has two effects: | |
43 | it implicitly releases the lock, so that `systemd-udevd` can process events on | |
44 | the device node again. Secondly, it results an `IN_CLOSE` event, which causes | |
45 | `systemd-udevd` to immediately re-process the device — seeing all changes the | |
46 | tool made — and notify subscribed clients about it. | |
47 | ||
48 | Besides synchronizing block device access between `systemd-udevd` and such | |
49 | tools this scheme may also be used to synchronize access between those tools | |
50 | themselves. However, do note that `flock()` locks are advisory only. This means | |
51 | if one tool honours this scheme and another tool does not, they will of course | |
52 | not be synchronized properly, and might interfere with each other's work. | |
53 | ||
54 | Note that the file locks follow the usual access semantics of BSD locks: since | |
55 | `systemd-udevd` never writes to such block devices it only takes a `LOCK_SH` | |
56 | *shared* lock. A program intending to make changes to the block device should | |
57 | take a `LOCK_EX` *exclusive* lock instead. For further details, see the | |
58 | `flock(2)` man page. | |
59 | ||
60 | And please keep in mind: BSD file locks (`flock()`) and POSIX file locks | |
61 | (`lockf()`, `F_SETLK`, …) are different concepts, and in their effect | |
62 | orthogonal. The scheme discussed above uses the former and not the latter, | |
edc8e7b8 | 63 | because these types of locks more closely match the required semantics. |
ecb1a44c LP |
64 | |
65 | Summarizing: it is recommended to take `LOCK_EX` BSD file locks when | |
66 | manipulating block devices in all tools that change file system block devices | |
67 | (`mkfs`, `fsck`, …) or partition tables (`fdisk`, `parted`, …), right after | |
68 | opening the node. |