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 :|