[libvirt] [PATCH 11/14] Support for JSON mode monitor
Matthias Bolte
matthias.bolte at googlemail.com
Wed Dec 2 23:51:13 UTC 2009
2009/11/26 Daniel P. Berrange <berrange at 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 at 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
More information about the libvir-list
mailing list