mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 07:17:44 +00:00
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:
parent
fde060b8f5
commit
db336caa58
@ -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;
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user