diff options
Diffstat (limited to 'debian/patches/udevadm-settle.patch')
-rw-r--r-- | debian/patches/udevadm-settle.patch | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/debian/patches/udevadm-settle.patch b/debian/patches/udevadm-settle.patch new file mode 100644 index 0000000..96cdbcf --- /dev/null +++ b/debian/patches/udevadm-settle.patch @@ -0,0 +1,105 @@ +From 3947abeeb92069705229bff681b28d8ac78aedaa Mon Sep 17 00:00:00 2001 +From: Colin Watson <cjwatson@ubuntu.com> +Date: Fri, 28 Mar 2014 17:10:16 +0000 +Subject: udev handling + +Run udevadm settle around partition table rereads, to avoid races. + +This should be replaced by a proper completion-notification mechanism +between the kernel and udev. + +Forwarded: no +Last-Update: 2019-10-11 + +Patch-Name: udevadm-settle.patch +--- + libparted/arch/linux.c | 56 ++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 54 insertions(+), 2 deletions(-) + +diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c +index ccbba865..f6f72360 100644 +--- a/libparted/arch/linux.c ++++ b/libparted/arch/linux.c +@@ -26,6 +26,7 @@ + #include <parted/fdasd.h> + #endif + ++#include <stdlib.h> + #include <ctype.h> + #include <errno.h> + #include <fcntl.h> +@@ -3250,10 +3251,52 @@ _have_blkpg () + return have_blkpg = kver >= KERNEL_VERSION (2,4,0) ? 1 : 0; + } + ++static int ++_chrooted () ++{ ++ static int cached = -1; ++ struct stat root, init_root; ++ ++ if (cached != -1) ++ return cached; ++ ++ if (stat ("/", &root) || stat ("/proc/1/root", &init_root)) ++ /* We can't tell, but are unlikely to be able to tell in the ++ * future either. ++ */ ++ cached = 0; ++ else if (root.st_dev == init_root.st_dev && ++ root.st_ino == init_root.st_ino) ++ /* / has the same dev/ino as /sbin/init's root, so we're not ++ * in a chroot. ++ */ ++ cached = 0; ++ else ++ /* We must be in a chroot. */ ++ cached = 1; ++ ++ return cached; ++} ++ + /* Return nonzero upon success, 0 if something fails. */ + static int + linux_disk_commit (PedDisk* disk) + { ++ int ret = 1; ++ ++ /* Modern versions of udev may notice the write activity on ++ * partition devices caused by _flush_cache, and may decide to ++ * synthesise some change events as a result. These may in turn run ++ * programs that open partition devices, which will race with us ++ * trying to remove those devices. To avoid this, we need to wait ++ * until udevd has finished processing its event queue. ++ * TODO: for upstream submission, this should check whether udevadm ++ * exists on $PATH. ++ */ ++ if (!_chrooted () && system ("udevadm settle") != 0) { ++ /* ignore failures */ ++ } ++ + if (disk->dev->type != PED_DEVICE_FILE) { + + /* We now require BLKPG support. If this assertion fails, +@@ -3263,10 +3306,19 @@ linux_disk_commit (PedDisk* disk) + assert (_have_blkpg ()); + + if (!_disk_sync_part_table (disk)) +- return 0; ++ ret = 0; + } + +- return 1; ++ /* Now we wait for udevd to finish creating device nodes based on ++ * the above activity, so that callers can reliably use them. ++ * TODO: for upstream submission, this should check whether udevadm ++ * exists on $PATH. ++ */ ++ if (!_chrooted () && system ("udevadm settle") != 0) { ++ /* ignore failures */ ++ } ++ ++ return ret; + } + + #if USE_BLKID |