summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Lalancette <clalance@redhat.com>2008-11-28 07:50:20 +0000
committerChris Lalancette <clalance@redhat.com>2008-11-28 07:50:20 +0000
commita9567e09ef43ab01f7beb4c1d1c2ff4aef13fca2 (patch)
tree1d545e867a024db63344f79fb75612bfd4497960 /src
parentCurrently libvirt can race with udev (diff)
downloadlibvirt-a9567e09ef43ab01f7beb4c1d1c2ff4aef13fca2.tar.gz
libvirt-a9567e09ef43ab01f7beb4c1d1c2ff4aef13fca2.tar.bz2
libvirt-a9567e09ef43ab01f7beb4c1d1c2ff4aef13fca2.zip
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@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/storage_backend.c21
-rw-r--r--src/storage_backend.h2
-rw-r--r--src/storage_backend_disk.c2
-rw-r--r--src/storage_backend_iscsi.c2
-rw-r--r--src/storage_backend_logical.c2
5 files changed, 29 insertions, 0 deletions
diff --git a/src/storage_backend.c b/src/storage_backend.c
index 9266e5cdc..6b4fa818c 100644
--- a/src/storage_backend.c
+++ b/src/storage_backend.c
@@ -270,6 +270,27 @@ virStorageBackendUpdateVolInfoFD(virConnectPtr conn,
return 0;
}
+#ifdef UDEVADM
+void virStorageBackendWaitForDevices(virConnectPtr conn)
+{
+ const char *const settleprog[] = { UDEVADM, "settle", NULL };
+ int exitstatus;
+
+ if (access(UDEVADM, X_OK) != 0)
+ return;
+
+ /*
+ * 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 for any reason, we still have the backup of polling for
+ * 5 seconds for device nodes.
+ */
+ virRun(conn, settleprog, &exitstatus);
+}
+#else
+void virStorageBackendWaitForDevices(virConnectPtr conn ATTRIBUTE_UNUSED) {}
+#endif
+
/*
* Given a volume path directly in /dev/XXX, iterate over the
* entries in the directory pool->def->target.path and find the
diff --git a/src/storage_backend.h b/src/storage_backend.h
index 7904d9d06..06f6979ad 100644
--- a/src/storage_backend.h
+++ b/src/storage_backend.h
@@ -69,6 +69,8 @@ int virStorageBackendUpdateVolInfoFD(virConnectPtr conn,
int fd,
int withCapacity);
+void virStorageBackendWaitForDevices(virConnectPtr conn);
+
char *virStorageBackendStablePath(virConnectPtr conn,
virStoragePoolObjPtr pool,
const char *devpath);
diff --git a/src/storage_backend_disk.c b/src/storage_backend_disk.c
index 458e30773..127e02c4a 100644
--- a/src/storage_backend_disk.c
+++ b/src/storage_backend_disk.c
@@ -262,6 +262,8 @@ virStorageBackendDiskRefreshPool(virConnectPtr conn,
VIR_FREE(pool->def->source.devices[0].freeExtents);
pool->def->source.devices[0].nfreeExtent = 0;
+ virStorageBackendWaitForDevices(conn);
+
return virStorageBackendDiskReadPartitions(conn, pool, NULL);
}
diff --git a/src/storage_backend_iscsi.c b/src/storage_backend_iscsi.c
index 54a6409e0..b347fa930 100644
--- a/src/storage_backend_iscsi.c
+++ b/src/storage_backend_iscsi.c
@@ -603,6 +603,8 @@ virStorageBackendISCSIRefreshPool(virConnectPtr conn,
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)
diff --git a/src/storage_backend_logical.c b/src/storage_backend_logical.c
index ee8e8f84d..a358c4320 100644
--- a/src/storage_backend_logical.c
+++ b/src/storage_backend_logical.c
@@ -470,6 +470,8 @@ virStorageBackendLogicalRefreshPool(virConnectPtr conn,
};
int exitstatus;
+ virStorageBackendWaitForDevices(conn);
+
/* Get list of all logical volumes */
if (virStorageBackendLogicalFindLVs(conn, pool, NULL) < 0) {
virStoragePoolObjClearVols(pool);