]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Remote protocol for virDomainGetDiskErrors
authorJiri Denemark <jdenemar@redhat.com>
Tue, 31 Jan 2012 06:42:31 +0000 (07:42 +0100)
committerJiri Denemark <jdenemar@redhat.com>
Wed, 1 Feb 2012 09:50:58 +0000 (10:50 +0100)
daemon/remote.c
src/remote/remote_driver.c
src/remote/remote_protocol.x
src/remote_protocol-structs

index e7d9b2fd9f0be00f206662bfa1654f5881d9c34e..8fbcf43b63329e3ba89ed169db3853af862d6c06 100644 (file)
@@ -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"
 
@@ -3591,6 +3597,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
@@ -3721,3 +3790,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;
+}
index 031becda671b7217aa4ac1585eb70fa440bcb048..09b5ace66675e294c66751abc8680cd621b14211 100644 (file)
@@ -1423,6 +1423,39 @@ cleanup:
     return rv;
 }
 
+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,
@@ -4438,6 +4471,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"
 
@@ -4840,6 +4916,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 = {
index b2c84261af4c699a00efb61ea99275128eeb9fd7..10fd2940a885961f12beeb4441dea519448f18bb 100644 (file)
@@ -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 ?
index e9137a90b9a0ec6592a30e81b7304c5d9dabd824..ee2207ca5261a4247610c44ec08f70532b39bf44 100644 (file)
@@ -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,
 };