mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-11-02 11:21:12 +00:00
11f20e43f1
https://bugzilla.redhat.com/show_bug.cgi?id=1058839 Commitf9f56340
for CVE-2014-0028 almost had the right idea - we need to check the ACL rules to filter which events to send. But it overlooked one thing: the event dispatch queue is running in the main loop thread, and therefore does not normally have a current virIdentityPtr. But filter checks can be based on current identity, so when libvirtd.conf contains access_drivers=["polkit"], we ended up rejecting access for EVERY event due to failure to look up the current identity, even if it should have been allowed. Furthermore, even for events that are triggered by API calls, it is important to remember that the point of events is that they can be copied across multiple connections, which may have separate identities and permissions. So even if events were dispatched from a context where we have an identity, we must change to the correct identity of the connection that will be receiving the event, rather than basing a decision on the context that triggered the event, when deciding whether to filter an event to a particular connection. If there were an easy way to get from virConnectPtr to the appropriate virIdentityPtr, then object_event.c could adjust the identity prior to checking whether to dispatch an event. But setting up that back-reference is a bit invasive. Instead, it is easier to delay the filtering check until lower down the stack, at the point where we have direct access to the RPC client object that owns an identity. As such, this patch ends up reverting a large portion of the framework of commitf9f56340
. We also have to teach 'make check' to special-case the fact that the event registration filtering is done at the point of dispatch, rather than the point of registration. Note that even though we don't actually use virConnectDomainEventRegisterCheckACL (because the RegisterAny variant is sufficient), we still generate the function for the purposes of documenting that the filtering takes place. Also note that I did not entirely delete the notion of a filter from object_event.c; I still plan on using that for my upcoming patch series for qemu monitor events in libvirt-qemu.so. In other words, while this patch changes ACL filtering to live in remote.c and therefore we have no current client of the filtering in object_event.c, the notion of filtering in object_event.c is still useful down the road. * src/check-aclrules.pl: Exempt event registration from having to pass checkACL filter down call stack. * daemon/remote.c (remoteRelayDomainEventCheckACL) (remoteRelayNetworkEventCheckACL): New functions. (remoteRelay*Event*): Use new functions. * src/conf/domain_event.h (virDomainEventStateRegister) (virDomainEventStateRegisterID): Drop unused parameter. * src/conf/network_event.h (virNetworkEventStateRegisterID): Likewise. * src/conf/domain_event.c (virDomainEventFilter): Delete unused function. * src/conf/network_event.c (virNetworkEventFilter): Likewise. * src/libxl/libxl_driver.c: Adjust caller. * src/lxc/lxc_driver.c: Likewise. * src/network/bridge_driver.c: Likewise. * src/qemu/qemu_driver.c: Likewise. * src/remote/remote_driver.c: Likewise. * src/test/test_driver.c: Likewise. * src/uml/uml_driver.c: Likewise. * src/vbox/vbox_tmpl.c: Likewise. * src/xen/xen_driver.c: Likewise. Signed-off-by: Eric Blake <eblake@redhat.com>
1359 lines
42 KiB
C
1359 lines
42 KiB
C
/*
|
|
* domain_event.c: domain event queue processing helpers
|
|
*
|
|
* Copyright (C) 2010-2014 Red Hat, Inc.
|
|
* Copyright (C) 2008 VirtualIron
|
|
* Copyright (C) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Author: Ben Guthro
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include "domain_event.h"
|
|
#include "object_event.h"
|
|
#include "object_event_private.h"
|
|
#include "virlog.h"
|
|
#include "datatypes.h"
|
|
#include "viralloc.h"
|
|
#include "virerror.h"
|
|
#include "virstring.h"
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
|
|
|
|
|
static virClassPtr virDomainEventClass;
|
|
static virClassPtr virDomainEventLifecycleClass;
|
|
static virClassPtr virDomainEventRTCChangeClass;
|
|
static virClassPtr virDomainEventWatchdogClass;
|
|
static virClassPtr virDomainEventIOErrorClass;
|
|
static virClassPtr virDomainEventGraphicsClass;
|
|
static virClassPtr virDomainEventBlockJobClass;
|
|
static virClassPtr virDomainEventDiskChangeClass;
|
|
static virClassPtr virDomainEventTrayChangeClass;
|
|
static virClassPtr virDomainEventBalloonChangeClass;
|
|
static virClassPtr virDomainEventDeviceRemovedClass;
|
|
|
|
|
|
static void virDomainEventDispose(void *obj);
|
|
static void virDomainEventLifecycleDispose(void *obj);
|
|
static void virDomainEventRTCChangeDispose(void *obj);
|
|
static void virDomainEventWatchdogDispose(void *obj);
|
|
static void virDomainEventIOErrorDispose(void *obj);
|
|
static void virDomainEventGraphicsDispose(void *obj);
|
|
static void virDomainEventBlockJobDispose(void *obj);
|
|
static void virDomainEventDiskChangeDispose(void *obj);
|
|
static void virDomainEventTrayChangeDispose(void *obj);
|
|
static void virDomainEventBalloonChangeDispose(void *obj);
|
|
static void virDomainEventDeviceRemovedDispose(void *obj);
|
|
|
|
static void
|
|
virDomainEventDispatchDefaultFunc(virConnectPtr conn,
|
|
virObjectEventPtr event,
|
|
virConnectObjectEventGenericCallback cb,
|
|
void *cbopaque);
|
|
|
|
struct _virDomainEvent {
|
|
virObjectEvent parent;
|
|
|
|
/* Unused attribute to allow for subclass creation */
|
|
bool dummy;
|
|
};
|
|
typedef struct _virDomainEvent virDomainEvent;
|
|
typedef virDomainEvent *virDomainEventPtr;
|
|
|
|
struct _virDomainEventLifecycle {
|
|
virDomainEvent parent;
|
|
|
|
int type;
|
|
int detail;
|
|
};
|
|
typedef struct _virDomainEventLifecycle virDomainEventLifecycle;
|
|
typedef virDomainEventLifecycle *virDomainEventLifecyclePtr;
|
|
|
|
struct _virDomainEventRTCChange {
|
|
virDomainEvent parent;
|
|
|
|
long long offset;
|
|
};
|
|
typedef struct _virDomainEventRTCChange virDomainEventRTCChange;
|
|
typedef virDomainEventRTCChange *virDomainEventRTCChangePtr;
|
|
|
|
struct _virDomainEventWatchdog {
|
|
virDomainEvent parent;
|
|
|
|
int action;
|
|
};
|
|
typedef struct _virDomainEventWatchdog virDomainEventWatchdog;
|
|
typedef virDomainEventWatchdog *virDomainEventWatchdogPtr;
|
|
|
|
struct _virDomainEventIOError {
|
|
virDomainEvent parent;
|
|
|
|
char *srcPath;
|
|
char *devAlias;
|
|
int action;
|
|
char *reason;
|
|
};
|
|
typedef struct _virDomainEventIOError virDomainEventIOError;
|
|
typedef virDomainEventIOError *virDomainEventIOErrorPtr;
|
|
|
|
struct _virDomainEventBlockJob {
|
|
virDomainEvent parent;
|
|
|
|
char *path;
|
|
int type;
|
|
int status;
|
|
};
|
|
typedef struct _virDomainEventBlockJob virDomainEventBlockJob;
|
|
typedef virDomainEventBlockJob *virDomainEventBlockJobPtr;
|
|
|
|
struct _virDomainEventGraphics {
|
|
virDomainEvent parent;
|
|
|
|
int phase;
|
|
virDomainEventGraphicsAddressPtr local;
|
|
virDomainEventGraphicsAddressPtr remote;
|
|
char *authScheme;
|
|
virDomainEventGraphicsSubjectPtr subject;
|
|
};
|
|
typedef struct _virDomainEventGraphics virDomainEventGraphics;
|
|
typedef virDomainEventGraphics *virDomainEventGraphicsPtr;
|
|
|
|
struct _virDomainEventDiskChange {
|
|
virDomainEvent parent;
|
|
|
|
char *oldSrcPath;
|
|
char *newSrcPath;
|
|
char *devAlias;
|
|
int reason;
|
|
};
|
|
typedef struct _virDomainEventDiskChange virDomainEventDiskChange;
|
|
typedef virDomainEventDiskChange *virDomainEventDiskChangePtr;
|
|
|
|
struct _virDomainEventTrayChange {
|
|
virDomainEvent parent;
|
|
|
|
char *devAlias;
|
|
int reason;
|
|
};
|
|
typedef struct _virDomainEventTrayChange virDomainEventTrayChange;
|
|
typedef virDomainEventTrayChange *virDomainEventTrayChangePtr;
|
|
|
|
struct _virDomainEventBalloonChange {
|
|
virDomainEvent parent;
|
|
|
|
/* In unit of 1024 bytes */
|
|
unsigned long long actual;
|
|
};
|
|
typedef struct _virDomainEventBalloonChange virDomainEventBalloonChange;
|
|
typedef virDomainEventBalloonChange *virDomainEventBalloonChangePtr;
|
|
|
|
struct _virDomainEventDeviceRemoved {
|
|
virDomainEvent parent;
|
|
|
|
char *devAlias;
|
|
};
|
|
typedef struct _virDomainEventDeviceRemoved virDomainEventDeviceRemoved;
|
|
typedef virDomainEventDeviceRemoved *virDomainEventDeviceRemovedPtr;
|
|
|
|
|
|
static int
|
|
virDomainEventsOnceInit(void)
|
|
{
|
|
if (!(virDomainEventClass =
|
|
virClassNew(virClassForObjectEvent(),
|
|
"virDomainEvent",
|
|
sizeof(virDomainEvent),
|
|
virDomainEventDispose)))
|
|
return -1;
|
|
if (!(virDomainEventLifecycleClass =
|
|
virClassNew(virDomainEventClass,
|
|
"virDomainEventLifecycle",
|
|
sizeof(virDomainEventLifecycle),
|
|
virDomainEventLifecycleDispose)))
|
|
return -1;
|
|
if (!(virDomainEventRTCChangeClass =
|
|
virClassNew(virDomainEventClass,
|
|
"virDomainEventRTCChange",
|
|
sizeof(virDomainEventRTCChange),
|
|
virDomainEventRTCChangeDispose)))
|
|
return -1;
|
|
if (!(virDomainEventWatchdogClass =
|
|
virClassNew(virDomainEventClass,
|
|
"virDomainEventWatchdog",
|
|
sizeof(virDomainEventWatchdog),
|
|
virDomainEventWatchdogDispose)))
|
|
return -1;
|
|
if (!(virDomainEventIOErrorClass =
|
|
virClassNew(virDomainEventClass,
|
|
"virDomainEventIOError",
|
|
sizeof(virDomainEventIOError),
|
|
virDomainEventIOErrorDispose)))
|
|
return -1;
|
|
if (!(virDomainEventGraphicsClass =
|
|
virClassNew(virDomainEventClass,
|
|
"virDomainEventGraphics",
|
|
sizeof(virDomainEventGraphics),
|
|
virDomainEventGraphicsDispose)))
|
|
return -1;
|
|
if (!(virDomainEventBlockJobClass =
|
|
virClassNew(virDomainEventClass,
|
|
"virDomainEventBlockJob",
|
|
sizeof(virDomainEventBlockJob),
|
|
virDomainEventBlockJobDispose)))
|
|
return -1;
|
|
if (!(virDomainEventDiskChangeClass =
|
|
virClassNew(virDomainEventClass,
|
|
"virDomainEventDiskChange",
|
|
sizeof(virDomainEventDiskChange),
|
|
virDomainEventDiskChangeDispose)))
|
|
return -1;
|
|
if (!(virDomainEventTrayChangeClass =
|
|
virClassNew(virDomainEventClass,
|
|
"virDomainEventTrayChange",
|
|
sizeof(virDomainEventTrayChange),
|
|
virDomainEventTrayChangeDispose)))
|
|
return -1;
|
|
if (!(virDomainEventBalloonChangeClass =
|
|
virClassNew(virDomainEventClass,
|
|
"virDomainEventBalloonChange",
|
|
sizeof(virDomainEventBalloonChange),
|
|
virDomainEventBalloonChangeDispose)))
|
|
return -1;
|
|
if (!(virDomainEventDeviceRemovedClass =
|
|
virClassNew(virDomainEventClass,
|
|
"virDomainEventDeviceRemoved",
|
|
sizeof(virDomainEventDeviceRemoved),
|
|
virDomainEventDeviceRemovedDispose)))
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
VIR_ONCE_GLOBAL_INIT(virDomainEvents)
|
|
|
|
|
|
static void
|
|
virDomainEventDispose(void *obj)
|
|
{
|
|
virDomainEventPtr event = obj;
|
|
|
|
VIR_DEBUG("obj=%p", event);
|
|
}
|
|
|
|
static void
|
|
virDomainEventLifecycleDispose(void *obj)
|
|
{
|
|
virDomainEventLifecyclePtr event = obj;
|
|
VIR_DEBUG("obj=%p", event);
|
|
}
|
|
|
|
static void
|
|
virDomainEventRTCChangeDispose(void *obj)
|
|
{
|
|
virDomainEventRTCChangePtr event = obj;
|
|
VIR_DEBUG("obj=%p", event);
|
|
}
|
|
|
|
static void
|
|
virDomainEventWatchdogDispose(void *obj)
|
|
{
|
|
virDomainEventWatchdogPtr event = obj;
|
|
VIR_DEBUG("obj=%p", event);
|
|
}
|
|
|
|
static void
|
|
virDomainEventIOErrorDispose(void *obj)
|
|
{
|
|
virDomainEventIOErrorPtr event = obj;
|
|
VIR_DEBUG("obj=%p", event);
|
|
|
|
VIR_FREE(event->srcPath);
|
|
VIR_FREE(event->devAlias);
|
|
VIR_FREE(event->reason);
|
|
}
|
|
|
|
static void
|
|
virDomainEventGraphicsDispose(void *obj)
|
|
{
|
|
virDomainEventGraphicsPtr event = obj;
|
|
VIR_DEBUG("obj=%p", event);
|
|
|
|
if (event->local) {
|
|
VIR_FREE(event->local->node);
|
|
VIR_FREE(event->local->service);
|
|
VIR_FREE(event->local);
|
|
}
|
|
if (event->remote) {
|
|
VIR_FREE(event->remote->node);
|
|
VIR_FREE(event->remote->service);
|
|
VIR_FREE(event->remote);
|
|
}
|
|
VIR_FREE(event->authScheme);
|
|
if (event->subject) {
|
|
size_t i;
|
|
for (i = 0; i < event->subject->nidentity; i++) {
|
|
VIR_FREE(event->subject->identities[i].type);
|
|
VIR_FREE(event->subject->identities[i].name);
|
|
}
|
|
VIR_FREE(event->subject);
|
|
}
|
|
}
|
|
|
|
static void
|
|
virDomainEventBlockJobDispose(void *obj)
|
|
{
|
|
virDomainEventBlockJobPtr event = obj;
|
|
VIR_DEBUG("obj=%p", event);
|
|
|
|
VIR_FREE(event->path);
|
|
}
|
|
|
|
static void
|
|
virDomainEventDiskChangeDispose(void *obj)
|
|
{
|
|
virDomainEventDiskChangePtr event = obj;
|
|
VIR_DEBUG("obj=%p", event);
|
|
|
|
VIR_FREE(event->oldSrcPath);
|
|
VIR_FREE(event->newSrcPath);
|
|
VIR_FREE(event->devAlias);
|
|
}
|
|
|
|
static void
|
|
virDomainEventTrayChangeDispose(void *obj)
|
|
{
|
|
virDomainEventTrayChangePtr event = obj;
|
|
VIR_DEBUG("obj=%p", event);
|
|
|
|
VIR_FREE(event->devAlias);
|
|
}
|
|
|
|
static void
|
|
virDomainEventBalloonChangeDispose(void *obj)
|
|
{
|
|
virDomainEventBalloonChangePtr event = obj;
|
|
VIR_DEBUG("obj=%p", event);
|
|
}
|
|
|
|
static void
|
|
virDomainEventDeviceRemovedDispose(void *obj)
|
|
{
|
|
virDomainEventDeviceRemovedPtr event = obj;
|
|
VIR_DEBUG("obj=%p", event);
|
|
|
|
VIR_FREE(event->devAlias);
|
|
}
|
|
|
|
|
|
static void *
|
|
virDomainEventNew(virClassPtr klass,
|
|
int eventID,
|
|
int id,
|
|
const char *name,
|
|
const unsigned char *uuid)
|
|
{
|
|
virDomainEventPtr event;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!virClassIsDerivedFrom(klass, virDomainEventClass)) {
|
|
virReportInvalidArg(klass,
|
|
_("Class %s must derive from virDomainEvent"),
|
|
virClassName(klass));
|
|
return NULL;
|
|
}
|
|
|
|
if (!(event = virObjectEventNew(klass,
|
|
virDomainEventDispatchDefaultFunc,
|
|
eventID,
|
|
id, name, uuid)))
|
|
return NULL;
|
|
|
|
return (virObjectEventPtr)event;
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventLifecycleNew(int id,
|
|
const char *name,
|
|
const unsigned char *uuid,
|
|
int type,
|
|
int detail)
|
|
{
|
|
virDomainEventLifecyclePtr event;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(event = virDomainEventNew(virDomainEventLifecycleClass,
|
|
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
|
|
id, name, uuid)))
|
|
return NULL;
|
|
|
|
event->type = type;
|
|
event->detail = detail;
|
|
|
|
return (virObjectEventPtr)event;
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventLifecycleNewFromDom(virDomainPtr dom,
|
|
int type,
|
|
int detail)
|
|
{
|
|
return virDomainEventLifecycleNew(dom->id, dom->name, dom->uuid,
|
|
type, detail);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventLifecycleNewFromObj(virDomainObjPtr obj,
|
|
int type,
|
|
int detail)
|
|
{
|
|
return virDomainEventLifecycleNewFromDef(obj->def, type, detail);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventLifecycleNewFromDef(virDomainDefPtr def,
|
|
int type,
|
|
int detail)
|
|
{
|
|
return virDomainEventLifecycleNew(def->id, def->name, def->uuid,
|
|
type, detail);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventRebootNew(int id,
|
|
const char *name,
|
|
const unsigned char *uuid)
|
|
{
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
return virDomainEventNew(virDomainEventClass,
|
|
VIR_DOMAIN_EVENT_ID_REBOOT,
|
|
id, name, uuid);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventRebootNewFromDom(virDomainPtr dom)
|
|
{
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
return virDomainEventNew(virDomainEventClass,
|
|
VIR_DOMAIN_EVENT_ID_REBOOT,
|
|
dom->id, dom->name, dom->uuid);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventRebootNewFromObj(virDomainObjPtr obj)
|
|
{
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
return virDomainEventNew(virDomainEventClass,
|
|
VIR_DOMAIN_EVENT_ID_REBOOT,
|
|
obj->def->id, obj->def->name, obj->def->uuid);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventRTCChangeNewFromDom(virDomainPtr dom,
|
|
long long offset)
|
|
{
|
|
virDomainEventRTCChangePtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventRTCChangeClass,
|
|
VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
|
|
dom->id, dom->name, dom->uuid)))
|
|
return NULL;
|
|
|
|
ev->offset = offset;
|
|
|
|
return (virObjectEventPtr)ev;
|
|
}
|
|
virObjectEventPtr
|
|
virDomainEventRTCChangeNewFromObj(virDomainObjPtr obj,
|
|
long long offset)
|
|
{
|
|
virDomainEventRTCChangePtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventRTCChangeClass,
|
|
VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
|
|
obj->def->id, obj->def->name,
|
|
obj->def->uuid)))
|
|
return NULL;
|
|
|
|
ev->offset = offset;
|
|
|
|
return (virObjectEventPtr)ev;
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventWatchdogNewFromDom(virDomainPtr dom,
|
|
int action)
|
|
{
|
|
virDomainEventWatchdogPtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventWatchdogClass,
|
|
VIR_DOMAIN_EVENT_ID_WATCHDOG,
|
|
dom->id, dom->name, dom->uuid)))
|
|
return NULL;
|
|
|
|
ev->action = action;
|
|
|
|
return (virObjectEventPtr)ev;
|
|
}
|
|
virObjectEventPtr
|
|
virDomainEventWatchdogNewFromObj(virDomainObjPtr obj,
|
|
int action)
|
|
{
|
|
virDomainEventWatchdogPtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventWatchdogClass,
|
|
VIR_DOMAIN_EVENT_ID_WATCHDOG,
|
|
obj->def->id, obj->def->name,
|
|
obj->def->uuid)))
|
|
return NULL;
|
|
|
|
ev->action = action;
|
|
|
|
return (virObjectEventPtr)ev;
|
|
}
|
|
|
|
static virObjectEventPtr
|
|
virDomainEventIOErrorNewFromDomImpl(int event,
|
|
virDomainPtr dom,
|
|
const char *srcPath,
|
|
const char *devAlias,
|
|
int action,
|
|
const char *reason)
|
|
{
|
|
virDomainEventIOErrorPtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventIOErrorClass, event,
|
|
dom->id, dom->name, dom->uuid)))
|
|
return NULL;
|
|
|
|
ev->action = action;
|
|
if (VIR_STRDUP(ev->srcPath, srcPath) < 0 ||
|
|
VIR_STRDUP(ev->devAlias, devAlias) < 0 ||
|
|
VIR_STRDUP(ev->reason, reason) < 0) {
|
|
virObjectUnref(ev);
|
|
ev = NULL;
|
|
}
|
|
|
|
return (virObjectEventPtr)ev;
|
|
}
|
|
|
|
static virObjectEventPtr
|
|
virDomainEventIOErrorNewFromObjImpl(int event,
|
|
virDomainObjPtr obj,
|
|
const char *srcPath,
|
|
const char *devAlias,
|
|
int action,
|
|
const char *reason)
|
|
{
|
|
virDomainEventIOErrorPtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventIOErrorClass, event,
|
|
obj->def->id, obj->def->name,
|
|
obj->def->uuid)))
|
|
return NULL;
|
|
|
|
ev->action = action;
|
|
if (VIR_STRDUP(ev->srcPath, srcPath) < 0 ||
|
|
VIR_STRDUP(ev->devAlias, devAlias) < 0 ||
|
|
VIR_STRDUP(ev->reason, reason) < 0) {
|
|
virObjectUnref(ev);
|
|
ev = NULL;
|
|
}
|
|
|
|
return (virObjectEventPtr)ev;
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventIOErrorNewFromDom(virDomainPtr dom,
|
|
const char *srcPath,
|
|
const char *devAlias,
|
|
int action)
|
|
{
|
|
return virDomainEventIOErrorNewFromDomImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR,
|
|
dom, srcPath, devAlias,
|
|
action, NULL);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventIOErrorNewFromObj(virDomainObjPtr obj,
|
|
const char *srcPath,
|
|
const char *devAlias,
|
|
int action)
|
|
{
|
|
return virDomainEventIOErrorNewFromObjImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR,
|
|
obj, srcPath, devAlias,
|
|
action, NULL);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventIOErrorReasonNewFromDom(virDomainPtr dom,
|
|
const char *srcPath,
|
|
const char *devAlias,
|
|
int action,
|
|
const char *reason)
|
|
{
|
|
return virDomainEventIOErrorNewFromDomImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON,
|
|
dom, srcPath, devAlias,
|
|
action, reason);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventIOErrorReasonNewFromObj(virDomainObjPtr obj,
|
|
const char *srcPath,
|
|
const char *devAlias,
|
|
int action,
|
|
const char *reason)
|
|
{
|
|
return virDomainEventIOErrorNewFromObjImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON,
|
|
obj, srcPath, devAlias,
|
|
action, reason);
|
|
}
|
|
|
|
|
|
virObjectEventPtr
|
|
virDomainEventGraphicsNewFromDom(virDomainPtr dom,
|
|
int phase,
|
|
virDomainEventGraphicsAddressPtr local,
|
|
virDomainEventGraphicsAddressPtr remote,
|
|
const char *authScheme,
|
|
virDomainEventGraphicsSubjectPtr subject)
|
|
{
|
|
virDomainEventGraphicsPtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventGraphicsClass,
|
|
VIR_DOMAIN_EVENT_ID_GRAPHICS,
|
|
dom->id, dom->name, dom->uuid)))
|
|
return NULL;
|
|
|
|
ev->phase = phase;
|
|
if (VIR_STRDUP(ev->authScheme, authScheme) < 0) {
|
|
virObjectUnref(ev);
|
|
return NULL;
|
|
}
|
|
ev->local = local;
|
|
ev->remote = remote;
|
|
ev->subject = subject;
|
|
|
|
return (virObjectEventPtr)ev;
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventGraphicsNewFromObj(virDomainObjPtr obj,
|
|
int phase,
|
|
virDomainEventGraphicsAddressPtr local,
|
|
virDomainEventGraphicsAddressPtr remote,
|
|
const char *authScheme,
|
|
virDomainEventGraphicsSubjectPtr subject)
|
|
{
|
|
virDomainEventGraphicsPtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventGraphicsClass,
|
|
VIR_DOMAIN_EVENT_ID_GRAPHICS,
|
|
obj->def->id, obj->def->name,
|
|
obj->def->uuid)))
|
|
return NULL;
|
|
|
|
ev->phase = phase;
|
|
if (VIR_STRDUP(ev->authScheme, authScheme) < 0) {
|
|
virObjectUnref(ev);
|
|
return NULL;
|
|
}
|
|
ev->local = local;
|
|
ev->remote = remote;
|
|
ev->subject = subject;
|
|
|
|
return (virObjectEventPtr)ev;
|
|
}
|
|
|
|
static virObjectEventPtr
|
|
virDomainEventBlockJobNew(int id,
|
|
const char *name,
|
|
unsigned char *uuid,
|
|
const char *path,
|
|
int type,
|
|
int status)
|
|
{
|
|
virDomainEventBlockJobPtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventBlockJobClass,
|
|
VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
|
|
id, name, uuid)))
|
|
return NULL;
|
|
|
|
if (VIR_STRDUP(ev->path, path) < 0) {
|
|
virObjectUnref(ev);
|
|
return NULL;
|
|
}
|
|
ev->type = type;
|
|
ev->status = status;
|
|
|
|
return (virObjectEventPtr)ev;
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventBlockJobNewFromObj(virDomainObjPtr obj,
|
|
const char *path,
|
|
int type,
|
|
int status)
|
|
{
|
|
return virDomainEventBlockJobNew(obj->def->id, obj->def->name,
|
|
obj->def->uuid, path, type, status);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventBlockJobNewFromDom(virDomainPtr dom,
|
|
const char *path,
|
|
int type,
|
|
int status)
|
|
{
|
|
return virDomainEventBlockJobNew(dom->id, dom->name, dom->uuid,
|
|
path, type, status);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventControlErrorNewFromDom(virDomainPtr dom)
|
|
{
|
|
virObjectEventPtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventClass,
|
|
VIR_DOMAIN_EVENT_ID_CONTROL_ERROR,
|
|
dom->id, dom->name, dom->uuid)))
|
|
return NULL;
|
|
return ev;
|
|
}
|
|
|
|
|
|
virObjectEventPtr
|
|
virDomainEventControlErrorNewFromObj(virDomainObjPtr obj)
|
|
{
|
|
virObjectEventPtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventClass,
|
|
VIR_DOMAIN_EVENT_ID_CONTROL_ERROR,
|
|
obj->def->id, obj->def->name,
|
|
obj->def->uuid)))
|
|
return NULL;
|
|
return ev;
|
|
}
|
|
|
|
static virObjectEventPtr
|
|
virDomainEventDiskChangeNew(int id,
|
|
const char *name,
|
|
unsigned char *uuid,
|
|
const char *oldSrcPath,
|
|
const char *newSrcPath,
|
|
const char *devAlias,
|
|
int reason)
|
|
{
|
|
virDomainEventDiskChangePtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventDiskChangeClass,
|
|
VIR_DOMAIN_EVENT_ID_DISK_CHANGE,
|
|
id, name, uuid)))
|
|
return NULL;
|
|
|
|
if (VIR_STRDUP(ev->devAlias, devAlias) < 0)
|
|
goto error;
|
|
|
|
if (VIR_STRDUP(ev->oldSrcPath, oldSrcPath) < 0)
|
|
goto error;
|
|
|
|
if (VIR_STRDUP(ev->newSrcPath, newSrcPath) < 0)
|
|
goto error;
|
|
|
|
ev->reason = reason;
|
|
|
|
return (virObjectEventPtr)ev;
|
|
|
|
error:
|
|
virObjectUnref(ev);
|
|
return NULL;
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventDiskChangeNewFromObj(virDomainObjPtr obj,
|
|
const char *oldSrcPath,
|
|
const char *newSrcPath,
|
|
const char *devAlias,
|
|
int reason)
|
|
{
|
|
return virDomainEventDiskChangeNew(obj->def->id, obj->def->name,
|
|
obj->def->uuid, oldSrcPath,
|
|
newSrcPath, devAlias, reason);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventDiskChangeNewFromDom(virDomainPtr dom,
|
|
const char *oldSrcPath,
|
|
const char *newSrcPath,
|
|
const char *devAlias,
|
|
int reason)
|
|
{
|
|
return virDomainEventDiskChangeNew(dom->id, dom->name, dom->uuid,
|
|
oldSrcPath, newSrcPath,
|
|
devAlias, reason);
|
|
}
|
|
|
|
static virObjectEventPtr
|
|
virDomainEventTrayChangeNew(int id,
|
|
const char *name,
|
|
unsigned char *uuid,
|
|
const char *devAlias,
|
|
int reason)
|
|
{
|
|
virDomainEventTrayChangePtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventTrayChangeClass,
|
|
VIR_DOMAIN_EVENT_ID_TRAY_CHANGE,
|
|
id, name, uuid)))
|
|
return NULL;
|
|
|
|
if (VIR_STRDUP(ev->devAlias, devAlias) < 0)
|
|
goto error;
|
|
|
|
ev->reason = reason;
|
|
|
|
return (virObjectEventPtr)ev;
|
|
|
|
error:
|
|
virObjectUnref(ev);
|
|
return NULL;
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventTrayChangeNewFromObj(virDomainObjPtr obj,
|
|
const char *devAlias,
|
|
int reason)
|
|
{
|
|
return virDomainEventTrayChangeNew(obj->def->id,
|
|
obj->def->name,
|
|
obj->def->uuid,
|
|
devAlias,
|
|
reason);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventTrayChangeNewFromDom(virDomainPtr dom,
|
|
const char *devAlias,
|
|
int reason)
|
|
{
|
|
return virDomainEventTrayChangeNew(dom->id, dom->name, dom->uuid,
|
|
devAlias, reason);
|
|
}
|
|
|
|
static virObjectEventPtr
|
|
virDomainEventPMWakeupNew(int id,
|
|
const char *name,
|
|
unsigned char *uuid)
|
|
{
|
|
virObjectEventPtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventClass,
|
|
VIR_DOMAIN_EVENT_ID_PMWAKEUP,
|
|
id, name, uuid)))
|
|
return NULL;
|
|
|
|
return ev;
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventPMWakeupNewFromObj(virDomainObjPtr obj)
|
|
{
|
|
return virDomainEventPMWakeupNew(obj->def->id,
|
|
obj->def->name,
|
|
obj->def->uuid);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventPMWakeupNewFromDom(virDomainPtr dom)
|
|
{
|
|
return virDomainEventPMWakeupNew(dom->id, dom->name, dom->uuid);
|
|
}
|
|
|
|
static virObjectEventPtr
|
|
virDomainEventPMSuspendNew(int id,
|
|
const char *name,
|
|
unsigned char *uuid)
|
|
{
|
|
virObjectEventPtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventClass,
|
|
VIR_DOMAIN_EVENT_ID_PMSUSPEND,
|
|
id, name, uuid)))
|
|
return NULL;
|
|
|
|
return ev;
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventPMSuspendNewFromObj(virDomainObjPtr obj)
|
|
{
|
|
return virDomainEventPMSuspendNew(obj->def->id,
|
|
obj->def->name,
|
|
obj->def->uuid);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventPMSuspendNewFromDom(virDomainPtr dom)
|
|
{
|
|
return virDomainEventPMSuspendNew(dom->id, dom->name, dom->uuid);
|
|
}
|
|
|
|
static virObjectEventPtr
|
|
virDomainEventPMSuspendDiskNew(int id,
|
|
const char *name,
|
|
unsigned char *uuid)
|
|
{
|
|
virObjectEventPtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventClass,
|
|
VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK,
|
|
id, name, uuid)))
|
|
return NULL;
|
|
return ev;
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventPMSuspendDiskNewFromObj(virDomainObjPtr obj)
|
|
{
|
|
return virDomainEventPMSuspendDiskNew(obj->def->id,
|
|
obj->def->name,
|
|
obj->def->uuid);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventPMSuspendDiskNewFromDom(virDomainPtr dom)
|
|
{
|
|
return virDomainEventPMSuspendDiskNew(dom->id, dom->name, dom->uuid);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventBalloonChangeNewFromDom(virDomainPtr dom,
|
|
unsigned long long actual)
|
|
{
|
|
virDomainEventBalloonChangePtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventBalloonChangeClass,
|
|
VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE,
|
|
dom->id, dom->name, dom->uuid)))
|
|
return NULL;
|
|
|
|
ev->actual = actual;
|
|
|
|
return (virObjectEventPtr)ev;
|
|
}
|
|
virObjectEventPtr
|
|
virDomainEventBalloonChangeNewFromObj(virDomainObjPtr obj,
|
|
unsigned long long actual)
|
|
{
|
|
virDomainEventBalloonChangePtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventBalloonChangeClass,
|
|
VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE,
|
|
obj->def->id, obj->def->name, obj->def->uuid)))
|
|
return NULL;
|
|
|
|
ev->actual = actual;
|
|
|
|
return (virObjectEventPtr)ev;
|
|
}
|
|
|
|
static virObjectEventPtr
|
|
virDomainEventDeviceRemovedNew(int id,
|
|
const char *name,
|
|
unsigned char *uuid,
|
|
const char *devAlias)
|
|
{
|
|
virDomainEventDeviceRemovedPtr ev;
|
|
|
|
if (virDomainEventsInitialize() < 0)
|
|
return NULL;
|
|
|
|
if (!(ev = virDomainEventNew(virDomainEventDeviceRemovedClass,
|
|
VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED,
|
|
id, name, uuid)))
|
|
return NULL;
|
|
|
|
if (VIR_STRDUP(ev->devAlias, devAlias) < 0)
|
|
goto error;
|
|
|
|
return (virObjectEventPtr)ev;
|
|
|
|
error:
|
|
virObjectUnref(ev);
|
|
return NULL;
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventDeviceRemovedNewFromObj(virDomainObjPtr obj,
|
|
const char *devAlias)
|
|
{
|
|
return virDomainEventDeviceRemovedNew(obj->def->id, obj->def->name,
|
|
obj->def->uuid, devAlias);
|
|
}
|
|
|
|
virObjectEventPtr
|
|
virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
|
|
const char *devAlias)
|
|
{
|
|
return virDomainEventDeviceRemovedNew(dom->id, dom->name, dom->uuid,
|
|
devAlias);
|
|
}
|
|
|
|
|
|
static void
|
|
virDomainEventDispatchDefaultFunc(virConnectPtr conn,
|
|
virObjectEventPtr event,
|
|
virConnectObjectEventGenericCallback cb,
|
|
void *cbopaque)
|
|
{
|
|
virDomainPtr dom = virGetDomain(conn, event->meta.name, event->meta.uuid);
|
|
if (!dom)
|
|
return;
|
|
dom->id = event->meta.id;
|
|
|
|
switch ((virDomainEventID) event->eventID) {
|
|
case VIR_DOMAIN_EVENT_ID_LIFECYCLE:
|
|
{
|
|
virDomainEventLifecyclePtr lifecycleEvent;
|
|
|
|
lifecycleEvent = (virDomainEventLifecyclePtr)event;
|
|
((virConnectDomainEventCallback)cb)(conn, dom,
|
|
lifecycleEvent->type,
|
|
lifecycleEvent->detail,
|
|
cbopaque);
|
|
goto cleanup;
|
|
}
|
|
|
|
case VIR_DOMAIN_EVENT_ID_REBOOT:
|
|
(cb)(conn, dom,
|
|
cbopaque);
|
|
goto cleanup;
|
|
|
|
case VIR_DOMAIN_EVENT_ID_RTC_CHANGE:
|
|
{
|
|
virDomainEventRTCChangePtr rtcChangeEvent;
|
|
|
|
rtcChangeEvent = (virDomainEventRTCChangePtr)event;
|
|
((virConnectDomainEventRTCChangeCallback)cb)(conn, dom,
|
|
rtcChangeEvent->offset,
|
|
cbopaque);
|
|
goto cleanup;
|
|
}
|
|
|
|
case VIR_DOMAIN_EVENT_ID_WATCHDOG:
|
|
{
|
|
virDomainEventWatchdogPtr watchdogEvent;
|
|
|
|
watchdogEvent = (virDomainEventWatchdogPtr)event;
|
|
((virConnectDomainEventWatchdogCallback)cb)(conn, dom,
|
|
watchdogEvent->action,
|
|
cbopaque);
|
|
goto cleanup;
|
|
}
|
|
|
|
case VIR_DOMAIN_EVENT_ID_IO_ERROR:
|
|
{
|
|
virDomainEventIOErrorPtr ioErrorEvent;
|
|
|
|
ioErrorEvent = (virDomainEventIOErrorPtr)event;
|
|
((virConnectDomainEventIOErrorCallback)cb)(conn, dom,
|
|
ioErrorEvent->srcPath,
|
|
ioErrorEvent->devAlias,
|
|
ioErrorEvent->action,
|
|
cbopaque);
|
|
goto cleanup;
|
|
}
|
|
|
|
case VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON:
|
|
{
|
|
virDomainEventIOErrorPtr ioErrorEvent;
|
|
|
|
ioErrorEvent = (virDomainEventIOErrorPtr)event;
|
|
((virConnectDomainEventIOErrorReasonCallback)cb)(conn, dom,
|
|
ioErrorEvent->srcPath,
|
|
ioErrorEvent->devAlias,
|
|
ioErrorEvent->action,
|
|
ioErrorEvent->reason,
|
|
cbopaque);
|
|
goto cleanup;
|
|
}
|
|
|
|
case VIR_DOMAIN_EVENT_ID_GRAPHICS:
|
|
{
|
|
virDomainEventGraphicsPtr graphicsEvent;
|
|
|
|
graphicsEvent = (virDomainEventGraphicsPtr)event;
|
|
((virConnectDomainEventGraphicsCallback)cb)(conn, dom,
|
|
graphicsEvent->phase,
|
|
graphicsEvent->local,
|
|
graphicsEvent->remote,
|
|
graphicsEvent->authScheme,
|
|
graphicsEvent->subject,
|
|
cbopaque);
|
|
goto cleanup;
|
|
}
|
|
|
|
case VIR_DOMAIN_EVENT_ID_CONTROL_ERROR:
|
|
(cb)(conn, dom,
|
|
cbopaque);
|
|
goto cleanup;
|
|
|
|
case VIR_DOMAIN_EVENT_ID_BLOCK_JOB:
|
|
{
|
|
virDomainEventBlockJobPtr blockJobEvent;
|
|
|
|
blockJobEvent = (virDomainEventBlockJobPtr)event;
|
|
((virConnectDomainEventBlockJobCallback)cb)(conn, dom,
|
|
blockJobEvent->path,
|
|
blockJobEvent->type,
|
|
blockJobEvent->status,
|
|
cbopaque);
|
|
goto cleanup;
|
|
}
|
|
|
|
case VIR_DOMAIN_EVENT_ID_DISK_CHANGE:
|
|
{
|
|
virDomainEventDiskChangePtr diskChangeEvent;
|
|
|
|
diskChangeEvent = (virDomainEventDiskChangePtr)event;
|
|
((virConnectDomainEventDiskChangeCallback)cb)(conn, dom,
|
|
diskChangeEvent->oldSrcPath,
|
|
diskChangeEvent->newSrcPath,
|
|
diskChangeEvent->devAlias,
|
|
diskChangeEvent->reason,
|
|
cbopaque);
|
|
goto cleanup;
|
|
}
|
|
|
|
case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE:
|
|
{
|
|
virDomainEventTrayChangePtr trayChangeEvent;
|
|
|
|
trayChangeEvent = (virDomainEventTrayChangePtr)event;
|
|
((virConnectDomainEventTrayChangeCallback)cb)(conn, dom,
|
|
trayChangeEvent->devAlias,
|
|
trayChangeEvent->reason,
|
|
cbopaque);
|
|
goto cleanup;
|
|
}
|
|
|
|
case VIR_DOMAIN_EVENT_ID_PMWAKEUP:
|
|
((virConnectDomainEventPMWakeupCallback)cb)(conn, dom, 0, cbopaque);
|
|
goto cleanup;
|
|
|
|
case VIR_DOMAIN_EVENT_ID_PMSUSPEND:
|
|
((virConnectDomainEventPMSuspendCallback)cb)(conn, dom, 0, cbopaque);
|
|
goto cleanup;
|
|
|
|
case VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE:
|
|
{
|
|
virDomainEventBalloonChangePtr balloonChangeEvent;
|
|
|
|
balloonChangeEvent = (virDomainEventBalloonChangePtr)event;
|
|
((virConnectDomainEventBalloonChangeCallback)cb)(conn, dom,
|
|
balloonChangeEvent->actual,
|
|
cbopaque);
|
|
goto cleanup;
|
|
}
|
|
|
|
case VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK:
|
|
((virConnectDomainEventPMSuspendDiskCallback)cb)(conn, dom, 0, cbopaque);
|
|
goto cleanup;
|
|
|
|
case VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED:
|
|
{
|
|
virDomainEventDeviceRemovedPtr deviceRemovedEvent;
|
|
|
|
deviceRemovedEvent = (virDomainEventDeviceRemovedPtr)event;
|
|
((virConnectDomainEventDeviceRemovedCallback)cb)(conn, dom,
|
|
deviceRemovedEvent->devAlias,
|
|
cbopaque);
|
|
goto cleanup;
|
|
}
|
|
|
|
case VIR_DOMAIN_EVENT_ID_LAST:
|
|
break;
|
|
}
|
|
|
|
VIR_WARN("Unexpected event ID %d", event->eventID);
|
|
|
|
cleanup:
|
|
virDomainFree(dom);
|
|
}
|
|
|
|
|
|
/**
|
|
* virDomainEventStateRegister:
|
|
* @conn: connection to associate with callback
|
|
* @state: object event state
|
|
* @callback: the callback to add
|
|
* @opaque: data blob to pass to @callback
|
|
* @freecb: callback to free @opaque
|
|
*
|
|
* Register the function @callback with connection @conn,
|
|
* from @state, for lifecycle events.
|
|
*
|
|
* Returns: the number of lifecycle callbacks now registered, or -1 on error
|
|
*/
|
|
int
|
|
virDomainEventStateRegister(virConnectPtr conn,
|
|
virObjectEventStatePtr state,
|
|
virConnectDomainEventCallback callback,
|
|
void *opaque,
|
|
virFreeCallback freecb)
|
|
{
|
|
if (virDomainEventsInitialize() < 0)
|
|
return -1;
|
|
|
|
return virObjectEventStateRegisterID(conn, state, NULL,
|
|
NULL, NULL, virDomainEventClass,
|
|
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
|
|
VIR_OBJECT_EVENT_CALLBACK(callback),
|
|
opaque, freecb, NULL, false);
|
|
}
|
|
|
|
|
|
/**
|
|
* virDomainEventStateRegisterID:
|
|
* @conn: connection to associate with callback
|
|
* @state: object event state
|
|
* @dom: optional domain for filtering the event
|
|
* @eventID: ID of the event type to register for
|
|
* @cb: function to invoke when event fires
|
|
* @opaque: data blob to pass to @callback
|
|
* @freecb: callback to free @opaque
|
|
* @callbackID: filled with callback ID
|
|
*
|
|
* Register the function @cb with connection @conn, from @state, for
|
|
* events of type @eventID, and return the registration handle in
|
|
* @callbackID.
|
|
*
|
|
* Returns: the number of callbacks now registered, or -1 on error
|
|
*/
|
|
int
|
|
virDomainEventStateRegisterID(virConnectPtr conn,
|
|
virObjectEventStatePtr state,
|
|
virDomainPtr dom,
|
|
int eventID,
|
|
virConnectDomainEventGenericCallback cb,
|
|
void *opaque,
|
|
virFreeCallback freecb,
|
|
int *callbackID)
|
|
{
|
|
if (virDomainEventsInitialize() < 0)
|
|
return -1;
|
|
|
|
return virObjectEventStateRegisterID(conn, state, dom ? dom->uuid : NULL,
|
|
NULL, NULL,
|
|
virDomainEventClass, eventID,
|
|
VIR_OBJECT_EVENT_CALLBACK(cb),
|
|
opaque, freecb, callbackID, false);
|
|
}
|
|
|
|
|
|
/**
|
|
* virDomainEventStateDeregister:
|
|
* @conn: connection to associate with callback
|
|
* @state: object event state
|
|
* @cb: function to remove from event
|
|
*
|
|
* Unregister the function @cb with connection @conn, from @state, for
|
|
* lifecycle events.
|
|
*
|
|
* Returns: the number of lifecycle callbacks still registered, or -1 on error
|
|
*/
|
|
int
|
|
virDomainEventStateDeregister(virConnectPtr conn,
|
|
virObjectEventStatePtr state,
|
|
virConnectDomainEventCallback cb)
|
|
{
|
|
int callbackID;
|
|
|
|
callbackID = virObjectEventStateCallbackID(conn, state,
|
|
virDomainEventClass,
|
|
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
|
|
VIR_OBJECT_EVENT_CALLBACK(cb));
|
|
if (callbackID < 0)
|
|
return -1;
|
|
return virObjectEventStateDeregisterID(conn, state, callbackID);
|
|
}
|