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.fnst(a)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