[libvirt] [PATCH 4/6] Add disk streaming support to the remote driver

Adam Litke agl at us.ibm.com
Wed Nov 17 19:14:01 UTC 2010


* src/remote/remote_protocol.x: provide defines for the new entry points
* src/remote/remote_driver.c daemon/remote.c: implement the client and
  server side
* daemon/remote_dispatch_args.h daemon/remote_dispatch_prototypes.h
  daemon/remote_dispatch_ret.h daemon/remote_dispatch_table.h
  src/remote/remote_protocol.c src/remote/remote_protocol.h: generated
  stubs

Signed-off-by: Adam Litke <agl at us.ibm.com>
---
 daemon/remote.c                     |   96 +++++++++++++++++++++++++++++++++++
 daemon/remote_dispatch_args.h       |    2 +
 daemon/remote_dispatch_prototypes.h |   16 ++++++
 daemon/remote_dispatch_ret.h        |    2 +
 daemon/remote_dispatch_table.h      |   10 ++++
 src/remote/remote_driver.c          |   87 +++++++++++++++++++++++++++++++-
 src/remote/remote_protocol.c        |   63 +++++++++++++++++++++++
 src/remote/remote_protocol.h        |   51 ++++++++++++++++++
 src/remote/remote_protocol.x        |   37 +++++++++++++-
 9 files changed, 361 insertions(+), 3 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 886d53d..69709b3 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -6591,6 +6591,102 @@ cleanup:
     return rc;
 }
 
