[libvirt] [PATCH v3 4/6] storage: Handle readflags errors

John Ferlan jferlan at redhat.com
Fri Dec 4 22:23:51 UTC 2015


Similar to the openflags VIR_STORAGE_VOL_OPEN_NOERROR processing, if some
read processing operation fails, check the readflags for the corresponding
error flag being set. If so, rather then causing an error - use VIR_WARN
to flag the error, but return -2 which some callers can use to perform
specific actions. Use a new VIR_STORAGE_VOL_READ_NOERROR flag in a new
VolReadErrorMode enum.

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 src/storage/storage_backend.c | 43 +++++++++++++++++++++++++++++++------------
 src/storage/storage_backend.h |  9 +++++++++
 2 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 8eb5b04..c29b162 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -1393,14 +1393,17 @@ static struct diskType const disk_types[] = {
  * virStorageBackendDetectBlockVolFormatFD
  * @target: target definition ptr of volume to update
  * @fd: fd of storage volume to update,
- * @readflags: unused
+ * @readflags: VolReadErrorMode flags to handle read error after open
+ *             is successful, but read is not.
  *
- * Returns 0 for success, -1 on a legitimate error condition
+ * Returns 0 for success, -1 on a legitimate error condition, -2 if
+ * the read error is desired to be ignored (along with appropriate
+ * VIR_WARN of the issue).
  */
 static int
 virStorageBackendDetectBlockVolFormatFD(virStorageSourcePtr target,
                                         int fd,
-                                        unsigned int readflags ATTRIBUTE_UNUSED)
+                                        unsigned int readflags)
 {
     size_t i;
     off_t start;
@@ -1419,10 +1422,16 @@ virStorageBackendDetectBlockVolFormatFD(virStorageSourcePtr target,
     }
     bytes = saferead(fd, buffer, sizeof(buffer));
     if (bytes < 0) {
-        virReportSystemError(errno,
-                             _("cannot read beginning of file '%s'"),
-                             target->path);
-        return -1;
+        if (readflags & VIR_STORAGE_VOL_READ_NOERROR) {
+            VIR_WARN("ignoring failed saferead of file '%s'",
+                     target->path);
+            return -2;
+        } else {
+            virReportSystemError(errno,
+                                 _("cannot read beginning of file '%s'"),
+                                 target->path);
+            return -1;
+        }
     }
 
     for (i = 0; disk_types[i].part_table_type != -1; i++) {
@@ -1591,11 +1600,13 @@ virStorageBackendVolOpen(const char *path, struct stat *sb,
  * @target: target definition ptr of volume to update
  * @withBlockVolFormat: true if caller determined a block file
  * @openflags: various VolOpenCheckMode flags to handle errors on open
- * @readflags: unused
+ * @readflags: VolReadErrorMode flags to handle read error after open
+ *             is successful, but read is not.
  *
  * Returns 0 for success, -1 on a legitimate error condition, and -2
  * if the openflags used VIR_STORAGE_VOL_OPEN_NOERROR and some sort of
- * open error occurred. It is up to the caller to handle.
+ * open error occurred. It is up to the caller to handle. A -2 may also
+ * be returned if the caller passed a readflagsflag.
  */
 int
 virStorageBackendUpdateVolTargetInfo(virStorageSourcePtr target,
@@ -1630,8 +1641,16 @@ virStorageBackendUpdateVolTargetInfo(virStorageSourcePtr target,
         }
 
         if ((len = virFileReadHeaderFD(fd, len, &buf)) < 0) {
-            virReportSystemError(errno, _("cannot read header '%s'"), target->path);
-            ret = -1;
+            if (readflags & VIR_STORAGE_VOL_READ_NOERROR) {
+                VIR_WARN("ignoring failed header read for '%s'",
+                         target->path);
+                ret = -2;
+            } else {
+                virReportSystemError(errno,
+                                     _("cannot read header '%s'"),
+                                     target->path);
+                ret = -1;
+            }
             goto cleanup;
         }
 
@@ -1663,7 +1682,7 @@ virStorageBackendUpdateVolTargetInfo(virStorageSourcePtr target,
  * @vol: Pointer to a volume storage definition
  * @withBlockVolFormat: true if the caller determined a block file
  * @openflags: various VolOpenCheckMode flags to handle errors on open
- * @readflags: unused
+ * @readflags: various VolReadErrorMode flags to handle errors on read
  *
  * Returns 0 for success, -1 on a legitimate error condition, and -2
  * if the openflags used VIR_STORAGE_VOL_OPEN_NOERROR and some sort of
diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h
index 64c46ee..20e6079 100644
--- a/src/storage/storage_backend.h
+++ b/src/storage/storage_backend.h
@@ -179,6 +179,15 @@ enum {
     VIR_STORAGE_VOL_OPEN_DIR     = 1 << 4, /* directories okay */
 };
 
+/* VolReadErrorMode flags
+ * If flag is present, then operation won't cause fatal error for
+ * specified operation, rather a VIR_WARN will be issued and a -2 returned
+ * for function call
+ */
+enum {
+    VIR_STORAGE_VOL_READ_NOERROR    = 1 << 0, /* ignore *read errors */
+};
+
 # define VIR_STORAGE_VOL_OPEN_DEFAULT (VIR_STORAGE_VOL_OPEN_REG      |\
                                        VIR_STORAGE_VOL_OPEN_BLOCK)
 
-- 
2.5.0




More information about the libvir-list mailing list