[libvirt] [PATCHv3 04/10] threshold: wire up threshold event in RPC

Eric Blake eblake at redhat.com
Mon Jun 22 23:06:40 UTC 2015


Pass the new virDomainBlockSetWriteThreshold() API and
WRITE_THRESHOLD event across RPC.  The event takes the bulk
of the patch, but everything here is pretty mechanical and
copies patterns from existing code.

Yes, it is intentional that registration takes a single
mandatory string (which can be either "vda" or path notation),
while the reported event has two strings (one mandatory, for
"vda"; the other optional for when path is available).

I debated about splitting the event separately from the API for
setting the threshold, in case we ever want to support setting
a write threshold by overloading an existing API such as
virDomainSetBlockIoTune(); but consensus on the design was
that overloading existing API was not appropriate, and that
no one is expecting to use this functionality without
also being prepared to require the .so bump.

* daemon/remote.c (remoteRelayDomainEventWriteThreshold): New function.
* src/remote/remote_driver.c
(remoteDomainBuildEventCallbackWriteThreshold): Likewise.
* src/remote/remote_protocol.x
(remote_domain_event_callback_write_threshold_msg)
(remote_domain_block_set_write_threshold_args): New structs.
* src/remote_protocol-structs: Update.

Signed-off-by: Eric Blake <eblake at redhat.com>
---
 daemon/remote.c              | 53 ++++++++++++++++++++++++++++++++++++++++++--
 src/remote/remote_driver.c   | 35 +++++++++++++++++++++++++++++
 src/remote/remote_protocol.x | 30 ++++++++++++++++++++++++-
 src/remote_protocol-structs  | 16 +++++++++++++
 4 files changed, 131 insertions(+), 3 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 283ece2..457e220 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1079,6 +1079,56 @@ remoteRelayDomainEventDeviceAdded(virConnectPtr conn,
 }


+static int
+remoteRelayDomainEventWriteThreshold(virConnectPtr conn,
+                                     virDomainPtr dom,
+                                     const char *disk,
+                                     const char *path,
+                                     unsigned long long threshold,
+                                     unsigned long long length,
+                                     void *opaque)
+{
+    daemonClientEventCallbackPtr callback = opaque;
+    remote_domain_event_callback_write_threshold_msg data;
+    char **path_p = NULL;
+
+    if (callback->callbackID < 0 ||
+        !remoteRelayDomainEventCheckACL(callback->client, conn, dom))
+        return -1;
+
+    VIR_DEBUG("Relaying domain write threshold event %s %d %s (%s) %llu %llu, "
+              "callback %d", dom->name, dom->id,
+              disk, NULLSTR(path), threshold, length, callback->callbackID);
+
+    /* build return data */
+    memset(&data, 0, sizeof(data));
+
+    if (VIR_STRDUP(data.disk, disk) < 0)
+        goto error;
+    if (path &&
+        ((VIR_ALLOC(path_p) < 0) ||
+         VIR_STRDUP(*path_p, path) < 0))
+        goto error;
+
+    make_nonnull_domain(&data.dom, dom);
+    data.callbackID = callback->callbackID;
+    data.path = path_p;
+    data.threshold = threshold;
+    data.length = length;
+
+    remoteDispatchObjectEventSend(callback->client, remoteProgram,
+                                  REMOTE_PROC_DOMAIN_EVENT_CALLBACK_WRITE_THRESHOLD,
+                                  (xdrproc_t)xdr_remote_domain_event_callback_write_threshold_msg,
+                                  &data);
+
+    return 0;
+ error:
+    VIR_FREE(data.disk);
+    VIR_FREE(data.path);
+    VIR_FREE(path_p);
+    return -1;
+}
+


 static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
@@ -1102,8 +1152,7 @@ static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
     VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventTunable),
     VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventAgentLifecycle),
     VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventDeviceAdded),
-    /* TODO: Implement RPC support for this */
-    VIR_DOMAIN_EVENT_CALLBACK(NULL),
+    VIR_DOMAIN_EVENT_CALLBACK(remoteRelayDomainEventWriteThreshold),
 };

 verify(ARRAY_CARDINALITY(domainEventCallbacks) == VIR_DOMAIN_EVENT_ID_LAST);
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 273799b..f0b1941 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -342,6 +342,12 @@ remoteDomainBuildEventCallbackAgentLifecycle(virNetClientProgramPtr prog,
                                              void *evdata, void *opaque);

 static void
+remoteDomainBuildEventCallbackWriteThreshold(virNetClientProgramPtr prog,
+                                             virNetClientPtr client,
+                                             void *evdata, void *opaque);
+
+
+static void
 remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
                                  virNetClientPtr client ATTRIBUTE_UNUSED,
                                  void *evdata, void *opaque);
@@ -504,6 +510,10 @@ static virNetClientProgramEvent remoteEvents[] = {
       remoteDomainBuildEventCallbackDeviceAdded,
       sizeof(remote_domain_event_callback_device_added_msg),
       (xdrproc_t)xdr_remote_domain_event_callback_device_added_msg },
