diff --git a/ChangeLog b/ChangeLog index 74d0b80c55c8420e54a43ce276cf3f4b8e7159eb..7247f9a6afba5e309720f28c79dfd5faac365e11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,16 @@ -Fri Apr 25 12:21:28 EST 2008 Daniel P. Berrange +Fri Apr 25 16:45:28 EST 2008 Daniel P. Berrange + + * src/internal.c: Convenience macros for fixed arrays + * src/qemu_driver.c: Extract TTY paths for serial and parallel + devices too + * src/qemu_conf.c, src/qemu_conf.h: Support arbitrary serial + and parallel devices. + * tests/qemuxml2argvtest.c, tests/qemuxml2xmltest.c: Add tests + for serial and parallel devices + * tests/qemuxml2argvdata/*: Updated and added data files for + new test cases + +Fri Apr 25 12:21:28 EST 2008 Daniel P. Berrange * docs/page.xsl, docs/libvir.css: Re-arrange layout to workaround IE6 bugs diff --git a/src/internal.h b/src/internal.h index 6bed4770d2a944140547b728b3dafdfeac634b34..67d31b3639d15bd72f1a01fcb8c15627ea0a2cea 100644 --- a/src/internal.h +++ b/src/internal.h @@ -66,6 +66,10 @@ extern "C" { #define STRNEQLEN(a,b,n) (strncmp((a),(b),(n)) != 0) #define STRCASENEQLEN(a,b,n) (strncasecmp((a),(b),(n)) != 0) + +#define NUL_TERMINATE(buf) do { (buf)[sizeof(buf)-1] = '\0'; } while (0) +#define ARRAY_CARDINALITY(Array) (sizeof (Array) / sizeof *(Array)) + /* If configured with --enable-debug=yes then library calls * are printed to stderr for debugging. */ diff --git a/src/qemu_conf.c b/src/qemu_conf.c index d9b82b205baacfbecc36c986f7cfed8a1b19c597..2d048d36ff5852f7ad5f625e5ce9251dffa3e523 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -205,6 +205,8 @@ void qemudFreeVMDef(struct qemud_vm_def *def) { struct qemud_vm_disk_def *disk = def->disks; struct qemud_vm_net_def *net = def->nets; struct qemud_vm_input_def *input = def->inputs; + struct qemud_vm_chr_def *serial = def->serials; + struct qemud_vm_chr_def *parallel = def->parallels; while (disk) { struct qemud_vm_disk_def *prev = disk; @@ -221,6 +223,16 @@ void qemudFreeVMDef(struct qemud_vm_def *def) { input = input->next; free(prev); } + while (serial) { + struct qemud_vm_chr_def *prev = serial; + serial = serial->next; + free(prev); + } + while (parallel) { + struct qemud_vm_chr_def *prev = parallel; + parallel = parallel->next; + free(prev); + } xmlFree(def->keymap); free(def); } @@ -945,6 +957,333 @@ static int qemudParseInterfaceXML(virConnectPtr conn, } +/* Parse the XML definition for a character device + * @param net pre-allocated & zero'd net record + * @param node XML nodeset to parse for net definition + * @return 0 on success, -1 on failure + * + * The XML we're dealing with looks like + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +static int qemudParseCharXML(virConnectPtr conn, + struct qemud_vm_chr_def *chr, + int portNum, + xmlNodePtr node) { + xmlNodePtr cur; + xmlChar *type = NULL; + xmlChar *bindHost = NULL; + xmlChar *bindService = NULL; + xmlChar *connectHost = NULL; + xmlChar *connectService = NULL; + xmlChar *path = NULL; + xmlChar *mode = NULL; + xmlChar *protocol = NULL; + int ret = -1; + + chr->srcType = QEMUD_CHR_SRC_TYPE_PTY; + type = xmlGetProp(node, BAD_CAST "type"); + if (type != NULL) { + if (xmlStrEqual(type, BAD_CAST "null")) + chr->srcType = QEMUD_CHR_SRC_TYPE_NULL; + else if (xmlStrEqual(type, BAD_CAST "vc")) + chr->srcType = QEMUD_CHR_SRC_TYPE_VC; + else if (xmlStrEqual(type, BAD_CAST "pty")) + chr->srcType = QEMUD_CHR_SRC_TYPE_PTY; + else if (xmlStrEqual(type, BAD_CAST "dev")) + chr->srcType = QEMUD_CHR_SRC_TYPE_DEV; + else if (xmlStrEqual(type, BAD_CAST "file")) + chr->srcType = QEMUD_CHR_SRC_TYPE_FILE; + else if (xmlStrEqual(type, BAD_CAST "pipe")) + chr->srcType = QEMUD_CHR_SRC_TYPE_PIPE; + else if (xmlStrEqual(type, BAD_CAST "stdio")) + chr->srcType = QEMUD_CHR_SRC_TYPE_STDIO; + else if (xmlStrEqual(type, BAD_CAST "udp")) + chr->srcType = QEMUD_CHR_SRC_TYPE_UDP; + else if (xmlStrEqual(type, BAD_CAST "tcp")) + chr->srcType = QEMUD_CHR_SRC_TYPE_TCP; + else if (xmlStrEqual(type, BAD_CAST "unix")) + chr->srcType = QEMUD_CHR_SRC_TYPE_UNIX; + else + chr->srcType = QEMUD_CHR_SRC_TYPE_NULL; + } + + cur = node->children; + while (cur != NULL) { + if (cur->type == XML_ELEMENT_NODE) { + if (xmlStrEqual(cur->name, BAD_CAST "source")) { + if (mode == NULL) + mode = xmlGetProp(cur, BAD_CAST "mode"); + + switch (chr->srcType) { + case QEMUD_CHR_SRC_TYPE_PTY: + case QEMUD_CHR_SRC_TYPE_DEV: + case QEMUD_CHR_SRC_TYPE_FILE: + case QEMUD_CHR_SRC_TYPE_PIPE: + case QEMUD_CHR_SRC_TYPE_UNIX: + if (path == NULL) + path = xmlGetProp(cur, BAD_CAST "path"); + + break; + + case QEMUD_CHR_SRC_TYPE_UDP: + case QEMUD_CHR_SRC_TYPE_TCP: + if (mode == NULL || + STREQ((const char *)mode, "connect")) { + + if (connectHost == NULL) + connectHost = xmlGetProp(cur, BAD_CAST "host"); + if (connectService == NULL) + connectService = xmlGetProp(cur, BAD_CAST "service"); + } else { + if (bindHost == NULL) + bindHost = xmlGetProp(cur, BAD_CAST "host"); + if (bindService == NULL) + bindService = xmlGetProp(cur, BAD_CAST "service"); + } + + if (chr->srcType == QEMUD_CHR_SRC_TYPE_UDP) { + xmlFree(mode); + mode = NULL; + } + } + } else if (xmlStrEqual(cur->name, BAD_CAST "protocol")) { + if (protocol == NULL) + protocol = xmlGetProp(cur, BAD_CAST "type"); + } + } + cur = cur->next; + } + + + chr->dstPort = portNum; + + switch (chr->srcType) { + case QEMUD_CHR_SRC_TYPE_NULL: + /* Nada */ + break; + + case QEMUD_CHR_SRC_TYPE_VC: + break; + + case QEMUD_CHR_SRC_TYPE_PTY: + /* @path attribute is an output only property - pty is auto-allocted */ + break; + + case QEMUD_CHR_SRC_TYPE_DEV: + case QEMUD_CHR_SRC_TYPE_FILE: + case QEMUD_CHR_SRC_TYPE_PIPE: + if (path == NULL) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("Missing source path attribute for char device")); + goto cleanup; + } + + strncpy(chr->srcData.file.path, (const char *)path, + sizeof(chr->srcData.file.path)); + NUL_TERMINATE(chr->srcData.file.path); + break; + + case QEMUD_CHR_SRC_TYPE_STDIO: + /* Nada */ + break; + + case QEMUD_CHR_SRC_TYPE_TCP: + if (mode == NULL || + STREQ((const char *)mode, "connect")) { + if (connectHost == NULL) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("Missing source host attribute for char device")); + goto cleanup; + } + if (connectService == NULL) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("Missing source service attribute for char device")); + goto cleanup; + } + + strncpy(chr->srcData.tcp.host, (const char *)connectHost, + sizeof(chr->srcData.tcp.host)); + NUL_TERMINATE(chr->srcData.tcp.host); + strncpy(chr->srcData.tcp.service, (const char *)connectService, + sizeof(chr->srcData.tcp.service)); + NUL_TERMINATE(chr->srcData.tcp.service); + + chr->srcData.tcp.listen = 0; + } else { + if (bindHost == NULL) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("Missing source host attribute for char device")); + goto cleanup; + } + if (bindService == NULL) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("Missing source service attribute for char device")); + goto cleanup; + } + + strncpy(chr->srcData.tcp.host, (const char *)bindHost, + sizeof(chr->srcData.tcp.host)); + NUL_TERMINATE(chr->srcData.tcp.host); + strncpy(chr->srcData.tcp.service, (const char *)bindService, + sizeof(chr->srcData.tcp.service)); + NUL_TERMINATE(chr->srcData.tcp.service); + + chr->srcData.tcp.listen = 1; + } + if (protocol != NULL && + STREQ((const char *)protocol, "telnet")) + chr->srcData.tcp.protocol = QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET; + else + chr->srcData.tcp.protocol = QEMUD_CHR_SRC_TCP_PROTOCOL_RAW; + break; + + case QEMUD_CHR_SRC_TYPE_UDP: + if (connectService == NULL) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("Missing source service attribute for char device")); + goto cleanup; + } + + if (connectHost != NULL) { + strncpy(chr->srcData.udp.connectHost, (const char *)connectHost, + sizeof(chr->srcData.udp.connectHost)); + NUL_TERMINATE(chr->srcData.udp.connectHost); + } + strncpy(chr->srcData.udp.connectService, (const char *)connectService, + sizeof(chr->srcData.udp.connectService)); + NUL_TERMINATE(chr->srcData.udp.connectService); + + if (bindHost != NULL) { + strncpy(chr->srcData.udp.bindHost, (const char *)bindHost, + sizeof(chr->srcData.udp.bindHost)); + NUL_TERMINATE(chr->srcData.udp.bindHost); + } + if (bindService != NULL) { + strncpy(chr->srcData.udp.bindService, (const char *)bindService, + sizeof(chr->srcData.udp.bindService)); + NUL_TERMINATE(chr->srcData.udp.bindService); + } + break; + + case QEMUD_CHR_SRC_TYPE_UNIX: + if (path == NULL) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("Missing source path attribute for char device")); + goto cleanup; + } + + if (mode != NULL && + STRNEQ((const char *)mode, "connect")) + chr->srcData.nix.listen = 1; + else + chr->srcData.nix.listen = 0; + + strncpy(chr->srcData.nix.path, (const char *)path, + sizeof(chr->srcData.nix.path)); + NUL_TERMINATE(chr->srcData.nix.path); + break; + } + + ret = 0; + +cleanup: + xmlFree(mode); + xmlFree(protocol); + xmlFree(type); + xmlFree(bindHost); + xmlFree(bindService); + xmlFree(connectHost); + xmlFree(connectService); + xmlFree(path); + + return ret; +} + + +static int qemudParseCharXMLDevices(virConnectPtr conn, + xmlXPathContextPtr ctxt, + const char *xpath, + unsigned int *ndevs, + struct qemud_vm_chr_def **devs) +{ + xmlXPathObjectPtr obj; + int i, ret = -1; + + obj = xmlXPathEval(BAD_CAST xpath, ctxt); + if ((obj != NULL) && (obj->type == XPATH_NODESET) && + (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr >= 0)) { + struct qemud_vm_chr_def *prev = *devs; + if (ndevs == NULL && + obj->nodesetval->nodeNr > 1) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("too many character devices")); + goto cleanup; + } + + for (i = 0; i < obj->nodesetval->nodeNr; i++) { + struct qemud_vm_chr_def *chr = calloc(1, sizeof(*chr)); + if (!chr) { + qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, + "%s", + _("failed to allocate space for char device")); + goto cleanup; + } + + if (qemudParseCharXML(conn, chr, i, obj->nodesetval->nodeTab[i]) < 0) { + free(chr); + goto cleanup; + } + if (ndevs) + (*ndevs)++; + chr->next = NULL; + if (i == 0) { + *devs = chr; + } else { + prev->next = chr; + } + prev = chr; + } + } + + ret = 0; + +cleanup: + xmlXPathFreeObject(obj); + return ret; +} + + /* Parse the XML definition for a network interface */ static int qemudParseInputXML(virConnectPtr conn, struct qemud_vm_input_def *input, @@ -1423,6 +1762,45 @@ static struct qemud_vm_def *qemudParseXML(virConnectPtr conn, } } xmlXPathFreeObject(obj); + obj = NULL; + + /* analysis of the character devices */ + if (qemudParseCharXMLDevices(conn, ctxt, + "/domain/devices/parallel", + &def->nparallels, + &def->parallels) < 0) + goto error; + if (qemudParseCharXMLDevices(conn, ctxt, + "/domain/devices/serial", + &def->nserials, + &def->serials) < 0) + goto error; + + /* + * If no serial devices were listed, then look for console + * devices which is the legacy syntax for the same thing + */ + if (def->nserials == 0) { + obj = xmlXPathEval(BAD_CAST "/domain/devices/console", ctxt); + if ((obj != NULL) && (obj->type == XPATH_NODESET) && + (obj->nodesetval != NULL) && (obj->nodesetval->nodeNr == 1)) { + struct qemud_vm_chr_def *chr = calloc(1, sizeof(*chr)); + if (!chr) { + qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY, + "%s", + _("failed to allocate space for char device")); + goto error; + } + + if (qemudParseCharXML(conn, chr, 0, obj->nodesetval->nodeTab[0]) < 0) { + free(chr); + goto error; + } + def->nserials = 1; + def->serials = chr; + } + xmlXPathFreeObject(obj); + } /* analysis of the network devices */ @@ -1617,6 +1995,78 @@ qemudNetworkIfaceConnect(virConnectPtr conn, return NULL; } +static int qemudBuildCommandLineChrDevStr(struct qemud_vm_chr_def *dev, + char *buf, + int buflen) +{ + switch (dev->srcType) { + case QEMUD_CHR_SRC_TYPE_NULL: + strncpy(buf, "null", buflen); + buf[buflen-1] = '\0'; + break; + + case QEMUD_CHR_SRC_TYPE_VC: + strncpy(buf, "vc", buflen); + buf[buflen-1] = '\0'; + break; + + case QEMUD_CHR_SRC_TYPE_PTY: + strncpy(buf, "pty", buflen); + buf[buflen-1] = '\0'; + break; + + case QEMUD_CHR_SRC_TYPE_DEV: + if (snprintf(buf, buflen, "%s", + dev->srcData.file.path) >= buflen) + return -1; + break; + + case QEMUD_CHR_SRC_TYPE_FILE: + if (snprintf(buf, buflen, "file:%s", + dev->srcData.file.path) >= buflen) + return -1; + break; + + case QEMUD_CHR_SRC_TYPE_PIPE: + if (snprintf(buf, buflen, "pipe:%s", + dev->srcData.file.path) >= buflen) + return -1; + break; + + case QEMUD_CHR_SRC_TYPE_STDIO: + strncpy(buf, "stdio", buflen); + buf[buflen-1] = '\0'; + break; + + case QEMUD_CHR_SRC_TYPE_UDP: + if (snprintf(buf, buflen, "udp:%s:%s@%s:%s", + dev->srcData.udp.connectHost, + dev->srcData.udp.connectService, + dev->srcData.udp.bindHost, + dev->srcData.udp.bindService) >= buflen) + return -1; + break; + + case QEMUD_CHR_SRC_TYPE_TCP: + if (snprintf(buf, buflen, "%s:%s:%s%s", + dev->srcData.tcp.protocol == QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET ? "telnet" : "tcp", + dev->srcData.tcp.host, + dev->srcData.tcp.service, + dev->srcData.tcp.listen ? ",listen" : "") >= buflen) + return -1; + break; + + case QEMUD_CHR_SRC_TYPE_UNIX: + if (snprintf(buf, buflen, "unix:%s%s", + dev->srcData.nix.path, + dev->srcData.nix.listen ? ",listen" : "") >= buflen) + return -1; + break; + } + + return 0; +} + /* * Constructs a argv suitable for launching qemu with config defined * for a given virtual machine. @@ -1633,6 +2083,8 @@ int qemudBuildCommandLine(virConnectPtr conn, struct qemud_vm_disk_def *disk = vm->def->disks; struct qemud_vm_net_def *net = vm->def->nets; struct qemud_vm_input_def *input = vm->def->inputs; + struct qemud_vm_chr_def *serial = vm->def->serials; + struct qemud_vm_chr_def *parallel = vm->def->parallels; struct utsname ut; int disableKQEMU = 0; @@ -1681,6 +2133,8 @@ int qemudBuildCommandLine(virConnectPtr conn, (vm->def->nnets > 0 ? (4 * vm->def->nnets) : 2) + /* networks */ 1 + /* usb */ 2 * vm->def->ninputs + /* input devices */ + (vm->def->nserials > 0 ? (2 * vm->def->nserials) : 2) + /* character devices */ + (vm->def->nparallels > 0 ? (2 * vm->def->nparallels) : 2) + /* character devices */ 2 + /* memory*/ 2 + /* cpus */ 2 + /* boot device */ @@ -1913,6 +2367,48 @@ int qemudBuildCommandLine(virConnectPtr conn, } } + if (!serial) { + if (!((*argv)[++n] = strdup("-serial"))) + goto no_memory; + if (!((*argv)[++n] = strdup("none"))) + goto no_memory; + } else { + while (serial) { + char buf[4096]; + + if (qemudBuildCommandLineChrDevStr(serial, buf, sizeof(buf)) < 0) + goto error; + + if (!((*argv)[++n] = strdup("-serial"))) + goto no_memory; + if (!((*argv)[++n] = strdup(buf))) + goto no_memory; + + serial = serial->next; + } + } + + if (!parallel) { + if (!((*argv)[++n] = strdup("-parallel"))) + goto no_memory; + if (!((*argv)[++n] = strdup("none"))) + goto no_memory; + } else { + while (parallel) { + char buf[4096]; + + if (qemudBuildCommandLineChrDevStr(parallel, buf, sizeof(buf)) < 0) + goto error; + + if (!((*argv)[++n] = strdup("-parallel"))) + goto no_memory; + if (!((*argv)[++n] = strdup(buf))) + goto no_memory; + + parallel = parallel->next; + } + } + if (!((*argv)[++n] = strdup("-usb"))) goto no_memory; while (input) { @@ -2838,6 +3334,127 @@ int qemudScanConfigs(struct qemud_driver *driver) { return 0; } +static int qemudGenerateXMLChar(virBufferPtr buf, + const struct qemud_vm_chr_def *dev, + const char *type) +{ + const char *const types[] = { + "null", + "vc", + "pty", + "dev", + "file", + "pipe", + "stdio", + "udp", + "tcp", + "unix" + }; + /*verify(ARRAY_CARDINALITY(types) == QEMUD_CHR_SRC_TYPE_LAST);*/ + + if (dev->srcType < 0 || dev->srcType >= QEMUD_CHR_SRC_TYPE_LAST) + return -1; + + /* Compat with legacy syntax */ + if (STREQ(type, "console") && + dev->srcType == QEMUD_CHR_SRC_TYPE_PTY && + dev->srcData.file.path[0] != '\0') { + if (virBufferVSprintf(buf, " <%s type='%s' tty='%s'>\n", + type, types[dev->srcType], + dev->srcData.file.path) < 0) + return -1; + } else { + if (virBufferVSprintf(buf, " <%s type='%s'>\n", + type, types[dev->srcType]) < 0) + return -1; + } + + switch (dev->srcType) { + case QEMUD_CHR_SRC_TYPE_NULL: + case QEMUD_CHR_SRC_TYPE_VC: + case QEMUD_CHR_SRC_TYPE_STDIO: + /* nada */ + break; + + case QEMUD_CHR_SRC_TYPE_PTY: + case QEMUD_CHR_SRC_TYPE_DEV: + case QEMUD_CHR_SRC_TYPE_FILE: + case QEMUD_CHR_SRC_TYPE_PIPE: + if (dev->srcType != QEMUD_CHR_SRC_TYPE_PTY || + dev->srcData.file.path[0]) { + if (virBufferVSprintf(buf, " \n", + dev->srcData.file.path) < 0) + return -1; + } + break; + + case QEMUD_CHR_SRC_TYPE_UDP: + if (dev->srcData.udp.bindService[0] != '\0' && + dev->srcData.udp.bindHost[0] != '\0') { + if (virBufferVSprintf(buf, " \n", + dev->srcData.udp.bindHost, + dev->srcData.udp.bindService) < 0) + return -1; + } else if (dev->srcData.udp.bindHost[0] !='\0') { + if (virBufferVSprintf(buf, " \n", + dev->srcData.udp.bindHost) < 0) + return -1; + } else if (dev->srcData.udp.bindService[0] != '\0') { + if (virBufferVSprintf(buf, " \n", + dev->srcData.udp.bindService) < 0) + return -1; + } + + if (dev->srcData.udp.connectService[0] != '\0' && + dev->srcData.udp.connectHost[0] != '\0') { + if (virBufferVSprintf(buf, " \n", + dev->srcData.udp.connectHost, + dev->srcData.udp.connectService) < 0) + return -1; + } else if (dev->srcData.udp.connectHost[0] != '\0') { + if (virBufferVSprintf(buf, " \n", + dev->srcData.udp.connectHost) < 0) + return -1; + } else if (dev->srcData.udp.connectService[0] != '\0') { + if (virBufferVSprintf(buf, " \n", + dev->srcData.udp.connectService) < 0) + return -1; + } + + break; + + case QEMUD_CHR_SRC_TYPE_TCP: + if (virBufferVSprintf(buf, " \n", + dev->srcData.tcp.listen ? "bind" : "connect", + dev->srcData.tcp.host, + dev->srcData.tcp.service) < 0) + return -1; + if (virBufferVSprintf(buf, " \n", + dev->srcData.tcp.protocol == QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET + ? "telnet" : "raw") < 0) + return -1; + break; + + case QEMUD_CHR_SRC_TYPE_UNIX: + if (virBufferVSprintf(buf, " \n", + dev->srcData.nix.listen ? "bind" : "connect", + dev->srcData.nix.path) < 0) + return -1; + break; + } + + if (virBufferVSprintf(buf, " \n", + dev->dstPort) < 0) + return -1; + + if (virBufferVSprintf(buf, " \n", + type) < 0) + return -1; + + return 0; +} + + /* Generate an XML document describing the guest's configuration */ char *qemudGenerateXML(virConnectPtr conn, struct qemud_driver *driver ATTRIBUTE_UNUSED, @@ -2847,9 +3464,10 @@ char *qemudGenerateXML(virConnectPtr conn, virBufferPtr buf = 0; unsigned char *uuid; char uuidstr[VIR_UUID_STRING_BUFLEN]; - struct qemud_vm_disk_def *disk; - struct qemud_vm_net_def *net; - struct qemud_vm_input_def *input; + const struct qemud_vm_disk_def *disk; + const struct qemud_vm_net_def *net; + const struct qemud_vm_input_def *input; + const struct qemud_vm_chr_def *chr; const char *type = NULL; int n; @@ -3078,6 +3696,27 @@ char *qemudGenerateXML(virConnectPtr conn, net = net->next; } + chr = def->serials; + while (chr) { + if (qemudGenerateXMLChar(buf, chr, "serial") < 0) + goto no_memory; + + chr = chr->next; + } + + chr = def->parallels; + while (chr) { + if (qemudGenerateXMLChar(buf, chr, "parallel") < 0) + goto no_memory; + + chr = chr->next; + } + + /* First serial device is the primary console */ + if (def->nserials > 0 && + qemudGenerateXMLChar(buf, def->serials, "console") < 0) + goto no_memory; + input = def->inputs; while (input) { if (input->bus != QEMU_INPUT_BUS_PS2 && @@ -3125,9 +3764,6 @@ char *qemudGenerateXML(virConnectPtr conn, break; } - if (def->graphicsType == QEMUD_GRAPHICS_VNC) { - } - if (virBufferAddLit(buf, " \n") < 0) goto no_memory; diff --git a/src/qemu_conf.h b/src/qemu_conf.h index c59b1faebd81f0043bda8c41370e2c110def39be..8a367e3eca429fbb9c4271aab96cb0fb82e6ffda 100644 --- a/src/qemu_conf.h +++ b/src/qemu_conf.h @@ -119,6 +119,54 @@ struct qemud_vm_net_def { struct qemud_vm_net_def *next; }; +enum qemu_vm_chr_dst_type { + QEMUD_CHR_SRC_TYPE_NULL, + QEMUD_CHR_SRC_TYPE_VC, + QEMUD_CHR_SRC_TYPE_PTY, + QEMUD_CHR_SRC_TYPE_DEV, + QEMUD_CHR_SRC_TYPE_FILE, + QEMUD_CHR_SRC_TYPE_PIPE, + QEMUD_CHR_SRC_TYPE_STDIO, + QEMUD_CHR_SRC_TYPE_UDP, + QEMUD_CHR_SRC_TYPE_TCP, + QEMUD_CHR_SRC_TYPE_UNIX, + + QEMUD_CHR_SRC_TYPE_LAST, +}; + +enum { + QEMUD_CHR_SRC_TCP_PROTOCOL_RAW, + QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET, +}; + +struct qemud_vm_chr_def { + int dstPort; + + int srcType; + union { + struct { + char path[PATH_MAX]; + } file; /* pty, file, pipe, or device */ + struct { + char host[BR_INET_ADDR_MAXLEN]; + char service[BR_INET_ADDR_MAXLEN]; + int listen; + int protocol; + } tcp; + struct { + char bindHost[BR_INET_ADDR_MAXLEN]; + char bindService[BR_INET_ADDR_MAXLEN]; + char connectHost[BR_INET_ADDR_MAXLEN]; + char connectService[BR_INET_ADDR_MAXLEN]; + } udp; + struct { + char path[PATH_MAX]; + int listen; + } nix; + } srcData; + + struct qemud_vm_chr_def *next; +}; enum qemu_vm_input_type { QEMU_INPUT_TYPE_MOUSE, @@ -215,14 +263,20 @@ struct qemud_vm_def { char vncListen[BR_INET_ADDR_MAXLEN]; char *keymap; - int ndisks; + unsigned int ndisks; struct qemud_vm_disk_def *disks; - int nnets; + unsigned int nnets; struct qemud_vm_net_def *nets; - int ninputs; + unsigned int ninputs; struct qemud_vm_input_def *inputs; + + unsigned int nserials; + struct qemud_vm_chr_def *serials; + + unsigned int nparallels; + struct qemud_vm_chr_def *parallels; }; /* Guest VM runtime state */ diff --git a/src/qemu_driver.c b/src/qemu_driver.c index eb2f6e8903ab2c0edd7139f3640bd3ecf82e6986..e9246336c589a31a12667681139262c43b2d0993 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -381,7 +381,6 @@ qemudReadMonitorOutput(virConnectPtr conn, const char *what) { #define MONITOR_TIMEOUT 3000 - int got = 0; buf[0] = '\0'; @@ -498,48 +497,88 @@ static int qemudOpenMonitor(virConnectPtr conn, return ret; } -static int qemudExtractMonitorPath(const char *haystack, char *path, int pathmax) { +static int qemudExtractMonitorPath(const char *haystack, + size_t *offset, + char *path, int pathmax) { static const char needle[] = "char device redirected to"; char *tmp; - if (!(tmp = strstr(haystack, needle))) + /* First look for our magic string */ + if (!(tmp = strstr(haystack + *offset, needle))) return -1; + /* Grab all the trailing data */ strncpy(path, tmp+sizeof(needle), pathmax-1); path[pathmax-1] = '\0'; - while (*path) { - /* - * The monitor path ends at first whitespace char - * so lets search for it & NULL terminate it there - */ - if (isspace(to_uchar(*path))) { - *path = '\0'; + /* + * And look for first whitespace character and nul terminate + * to mark end of the pty path + */ + tmp = path; + while (*tmp) { + if (isspace(to_uchar(*tmp))) { + *tmp = '\0'; + *offset += (sizeof(needle)-1) + strlen(path); return 0; } - path++; + tmp++; } /* * We found a path, but didn't find any whitespace, * so it must be still incomplete - we should at - * least see a \n + * least see a \n - indicate that we want to carry + * on trying again */ return -1; } static int -qemudOpenMonitorPath(virConnectPtr conn, - struct qemud_driver *driver, - struct qemud_vm *vm, - const char *output, - int fd ATTRIBUTE_UNUSED) +qemudFindCharDevicePTYs(virConnectPtr conn, + struct qemud_driver *driver, + struct qemud_vm *vm, + const char *output, + int fd ATTRIBUTE_UNUSED) { char monitor[PATH_MAX]; + size_t offset = 0; + struct qemud_vm_chr_def *chr; - if (qemudExtractMonitorPath(output, monitor, sizeof(monitor)) < 0) + /* The order in which QEMU prints out the PTY paths is + the order in which it procsses its monitor, serial + and parallel device args. This code must match that + ordering.... */ + + /* So first comes the monitor device */ + if (qemudExtractMonitorPath(output, &offset, monitor, sizeof(monitor)) < 0) return 1; /* keep reading */ + /* then the serial devices */ + chr = vm->def->serials; + while (chr) { + if (chr->srcType == QEMUD_CHR_SRC_TYPE_PTY) { + if (qemudExtractMonitorPath(output, &offset, + chr->srcData.file.path, + sizeof(chr->srcData.file.path)) < 0) + return 1; /* keep reading */ + } + chr = chr->next; + } + + /* and finally the parallel devices */ + chr = vm->def->parallels; + while (chr) { + if (chr->srcType == QEMUD_CHR_SRC_TYPE_PTY) { + if (qemudExtractMonitorPath(output, &offset, + chr->srcData.file.path, + sizeof(chr->srcData.file.path)) < 0) + return 1; /* keep reading */ + } + chr = chr->next; + } + + /* Got them all, so now open the monitor console */ return qemudOpenMonitor(conn, driver, vm, monitor); } @@ -550,7 +589,7 @@ static int qemudWaitForMonitor(virConnectPtr conn, int ret = qemudReadMonitorOutput(conn, driver, vm, vm->stderr, buf, sizeof(buf), - qemudOpenMonitorPath, + qemudFindCharDevicePTYs, "console"); buf[sizeof(buf)-1] = '\0'; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.args b/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.args index cf4a92815b2c7731f61364b3a96ef4b1c87a8f86..fe29e97c121a9a8c451bed4d264410f3ee280789 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-cdrom.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot d -cdrom /dev/cdrom -net none -usb \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot d -cdrom /dev/cdrom -net none -serial none -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.args b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.args index 70d96dee84c0de15425cf45d73270153d3cad4cd..9141ef299dea13795be65634d643f55c93c57edb 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-floppy.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot a -hda /dev/HostVG/QEMUGuest1 -fda /tmp/firmware.img -net none -usb \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot a -hda /dev/HostVG/QEMUGuest1 -fda /tmp/firmware.img -net none -serial none -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-network.args b/tests/qemuxml2argvdata/qemuxml2argv-boot-network.args index 991f2f991739a8b6609b16c7208aecc610d70c1a..fdef4608d4fd8e8cb78614cac90d80e477f1f5f9 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-network.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-network.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot n -hda /dev/HostVG/QEMUGuest1 -net none -usb \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot n -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.args b/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.args index c7ef740256a561dd5f1f87764bfd56e2b4a7069d..9e2f9706ed09e23d6c3b956bc2566d85a7cf0f14 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-localtime.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -localtime -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -usb \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -localtime -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.args b/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.args index 08b55b8846410eee801328669a833b21759e01a1..69b1e7a421e2e71b7d31cad5e770f5dc18d0cf61 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-clock-utc.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -usb \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-compat.args b/tests/qemuxml2argvdata/qemuxml2argv-console-compat.args new file mode 100644 index 0000000000000000000000000000000000000000..541b7194ef93f4bad2ab77ffa7e14231705801e9 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-compat.args @@ -0,0 +1 @@ +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial pty -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml b/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml new file mode 100644 index 0000000000000000000000000000000000000000..7752c023579a3d051d5336ac0bcabb86952e48d7 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-compat.xml @@ -0,0 +1,28 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.args index 86964c1a07721dc74cef4d674433e897e030344c..8f0cdf8dadf35f77b2d15a318c38c31503f33d2b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -cdrom /root/boot.iso -net none -usb \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -cdrom /root/boot.iso -net none -serial none -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.args index 87c579c294430e905761efc14ccf395a4e5c0be2..10b72d7d99579b9d4e8f344e059afef87432e66e 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-floppy.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -fda /dev/fd0 -fdb /tmp/firmware.img -net none -usb \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -fda /dev/fd0 -fdb /tmp/firmware.img -net none -serial none -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-many.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-many.args index 0534d6195ee15c8a591c838299dfa8faa851b5d8..899b35b226d5aa9dd27d5ab809e05d8c4023d5c3 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-disk-many.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-many.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -hdb /dev/HostVG/QEMUGuest2 -hdc /tmp/data.img -hdd /tmp/logs.img -net none -usb \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -hdb /dev/HostVG/QEMUGuest2 -hdc /tmp/data.img -hdd /tmp/logs.img -net none -serial none -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.args index 6163ba6dc2e6f544b515808cb0c5c0309260ef61..b2faaabffd40dab10a6bf353e5ecf360553e3ea9 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-sdl.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -usb \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args index 42a33a47bbd92fa49138feac500142254b533c59..f8a98cd1cdb79fd6b2c4e5ea0e5b635d8aef5640 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -usb -vnc 127.0.0.1:3 \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -vnc 127.0.0.1:3 \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.args b/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.args index 0e27138ce1e39c53b7509b9a290f2b7771142df2..8552d308cb9ebe82d6406e4dcb8234e70c157426 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-input-usbmouse.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -usb -usbdevice mouse \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -usbdevice mouse \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.args b/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.args index 2c9652b20d8cbab8fbab4b72cc99dc257962c770..790bc1b32489788e533d3274d05af6bdac34dfcf 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-input-usbtablet.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -usb -usbdevice tablet \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb -usbdevice tablet \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-minimal.args b/tests/qemuxml2argvdata/qemuxml2argv-minimal.args index 08b55b8846410eee801328669a833b21759e01a1..69b1e7a421e2e71b7d31cad5e770f5dc18d0cf61 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-minimal.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-minimal.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -usb \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.args b/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.args index b4e8f6804cf9055e9b4bf84052ae5041f453931b..ba87bfbafbac7678891c7da7c2feb0274a257693 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-misc-acpi.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -boot c -hda /dev/HostVG/QEMUGuest1 -net none -usb \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.args b/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.args index 0135d5e6c4e1d58988925e3d903f8a25eee552d0..7461c957c77bb369433d81ae97cb74ad00a96729 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-misc-no-reboot.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-reboot -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -usb \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-reboot -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-user.args b/tests/qemuxml2argvdata/qemuxml2argv-net-user.args index 5c218610ed01dd86b47c9bfe46a949acc631a77e..fce8a215d524a614a8f11352d6a100e004afffda 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-net-user.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-user.args @@ -1 +1 @@ -/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net nic,macaddr=00:11:22:33:44:55,vlan=0 -net user,vlan=0 -usb \ No newline at end of file +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net nic,macaddr=00:11:22:33:44:55,vlan=0 -net user,vlan=0 -serial none -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.args b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.args new file mode 100644 index 0000000000000000000000000000000000000000..31c482ee0af0e9f1c94cd045e8de90b2ecd53de3 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.args @@ -0,0 +1 @@ +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel tcp:127.0.0.1:9999,listen -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml new file mode 100644 index 0000000000000000000000000000000000000000..e0fd51383ef424214a229891caa3eac0776346cb --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-parallel-tcp.xml @@ -0,0 +1,27 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.args new file mode 100644 index 0000000000000000000000000000000000000000..9c6262b057a2d8123594ce2979e5d87971038b1b --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.args @@ -0,0 +1 @@ +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial /dev/ttyS2 -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml new file mode 100644 index 0000000000000000000000000000000000000000..fa371cc0ee92d1f17518fe6e623be8213f1fc0ca --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-dev.xml @@ -0,0 +1,30 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + + + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-file.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-file.args new file mode 100644 index 0000000000000000000000000000000000000000..a373db29c16edd379f26dae361f59984b9928d0a --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-file.args @@ -0,0 +1 @@ +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial file:/tmp/serial.log -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml new file mode 100644 index 0000000000000000000000000000000000000000..4a1bdc5df472e5a7fba79a025a326f92d6d1307a --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-file.xml @@ -0,0 +1,30 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + + + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-many.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-many.args new file mode 100644 index 0000000000000000000000000000000000000000..d3e26867fd6fae32c09c7734722557fafff2094c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-many.args @@ -0,0 +1 @@ +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial pty -serial file:/tmp/serial.log -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml new file mode 100644 index 0000000000000000000000000000000000000000..3b9f124d2f2220f24e5bd02f5ba4ef7ab8a75110 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-many.xml @@ -0,0 +1,32 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + + + + + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.args new file mode 100644 index 0000000000000000000000000000000000000000..541b7194ef93f4bad2ab77ffa7e14231705801e9 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.args @@ -0,0 +1 @@ +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial pty -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml new file mode 100644 index 0000000000000000000000000000000000000000..7752c023579a3d051d5336ac0bcabb86952e48d7 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-pty.xml @@ -0,0 +1,28 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.args new file mode 100644 index 0000000000000000000000000000000000000000..961391997176a33a44e2a6d3ee8d58cf25e5b5c9 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.args @@ -0,0 +1 @@ +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial telnet:127.0.0.1:9999,listen -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml new file mode 100644 index 0000000000000000000000000000000000000000..77ac6a3f65e3338859127bf96dddcd13cd251c41 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp-telnet.xml @@ -0,0 +1,32 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + + + + + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.args new file mode 100644 index 0000000000000000000000000000000000000000..c82ef995edd5c64afd87af548e3d84aa81fef37c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.args @@ -0,0 +1 @@ +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial tcp:127.0.0.1:9999 -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml new file mode 100644 index 0000000000000000000000000000000000000000..fe80d2d4814e6c1db9f5e2b94fa3bc4a3dcec8a2 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-tcp.xml @@ -0,0 +1,32 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + + + + + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.args new file mode 100644 index 0000000000000000000000000000000000000000..e376ffc9e4bbab89c6ccc921abbacf6355e0b7dc --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.args @@ -0,0 +1 @@ +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial udp:127.0.0.1:9998@127.0.0.1:9999 -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml new file mode 100644 index 0000000000000000000000000000000000000000..bdab917bbd1309021908afa8c36725ddc5b4efa9 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-udp.xml @@ -0,0 +1,32 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + + + + + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.args new file mode 100644 index 0000000000000000000000000000000000000000..1ce9aee7c17e43877d0d8d74682b4f35425abd00 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.args @@ -0,0 +1 @@ +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial unix:/tmp/serial.sock -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml new file mode 100644 index 0000000000000000000000000000000000000000..cc9626998be5e9631917de586415085e512860ff --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-unix.xml @@ -0,0 +1,30 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + + + + + + + + + diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.args b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.args new file mode 100644 index 0000000000000000000000000000000000000000..93f331f0157986af84861ea830e0569fe047a4e1 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.args @@ -0,0 +1 @@ +/usr/bin/qemu -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial vc -parallel none -usb \ No newline at end of file diff --git a/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml new file mode 100644 index 0000000000000000000000000000000000000000..b5d6d178d88443207bf428cc720ecfa69fb3e596 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-serial-vc.xml @@ -0,0 +1,28 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + + + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 59ea21dab465528994a23891beecc6696b9b5647..093ff87407dab6ba5c5f2927ee210fb213bba6c0 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -15,7 +15,7 @@ #include "qemu_conf.h" static char *progname; -static char *abs_top_srcdir; +static char *abs_srcdir; static struct qemud_driver driver; #define MAX_FILE 4096 @@ -71,11 +71,8 @@ static int testCompareXMLToArgvFiles(const char *xml, const char *cmd) { tmp++; } - if (strcmp(expectargv, actualargv)) { - if (getenv("DEBUG_TESTS")) { - printf("Expect %4d '%s'\n", (int)strlen(expectargv), expectargv); - printf("Actual %4d '%s'\n", (int)strlen(actualargv), actualargv); - } + if (STRNEQ(expectargv, actualargv)) { + virtTestDifference(stderr, expectargv, actualargv); goto fail; } @@ -100,10 +97,10 @@ static int testCompareXMLToArgvFiles(const char *xml, const char *cmd) { static int testCompareXMLToArgvHelper(const void *data) { char xml[PATH_MAX]; char args[PATH_MAX]; - snprintf(xml, PATH_MAX, "%s/tests/qemuxml2argvdata/qemuxml2argv-%s.xml", - abs_top_srcdir, (const char*)data); - snprintf(args, PATH_MAX, "%s/tests/qemuxml2argvdata/qemuxml2argv-%s.args", - abs_top_srcdir, (const char*)data); + snprintf(xml, PATH_MAX, "%s/qemuxml2argvdata/qemuxml2argv-%s.xml", + abs_srcdir, (const char*)data); + snprintf(args, PATH_MAX, "%s/qemuxml2argvdata/qemuxml2argv-%s.args", + abs_srcdir, (const char*)data); return testCompareXMLToArgvFiles(xml, args); } @@ -113,6 +110,7 @@ int main(int argc, char **argv) { int ret = 0; + char cwd[PATH_MAX]; progname = argv[0]; @@ -121,76 +119,45 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } - abs_top_srcdir = getenv("abs_top_srcdir"); - if (!abs_top_srcdir) - return 1; + abs_srcdir = getenv("abs_srcdir"); + if (!abs_srcdir) + abs_srcdir = getcwd(cwd, sizeof(cwd)); driver.caps = qemudCapsInit(); - if (virtTestRun("QEMU XML-2-ARGV minimal", - 1, testCompareXMLToArgvHelper, "minimal") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Boot CDROM", - 1, testCompareXMLToArgvHelper, "boot-cdrom") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Boot Network", - 1, testCompareXMLToArgvHelper, "boot-network") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Boot Floppy", - 1, testCompareXMLToArgvHelper, "boot-floppy") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Clock UTC", - 1, testCompareXMLToArgvHelper, "clock-utc") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Clock Localtime", - 1, testCompareXMLToArgvHelper, "clock-localtime") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Disk CDROM", - 1, testCompareXMLToArgvHelper, "disk-cdrom") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Disk Floppy", - 1, testCompareXMLToArgvHelper, "disk-floppy") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Disk Many", - 1, testCompareXMLToArgvHelper, "disk-many") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Graphics VNC", - 1, testCompareXMLToArgvHelper, "graphics-vnc") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Graphics SDL", - 1, testCompareXMLToArgvHelper, "graphics-sdl") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Input USB Mouse", - 1, testCompareXMLToArgvHelper, "input-usbmouse") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Input USB Tablet", - 1, testCompareXMLToArgvHelper, "input-usbtablet") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Misc ACPI", - 1, testCompareXMLToArgvHelper, "misc-acpi") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Misc No Reboot", - 1, testCompareXMLToArgvHelper, "misc-no-reboot") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Net User", - 1, testCompareXMLToArgvHelper, "net-user") < 0) - ret = -1; - +#define DO_TEST(name) \ + if (virtTestRun("QEMU XML-2-ARGV " name, \ + 1, testCompareXMLToArgvHelper, (name)) < 0) \ + ret = -1 + + DO_TEST("minimal"); + DO_TEST("boot-cdrom"); + DO_TEST("boot-network"); + DO_TEST("boot-floppy"); + DO_TEST("clock-utc"); + DO_TEST("clock-localtime"); + DO_TEST("disk-cdrom"); + DO_TEST("disk-floppy"); + DO_TEST("disk-many"); + DO_TEST("graphics-vnc"); + DO_TEST("graphics-sdl"); + DO_TEST("input-usbmouse"); + DO_TEST("input-usbtablet"); + DO_TEST("misc-acpi"); + DO_TEST("misc-no-reboot"); + DO_TEST("net-user"); + + DO_TEST("serial-vc"); + DO_TEST("serial-pty"); + DO_TEST("serial-dev"); + DO_TEST("serial-file"); + DO_TEST("serial-unix"); + DO_TEST("serial-tcp"); + DO_TEST("serial-udp"); + DO_TEST("serial-tcp-telnet"); + DO_TEST("serial-many"); + DO_TEST("parallel-tcp"); + DO_TEST("console-compat"); virCapabilitiesFree(driver.caps); diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 69cf77b8250988fa81d2e195d41f7b07a6df5f9d..156d5093c69d72354072a62aa4d796e8cd22e433 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -15,7 +15,7 @@ #include "qemu_conf.h" static char *progname; -static char *abs_top_srcdir; +static char *abs_srcdir; static struct qemud_driver driver; #define MAX_FILE 4096 @@ -47,11 +47,8 @@ static int testCompareXMLToXMLFiles(const char *xml) { if (!(actual = qemudGenerateXML(NULL, &driver, &vm, vmdef, 0))) goto fail; - if (strcmp(xmlData, actual)) { - if (getenv("DEBUG_TESTS")) { - printf("Expect %4d '%s'\n", (int)strlen(xmlData), xmlData); - printf("Actual %4d '%s'\n", (int)strlen(actual), actual); - } + if (STRNEQ(xmlData, actual)) { + virtTestDifference(stderr, xmlData, actual); goto fail; } @@ -66,8 +63,8 @@ static int testCompareXMLToXMLFiles(const char *xml) { static int testCompareXMLToXMLHelper(const void *data) { char xml[PATH_MAX]; - snprintf(xml, PATH_MAX, "%s/tests/qemuxml2argvdata/qemuxml2argv-%s.xml", - abs_top_srcdir, (const char*)data); + snprintf(xml, PATH_MAX, "%s/qemuxml2argvdata/qemuxml2argv-%s.xml", + abs_srcdir, (const char*)data); return testCompareXMLToXMLFiles(xml); } @@ -76,6 +73,7 @@ int main(int argc, char **argv) { int ret = 0; + char cwd[PATH_MAX]; progname = argv[0]; @@ -84,76 +82,45 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } - abs_top_srcdir = getenv("abs_top_srcdir"); - if (!abs_top_srcdir) - return 1; - + abs_srcdir = getenv("abs_srcdir"); + if (!abs_srcdir) + abs_srcdir = getcwd(cwd, sizeof(cwd)); driver.caps = qemudCapsInit(); - if (virtTestRun("QEMU XML-2-ARGV minimal", - 1, testCompareXMLToXMLHelper, "minimal") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Boot CDROM", - 1, testCompareXMLToXMLHelper, "boot-cdrom") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Boot Network", - 1, testCompareXMLToXMLHelper, "boot-network") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Boot Floppy", - 1, testCompareXMLToXMLHelper, "boot-floppy") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Clock UTC", - 1, testCompareXMLToXMLHelper, "clock-utc") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Clock Localtime", - 1, testCompareXMLToXMLHelper, "clock-localtime") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Disk CDROM", - 1, testCompareXMLToXMLHelper, "disk-cdrom") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Disk Floppy", - 1, testCompareXMLToXMLHelper, "disk-floppy") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Disk Many", - 1, testCompareXMLToXMLHelper, "disk-many") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Graphics VNC", - 1, testCompareXMLToXMLHelper, "graphics-vnc") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Graphics SDL", - 1, testCompareXMLToXMLHelper, "graphics-sdl") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Input USB Mouse", - 1, testCompareXMLToXMLHelper, "input-usbmouse") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Input USB Tablet", - 1, testCompareXMLToXMLHelper, "input-usbtablet") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Misc ACPI", - 1, testCompareXMLToXMLHelper, "misc-acpi") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Misc No Reboot", - 1, testCompareXMLToXMLHelper, "misc-no-reboot") < 0) - ret = -1; - - if (virtTestRun("QEMU XML-2-ARGV Net User", - 1, testCompareXMLToXMLHelper, "net-user") < 0) - ret = -1; +#define DO_TEST(name) \ + if (virtTestRun("QEMU XML-2-XML " name, \ + 1, testCompareXMLToXMLHelper, (name)) < 0) \ + ret = -1 + + DO_TEST("minimal"); + DO_TEST("boot-cdrom"); + DO_TEST("boot-network"); + DO_TEST("boot-floppy"); + DO_TEST("clock-utc"); + DO_TEST("clock-localtime"); + DO_TEST("disk-cdrom"); + DO_TEST("disk-floppy"); + DO_TEST("disk-many"); + DO_TEST("graphics-vnc"); + DO_TEST("graphics-sdl"); + DO_TEST("input-usbmouse"); + DO_TEST("input-usbtablet"); + DO_TEST("misc-acpi"); + DO_TEST("misc-no-reboot"); + DO_TEST("net-user"); + + DO_TEST("serial-vc"); + DO_TEST("serial-pty"); + DO_TEST("serial-dev"); + DO_TEST("serial-file"); + DO_TEST("serial-unix"); + DO_TEST("serial-tcp"); + DO_TEST("serial-udp"); + DO_TEST("serial-tcp-telnet"); + DO_TEST("serial-many"); + DO_TEST("parallel-tcp"); + DO_TEST("console-compat"); virCapabilitiesFree(driver.caps);