Having just tried out the QEMU ARGV -> XML convertor on a random set of args posted on the mailing list I found a few bugs. It didn't cope with a -net arg without a vlan=XX option set - this should assume vlan=0 if not set. It didn't cope with quoting of args with spaces in them. It finally did not generate a random UUID or MAC address if omitted. Regards, Daniel diff -r eb060781cfb9 src/qemu_conf.c --- a/src/qemu_conf.c Wed May 27 21:07:37 2009 +0100 +++ b/src/qemu_conf.c Wed May 27 22:56:55 2009 +0100 @@ -1565,14 +1565,27 @@ static int qemuStringToArgvEnv(const cha /* Iterate over string, splitting on sequences of ' ' */ while (curr && *curr != '\0') { char *arg; - const char *next = strchr(curr, ' '); + const char *next; + if (*curr == '\'') { + curr++; + next = strchr(curr, '\''); + } else if (*curr == '"') { + curr++; + next = strchr(curr, '"'); + } else { + next = strchr(curr, ' '); + } if (!next) next = strchr(curr, '\n'); - if (next) + if (next) { arg = strndup(curr, next-curr); - else + if (*next == '\'' || + *next == '"') + next++; + } else { arg = strdup(curr); + } if (!arg) goto no_memory; @@ -1644,7 +1657,7 @@ static const char *qemuFindEnv(const cha int i; int len = strlen(name); - for (i = 0 ; progenv[i] ; i++) { + for (i = 0 ; progenv && progenv[i] ; i++) { if (STREQLEN(progenv[i], name, len) && progenv[i][len] == '=') return progenv[i] + len + 1; @@ -1883,8 +1896,10 @@ qemuFindNICForVLAN(virConnectPtr conn, int gotvlan; const char *tmp = strstr(nics[i], "vlan="); char *end; - if (tmp) - tmp += strlen("vlan="); + if (!tmp) + continue; + + tmp += strlen("vlan="); if (virStrToLong_i(tmp, &end, 10, &gotvlan) < 0) { qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, @@ -1896,6 +1911,9 @@ qemuFindNICForVLAN(virConnectPtr conn, return nics[i]; } + if (wantvlan == 0 && nnics > 0) + return nics[0]; + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("cannot find NIC definition for vlan %d"), wantvlan); return NULL; @@ -1909,32 +1927,33 @@ qemuFindNICForVLAN(virConnectPtr conn, */ static virDomainNetDefPtr qemuParseCommandLineNet(virConnectPtr conn, + virCapsPtr caps, const char *val, int nnics, const char **nics) { virDomainNetDefPtr def = NULL; - char **keywords; - char **values; + char **keywords = NULL; + char **values = NULL; int nkeywords; const char *nic; int wantvlan = 0; const char *tmp; + int genmac = 1; int i; tmp = strchr(val, ','); - if (!tmp) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - _("cannot extract NIC type from '%s'"), val); - return NULL; + + if (tmp) { + if ((nkeywords = qemuParseCommandLineKeywords(conn, + tmp+1, + &keywords, + &values)) < 0) + return NULL; + } else { + nkeywords = 0; } - if ((nkeywords = qemuParseCommandLineKeywords(conn, - tmp+1, - &keywords, - &values)) < 0) - return NULL; - if (VIR_ALLOC(def) < 0) { virReportOOMError(conn); goto cleanup; @@ -1983,7 +2002,9 @@ qemuParseCommandLineNet(virConnectPtr co goto cleanup; } - if (!STRPREFIX(nic, "nic,")) { + if (!STRPREFIX(nic, "nic")) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("cannot parse NIC definition '%s'"), nic); virDomainNetDefFree(def); def = NULL; goto cleanup; @@ -1996,17 +2017,22 @@ qemuParseCommandLineNet(virConnectPtr co VIR_FREE(keywords); VIR_FREE(values); - if ((nkeywords = qemuParseCommandLineKeywords(conn, - nic + strlen("nic,"), - &keywords, - &values)) < 0) { - virDomainNetDefFree(def); - def = NULL; - goto cleanup; + if (STRPREFIX(nic, "nic,")) { + if ((nkeywords = qemuParseCommandLineKeywords(conn, + nic + strlen("nic,"), + &keywords, + &values)) < 0) { + virDomainNetDefFree(def); + def = NULL; + goto cleanup; + } + } else { + nkeywords = 0; } for (i = 0 ; i < nkeywords ; i++) { if (STREQ(keywords[i], "macaddr")) { + genmac = 0; virParseMacAddr(values[i], def->mac); } else if (STREQ(keywords[i], "model")) { def->model = values[i]; @@ -2014,6 +2040,9 @@ qemuParseCommandLineNet(virConnectPtr co } } + if (genmac) + virCapabilitiesGenerateMac(caps, def->mac); + cleanup: for (i = 0 ; i < nkeywords ; i++) { VIR_FREE(keywords[i]); @@ -2283,6 +2312,7 @@ error: * as is practical. This is not an exact science.... */ virDomainDefPtr qemuParseCommandLine(virConnectPtr conn, + virCapsPtr caps, const char **progenv, const char **progargv) { @@ -2303,6 +2333,8 @@ virDomainDefPtr qemuParseCommandLine(vir if (VIR_ALLOC(def) < 0) goto no_memory; + virUUIDGenerate(def->uuid); + def->id = -1; def->memory = def->maxmem = 64 * 1024; def->vcpus = 1; @@ -2604,7 +2636,7 @@ virDomainDefPtr qemuParseCommandLine(vir WANT_VALUE(); if (!STRPREFIX(val, "nic") && STRNEQ(val, "none")) { virDomainNetDefPtr net; - if (!(net = qemuParseCommandLineNet(conn, val, nnics, nics))) + if (!(net = qemuParseCommandLineNet(conn, caps, val, nnics, nics))) goto error; if (VIR_REALLOC_N(def->nets, def->nnets+1) < 0) { virDomainNetDefFree(net); @@ -2741,6 +2773,7 @@ error: virDomainDefPtr qemuParseCommandLineString(virConnectPtr conn, + virCapsPtr caps, const char *args) { const char **progenv = NULL; @@ -2751,7 +2784,7 @@ virDomainDefPtr qemuParseCommandLineStri if (qemuStringToArgvEnv(args, &progenv, &progargv) < 0) goto cleanup; - def = qemuParseCommandLine(conn, progenv, progargv); + def = qemuParseCommandLine(conn, caps, progenv, progargv); cleanup: for (i = 0 ; progargv && progargv[i] ; i++) diff -r eb060781cfb9 src/qemu_conf.h --- a/src/qemu_conf.h Wed May 27 21:07:37 2009 +0100 +++ b/src/qemu_conf.h Wed May 27 22:56:55 2009 +0100 @@ -127,9 +127,11 @@ int qemudBuildCommandLine const char *migrateFrom); virDomainDefPtr qemuParseCommandLine(virConnectPtr conn, + virCapsPtr caps, const char **progenv, const char **progargv); virDomainDefPtr qemuParseCommandLineString(virConnectPtr conn, + virCapsPtr caps, const char *args); #endif /* __QEMUD_CONF_H */ diff -r eb060781cfb9 src/qemu_driver.c --- a/src/qemu_driver.c Wed May 27 21:07:37 2009 +0100 +++ b/src/qemu_driver.c Wed May 27 22:56:55 2009 +0100 @@ -3418,6 +3418,7 @@ static char *qemuDomainXMLFromNative(vir const char *format, const char *config, unsigned int flags ATTRIBUTE_UNUSED) { + struct qemud_driver *driver = conn->privateData; virDomainDefPtr def = NULL; char *xml = NULL; @@ -3427,7 +3428,7 @@ static char *qemuDomainXMLFromNative(vir goto cleanup; } - def = qemuParseCommandLineString(conn, config); + def = qemuParseCommandLineString(conn, driver->caps, config); if (!def) goto cleanup; diff -r eb060781cfb9 tests/qemuargv2xmltest.c --- a/tests/qemuargv2xmltest.c Wed May 27 21:07:37 2009 +0100 +++ b/tests/qemuargv2xmltest.c Wed May 27 22:56:55 2009 +0100 @@ -49,7 +49,7 @@ static int testCompareXMLToArgvFiles(con if (virtTestLoadFile(xml, &expectxml, MAX_FILE) < 0) goto fail; - if (!(vmdef = qemuParseCommandLineString(NULL, cmd))) + if (!(vmdef = qemuParseCommandLineString(NULL, driver.caps, cmd))) goto fail; if (!(actualxml = virDomainDefFormat(NULL, vmdef, 0))) @@ -109,6 +109,8 @@ mymain(int argc, char **argv) if (!abs_srcdir) abs_srcdir = getcwd(cwd, sizeof(cwd)); + virRandomInitialize(0); + if ((driver.caps = testQemuCapsInit()) == NULL) return EXIT_FAILURE; if((driver.stateDir = strdup("/nowhere")) == NULL) -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list