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