
2009/11/26 Daniel P. Berrange <berrange@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@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