bool json;
bool waitGreeting;
+
+ /* cache of query-command-line-options results */
+ virJSONValuePtr options;
};
static virClassPtr qemuMonitorClass;
(mon->cb->destroy)(mon, mon->vm);
virCondDestroy(&mon->notify);
VIR_FREE(mon->buffer);
+ virJSONValueFree(mon->options);
}
}
+virJSONValuePtr
+qemuMonitorGetOptions(qemuMonitorPtr mon)
+{
+ return mon->options;
+}
+
+void
+qemuMonitorSetOptions(qemuMonitorPtr mon, virJSONValuePtr options)
+{
+ mon->options = options;
+}
+
int qemuMonitorHMPCommandWithFd(qemuMonitorPtr mon,
const char *cmd,
int scm_fd,
}
+/* Collect the parameters associated with a given command line option.
+ * Return count of known parameters or -1 on error. */
+int
+qemuMonitorGetCommandLineOptionParameters(qemuMonitorPtr mon,
+ const char *option,
+ char ***params)
+{
+ VIR_DEBUG("mon=%p option=%s params=%p", mon, option, params);
+
+ if (!mon) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("monitor must not be NULL"));
+ return -1;
+ }
+
+ if (!mon->json) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("JSON monitor is required"));
+ return -1;
+ }
+
+ return qemuMonitorJSONGetCommandLineOptionParameters(mon, option, params);
+}
+
+
int qemuMonitorGetKVMState(qemuMonitorPtr mon,
bool *enabled,
bool *present)
int qemuMonitorSetLink(qemuMonitorPtr mon,
const char *name,
- enum virDomainNetInterfaceLinkState state) ;
+ enum virDomainNetInterfaceLinkState state);
/* These APIs are for use by the internal Text/JSON monitor impl code only */
char *qemuMonitorNextCommandID(qemuMonitorPtr mon);
int qemuMonitorSend(qemuMonitorPtr mon,
qemuMonitorMessagePtr msg);
+virJSONValuePtr qemuMonitorGetOptions(qemuMonitorPtr mon)
+ ATTRIBUTE_NONNULL(1);
+void qemuMonitorSetOptions(qemuMonitorPtr mon, virJSONValuePtr options)
+ ATTRIBUTE_NONNULL(1);
int qemuMonitorHMPCommandWithFd(qemuMonitorPtr mon,
const char *cmd,
int scm_fd,
char ***commands);
int qemuMonitorGetEvents(qemuMonitorPtr mon,
char ***events);
+int qemuMonitorGetCommandLineOptionParameters(qemuMonitorPtr mon,
+ const char *option,
+ char ***params);
int qemuMonitorGetKVMState(qemuMonitorPtr mon,
bool *enabled,
}
+int
+qemuMonitorJSONGetCommandLineOptionParameters(qemuMonitorPtr mon,
+ const char *option,
+ char ***params)
+{
+ int ret;
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+ virJSONValuePtr data = NULL;
+ virJSONValuePtr array = NULL;
+ char **paramlist = NULL;
+ int n = 0;
+ size_t i;
+
+ *params = NULL;
+
+ /* query-command-line-options has fixed output for a given qemu
+ * binary; but since callers want to query parameters for one
+ * option at a time, we cache the option list from qemu. */
+ if (!(array = qemuMonitorGetOptions(mon))) {
+ if (!(cmd = qemuMonitorJSONMakeCommand("query-command-line-options",
+ NULL)))
+ return -1;
+
+ ret = qemuMonitorJSONCommand(mon, cmd, &reply);
+
+ if (ret == 0) {
+ if (qemuMonitorJSONHasError(reply, "CommandNotFound"))
+ goto cleanup;
+ ret = qemuMonitorJSONCheckError(cmd, reply);
+ }
+
+ if (ret < 0)
+ goto cleanup;
+
+ if (virJSONValueObjectRemoveKey(reply, "return", &array) <= 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-command-line-options reply was missing "
+ "return data"));
+ goto cleanup;
+ }
+ qemuMonitorSetOptions(mon, array);
+ }
+
+ ret = -1;
+
+ if ((n = virJSONValueArraySize(array)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-command-line-options reply data was not "
+ "an array"));
+ goto cleanup;
+ }
+
+ for (i = 0 ; i < n ; i++) {
+ virJSONValuePtr child = virJSONValueArrayGet(array, i);
+ const char *tmp;
+
+ if (!(tmp = virJSONValueObjectGetString(child, "option"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-command-line-options reply data was "
+ "missing 'option'"));
+ goto cleanup;
+ }
+ if (STREQ(tmp, option)) {
+ data = virJSONValueObjectGet(child, "parameters");
+ break;
+ }
+ }
+
+ if (!data) {
+ /* Option not found; return 0 parameters rather than an error. */
+ ret = 0;
+ goto cleanup;
+ }
+
+ if ((n = virJSONValueArraySize(data)) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-command-line-options parameter data was not "
+ "an array"));
+ goto cleanup;
+ }
+
+ /* null-terminated list */
+ if (VIR_ALLOC_N(paramlist, n + 1) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ for (i = 0 ; i < n ; i++) {
+ virJSONValuePtr child = virJSONValueArrayGet(data, i);
+ const char *tmp;
+
+ if (!(tmp = virJSONValueObjectGetString(child, "name"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-command-line-options parameter data was "
+ "missing 'name'"));
+ goto cleanup;
+ }
+
+ if (VIR_STRDUP(paramlist[i], tmp) < 0)
+ goto cleanup;
+ }
+
+ ret = n;
+ *params = paramlist;
+
+cleanup:
+ /* If we failed before getting the JSON array of options, we (try)
+ * to cache an empty array to speed up the next failure. */
+ if (!qemuMonitorGetOptions(mon))
+ qemuMonitorSetOptions(mon, virJSONValueNewArray());
+
+ if (ret < 0)
+ virStringFreeList(paramlist);
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
+
+
int qemuMonitorJSONGetKVMState(qemuMonitorPtr mon,
bool *enabled,
bool *present)
int qemuMonitorJSONGetEvents(qemuMonitorPtr mon,
char ***events)
ATTRIBUTE_NONNULL(2);
+int qemuMonitorJSONGetCommandLineOptionParameters(qemuMonitorPtr mon,
+ const char *option,
+ char ***params)
+ ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
int qemuMonitorJSONGetKVMState(qemuMonitorPtr mon,
bool *enabled,
}
+static int
+testQemuMonitorJSONGetCommandLineOptionParameters(const void *data)
+{
+ const virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
+ qemuMonitorTestPtr test = qemuMonitorTestNew(true, xmlopt);
+ int ret = -1;
+ char **params = NULL;
+ int nparams = 0;
+
+ if (!test)
+ return -1;
+
+ if (qemuMonitorTestAddItem(test, "query-command-line-options",
+ "{ "
+ " \"return\": [ "
+ " {\"parameters\": [], \"option\": \"acpi\" },"
+ " {\"parameters\": ["
+ " {\"name\": \"romfile\", "
+ " \"type\": \"string\"}, "
+ " {\"name\": \"bootindex\", "
+ " \"type\": \"number\"}], "
+ " \"option\": \"option-rom\"}"
+ " ]"
+ "}") < 0)
+ goto cleanup;
+
+ /* present with params */
+ if ((nparams = qemuMonitorGetCommandLineOptionParameters(qemuMonitorTestGetMonitor(test),
+ "option-rom",
+ ¶ms)) < 0)
+ goto cleanup;
+
+ if (nparams != 2) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "nparams was %d, expected 2", nparams);
+ goto cleanup;
+ }
+
+#define CHECK(i, wantname) \
+ do { \
+ if (STRNEQ(params[i], (wantname))) { \
+ virReportError(VIR_ERR_INTERNAL_ERROR, \
+ "name was %s, expected %s", \
+ params[i], (wantname)); \
+ goto cleanup; \
+ } \
+ } while (0)
+
+ CHECK(0, "romfile");
+ CHECK(1, "bootindex");
+
+#undef CHECK
+
+ virStringFreeList(params);
+ params = NULL;
+
+ /* present but empty */
+ if ((nparams = qemuMonitorGetCommandLineOptionParameters(qemuMonitorTestGetMonitor(test),
+ "acpi",
+ ¶ms)) < 0)
+ goto cleanup;
+
+ if (nparams != 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "nparams was %d, expected 0", nparams);
+ goto cleanup;
+ }
+ if (params && params[0]) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ "unexpected array contents");
+ goto cleanup;
+ }
+
+ virStringFreeList(params);
+ params = NULL;
+
+ /* no such option */
+ if ((nparams = qemuMonitorGetCommandLineOptionParameters(qemuMonitorTestGetMonitor(test),
+ "foobar",
+ ¶ms)) < 0)
+ goto cleanup;
+
+ if (nparams != 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "nparams was %d, expected 0", nparams);
+ goto cleanup;
+ }
+ if (params && params[0]) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ "unexpected array contents");
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ qemuMonitorTestFree(test);
+ virStringFreeList(params);
+ return ret;
+}
+
+
static int
mymain(void)
{
DO_TEST(GetCPUDefinitions);
DO_TEST(GetCommands);
DO_TEST(GetTPMModels);
+ DO_TEST(GetCommandLineOptionParameters);
virObjectUnref(xmlopt);