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>
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 ' ' */
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++)

View File

@ -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);

View File

@ -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;

View File

@ -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)