Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=977706 v1, v2 by Ján Tomko https://www.redhat.com/archives/libvir-list/2013-July/msg00639.html To get volume file fd in the fist place. The purpose of doing so is to ensure the async deletion of volume doesn't make impact on the following operation for the volume till we recheck the existence of volume file later. If we don't get its fd firstly, it is diffcult to differentiate the non-existent file error caused by system or being deleted asynchronous. --- src/storage/storage_backend.c | 49 +++++++++++++++++----------------------- src/storage/storage_backend_fs.c | 6 +++++ 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index 8d5880e..aa1635a 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -1093,29 +1093,13 @@ virStorageBackendVolOpenCheckMode(const char *path, unsigned int flags) int fd, mode = 0; struct stat sb; char *base = last_component(path); - - if (lstat(path, &sb) < 0) { - virReportSystemError(errno, - _("cannot stat file '%s'"), - path); - return -1; - } - - if (S_ISFIFO(sb.st_mode)) { - VIR_WARN("ignoring FIFO '%s'", path); - return -2; - } else if (S_ISSOCK(sb.st_mode)) { - VIR_WARN("ignoring socket '%s'", path); - return -2; - } + int ret = -1; if ((fd = open(path, O_RDONLY|O_NONBLOCK|O_NOCTTY)) < 0) { - if ((errno == ENOENT || errno == ELOOP) && - S_ISLNK(sb.st_mode)) { - VIR_WARN("ignoring dangling symlink '%s'", path); + if (errno == ENOENT) { + VIR_WARN("volume '%s' does not exist", path); return -2; } - virReportSystemError(errno, _("cannot open volume '%s'"), path); @@ -1126,8 +1110,7 @@ virStorageBackendVolOpenCheckMode(const char *path, unsigned int flags) virReportSystemError(errno, _("cannot stat file '%s'"), path); - VIR_FORCE_CLOSE(fd); - return -1; + goto error; } if (S_ISREG(sb.st_mode)) @@ -1141,26 +1124,36 @@ virStorageBackendVolOpenCheckMode(const char *path, unsigned int flags) if (STREQ(base, ".") || STREQ(base, "..")) { - VIR_FORCE_CLOSE(fd); VIR_INFO("Skipping special dir '%s'", base); - return -2; + goto skipfile; } + } else if (S_ISFIFO(sb.st_mode)) { + VIR_WARN("ignoring FIFO '%s'", path); + goto skipfile; + } else if (S_ISSOCK(sb.st_mode)) { + VIR_WARN("ignoring socket '%s'", path); + goto skipfile; } if (!(mode & flags)) { - VIR_FORCE_CLOSE(fd); - VIR_INFO("Skipping volume '%s'", path); - if (mode & VIR_STORAGE_VOL_OPEN_ERROR) { virReportError(VIR_ERR_INTERNAL_ERROR, _("unexpected storage mode for '%s'"), path); - return -1; + goto error; } - return -2; + VIR_INFO("Skipping volume '%s'", path); + goto skipfile; } return fd; + +skipfile: + ret = -2; + +error: + VIR_FORCE_CLOSE(fd); + return ret; } int virStorageBackendVolOpen(const char *path) diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c index d305b06..d0276fc 100644 --- a/src/storage/storage_backend_fs.c +++ b/src/storage/storage_backend_fs.c @@ -889,6 +889,12 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED, } } + /* Recheck the existence of volume again */ + if (access(vol->target.path, F_OK) < 0) { + virStorageVolDefFree(vol); + vol = NULL; + continue; + } if (VIR_REALLOC_N(pool->volumes.objs, pool->volumes.count+1) < 0) -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list