int qemuMonitorTestAddItem(qemuMonitorTestPtr test, const char *command_name, const char *response) { qemuMonitorTestItemPtr item; if (VIR_ALLOC(item) < 0) goto no_memory; if (!(item->command_name = strdup(command_name)) || !(item->response = strdup(response))) goto no_memory; virMutexLock(&test->lock); if (VIR_EXPAND_N(test->items, test->nitems, 1) < 0) { virMutexUnlock(&test->lock); goto no_memory; } test->items[test->nitems - 1] = item; virMutexUnlock(&test->lock); return 0; no_memory: virReportOOMError(); qemuMonitorTestItemFree(item); return -1; }
void qemuMonitorTestFree(qemuMonitorTestPtr test) { size_t i; int timer = -1; if (!test) return; virMutexLock(&test->lock); if (test->running) { test->quit = true; /* HACK: Add a dummy timeout to break event loop */ timer = virEventAddTimeout(0, qemuMonitorTestFreeTimer, NULL, NULL); } virMutexUnlock(&test->lock); if (test->client) { virNetSocketRemoveIOCallback(test->client); virNetSocketClose(test->client); virObjectUnref(test->client); } virObjectUnref(test->server); if (test->mon) { virObjectUnlock(test->mon); qemuMonitorClose(test->mon); } virObjectUnref(test->vm); virThreadJoin(&test->thread); if (timer != -1) virEventRemoveTimeout(timer); VIR_FREE(test->incoming); VIR_FREE(test->outgoing); for (i = 0 ; i < test->nitems ; i++) qemuMonitorTestItemFree(test->items[i]); VIR_FREE(test->items); if (test->tmpdir && rmdir(test->tmpdir) < 0) VIR_WARN("Failed to remove tempdir: %s", strerror(errno)); VIR_FREE(test->tmpdir); virMutexDestroy(&test->lock); VIR_FREE(test); }
static int qemuMonitorTestProcessCommandText(qemuMonitorTestPtr test, const char *cmdstr) { char *tmp; char *cmdname; int ret = -1; if (!(cmdname = strdup(cmdstr))) { virReportOOMError(); return -1; } if (!(tmp = strchr(cmdname, ' '))) { virReportError(VIR_ERR_INTERNAL_ERROR, "Cannot find command name in '%s'", cmdstr); goto cleanup; } *tmp = '\0'; if (test->nitems == 0 || STRNEQ(test->items[0]->command_name, cmdname)) { ret = qemuMonitorTestAddReponse(test, "unexpected command"); } else { ret = qemuMonitorTestAddReponse(test, test->items[0]->response); qemuMonitorTestItemFree(test->items[0]); if (test->nitems == 1) { VIR_FREE(test->items); test->nitems = 0; } else { memmove(test->items, test->items + 1, sizeof(test->items[0]) * (test->nitems - 1)); VIR_SHRINK_N(test->items, test->nitems, 1); } } cleanup: VIR_FREE(cmdname); return ret; }
/* * Processes a single line, looking for a matching expected * item to reply with, else replies with an error */ static int qemuMonitorTestProcessCommandJSON(qemuMonitorTestPtr test, const char *cmdstr) { virJSONValuePtr val; const char *cmdname; int ret = -1; if (!(val = virJSONValueFromString(cmdstr))) return -1; if (!(cmdname = virJSONValueObjectGetString(val, "execute"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "Missing command name in %s", cmdstr); goto cleanup; } if (test->nitems == 0 || STRNEQ(test->items[0]->command_name, cmdname)) { ret = qemuMonitorTestAddReponse(test, "{ \"error\": " " { \"desc\": \"Unexpected command\", " " \"class\": \"UnexpectedCommand\" } }"); } else { ret = qemuMonitorTestAddReponse(test, test->items[0]->response); qemuMonitorTestItemFree(test->items[0]); if (test->nitems == 1) { VIR_FREE(test->items); test->nitems = 0; } else { memmove(test->items, test->items + 1, sizeof(test->items[0]) * (test->nitems - 1)); VIR_SHRINK_N(test->items, test->nitems, 1); } } cleanup: virJSONValueFree(val); return ret; }