[libvirt] [PATCH 01/12] Introduce virNodeHugeTLB

Michal Privoznik mprivozn at redhat.com
Thu May 29 08:32:35 UTC 2014


The API queries huge page info in the host and reports it back
to the caller. This may be handy for management application to
decide whether to run a domain with huge pages enabled or not.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 daemon/remote.c              | 54 ++++++++++++++++++++++++++++++++++++++++++++
 include/libvirt/libvirt.h.in |  6 +++++
 src/driver.h                 |  7 ++++++
 src/libvirt.c                | 54 ++++++++++++++++++++++++++++++++++++++++++++
 src/libvirt_public.syms      |  5 ++++
 src/remote/remote_driver.c   | 48 +++++++++++++++++++++++++++++++++++++++
 src/remote/remote_protocol.x | 19 +++++++++++++++-
 src/remote_protocol-structs  | 13 +++++++++++
 8 files changed, 205 insertions(+), 1 deletion(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 34c96c9..95ff973 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -6115,6 +6115,60 @@ remoteDispatchDomainGetTime(virNetServerPtr server ATTRIBUTE_UNUSED,
     return rv;
 }
 
+static int remoteDispatchNodeHugeTlb(virNetServerPtr server ATTRIBUTE_UNUSED,
+                                     virNetServerClientPtr client,
+                                     virNetMessagePtr msg ATTRIBUTE_UNUSED,
+                                     virNetMessageErrorPtr rerr,
+                                     remote_node_huge_tlb_args *args,
+                                     remote_node_huge_tlb_ret *ret)
+{
+    virTypedParameterPtr params = NULL;
+    int nparams = 0;
+    int rv = -1;
+    struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
+
+    if (!priv->conn) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+        goto cleanup;
+    }
+
+    if (args->nparams > REMOTE_NODE_MEMORY_PARAMETERS_MAX) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
+        goto cleanup;
+    }
+    if (args->nparams && VIR_ALLOC_N(params, args->nparams) < 0)
+        goto cleanup;
+    nparams = args->nparams;
+
+    if (virNodeHugeTLB(priv->conn, args->type, params, &nparams, args->flags) < 0)
+        goto cleanup;
+
+    /* In this case, we need to send back the number of parameters
+     * supported
+     */
+    if (args->nparams == 0) {
+        ret->nparams = nparams;
+        goto success;
+    }
+
+    if (remoteSerializeTypedParameters(params, nparams,
+                                       &ret->params.params_val,
+                                       &ret->params.params_len,
+                                       args->flags) < 0)
+        goto cleanup;
+
+
+ success:
+    rv = 0;
+
+ cleanup:
+    if (rv < 0)
+        virNetMessageSaveError(rerr);
+    virTypedParamsFree(params, nparams);
+    return rv;
+}
+
+
 /*----- Helpers. -----*/
 
 /* get_nonnull_domain and get_nonnull_network turn an on-wire
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 260c971..cb1cad9 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -858,6 +858,12 @@ int virNodeSetMemoryParameters(virConnectPtr conn,
                                int nparams,
                                unsigned int flags);
 
+int virNodeHugeTLB(virConnectPtr conn,
+                   int type,
+                   virTypedParameterPtr params,
+                   int *nparams,
+                   unsigned int flags);
+
 /*
  *  node CPU map
  */
diff --git a/src/driver.h b/src/driver.h
index 5ac89d6..4acde08 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -1070,6 +1070,12 @@ typedef int
                                  virTypedParameterPtr params,
                                  int nparams,
                                  unsigned int flags);
