[libvirt] [PATCH v3 2/5] Remote protocol for virDomainGetDiskErrors

Jiri Denemark jdenemar at redhat.com
Tue Jan 31 19:26:11 UTC 2012


---
 daemon/remote.c              |  103 ++++++++++++++++++++++++++++++++++++++++++
 src/remote/remote_driver.c   |   77 +++++++++++++++++++++++++++++++
 src/remote/remote_protocol.x |   23 +++++++++-
 src/remote_protocol-structs  |   17 +++++++
 4 files changed, 219 insertions(+), 1 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index cb8423a..3d7021a 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -98,6 +98,12 @@ remoteDeserializeTypedParameters(remote_typed_param *args_params_val,
                                  int limit,
                                  int *nparams);
 
+static int
+remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors,
+                                int nerrors,
+                                remote_domain_disk_error **ret_errors_val,
+                                u_int *ret_errors_len);
+
 #include "remote_dispatch.h"
 #include "qemu_dispatch.h"
 
@@ -3595,6 +3601,69 @@ cleanup:
     return rv;
 }
 
+static int remoteDispatchDomainGetDiskErrors(
+    virNetServerPtr server ATTRIBUTE_UNUSED,
+    virNetServerClientPtr client,
+    virNetMessagePtr msg ATTRIBUTE_UNUSED,
+    virNetMessageErrorPtr rerr,
+    remote_domain_get_disk_errors_args *args,
+    remote_domain_get_disk_errors_ret *ret)
+{
+    int rv = -1;
+    virDomainPtr dom = NULL;
+    virDomainDiskErrorPtr errors = NULL;
+    int len;
+    struct daemonClientPrivate *priv =
+        virNetServerClientGetPrivateData(client);
+
+    if (!priv->conn) {
+        virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+        goto cleanup;
+    }
+
+    if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
+        goto cleanup;
+
+    if (args->maxerrors > REMOTE_DOMAIN_DISK_ERRORS_MAX) {
+        virNetError(VIR_ERR_INTERNAL_ERROR, "%s",
+                    _("maxerrors too large"));
+        goto cleanup;
+    }
+
+    if (args->maxerrors &&
+        VIR_ALLOC_N(errors, args->maxerrors) < 0) {
+        virReportOOMError();
+        goto cleanup;
+    }
+
+    if ((len = virDomainGetDiskErrors(dom, errors,
+                                      args->maxerrors,
+                                      args->flags)) < 0)
+        goto cleanup;
+
+    ret->nerrors = len;
+    if (errors &&
+        remoteSerializeDomainDiskErrors(errors, len,
+                                        &ret->errors.errors_val,
+                                        &ret->errors.errors_len) < 0)
+        goto cleanup;
+
+    rv = 0;
+
+cleanup:
+    if (rv < 0)
+        virNetMessageSaveError(rerr);
+    if (dom)
+        virDomainFree(dom);
+    if (errors) {
+        int i;
+        for (i = 0; i < len; i++)
+            VIR_FREE(errors[i].disk);
+    }
+    VIR_FREE(errors);
+    return rv;
+}
+
 /*----- Helpers. -----*/
 
 /* get_nonnull_domain and get_nonnull_network turn an on-wire
@@ -3725,3 +3794,37 @@ make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDo
     snapshot_dst->name = strdup(snapshot_src->name);
     make_nonnull_domain(&snapshot_dst->dom, snapshot_src->domain);
 }
+
+static int
+remoteSerializeDomainDiskErrors(virDomainDiskErrorPtr errors,
+                                int nerrors,
+                                remote_domain_disk_error **ret_errors_val,
+                                u_int *ret_errors_len)
+{
+    remote_domain_disk_error *val = NULL;
+    int i = 0;
+
+    if (VIR_ALLOC_N(val, nerrors) < 0)
+        goto no_memory;
+
+    for (i = 0; i < nerrors; i++) {
+        if (!(val[i].disk = strdup(errors[i].disk)))
+            goto no_memory;
+        val[i].error = errors[i].error;
+    }
+
+    *ret_errors_len = nerrors;
+    *ret_errors_val = val;
+
+    return 0;
+
+no_memory:
+    if (val) {
+        int j;
+        for (j = 0; j < i; j++)
+            VIR_FREE(val[j].disk);
+        VIR_FREE(val);
+    }
+    virReportOOMError();
+    return -1;
+}
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 61b96e9..9c3dbab 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -1427,6 +1427,39 @@ cleanup:
 }
 
 static int
+remoteDeserializeDomainDiskErrors(remote_domain_disk_error *ret_errors_val,
+                                  u_int ret_errors_len,
+                                  int limit,
+                                  virDomainDiskErrorPtr errors,
+                                  int maxerrors)
+{
+    int i = 0;
+    int j;
+
+    if (ret_errors_len > limit || ret_errors_len > maxerrors) {
+        remoteError(VIR_ERR_RPC, "%s",
+                    _("returned number of disk errors exceeds limit"));
+        goto error;
+    }
+
+    for (i = 0; i < ret_errors_len; i++) {
+        if (!(errors[i].disk = strdup(ret_errors_val[i].disk))) {
+            virReportOOMError();
+            goto error;
+        }
+        errors[i].error = ret_errors_val[i].error;
+    }
+
+    return 0;
+
+error:
+    for (j = 0; j < i; j++)
+        VIR_FREE(errors[i].disk);
+
+    return -1;
+}
+
+static int
 remoteDomainBlockStatsFlags(virDomainPtr domain,
                             const char *path,
                             virTypedParameterPtr params,
@@ -4447,6 +4480,49 @@ remoteIsAlive(virConnectPtr conn)
 }
 
 
+static int
+remoteDomainGetDiskErrors(virDomainPtr dom,
+                          virDomainDiskErrorPtr errors,
+                          unsigned int maxerrors,
+                          unsigned int flags)
+{
+    int rv = -1;
+    struct private_data *priv = dom->conn->privateData;
+    remote_domain_get_disk_errors_args args;
+    remote_domain_get_disk_errors_ret ret;
+
+    remoteDriverLock(priv);
+
+    make_nonnull_domain(&args.dom, dom);
+    args.maxerrors = maxerrors;
+    args.flags = flags;
+
+    memset(&ret, 0, sizeof ret);
+
+    if (call(dom->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_DISK_ERRORS,
+             (xdrproc_t) xdr_remote_domain_get_disk_errors_args,
+             (char *) &args,
+             (xdrproc_t) xdr_remote_domain_get_disk_errors_ret,
+             (char *) &ret) == -1)
+        goto done;
+
+    if (remoteDeserializeDomainDiskErrors(ret.errors.errors_val,
+                                          ret.errors.errors_len,
+                                          REMOTE_DOMAIN_DISK_ERRORS_MAX,
+                                          errors,
+                                          maxerrors) < 0)
+        goto cleanup;
+
+    rv = ret.nerrors;
+
+cleanup:
+    xdr_free((xdrproc_t) xdr_remote_domain_get_disk_errors_ret, (char *) &ret);
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
 #include "remote_client_bodies.h"
 #include "qemu_client_bodies.h"
 
@@ -4849,6 +4925,7 @@ static virDriver remote_driver = {
     .domainSetNumaParameters = remoteDomainSetNumaParameters, /* 0.9.9 */
     .domainGetNumaParameters = remoteDomainGetNumaParameters, /* 0.9.9 */
     .domainGetCPUStats = remoteDomainGetCPUStats, /* 0.9.10 */
