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.
I debated about splitting the event separately from the
API, 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 (remoteRelayDomainEventDeviceAdded): Fix odd use
of comma operator.
(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 | 41 +++++++++++++++++++++++++++++++++++++++--
src/remote/remote_driver.c | 34 ++++++++++++++++++++++++++++++++++
src/remote/remote_protocol.x | 29 ++++++++++++++++++++++++++++-
src/remote_protocol-structs | 15 +++++++++++++++
4 files changed, 116 insertions(+), 3 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 283ece2..cc9936b 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1079,6 +1079,44 @@ remoteRelayDomainEventDeviceAdded(virConnectPtr conn,
}
+static int
+remoteRelayDomainEventWriteThreshold(virConnectPtr conn,
+ virDomainPtr dom,
+ const char *disk,
+ unsigned long long threshold,
+ unsigned long long length,
+ void *opaque)
+{
+ daemonClientEventCallbackPtr callback = opaque;
+ remote_domain_event_callback_write_threshold_msg data;
+
+ if (callback->callbackID < 0 ||
+ !remoteRelayDomainEventCheckACL(callback->client, conn, dom))
+ return -1;
+
+ VIR_DEBUG("Relaying domain write threshold event %s %d %s %lld %lld, "
+ "callback %d", dom->name, dom->id,
+ disk, threshold, length, callback->callbackID);
+
+ /* build return data */
+ memset(&data, 0, sizeof(data));
+
+ if (VIR_STRDUP(data.disk, disk) < 0)
+ return -1;
+
+ make_nonnull_domain(&data.dom, dom);
+ data.callbackID = callback->callbackID;
+ 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;
+}
+
static virConnectDomainEventGenericCallback domainEventCallbacks[] = {
@@ -1102,8 +1140,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..2e631ba 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,29 @@ 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;
+
+ if (!(dom = get_nonnull_domain(conn, msg->dom)))
+ return;
+
+ event = virDomainEventWriteThresholdNewFromDom(dom, msg->disk,
+ 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 +8308,7 @@ static virHypervisorDriver hypervisor_driver = {
.domainBlockResize = remoteDomainBlockResize, /* 0.9.8 */
.domainBlockStats = remoteDomainBlockStats, /* 0.3.2 */
.domainBlockStatsFlags = remoteDomainBlockStatsFlags, /* 0.9.5 */
+ .domainBlockSetWriteThreshold = remoteDomainBlockSetWriteThreshold, /* 1.2.17 */
.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..93f0952 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -3230,6 +3230,21 @@ 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;
+ 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 +5711,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..991357f 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -2684,6 +2684,19 @@ 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;
+ 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 +3055,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.2