Instead of relying solely on polling for /dev devices to appear in libvirt, we
really should be synchronizing against udev. This is generally done by a call
to udevsettle, which is exactly what this patch implements for the storage
backends that are likely to create new /dev nodes. I believe I've read that
even after udevsettle, you are not guaranteed that devices are all the way
created, so we still need the polling in the rest of the sources, but this
should give us a much better chance of things existing as we expect.
Signed-off-by: Chris Lalancette <clalance(a)redhat.com>
Index: src/storage_backend.c
===================================================================
RCS file: /data/cvs/libvirt/src/storage_backend.c,v
retrieving revision 1.29
diff -u -r1.29 storage_backend.c
--- a/src/storage_backend.c 17 Nov 2008 11:19:33 -0000 1.29
+++ b/src/storage_backend.c 26 Nov 2008 12:40:19 -0000
@@ -270,6 +270,20 @@
return 0;
}
+void virStorageBackendWaitForDevices(virConnectPtr conn)
+{
+ const char *const settleprog[] = { UDEVSETTLE, NULL };
+ int exitstatus;
+
+ /*
+ * NOTE: we ignore errors here; this is just to make sure that any device
+ * nodes that are being created finish before we try to
+ * scan them. If this fails (udevsettle exits badly, or doesn't exist
+ * at all), then we still have a fallback mechanism anyway.
+ */
+ virRun(conn, settleprog, &exitstatus);
+}
+
/*
* Given a volume path directly in /dev/XXX, iterate over the
* entries in the directory pool->def->target.path and find the
Index: src/storage_backend.h
===================================================================
RCS file: /data/cvs/libvirt/src/storage_backend.h,v
retrieving revision 1.13
diff -u -r1.13 storage_backend.h
--- a/src/storage_backend.h 17 Nov 2008 11:19:33 -0000 1.13
+++ b/src/storage_backend.h 26 Nov 2008 12:40:19 -0000
@@ -69,6 +69,8 @@
int fd,
int withCapacity);
+void virStorageBackendWaitForDevices(virConnectPtr conn);
+
char *virStorageBackendStablePath(virConnectPtr conn,
virStoragePoolObjPtr pool,
const char *devpath);
Index: src/storage_backend_logical.c
===================================================================
RCS file: /data/cvs/libvirt/src/storage_backend_logical.c,v
retrieving revision 1.26
diff -u -r1.26 storage_backend_logical.c
--- a/src/storage_backend_logical.c 17 Nov 2008 11:19:33 -0000 1.26
+++ b/src/storage_backend_logical.c 26 Nov 2008 12:40:19 -0000
@@ -470,6 +470,8 @@
};
int exitstatus;
+ virStorageBackendWaitForDevices(conn);
+
/* Get list of all logical volumes */
if (virStorageBackendLogicalFindLVs(conn, pool, NULL) < 0) {
virStoragePoolObjClearVols(pool);
Index: src/storage_backend_disk.c
===================================================================
RCS file: /data/cvs/libvirt/src/storage_backend_disk.c,v
retrieving revision 1.20
diff -u -r1.20 storage_backend_disk.c
--- a/src/storage_backend_disk.c 17 Nov 2008 11:19:33 -0000 1.20
+++ b/src/storage_backend_disk.c 26 Nov 2008 12:40:19 -0000
@@ -262,6 +262,8 @@
VIR_FREE(pool->def->source.devices[0].freeExtents);
pool->def->source.devices[0].nfreeExtent = 0;
+ virStorageBackendWaitForDevices(conn);
+
return virStorageBackendDiskReadPartitions(conn, pool, NULL);
}
Index: src/storage_backend_iscsi.c
===================================================================
RCS file: /data/cvs/libvirt/src/storage_backend_iscsi.c,v
retrieving revision 1.18
diff -u -r1.18 storage_backend_iscsi.c
--- a/src/storage_backend_iscsi.c 17 Nov 2008 11:19:33 -0000 1.18
+++ b/src/storage_backend_iscsi.c 26 Nov 2008 12:40:19 -0000
@@ -603,6 +603,8 @@
pool->def->allocation = pool->def->capacity = pool->def->available
= 0;
+ virStorageBackendWaitForDevices(conn);
+
if ((session = virStorageBackendISCSISession(conn, pool)) == NULL)
goto cleanup;
if (virStorageBackendISCSIRescanLUNs(conn, pool, session) < 0)
Index: configure.in
===================================================================
RCS file: /data/cvs/libvirt/configure.in,v
retrieving revision 1.187
diff -u -r1.187 configure.in
--- a/configure.in 25 Nov 2008 15:48:11 -0000 1.187
+++ b/configure.in 26 Nov 2008 12:40:19 -0000
@@ -115,11 +115,15 @@
[/sbin:/usr/sbin:/usr/local/sbin:$PATH])
AC_PATH_PROG([BRCTL], [brctl], [brctl],
[/sbin:/usr/sbin:/usr/local/sbin:$PATH])
+AC_PATH_PROG([UDEVSETTLE], [udevsettle], [udevsettle],
+ [/sbin:/usr/sbin:/usr/local/sbin:$PATH])
AC_DEFINE_UNQUOTED([DNSMASQ],["$DNSMASQ"],
[Location or name of the dnsmasq program])
AC_DEFINE_UNQUOTED([BRCTL],["$BRCTL"],
[Location or name of the brctl program (see bridge-utils)])
+AC_DEFINE_UNQUOTED([UDEVSETTLE],["$UDEVSETTLE"],
+ [Location or name of the udevsettle program (see udev)])
dnl Specific dir for HTML output ?
AC_ARG_WITH([html-dir], [AC_HELP_STRING([--with-html-dir=path],