]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
storage: Report error from VolOpen by default
authorCole Robinson <crobinso@redhat.com>
Wed, 2 Apr 2014 15:51:45 +0000 (11:51 -0400)
committerCole Robinson <crobinso@redhat.com>
Mon, 8 Sep 2014 16:17:32 +0000 (12:17 -0400)
Currently VolOpen notifies the user of a potentially non-fatal failure by
returning -2 and logging a VIR_WARN or VIR_INFO. Unfortunately most
callers treat -2 as fatal but don't actually report any message with
the error APIs.

Rename the VOL_OPEN_ERROR flag to VOL_OPEN_NOERROR. If NOERROR is specified,
we preserve the current behavior of returning -2 (there's only one caller
that wants this).

However in the default case, only return -1, and actually use the error
APIs. Fix up a couple callers as a result.

(cherry picked from commit 138e65c3bea86fd5f51d9133bdcd0b36bff143b7)

Conflicts:
src/storage/storage_backend.c
src/storage/storage_backend_fs.c

src/storage/storage_backend.c
src/storage/storage_backend.h
src/storage/storage_backend_fs.c
src/storage/storage_backend_scsi.c

index 0990ee4c4a48ab58019e6224773b2cfd112c27f6..717252e27f1246fbad353165b0c23fbb411d7a30 100644 (file)
@@ -1193,8 +1193,9 @@ virStorageBackendDetectBlockVolFormatFD(virStorageVolTargetPtr target,
 /*
  * Allows caller to silently ignore files with improper mode
  *
- * Returns -1 on error, -2 if file mode is unexpected or the
- * volume is a dangling symbolic link.
+ * Returns -1 on error. If VIR_STORAGE_VOL_OPEN_NOERROR is passed, we
+ * return -2 if file mode is unexpected or the volume is a dangling
+ * symbolic link.
  */
 int
 virStorageBackendVolOpen(const char *path, struct stat *sb,
@@ -1202,9 +1203,10 @@ virStorageBackendVolOpen(const char *path, struct stat *sb,
 {
     int fd, mode = 0;
     char *base = last_component(path);
+    bool noerror = (flags & VIR_STORAGE_VOL_OPEN_NOERROR);
 
     if (lstat(path, sb) < 0) {
-        if (errno == ENOENT && !(flags & VIR_STORAGE_VOL_OPEN_ERROR)) {
+        if (errno == ENOENT && noerror) {
             VIR_WARN("ignoring missing file '%s'", path);
             return -2;
         }
@@ -1215,34 +1217,40 @@ virStorageBackendVolOpen(const char *path, struct stat *sb,
     }
 
     if (S_ISFIFO(sb->st_mode)) {
-        VIR_WARN("ignoring FIFO '%s'", path);
-        return -2;
+        if (noerror) {
+            VIR_WARN("ignoring FIFO '%s'", path);
+            return -2;
+        }
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Volume path '%s' is a FIFO"), path);
+        return -1;
     } else if (S_ISSOCK(sb->st_mode)) {
-        VIR_WARN("ignoring socket '%s'", path);
-        return -2;
+        if (noerror) {
+            VIR_WARN("ignoring socket '%s'", path);
+            return -2;
+        }
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Volume path '%s' is a socket"), path);
+        return -1;
     }
 
     if ((fd = open(path, O_RDONLY|O_NONBLOCK|O_NOCTTY)) < 0) {
         if ((errno == ENOENT || errno == ELOOP) &&
-            S_ISLNK(sb->st_mode)) {
+            S_ISLNK(sb->st_mode) && noerror) {
             VIR_WARN("ignoring dangling symlink '%s'", path);
             return -2;
         }
-        if (errno == ENOENT && !(flags & VIR_STORAGE_VOL_OPEN_ERROR)) {
+        if (errno == ENOENT && noerror) {
             VIR_WARN("ignoring missing file '%s'", path);
             return -2;
         }
 
-        virReportSystemError(errno,
-                             _("cannot open volume '%s'"),
-                             path);
+        virReportSystemError(errno, _("cannot open volume '%s'"), path);
         return -1;
     }
 
     if (fstat(fd, sb) < 0) {
-        virReportSystemError(errno,
-                             _("cannot stat file '%s'"),
-                             path);
+        virReportSystemError(errno, _("cannot stat file '%s'"), path);
         VIR_FORCE_CLOSE(fd);
         return -1;
     }
@@ -1259,22 +1267,42 @@ virStorageBackendVolOpen(const char *path, struct stat *sb,
         if (STREQ(base, ".") ||
             STREQ(base, "..")) {
             VIR_FORCE_CLOSE(fd);
-            VIR_INFO("Skipping special dir '%s'", base);
+            if (noerror) {
+                VIR_INFO("Skipping special dir '%s'", base);
+                return -2;
+            }
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Cannot use volume path '%s'"), path);
+            return -1;
+        }
+    } else {
+        VIR_FORCE_CLOSE(fd);
+        if (noerror) {
+            VIR_WARN("ignoring unexpected type for file '%s'", path);
             return -2;
         }
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("unexpected type for file '%s'"), path);
+        return -1;
     }
 
-    if (!(mode & flags)) {
+    if (virSetBlocking(fd, true) < 0) {
         VIR_FORCE_CLOSE(fd);
-        VIR_INFO("Skipping volume '%s'", path);
+        virReportSystemError(errno, _("unable to set blocking mode for '%s'"),
+                             path);
+        return -1;
+    }
 
-        if (mode & VIR_STORAGE_VOL_OPEN_ERROR) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("unexpected storage mode for '%s'"), path);
-            return -1;
+    if (!(mode & flags)) {
+        VIR_FORCE_CLOSE(fd);
+        if (noerror) {
+            VIR_INFO("Skipping volume '%s'", path);
+            return -2;
         }
 
-        return -2;
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("unexpected storage mode for '%s'"), path);
+        return -1;
     }
 
     return fd;
index ed8a4c25c9e95aa86a38186520effbdf27751254..b7f68777de94dc544d28b0dbce31d4e87efc00e3 100644 (file)
@@ -93,16 +93,15 @@ virStorageBackendPtr virStorageBackendForType(int type);
 
 /* VolOpenCheckMode flags */
 enum {
-    VIR_STORAGE_VOL_OPEN_ERROR  = 1 << 0, /* warn if unexpected type
-                                           * encountered */
-    VIR_STORAGE_VOL_OPEN_REG    = 1 << 1, /* regular files okay */
-    VIR_STORAGE_VOL_OPEN_BLOCK  = 1 << 2, /* block files okay */
-    VIR_STORAGE_VOL_OPEN_CHAR   = 1 << 3, /* char files okay */
-    VIR_STORAGE_VOL_OPEN_DIR    = 1 << 4, /* directories okay */
+    VIR_STORAGE_VOL_OPEN_NOERROR = 1 << 0, /* don't error if unexpected type
+                                            * encountered, just warn */
+    VIR_STORAGE_VOL_OPEN_REG     = 1 << 1, /* regular files okay */
+    VIR_STORAGE_VOL_OPEN_BLOCK   = 1 << 2, /* block files okay */
+    VIR_STORAGE_VOL_OPEN_CHAR    = 1 << 3, /* char files okay */
+    VIR_STORAGE_VOL_OPEN_DIR     = 1 << 4, /* directories okay */
 };
 
-# define VIR_STORAGE_VOL_OPEN_DEFAULT (VIR_STORAGE_VOL_OPEN_ERROR    |\
-                                       VIR_STORAGE_VOL_OPEN_REG      |\
+# define VIR_STORAGE_VOL_OPEN_DEFAULT (VIR_STORAGE_VOL_OPEN_REG      |\
                                        VIR_STORAGE_VOL_OPEN_BLOCK)
 
 int virStorageBackendVolOpen(const char *path, struct stat *sb,
index 05da82caa4fef5dd7a46fd03dbf72778378f46c5..17fb84fe38278834a5e124e73d7cb543f9556fe8 100644 (file)
 
 #define VIR_FROM_THIS VIR_FROM_STORAGE
 
-#define VIR_STORAGE_VOL_FS_OPEN_FLAGS       (VIR_STORAGE_VOL_OPEN_DEFAULT   |\
-                                             VIR_STORAGE_VOL_OPEN_DIR)
-#define VIR_STORAGE_VOL_FS_REFRESH_FLAGS    (VIR_STORAGE_VOL_FS_OPEN_FLAGS  &\
-                                             ~VIR_STORAGE_VOL_OPEN_ERROR)
+#define VIR_STORAGE_VOL_FS_OPEN_FLAGS    (VIR_STORAGE_VOL_OPEN_DEFAULT | \
+                                          VIR_STORAGE_VOL_OPEN_DIR)
+#define VIR_STORAGE_VOL_FS_PROBE_FLAGS   (VIR_STORAGE_VOL_FS_OPEN_FLAGS | \
+                                          VIR_STORAGE_VOL_OPEN_NOERROR)
 
 static int ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
 virStorageBackendProbeTarget(virStorageVolTargetPtr target,
@@ -78,7 +78,7 @@ virStorageBackendProbeTarget(virStorageVolTargetPtr target,
         *encryption = NULL;
 
     if ((ret = virStorageBackendVolOpen(target->path, &sb,
-                                        VIR_STORAGE_VOL_FS_REFRESH_FLAGS)) < 0)
+                                        VIR_STORAGE_VOL_FS_PROBE_FLAGS)) < 0)
         goto error; /* Take care to propagate ret, it is not always -1 */
     fd = ret;
 
