File libvirt-qemu_agent-Introduce-helpers-for-agent-based-CPU-hot-un-plug.patch of Package libvirt

From bd3a57a36751b7b81184eba6729027bc1e46eb2b Mon Sep 17 00:00:00 2001
Message-Id: <bd3a57a36751b7b81184eba6729027bc1e46eb2b.1373885146.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 13 Jun 2013 15:52:09 +0200
Subject: [PATCH] qemu_agent: Introduce helpers for agent based CPU hot(un)plug

https://bugzilla.redhat.com/show_bug.cgi?id=924400

The qemu guest agent allows to online and offline CPUs from the
perspective of the guest. This patch adds helpers that call
'guest-get-vcpus' and 'guest-set-vcpus' guest agent functions and
convert the data for internal libvirt usage.
(cherry picked from commit 3099c063e348fdc79a900f88bcfc5389dada7786)

Conflicts:
	src/qemu/qemu_agent.h - context: guestFStrim not backported
---
 src/qemu/qemu_agent.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_agent.h |  11 ++++
 2 files changed, 159 insertions(+)

diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
index 488aa99..46fafa1 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -1447,3 +1447,151 @@ qemuAgentArbitraryCommand(qemuAgentPtr mon,
     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);
+    virJSONValueFree(data);
+    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 no_memory;
+
+    for (i = 0; i < ninfo; i++) {
+        qemuAgentCPUInfoPtr in = &info[i];
+
+        /* create single cpu object */
+        if (!(cpu = virJSONValueNewObject()))
+            goto no_memory;
+
+        if (virJSONValueObjectAppendNumberInt(cpu, "logical-id", in->id) < 0)
+            goto no_memory;
+
+        if (virJSONValueObjectAppendBoolean(cpu, "online", in->online) < 0)
+            goto no_memory;
+
+        if (virJSONValueArrayAppend(cpus, cpu) < 0)
+            goto no_memory;
+
+        cpu = NULL;
+    }
+
+    if (!(cmd = qemuAgentMakeCommand("guest-set-vcpus",
+                                     "a:vcpus", cpus,
+                                     NULL)))
+        goto cleanup;
+
+    cpus = NULL;
+
+    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);
+    virJSONValueFree(cpu);
+    virJSONValueFree(cpus);
+    return ret;
+
+no_memory:
+    virReportOOMError();
+    goto cleanup;
+}
diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
index c62c438..946b792 100644
--- a/src/qemu/qemu_agent.h
+++ b/src/qemu/qemu_agent.h
@@ -83,4 +83,15 @@ int qemuAgentArbitraryCommand(qemuAgentPtr mon,
                               const char *cmd,
                               char **result,
                               int timeout);
+
+typedef struct _qemuAgentCPUInfo qemuAgentCPUInfo;
+typedef qemuAgentCPUInfo *qemuAgentCPUInfoPtr;
+struct _qemuAgentCPUInfo {
+    unsigned int id;    /* logical cpu ID */
+    bool online;        /* true if the CPU is activated */
+    bool offlinable;    /* true if the CPU can be offlined */
+};
+
+int qemuAgentGetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr *info);
+int qemuAgentSetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr cpus, size_t ncpus);
 #endif /* __QEMU_AGENT_H__ */
-- 
1.8.3.2

openSUSE Build Service is sponsored by