Richard W.M. Jones
2012-Feb-06 21:52 UTC
[Libguestfs] [PATCH 0/2] Work-around blkid running from udev after device close.
This is a possibly better work-around for bug 769304, the bug where blkid runs from udev whenever a device closes, causing the subsequent operation to fail. For background to this change, see: https://rwmj.wordpress.com/2012/01/19/udev-unexpectedness/#content So far we have noticed this problem in two places (although I'm fairly certain it affects many more): - in virt-resize, after copy_device_to_device and before part_set_bootable (which runs parted) - in virt-format, after wiping the device (which writes zeroes then closes it) and before blockdev_rereadpt The fix is to run udev_settle *before* all blockdev, parted and sfdisk commands. Note we do it before because at this point a blkid command may be running which we have to wait for. None of these commands should be performance sensitive (unlike pwrite_device, where I have removed the udev_settle call). In the parted and sfdisk cases we also have to run this command afterwards, since parted itself will have closed the block device. There may be alternatives to this patch: - Add a udev rule (temporarily?) which causes udev to ignore devices that libguestfs is using. However I feel this could be dangerous since it may affect more than just the problematic blkid operation. - Edit the udev rules so that the blkid rule doesn't run. This requires complex and distro-specific edits to built-in udev rules. - Get something into udev upstream which lessens the effect of the blkid rule (eg. delaying it or disabling it in some circumstances) Rich.
Richard W.M. Jones
2012-Feb-06 21:52 UTC
[Libguestfs] [PATCH 1/2] Revert "daemon: Run udev_settle after pwrite-device finishes."
From: "Richard W.M. Jones" <rjones at redhat.com> This reverts commit a9c8123c72db47bcab8dd738e8d5256a9ae87f11. --- daemon/file.c | 18 +++--------------- daemon/parted.c | 3 +-- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/daemon/file.c b/daemon/file.c index 057e15d..91746e0 100644 --- a/daemon/file.c +++ b/daemon/file.c @@ -525,7 +525,7 @@ do_pread_device (const char *device, int count, int64_t offset, size_t *size_r) static int pwrite_fd (int fd, const char *content, size_t size, int64_t offset, - const char *display_path, int settle) + const char *display_path) { ssize_t r; @@ -541,18 +541,6 @@ pwrite_fd (int fd, const char *content, size_t size, int64_t offset, return -1; } - /* When you call close on any block device, udev kicks off a rule - * which runs blkid to reexamine the device. We need to wait for - * this rule to finish running since it holds the device open and - * can cause other operations to fail, notably BLKRRPART. 'settle' - * flag is only set on block devices. - * - * XXX We should be smarter about when we do this or should get rid - * of the udev rules since we don't use blkid in cached mode. - */ - if (settle) - udev_settle (); - return r; } @@ -575,7 +563,7 @@ do_pwrite (const char *path, const char *content, size_t size, int64_t offset) return -1; } - return pwrite_fd (fd, content, size, offset, path, 0); + return pwrite_fd (fd, content, size, offset, path); } int @@ -593,7 +581,7 @@ do_pwrite_device (const char *device, const char *content, size_t size, return -1; } - return pwrite_fd (fd, content, size, offset, device, 1); + return pwrite_fd (fd, content, size, offset, device); } /* This runs the 'file' command. */ diff --git a/daemon/parted.c b/daemon/parted.c index 64a7d1d..16f0843 100644 --- a/daemon/parted.c +++ b/daemon/parted.c @@ -34,8 +34,7 @@ * COMMAND_FLAG_FOLD_STDOUT_ON_STDERR flag. * * parted occasionally fails to do ioctl(BLKRRPART) on the device, - * probably because udev monitors all 'close' on block devices - * and runs 'blkid' which opens and examines the device. We attempt + * apparently because of some internal race in the code. We attempt * to detect and recover from this error if we can. */ static int -- 1.7.6
Richard W.M. Jones
2012-Feb-06 21:57 UTC
[Libguestfs] [PATCH 0/2] Work-around blkid running from udev after device close.
I should add that I have a good reproducer for this: https://bugzilla.redhat.com/show_bug.cgi?id=769359#c5 I have run libguestfs built with and without these patches on RHEL 6.3 and demonstrated that the reproducer only fails on the unpatched libguestfs. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://libguestfs.org
Reasonably Related Threads
- [PATCH 1/3] daemon: pwrite/pread: Don't double close on error path.
- [PATCH 1/2] Revert "daemon: Run udev_settle after pwrite-device finishes."
- [PATCH 0/3]: daemon: Reimplement ‘file’ API in OCaml.
- [PATCH] blkid: remove the -o export option
- [PATCH] GuestOS: Delete blkid.tab if it's present