+typedef int
+(*virDrvNodeHugeTLB)(virConnectPtr conn,
+                     int type,
+                     virTypedParameterPtr params,
+                     int *nparams,
+                     unsigned int flags);
 
 typedef int
 (*virDrvNodeGetCPUMap)(virConnectPtr conn,
@@ -1376,6 +1382,7 @@ struct _virDriver {
     virDrvDomainGetMetadata domainGetMetadata;
     virDrvNodeGetMemoryParameters nodeGetMemoryParameters;
     virDrvNodeSetMemoryParameters nodeSetMemoryParameters;
+    virDrvNodeHugeTLB nodeHugeTLB;
     virDrvNodeGetCPUMap nodeGetCPUMap;
     virDrvDomainFSTrim domainFSTrim;
     virDrvDomainSendProcessSignal domainSendProcessSignal;
diff --git a/src/libvirt.c b/src/libvirt.c
index f01b6dd..de20b0c 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -7561,6 +7561,60 @@ virNodeSetMemoryParameters(virConnectPtr conn,
 
 
 /**
+ * virNodeHugeTLB:
+ * @conn: pointer to the hypervisor connection
+ * @type: type
+ * @params: pointer to memory parameter object
+ *          (return value, allocated by the caller)
+ * @nparams: pointer to number of memory parameters; input and output
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Get information about host's huge pages. On input, @nparams
+ * gives the size of the @params array; on output, @nparams gives
+ * how many slots were filled with parameter information, which
+ * might be less but will not exceed the input value.
+ *
+ * As a special case, calling with @params as NULL and @nparams
+ * as 0 on input will cause @nparams on output to contain the
+ * number of parameters supported by the hypervisor. The caller
+ * should then allocate @params array, i.e.
+ * (sizeof(@virTypedParameter) * @nparams) bytes and call the API
+ * again.  See virDomainGetMemoryParameters() for an equivalent
+ * usage example.
+ *
+ * Returns 0 in case of success, and -1 in case of failure.
+ */
+int
+virNodeHugeTLB(virConnectPtr conn,
+               int type,
+               virTypedParameterPtr params,
+               int *nparams,
+               unsigned int flags)
+{
+    VIR_DEBUG("conn=%p, type=%d, params=%p, nparams=%p, flags=%x",
+              conn, type, params, nparams, flags);
+
+    virResetLastError();
+
+    virCheckNonNullArgGoto(nparams, error);
+    virCheckNonNegativeArgGoto(*nparams, error);
+
+    if (conn->driver->nodeHugeTLB) {
+        int ret;
+        ret = conn->driver->nodeHugeTLB(conn, type, params, nparams, flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+    virReportUnsupportedError();
+
+ error:
+    virDispatchError(conn);
+    return -1;
+}
+
+
+/**
  * virDomainGetSchedulerType:
  * @domain: pointer to domain object
  * @nparams: pointer to number of scheduler parameters, can be NULL
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index cce6bdf..0339e70 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -658,5 +658,10 @@ LIBVIRT_1.2.5 {
         virDomainSetTime;
 } LIBVIRT_1.2.3;
 
+LIBVIRT_1.2.6 {
+    global:
+        virNodeHugeTLB;
+} LIBVIRT_1.2.5;
+
 
 # .... define new API here using predicted next version number ....
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 85fe597..9136b78 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -7469,6 +7469,53 @@ remoteDomainGetTime(virDomainPtr dom,
 }
 
 
+static int
+remoteNodeHugeTLB(virConnectPtr conn,
+                  int type,
+                  virTypedParameterPtr params,
+                  int *nparams,
+                  unsigned int flags)
+{
+    int rv = -1;
+    remote_node_huge_tlb_args args;
+    remote_node_huge_tlb_ret ret;
+    struct private_data *priv = conn->privateData;
+
+    remoteDriverLock(priv);
+
+    args.type = type;
+    args.nparams = *nparams;
+    args.flags = flags;
+
+    memset(&ret, 0, sizeof(ret));
+    if (call(conn, priv, 0, REMOTE_PROC_NODE_HUGE_TLB,
+             (xdrproc_t) xdr_remote_node_huge_tlb_args, (char *) &args,
+             (xdrproc_t) xdr_remote_node_huge_tlb_ret, (char *) &ret) == -1)
+        goto done;
+
+    if (*nparams == 0) {
+        *nparams = ret.nparams;
+        rv = 0;
+        goto cleanup;
+    }
+
+    if (remoteDeserializeTypedParameters(ret.params.params_val,
+                                         ret.params.params_len,
+                                         REMOTE_NODE_MEMORY_PARAMETERS_MAX,
+                                         &params,
+                                         nparams) < 0)
+        goto cleanup;
+
+    rv = 0;
+
+ cleanup:
+    xdr_free((xdrproc_t) xdr_remote_node_huge_tlb_ret, (char *) &ret);
+ done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
+
 /* get_nonnull_domain and get_nonnull_network turn an on-wire
  * (name, uuid) pair into virDomainPtr or virNetworkPtr object.
  * These can return NULL if underlying memory allocations fail,
@@ -7805,6 +7852,7 @@ static virDriver remote_driver = {
     .domainFSThaw = remoteDomainFSThaw, /* 1.2.5 */
     .domainGetTime = remoteDomainGetTime, /* 1.2.5 */
     .domainSetTime = remoteDomainSetTime, /* 1.2.5 */
+    .nodeHugeTLB = remoteNodeHugeTLB, /* 1.2.6 */
 };
 
 static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 1f9d583..4d6cc15 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -2836,6 +2836,17 @@ struct remote_node_get_memory_parameters_ret {
     int nparams;
 };
 
+struct remote_node_huge_tlb_args {
+    int type;
+    int nparams;
+    unsigned int flags;
+};
+
+struct remote_node_huge_tlb_ret {
+    remote_typed_param params<REMOTE_NODE_MEMORY_PARAMETERS_MAX>;
+    int nparams;
+};
+
 struct remote_node_get_cpu_map_args {
     int need_map;
     int need_online;
@@ -5338,5 +5349,11 @@ enum remote_procedure {
      * @generate: both
      * @acl: domain:set_time
      */
-    REMOTE_PROC_DOMAIN_SET_TIME = 338
+    REMOTE_PROC_DOMAIN_SET_TIME = 338,
+
+    /**
+     * @generate: none
+     * @acl: connect:read
+     */
+    REMOTE_PROC_NODE_HUGE_TLB = 339
 };
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 5b22049..e3fcdea 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -2271,6 +2271,18 @@ struct remote_node_get_memory_parameters_ret {
         } params;
         int                        nparams;
 };
+struct remote_node_huge_tlb_args {
+        int                        type;
+        int                        nparams;
+        u_int                      flags;
+};
+struct remote_node_huge_tlb_ret {
+        struct {
+                u_int              params_len;
+                remote_typed_param * params_val;
+        } params;
+        int                        nparams;
+};
 struct remote_node_get_cpu_map_args {
         int                        need_map;
         int                        need_online;
@@ -2802,4 +2814,5 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_FSTHAW = 336,
         REMOTE_PROC_DOMAIN_GET_TIME = 337,
         REMOTE_PROC_DOMAIN_SET_TIME = 338,
+        REMOTE_PROC_NODE_HUGE_TLB = 339,
 };
-- 
1.9.3




More information about the libvir-list mailing list