mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 19:11:16 +00:00
remote: implement node device lifecycle event APIs
This commit is contained in:
parent
1f12580a64
commit
9b13df379c
@ -62,6 +62,8 @@ struct daemonClientPrivate {
|
|||||||
size_t nqemuEventCallbacks;
|
size_t nqemuEventCallbacks;
|
||||||
daemonClientEventCallbackPtr *storageEventCallbacks;
|
daemonClientEventCallbackPtr *storageEventCallbacks;
|
||||||
size_t nstorageEventCallbacks;
|
size_t nstorageEventCallbacks;
|
||||||
|
daemonClientEventCallbackPtr *nodeDeviceEventCallbacks;
|
||||||
|
size_t nnodeDeviceEventCallbacks;
|
||||||
bool closeRegistered;
|
bool closeRegistered;
|
||||||
|
|
||||||
# if WITH_SASL
|
# if WITH_SASL
|
||||||
|
206
daemon/remote.c
206
daemon/remote.c
@ -91,6 +91,7 @@ static virStorageVolPtr get_nonnull_storage_vol(virConnectPtr conn, remote_nonnu
|
|||||||
static virSecretPtr get_nonnull_secret(virConnectPtr conn, remote_nonnull_secret secret);
|
static virSecretPtr get_nonnull_secret(virConnectPtr conn, remote_nonnull_secret secret);
|
||||||
static virNWFilterPtr get_nonnull_nwfilter(virConnectPtr conn, remote_nonnull_nwfilter nwfilter);
|
static virNWFilterPtr get_nonnull_nwfilter(virConnectPtr conn, remote_nonnull_nwfilter nwfilter);
|
||||||
static virDomainSnapshotPtr get_nonnull_domain_snapshot(virDomainPtr dom, remote_nonnull_domain_snapshot snapshot);
|
static virDomainSnapshotPtr get_nonnull_domain_snapshot(virDomainPtr dom, remote_nonnull_domain_snapshot snapshot);
|
||||||
|
static virNodeDevicePtr get_nonnull_node_device(virConnectPtr conn, remote_nonnull_node_device dev);
|
||||||
static void make_nonnull_domain(remote_nonnull_domain *dom_dst, virDomainPtr dom_src);
|
static void make_nonnull_domain(remote_nonnull_domain *dom_dst, virDomainPtr dom_src);
|
||||||
static void make_nonnull_network(remote_nonnull_network *net_dst, virNetworkPtr net_src);
|
static void make_nonnull_network(remote_nonnull_network *net_dst, virNetworkPtr net_src);
|
||||||
static void make_nonnull_interface(remote_nonnull_interface *interface_dst, virInterfacePtr interface_src);
|
static void make_nonnull_interface(remote_nonnull_interface *interface_dst, virInterfacePtr interface_src);
|
||||||
@ -208,6 +209,32 @@ remoteRelayStoragePoolEventCheckACL(virNetServerClientPtr client,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
remoteRelayNodeDeviceEventCheckACL(virNetServerClientPtr client,
|
||||||
|
virConnectPtr conn,
|
||||||
|
virNodeDevicePtr dev)
|
||||||
|
{
|
||||||
|
virNodeDeviceDef def;
|
||||||
|
virIdentityPtr identity = NULL;
|
||||||
|
bool ret = false;
|
||||||
|
|
||||||
|
/* For now, we just create a virNodeDeviceDef with enough contents to
|
||||||
|
* satisfy what viraccessdriverpolkit.c references. This is a bit
|
||||||
|
* fragile, but I don't know of anything better. */
|
||||||
|
def.name = dev->name;
|
||||||
|
|
||||||
|
if (!(identity = virNetServerClientGetIdentity(client)))
|
||||||
|
goto cleanup;
|
||||||
|
if (virIdentitySetCurrent(identity) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
ret = virConnectNodeDeviceEventRegisterAnyCheckACL(conn, &def);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
ignore_value(virIdentitySetCurrent(NULL));
|
||||||
|
virObjectUnref(identity);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
remoteRelayDomainQemuMonitorEventCheckACL(virNetServerClientPtr client,
|
remoteRelayDomainQemuMonitorEventCheckACL(virNetServerClientPtr client,
|
||||||
virConnectPtr conn, virDomainPtr dom)
|
virConnectPtr conn, virDomainPtr dom)
|
||||||
@ -1329,6 +1356,44 @@ static virConnectStoragePoolEventGenericCallback storageEventCallbacks[] = {
|
|||||||
|
|
||||||
verify(ARRAY_CARDINALITY(storageEventCallbacks) == VIR_STORAGE_POOL_EVENT_ID_LAST);
|
verify(ARRAY_CARDINALITY(storageEventCallbacks) == VIR_STORAGE_POOL_EVENT_ID_LAST);
|
||||||
|
|
||||||
|
static int
|
||||||
|
remoteRelayNodeDeviceEventLifecycle(virConnectPtr conn,
|
||||||
|
virNodeDevicePtr dev,
|
||||||
|
int event,
|
||||||
|
int detail,
|
||||||
|
void *opaque)
|
||||||
|
{
|
||||||
|
daemonClientEventCallbackPtr callback = opaque;
|
||||||
|
remote_node_device_event_lifecycle_msg data;
|
||||||
|
|
||||||
|
if (callback->callbackID < 0 ||
|
||||||
|
!remoteRelayNodeDeviceEventCheckACL(callback->client, conn, dev))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
VIR_DEBUG("Relaying node device lifecycle event %d, detail %d, callback %d",
|
||||||
|
event, detail, callback->callbackID);
|
||||||
|
|
||||||
|
/* build return data */
|
||||||
|
memset(&data, 0, sizeof(data));
|
||||||
|
make_nonnull_node_device(&data.dev, dev);
|
||||||
|
data.callbackID = callback->callbackID;
|
||||||
|
data.event = event;
|
||||||
|
data.detail = detail;
|
||||||
|
|
||||||
|
remoteDispatchObjectEventSend(callback->client, remoteProgram,
|
||||||
|
REMOTE_PROC_NODE_DEVICE_EVENT_LIFECYCLE,
|
||||||
|
(xdrproc_t)xdr_remote_node_device_event_lifecycle_msg,
|
||||||
|
&data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static virConnectNodeDeviceEventGenericCallback nodeDeviceEventCallbacks[] = {
|
||||||
|
VIR_NODE_DEVICE_EVENT_CALLBACK(remoteRelayNodeDeviceEventLifecycle),
|
||||||
|
};
|
||||||
|
|
||||||
|
verify(ARRAY_CARDINALITY(nodeDeviceEventCallbacks) == VIR_NODE_DEVICE_EVENT_ID_LAST);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remoteRelayDomainQemuMonitorEvent(virConnectPtr conn,
|
remoteRelayDomainQemuMonitorEvent(virConnectPtr conn,
|
||||||
virDomainPtr dom,
|
virDomainPtr dom,
|
||||||
@ -1451,6 +1516,21 @@ void remoteClientFreeFunc(void *data)
|
|||||||
}
|
}
|
||||||
VIR_FREE(priv->storageEventCallbacks);
|
VIR_FREE(priv->storageEventCallbacks);
|
||||||
|
|
||||||
|
for (i = 0; i < priv->nnodeDeviceEventCallbacks; i++) {
|
||||||
|
int callbackID = priv->nodeDeviceEventCallbacks[i]->callbackID;
|
||||||
|
if (callbackID < 0) {
|
||||||
|
VIR_WARN("unexpected incomplete node device callback %zu", i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
VIR_DEBUG("Deregistering remote node device event relay %d",
|
||||||
|
callbackID);
|
||||||
|
priv->nodeDeviceEventCallbacks[i]->callbackID = -1;
|
||||||
|
if (virConnectNodeDeviceEventDeregisterAny(priv->conn,
|
||||||
|
callbackID) < 0)
|
||||||
|
VIR_WARN("unexpected node device event deregister failure");
|
||||||
|
}
|
||||||
|
VIR_FREE(priv->nodeDeviceEventCallbacks);
|
||||||
|
|
||||||
for (i = 0; i < priv->nqemuEventCallbacks; i++) {
|
for (i = 0; i < priv->nqemuEventCallbacks; i++) {
|
||||||
int callbackID = priv->qemuEventCallbacks[i]->callbackID;
|
int callbackID = priv->qemuEventCallbacks[i]->callbackID;
|
||||||
if (callbackID < 0) {
|
if (callbackID < 0) {
|
||||||
@ -5662,6 +5742,126 @@ remoteDispatchConnectStoragePoolEventDeregisterAny(virNetServerPtr server ATTRIB
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
remoteDispatchConnectNodeDeviceEventRegisterAny(virNetServerPtr server ATTRIBUTE_UNUSED,
|
||||||
|
virNetServerClientPtr client,
|
||||||
|
virNetMessagePtr msg ATTRIBUTE_UNUSED,
|
||||||
|
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
|
||||||
|
remote_connect_node_device_event_register_any_args *args,
|
||||||
|
remote_connect_node_device_event_register_any_ret *ret)
|
||||||
|
{
|
||||||
|
int callbackID;
|
||||||
|
int rv = -1;
|
||||||
|
daemonClientEventCallbackPtr callback = NULL;
|
||||||
|
daemonClientEventCallbackPtr ref;
|
||||||
|
struct daemonClientPrivate *priv =
|
||||||
|
virNetServerClientGetPrivateData(client);
|
||||||
|
virNodeDevicePtr dev = NULL;
|
||||||
|
|
||||||
|
if (!priv->conn) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
virMutexLock(&priv->lock);
|
||||||
|
|
||||||
|
if (args->dev &&
|
||||||
|
!(dev = get_nonnull_node_device(priv->conn, *args->dev)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (args->eventID >= VIR_NODE_DEVICE_EVENT_ID_LAST || args->eventID < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unsupported node device event ID %d"), args->eventID);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we call register first, we could append a complete callback
|
||||||
|
* to our array, but on OOM append failure, we'd have to then hope
|
||||||
|
* deregister works to undo our register. So instead we append an
|
||||||
|
* incomplete callback to our array, then register, then fix up
|
||||||
|
* our callback; but since VIR_APPEND_ELEMENT clears 'callback' on
|
||||||
|
* success, we use 'ref' to save a copy of the pointer. */
|
||||||
|
if (VIR_ALLOC(callback) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
callback->client = client;
|
||||||
|
callback->eventID = args->eventID;
|
||||||
|
callback->callbackID = -1;
|
||||||
|
ref = callback;
|
||||||
|
if (VIR_APPEND_ELEMENT(priv->nodeDeviceEventCallbacks,
|
||||||
|
priv->nnodeDeviceEventCallbacks,
|
||||||
|
callback) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if ((callbackID = virConnectNodeDeviceEventRegisterAny(priv->conn,
|
||||||
|
dev,
|
||||||
|
args->eventID,
|
||||||
|
nodeDeviceEventCallbacks[args->eventID],
|
||||||
|
ref,
|
||||||
|
remoteEventCallbackFree)) < 0) {
|
||||||
|
VIR_SHRINK_N(priv->nodeDeviceEventCallbacks,
|
||||||
|
priv->nnodeDeviceEventCallbacks, 1);
|
||||||
|
callback = ref;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ref->callbackID = callbackID;
|
||||||
|
ret->callbackID = callbackID;
|
||||||
|
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(callback);
|
||||||
|
if (rv < 0)
|
||||||
|
virNetMessageSaveError(rerr);
|
||||||
|
virObjectUnref(dev);
|
||||||
|
virMutexUnlock(&priv->lock);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
remoteDispatchConnectNodeDeviceEventDeregisterAny(virNetServerPtr server ATTRIBUTE_UNUSED,
|
||||||
|
virNetServerClientPtr client,
|
||||||
|
virNetMessagePtr msg ATTRIBUTE_UNUSED,
|
||||||
|
virNetMessageErrorPtr rerr ATTRIBUTE_UNUSED,
|
||||||
|
remote_connect_node_device_event_deregister_any_args *args)
|
||||||
|
{
|
||||||
|
int rv = -1;
|
||||||
|
size_t i;
|
||||||
|
struct daemonClientPrivate *priv =
|
||||||
|
virNetServerClientGetPrivateData(client);
|
||||||
|
|
||||||
|
if (!priv->conn) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
virMutexLock(&priv->lock);
|
||||||
|
|
||||||
|
for (i = 0; i < priv->nnodeDeviceEventCallbacks; i++) {
|
||||||
|
if (priv->nodeDeviceEventCallbacks[i]->callbackID == args->callbackID)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == priv->nnodeDeviceEventCallbacks) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("node device event callback %d not registered"),
|
||||||
|
args->callbackID);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virConnectNodeDeviceEventDeregisterAny(priv->conn, args->callbackID) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
VIR_DELETE_ELEMENT(priv->nodeDeviceEventCallbacks, i,
|
||||||
|
priv->nnodeDeviceEventCallbacks);
|
||||||
|
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (rv < 0)
|
||||||
|
virNetMessageSaveError(rerr);
|
||||||
|
virMutexUnlock(&priv->lock);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qemuDispatchConnectDomainMonitorEventRegister(virNetServerPtr server ATTRIBUTE_UNUSED,
|
qemuDispatchConnectDomainMonitorEventRegister(virNetServerPtr server ATTRIBUTE_UNUSED,
|
||||||
@ -6431,6 +6631,12 @@ get_nonnull_domain_snapshot(virDomainPtr dom, remote_nonnull_domain_snapshot sna
|
|||||||
return virGetDomainSnapshot(dom, snapshot.name);
|
return virGetDomainSnapshot(dom, snapshot.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static virNodeDevicePtr
|
||||||
|
get_nonnull_node_device(virConnectPtr conn, remote_nonnull_node_device dev)
|
||||||
|
{
|
||||||
|
return virGetNodeDevice(conn, dev.name);
|
||||||
|
}
|
||||||
|
|
||||||
/* Make remote_nonnull_domain and remote_nonnull_network. */
|
/* Make remote_nonnull_domain and remote_nonnull_network. */
|
||||||
static void
|
static void
|
||||||
make_nonnull_domain(remote_nonnull_domain *dom_dst, virDomainPtr dom_src)
|
make_nonnull_domain(remote_nonnull_domain *dom_dst, virDomainPtr dom_src)
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "domain_event.h"
|
#include "domain_event.h"
|
||||||
#include "network_event.h"
|
#include "network_event.h"
|
||||||
#include "storage_event.h"
|
#include "storage_event.h"
|
||||||
|
#include "node_device_event.h"
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
#include "virbuffer.h"
|
#include "virbuffer.h"
|
||||||
#include "remote_driver.h"
|
#include "remote_driver.h"
|
||||||
@ -151,6 +152,8 @@ static void make_nonnull_network(remote_nonnull_network *net_dst, virNetworkPtr
|
|||||||
static void make_nonnull_interface(remote_nonnull_interface *interface_dst, virInterfacePtr interface_src);
|
static void make_nonnull_interface(remote_nonnull_interface *interface_dst, virInterfacePtr interface_src);
|
||||||
static void make_nonnull_storage_pool(remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr vol_src);
|
static void make_nonnull_storage_pool(remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr vol_src);
|
||||||
static void make_nonnull_storage_vol(remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src);
|
static void make_nonnull_storage_vol(remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src);
|
||||||
|
static void
|
||||||
|
make_nonnull_node_device(remote_nonnull_node_device *dev_dst, virNodeDevicePtr dev_src);
|
||||||
static void make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr secret_src);
|
static void make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr secret_src);
|
||||||
static void make_nonnull_nwfilter(remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src);
|
static void make_nonnull_nwfilter(remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src);
|
||||||
static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src);
|
static void make_nonnull_domain_snapshot(remote_nonnull_domain_snapshot *snapshot_dst, virDomainSnapshotPtr snapshot_src);
|
||||||
@ -366,6 +369,11 @@ remoteStoragePoolBuildEventRefresh(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|||||||
virNetClientPtr client ATTRIBUTE_UNUSED,
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
||||||
void *evdata, void *opaque);
|
void *evdata, void *opaque);
|
||||||
|
|
||||||
|
static void
|
||||||
|
remoteNodeDeviceBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
||||||
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
||||||
|
void *evdata, void *opaque);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remoteConnectNotifyEventConnectionClosed(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
remoteConnectNotifyEventConnectionClosed(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
||||||
virNetClientPtr client ATTRIBUTE_UNUSED,
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
||||||
@ -553,6 +561,10 @@ static virNetClientProgramEvent remoteEvents[] = {
|
|||||||
remoteStoragePoolBuildEventRefresh,
|
remoteStoragePoolBuildEventRefresh,
|
||||||
sizeof(remote_storage_pool_event_refresh_msg),
|
sizeof(remote_storage_pool_event_refresh_msg),
|
||||||
(xdrproc_t)xdr_remote_storage_pool_event_refresh_msg },
|
(xdrproc_t)xdr_remote_storage_pool_event_refresh_msg },
|
||||||
|
{ REMOTE_PROC_NODE_DEVICE_EVENT_LIFECYCLE,
|
||||||
|
remoteNodeDeviceBuildEventLifecycle,
|
||||||
|
sizeof(remote_node_device_event_lifecycle_msg),
|
||||||
|
(xdrproc_t)xdr_remote_node_device_event_lifecycle_msg },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -3146,6 +3158,103 @@ remoteConnectStoragePoolEventDeregisterAny(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
remoteConnectNodeDeviceEventRegisterAny(virConnectPtr conn,
|
||||||
|
virNodeDevicePtr dev,
|
||||||
|
int eventID,
|
||||||
|
virConnectNodeDeviceEventGenericCallback callback,
|
||||||
|
void *opaque,
|
||||||
|
virFreeCallback freecb)
|
||||||
|
{
|
||||||
|
int rv = -1;
|
||||||
|
struct private_data *priv = conn->privateData;
|
||||||
|
remote_connect_node_device_event_register_any_args args;
|
||||||
|
remote_connect_node_device_event_register_any_ret ret;
|
||||||
|
int callbackID;
|
||||||
|
int count;
|
||||||
|
remote_nonnull_node_device node_device;
|
||||||
|
|
||||||
|
remoteDriverLock(priv);
|
||||||
|
|
||||||
|
if ((count = virNodeDeviceEventStateRegisterClient(conn, priv->eventState,
|
||||||
|
dev, eventID, callback,
|
||||||
|
opaque, freecb,
|
||||||
|
&callbackID)) < 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* If this is the first callback for this eventID, we need to enable
|
||||||
|
* events on the server */
|
||||||
|
if (count == 1) {
|
||||||
|
args.eventID = eventID;
|
||||||
|
if (dev) {
|
||||||
|
make_nonnull_node_device(&node_device, dev);
|
||||||
|
args.dev = &node_device;
|
||||||
|
} else {
|
||||||
|
args.dev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&ret, 0, sizeof(ret));
|
||||||
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_NODE_DEVICE_EVENT_REGISTER_ANY,
|
||||||
|
(xdrproc_t) xdr_remote_connect_node_device_event_register_any_args, (char *) &args,
|
||||||
|
(xdrproc_t) xdr_remote_connect_node_device_event_register_any_ret, (char *) &ret) == -1) {
|
||||||
|
virObjectEventStateDeregisterID(conn, priv->eventState,
|
||||||
|
callbackID);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
virObjectEventStateSetRemote(conn, priv->eventState, callbackID,
|
||||||
|
ret.callbackID);
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = callbackID;
|
||||||
|
|
||||||
|
done:
|
||||||
|
remoteDriverUnlock(priv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
remoteConnectNodeDeviceEventDeregisterAny(virConnectPtr conn,
|
||||||
|
int callbackID)
|
||||||
|
{
|
||||||
|
struct private_data *priv = conn->privateData;
|
||||||
|
int rv = -1;
|
||||||
|
remote_connect_node_device_event_deregister_any_args args;
|
||||||
|
int eventID;
|
||||||
|
int remoteID;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
remoteDriverLock(priv);
|
||||||
|
|
||||||
|
if ((eventID = virObjectEventStateEventID(conn, priv->eventState,
|
||||||
|
callbackID, &remoteID)) < 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if ((count = virObjectEventStateDeregisterID(conn, priv->eventState,
|
||||||
|
callbackID)) < 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
/* If that was the last callback for this eventID, we need to disable
|
||||||
|
* events on the server */
|
||||||
|
if (count == 0) {
|
||||||
|
args.callbackID = remoteID;
|
||||||
|
|
||||||
|
if (call(conn, priv, 0, REMOTE_PROC_CONNECT_NODE_DEVICE_EVENT_DEREGISTER_ANY,
|
||||||
|
(xdrproc_t) xdr_remote_connect_node_device_event_deregister_any_args, (char *) &args,
|
||||||
|
(xdrproc_t) xdr_void, (char *) NULL) == -1)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = 0;
|
||||||
|
|
||||||
|
done:
|
||||||
|
remoteDriverUnlock(priv);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
remoteConnectDomainQemuMonitorEventRegister(virConnectPtr conn,
|
remoteConnectDomainQemuMonitorEventRegister(virConnectPtr conn,
|
||||||
virDomainPtr dom,
|
virDomainPtr dom,
|
||||||
@ -5154,6 +5263,28 @@ remoteStoragePoolBuildEventRefresh(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
|||||||
remoteEventQueue(priv, event, msg->callbackID);
|
remoteEventQueue(priv, event, msg->callbackID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
remoteNodeDeviceBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
||||||
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
||||||
|
void *evdata, void *opaque)
|
||||||
|
{
|
||||||
|
virConnectPtr conn = opaque;
|
||||||
|
struct private_data *priv = conn->privateData;
|
||||||
|
remote_node_device_event_lifecycle_msg *msg = evdata;
|
||||||
|
virNodeDevicePtr dev;
|
||||||
|
virObjectEventPtr event = NULL;
|
||||||
|
|
||||||
|
dev = get_nonnull_node_device(conn, msg->dev);
|
||||||
|
if (!dev)
|
||||||
|
return;
|
||||||
|
|
||||||
|
event = virNodeDeviceEventLifecycleNew(dev->name, msg->event,
|
||||||
|
msg->detail);
|
||||||
|
virObjectUnref(dev);
|
||||||
|
|
||||||
|
remoteEventQueue(priv, event, msg->callbackID);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remoteDomainBuildQemuMonitorEvent(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
remoteDomainBuildQemuMonitorEvent(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
|
||||||
virNetClientPtr client ATTRIBUTE_UNUSED,
|
virNetClientPtr client ATTRIBUTE_UNUSED,
|
||||||
@ -7752,6 +7883,12 @@ make_nonnull_secret(remote_nonnull_secret *secret_dst, virSecretPtr secret_src)
|
|||||||
secret_dst->usageID = secret_src->usageID;
|
secret_dst->usageID = secret_src->usageID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
make_nonnull_node_device(remote_nonnull_node_device *dev_dst, virNodeDevicePtr dev_src)
|
||||||
|
{
|
||||||
|
dev_dst->name = dev_src->name;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
make_nonnull_nwfilter(remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src)
|
make_nonnull_nwfilter(remote_nonnull_nwfilter *nwfilter_dst, virNWFilterPtr nwfilter_src)
|
||||||
{
|
{
|
||||||
@ -8103,6 +8240,8 @@ static virSecretDriver secret_driver = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static virNodeDeviceDriver node_device_driver = {
|
static virNodeDeviceDriver node_device_driver = {
|
||||||
|
.connectNodeDeviceEventDeregisterAny = remoteConnectNodeDeviceEventDeregisterAny, /* 2.2.0 */
|
||||||
|
.connectNodeDeviceEventRegisterAny = remoteConnectNodeDeviceEventRegisterAny, /* 2.2.0 */
|
||||||
.nodeNumOfDevices = remoteNodeNumOfDevices, /* 0.5.0 */
|
.nodeNumOfDevices = remoteNodeNumOfDevices, /* 0.5.0 */
|
||||||
.nodeListDevices = remoteNodeListDevices, /* 0.5.0 */
|
.nodeListDevices = remoteNodeListDevices, /* 0.5.0 */
|
||||||
.connectListAllNodeDevices = remoteConnectListAllNodeDevices, /* 0.10.2 */
|
.connectListAllNodeDevices = remoteConnectListAllNodeDevices, /* 0.10.2 */
|
||||||
|
@ -3131,6 +3131,26 @@ struct remote_storage_pool_event_refresh_msg {
|
|||||||
remote_nonnull_storage_pool pool;
|
remote_nonnull_storage_pool pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct remote_connect_node_device_event_register_any_args {
|
||||||
|
int eventID;
|
||||||
|
remote_node_device dev;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct remote_connect_node_device_event_register_any_ret {
|
||||||
|
int callbackID;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct remote_connect_node_device_event_deregister_any_args {
|
||||||
|
int callbackID;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct remote_node_device_event_lifecycle_msg {
|
||||||
|
int callbackID;
|
||||||
|
remote_nonnull_node_device dev;
|
||||||
|
int event;
|
||||||
|
int detail;
|
||||||
|
};
|
||||||
|
|
||||||
struct remote_domain_fsfreeze_args {
|
struct remote_domain_fsfreeze_args {
|
||||||
remote_nonnull_domain dom;
|
remote_nonnull_domain dom;
|
||||||
remote_nonnull_string mountpoints<REMOTE_DOMAIN_FSFREEZE_MOUNTPOINTS_MAX>; /* (const char **) */
|
remote_nonnull_string mountpoints<REMOTE_DOMAIN_FSFREEZE_MOUNTPOINTS_MAX>; /* (const char **) */
|
||||||
@ -5882,5 +5902,26 @@ enum remote_procedure {
|
|||||||
* @generate: both
|
* @generate: both
|
||||||
* @acl: none
|
* @acl: none
|
||||||
*/
|
*/
|
||||||
REMOTE_PROC_STORAGE_POOL_EVENT_REFRESH = 373
|
REMOTE_PROC_STORAGE_POOL_EVENT_REFRESH = 373,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generate: none
|
||||||
|
* @priority: high
|
||||||
|
* @acl: connect:search_node_devices
|
||||||
|
* @aclfilter: node_device:getattr
|
||||||
|
*/
|
||||||
|
REMOTE_PROC_CONNECT_NODE_DEVICE_EVENT_REGISTER_ANY = 374,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generate: none
|
||||||
|
* @priority: high
|
||||||
|
* @acl: connect:read
|
||||||
|
*/
|
||||||
|
REMOTE_PROC_CONNECT_NODE_DEVICE_EVENT_DEREGISTER_ANY = 375,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @generate: both
|
||||||
|
* @acl: none
|
||||||
|
*/
|
||||||
|
REMOTE_PROC_NODE_DEVICE_EVENT_LIFECYCLE = 376
|
||||||
};
|
};
|
||||||
|
@ -2571,6 +2571,22 @@ struct remote_storage_pool_event_refresh_msg {
|
|||||||
int callbackID;
|
int callbackID;
|
||||||
remote_nonnull_storage_pool pool;
|
remote_nonnull_storage_pool pool;
|
||||||
};
|
};
|
||||||
|
struct remote_connect_node_device_event_register_any_args {
|
||||||
|
int eventID;
|
||||||
|
remote_node_device dev;
|
||||||
|
};
|
||||||
|
struct remote_connect_node_device_event_register_any_ret {
|
||||||
|
int callbackID;
|
||||||
|
};
|
||||||
|
struct remote_connect_node_device_event_deregister_any_args {
|
||||||
|
int callbackID;
|
||||||
|
};
|
||||||
|
struct remote_node_device_event_lifecycle_msg {
|
||||||
|
int callbackID;
|
||||||
|
remote_nonnull_node_device dev;
|
||||||
|
int event;
|
||||||
|
int detail;
|
||||||
|
};
|
||||||
struct remote_domain_fsfreeze_args {
|
struct remote_domain_fsfreeze_args {
|
||||||
remote_nonnull_domain dom;
|
remote_nonnull_domain dom;
|
||||||
struct {
|
struct {
|
||||||
@ -3145,4 +3161,7 @@ enum remote_procedure {
|
|||||||
REMOTE_PROC_DOMAIN_GET_GUEST_VCPUS = 371,
|
REMOTE_PROC_DOMAIN_GET_GUEST_VCPUS = 371,
|
||||||
REMOTE_PROC_DOMAIN_SET_GUEST_VCPUS = 372,
|
REMOTE_PROC_DOMAIN_SET_GUEST_VCPUS = 372,
|
||||||
REMOTE_PROC_STORAGE_POOL_EVENT_REFRESH = 373,
|
REMOTE_PROC_STORAGE_POOL_EVENT_REFRESH = 373,
|
||||||
|
REMOTE_PROC_CONNECT_NODE_DEVICE_EVENT_REGISTER_ANY = 374,
|
||||||
|
REMOTE_PROC_CONNECT_NODE_DEVICE_EVENT_DEREGISTER_ANY = 375,
|
||||||
|
REMOTE_PROC_NODE_DEVICE_EVENT_LIFECYCLE = 376,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user