]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: blockjob: Introduce "broken" block job type
authorPeter Krempa <pkrempa@redhat.com>
Tue, 26 Nov 2019 13:55:05 +0000 (14:55 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Wed, 27 Nov 2019 14:59:33 +0000 (15:59 +0100)
To better track jobs we couldn't parse let's introduce a new job type
which will clarify semantics internally in few places.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Cole Robinson <crobinso@redhat.com>
src/qemu/qemu_blockjob.c
src/qemu/qemu_blockjob.h
src/qemu/qemu_domain.c
src/qemu/qemu_driver.c
tests/qemustatusxml2xmldata/blockjob-blockdev-in.xml

index 9148e40ce5b3837bf12fe25c8c04ce807ebee930..1e31052385b6b4c545c5acad5aa7ff260bf3cbaa 100644 (file)
@@ -66,7 +66,8 @@ VIR_ENUM_IMPL(qemuBlockjob,
               "commit",
               "active-commit",
               "",
-              "create");
+              "create",
+              "broken");
 
 static virClassPtr qemuBlockJobDataClass;
 
@@ -128,6 +129,23 @@ qemuBlockJobDataNew(qemuBlockJobType type,
 }
 
 
+/**
+ * qemuBlockJobMarkBroken:
+ * @job: job to mark as broken
+ *
+ * In case when we are unable to parse the block job data from the XML
+ * successfully we'll need to mark the job as broken and then attempt to abort
+ * it. This function marks the job as broken.
+ */
+static void
+qemuBlockJobMarkBroken(qemuBlockJobDataPtr job)
+{
+    qemuBlockJobDataDisposeJobdata(job);
+    job->brokentype = job->type;
+    job->type = QEMU_BLOCKJOB_TYPE_BROKEN;
+}
+
+
 /**
  * qemuBlockJobRegister:
  * @job: job to register
@@ -461,6 +479,9 @@ qemuBlockJobRefreshJobs(virQEMUDriverPtr driver,
          * in qemu and just forget about it in libvirt because there's not much
          * we coud do besides killing the VM */
         if (job->invalidData) {
+
+            qemuBlockJobMarkBroken(job);
+
             qemuDomainObjEnterMonitor(driver, vm);
 
             rc = qemuMonitorJobCancel(priv->mon, job->name, true);
@@ -1255,6 +1276,8 @@ qemuBlockJobEventProcessConcludedTransition(qemuBlockJobDataPtr job,
             qemuBlockJobProcessEventConcludedCopyAbort(driver, vm, job, asyncJob);
         break;
 
+
+    case QEMU_BLOCKJOB_TYPE_BROKEN:
     case QEMU_BLOCKJOB_TYPE_NONE:
     case QEMU_BLOCKJOB_TYPE_INTERNAL:
     case QEMU_BLOCKJOB_TYPE_LAST:
index d8da918f2f93d83b29af651145ae7067280a2666..fdfe2c57ec74cef3673edc0e770af05ce0d80af4 100644 (file)
@@ -63,6 +63,7 @@ typedef enum {
     /* Additional enum values local to qemu */
     QEMU_BLOCKJOB_TYPE_INTERNAL,
     QEMU_BLOCKJOB_TYPE_CREATE,
+    QEMU_BLOCKJOB_TYPE_BROKEN,
     QEMU_BLOCKJOB_TYPE_LAST
 } qemuBlockJobType;
 verify((int)QEMU_BLOCKJOB_TYPE_INTERNAL == VIR_DOMAIN_BLOCK_JOB_TYPE_LAST);
@@ -131,6 +132,8 @@ struct _qemuBlockJobData {
 
     int newstate; /* qemuBlockjobState, subset of events emitted by qemu */
 
+    int brokentype; /* the previous type of a broken blockjob qemuBlockJobType */
+
     bool invalidData; /* the job data (except name) is not valid */
     bool reconnected; /* internal field for tracking whether job is live after reconnect to qemu */
 };
index c233a4ba9653584187c03757696c260b1d3d18fd..d1596a28ca3ae0fc575682790763b5d1539b51e1 100644 (file)
@@ -2475,6 +2475,8 @@ qemuDomainObjPrivateXMLFormatBlockjobIterator(void *payload,
     virBufferEscapeString(&attrBuf, " type='%s'", qemuBlockjobTypeToString(job->type));
     virBufferEscapeString(&attrBuf, " state='%s'", state);
     virBufferEscapeString(&attrBuf, " newstate='%s'", newstate);
+    if (job->brokentype != QEMU_BLOCKJOB_TYPE_NONE)
+        virBufferEscapeString(&attrBuf, " brokentype='%s'", qemuBlockjobTypeToString(job->brokentype));
     virBufferEscapeString(&childBuf, "<errmsg>%s</errmsg>", job->errmsg);
 
     if (job->disk) {
@@ -2536,6 +2538,8 @@ qemuDomainObjPrivateXMLFormatBlockjobIterator(void *payload,
                 virBufferAddLit(&attrBuf, " shallownew='yes'");
             break;
 
+
+        case QEMU_BLOCKJOB_TYPE_BROKEN:
         case QEMU_BLOCKJOB_TYPE_NONE:
         case QEMU_BLOCKJOB_TYPE_INTERNAL:
         case QEMU_BLOCKJOB_TYPE_LAST:
@@ -3100,6 +3104,8 @@ qemuDomainObjPrivateXMLParseBlockjobDataSpecific(qemuBlockJobDataPtr job,
             }
             break;
 
+
+        case QEMU_BLOCKJOB_TYPE_BROKEN:
         case QEMU_BLOCKJOB_TYPE_NONE:
         case QEMU_BLOCKJOB_TYPE_INTERNAL:
         case QEMU_BLOCKJOB_TYPE_LAST:
@@ -3125,6 +3131,7 @@ qemuDomainObjPrivateXMLParseBlockjobData(virDomainObjPtr vm,
     g_autoptr(qemuBlockJobData) job = NULL;
     g_autofree char *name = NULL;
     g_autofree char *typestr = NULL;
+    g_autofree char *brokentypestr = NULL;
     int type;
     g_autofree char *statestr = NULL;
     int state = QEMU_BLOCKJOB_STATE_FAILED;
@@ -3146,13 +3153,17 @@ qemuDomainObjPrivateXMLParseBlockjobData(virDomainObjPtr vm,
      * clean it up */
     if (!(typestr = virXPathString("string(./@type)", ctxt)) ||
         (type = qemuBlockjobTypeFromString(typestr)) < 0) {
-        type = QEMU_BLOCKJOB_TYPE_NONE;
+        type = QEMU_BLOCKJOB_TYPE_BROKEN;
         invalidData = true;
     }
 
     if (!(job = qemuBlockJobDataNew(type, name)))
         return -1;
 
+    if ((brokentypestr = virXPathString("string(./@brokentype)", ctxt)) &&
+        (job->brokentype = qemuBlockjobTypeFromString(brokentypestr)) < 0)
+        job->brokentype = QEMU_BLOCKJOB_TYPE_NONE;
+
     if (!(statestr = virXPathString("string(./@state)", ctxt)) ||
         (state = qemuBlockjobStateTypeFromString(statestr)) < 0)
         invalidData = true;
index 8c2670d377e1716e16e5c16691ba066cf4273647..18bd0101e7dedb0bc1d7bc0addf400df419a4144 100644 (file)
@@ -17418,6 +17418,7 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
     case QEMU_BLOCKJOB_TYPE_COMMIT:
     case QEMU_BLOCKJOB_TYPE_INTERNAL:
     case QEMU_BLOCKJOB_TYPE_CREATE:
+    case QEMU_BLOCKJOB_TYPE_BROKEN:
         virReportError(VIR_ERR_OPERATION_INVALID,
                        _("job type '%s' does not support pivot"),
                        qemuBlockjobTypeToString(job->type));
index 4f6930001efdbf7d3fe7f8bf4524c0fe4a82118f..67ab099bd99fd59a75b9d86359adf9acfa9f4ba5 100644 (file)
         </source>
       </src>
     </blockjob>
+    <blockjob name='broken-test' type='broken' state='ready' brokentype='commit'/>
     <blockjob name='test-orphan-job0' type='copy' state='ready'>
       <chains>
         <disk type='file' format='qcow2'>