+    { REMOTE_PROC_DOMAIN_EVENT_CALLBACK_WRITE_THRESHOLD,
+      remoteDomainBuildEventCallbackWriteThreshold,
+      sizeof(remote_domain_event_callback_write_threshold_msg),
+      (xdrproc_t)xdr_remote_domain_event_callback_write_threshold_msg },
 };


@@ -5518,6 +5528,30 @@ remoteDomainBuildEventCallbackAgentLifecycle(virNetClientProgramPtr prog ATTRIBU
 }

 static void
+remoteDomainBuildEventCallbackWriteThreshold(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
+                                             virNetClientPtr client ATTRIBUTE_UNUSED,
+                                             void *evdata, void *opaque)
+{
+    virConnectPtr conn = opaque;
+    remote_domain_event_callback_write_threshold_msg *msg = evdata;
+    struct private_data *priv = conn->privateData;
+    virDomainPtr dom;
+    virObjectEventPtr event = NULL;
+    const char *path = msg->path ? *msg->path : NULL;
+
+    if (!(dom = get_nonnull_domain(conn, msg->dom)))
+        return;
+
+    event = virDomainEventWriteThresholdNewFromDom(dom, msg->disk, path,
+                                                   msg->threshold,
+                                                   msg->length);
+
+    virObjectUnref(dom);
+
+    remoteEventQueue(priv, event, msg->callbackID);
+}
+
+static void
 remoteNetworkBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
                                  virNetClientPtr client ATTRIBUTE_UNUSED,
                                  void *evdata, void *opaque)
@@ -8275,6 +8309,7 @@ static virHypervisorDriver hypervisor_driver = {
     .domainBlockResize = remoteDomainBlockResize, /* 0.9.8 */
     .domainBlockStats = remoteDomainBlockStats, /* 0.3.2 */
     .domainBlockStatsFlags = remoteDomainBlockStatsFlags, /* 0.9.5 */
+    .domainBlockSetWriteThreshold = remoteDomainBlockSetWriteThreshold, /* 1.3.0 */
     .domainInterfaceStats = remoteDomainInterfaceStats, /* 0.3.2 */
     .domainSetInterfaceParameters = remoteDomainSetInterfaceParameters, /* 0.9.9 */
     .domainGetInterfaceParameters = remoteDomainGetInterfaceParameters, /* 0.9.9 */
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 9f1be6b..0461319 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -3230,6 +3230,22 @@ struct remote_domain_set_user_password_args {
     unsigned int flags;
 };

+struct remote_domain_event_callback_write_threshold_msg {
+    int callbackID;
+    remote_nonnull_domain dom;
+    remote_nonnull_string disk;
+    remote_string path;
+    unsigned hyper threshold;
+    unsigned hyper length;
+};
+
+struct remote_domain_block_set_write_threshold_args {
+    remote_nonnull_domain dom;
+    remote_nonnull_string disk;
+    unsigned hyper threshold;
+    unsigned int flags;
+};
+

 /*----- Protocol. -----*/

@@ -5696,5 +5712,17 @@ enum remote_procedure {
      * @generate:both
      * @acl: domain:set_password
      */
-    REMOTE_PROC_DOMAIN_SET_USER_PASSWORD = 357
+    REMOTE_PROC_DOMAIN_SET_USER_PASSWORD = 357,
+
+    /**
+     * @generate: both
+     * @acl: none
+     */
+    REMOTE_PROC_DOMAIN_EVENT_CALLBACK_WRITE_THRESHOLD = 358,
+
+    /**
+     * @generate: both
+     * @acl: domain:block_write
+     */
+    REMOTE_PROC_DOMAIN_BLOCK_SET_WRITE_THRESHOLD = 359
 };
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 48c3bd8..bfa3d3c 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -2684,6 +2684,20 @@ struct remote_domain_set_user_password_args {
         remote_string              password;
         u_int                      flags;
 };
+struct remote_domain_event_callback_write_threshold_msg {
+        int                        callbackID;
+        remote_nonnull_domain      dom;
+        remote_nonnull_string      disk;
+        remote_string              path;
+        uint64_t                   threshold;
+        uint64_t                   length;
+};
+struct remote_domain_block_set_write_threshold_args {
+        remote_nonnull_domain      dom;
+        remote_nonnull_string      disk;
+        uint64_t                   threshold;
+        u_int                      flags;
+};
 enum remote_procedure {
         REMOTE_PROC_CONNECT_OPEN = 1,
         REMOTE_PROC_CONNECT_CLOSE = 2,
@@ -3042,4 +3056,6 @@ enum remote_procedure {
         REMOTE_PROC_DOMAIN_ADD_IOTHREAD = 355,
         REMOTE_PROC_DOMAIN_DEL_IOTHREAD = 356,
         REMOTE_PROC_DOMAIN_SET_USER_PASSWORD = 357,
+        REMOTE_PROC_DOMAIN_EVENT_CALLBACK_WRITE_THRESHOLD = 358,
+        REMOTE_PROC_DOMAIN_BLOCK_SET_WRITE_THRESHOLD = 359,
 };
-- 
2.4.3




More information about the libvir-list mailing list