From 99e28249d52ca5495b636e14ae3e4387ee62c8fe Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Wed, 1 Jul 2009 17:15:24 +0100 Subject: [PATCH] Call 'udevadm settle' after operations which add/remove device nodes. Because udev operates asynchronously, we found errors which were caused by a previous command (eg. sfdisk or pvremove) creating or removing a device, and that change not having happened by the time the next command was run. This patch adds calls to '/sbin/udevadm settle' after any commands which can add or remove device nodes. If udev is not being used or not available, this should have no effect. The command fails and this is silently ignored. --- daemon/daemon.h | 2 ++ daemon/guestfsd.c | 13 +++++++++++++ daemon/lvm.c | 23 +++++++++++++++++++++++ daemon/sfdisk.c | 4 ++++ 4 files changed, 42 insertions(+) diff --git a/daemon/daemon.h b/daemon/daemon.h index 70f0bee..553973d 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -51,6 +51,8 @@ extern int shell_quote (char *out, int len, const char *in); extern int device_name_translation (char *device, const char *func); +extern void udev_settle (void); + extern int verbose; /*-- in proto.c --*/ diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c index 0a3e64f..e5f2cf0 100644 --- a/daemon/guestfsd.c +++ b/daemon/guestfsd.c @@ -741,3 +741,16 @@ device_name_translation (char *device, const char *func) device[5] = 's'; /* Restore original device name. */ goto error; } + +/* LVM and other commands aren't synchronous, especially when udev is + * involved. eg. You can create or remove some device, but the /dev + * device node won't appear until some time later. This means that + * you get an error if you run one command followed by another. + * Use 'udevadm settle' after certain commands, but don't be too + * fussed if it fails. + */ +void +udev_settle (void) +{ + command (NULL, NULL, "/sbin/udevadm", "settle", NULL); +} diff --git a/daemon/lvm.c b/daemon/lvm.c index 143c5a8..0fba447 100644 --- a/daemon/lvm.c +++ b/daemon/lvm.c @@ -187,6 +187,9 @@ do_pvcreate (char *device) } free (err); + + udev_settle (); + return 0; } @@ -221,6 +224,9 @@ do_vgcreate (char *volgroup, char **physvols) } free (err); + + udev_settle (); + return 0; } @@ -243,6 +249,9 @@ do_lvcreate (char *logvol, char *volgroup, int mbytes) } free (err); + + udev_settle (); + return 0; } @@ -331,6 +340,8 @@ do_lvm_remove_all (void) } free_strings (xs); + udev_settle (); + /* There, that was easy, sorry about your data. */ return 0; } @@ -352,6 +363,9 @@ do_lvremove (char *device) } free (err); + + udev_settle (); + return 0; } @@ -370,6 +384,9 @@ do_vgremove (char *device) } free (err); + + udev_settle (); + return 0; } @@ -390,6 +407,9 @@ do_pvremove (char *device) } free (err); + + udev_settle (); + return 0; } @@ -442,6 +462,9 @@ do_vg_activate (int activate, char **volgroups) } free (err); + + udev_settle (); + return 0; } diff --git a/daemon/sfdisk.c b/daemon/sfdisk.c index 6ff2736..5fb30c0 100644 --- a/daemon/sfdisk.c +++ b/daemon/sfdisk.c @@ -73,6 +73,8 @@ sfdisk (char *device, int n, int cyls, int heads, int sectors, return -1; } + udev_settle (); + return 0; } @@ -110,6 +112,8 @@ sfdisk_flag (char *device, const char *flag) free (err); + udev_settle (); + return out; /* caller frees */ } -- 1.8.3.1