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