[libvirt] [PATCH 08/10] vcpubandwidth: implement the remote protocol to address the new API

Wen Congyang wency at cn.fujitsu.com
Thu Jun 30 03:14:59 UTC 2011


---
 daemon/remote.c              |  132 ++++++++++++++++++++++++++++++++++++++++++
 src/remote/remote_driver.c   |   64 ++++++++++++++++++++
 src/remote/remote_protocol.x |   32 ++++++++++-
 src/rpc/gendispatch.pl       |   30 ++++++++++
 4 files changed, 257 insertions(+), 1 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 9e6cf77..c83a8fa 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -100,6 +100,17 @@ remoteDeserializeTypedParameters(remote_typed_param *args_params_val,
                                  u_int args_params_len,
                                  int limit,
                                  int *nparams);
+static int
+remoteSerializeVcpuBandwidth(virDomainVcpuBWDefPtr vcpubw,
+                             int nvcpubw,
+                             remote_vcpu_bandwidth **args_vcpubw_val,
+                             u_int *args_vcpubw_len);
+static virDomainVcpuBWDefPtr
+remoteDeserializeVcpuBandwidth(remote_vcpu_bandwidth *ret_vcpubw_val,
+                               u_int ret_vcpubw_len,
+                               int limit,
+                               int *nvcpubw);
+
 
 #include "remote_dispatch.h"
 #include "qemu_dispatch.h"
@@ -2857,6 +2868,127 @@ cleanup:
 }
 
 
