From 5ec6cf7fb87082b623f29ff873c9f0654a43b0c9 Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Tue, 26 Jan 2010 15:34:46 +0000 Subject: [PATCH] Introduce internal QEMU monitor APIs for drive + device hotadd The way QEMU is started has been changed to use '-device' and the new style '-drive' syntax. This needs to be mirrored in the hotplug code, requiring addition of two new APIs. * src/qemu/qemu_monitor.h, src/qemu/qemu_monitor.c: Define APIs qemuMonitorAddDevice() and qemuMonitorAddDrive() * src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h, src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Implement the new monitor APIs --- src/qemu/qemu_monitor.c | 27 +++++++++++++ src/qemu/qemu_monitor.h | 6 +++ src/qemu/qemu_monitor_json.c | 49 +++++++++++++++++++++++ src/qemu/qemu_monitor_json.h | 6 +++ src/qemu/qemu_monitor_text.c | 77 ++++++++++++++++++++++++++++++++++++ src/qemu/qemu_monitor_text.h | 6 +++ 6 files changed, 171 insertions(+) diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 817ccd74be..9e0987666b 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -1304,3 +1304,30 @@ int qemuMonitorGetAllPCIAddresses(qemuMonitorPtr mon, ret = qemuMonitorTextGetAllPCIAddresses(mon, addrs); return ret; } + + +int qemuMonitorAddDevice(qemuMonitorPtr mon, + const char *devicestr) +{ + DEBUG("mon=%p, fd=%d device=%s", mon, mon->fd, devicestr); + int ret; + + if (mon->json) + ret = qemuMonitorJSONAddDevice(mon, devicestr); + else + ret = qemuMonitorTextAddDevice(mon, devicestr); + return ret; +} + +int qemuMonitorAddDrive(qemuMonitorPtr mon, + const char *drivestr) +{ + DEBUG("mon=%p, fd=%d drive=%s", mon, mon->fd, drivestr); + int ret; + + if (mon->json) + ret = qemuMonitorJSONAddDrive(mon, drivestr); + else + ret = qemuMonitorTextAddDrive(mon, drivestr); + return ret; +} diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 8a405ce3d2..a330eff084 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -285,4 +285,10 @@ struct _qemuMonitorPCIAddress { int qemuMonitorGetAllPCIAddresses(qemuMonitorPtr mon, qemuMonitorPCIAddress **addrs); +int qemuMonitorAddDevice(qemuMonitorPtr mon, + const char *devicestr); + +int qemuMonitorAddDrive(qemuMonitorPtr mon, + const char *drivestr); + #endif /* QEMU_MONITOR_H */ diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c index 8e88c7e8b7..a5560880b0 100644 --- a/src/qemu/qemu_monitor_json.c +++ b/src/qemu/qemu_monitor_json.c @@ -1785,3 +1785,52 @@ int qemuMonitorJSONGetAllPCIAddresses(qemuMonitorPtr mon ATTRIBUTE_UNUSED, _("query-pci not suppported in JSON mode")); return -1; } + + +int qemuMonitorJSONAddDevice(qemuMonitorPtr mon, + const char *devicestr) +{ + int ret; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + + cmd = qemuMonitorJSONMakeCommand("device_add", + "s:config", devicestr, + NULL); + if (!cmd) + return -1; + + ret = qemuMonitorJSONCommand(mon, cmd, &reply); + + if (ret == 0) + ret = qemuMonitorJSONCheckError(cmd, reply); + + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} + + +int qemuMonitorJSONAddDrive(qemuMonitorPtr mon, + const char *drivestr) +{ + int ret; + virJSONValuePtr cmd; + virJSONValuePtr reply = NULL; + + cmd = qemuMonitorJSONMakeCommand("drive_add", + "s:pci_addr", "dummy", + "s:opts", drivestr, + NULL); + if (!cmd) + return -1; + + ret = qemuMonitorJSONCommand(mon, cmd, &reply); + + if (ret == 0) + ret = qemuMonitorJSONCheckError(cmd, reply); + + virJSONValueFree(cmd); + virJSONValueFree(reply); + return ret; +} diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h index 858aac038b..ac6458c548 100644 --- a/src/qemu/qemu_monitor_json.h +++ b/src/qemu/qemu_monitor_json.h @@ -156,4 +156,10 @@ int qemuMonitorJSONAttachDrive(qemuMonitorPtr mon, int qemuMonitorJSONGetAllPCIAddresses(qemuMonitorPtr mon, qemuMonitorPCIAddress **addrs); +int qemuMonitorJSONAddDevice(qemuMonitorPtr mon, + const char *devicestr); + +int qemuMonitorJSONAddDrive(qemuMonitorPtr mon, + const char *drivestr); + #endif /* QEMU_MONITOR_JSON_H */ diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c index 44111e1456..c669dbb09e 100644 --- a/src/qemu/qemu_monitor_text.c +++ b/src/qemu/qemu_monitor_text.c @@ -2029,3 +2029,80 @@ error: #undef SKIP_SPACE #undef CHECK_END #undef SKIP_TO + + +int qemuMonitorTextAddDevice(qemuMonitorPtr mon, + const char *devicestr) +{ + char *cmd = NULL; + char *reply = NULL; + char *safedev; + int ret = -1; + + if (!(safedev = qemuMonitorEscapeArg(devicestr))) { + virReportOOMError(NULL); + goto cleanup; + } + + if (virAsprintf(&cmd, "device_add %s", safedev) < 0) { + virReportOOMError(NULL); + goto cleanup; + } + + if (qemuMonitorCommand(mon, cmd, &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("cannot attach %s device"), devicestr); + goto cleanup; + } + + if (STRNEQ(reply, "")) { + qemudReportError (NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("adding %s device failed: %s"), devicestr, reply); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(cmd); + VIR_FREE(reply); + return ret; +} + + +int qemuMonitorTextAddDrive(qemuMonitorPtr mon, + const char *drivestr) +{ + char *cmd = NULL; + char *reply = NULL; + int ret = -1; + char *safe_str; + + safe_str = qemuMonitorEscapeArg(drivestr); + if (!safe_str) { + virReportOOMError(NULL); + return -1; + } + + /* 'dummy' here is just a placeholder since there is no PCI + * address required when attaching drives to a controller */ + ret = virAsprintf(&cmd, "drive_add dummy %s", safe_str); + if (ret == -1) { + virReportOOMError(NULL); + goto cleanup; + } + + if (qemuMonitorCommand(mon, cmd, &reply) < 0) { + qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED, + _("failed to close fd in qemu with '%s'"), cmd); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(cmd); + VIR_FREE(reply); + VIR_FREE(safe_str); + return ret; +} diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h index d6e9ca1402..12d75f512f 100644 --- a/src/qemu/qemu_monitor_text.h +++ b/src/qemu/qemu_monitor_text.h @@ -160,4 +160,10 @@ int qemuMonitorTextAttachDrive(qemuMonitorPtr mon, int qemuMonitorTextGetAllPCIAddresses(qemuMonitorPtr mon, qemuMonitorPCIAddress **addrs); +int qemuMonitorTextAddDevice(qemuMonitorPtr mon, + const char *devicestr); + +int qemuMonitorTextAddDrive(qemuMonitorPtr mon, + const char *drivestr); + #endif /* QEMU_MONITOR_TEXT_H */ -- GitLab