2009/11/26 Daniel P. Berrange <berrange@xxxxxxxxxx>: > 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@xxxxxxxxxx> > + */ > + > +#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 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list