mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
Make handling of monitor prompts more general.
* src/qemu_driver.c: Support arbitrary callbacks for "secondary prompts". Reimplement qemudMonitorCommandExtra using such a callback.
This commit is contained in:
parent
077cd91773
commit
28b8cc31f6
@ -88,6 +88,12 @@ static void qemuDriverUnlock(struct qemud_driver *driver)
|
|||||||
virMutexUnlock(&driver->lock);
|
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 qemuDomainEventFlush(int timer, void *opaque);
|
||||||
static void qemuDomainEventQueue(struct qemud_driver *driver,
|
static void qemuDomainEventQueue(struct qemud_driver *driver,
|
||||||
virDomainEventPtr event);
|
virDomainEventPtr event);
|
||||||
@ -116,6 +122,13 @@ static int qemudMonitorCommandWithFd(const virDomainObjPtr vm,
|
|||||||
const char *cmd,
|
const char *cmd,
|
||||||
int scm_fd,
|
int scm_fd,
|
||||||
char **reply);
|
char **reply);
|
||||||
|
static int qemudMonitorCommandWithHandler(const virDomainObjPtr vm,
|
||||||
|
const char *cmd,
|
||||||
|
const char *extraPrompt,
|
||||||
|
qemudMonitorExtraPromptHandler extraHandler,
|
||||||
|
void *handlerData,
|
||||||
|
int scm_fd,
|
||||||
|
char **reply);
|
||||||
static int qemudMonitorCommandExtra(const virDomainObjPtr vm,
|
static int qemudMonitorCommandExtra(const virDomainObjPtr vm,
|
||||||
const char *cmd,
|
const char *cmd,
|
||||||
const char *extra,
|
const char *extra,
|
||||||
@ -2406,12 +2419,13 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qemudMonitorCommandExtra(const virDomainObjPtr vm,
|
qemudMonitorCommandWithHandler(const virDomainObjPtr vm,
|
||||||
const char *cmd,
|
const char *cmd,
|
||||||
const char *extra,
|
const char *extraPrompt,
|
||||||
const char *extraPrompt,
|
qemudMonitorExtraPromptHandler extraHandler,
|
||||||
int scm_fd,
|
void *handlerData,
|
||||||
char **reply) {
|
int scm_fd,
|
||||||
|
char **reply) {
|
||||||
int size = 0;
|
int size = 0;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
|
|
||||||
@ -2455,12 +2469,20 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm,
|
|||||||
|
|
||||||
/* Look for QEMU prompt to indicate completion */
|
/* Look for QEMU prompt to indicate completion */
|
||||||
if (buf) {
|
if (buf) {
|
||||||
if (extra) {
|
char *foundPrompt;
|
||||||
if (strstr(buf, extraPrompt) != NULL) {
|
|
||||||
if (qemudMonitorSend(vm, extra, -1) < 0)
|
if (extraPrompt &&
|
||||||
return -1;
|
(foundPrompt = strstr(buf, extraPrompt)) != NULL) {
|
||||||
extra = 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) {
|
} else if ((tmp = strstr(buf, QEMU_CMD_PROMPT)) != NULL) {
|
||||||
char *commptr = NULL, *nlptr = NULL;
|
char *commptr = NULL, *nlptr = NULL;
|
||||||
/* Preserve the newline */
|
/* Preserve the newline */
|
||||||
@ -2498,6 +2520,44 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm,
|
|||||||
return -1;
|
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_;
|
||||||
|
|
||||||
|
if (!data->first)
|
||||||
|
return 0;
|
||||||
|
if (qemudMonitorSend(vm, data->reply, -1) < 0)
|
||||||
|
return -1;
|
||||||
|
data->first = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemudMonitorCommandExtra(const virDomainObjPtr vm,
|
||||||
|
const char *cmd,
|
||||||
|
const char *extra,
|
||||||
|
const char *extraPrompt,
|
||||||
|
int scm_fd,
|
||||||
|
char **reply) {
|
||||||
|
struct extraHandlerData data;
|
||||||
|
|
||||||
|
data.reply = extra;
|
||||||
|
data.first = true;
|
||||||
|
return qemudMonitorCommandWithHandler(vm, cmd, extraPrompt,
|
||||||
|
qemudMonitorCommandSimpleExtraHandler,
|
||||||
|
&data, scm_fd, reply);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qemudMonitorCommandWithFd(const virDomainObjPtr vm,
|
qemudMonitorCommandWithFd(const virDomainObjPtr vm,
|
||||||
const char *cmd,
|
const char *cmd,
|
||||||
|
Loading…
Reference in New Issue
Block a user