---
src/qemu_driver.c | 87 ++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 73 insertions(+), 14 deletions(-)
I have a feeling this patch is going to clash horribly with the
refactoring Mark just did of the monitor code for FD passing.
Your goal seems sane here - we'll just need to resolve this
against Mark's code
Daniel
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(a)redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|