2009/11/26 Daniel P. Berrange <berrange(a)redhat.com>:
Initial support for the new QEMU monitor protocol using JSON
as the data encoding format instead of plain text
* po/POTFILES.in: Add src/qemu/qemu_monitor_json.c
* src/qemu/qemu_conf.c, src/qemu/qemu_conf.h: Hack to turn on QMP
mode. Replace with a version number check on >= 0.12 later
* src/qemu/qemu_monitor.c: Delegate to json monitor if enabled
* src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h: Add
impl of QMP protocol
* src/Makefile.am: Add src/qemu/qemu_monitor_json.{c,h}
---
[...]
diff --git a/src/qemu/qemu_monitor_json.c
b/src/qemu/qemu_monitor_json.c
new file mode 100644
index 0000000..9d71826
--- /dev/null
+++ b/src/qemu/qemu_monitor_json.c
@@ -0,0 +1,1423 @@
+/*
+ * qemu_monitor_json.c: interaction with QEMU monitor console
+ *
+ * Copyright (C) 2006-2009 Red Hat, Inc.
+ * Copyright (C) 2006 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <poll.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include "qemu_monitor_json.h"
+#include "qemu_conf.h"
+#include "memory.h"
+#include "logging.h"
+#include "driver.h"
+#include "datatypes.h"
+#include "virterror_internal.h"
+#include "json.h"
+
+#define VIR_FROM_THIS VIR_FROM_QEMU
+
+
+#define LINE_ENDING "\r\n"
+
+static int
+qemuMonitorJSONIOProcessLine(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
+ const char *line,
+ qemuMonitorMessagePtr msg)
+{
+ virJSONValuePtr obj = NULL;
+ int ret = -1;
+
+ VIR_DEBUG("Line [%s]", line);
+
+ if (!(obj = virJSONValueFromString(line))) {
+ VIR_DEBUG0("Parsing JSON string failed");
+ errno = EINVAL;
+ goto cleanup;
+ }
+
+ if (obj->type != VIR_JSON_TYPE_OBJECT) {
+ VIR_DEBUG0("Parsed JSON string isn't an object");
+ errno = EINVAL;
+ }
+
+ if (virJSONValueObjectHasKey(obj, "QMP") == 1) {
+ VIR_DEBUG0("Got QMP capabilities data");
+ ret = 0;
+ goto cleanup;
+ }
+
+ if (virJSONValueObjectHasKey(obj, "event") == 1) {
+ VIR_DEBUG0("Got an event");
+ ret = 0;
+ goto cleanup;
+ }
+
+ if (msg) {
+ msg->rxBuffer = strdup(line);
OOM check is missing.
+ msg->rxLength = strlen(line);
+ msg->finished = 1;
+ } else {
+ VIR_DEBUG("Ignoring unexpected JSON message [%s]", line);
+ }
+
+ ret = 0;
+
+cleanup:
+ virJSONValueFree(obj);
+ return ret;
+}
+
+int qemuMonitorJSONIOProcess(qemuMonitorPtr mon,
+ const char *data,
+ size_t len,
+ qemuMonitorMessagePtr msg)
+{
+ int used = 0;
+ /*VIR_DEBUG("Data %d bytes [%s]", len, data);*/
+
+ while (used < len) {
+ char *nl = strstr(data + used, LINE_ENDING);
Is it guaranteed that data ends with LINE_ENDING?
+
+ if (nl) {
+ int got = nl - (data + used);
+ char *line = strndup(data + used, got);
OOM check is missing.
+ used += got + strlen(LINE_ENDING);
+ line[got] = '\0'; /* kill \n */
+ if (qemuMonitorJSONIOProcessLine(mon, line, msg) < 0) {
+ VIR_FREE(line);
+ return -1;
+ }
+
+ VIR_FREE(line);
+ } else {
+ break;
+ }
+ }
+
+ VIR_DEBUG("Total used %d bytes out of %d available in buffer", used, len);
len has type size_t, so the second %d should be a %zd, otherwise it'll
break 64bit compilation.
+ return used;
+}
+
[...]
+
+int qemuMonitorJSONAddUSBDeviceExact(qemuMonitorPtr mon,
+ int bus ATTRIBUTE_UNUSED,
+ int dev ATTRIBUTE_UNUSED)
+{
bus and dev aren't unused.
+ int ret;
+ char *addr;
+
+ if (virAsprintf(&addr, "host:%.3d.%.3d", bus, dev) < 0) {
+ virReportOOMError(NULL);
+ return -1;
+ }
+
+ ret = qemuMonitorJSONAddUSB(mon, addr);
+
+ VIR_FREE(addr);
+ return ret;
+}
+
+
+int qemuMonitorJSONAddUSBDeviceMatch(qemuMonitorPtr mon,
+ int vendor ATTRIBUTE_UNUSED,
+ int product ATTRIBUTE_UNUSED)
+{
vendor and product aren't unused.
+ int ret;
+ char *addr;
+
+ if (virAsprintf(&addr, "host:%.4x:%.4x", vendor, product) < 0) {
+ virReportOOMError(NULL);
+ return -1;
+ }
+
+ ret = qemuMonitorJSONAddUSB(mon, addr);
+
+ VIR_FREE(addr);
+ return ret;
+}
+
Some minor issues. ACK anyway.
Matthias