Since we have a number of places where we workaround timing issues with devices, attributes (files in general) not being available at the time of processing them by calling usleep in a loop for a fixed number of tries, we could as well have a utility function that would do that. Therefore we won't have to duplicate this ugly workaround even more. This is a prerequisite for https://bugzilla.redhat.com/show_bug.cgi?id=1463285. Signed-off-by: Erik Skultety <eskultet@xxxxxxxxxx> --- src/libvirt_private.syms | 1 + src/util/virfile.c | 36 ++++++++++++++++++++++++++++++++++++ src/util/virfile.h | 2 ++ 3 files changed, 39 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c1e9471c5..53878a30f 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1698,6 +1698,7 @@ virFileStripSuffix; virFileTouch; virFileUnlock; virFileUpdatePerm; +virFileWaitForAccess; virFileWrapperFdClose; virFileWrapperFdFree; virFileWrapperFdNew; diff --git a/src/util/virfile.c b/src/util/virfile.c index 6bbcc3d15..0b1a91699 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -4164,3 +4164,39 @@ virFileReadValueString(char **value, const char *format, ...) VIR_FREE(str); return ret; } + + +/** + * virFileWaitForAccess: + * @path: absolute path to a sysfs attribute (can be a symlink) + * @ms: how long to wait (in milliseconds) + * @tries: how many times should we try to wait for @path to become accessible + * + * Checks the existence of @path. In case the file defined by @path + * doesn't exist, we wait for it to appear in 100ms (for up to @tries times). + * + * Returns 0 on success, -1 on error (ENOENT is fine here). + */ +int +virFileWaitForAccess(const char *path, size_t ms, size_t tries) +{ + errno = 0; + + /* wait for @path to be accessible in @ms milliseconds, up to @tries */ + while (tries-- > 0 && !virFileExists(path)) { + if (errno != ENOENT) { + virReportSystemError(errno, "%s", path); + return -1; + } else if (tries == 10) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to access '%s' after %zu tries"), + path, tries); + return -1; + } else { + VIR_DEBUG("Failed to access '%s', re-try in %zu ms", path, ms); + usleep(ms * 1000); + } + } + + return 0; +} diff --git a/src/util/virfile.h b/src/util/virfile.h index 57ceb8072..42630ebb5 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -347,6 +347,8 @@ int virFileReadValueScaledInt(unsigned long long *value, const char *format, ... int virFileReadValueString(char **value, const char *format, ...) ATTRIBUTE_FMT_PRINTF(2, 3); +int virFileWaitForAccess(const char *path, size_t ms, size_t tries); + int virFileInData(int fd, int *inData, -- 2.13.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list