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

[libvirt] [PATCH 2/2] qemu: add separate rerror_policy for disk errors



libvirt's XML only had a single attribute, error_policy to control
both read and write error policy, but qemu has separate settings for
these. In one case (enospc) a policy is allowed for write errors but
not read errors.

This patch adds a separate attribute that sets only the read error
policy. If just error_policy is set, it will apply to both read and
write error policy (previous behavior), but if the new rerror_policy
attribute is set, it will override error_policy for read errors only.
---
 docs/formatdomain.html.in |   16 +++++++++++++---
 src/conf/domain_conf.c    |   16 ++++++++++++++++
 src/conf/domain_conf.h    |    3 ++-
 src/qemu/qemu_command.c   |    5 ++++-
 4 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 593adcb..5265b21 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1008,9 +1008,19 @@
           </li>
           <li>
             The optional <code>error_policy</code> attribute controls
-            how the hypervisor will behave on an error, possible
-            values are "stop", "ignore", and "enospace".
-            <span class="since">Since 0.8.0</span>
+            how the hypervisor will behave on a disk read or write
+            error, possible values are "stop", "ignore", and
+            "enospace".<span class="since">Since 0.8.0</span> There is
+            also an optional <code>rerror_policy</code> that controls
+            behavior for read errors only.<span class="since">Since
+            0.9.7</space>. If no rerror_policy is given, error_policy
+            is used for both read and write errors. If rerror_policy
+            is given, it overrides the <code>error_policy</code> for
+            read errors. Also note that "enospace" is not a valid
+            policy for read errors, so if <code>error_policy</code> is
+            set to "enospace" and no <code>rerror_policy</code> is
+            given, the read error policy will be automatically set to
+            "ignore".
           </li>
           <li>
             The optional <code>io</code> attribute controls specific
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f9007ce..95e1a9a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2297,6 +2297,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
     char *bus = NULL;
     char *cachetag = NULL;
     char *error_policy = NULL;
+    char *rerror_policy = NULL;
     char *iotag = NULL;
     char *ioeventfd = NULL;
     char *event_idx = NULL;
@@ -2416,6 +2417,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
                 driverType = virXMLPropString(cur, "type");
                 cachetag = virXMLPropString(cur, "cache");
                 error_policy = virXMLPropString(cur, "error_policy");
+                rerror_policy = virXMLPropString(cur, "rerror_policy");
                 iotag = virXMLPropString(cur, "io");
                 ioeventfd = virXMLPropString(cur, "ioeventfd");
                 event_idx = virXMLPropString(cur, "event_idx");
@@ -2560,6 +2562,16 @@ virDomainDiskDefParseXML(virCapsPtr caps,
         goto error;
     }
 
+    if (rerror_policy &&
+        (((def->rerror_policy
+           = virDomainDiskErrorPolicyTypeFromString(error_policy)) < 0) ||
+         (def->rerror_policy == VIR_DOMAIN_DISK_ERROR_POLICY_ENOSPACE))) {
+        virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+                             _("unknown disk read error policy '%s'"),
+                             rerror_policy);
+        goto error;
+    }
+
     if (iotag) {
         if ((def->iomode = virDomainDiskIoTypeFromString(iotag)) < 0 ||
             def->iomode == VIR_DOMAIN_DISK_IO_DEFAULT) {
@@ -2667,6 +2679,7 @@ cleanup:
     VIR_FREE(driverName);
     VIR_FREE(cachetag);
     VIR_FREE(error_policy);
+    VIR_FREE(rerror_policy);
     VIR_FREE(iotag);
     VIR_FREE(ioeventfd);
     VIR_FREE(event_idx);
@@ -9127,6 +9140,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
     const char *bus = virDomainDiskBusTypeToString(def->bus);
     const char *cachemode = virDomainDiskCacheTypeToString(def->cachemode);
     const char *error_policy = virDomainDiskErrorPolicyTypeToString(def->error_policy);
+    const char *rerror_policy = virDomainDiskErrorPolicyTypeToString(def->rerror_policy);
     const char *iomode = virDomainDiskIoTypeToString(def->iomode);
     const char *ioeventfd = virDomainIoEventFdTypeToString(def->ioeventfd);
     const char *event_idx = virDomainVirtioEventIdxTypeToString(def->event_idx);
@@ -9177,6 +9191,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
             virBufferAsprintf(buf, " cache='%s'", cachemode);
         if (def->error_policy)
             virBufferAsprintf(buf, " error_policy='%s'", error_policy);
+        if (def->rerror_policy)
+            virBufferAsprintf(buf, " rerror_policy='%s'", rerror_policy);
         if (def->iomode)
             virBufferAsprintf(buf, " io='%s'", iomode);
         if (def->ioeventfd)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index bc41d34..35eacc7 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -284,7 +284,8 @@ struct _virDomainDiskDef {
     char *driverType;
     char *serial;
     int cachemode;
-    int error_policy;
+    int error_policy;  /* virDomainDiskErrorPolicy */
+    int rerror_policy; /* virDomainDiskErrorPolicy */
     int bootIndex;
     int iomode;
     int ioeventfd;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 123bcab..4f1bb25 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1696,6 +1696,8 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
 
         if (disk->error_policy)
             wpolicy = virDomainDiskErrorPolicyTypeToString(disk->error_policy);
+        if (disk->rerror_policy)
+            rpolicy = virDomainDiskErrorPolicyTypeToString(disk->rerror_policy);
         if (!rpolicy)
             rpolicy = wpolicy;
 
@@ -1704,7 +1706,8 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
              * and it's only valid for werror, not for rerror.
              */
             wpolicy="enospc";
-            rpolicy="ignore";
+            if (!disk->rerror_policy)
+               rpolicy="ignore";
         }
 
         if (wpolicy)
-- 
1.7.3.4


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