[libvirt] [v3 PATCH] storage: skip async-deleted volume while fs storage is being refreshed

Guannan Ren gren at redhat.com
Tue Jul 16 11:27:02 UTC 2013


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




More information about the libvir-list mailing list