+    .domainGetDiskErrors = remoteDomainGetDiskErrors, /* 0.9.10 */
 };
 
 static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index b2c8426..10fd294 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -219,6 +219,11 @@ const REMOTE_DOMAIN_GET_CPU_STATS_NCPUS_MAX = 128;
  */
 const REMOTE_DOMAIN_GET_CPU_STATS_MAX = 2048;
 
+/*
+ * Upper limit on number of disks with errors
+ */
+const REMOTE_DOMAIN_DISK_ERRORS_MAX = 256;
+
 /* UUID.  VIR_UUID_BUFLEN definition comes from libvirt.h */
 typedef opaque remote_uuid[VIR_UUID_BUFLEN];
 
@@ -359,6 +364,10 @@ struct remote_node_get_memory_stats {
     unsigned hyper value;
 };
 
+struct remote_domain_disk_error {
+    remote_nonnull_string disk;
+    int error;
+};
 
 /*----- Calls. -----*/
 
@@ -2397,6 +2406,17 @@ struct remote_domain_shutdown_flags_args {
     unsigned int flags;
 };
 
+struct remote_domain_get_disk_errors_args {
+    remote_nonnull_domain dom;
+    unsigned int maxerrors;
+    unsigned int flags;
+};
+
+struct remote_domain_get_disk_errors_ret {
+    remote_domain_disk_error errors<REMOTE_DOMAIN_DISK_ERRORS_MAX>;
+    int nerrors;
+};
+
 
 /*----- Protocol. -----*/
 
@@ -2708,7 +2728,8 @@ enum remote_procedure {
     REMOTE_PROC_STORAGE_VOL_RESIZE = 260, /* autogen autogen */
 
     REMOTE_PROC_DOMAIN_PM_SUSPEND_FOR_DURATION = 261, /* autogen autogen */
-    REMOTE_PROC_DOMAIN_GET_CPU_STATS = 262 /* skipgen skipgen */
+    REMOTE_PROC_DOMAIN_GET_CPU_STATS = 262, /* skipgen skipgen */
+    REMOTE_PROC_DOMAIN_GET_DISK_ERRORS = 263 /* skipgen skipgen */
 
     /*
      * Notice how the entries are grouped in sets of 10 ?
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index e9137a9..ee2207c 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -94,6 +94,10 @@ struct remote_node_get_memory_stats {
         remote_nonnull_string      field;
         uint64_t                   value;
 };
+struct remote_domain_disk_error {
+        remote_nonnull_string      disk;
+        int                        error;
+};
 struct remote_open_args {
         remote_string              name;
         u_int                      flags;
@@ -1866,6 +1870,18 @@ struct remote_domain_shutdown_flags_args {
         remote_nonnull_domain      dom;
         u_int                      flags;
 };
+struct remote_domain_get_disk_errors_args {
+        remote_nonnull_domain      dom;
+        u_int                      maxerrors;
+        u_int                      flags;
+};
+struct remote_domain_get_disk_errors_ret {
+        struct {
+                u_int              errors_len;
+                remote_domain_disk_error * errors_val;
+        } errors;
+        int                        nerrors;
+};
 enum remote_procedure {
         REMOTE_PROC_OPEN = 1,
         REMOTE_PROC_CLOSE = 2,
@@ -2129,4 +2145,5 @@ enum remote_procedure {
         REMOTE_PROC_STORAGE_VOL_RESIZE = 260,
         REMOTE_PROC_DOMAIN_PM_SUSPEND_FOR_DURATION = 261,
         REMOTE_PROC_DOMAIN_GET_CPU_STATS = 262,
+        REMOTE_PROC_DOMAIN_GET_DISK_ERRORS = 263,
 };
-- 
1.7.8.4




More information about the libvir-list mailing list