+static int
+remoteDispatchDomainStreamDisk (struct qemud_server *server ATTRIBUTE_UNUSED,
+                                struct qemud_client *client ATTRIBUTE_UNUSED,
+                                virConnectPtr conn,
+                                remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                remote_error *rerr,
+                                remote_domain_stream_disk_args *args,
+                                remote_domain_stream_disk_ret *ret)
+{
+    virDomainPtr dom;
+    const char *path;
+    unsigned long long offset;
+    unsigned int flags;
+    int rc;
+
+    dom = get_nonnull_domain (conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchConnError(rerr, conn);
+        return -1;
+    }
+
+    path = args->path;
+    offset = args->offset;
+    flags = args->flags;
+
+    rc = virDomainStreamDisk(dom, path, offset, flags);
+    if (rc == (unsigned long long) -1) {
+        remoteDispatchConnError(rerr, conn);
+        return -1;
+    }
+    ret->offset = rc;
+    return 0;
+}
+
+static int
+remoteDispatchDomainStreamDiskInfo (struct qemud_server *server ATTRIBUTE_UNUSED,
+                                    struct qemud_client *client ATTRIBUTE_UNUSED,
+                                    virConnectPtr conn,
+                                    remote_message_header *hdr ATTRIBUTE_UNUSED,
+                                    remote_error *rerr,
+                                    remote_domain_stream_disk_info_args *args,
+                                    remote_domain_stream_disk_info_ret *ret)
+{
+    virDomainPtr dom;
+    struct _virStreamDiskState *states;
+    unsigned int nr_states, flags, i;
+    int nr_returned;
+
+    if (args->nr_results > REMOTE_DOMAIN_STREAM_DISK_STATES_MAX) {
+        remoteDispatchFormatError (rerr, "%s",
+                        _("nr_results > REMOTE_DOMAIN_STREAM_DISK_STATES_MAX"));
+        return -1;
+    }
+
+    dom = get_nonnull_domain (conn, args->dom);
+    if (dom == NULL) {
+        remoteDispatchConnError(rerr, conn);
+        return -1;
+    }
+
+    nr_states = args->nr_results;
+    flags = args->flags;
+
+    /* Allocate array of stats structs for making dispatch call */
+    if (VIR_ALLOC_N(states, nr_states) < 0) {
+        virDomainFree (dom);
+        remoteDispatchOOMError(rerr);
+        return -1;
+    }
+
+    nr_returned = virDomainStreamDiskInfo (dom, states, nr_states, flags);
+    virDomainFree (dom);
+    if (nr_returned < 0) {
+        VIR_FREE(states);
+        remoteDispatchConnError(rerr, conn);
+        return -1;
+    }
+
+    /* Allocate return buffer */
+    if (VIR_ALLOC_N(ret->states.states_val, nr_returned) < 0) {
+        VIR_FREE(states);
+        remoteDispatchOOMError(rerr);
+        return -1;
+    }
+
+    /* Copy the stats into the return structure */
+    ret->states.states_len = nr_returned;
+    for (i = 0; i < nr_returned; i++) {
+        ret->states.states_val[i].path.path_val = strdup(states[i].path);
+        ret->states.states_val[i].path.path_len = strlen(states[i].path);
+        ret->states.states_val[i].offset = states[i].offset;
+        ret->states.states_val[i].size = states[i].size;
+    }
+    VIR_FREE(states);
+    return 0;
+}
 
 static int
 remoteDispatchDomainEventsRegisterAny (struct qemud_server *server ATTRIBUTE_UNUSED,
diff --git a/daemon/remote_dispatch_args.h b/daemon/remote_dispatch_args.h
index 9583e9c..91cbd52 100644
--- a/daemon/remote_dispatch_args.h
+++ b/daemon/remote_dispatch_args.h
@@ -169,3 +169,5 @@
     remote_domain_get_memory_parameters_args val_remote_domain_get_memory_parameters_args;
     remote_domain_set_vcpus_flags_args val_remote_domain_set_vcpus_flags_args;
     remote_domain_get_vcpus_flags_args val_remote_domain_get_vcpus_flags_args;
+    remote_domain_stream_disk_args val_remote_domain_stream_disk_args;
+    remote_domain_stream_disk_info_args val_remote_domain_stream_disk_info_args;
diff --git a/daemon/remote_dispatch_prototypes.h b/daemon/remote_dispatch_prototypes.h
index 6b35851..491bc96 100644
--- a/daemon/remote_dispatch_prototypes.h
+++ b/daemon/remote_dispatch_prototypes.h
@@ -634,6 +634,22 @@ static int remoteDispatchDomainSnapshotNum(
     remote_error *err,
     remote_domain_snapshot_num_args *args,
     remote_domain_snapshot_num_ret *ret);
+static int remoteDispatchDomainStreamDisk(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_domain_stream_disk_args *args,
+    remote_domain_stream_disk_ret *ret);
+static int remoteDispatchDomainStreamDiskInfo(
+    struct qemud_server *server,
+    struct qemud_client *client,
+    virConnectPtr conn,
+    remote_message_header *hdr,
+    remote_error *err,
+    remote_domain_stream_disk_info_args *args,
+    remote_domain_stream_disk_info_ret *ret);
 static int remoteDispatchDomainSuspend(
     struct qemud_server *server,
     struct qemud_client *client,
diff --git a/daemon/remote_dispatch_ret.h b/daemon/remote_dispatch_ret.h
index 3723b00..84d8ba4 100644
--- a/daemon/remote_dispatch_ret.h
+++ b/daemon/remote_dispatch_ret.h
@@ -137,3 +137,5 @@
     remote_domain_create_with_flags_ret val_remote_domain_create_with_flags_ret;
     remote_domain_get_memory_parameters_ret val_remote_domain_get_memory_parameters_ret;
     remote_domain_get_vcpus_flags_ret val_remote_domain_get_vcpus_flags_ret;
+    remote_domain_stream_disk_ret val_remote_domain_stream_disk_ret;
+    remote_domain_stream_disk_info_ret val_remote_domain_stream_disk_info_ret;
diff --git a/daemon/remote_dispatch_table.h b/daemon/remote_dispatch_table.h
index dd2adc7..fac32d3 100644
--- a/daemon/remote_dispatch_table.h
+++ b/daemon/remote_dispatch_table.h
@@ -1007,3 +1007,13 @@
     .args_filter = (xdrproc_t) xdr_remote_domain_get_vcpus_flags_args,
     .ret_filter = (xdrproc_t) xdr_remote_domain_get_vcpus_flags_ret,
 },
+{   /* DomainStreamDisk => 201 */
+    .fn = (dispatch_fn) remoteDispatchDomainStreamDisk,
+    .args_filter = (xdrproc_t) xdr_remote_domain_stream_disk_args,
+    .ret_filter = (xdrproc_t) xdr_remote_domain_stream_disk_ret,
+},
+{   /* DomainStreamDiskInfo => 202 */
+    .fn = (dispatch_fn) remoteDispatchDomainStreamDiskInfo,
+    .args_filter = (xdrproc_t) xdr_remote_domain_stream_disk_info_args,
+    .ret_filter = (xdrproc_t) xdr_remote_domain_stream_disk_info_ret,
+},
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 237e03b..47705e7 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8948,6 +8948,89 @@ done:
     return rv;
 }
 
