mirror of https://gitee.com/openkylin/libvirt.git
qemu: Issue query-iothreads and to get list of active IOThreads
Generate infrastructure and test to handle fetching the QMP IOThreads data.
This commit is contained in:
parent
bc5a8090af
commit
4cf6bfab4c
|
@ -4061,3 +4061,44 @@ qemuMonitorRTCResetReinjection(qemuMonitorPtr mon)
|
||||||
|
|
||||||
return qemuMonitorJSONRTCResetReinjection(mon);
|
return qemuMonitorJSONRTCResetReinjection(mon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qemuMonitorGetIOThreads:
|
||||||
|
* @mon: Pointer to the monitor
|
||||||
|
* @iothreads: Location to return array of IOThreadInfo data
|
||||||
|
*
|
||||||
|
* Issue query-iothreads command.
|
||||||
|
* Retrieve the list of iothreads defined/running for the machine
|
||||||
|
*
|
||||||
|
* Returns count of IOThreadInfo structures on success
|
||||||
|
* -1 on error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
qemuMonitorGetIOThreads(qemuMonitorPtr mon,
|
||||||
|
qemuMonitorIOThreadsInfoPtr **iothreads)
|
||||||
|
{
|
||||||
|
|
||||||
|
VIR_DEBUG("mon=%p iothreads=%p", mon, iothreads);
|
||||||
|
|
||||||
|
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 qemuMonitorJSONGetIOThreads(mon, iothreads);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qemuMonitorIOThreadsInfoFree(qemuMonitorIOThreadsInfoPtr iothread)
|
||||||
|
{
|
||||||
|
if (!iothread)
|
||||||
|
return;
|
||||||
|
VIR_FREE(iothread->name);
|
||||||
|
VIR_FREE(iothread);
|
||||||
|
}
|
||||||
|
|
|
@ -798,6 +798,18 @@ int qemuMonitorGetGuestCPU(qemuMonitorPtr mon,
|
||||||
|
|
||||||
int qemuMonitorRTCResetReinjection(qemuMonitorPtr mon);
|
int qemuMonitorRTCResetReinjection(qemuMonitorPtr mon);
|
||||||
|
|
||||||
|
typedef struct _qemuMonitorIOThreadsInfo qemuMonitorIOThreadsInfo;
|
||||||
|
typedef qemuMonitorIOThreadsInfo *qemuMonitorIOThreadsInfoPtr;
|
||||||
|
|
||||||
|
struct _qemuMonitorIOThreadsInfo {
|
||||||
|
char *name;
|
||||||
|
int thread_id;
|
||||||
|
};
|
||||||
|
int qemuMonitorGetIOThreads(qemuMonitorPtr mon,
|
||||||
|
qemuMonitorIOThreadsInfoPtr **iothreads);
|
||||||
|
|
||||||
|
void qemuMonitorIOThreadsInfoFree(qemuMonitorIOThreadsInfoPtr iothread);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When running two dd process and using <> redirection, we need a
|
* When running two dd process and using <> redirection, we need a
|
||||||
* shell that will not truncate files. These two strings serve that
|
* shell that will not truncate files. These two strings serve that
|
||||||
|
|
|
@ -5910,3 +5910,94 @@ qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon)
|
||||||
virJSONValueFree(reply);
|
virJSONValueFree(reply);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query and parse returned array of data such as:
|
||||||
|
*
|
||||||
|
* {u'return': [{u'id': u'iothread1', u'thread-id': 30992}, \
|
||||||
|
* {u'id': u'iothread2', u'thread-id': 30993}]}
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
qemuMonitorJSONGetIOThreads(qemuMonitorPtr mon,
|
||||||
|
qemuMonitorIOThreadsInfoPtr **iothreads)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
virJSONValuePtr cmd;
|
||||||
|
virJSONValuePtr reply = NULL;
|
||||||
|
virJSONValuePtr data;
|
||||||
|
qemuMonitorIOThreadsInfoPtr *infolist = NULL;
|
||||||
|
int n = 0;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
*iothreads = NULL;
|
||||||
|
|
||||||
|
if (!(cmd = qemuMonitorJSONMakeCommand("query-iothreads", NULL)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = qemuMonitorJSONCommand(mon, cmd, &reply);
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
ret = qemuMonitorJSONCheckError(cmd, reply);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
if (!(data = virJSONValueObjectGet(reply, "return"))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("query-iothreads reply was missing return data"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((n = virJSONValueArraySize(data)) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("query-iothreads reply data was not an array"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* null-terminated list */
|
||||||
|
if (VIR_ALLOC_N(infolist, n + 1) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
virJSONValuePtr child = virJSONValueArrayGet(data, i);
|
||||||
|
const char *tmp;
|
||||||
|
qemuMonitorIOThreadsInfoPtr info;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(info) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
infolist[i] = info;
|
||||||
|
|
||||||
|
if (!(tmp = virJSONValueObjectGetString(child, "id"))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("query-iothreads reply data was missing 'id'"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VIR_STRDUP(info->name, tmp) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virJSONValueObjectGetNumberInt(child, "thread-id",
|
||||||
|
&info->thread_id) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("query-iothreads reply has malformed "
|
||||||
|
"'thread-id' data"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = n;
|
||||||
|
*iothreads = infolist;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (ret < 0 && infolist) {
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
qemuMonitorIOThreadsInfoFree(infolist[i]);
|
||||||
|
VIR_FREE(infolist);
|
||||||
|
}
|
||||||
|
virJSONValueFree(cmd);
|
||||||
|
virJSONValueFree(reply);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -446,4 +446,8 @@ int qemuMonitorJSONGetGuestCPU(qemuMonitorPtr mon,
|
||||||
virCPUDataPtr *data);
|
virCPUDataPtr *data);
|
||||||
|
|
||||||
int qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon);
|
int qemuMonitorJSONRTCResetReinjection(qemuMonitorPtr mon);
|
||||||
|
|
||||||
|
int qemuMonitorJSONGetIOThreads(qemuMonitorPtr mon,
|
||||||
|
qemuMonitorIOThreadsInfoPtr **iothreads)
|
||||||
|
ATTRIBUTE_NONNULL(2);
|
||||||
#endif /* QEMU_MONITOR_JSON_H */
|
#endif /* QEMU_MONITOR_JSON_H */
|
||||||
|
|
|
@ -2216,6 +2216,76 @@ testQemuMonitorJSONGetNonExistingCPUData(const void *opaque)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
testQemuMonitorJSONGetIOThreads(const void *data)
|
||||||
|
{
|
||||||
|
virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
|
||||||
|
qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt);
|
||||||
|
qemuMonitorIOThreadsInfoPtr *info;
|
||||||
|
int ninfo = 0;
|
||||||
|
int ret = -1;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!test)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (qemuMonitorTestAddItem(test, "query-iothreads",
|
||||||
|
"{ "
|
||||||
|
" \"return\": [ "
|
||||||
|
" { "
|
||||||
|
" \"id\": \"iothread1\", "
|
||||||
|
" \"thread-id\": 30992 "
|
||||||
|
" }, "
|
||||||
|
" { "
|
||||||
|
" \"id\": \"iothread2\", "
|
||||||
|
" \"thread-id\": 30993 "
|
||||||
|
" } "
|
||||||
|
" ]"
|
||||||
|
"}") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if ((ninfo = qemuMonitorGetIOThreads(qemuMonitorTestGetMonitor(test),
|
||||||
|
&info)) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (ninfo != 2) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
"ninfo %d is not 2", ninfo);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK(i, wantname, wantthread_id) \
|
||||||
|
do { \
|
||||||
|
if (STRNEQ(info[i]->name, (wantname))) { \
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, \
|
||||||
|
"name %s is not %s", \
|
||||||
|
info[i]->name, (wantname)); \
|
||||||
|
goto cleanup; \
|
||||||
|
} \
|
||||||
|
if (info[i]->thread_id != (wantthread_id)) { \
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, \
|
||||||
|
"thread_id %d is not %d", \
|
||||||
|
info[i]->thread_id, (wantthread_id)); \
|
||||||
|
goto cleanup; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
CHECK(0, "iothread1", 30992);
|
||||||
|
CHECK(1, "iothread2", 30993);
|
||||||
|
|
||||||
|
#undef CHECK
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
qemuMonitorTestFree(test);
|
||||||
|
for (i = 0; i < ninfo; i++)
|
||||||
|
qemuMonitorIOThreadsInfoFree(info[i]);
|
||||||
|
VIR_FREE(info);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mymain(void)
|
mymain(void)
|
||||||
{
|
{
|
||||||
|
@ -2272,6 +2342,7 @@ mymain(void)
|
||||||
DO_TEST(GetDeviceAliases);
|
DO_TEST(GetDeviceAliases);
|
||||||
DO_TEST(CPU);
|
DO_TEST(CPU);
|
||||||
DO_TEST(GetNonExistingCPUData);
|
DO_TEST(GetNonExistingCPUData);
|
||||||
|
DO_TEST(GetIOThreads);
|
||||||
DO_TEST_SIMPLE("qmp_capabilities", qemuMonitorJSONSetCapabilities);
|
DO_TEST_SIMPLE("qmp_capabilities", qemuMonitorJSONSetCapabilities);
|
||||||
DO_TEST_SIMPLE("system_powerdown", qemuMonitorJSONSystemPowerdown);
|
DO_TEST_SIMPLE("system_powerdown", qemuMonitorJSONSystemPowerdown);
|
||||||
DO_TEST_SIMPLE("system_reset", qemuMonitorJSONSystemReset);
|
DO_TEST_SIMPLE("system_reset", qemuMonitorJSONSystemReset);
|
||||||
|
|
Loading…
Reference in New Issue