summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2012-01-19 13:54:50 +0000
committerRichard W.M. Jones <rjones@redhat.com>2012-01-23 18:16:14 +0000
commit90d530492e6a6a77c68af68ebb52e58bca0142da (patch)
tree18f4cabbca299deda06f16e6af3123e5977bcc88
parent6ba46d85fdbae54d02b2e2a40a5f4148ea825988 (diff)
downloadlibguestfs-90d530492e6a6a77c68af68ebb52e58bca0142da.tar.gz
libguestfs-90d530492e6a6a77c68af68ebb52e58bca0142da.tar.xz
libguestfs-90d530492e6a6a77c68af68ebb52e58bca0142da.zip
daemon: Run udev_settle after pwrite-device finishes.
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. (cherry picked from commit a9c8123c72db47bcab8dd738e8d5256a9ae87f11)
-rw-r--r--daemon/file.c18
-rw-r--r--daemon/parted.c3
2 files changed, 17 insertions, 4 deletions
diff --git a/daemon/file.c b/daemon/file.c
index f0389196..163f0aa7 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)
+ const char *display_path, int settle)
{
ssize_t r;
@@ -541,6 +541,18 @@ 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;
}
@@ -563,7 +575,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);
+ return pwrite_fd (fd, content, size, offset, path, 0);
}
int
@@ -581,7 +593,7 @@ do_pwrite_device (const char *device, const char *content, size_t size,
return -1;
}
- return pwrite_fd (fd, content, size, offset, device);
+ return pwrite_fd (fd, content, size, offset, device, 1);
}
/* This runs the 'file' command. */
diff --git a/daemon/parted.c b/daemon/parted.c
index 0d229484..4e7d52b0 100644
--- a/daemon/parted.c
+++ b/daemon/parted.c
@@ -34,7 +34,8 @@
* COMMAND_FLAG_FOLD_STDOUT_ON_STDERR flag.
*
* parted occasionally fails to do ioctl(BLKRRPART) on the device,
- * apparently because of some internal race in the code. We attempt
+ * probably because udev monitors all 'close' on block devices
+ * and runs 'blkid' which opens and examines the device. We attempt
* to detect and recover from this error if we can.
*/
static int