]> xenbits.xensource.com Git - libvirt.git/commitdiff
Introduce internal QEMU monitor APIs for drive + device hotadd
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 26 Jan 2010 15:34:46 +0000 (15:34 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 2 Feb 2010 16:31:42 +0000 (16:31 +0000)
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
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_json.h
src/qemu/qemu_monitor_text.c
src/qemu/qemu_monitor_text.h

index 817ccd74be5664b3740143acdcbc876585661d04..9e0987666bf0e347e4490fc9414971b43f37b9ab 100644 (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;
+}
index 8a405ce3d25ebf3c7da94abdb573107edf1bbadd..a330eff084e73ceeff8c42ef1d3ac16c3a248e2e 100644 (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 */
index 8e88c7e8b7e386781bb1f84e49b94a926057f100..a5560880b05981df21d9dd3389b64e36d9f57c22 100644 (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;
+}
index 858aac038b84399bc550a3271100f2b433ee5d1d..ac6458c5480936de07b30036d475511656e1ac87 100644 (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 */
index 44111e14568d55ab28e4522b2720ee64dc947071..c669dbb09e8cf52c7bea2b87c328327b551ba218 100644 (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;
+}
index d6e9ca1402ad1b406c2c71857f9d7444a4a8c959..12d75f512fec8a5c21b4faf1b2dbfdb2379393d8 100644 (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 */