--- src/qemu_driver.c | 87 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 73 insertions(+), 14 deletions(-) diff --git a/src/qemu_driver.c b/src/qemu_driver.c index f2be27f..12079f8 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -87,6 +87,12 @@ static void qemuDriverUnlock(struct qemud_driver *driver) virMutexUnlock(&driver->lock); } +/* Return -1 for error, 0 for success */ +typedef int qemudMonitorExtraPromptHandler(const virDomainObjPtr vm, + const char *buf, + const char *prompt, + void *data); + static void qemuDomainEventFlush(int timer, void *opaque); static void qemuDomainEventQueue(struct qemud_driver *driver, virDomainEventPtr event); @@ -111,6 +117,12 @@ static int qemudDomainGetMaxVcpus(virDomainPtr dom); static int qemudMonitorCommand(const virDomainObjPtr vm, const char *cmd, char **reply); +static int qemudMonitorCommandWithHandler(const virDomainObjPtr vm, + const char *cmd, + const char *extraPrompt, + qemudMonitorExtraPromptHandler extraHandler, + void *handlerData, + char **reply); static int qemudMonitorCommandExtra(const virDomainObjPtr vm, const char *cmd, const char *extra, @@ -2014,15 +2026,15 @@ qemuMonitorDiscardPendingData(virDomainObjPtr vm) { static int -qemudMonitorCommandExtra(const virDomainObjPtr vm, - const char *cmd, - const char *extra, - const char *extraPrompt, - char **reply) { +qemudMonitorCommandWithHandler(const virDomainObjPtr vm, + const char *cmd, + const char *extraPrompt, + qemudMonitorExtraPromptHandler extraHandler, + void *handlerData, + char **reply) { int size = 0; char *buf = NULL; size_t cmdlen = strlen(cmd); - size_t extralen = extra ? strlen(extra) : 0; qemuMonitorDiscardPendingData(vm); @@ -2061,14 +2073,20 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm, /* Look for QEMU prompt to indicate completion */ if (buf) { - if (extra) { - if (strstr(buf, extraPrompt) != NULL) { - if (safewrite(vm->monitor, extra, extralen) != extralen) - return -1; - if (safewrite(vm->monitor, "\r", 1) != 1) - return -1; - extra = NULL; - } + char *foundPrompt; + + if (extraPrompt && + (foundPrompt = strstr(buf, extraPrompt)) != NULL) { + char *promptEnd; + + if (extraHandler(vm, buf, foundPrompt, handlerData) < 0) + return -1; + /* Discard output so far, necessary to detect whether + extraPrompt appears again. We don't need the output between + original command and this prompt anyway. */ + promptEnd = foundPrompt + strlen(extraPrompt); + memmove(buf, promptEnd, strlen(promptEnd)+1); + size -= promptEnd - buf; } else if ((tmp = strstr(buf, QEMU_CMD_PROMPT)) != NULL) { char *commptr = NULL, *nlptr = NULL; /* Preserve the newline */ @@ -2106,6 +2124,47 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm, return -1; } +struct extraHandlerData +{ + const char *reply; + bool first; +}; + +static int +qemudMonitorCommandSimpleExtraHandler(const virDomainObjPtr vm, + const char *buf ATTRIBUTE_UNUSED, + const char *prompt ATTRIBUTE_UNUSED, + void *data_) +{ + struct extraHandlerData *data = data_; + size_t len; + + if (!data->first) + return 0; + len = strlen(data->reply); + if (safewrite(vm->monitor, data->reply, len) != len) + return -1; + if (safewrite(vm->monitor, "\r", 1) != 1) + return -1; + data->first = false; + return 0; +} + +static int +qemudMonitorCommandExtra(const virDomainObjPtr vm, + const char *cmd, + const char *extra, + const char *extraPrompt, + char **reply) { + struct extraHandlerData data; + + data.reply = extra; + data.first = true; + return qemudMonitorCommandWithHandler(vm, cmd, extraPrompt, + qemudMonitorCommandSimpleExtraHandler, + &data, reply); +} + static int qemudMonitorCommand(const virDomainObjPtr vm, const char *cmd, -- 1.6.2.5 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list