mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-30 17:45:23 +00:00
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 77eff5eeb2
)
This commit is contained in:
parent
aa9f65c869
commit
cbee5d8b90
@ -1338,10 +1338,14 @@ virStorageBackendDetectBlockVolFormatFD(virStorageVolTargetPtr target,
|
|||||||
*
|
*
|
||||||
* Typically target.path is one of the /dev/disk/by-XXX dirs
|
* Typically target.path is one of the /dev/disk/by-XXX dirs
|
||||||
* with stable paths.
|
* with stable paths.
|
||||||
|
*
|
||||||
|
* If 'wait' is true, we use a timeout loop to give dynamic paths
|
||||||
|
* a change to appear.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
virStorageBackendStablePath(virStoragePoolObjPtr pool,
|
virStorageBackendStablePath(virStoragePoolObjPtr pool,
|
||||||
const char *devpath)
|
const char *devpath,
|
||||||
|
bool wait)
|
||||||
{
|
{
|
||||||
DIR *dh;
|
DIR *dh;
|
||||||
struct dirent *dent;
|
struct dirent *dent;
|
||||||
@ -1372,7 +1376,7 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool,
|
|||||||
reopen:
|
reopen:
|
||||||
if ((dh = opendir(pool->def->target.path)) == NULL) {
|
if ((dh = opendir(pool->def->target.path)) == NULL) {
|
||||||
opentries++;
|
opentries++;
|
||||||
if (errno == ENOENT && opentries < 50) {
|
if (wait && errno == ENOENT && opentries < 50) {
|
||||||
usleep(100 * 1000);
|
usleep(100 * 1000);
|
||||||
goto reopen;
|
goto reopen;
|
||||||
}
|
}
|
||||||
@ -1387,7 +1391,7 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool,
|
|||||||
* the target directory and figure out which one points
|
* the target directory and figure out which one points
|
||||||
* to this device node.
|
* 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.
|
* up, so add timeout to retry here.
|
||||||
*/
|
*/
|
||||||
retry:
|
retry:
|
||||||
@ -1411,7 +1415,7 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool,
|
|||||||
VIR_FREE(stablepath);
|
VIR_FREE(stablepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++retry < 100) {
|
if (wait && ++retry < 100) {
|
||||||
usleep(100 * 1000);
|
usleep(100 * 1000);
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,8 @@ virStorageBackendDetectBlockVolFormatFD(virStorageVolTargetPtr target,
|
|||||||
int fd);
|
int fd);
|
||||||
|
|
||||||
char *virStorageBackendStablePath(virStoragePoolObjPtr pool,
|
char *virStorageBackendStablePath(virStoragePoolObjPtr pool,
|
||||||
const char *devpath);
|
const char *devpath,
|
||||||
|
bool wait);
|
||||||
|
|
||||||
typedef int (*virStorageBackendListVolRegexFunc)(virStoragePoolObjPtr pool,
|
typedef int (*virStorageBackendListVolRegexFunc)(virStoragePoolObjPtr pool,
|
||||||
char **const groups,
|
char **const groups,
|
||||||
|
@ -83,7 +83,7 @@ virStorageBackendDiskMakeDataVol(virStoragePoolObjPtr pool,
|
|||||||
* dir every time its run. Should figure out a more efficient
|
* dir every time its run. Should figure out a more efficient
|
||||||
* way of doing this...
|
* way of doing this...
|
||||||
*/
|
*/
|
||||||
vol->target.path = virStorageBackendStablePath(pool, devpath);
|
vol->target.path = virStorageBackendStablePath(pool, devpath, true);
|
||||||
VIR_FREE(devpath);
|
VIR_FREE(devpath);
|
||||||
if (vol->target.path == NULL)
|
if (vol->target.path == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -246,7 +246,8 @@ virStorageBackendSCSINewLun(virStoragePoolObjPtr pool,
|
|||||||
* way of doing this...
|
* way of doing this...
|
||||||
*/
|
*/
|
||||||
if ((vol->target.path = virStorageBackendStablePath(pool,
|
if ((vol->target.path = virStorageBackendStablePath(pool,
|
||||||
devpath)) == NULL) {
|
devpath,
|
||||||
|
true)) == NULL) {
|
||||||
retval = -1;
|
retval = -1;
|
||||||
goto free_vol;
|
goto free_vol;
|
||||||
}
|
}
|
||||||
|
@ -1318,7 +1318,8 @@ storageVolumeLookupByPath(virConnectPtr conn,
|
|||||||
const char *stable_path;
|
const char *stable_path;
|
||||||
|
|
||||||
stable_path = virStorageBackendStablePath(driver->pools.objs[i],
|
stable_path = virStorageBackendStablePath(driver->pools.objs[i],
|
||||||
cleanpath);
|
cleanpath,
|
||||||
|
false);
|
||||||
if (stable_path == NULL) {
|
if (stable_path == NULL) {
|
||||||
/* Don't break the whole lookup process if it fails on
|
/* Don't break the whole lookup process if it fails on
|
||||||
* getting the stable path for some of the pools.
|
* getting the stable path for some of the pools.
|
||||||
|
Loading…
Reference in New Issue
Block a user