diff --git a/ChangeLog b/ChangeLog index 8ea0ffca66..fb22963b17 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Thu May 28 14:20:30 BST 2009 Daniel P. Berrange + + Fix misc bugs in ARGV -> XML convertor + * src/qemu_conf.c, src/qemu_conf.h, src/qemu_driver.c: Fill + in autogenerated MAC adress and UUID when converting ARGV + into XML. Avoid crash if net device vlan isn't specified. + Cope with quoting of argument values + * tests/qemuargv2xmltest.c: Initialize random number generator + and pass in capabilities when parsing ARGV + Thu May 28 14:13:30 BST 2009 Daniel P. Berrange Avoid broken networking with new QEMU/KVM >= 86 diff --git a/src/qemu_conf.c b/src/qemu_conf.c index a04d2166ee..18156cdd9f 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -1565,14 +1565,27 @@ static int qemuStringToArgvEnv(const char *args, /* 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 char **progenv, 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,31 +1927,32 @@ 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 ((nkeywords = qemuParseCommandLineKeywords(conn, - tmp+1, - &keywords, - &values)) < 0) - return NULL; + if (tmp) { + if ((nkeywords = qemuParseCommandLineKeywords(conn, + tmp+1, + &keywords, + &values)) < 0) + return NULL; + } else { + nkeywords = 0; + } if (VIR_ALLOC(def) < 0) { virReportOOMError(conn); @@ -1983,7 +2002,9 @@ qemuParseCommandLineNet(virConnectPtr conn, 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 conn, 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 conn, } } + 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(virConnectPtr conn, 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(virConnectPtr conn, 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 qemuParseCommandLineString(virConnectPtr conn, 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 --git a/src/qemu_conf.h b/src/qemu_conf.h index 957e3cde9e..1001e00ecf 100644 --- a/src/qemu_conf.h +++ b/src/qemu_conf.h @@ -136,9 +136,11 @@ int qemudBuildCommandLine (virConnectPtr conn, const char *migrateFrom); virDomainDefPtr qemuParseCommandLine(virConnectPtr conn, + virCapsPtr caps, const char **progenv, const char **progargv); virDomainDefPtr qemuParseCommandLineString(virConnectPtr conn, + virCapsPtr caps, const char *args); const char *qemudVirtTypeToString (int type); diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 1301e5d5e3..40f5790420 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -3426,6 +3426,7 @@ static char *qemuDomainXMLFromNative(virConnectPtr conn, const char *format, const char *config, unsigned int flags ATTRIBUTE_UNUSED) { + struct qemud_driver *driver = conn->privateData; virDomainDefPtr def = NULL; char *xml = NULL; @@ -3435,7 +3436,7 @@ static char *qemuDomainXMLFromNative(virConnectPtr conn, goto cleanup; } - def = qemuParseCommandLineString(conn, config); + def = qemuParseCommandLineString(conn, driver->caps, config); if (!def) goto cleanup; diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c index fbf92ae6e6..f2537b7c11 100644 --- a/tests/qemuargv2xmltest.c +++ b/tests/qemuargv2xmltest.c @@ -49,7 +49,7 @@ static int testCompareXMLToArgvFiles(const char *xml, 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)