Fix misc bugs in ARGV -> XML convertor

This commit is contained in:
Daniel P. Berrange 2009-05-28 13:21:19 +00:00
parent 2afc3bfd8b
commit c31300e69f
5 changed files with 78 additions and 30 deletions

View File

@ -1,3 +1,13 @@
Thu May 28 14:20:30 BST 2009 Daniel P. Berrange <berrange@redhat.com>
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 <berrange@redhat.com> Thu May 28 14:13:30 BST 2009 Daniel P. Berrange <berrange@redhat.com>
Avoid broken networking with new QEMU/KVM >= 86 Avoid broken networking with new QEMU/KVM >= 86

View File

@ -1565,14 +1565,27 @@ static int qemuStringToArgvEnv(const char *args,
/* Iterate over string, splitting on sequences of ' ' */ /* Iterate over string, splitting on sequences of ' ' */
while (curr && *curr != '\0') { while (curr && *curr != '\0') {
char *arg; 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) if (!next)
next = strchr(curr, '\n'); next = strchr(curr, '\n');
if (next) if (next) {
arg = strndup(curr, next-curr); arg = strndup(curr, next-curr);
else if (*next == '\'' ||
*next == '"')
next++;
} else {
arg = strdup(curr); arg = strdup(curr);
}
if (!arg) if (!arg)
goto no_memory; goto no_memory;
@ -1644,7 +1657,7 @@ static const char *qemuFindEnv(const char **progenv,
int i; int i;
int len = strlen(name); int len = strlen(name);
for (i = 0 ; progenv[i] ; i++) { for (i = 0 ; progenv && progenv[i] ; i++) {
if (STREQLEN(progenv[i], name, len) && if (STREQLEN(progenv[i], name, len) &&
progenv[i][len] == '=') progenv[i][len] == '=')
return progenv[i] + len + 1; return progenv[i] + len + 1;
@ -1883,8 +1896,10 @@ qemuFindNICForVLAN(virConnectPtr conn,
int gotvlan; int gotvlan;
const char *tmp = strstr(nics[i], "vlan="); const char *tmp = strstr(nics[i], "vlan=");
char *end; char *end;
if (tmp) if (!tmp)
tmp += strlen("vlan="); continue;
tmp += strlen("vlan=");
if (virStrToLong_i(tmp, &end, 10, &gotvlan) < 0) { if (virStrToLong_i(tmp, &end, 10, &gotvlan) < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
@ -1896,6 +1911,9 @@ qemuFindNICForVLAN(virConnectPtr conn,
return nics[i]; return nics[i];
} }
if (wantvlan == 0 && nnics > 0)
return nics[0];
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
_("cannot find NIC definition for vlan %d"), wantvlan); _("cannot find NIC definition for vlan %d"), wantvlan);
return NULL; return NULL;
@ -1909,31 +1927,32 @@ qemuFindNICForVLAN(virConnectPtr conn,
*/ */
static virDomainNetDefPtr static virDomainNetDefPtr
qemuParseCommandLineNet(virConnectPtr conn, qemuParseCommandLineNet(virConnectPtr conn,
virCapsPtr caps,
const char *val, const char *val,
int nnics, int nnics,
const char **nics) const char **nics)
{ {
virDomainNetDefPtr def = NULL; virDomainNetDefPtr def = NULL;
char **keywords; char **keywords = NULL;
char **values; char **values = NULL;
int nkeywords; int nkeywords;
const char *nic; const char *nic;
int wantvlan = 0; int wantvlan = 0;
const char *tmp; const char *tmp;
int genmac = 1;
int i; int i;
tmp = strchr(val, ','); 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, if (tmp) {
tmp+1, if ((nkeywords = qemuParseCommandLineKeywords(conn,
&keywords, tmp+1,
&values)) < 0) &keywords,
return NULL; &values)) < 0)
return NULL;
} else {
nkeywords = 0;
}
if (VIR_ALLOC(def) < 0) { if (VIR_ALLOC(def) < 0) {
virReportOOMError(conn); virReportOOMError(conn);
@ -1983,7 +2002,9 @@ qemuParseCommandLineNet(virConnectPtr conn,
goto cleanup; 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); virDomainNetDefFree(def);
def = NULL; def = NULL;
goto cleanup; goto cleanup;
@ -1996,17 +2017,22 @@ qemuParseCommandLineNet(virConnectPtr conn,
VIR_FREE(keywords); VIR_FREE(keywords);
VIR_FREE(values); VIR_FREE(values);
if ((nkeywords = qemuParseCommandLineKeywords(conn, if (STRPREFIX(nic, "nic,")) {
nic + strlen("nic,"), if ((nkeywords = qemuParseCommandLineKeywords(conn,
&keywords, nic + strlen("nic,"),
&values)) < 0) { &keywords,
virDomainNetDefFree(def); &values)) < 0) {
def = NULL; virDomainNetDefFree(def);
goto cleanup; def = NULL;
goto cleanup;
}
} else {
nkeywords = 0;
} }
for (i = 0 ; i < nkeywords ; i++) { for (i = 0 ; i < nkeywords ; i++) {
if (STREQ(keywords[i], "macaddr")) { if (STREQ(keywords[i], "macaddr")) {
genmac = 0;
virParseMacAddr(values[i], def->mac); virParseMacAddr(values[i], def->mac);
} else if (STREQ(keywords[i], "model")) { } else if (STREQ(keywords[i], "model")) {
def->model = values[i]; def->model = values[i];
@ -2014,6 +2040,9 @@ qemuParseCommandLineNet(virConnectPtr conn,
} }
} }
if (genmac)
virCapabilitiesGenerateMac(caps, def->mac);
cleanup: cleanup:
for (i = 0 ; i < nkeywords ; i++) { for (i = 0 ; i < nkeywords ; i++) {
VIR_FREE(keywords[i]); VIR_FREE(keywords[i]);
@ -2283,6 +2312,7 @@ error:
* as is practical. This is not an exact science.... * as is practical. This is not an exact science....
*/ */
virDomainDefPtr qemuParseCommandLine(virConnectPtr conn, virDomainDefPtr qemuParseCommandLine(virConnectPtr conn,
virCapsPtr caps,
const char **progenv, const char **progenv,
const char **progargv) const char **progargv)
{ {
@ -2303,6 +2333,8 @@ virDomainDefPtr qemuParseCommandLine(virConnectPtr conn,
if (VIR_ALLOC(def) < 0) if (VIR_ALLOC(def) < 0)
goto no_memory; goto no_memory;
virUUIDGenerate(def->uuid);
def->id = -1; def->id = -1;
def->memory = def->maxmem = 64 * 1024; def->memory = def->maxmem = 64 * 1024;
def->vcpus = 1; def->vcpus = 1;
@ -2604,7 +2636,7 @@ virDomainDefPtr qemuParseCommandLine(virConnectPtr conn,
WANT_VALUE(); WANT_VALUE();
if (!STRPREFIX(val, "nic") && STRNEQ(val, "none")) { if (!STRPREFIX(val, "nic") && STRNEQ(val, "none")) {
virDomainNetDefPtr net; virDomainNetDefPtr net;
if (!(net = qemuParseCommandLineNet(conn, val, nnics, nics))) if (!(net = qemuParseCommandLineNet(conn, caps, val, nnics, nics)))
goto error; goto error;
if (VIR_REALLOC_N(def->nets, def->nnets+1) < 0) { if (VIR_REALLOC_N(def->nets, def->nnets+1) < 0) {
virDomainNetDefFree(net); virDomainNetDefFree(net);
@ -2741,6 +2773,7 @@ error:
virDomainDefPtr qemuParseCommandLineString(virConnectPtr conn, virDomainDefPtr qemuParseCommandLineString(virConnectPtr conn,
virCapsPtr caps,
const char *args) const char *args)
{ {
const char **progenv = NULL; const char **progenv = NULL;
@ -2751,7 +2784,7 @@ virDomainDefPtr qemuParseCommandLineString(virConnectPtr conn,
if (qemuStringToArgvEnv(args, &progenv, &progargv) < 0) if (qemuStringToArgvEnv(args, &progenv, &progargv) < 0)
goto cleanup; goto cleanup;
def = qemuParseCommandLine(conn, progenv, progargv); def = qemuParseCommandLine(conn, caps, progenv, progargv);
cleanup: cleanup:
for (i = 0 ; progargv && progargv[i] ; i++) for (i = 0 ; progargv && progargv[i] ; i++)

View File

@ -136,9 +136,11 @@ int qemudBuildCommandLine (virConnectPtr conn,
const char *migrateFrom); const char *migrateFrom);
virDomainDefPtr qemuParseCommandLine(virConnectPtr conn, virDomainDefPtr qemuParseCommandLine(virConnectPtr conn,
virCapsPtr caps,
const char **progenv, const char **progenv,
const char **progargv); const char **progargv);
virDomainDefPtr qemuParseCommandLineString(virConnectPtr conn, virDomainDefPtr qemuParseCommandLineString(virConnectPtr conn,
virCapsPtr caps,
const char *args); const char *args);
const char *qemudVirtTypeToString (int type); const char *qemudVirtTypeToString (int type);

View File

@ -3426,6 +3426,7 @@ static char *qemuDomainXMLFromNative(virConnectPtr conn,
const char *format, const char *format,
const char *config, const char *config,
unsigned int flags ATTRIBUTE_UNUSED) { unsigned int flags ATTRIBUTE_UNUSED) {
struct qemud_driver *driver = conn->privateData;
virDomainDefPtr def = NULL; virDomainDefPtr def = NULL;
char *xml = NULL; char *xml = NULL;
@ -3435,7 +3436,7 @@ static char *qemuDomainXMLFromNative(virConnectPtr conn,
goto cleanup; goto cleanup;
} }
def = qemuParseCommandLineString(conn, config); def = qemuParseCommandLineString(conn, driver->caps, config);
if (!def) if (!def)
goto cleanup; goto cleanup;

View File

@ -49,7 +49,7 @@ static int testCompareXMLToArgvFiles(const char *xml,
if (virtTestLoadFile(xml, &expectxml, MAX_FILE) < 0) if (virtTestLoadFile(xml, &expectxml, MAX_FILE) < 0)
goto fail; goto fail;
if (!(vmdef = qemuParseCommandLineString(NULL, cmd))) if (!(vmdef = qemuParseCommandLineString(NULL, driver.caps, cmd)))
goto fail; goto fail;
if (!(actualxml = virDomainDefFormat(NULL, vmdef, 0))) if (!(actualxml = virDomainDefFormat(NULL, vmdef, 0)))
@ -109,6 +109,8 @@ mymain(int argc, char **argv)
if (!abs_srcdir) if (!abs_srcdir)
abs_srcdir = getcwd(cwd, sizeof(cwd)); abs_srcdir = getcwd(cwd, sizeof(cwd));
virRandomInitialize(0);
if ((driver.caps = testQemuCapsInit()) == NULL) if ((driver.caps = testQemuCapsInit()) == NULL)
return EXIT_FAILURE; return EXIT_FAILURE;
if((driver.stateDir = strdup("/nowhere")) == NULL) if((driver.stateDir = strdup("/nowhere")) == NULL)