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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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





[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]