+static unsigned long long
+remoteDomainStreamDisk(virDomainPtr domain, const char *path,
+                       unsigned long long offset, unsigned int flags)
+{
+    unsigned long long rv = (unsigned long long) -1;
+
+    remote_domain_stream_disk_args args;
+    remote_domain_stream_disk_ret ret;
+    struct private_data *priv = domain->conn->privateData;
+
+    args.offset = offset;
+    args.flags = flags;
+    args.path = strdup(path);
+    if (args.path == NULL) {
+        virReportOOMError();
+        return -1;
+    }
+
+    remoteDriverLock(priv);
+    make_nonnull_domain (&args.dom, domain);
+    memset (&ret, 0, sizeof ret);
+
+    if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_STREAM_DISK,
+              (xdrproc_t) xdr_remote_domain_stream_disk_args,
+                (char *) &args,
+              (xdrproc_t) xdr_remote_domain_stream_disk_ret,
+                (char *) &ret) == -1)
+        goto done;
+
+    rv = ret.offset;
+    xdr_free((xdrproc_t) xdr_remote_domain_stream_disk_ret, (char *) &ret);
+
+done:
+    remoteDriverUnlock(priv);
+    VIR_FREE(args.path);
+    return rv;
+}
+
+static int remoteDomainStreamDiskInfo(virDomainPtr domain,
+                                      virStreamDiskStatePtr states,
+                                      unsigned int nr_states,
+                                      unsigned int flags)
+{
+    int rv = -1;
+    remote_domain_stream_disk_info_args args;
+    remote_domain_stream_disk_info_ret ret;
+    struct private_data *priv = domain->conn->privateData;
+    unsigned int i;
+
+    remoteDriverLock(priv);
+
+    make_nonnull_domain (&args.dom, domain);
+    if (nr_states > REMOTE_DOMAIN_STREAM_DISK_STATES_MAX) {
+        remoteError(VIR_ERR_RPC,
+                    _("too many disk stream stats requested: %d > %d"),
+                    nr_states, REMOTE_DOMAIN_STREAM_DISK_STATES_MAX);
+        goto done;
+    }
+    args.nr_results = nr_states;
+    args.flags = flags;
+    memset (&ret, 0, sizeof ret);
+
+    if (call (domain->conn, priv, 0, REMOTE_PROC_DOMAIN_STREAM_DISK_INFO,
+              (xdrproc_t) xdr_remote_domain_stream_disk_info_args,
+                (char *) &args,
+              (xdrproc_t) xdr_remote_domain_stream_disk_info_ret,
+                (char *) &ret) == -1)
+        goto done;
+
+    for (i = 0; i < ret.states.states_len; i++) {
+        strncpy (states[i].path, ret.states.states_val[i].path.path_val,
+                 VIR_STREAM_PATH_BUFLEN);
+        states[i].offset = ret.states.states_val[i].offset;
+        states[i].size = ret.states.states_val[i].size;
+    }
+    rv = ret.states.states_len;
+    xdr_free((xdrproc_t) xdr_remote_domain_stream_disk_info_ret, (char *) &ret);
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
 static int remoteDomainEventRegisterAny(virConnectPtr conn,
                                         virDomainPtr dom,
                                         int eventID,
@@ -10540,8 +10623,8 @@ static virDriver remote_driver = {
     remoteQemuDomainMonitorCommand, /* qemuDomainMonitorCommand */
     remoteDomainSetMemoryParameters, /* domainSetMemoryParameters */
     remoteDomainGetMemoryParameters, /* domainGetMemoryParameters */
-    NULL, /* domainStreamDisk */
-    NULL, /* domainStreamDiskInfo */
+    remoteDomainStreamDisk, /* domainStreamDisk */
+    remoteDomainStreamDiskInfo, /* domainStreamDiskInfo */
 };
 
 static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.c b/src/remote/remote_protocol.c
index 38ea050..0d072cd 100644
--- a/src/remote/remote_protocol.c
+++ b/src/remote/remote_protocol.c
@@ -1574,6 +1574,69 @@ xdr_remote_domain_set_autostart_args (XDR *xdrs, remote_domain_set_autostart_arg
 }
 
 bool_t
+xdr_remote_domain_stream_disk_args (XDR *xdrs, remote_domain_stream_disk_args *objp)
+{
+
+         if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
+                 return FALSE;
+         if (!xdr_remote_nonnull_string (xdrs, &objp->path))
+                 return FALSE;
+         if (!xdr_uint64_t (xdrs, &objp->offset))
+                 return FALSE;
+         if (!xdr_u_int (xdrs, &objp->flags))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_stream_disk_ret (XDR *xdrs, remote_domain_stream_disk_ret *objp)
+{
+
+         if (!xdr_uint64_t (xdrs, &objp->offset))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_stream_disk_info_args (XDR *xdrs, remote_domain_stream_disk_info_args *objp)
+{
+
+         if (!xdr_remote_nonnull_domain (xdrs, &objp->dom))
+                 return FALSE;
+         if (!xdr_u_int (xdrs, &objp->nr_results))
+                 return FALSE;
+         if (!xdr_u_int (xdrs, &objp->flags))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_stream_disk_state (XDR *xdrs, remote_stream_disk_state *objp)
+{
+        char **objp_cpp0 = (char **) (void *) &objp->path.path_val;
+
+         if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->path.path_len, VIR_STREAM_PATH_BUFLEN,
+                sizeof (char), (xdrproc_t) xdr_char))
+                 return FALSE;
+         if (!xdr_uint64_t (xdrs, &objp->offset))
+                 return FALSE;
+         if (!xdr_uint64_t (xdrs, &objp->size))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
+xdr_remote_domain_stream_disk_info_ret (XDR *xdrs, remote_domain_stream_disk_info_ret *objp)
+{
+        char **objp_cpp0 = (char **) (void *) &objp->states.states_val;
+
+         if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->states.states_len, REMOTE_DOMAIN_STREAM_DISK_STATES_MAX,
+                sizeof (remote_stream_disk_state), (xdrproc_t) xdr_remote_stream_disk_state))
+                 return FALSE;
+        return TRUE;
+}
+
+bool_t
 xdr_remote_num_of_networks_ret (XDR *xdrs, remote_num_of_networks_ret *objp)
 {
 
diff --git a/src/remote/remote_protocol.h b/src/remote/remote_protocol.h
index d75e76c..91aa6cf 100644
--- a/src/remote/remote_protocol.h
+++ b/src/remote/remote_protocol.h
@@ -67,6 +67,7 @@ typedef remote_nonnull_string *remote_string;
 #define REMOTE_SECRET_VALUE_MAX 65536
 #define REMOTE_SECRET_UUID_LIST_MAX 16384
 #define REMOTE_CPU_BASELINE_MAX 256
+#define REMOTE_DOMAIN_STREAM_DISK_STATES_MAX VIR_STREAM_DISK_MAX_STREAMS
 
 typedef char remote_uuid[VIR_UUID_BUFLEN];
 
@@ -882,6 +883,44 @@ struct remote_domain_set_autostart_args {
 };
 typedef struct remote_domain_set_autostart_args remote_domain_set_autostart_args;
 
+struct remote_domain_stream_disk_args {
+        remote_nonnull_domain dom;
+        remote_nonnull_string path;
+        uint64_t offset;
+        u_int flags;
+};
+typedef struct remote_domain_stream_disk_args remote_domain_stream_disk_args;
+
+struct remote_domain_stream_disk_ret {
+        uint64_t offset;
+};
+typedef struct remote_domain_stream_disk_ret remote_domain_stream_disk_ret;
+
+struct remote_domain_stream_disk_info_args {
+        remote_nonnull_domain dom;
+        u_int nr_results;
+        u_int flags;
+};
+typedef struct remote_domain_stream_disk_info_args remote_domain_stream_disk_info_args;
+
+struct remote_stream_disk_state {
+        struct {
+                u_int path_len;
+                char *path_val;
+        } path;
+        uint64_t offset;
+        uint64_t size;
+};
+typedef struct remote_stream_disk_state remote_stream_disk_state;
+
+struct remote_domain_stream_disk_info_ret {
+        struct {
+                u_int states_len;
+                remote_stream_disk_state *states_val;
+        } states;
+};
+typedef struct remote_domain_stream_disk_info_ret remote_domain_stream_disk_info_ret;
+
 struct remote_num_of_networks_ret {
         int num;
 };
@@ -2301,6 +2340,8 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS = 198,
         REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS = 199,
         REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS = 200,
+        REMOTE_PROC_DOMAIN_STREAM_DISK = 201,
+        REMOTE_PROC_DOMAIN_STREAM_DISK_INFO = 202,
 };
 typedef enum remote_procedure remote_procedure;
 
@@ -2461,6 +2502,11 @@ extern  bool_t xdr_remote_domain_update_device_flags_args (XDR *, remote_domain_
 extern  bool_t xdr_remote_domain_get_autostart_args (XDR *, remote_domain_get_autostart_args*);
 extern  bool_t xdr_remote_domain_get_autostart_ret (XDR *, remote_domain_get_autostart_ret*);
 extern  bool_t xdr_remote_domain_set_autostart_args (XDR *, remote_domain_set_autostart_args*);
+extern  bool_t xdr_remote_domain_stream_disk_args (XDR *, remote_domain_stream_disk_args*);
+extern  bool_t xdr_remote_domain_stream_disk_ret (XDR *, remote_domain_stream_disk_ret*);
+extern  bool_t xdr_remote_domain_stream_disk_info_args (XDR *, remote_domain_stream_disk_info_args*);
+extern  bool_t xdr_remote_stream_disk_state (XDR *, remote_stream_disk_state*);
+extern  bool_t xdr_remote_domain_stream_disk_info_ret (XDR *, remote_domain_stream_disk_info_ret*);
 extern  bool_t xdr_remote_num_of_networks_ret (XDR *, remote_num_of_networks_ret*);
 extern  bool_t xdr_remote_list_networks_args (XDR *, remote_list_networks_args*);
 extern  bool_t xdr_remote_list_networks_ret (XDR *, remote_list_networks_ret*);
@@ -2804,6 +2850,11 @@ extern bool_t xdr_remote_domain_update_device_flags_args ();
 extern bool_t xdr_remote_domain_get_autostart_args ();
 extern bool_t xdr_remote_domain_get_autostart_ret ();
 extern bool_t xdr_remote_domain_set_autostart_args ();
+extern bool_t xdr_remote_domain_stream_disk_args ();
+extern bool_t xdr_remote_domain_stream_disk_ret ();
+extern bool_t xdr_remote_domain_stream_disk_info_args ();
+extern bool_t xdr_remote_stream_disk_state ();
+extern bool_t xdr_remote_domain_stream_disk_info_ret ();
 extern bool_t xdr_remote_num_of_networks_ret ();
 extern bool_t xdr_remote_list_networks_args ();
 extern bool_t xdr_remote_list_networks_ret ();
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index d57e6d0..e6de63e 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -188,6 +188,11 @@ const REMOTE_SECRET_UUID_LIST_MAX = 16384;
  */
 const REMOTE_CPU_BASELINE_MAX = 256;
 
+/*
+ * Maximum number of active disk streams that can be reported
+ */
+const REMOTE_DOMAIN_STREAM_DISK_STATES_MAX = VIR_STREAM_DISK_MAX_STREAMS;
+
 /* UUID.  VIR_UUID_BUFLEN definition comes from libvirt.h */
 typedef opaque remote_uuid[VIR_UUID_BUFLEN];
 
@@ -863,6 +868,33 @@ struct remote_domain_set_autostart_args {
     int autostart;
 };
 
+struct remote_domain_stream_disk_args {
+    remote_nonnull_domain dom;
+    remote_nonnull_string path;
+    unsigned hyper offset;
+    unsigned int flags;
+};
+
+struct remote_domain_stream_disk_ret {
+    unsigned hyper offset;
+};
+
+struct remote_domain_stream_disk_info_args {
+    remote_nonnull_domain dom;
+    unsigned int nr_results;
+    unsigned int flags;
+};
+
+struct remote_stream_disk_state {
+    char path<VIR_STREAM_PATH_BUFLEN>;
+    unsigned hyper offset;
+    unsigned hyper size;
+};
+
+struct remote_domain_stream_disk_info_ret {
+    remote_stream_disk_state states<REMOTE_DOMAIN_STREAM_DISK_STATES_MAX>;
+};
+
 /* Network calls: */
 
 struct remote_num_of_networks_ret {
@@ -2079,7 +2111,10 @@ enum remote_procedure {
     REMOTE_PROC_DOMAIN_SET_MEMORY_PARAMETERS = 197,
     REMOTE_PROC_DOMAIN_GET_MEMORY_PARAMETERS = 198,
     REMOTE_PROC_DOMAIN_SET_VCPUS_FLAGS = 199,
-    REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS = 200
+    REMOTE_PROC_DOMAIN_GET_VCPUS_FLAGS = 200,
+
+    REMOTE_PROC_DOMAIN_STREAM_DISK = 201,
+    REMOTE_PROC_DOMAIN_STREAM_DISK_INFO = 202
 
     /*
      * Notice how the entries are grouped in sets of 10 ?
-- 
1.7.3.2.164.g6f10c




More information about the libvir-list mailing list