[systemd-devel] udev interferes with sfdisk partition changes

Daniel Drake dsd at laptop.org
Wed Nov 14 08:53:16 PST 2012


Hi,

At OLPC we use sfdisk to grow a partition from the initramfs on first boot.

However, we are finding this to be unreliable. Working with Fedora 18,
systemd-195, and OLPC XO-4 hardware.

The core of the problem seems to be udev's response to BLKRRPART - the
ioctl used to ask the kernel to re-read the partition table. When
BLKRRPART is executed, "udevadm monitor" shows KERNEL events for the
device partitions being removed, and then added again - even when no
partition change has happened.

A quick and easy way to fire off a BLKRRPART (and nothing else):
sfdisk -R /dev/mmcblk1

By inserting some printks in the kernel, I can see that firing off
BLKRRPART causes systemd-udevd to open and close the device,
presumably in response to the KERNEL events mentioned above, even when
no partitioning changes have happened.

With that background, here is what happens when sfdisk is run to
modify the partition table on a device which is fully settled and is
not mounted:

1. sfdisk fires off BLKRRPART immediately, before making any changes,
to check that the device isn't in use.
2. This causes the KERNEL events, and udev opens and closes the device
shortly after.
3. sfdisk writes the modified new partition table
4. sfdisk fires BLKRRPART again asking the kernel to note the new
partition table

The problem here is that #2 runs in parallel, being a separate
process. On a quite regular basis, the sequence actually happens like
this:

1. sfdisk fires off BLKRRPART immediately, before making any changes,
to check that the device isn't in use.
2. This causes the KERNEL events, and udev opens the device.
3. sfdisk writes the modified new partition table
4. sfdisk fires BLKRRPART again asking the kernel to note the new
partition table. This fails, since the device is open.
5. udev closes the device.

In such a case, sfdisk has failed to update the partition setup
visible to the user, claiming that the device is probably mounted or
something, for no immediately obvious reason ("eh? the device wasn't
in use by anyone!").

This can be reproduced within seconds by running a script in a loop
that uses sfdisk to do the following to an unmounted and otherwise
unused SD card:
 1. Make the first partition a little smaller
 2. Grow the first partition to its full size

Within seconds you hit the failure condition noted above.


How can/should this be corrected?

Its annoying that udev is performing the device open here, but given
the events from the kernel, its probably a sensible thing to do.

Should the kernel not be generating these events when the partition
table hasn't changed?

Or should sfdisk acknowledge these possible races and try these ioctls
a few times in a loop before bailing out?

Maybe this is all a consequence of the kernel's lack of "lock this
device down, I want to partition it" interface?

Thanks
Daniel


More information about the systemd-devel mailing list