]> xenbits.xensource.com Git - libvirt.git/commitdiff
blockjob: return appropriate event and info
authorEric Blake <eblake@redhat.com>
Fri, 12 Oct 2012 20:06:10 +0000 (14:06 -0600)
committerEric Blake <eblake@redhat.com>
Sat, 27 Oct 2012 13:43:38 +0000 (07:43 -0600)
Handle the new type of block copy event and info.  Of course,
this patch does nothing until a later patch actually allows the
creation/abort of a block copy job.

* include/libvirt/libvirt.h.in (VIR_DOMAIN_BLOCK_JOB_READY): New
block job status.
* src/libvirt.c (virDomainBlockRebase): Document the event.
* src/qemu/qemu_monitor_json.c (eventHandlers): New event.
(qemuMonitorJSONHandleBlockJobReady): New function.
(qemuMonitorJSONGetBlockJobInfoOne): Translate new job type.
(qemuMonitorJSONHandleBlockJobImpl): Handle new event and job type.
* src/qemu/qemu_process.c (qemuProcessHandleBlockJob): Recognize
the event to minimize snooping.
* src/qemu/qemu_driver.c (qemuDomainBlockJobImpl): Snoop a successful
info query to save effort on a pivot request.

include/libvirt/libvirt.h.in
src/libvirt.c
src/qemu/qemu_driver.c
src/qemu/qemu_monitor_json.c
src/qemu/qemu_process.c

