int qemuAgentArbitraryCommand(qemuAgentPtr mon, const char *cmd_str, char **result, int timeout) { int ret = -1; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; *result = NULL; if (timeout < VIR_DOMAIN_QEMU_AGENT_COMMAND_MIN) return ret; cmd = virJSONValueFromString(cmd_str); if (!cmd) return ret; ret = qemuAgentCommand(mon, cmd, &reply, timeout); if (ret == 0) { ret = qemuAgentCheckError(cmd, reply); *result = virJSONValueToString(reply, false); } virJSONValueFree(cmd); virJSONValueFree(reply); return ret; }
int qemuAgentShutdown(qemuAgentPtr mon, qemuAgentShutdownMode mode) { int ret = -1; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; cmd = qemuAgentMakeCommand("guest-shutdown", "s:mode", qemuAgentShutdownModeTypeToString(mode), NULL); if (!cmd) return -1; if (mode == QEMU_AGENT_SHUTDOWN_REBOOT) mon->await_event = QEMU_AGENT_EVENT_RESET; else mon->await_event = QEMU_AGENT_EVENT_SHUTDOWN; ret = qemuAgentCommand(mon, cmd, &reply, VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK); if (reply && ret == 0) ret = qemuAgentCheckError(cmd, reply); virJSONValueFree(cmd); virJSONValueFree(reply); return ret; }
/* * qemuAgentFSThaw: * @mon: Agent * * Issue guest-fsfreeze-thaw command to guest agent, * which unfreezes all mounted file systems and returns * number of thawed file systems on success. * * Returns: number of file system thawed on success, * -1 on error. */ int qemuAgentFSThaw(qemuAgentPtr mon) { int ret = -1; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; cmd = qemuAgentMakeCommand("guest-fsfreeze-thaw", NULL); if (!cmd) return -1; if (qemuAgentCommand(mon, cmd, &reply, VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0 || qemuAgentCheckError(cmd, reply) < 0) goto cleanup; if (virJSONValueObjectGetNumberInt(reply, "return", &ret) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed return value")); } cleanup: virJSONValueFree(cmd); virJSONValueFree(reply); return ret; }
int qemuAgentArbitraryCommand(qemuAgentPtr mon, const char *cmd_str, char **result, int timeout) { int ret = -1; virJSONValuePtr cmd = NULL; virJSONValuePtr reply = NULL; *result = NULL; if (timeout < VIR_DOMAIN_QEMU_AGENT_COMMAND_MIN) { virReportError(VIR_ERR_INVALID_ARG, _("guest agent timeout '%d' is " "less than the minimum '%d'"), timeout, VIR_DOMAIN_QEMU_AGENT_COMMAND_MIN); goto cleanup; } if (!(cmd = virJSONValueFromString(cmd_str))) goto cleanup; if ((ret = qemuAgentCommand(mon, cmd, &reply, true, timeout)) < 0) goto cleanup; if (!(*result = virJSONValueToString(reply, false))) ret = -1; cleanup: virJSONValueFree(cmd); virJSONValueFree(reply); return ret; }
/** * Set the VCPU state using guest agent. * * Returns -1 on error, ninfo in case everything was successful and less than * ninfo on a partial failure. */ int qemuAgentSetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr info, size_t ninfo) { int ret = -1; virJSONValuePtr cmd = NULL; virJSONValuePtr reply = NULL; virJSONValuePtr cpus = NULL; virJSONValuePtr cpu = NULL; size_t i; /* create the key data array */ if (!(cpus = virJSONValueNewArray())) goto cleanup; for (i = 0; i < ninfo; i++) { qemuAgentCPUInfoPtr in = &info[i]; /* create single cpu object */ if (!(cpu = virJSONValueNewObject())) goto cleanup; if (virJSONValueObjectAppendNumberInt(cpu, "logical-id", in->id) < 0) goto cleanup; if (virJSONValueObjectAppendBoolean(cpu, "online", in->online) < 0) goto cleanup; if (virJSONValueArrayAppend(cpus, cpu) < 0) goto cleanup; cpu = NULL; } if (!(cmd = qemuAgentMakeCommand("guest-set-vcpus", "a:vcpus", cpus, NULL))) goto cleanup; cpus = NULL; if (qemuAgentCommand(mon, cmd, &reply, true, VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) goto cleanup; if (virJSONValueObjectGetNumberInt(reply, "return", &ret) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed return value")); } cleanup: virJSONValueFree(cmd); virJSONValueFree(reply); virJSONValueFree(cpu); virJSONValueFree(cpus); return ret; }
/** * qemuAgentSetTime: * @setTime: time to set * @sync: let guest agent to read domain's RTC (@setTime is ignored) */ int qemuAgentSetTime(qemuAgentPtr mon, long long seconds, unsigned int nseconds, bool rtcSync) { int ret = -1; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; if (rtcSync) { cmd = qemuAgentMakeCommand("guest-set-time", NULL); } else { /* guest agent expect time with nanosecond granularity. * Impressing. */ long long json_time; /* Check if we overflow. For some reason qemu doesn't handle unsigned * long long on the monitor well as it silently truncates numbers to * signed long long. Therefore we must check overflow against LLONG_MAX * not ULLONG_MAX. */ if (seconds > LLONG_MAX / 1000000000LL) { virReportError(VIR_ERR_INVALID_ARG, _("Time '%lld' is too big for guest agent"), seconds); return ret; } json_time = seconds * 1000000000LL; json_time += nseconds; cmd = qemuAgentMakeCommand("guest-set-time", "I:time", json_time, NULL); } if (!cmd) return ret; if (qemuAgentCommand(mon, cmd, &reply, true, VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) goto cleanup; ret = 0; cleanup: virJSONValueFree(cmd); virJSONValueFree(reply); return ret; }
int qemuAgentFSTrim(qemuAgentPtr mon, unsigned long long minimum) { int ret = -1; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; cmd = qemuAgentMakeCommand("guest-fstrim", "U:minimum", minimum, NULL); if (!cmd) return ret; ret = qemuAgentCommand(mon, cmd, &reply, false, VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK); virJSONValueFree(cmd); virJSONValueFree(reply); return ret; }
int qemuAgentSuspend(qemuAgentPtr mon, unsigned int target) { int ret = -1; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; cmd = qemuAgentMakeCommand(qemuAgentSuspendModeTypeToString(target), NULL); if (!cmd) return -1; mon->await_event = QEMU_AGENT_EVENT_SUSPEND; ret = qemuAgentCommand(mon, cmd, &reply, false, VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK); virJSONValueFree(cmd); virJSONValueFree(reply); return ret; }
int qemuAgentSuspend(qemuAgentPtr mon, unsigned int target) { int ret = -1; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; cmd = qemuAgentMakeCommand(qemuAgentSuspendModeTypeToString(target), NULL); if (!cmd) return -1; ret = qemuAgentCommand(mon, cmd, &reply); if (ret == 0) ret = qemuAgentCheckError(cmd, reply); virJSONValueFree(cmd); virJSONValueFree(reply); return ret; }
int qemuAgentShutdown(qemuAgentPtr mon, qemuAgentShutdownMode mode) { int ret = -1; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; cmd = qemuAgentMakeCommand("guest-shutdown", "s:mode", qemuAgentShutdownModeTypeToString(mode), NULL); if (!cmd) return -1; ret = qemuAgentCommand(mon, cmd, &reply); if (ret == 0) ret = qemuAgentCheckError(cmd, reply); virJSONValueFree(cmd); virJSONValueFree(reply); return ret; }
/* * qemuAgentFSFreeze: * @mon: Agent * @mountpoints: Array of mountpoint paths to be frozen, or NULL for all * @nmountpoints: Number of mountpoints to be frozen, or 0 for all * * Issue guest-fsfreeze-freeze command to guest agent, * which freezes file systems mounted on specified mountpoints * (or all file systems when @mountpoints is NULL), and returns * number of frozen file systems on success. * * Returns: number of file system frozen on success, * -1 on error. */ int qemuAgentFSFreeze(qemuAgentPtr mon, const char **mountpoints, unsigned int nmountpoints) { int ret = -1; virJSONValuePtr cmd, arg = NULL; virJSONValuePtr reply = NULL; if (mountpoints && nmountpoints) { arg = qemuAgentMakeStringsArray(mountpoints, nmountpoints); if (!arg) return -1; cmd = qemuAgentMakeCommand("guest-fsfreeze-freeze-list", "a:mountpoints", arg, NULL); } else { cmd = qemuAgentMakeCommand("guest-fsfreeze-freeze", NULL); } if (!cmd) goto cleanup; arg = NULL; if (qemuAgentCommand(mon, cmd, &reply, true, VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) goto cleanup; if (virJSONValueObjectGetNumberInt(reply, "return", &ret) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed return value")); } cleanup: virJSONValueFree(arg); virJSONValueFree(cmd); virJSONValueFree(reply); return ret; }
int qemuAgentGetTime(qemuAgentPtr mon, long long *seconds, unsigned int *nseconds) { int ret = -1; unsigned long long json_time; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; cmd = qemuAgentMakeCommand("guest-get-time", NULL); if (!cmd) return ret; if (qemuAgentCommand(mon, cmd, &reply, true, VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) goto cleanup; if (virJSONValueObjectGetNumberUlong(reply, "return", &json_time) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("malformed return value")); goto cleanup; } /* guest agent returns time in nanoseconds, * we need it in seconds here */ *seconds = json_time / 1000000000LL; *nseconds = json_time % 1000000000LL; ret = 0; cleanup: virJSONValueFree(cmd); virJSONValueFree(reply); return ret; }
int qemuAgentGetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr *info) { int ret = -1; int i; virJSONValuePtr cmd; virJSONValuePtr reply = NULL; virJSONValuePtr data = NULL; int ndata; if (!(cmd = qemuAgentMakeCommand("guest-get-vcpus", NULL))) return -1; if (qemuAgentCommand(mon, cmd, &reply, VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0 || qemuAgentCheckError(cmd, reply) < 0) goto cleanup; if (!(data = virJSONValueObjectGet(reply, "return"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("guest-get-vcpus reply was missing return data")); goto cleanup; } if (data->type != VIR_JSON_TYPE_ARRAY) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("guest-get-vcpus return information was not an array")); goto cleanup; } ndata = virJSONValueArraySize(data); if (VIR_ALLOC_N(*info, ndata) < 0) { virReportOOMError(); goto cleanup; } for (i = 0; i < ndata; i++) { virJSONValuePtr entry = virJSONValueArrayGet(data, i); qemuAgentCPUInfoPtr in = *info + i; if (!entry) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("array element missing in guest-get-vcpus return " "value")); goto cleanup; } if (virJSONValueObjectGetNumberUint(entry, "logical-id", &in->id) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("'logical-id' missing in reply of guest-get-vcpus")); goto cleanup; } if (virJSONValueObjectGetBoolean(entry, "online", &in->online) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("'online' missing in reply of guest-get-vcpus")); goto cleanup; } if (virJSONValueObjectGetBoolean(entry, "can-offline", &in->offlinable) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("'can-offline' missing in reply of guest-get-vcpus")); goto cleanup; } } ret = ndata; cleanup: virJSONValueFree(cmd); virJSONValueFree(reply); return ret; }