Update QEMU device_add command in JSON mode

The device_add command was added in JSON mode in a way I didn't
expect. Instead of passing the normal device string to the JSON
command:

    { "execute": "device_add", "arguments": { "device": "ne2k_pci,id=nic.1,netdev=net.1" } }

We need to split up the device string into a full JSON object

    { "execute": "device_add", "arguments": { "driver": "ne2k_pci", "id": "nic.1", "netdev": "net.1" } }

* src/qemu/qemu_conf.h, src/qemu/qemu_conf.c: Rename the
  qemuCommandLineParseKeywords method to qemuParseKeywords
  and export it to monitor
* src/qemu/qemu_monitor_json.c: Split up device string into
  a JSON object for device_add command
This commit is contained in:
Daniel P. Berrange 2010-04-14 16:02:37 +01:00
parent fde060b8f5
commit db336caa58
3 changed files with 95 additions and 19 deletions

View File

@ -4771,8 +4771,8 @@ static const char *qemuFindEnv(const char **progenv,
* the "=value" part is optional and if a key with no value is found, * the "=value" part is optional and if a key with no value is found,
* NULL is be placed into corresponding place in retvalues. * NULL is be placed into corresponding place in retvalues.
*/ */
static int int
qemuParseCommandLineKeywords(const char *str, qemuParseKeywords(const char *str,
char ***retkeywords, char ***retkeywords,
char ***retvalues, char ***retvalues,
int allowEmptyValue) int allowEmptyValue)
@ -4874,7 +4874,7 @@ qemuParseCommandLineDisk(const char *val,
int busid = -1; int busid = -1;
int unitid = -1; int unitid = -1;
if ((nkeywords = qemuParseCommandLineKeywords(val, if ((nkeywords = qemuParseKeywords(val,
&keywords, &keywords,
&values, 0)) < 0) &values, 0)) < 0)
return NULL; return NULL;
@ -5114,7 +5114,7 @@ qemuParseCommandLineNet(virCapsPtr caps,
tmp = strchr(val, ','); tmp = strchr(val, ',');
if (tmp) { if (tmp) {
if ((nkeywords = qemuParseCommandLineKeywords(tmp+1, if ((nkeywords = qemuParseKeywords(tmp+1,
&keywords, &keywords,
&values, 0)) < 0) &values, 0)) < 0)
return NULL; return NULL;
@ -5186,7 +5186,7 @@ qemuParseCommandLineNet(virCapsPtr caps,
VIR_FREE(values); VIR_FREE(values);
if (STRPREFIX(nic, "nic,")) { if (STRPREFIX(nic, "nic,")) {
if ((nkeywords = qemuParseCommandLineKeywords(nic + strlen("nic,"), if ((nkeywords = qemuParseKeywords(nic + strlen("nic,"),
&keywords, &keywords,
&values, 0)) < 0) { &values, 0)) < 0) {
virDomainNetDefFree(def); virDomainNetDefFree(def);
@ -5596,7 +5596,7 @@ qemuParseCommandLineSmp(virDomainDefPtr dom,
char *end; char *end;
int ret; int ret;
nkws = qemuParseCommandLineKeywords(val, &kws, &vals, 1); nkws = qemuParseKeywords(val, &kws, &vals, 1);
if (nkws < 0) if (nkws < 0)
return -1; return -1;

View File

@ -311,5 +311,11 @@ int qemuAssignDeviceDiskAlias(virDomainDiskDefPtr def, unsigned long long qemuCm
int qemuAssignDeviceHostdevAlias(virDomainDefPtr def, virDomainHostdevDefPtr net, int idx); int qemuAssignDeviceHostdevAlias(virDomainDefPtr def, virDomainHostdevDefPtr net, int idx);
int qemuAssignDeviceControllerAlias(virDomainControllerDefPtr controller); int qemuAssignDeviceControllerAlias(virDomainControllerDefPtr controller);
int
qemuParseKeywords(const char *str,
char ***retkeywords,
char ***retvalues,
int allowEmptyValue);
#endif /* __QEMUD_CONF_H */ #endif /* __QEMUD_CONF_H */

View File

@ -1961,24 +1961,94 @@ int qemuMonitorJSONDelDevice(qemuMonitorPtr mon,
} }
static void
qemuFreeKeywords(int nkeywords, char **keywords, char **values)
{
int i;
for (i = 0 ; i < nkeywords ; i++) {
VIR_FREE(keywords[i]);
VIR_FREE(values[i]);
}
VIR_FREE(keywords);
VIR_FREE(values);
}
static virJSONValuePtr
qemuMonitorJSONKeywordStringToJSON(const char *str, const char *firstkeyword)
{
virJSONValuePtr ret = NULL;
char **keywords = NULL;
char **values = NULL;
int nkeywords = 0;
int i;
if (!(ret = virJSONValueNewObject()))
goto no_memory;
nkeywords = qemuParseKeywords(str, &keywords, &values, 1);
if (nkeywords < 0)
goto error;
for (i = 0 ; i < nkeywords ; i++) {
if (values[i] == NULL) {
if (i != 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected empty keyword in %s"), str);
goto error;
} else {
/* This 3rd arg isn't a typo - the way the parser works is
* that the value ended up in the keyword field */
if (virJSONValueObjectAppendString(ret, firstkeyword, keywords[i]) < 0)
goto no_memory;
}
} else {
if (virJSONValueObjectAppendString(ret, keywords[i], values[i]) < 0)
goto no_memory;
}
}
qemuFreeKeywords(nkeywords, keywords, values);
return ret;
no_memory:
virReportOOMError();
error:
qemuFreeKeywords(nkeywords, keywords, values);
virJSONValueFree(ret);
return NULL;
}
int qemuMonitorJSONAddDevice(qemuMonitorPtr mon, int qemuMonitorJSONAddDevice(qemuMonitorPtr mon,
const char *devicestr) const char *devicestr)
{ {
int ret; int ret = -1;
virJSONValuePtr cmd; virJSONValuePtr cmd;
virJSONValuePtr reply = NULL; virJSONValuePtr reply = NULL;
virJSONValuePtr args;
cmd = qemuMonitorJSONMakeCommand("device_add", cmd = qemuMonitorJSONMakeCommand("device_add", NULL);
"s:config", devicestr,
NULL);
if (!cmd) if (!cmd)
return -1; return -1;
args = qemuMonitorJSONKeywordStringToJSON(devicestr, "driver");
if (!args)
goto cleanup;
if (virJSONValueObjectAppend(cmd, "arguments", args) < 0) {
virReportOOMError();
goto cleanup;
}
args = NULL; /* obj owns reference to args now */
ret = qemuMonitorJSONCommand(mon, cmd, &reply); ret = qemuMonitorJSONCommand(mon, cmd, &reply);
if (ret == 0) if (ret == 0)
ret = qemuMonitorJSONCheckError(cmd, reply); ret = qemuMonitorJSONCheckError(cmd, reply);
cleanup:
virJSONValueFree(args);
virJSONValueFree(cmd); virJSONValueFree(cmd);
virJSONValueFree(reply); virJSONValueFree(reply);
return ret; return ret;