@@ -874,19 +874,13 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn ATTRIBUTE_UNUSED,
             vol->backingStore.path = backingStore;
             vol->backingStore.format = backingStoreFormat;
 
-            if (virStorageBackendUpdateVolTargetInfo(&vol->backingStore,
-                                        NULL, NULL, false,
-                                        VIR_STORAGE_VOL_OPEN_DEFAULT) < 0) {
-                /* The backing file is currently unavailable, the capacity,
-                 * allocation, owner, group and mode are unknown. Just log the
-                 * error and continue.
-                 * Unfortunately virStorageBackendProbeTarget() might already
-                 * have logged a similar message for the same problem, but only
-                 * if AUTO format detection was used. */
-                virReportError(VIR_ERR_INTERNAL_ERROR,
-                               _("cannot probe backing volume info: %s"),
-                               vol->backingStore.path);
-            }
+            ignore_value(virStorageBackendUpdateVolTargetInfo(
+                                               &vol->backingStore,
+                                               NULL, NULL, false,
+                                               VIR_STORAGE_VOL_OPEN_DEFAULT));
+            /* If this failed, the backing file is currently unavailable,
+             * the capacity, allocation, owner, group and mode are unknown.
+             * An error message was raised, but we just continue. */
         }
 
 
index 9c38ca24c6fe927dd0f4ea856cdf6a509f4aa9c3..87a10a9902a815204e26c065d25f9e3384cd3abf 100644 (file)
@@ -199,9 +199,6 @@ virStorageBackendSCSINewLun(virStoragePoolObjPtr pool,
 
     if (virStorageBackendUpdateVolInfo(vol, true, true,
                                        VIR_STORAGE_VOL_OPEN_DEFAULT) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Failed to update volume for '%s'"),
-                       devpath);
         retval = -1;
         goto free_vol;
     }