index ad18cb0e5f552e965f00e9bab44aeaf39674b914..2b17cefd6487b5f543607cbd582a98e522c43d41 100644 (file)
@@ -4120,6 +4120,7 @@ typedef enum {
     VIR_DOMAIN_BLOCK_JOB_COMPLETED = 0,
     VIR_DOMAIN_BLOCK_JOB_FAILED = 1,
     VIR_DOMAIN_BLOCK_JOB_CANCELED = 2,
+    VIR_DOMAIN_BLOCK_JOB_READY = 3,
 
 #ifdef VIR_ENUM_SENTINELS
     VIR_DOMAIN_BLOCK_JOB_LAST
index 7e7947087f234338065a586f75961d35f87a60ae..8e014430346b7214669de5927bda5cfce0b225c4 100644 (file)
@@ -19219,9 +19219,10 @@ error:
  * mirror all further changes to both source and destination.  The user
  * must call virDomainBlockJobAbort() to end the mirroring while choosing
  * whether to revert to source or pivot to the destination.  An event is
- * issued when the job ends, and in the future, an event may be added when
- * the job transitions from pulling to mirroring.  If the job is aborted,
- * a new job will have to start over from the beginning of the first phase.
+ * issued when the job ends, and depending on the hypervisor, an event may
+ * also be issued when the job transitions from pulling to mirroring.  If
+ * the job is aborted, a new job will have to start over from the beginning
+ * of the first phase.
  *
  * Some hypervisors will restrict certain actions, such as virDomainSave()
  * or virDomainDetachDevice(), while a copy job is active; they may
index 79f9458cc1731512262daca6fa30a1b41ec22d10..458ebec10d269eb172f1ea1047939eae712f9f4d 100644 (file)
@@ -12628,6 +12628,12 @@ qemuDomainBlockJobImpl(virDomainPtr dom, const char *path, const char *base,
     if (ret < 0)
         goto endjob;
 
+    /* Snoop block copy operations, so future cancel operations can
+     * avoid checking if pivot is safe.  */
+    if (mode == BLOCK_JOB_INFO && ret == 1 && disk->mirror &&
+        info->cur == info->end && info->type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY)
+        disk->mirroring = true;
+
     /* With synchronous block cancel, we must synthesize an event, and
      * we silently ignore the ABORT_ASYNC flag.  With asynchronous
      * block cancel, the event will come from qemu, but without the
index 8f207b1b1de8a5fca855ec428adf5a3ccb9a740c..9a1f2dc9c2c04b87b74a846c5f88885ec388d52e 100644 (file)
@@ -69,6 +69,7 @@ static void qemuMonitorJSONHandlePMWakeup(qemuMonitorPtr mon, virJSONValuePtr da
 static void qemuMonitorJSONHandlePMSuspend(qemuMonitorPtr mon, virJSONValuePtr data);
 static void qemuMonitorJSONHandleBlockJobCompleted(qemuMonitorPtr mon, virJSONValuePtr data);
 static void qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon, virJSONValuePtr data);
+static void qemuMonitorJSONHandleBlockJobReady(qemuMonitorPtr mon, virJSONValuePtr data);
 static void qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon, virJSONValuePtr data);
 static void qemuMonitorJSONHandlePMSuspendDisk(qemuMonitorPtr mon, virJSONValuePtr data);
 
@@ -82,6 +83,7 @@ static qemuEventHandler eventHandlers[] = {
     { "BLOCK_IO_ERROR", qemuMonitorJSONHandleIOError, },
     { "BLOCK_JOB_CANCELLED", qemuMonitorJSONHandleBlockJobCanceled, },
     { "BLOCK_JOB_COMPLETED", qemuMonitorJSONHandleBlockJobCompleted, },
+    { "BLOCK_JOB_READY", qemuMonitorJSONHandleBlockJobReady, },
     { "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, },
     { "POWERDOWN", qemuMonitorJSONHandlePowerdown, },
     { "RESET", qemuMonitorJSONHandleReset, },
@@ -807,6 +809,8 @@ qemuMonitorJSONHandleBlockJobImpl(qemuMonitorPtr mon,
         type = VIR_DOMAIN_BLOCK_JOB_TYPE_PULL;
     else if (STREQ(type_str, "commit"))
         type = VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT;
+    else if (STREQ(type_str, "mirror"))
+        type = VIR_DOMAIN_BLOCK_JOB_TYPE_COPY;
 
     switch ((virConnectDomainEventBlockJobStatus) event) {
     case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
@@ -815,11 +819,12 @@ qemuMonitorJSONHandleBlockJobImpl(qemuMonitorPtr mon,
             event = VIR_DOMAIN_BLOCK_JOB_FAILED;
         break;
     case VIR_DOMAIN_BLOCK_JOB_CANCELED:
+    case VIR_DOMAIN_BLOCK_JOB_READY:
         break;
     case VIR_DOMAIN_BLOCK_JOB_FAILED:
     case VIR_DOMAIN_BLOCK_JOB_LAST:
-            VIR_DEBUG("should not get here");
-            break;
+        VIR_DEBUG("should not get here");
+        break;
     }
 
 out:
@@ -882,6 +887,14 @@ qemuMonitorJSONHandleBlockJobCanceled(qemuMonitorPtr mon,
                                       VIR_DOMAIN_BLOCK_JOB_CANCELED);
 }
 
+static void
+qemuMonitorJSONHandleBlockJobReady(qemuMonitorPtr mon,
+                                   virJSONValuePtr data)
+{
+    qemuMonitorJSONHandleBlockJobImpl(mon, data,
+                                      VIR_DOMAIN_BLOCK_JOB_READY);
+}
+
 static void
 qemuMonitorJSONHandleBalloonChange(qemuMonitorPtr mon,
                                    virJSONValuePtr data)
@@ -3485,6 +3498,8 @@ static int qemuMonitorJSONGetBlockJobInfoOne(virJSONValuePtr entry,
         info->type = VIR_DOMAIN_BLOCK_JOB_TYPE_PULL;
     else if (STREQ(type, "commit"))
         info->type = VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT;
+    else if (STREQ(type, "mirror"))
+        info->type = VIR_DOMAIN_BLOCK_JOB_TYPE_COPY;
     else
         info->type = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;
 
index 5004e9ba30b557a3a1ae745f444808d9f3418a8a..318875d263b822eeb72704327f477189da85b170 100644 (file)
@@ -920,6 +920,9 @@ qemuProcessHandleBlockJob(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
              type == VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT) &&
             status == VIR_DOMAIN_BLOCK_JOB_COMPLETED)
             qemuDomainDetermineDiskChain(driver, disk, true);
+        if (disk->mirror && type == VIR_DOMAIN_BLOCK_JOB_TYPE_COPY &&
+            status == VIR_DOMAIN_BLOCK_JOB_READY)
+            disk->mirroring = true;
     }
 
     virDomainObjUnlock(vm);