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(a)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