sometimes, we want to do some initialize work in guest when guest startup,
but currently, qemu-agent doesn't support that. so here we add an init
callback, when guest startup, notify libvirt it has been up, then
libvirt can do some work for guest.

Signed-off-by: Chen Fan <chen.fan.f...@cn.fujitsu.com>
---
 src/qemu/qemu_agent.c   | 26 +++++++++++++++++++++++---
 src/qemu/qemu_agent.h   |  2 ++
 src/qemu/qemu_process.c |  6 ++++++
 3 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
index 548d580..cee0f8b 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -92,6 +92,7 @@ struct _qemuAgent {
     int watch;
 
     bool connectPending;
+    bool connected;
 
     virDomainObjPtr vm;
 
@@ -306,6 +307,7 @@ qemuAgentIOProcessLine(qemuAgentPtr mon,
     virJSONValuePtr obj = NULL;
     int ret = -1;
     unsigned long long id;
+    const char *status;
 
     VIR_DEBUG("Line [%s]", line);
 
@@ -318,7 +320,11 @@ qemuAgentIOProcessLine(qemuAgentPtr mon,
         goto cleanup;
     }
 
-    if (virJSONValueObjectHasKey(obj, "QMP") == 1) {
+    if (virJSONValueObjectHasKey(obj, "QMP") == 1 ||
+        virJSONValueObjectHasKey(obj, "status") == 1) {
+        status = virJSONValueObjectGetString(obj, "status");
+        if (STREQ(status, "connected"))
+            mon->connected = true;
         ret = 0;
     } else if (virJSONValueObjectHasKey(obj, "event") == 1) {
         ret = qemuAgentIOProcessEvent(mon, obj);
@@ -700,8 +706,22 @@ qemuAgentIO(int watch, int fd, int events, void *opaque)
         VIR_DEBUG("Triggering error callback");
         (errorNotify)(mon, vm);
     } else {
-        virObjectUnlock(mon);
-        virObjectUnref(mon);
+        if (mon->connected) {
+            void (*init)(qemuAgentPtr, virDomainObjPtr)
+                = mon->cb->init;
+            virDomainObjPtr vm = mon->vm;
+
+            mon->connected = false;
+
+            virObjectUnlock(mon);
+            virObjectUnref(mon);
+
+            VIR_DEBUG("Triggering init callback");
+            (init)(mon, vm);
+        } else {
+            virObjectUnlock(mon);
+            virObjectUnref(mon);
+        }
     }
 }
 
diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
index 1cd5749..42414a7 100644
--- a/src/qemu/qemu_agent.h
+++ b/src/qemu/qemu_agent.h
@@ -34,6 +34,8 @@ typedef qemuAgent *qemuAgentPtr;
 typedef struct _qemuAgentCallbacks qemuAgentCallbacks;
 typedef qemuAgentCallbacks *qemuAgentCallbacksPtr;
 struct _qemuAgentCallbacks {
+    void (*init)(qemuAgentPtr mon,
+                 virDomainObjPtr vm);
     void (*destroy)(qemuAgentPtr mon,
                     virDomainObjPtr vm);
     void (*eofNotify)(qemuAgentPtr mon,
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 276837e..e6fc53a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -194,8 +194,14 @@ static void qemuProcessHandleAgentDestroy(qemuAgentPtr 
agent,
     virObjectUnref(vm);
 }
 
+static void qemuProcessHandleAgentInit(qemuAgentPtr agent ATTRIBUTE_UNUSED,
+                                       virDomainObjPtr vm)
+{
+    VIR_DEBUG("Received init from agent on %p '%s'", vm, vm->def->name);
+}
 
 static qemuAgentCallbacks agentCallbacks = {
+    .init = qemuProcessHandleAgentInit,
     .destroy = qemuProcessHandleAgentDestroy,
     .eofNotify = qemuProcessHandleAgentEOF,
     .errorNotify = qemuProcessHandleAgentError,
-- 
1.9.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to