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
This commit is contained in:
Daniel P. Berrange 2010-01-26 15:34:46 +00:00
parent 96c8608dc5
commit 5ec6cf7fb8
6 changed files with 171 additions and 0 deletions

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */