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,11 +4771,11 @@ static const char *qemuFindEnv(const char **progenv,
* the "=value" part is optional and if a key with no value is found,
* NULL is be placed into corresponding place in retvalues.
*/
static int
qemuParseCommandLineKeywords(const char *str,
char ***retkeywords,
char ***retvalues,
int allowEmptyValue)
int
qemuParseKeywords(const char *str,
char ***retkeywords,
char ***retvalues,
int allowEmptyValue)
{
int keywordCount = 0;
int keywordAlloc = 0;
@ -4874,9 +4874,9 @@ qemuParseCommandLineDisk(const char *val,
int busid = -1;
int unitid = -1;
if ((nkeywords = qemuParseCommandLineKeywords(val,
&keywords,
&values, 0)) < 0)
if ((nkeywords = qemuParseKeywords(val,
&keywords,
&values, 0)) < 0)
return NULL;
if (VIR_ALLOC(def) < 0) {
@ -5114,9 +5114,9 @@ qemuParseCommandLineNet(virCapsPtr caps,
tmp = strchr(val, ',');
if (tmp) {
if ((nkeywords = qemuParseCommandLineKeywords(tmp+1,
&keywords,
&values, 0)) < 0)
if ((nkeywords = qemuParseKeywords(tmp+1,
&keywords,
&values, 0)) < 0)
return NULL;
} else {
nkeywords = 0;
@ -5186,9 +5186,9 @@ qemuParseCommandLineNet(virCapsPtr caps,
VIR_FREE(values);
if (STRPREFIX(nic, "nic,")) {
if ((nkeywords = qemuParseCommandLineKeywords(nic + strlen("nic,"),
&keywords,
&values, 0)) < 0) {
if ((nkeywords = qemuParseKeywords(nic + strlen("nic,"),
&keywords,
&values, 0)) < 0) {
virDomainNetDefFree(def);
def = NULL;
goto cleanup;
@ -5596,7 +5596,7 @@ qemuParseCommandLineSmp(virDomainDefPtr dom,
char *end;
int ret;
nkws = qemuParseCommandLineKeywords(val, &kws, &vals, 1);
nkws = qemuParseKeywords(val, &kws, &vals, 1);
if (nkws < 0)
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 qemuAssignDeviceControllerAlias(virDomainControllerDefPtr controller);
int
qemuParseKeywords(const char *str,
char ***retkeywords,
char ***retvalues,
int allowEmptyValue);
#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,
const char *devicestr)
{
int ret;
int ret = -1;
virJSONValuePtr cmd;
virJSONValuePtr reply = NULL;
virJSONValuePtr args;
cmd = qemuMonitorJSONMakeCommand("device_add",
"s:config", devicestr,
NULL);
cmd = qemuMonitorJSONMakeCommand("device_add", NULL);
if (!cmd)
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);
if (ret == 0)
ret = qemuMonitorJSONCheckError(cmd, reply);
cleanup:
virJSONValueFree(args);
virJSONValueFree(cmd);
virJSONValueFree(reply);
return ret;