+/* Helper to serialize vcpu bandwidth. */
+static int remoteSerializeVcpuBandwidth(virDomainVcpuBWDefPtr vcpubw,
+                                        int nvcpubw,
+                                        remote_vcpu_bandwidth **ret_vcpubw_val,
+                                        u_int *ret_vcpubw_len)
+{
+    int i;
+    int rv = -1;
+    remote_vcpu_bandwidth *val;
+
+    if (VIR_ALLOC_N(val, nvcpubw) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    for (i = 0; i < nvcpubw; i++) {
+        val[i].vcpuid = vcpubw[i].vcpuid;
+        val[i].period = vcpubw[i].period;
+        val[i].quota = vcpubw[i].quota;
+    }
+
+    *ret_vcpubw_val = val;
+    *ret_vcpubw_len = nvcpubw;
+    val = NULL;
+    rv = 0;
+
+cleanup:
+    VIR_FREE(val);
+    return rv;
+}
+
+
+/* Helper to deserialize vcpu bandwidth. */
+static virDomainVcpuBWDefPtr
+remoteDeserializeVcpuBandwidth(remote_vcpu_bandwidth *args_vcpubw_val,
+                               u_int args_vcpubw_len,
+                               int limit,
+                               int *nvcpubw)
+{
+    int i;
+    virDomainVcpuBWDefPtr vcpubw = NULL;
+
+    /* Check the length of the returned list carefully. */
+    if (args_vcpubw_len > limit) {
+        virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
+                    _("returned number of vcpubw exceeds limit"));
+        goto cleanup;
+    }
+    if (VIR_ALLOC_N(vcpubw, args_vcpubw_len) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    /* Deserialise the result. */
+    for (i = 0; i < args_vcpubw_len; i++) {
+        vcpubw[i].vcpuid = args_vcpubw_val[i].vcpuid;
+        vcpubw[i].period = args_vcpubw_val[i].period;
+        vcpubw[i].quota = args_vcpubw_val[i].quota;
+    }
+
+    *nvcpubw = args_vcpubw_len;
+
+cleanup:
+    return vcpubw;
+}
+
+
+static int
+remoteDispatchDomainGetVcpuBW(virNetServerPtr server ATTRIBUTE_UNUSED,
+                              virNetServerClientPtr client ATTRIBUTE_UNUSED,
+                              virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+                              virNetMessageErrorPtr rerr,
+                              remote_domain_get_vcpu_b_w_args *args,
+                              remote_domain_get_vcpu_b_w_ret *ret)
+{
+    virDomainPtr dom = NULL;
+    virDomainVcpuBWDefPtr vcpubw = NULL;
+    int nvcpubw = args->nvcpubw_list;
+    int rv = -1;
+    struct daemonClientPrivate *priv =
+        virNetServerClientGetPrivateData(client);
+
+    if (!priv->conn) {
+        virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+        goto cleanup;
+    }
+
+    if (nvcpubw > REMOTE_DOMAIN_VCPU_MAX) {
+        virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("nvcpubw too large"));
+        goto cleanup;
+    }
+    if (VIR_ALLOC_N(vcpubw, nvcpubw) < 0)
+        goto no_memory;
+
+    if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
+        goto cleanup;
+
+    if (virDomainGetVcpuBW(dom, vcpubw, &nvcpubw, args->flags) < 0)
+        goto cleanup;
+
+    if (remoteSerializeVcpuBandwidth(vcpubw, nvcpubw,
+                                     &ret->vcpubw_list.vcpubw_list_val,
+                                     &ret->vcpubw_list.vcpubw_list_len) < 0)
+        goto cleanup;
+
+    rv = 0;
+
+cleanup:
+    if (rv < 0)
+        virNetMessageSaveError(rerr);
+    if (dom)
+        virDomainFree(dom);
+    VIR_FREE(vcpubw);
+    return rv;
+
+no_memory:
+    virReportOOMError();
+    goto cleanup;
+}
+
+
 /*----- Helpers. -----*/
 
 /* get_nonnull_domain and get_nonnull_network turn an on-wire
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 0e68bc5..fe3a4ab 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -1317,6 +1317,68 @@ cleanup:
     return rv;
 }
 
+/* Helper to serialize vcpu bandwidth. */
+static int remoteSerializeVcpuBandwidth(virDomainVcpuBWDefPtr vcpubw,
+                                        int nvcpubw,
+                                        remote_vcpu_bandwidth **args_vcpubw_val,
+                                        u_int *args_vcpubw_len)
+{
+    int i;
+    int rv = -1;
+    remote_vcpu_bandwidth *val;
+
+    if (VIR_ALLOC_N(val, nvcpubw) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    for (i = 0; i < nvcpubw; i++) {
+        val[i].vcpuid = vcpubw[i].vcpuid;
+        val[i].period = vcpubw[i].period;
+        val[i].quota = vcpubw[i].quota;
+    }
+
+    *args_vcpubw_val = val;
+    *args_vcpubw_len = nvcpubw;
+    val = NULL;
+    rv = 0;
+
+cleanup:
+    VIR_FREE(val);
+    return rv;
+}
+
+/* Helper to deserialize vcpu bandwidth. */
+static int remoteDeserializeVcpuBandwidth(remote_vcpu_bandwidth *ret_vcpubw_val,
+                                          u_int ret_vcpubw_len,
+                                          int limit,
+                                          virDomainVcpuBWDefPtr vcpubw,
+                                          int *nvcpubw)
+{
+    int i;
+    int rv = -1;
+
+    /* Check the length of the returned list carefully. */
+    if (ret_vcpubw_len > limit || ret_vcpubw_len > *nvcpubw) {
+        remoteError(VIR_ERR_RPC, "%s",
+                    _("returned number of vcpubw exceeds limit"));
+        goto cleanup;
+    }
+
+    /* Deserialise the result. */
+    for (i = 0; i < ret_vcpubw_len; i++) {
+        vcpubw[i].vcpuid = ret_vcpubw_val[i].vcpuid;
+        vcpubw[i].period = ret_vcpubw_val[i].period;
+        vcpubw[i].quota = ret_vcpubw_val[i].quota;
+    }
+
+    rv = 0;
+    *nvcpubw = ret_vcpubw_len;
+
+cleanup:
+    return rv;
+}
+
 static int
 remoteDomainGetMemoryParameters (virDomainPtr domain,
                                  virTypedParameterPtr params, int *nparams,
@@ -4234,6 +4296,8 @@ static virDriver remote_driver = {
     .domainMigrateFinish3 = remoteDomainMigrateFinish3, /* 0.9.2 */
     .domainMigrateConfirm3 = remoteDomainMigrateConfirm3, /* 0.9.2 */
     .domainSendKey = remoteDomainSendKey, /* 0.9.3 */
+    .domainGetVcpuBW = remoteDomainGetVcpuBW, /* 0.9.4 */
+    .domainSetVcpuBW = remoteDomainSetVcpuBW, /* 0.9.4 */
 };
 
 static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 7c3539c..3771ed1 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -193,6 +193,11 @@ const REMOTE_CPU_BASELINE_MAX = 256;
  */
 const REMOTE_DOMAIN_SEND_KEY_MAX = 16;
 
+/*
+ * Max number of vcpu
+ */
+const REMOTE_DOMAIN_VCPU_MAX = 4096;
+
 /* UUID.  VIR_UUID_BUFLEN definition comes from libvirt.h */
 typedef opaque remote_uuid[VIR_UUID_BUFLEN];
 
@@ -331,6 +336,12 @@ struct remote_node_get_memory_stats {
     unsigned hyper value;
 };
 
+struct remote_vcpu_bandwidth {
+    int vcpuid;
+    uint64_t period;
+    int64_t quota;
+};
+
 /*----- Calls. -----*/
 
 /* For each call we may have a 'remote_CALL_args' and 'remote_CALL_ret'
@@ -2115,6 +2126,22 @@ struct remote_domain_get_control_info_ret { /* insert at 1 */
     unsigned hyper stateTime;
 };
 
+struct remote_domain_get_vcpu_b_w_args {
+    remote_nonnull_domain dom;
+    int nvcpubw_list; /* call-by-reference */
+    unsigned int flags;
+};
+
+struct remote_domain_get_vcpu_b_w_ret {
+    remote_vcpu_bandwidth vcpubw_list<REMOTE_DOMAIN_VCPU_MAX>; /* insert at 1 */
+};
+
+struct remote_domain_set_vcpu_b_w_args {
+    remote_nonnull_domain dom;
+    remote_vcpu_bandwidth vcpubw_list<REMOTE_DOMAIN_VCPU_MAX>;
+    unsigned int flags;
+};
+
 /*----- Protocol. -----*/
 
 /* Define the program number, protocol version and procedure numbers here. */
@@ -2383,7 +2410,10 @@ enum remote_procedure {
     REMOTE_PROC_NODE_GET_CPU_STATS = 227, /* skipgen skipgen */
     REMOTE_PROC_NODE_GET_MEMORY_STATS = 228, /* skipgen skipgen */
     REMOTE_PROC_DOMAIN_GET_CONTROL_INFO = 229, /* autogen autogen */
-    REMOTE_PROC_DOMAIN_GET_VCPU_PIN_INFO = 230  /* skipgen skipgen */
+    REMOTE_PROC_DOMAIN_GET_VCPU_PIN_INFO = 230, /* skipgen skipgen */
+
+    REMOTE_PROC_DOMAIN_GET_VCPU_B_W = 231, /* skipgen autogen */
+    REMOTE_PROC_DOMAIN_SET_VCPU_B_W = 232  /* autogen autogen */
 
     /*
      * Notice how the entries are grouped in sets of 10 ?
diff --git a/src/rpc/gendispatch.pl b/src/rpc/gendispatch.pl
index 027560c..7ea1c52 100755
--- a/src/rpc/gendispatch.pl
+++ b/src/rpc/gendispatch.pl
@@ -423,6 +423,17 @@ elsif ($opt_b) {
                                         "                                                   &n$1)) == NULL)\n" .
                                         "        goto cleanup;\n");
                     push(@free_list, "    VIR_FREE(params);");
+                } elsif ($args_member =~ m/^remote_vcpu_bandwidth (\S+)<(\S+)>;/) {
+                    push(@vars_list, "virDomainVcpuBWDefPtr $1 = NULL");
+                    push(@vars_list, "int n$1");
+                    push(@args_list, "$1");
+                    push(@args_list, "n$1");
+                    push(@getters_list, "    if (($1 = remoteDeserializeVcpuBandwidth(args->$1.$1_val,\n" .
+                                        "                                                      args->$1.$1_len,\n" .
+                                        "                                                      $2,\n" .
+                                        "                                                      &n$1)) == NULL)\n" .
+                                        "        goto cleanup;\n");
+                    push(@free_list, "    VIR_FREE(vcpubw_list);");
                 } elsif ($args_member =~ m/<\S+>;/ or $args_member =~ m/\[\S+\];/) {
                     # just make all other array types fail
                     die "unhandled type for argument value: $args_member";
@@ -1099,6 +1110,13 @@ elsif ($opt_k) {
                                          "        xdr_free((xdrproc_t)xdr_$call->{args}, (char *)&args);\n" .
                                          "        goto done;\n" .
                                          "    }");
+                } elsif ($args_member =~ m/^remote_vcpu_bandwidth (\S+)<(\S+)>;/) {
+                    push(@args_list, "virDomainVcpuBWDefPtr $1");
+                    push(@args_list, "int n$1");
+                    push(@setters_list2, "if (remoteSerializeVcpuBandwidth($1, n$1, &args.$1.$1_val, &args.$1.$1_len) < 0) {\n" .
+                                         "        xdr_free((xdrproc_t)xdr_$call->{args}, (char *)&args);\n" .
+                                         "        goto done;\n" .
+                                         "    }");
                 } elsif ($args_member =~ m/^((?:unsigned )?int) (\S+);\s*\/\*\s*call-by-reference\s*\*\//) {
                     my $type_name = "$1 *";
                     my $arg_name = $2;
@@ -1264,6 +1282,18 @@ elsif ($opt_k) {
                 } elsif ($ret_member =~ m/^remote_typed_param (\S+)<\S+>;/) {
                     # error out on unannotated arrays
                     die "remote_typed_param array without insert@<offset> annotation: $ret_member";
+                } elsif ($ret_member =~ m/^remote_vcpu_bandwidth (\S+)<(\S+)>;\s*\/\*\s*insert@(\d+)\s*\*\//) {
+                    splice(@args_list, int($3), 0, ("virDomainVcpuBWDefPtr $1"));
+                    push(@ret_list2, "if (remoteDeserializeVcpuBandwidth(ret.$1.$1_val,\n" .
+                                     "                                       ret.$1.$1_len,\n" .
+                                     "                                       $2,\n" .
+                                     "                                       $1,\n" .
+                                     "                                       n$1) < 0)\n" .
+                                     "        goto cleanup;\n");
+                    $single_ret_cleanup = 1;
+                } elsif ($ret_member =~ m/^remote_vcpu_bandwidth (\S+)<\S+>;/) {
+                    # error out on unannotated arrays
+                    die "remote_vcpu_bandwidth array without insert@<offset> annotation: $ret_member";
                 } elsif ($ret_member =~ m/^int (\S+);/) {
                     my $arg_name = $1;
 
-- 
1.7.1




More information about the libvir-list mailing list