[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