From: Cole Robinson Date: Sun, 21 Oct 2012 16:53:20 +0000 (-0400) Subject: storage: Don't do wait loops from VolLookupByPath X-Git-Tag: v0.10.2.1~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cbee5d8b9011af3933876ee70907dbbd4bf5d712;p=thirdparty%2Flibvirt.git storage: Don't do wait loops from VolLookupByPath virStorageVolLookupByPath is an API call that virt-manager uses quite a bit when dealing with storage. This call use BackendStablePath which has several usleep() heuristics that can be tripped up and hang virt-manager for a while. Current example: an empty mpath pool pointing to /dev/mapper makes _any_ calls to virStorageVolLookupByPath take 5 seconds. The sleep heuristics are actually only needed in certain cases when we are waiting for new storage to appear, so let's skip the timeout steps when calling from LookupByPath. (cherry picked from commit 77eff5eeb2d2aada3c670d325d04a35b54428988) --- diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index aea70e2561..85b8287e30 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -1338,10 +1338,14 @@ virStorageBackendDetectBlockVolFormatFD(virStorageVolTargetPtr target, * * Typically target.path is one of the /dev/disk/by-XXX dirs * with stable paths. + * + * If 'wait' is true, we use a timeout loop to give dynamic paths + * a change to appear. */ char * virStorageBackendStablePath(virStoragePoolObjPtr pool, - const char *devpath) + const char *devpath, + bool wait) { DIR *dh; struct dirent *dent; @@ -1372,7 +1376,7 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool, reopen: if ((dh = opendir(pool->def->target.path)) == NULL) { opentries++; - if (errno == ENOENT && opentries < 50) { + if (wait && errno == ENOENT && opentries < 50) { usleep(100 * 1000); goto reopen; } @@ -1387,7 +1391,7 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool, * the target directory and figure out which one points * to this device node. * - * And it might need some time till the stabe path shows + * And it might need some time till the stable path shows * up, so add timeout to retry here. */ retry: @@ -1411,7 +1415,7 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool, VIR_FREE(stablepath); } - if (++retry < 100) { + if (wait && ++retry < 100) { usleep(100 * 1000); goto retry; } diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h index a67eeb7ddf..71935a7607 100644 --- a/src/storage/storage_backend.h +++ b/src/storage/storage_backend.h @@ -130,7 +130,8 @@ virStorageBackendDetectBlockVolFormatFD(virStorageVolTargetPtr target, int fd); char *virStorageBackendStablePath(virStoragePoolObjPtr pool, - const char *devpath); + const char *devpath, + bool wait); typedef int (*virStorageBackendListVolRegexFunc)(virStoragePoolObjPtr pool, char **const groups, diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c index ceceab06f9..b7bceea0c4 100644 --- a/src/storage/storage_backend_disk.c +++ b/src/storage/storage_backend_disk.c @@ -83,7 +83,7 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr pool, * dir every time its run. Should figure out a more efficient * way of doing this... */ - vol->target.path = virStorageBackendStablePath(pool, devpath); + vol->target.path = virStorageBackendStablePath(pool, devpath, true); VIR_FREE(devpath); if (vol->target.path == NULL) return -1; diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index 27dcbb67ea..4e832eb656 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -246,7 +246,8 @@ virStorageBackendSCSINewLun(virStoragePoolObjPtr pool, * way of doing this... */ if ((vol->target.path = virStorageBackendStablePath(pool, - devpath)) == NULL) { + devpath, + true)) == NULL) { retval = -1; goto free_vol; } diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c index 28829d3800..4fbc0c015d 100644 --- a/src/storage/storage_driver.c +++ b/src/storage/storage_driver.c @@ -1318,7 +1318,8 @@ storageVolumeLookupByPath(virConnectPtr conn, const char *stable_path; stable_path = virStorageBackendStablePath(driver->pools.objs[i], - cleanpath); + cleanpath, + false); if (stable_path == NULL) { /* Don't break the whole lookup process if it fails on * getting the stable path for some of the pools.