1 /*
2  * domain_event.c: domain event queue processing helpers
3  *
4  * Copyright (C) 2010-2014 Red Hat, Inc.
5  * Copyright (C) 2008 VirtualIron
6  * Copyright (C) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library.  If not, see
20  * <http://www.gnu.org/licenses/>.
21  */
22 
23 #include <config.h>
24 
25 #include "domain_event.h"
26 #include "object_event.h"
27 #include "object_event_private.h"
28 #include "virlog.h"
29 #include "datatypes.h"
30 #include "viralloc.h"
31 #include "virerror.h"
32 #include "virstring.h"
33 #include "virtypedparam.h"
34 
35 #define VIR_FROM_THIS VIR_FROM_NONE
36 
37 VIR_LOG_INIT("util.domain_event");
38 
39 static virClass *virDomainEventClass;
40 static virClass *virDomainEventLifecycleClass;
41 static virClass *virDomainEventRTCChangeClass;
42 static virClass *virDomainEventWatchdogClass;
43 static virClass *virDomainEventIOErrorClass;
44 static virClass *virDomainEventGraphicsClass;
45 static virClass *virDomainEventBlockJobClass;
46 static virClass *virDomainEventDiskChangeClass;
47 static virClass *virDomainEventTrayChangeClass;
48 static virClass *virDomainEventBalloonChangeClass;
49 static virClass *virDomainEventDeviceRemovedClass;
50 static virClass *virDomainEventPMClass;
51 static virClass *virDomainQemuMonitorEventClass;
52 static virClass *virDomainEventTunableClass;
53 static virClass *virDomainEventAgentLifecycleClass;
54 static virClass *virDomainEventDeviceAddedClass;
55 static virClass *virDomainEventMigrationIterationClass;
56 static virClass *virDomainEventJobCompletedClass;
57 static virClass *virDomainEventDeviceRemovalFailedClass;
58 static virClass *virDomainEventMetadataChangeClass;
59 static virClass *virDomainEventBlockThresholdClass;
60 static virClass *virDomainEventMemoryFailureClass;
61 static virClass *virDomainEventMemoryDeviceSizeChangeClass;
62 
63 static void virDomainEventDispose(void *obj);
64 static void virDomainEventLifecycleDispose(void *obj);
65 static void virDomainEventRTCChangeDispose(void *obj);
66 static void virDomainEventWatchdogDispose(void *obj);
67 static void virDomainEventIOErrorDispose(void *obj);
68 static void virDomainEventGraphicsDispose(void *obj);
69 static void virDomainEventBlockJobDispose(void *obj);
70 static void virDomainEventDiskChangeDispose(void *obj);
71 static void virDomainEventTrayChangeDispose(void *obj);
72 static void virDomainEventBalloonChangeDispose(void *obj);
73 static void virDomainEventDeviceRemovedDispose(void *obj);
74 static void virDomainEventPMDispose(void *obj);
75 static void virDomainQemuMonitorEventDispose(void *obj);
76 static void virDomainEventTunableDispose(void *obj);
77 static void virDomainEventAgentLifecycleDispose(void *obj);
78 static void virDomainEventDeviceAddedDispose(void *obj);
79 static void virDomainEventMigrationIterationDispose(void *obj);
80 static void virDomainEventJobCompletedDispose(void *obj);
81 static void virDomainEventDeviceRemovalFailedDispose(void *obj);
82 static void virDomainEventMetadataChangeDispose(void *obj);
83 static void virDomainEventBlockThresholdDispose(void *obj);
84 static void virDomainEventMemoryFailureDispose(void *obj);
85 static void virDomainEventMemoryDeviceSizeChangeDispose(void *obj);
86 
87 static void
88 virDomainEventDispatchDefaultFunc(virConnectPtr conn,
89                                   virObjectEvent *event,
90                                   virConnectObjectEventGenericCallback cb,
91                                   void *cbopaque);
92 
93 static void
94 virDomainQemuMonitorEventDispatchFunc(virConnectPtr conn,
95                                       virObjectEvent *event,
96                                       virConnectObjectEventGenericCallback cb,
97                                       void *cbopaque);
98 
99 struct _virDomainEvent {
100     virObjectEvent parent;
101 
102     /* Unused attribute to allow for subclass creation */
103     bool dummy;
104 };
105 typedef struct _virDomainEvent virDomainEvent;
106 
107 struct _virDomainEventLifecycle {
108     virDomainEvent parent;
109 
110     int type;
111     int detail;
112 };
113 typedef struct _virDomainEventLifecycle virDomainEventLifecycle;
114 
115 struct _virDomainEventRTCChange {
116     virDomainEvent parent;
117 
118     long long offset;
119 };
120 typedef struct _virDomainEventRTCChange virDomainEventRTCChange;
121 
122 struct _virDomainEventWatchdog {
123     virDomainEvent parent;
124 
125     int action;
126 };
127 typedef struct _virDomainEventWatchdog virDomainEventWatchdog;
128 
129 struct _virDomainEventIOError {
130     virDomainEvent parent;
131 
132     char *srcPath;
133     char *devAlias;
134     int action;
135     char *reason;
136 };
137 typedef struct _virDomainEventIOError virDomainEventIOError;
138 
139 struct _virDomainEventBlockJob {
140     virDomainEvent parent;
141 
142     char *disk; /* path or dst, depending on event id */
143     int type;
144     int status;
145 };
146 typedef struct _virDomainEventBlockJob virDomainEventBlockJob;
147 
148 struct _virDomainEventGraphics {
149     virDomainEvent parent;
150 
151     int phase;
152     virDomainEventGraphicsAddressPtr local;
153     virDomainEventGraphicsAddressPtr remote;
154     char *authScheme;
155     virDomainEventGraphicsSubjectPtr subject;
156 };
157 typedef struct _virDomainEventGraphics virDomainEventGraphics;
158 
159 struct _virDomainEventDiskChange {
160     virDomainEvent parent;
161 
162     char *oldSrcPath;
163     char *newSrcPath;
164     char *devAlias;
165     int reason;
166 };
167 typedef struct _virDomainEventDiskChange virDomainEventDiskChange;
168 
169 struct _virDomainEventTrayChange {
170     virDomainEvent parent;
171 
172     char *devAlias;
173     int reason;
174 };
175 typedef struct _virDomainEventTrayChange virDomainEventTrayChange;
176 
177 struct _virDomainEventBalloonChange {
178     virDomainEvent parent;
179 
180     /* In unit of 1024 bytes */
181     unsigned long long actual;
182 };
183 typedef struct _virDomainEventBalloonChange virDomainEventBalloonChange;
184 
185 struct _virDomainEventDeviceRemoved {
186     virDomainEvent parent;
187 
188     char *devAlias;
189 };
190 typedef struct _virDomainEventDeviceRemoved virDomainEventDeviceRemoved;
191 
192 struct _virDomainEventDeviceAdded {
193     virDomainEvent parent;
194 
195     char *devAlias;
196 };
197 typedef struct _virDomainEventDeviceAdded virDomainEventDeviceAdded;
198 
199 struct _virDomainEventPM {
200     virDomainEvent parent;
201 
202     int reason;
203 };
204 typedef struct _virDomainEventPM virDomainEventPM;
205 
206 struct _virDomainQemuMonitorEvent {
207     virObjectEvent parent;
208 
209     char *event;
210     long long seconds;
211     unsigned int micros;
212     char *details;
213 };
214 typedef struct _virDomainQemuMonitorEvent virDomainQemuMonitorEvent;
215 
216 struct _virDomainEventTunable {
217     virDomainEvent parent;
218 
219     virTypedParameterPtr params;
220     int nparams;
221 };
222 typedef struct _virDomainEventTunable virDomainEventTunable;
223 
224 struct _virDomainEventAgentLifecycle {
225     virDomainEvent parent;
226 
227     int state;
228     int reason;
229 };
230 typedef struct _virDomainEventAgentLifecycle virDomainEventAgentLifecycle;
231 
232 struct _virDomainEventMigrationIteration {
233     virDomainEvent parent;
234 
235     int iteration;
236 };
237 typedef struct _virDomainEventMigrationIteration virDomainEventMigrationIteration;
238 
239 struct _virDomainEventJobCompleted {
240     virDomainEvent parent;
241 
242     virTypedParameterPtr params;
243     int nparams;
244 };
245 typedef struct _virDomainEventJobCompleted virDomainEventJobCompleted;
246 
247 struct _virDomainEventDeviceRemovalFailed {
248     virDomainEvent parent;
249 
250     char *devAlias;
251 };
252 typedef struct _virDomainEventDeviceRemovalFailed virDomainEventDeviceRemovalFailed;
253 
254 struct _virDomainEventMetadataChange {
255     virDomainEvent parent;
256 
257     int type;
258     char *nsuri;
259 };
260 typedef struct _virDomainEventMetadataChange virDomainEventMetadataChange;
261 
262 struct _virDomainEventBlockThreshold {
263     virDomainEvent parent;
264 
265     char *dev;
266     char *path;
267 
268     unsigned long long threshold;
269     unsigned long long excess;
270 };
271 typedef struct _virDomainEventBlockThreshold virDomainEventBlockThreshold;
272 
273 struct _virDomainEventMemoryFailure {
274     virDomainEvent parent;
275 
276     int recipient;
277     int action;
278     unsigned int flags;
279 };
280 typedef struct _virDomainEventMemoryFailure virDomainEventMemoryFailure;
281 
282 struct _virDomainEventMemoryDeviceSizeChange {
283     virDomainEvent parent;
284 
285     char *alias;
286     unsigned long long size;
287 };
288 typedef struct _virDomainEventMemoryDeviceSizeChange virDomainEventMemoryDeviceSizeChange;
289 typedef virDomainEventMemoryDeviceSizeChange *virDomainEventMemoryDeviceSizeChangePtr;
290 
291 static int
virDomainEventsOnceInit(void)292 virDomainEventsOnceInit(void)
293 {
294     if (!VIR_CLASS_NEW(virDomainEvent, virClassForObjectEvent()))
295         return -1;
296     if (!VIR_CLASS_NEW(virDomainEventLifecycle, virDomainEventClass))
297         return -1;
298     if (!VIR_CLASS_NEW(virDomainEventRTCChange, virDomainEventClass))
299         return -1;
300     if (!VIR_CLASS_NEW(virDomainEventWatchdog, virDomainEventClass))
301         return -1;
302     if (!VIR_CLASS_NEW(virDomainEventIOError, virDomainEventClass))
303         return -1;
304     if (!VIR_CLASS_NEW(virDomainEventGraphics, virDomainEventClass))
305         return -1;
306     if (!VIR_CLASS_NEW(virDomainEventBlockJob, virDomainEventClass))
307         return -1;
308     if (!VIR_CLASS_NEW(virDomainEventDiskChange, virDomainEventClass))
309         return -1;
310     if (!VIR_CLASS_NEW(virDomainEventTrayChange, virDomainEventClass))
311         return -1;
312     if (!VIR_CLASS_NEW(virDomainEventBalloonChange, virDomainEventClass))
313         return -1;
314     if (!VIR_CLASS_NEW(virDomainEventDeviceRemoved, virDomainEventClass))
315         return -1;
316     if (!VIR_CLASS_NEW(virDomainEventDeviceAdded, virDomainEventClass))
317         return -1;
318     if (!VIR_CLASS_NEW(virDomainEventPM, virDomainEventClass))
319         return -1;
320     if (!VIR_CLASS_NEW(virDomainQemuMonitorEvent, virClassForObjectEvent()))
321         return -1;
322     if (!VIR_CLASS_NEW(virDomainEventTunable, virDomainEventClass))
323         return -1;
324     if (!VIR_CLASS_NEW(virDomainEventAgentLifecycle, virDomainEventClass))
325         return -1;
326     if (!VIR_CLASS_NEW(virDomainEventMigrationIteration, virDomainEventClass))
327         return -1;
328     if (!VIR_CLASS_NEW(virDomainEventJobCompleted, virDomainEventClass))
329         return -1;
330     if (!VIR_CLASS_NEW(virDomainEventDeviceRemovalFailed, virDomainEventClass))
331         return -1;
332     if (!VIR_CLASS_NEW(virDomainEventMetadataChange, virDomainEventClass))
333         return -1;
334     if (!VIR_CLASS_NEW(virDomainEventBlockThreshold, virDomainEventClass))
335         return -1;
336     if (!VIR_CLASS_NEW(virDomainEventMemoryFailure, virDomainEventClass))
337         return -1;
338     if (!VIR_CLASS_NEW(virDomainEventMemoryDeviceSizeChange, virDomainEventClass))
339         return -1;
340     return 0;
341 }
342 
343 VIR_ONCE_GLOBAL_INIT(virDomainEvents);
344 
345 
346 static void
virDomainEventDispose(void * obj)347 virDomainEventDispose(void *obj)
348 {
349     virDomainEvent *event = obj;
350 
351     VIR_DEBUG("obj=%p", event);
352 }
353 
354 static void
virDomainEventLifecycleDispose(void * obj)355 virDomainEventLifecycleDispose(void *obj)
356 {
357     virDomainEventLifecycle *event = obj;
358     VIR_DEBUG("obj=%p", event);
359 }
360 
361 static void
virDomainEventRTCChangeDispose(void * obj)362 virDomainEventRTCChangeDispose(void *obj)
363 {
364     virDomainEventRTCChange *event = obj;
365     VIR_DEBUG("obj=%p", event);
366 }
367 
368 static void
virDomainEventWatchdogDispose(void * obj)369 virDomainEventWatchdogDispose(void *obj)
370 {
371     virDomainEventWatchdog *event = obj;
372     VIR_DEBUG("obj=%p", event);
373 }
374 
375 static void
virDomainEventIOErrorDispose(void * obj)376 virDomainEventIOErrorDispose(void *obj)
377 {
378     virDomainEventIOError *event = obj;
379     VIR_DEBUG("obj=%p", event);
380 
381     g_free(event->srcPath);
382     g_free(event->devAlias);
383     g_free(event->reason);
384 }
385 
386 static void
virDomainEventGraphicsDispose(void * obj)387 virDomainEventGraphicsDispose(void *obj)
388 {
389     virDomainEventGraphics *event = obj;
390     VIR_DEBUG("obj=%p", event);
391 
392     if (event->local) {
393         g_free(event->local->node);
394         g_free(event->local->service);
395         g_free(event->local);
396     }
397     if (event->remote) {
398         g_free(event->remote->node);
399         g_free(event->remote->service);
400         g_free(event->remote);
401     }
402     g_free(event->authScheme);
403     if (event->subject) {
404         size_t i;
405         for (i = 0; i < event->subject->nidentity; i++) {
406             g_free(event->subject->identities[i].type);
407             g_free(event->subject->identities[i].name);
408         }
409         g_free(event->subject);
410     }
411 }
412 
413 static void
virDomainEventBlockJobDispose(void * obj)414 virDomainEventBlockJobDispose(void *obj)
415 {
416     virDomainEventBlockJob *event = obj;
417     VIR_DEBUG("obj=%p", event);
418 
419     g_free(event->disk);
420 }
421 
422 static void
virDomainEventDiskChangeDispose(void * obj)423 virDomainEventDiskChangeDispose(void *obj)
424 {
425     virDomainEventDiskChange *event = obj;
426     VIR_DEBUG("obj=%p", event);
427 
428     g_free(event->oldSrcPath);
429     g_free(event->newSrcPath);
430     g_free(event->devAlias);
431 }
432 
433 static void
virDomainEventTrayChangeDispose(void * obj)434 virDomainEventTrayChangeDispose(void *obj)
435 {
436     virDomainEventTrayChange *event = obj;
437     VIR_DEBUG("obj=%p", event);
438 
439     g_free(event->devAlias);
440 }
441 
442 static void
virDomainEventBalloonChangeDispose(void * obj)443 virDomainEventBalloonChangeDispose(void *obj)
444 {
445     virDomainEventBalloonChange *event = obj;
446     VIR_DEBUG("obj=%p", event);
447 }
448 
449 static void
virDomainEventDeviceRemovedDispose(void * obj)450 virDomainEventDeviceRemovedDispose(void *obj)
451 {
452     virDomainEventDeviceRemoved *event = obj;
453     VIR_DEBUG("obj=%p", event);
454 
455     g_free(event->devAlias);
456 }
457 
458 static void
virDomainEventDeviceAddedDispose(void * obj)459 virDomainEventDeviceAddedDispose(void *obj)
460 {
461     virDomainEventDeviceAdded *event = obj;
462     VIR_DEBUG("obj=%p", event);
463 
464     g_free(event->devAlias);
465 }
466 
467 
468 static void
virDomainEventDeviceRemovalFailedDispose(void * obj)469 virDomainEventDeviceRemovalFailedDispose(void *obj)
470 {
471     virDomainEventDeviceRemovalFailed *event = obj;
472     VIR_DEBUG("obj=%p", event);
473 
474     g_free(event->devAlias);
475 }
476 
477 
478 static void
virDomainEventPMDispose(void * obj)479 virDomainEventPMDispose(void *obj)
480 {
481     virDomainEventPM *event = obj;
482     VIR_DEBUG("obj=%p", event);
483 }
484 
485 static void
virDomainQemuMonitorEventDispose(void * obj)486 virDomainQemuMonitorEventDispose(void *obj)
487 {
488     virDomainQemuMonitorEvent *event = obj;
489     VIR_DEBUG("obj=%p", event);
490 
491     g_free(event->event);
492     g_free(event->details);
493 }
494 
495 static void
virDomainEventTunableDispose(void * obj)496 virDomainEventTunableDispose(void *obj)
497 {
498     virDomainEventTunable *event = obj;
499     VIR_DEBUG("obj=%p", event);
500 
501     virTypedParamsFree(event->params, event->nparams);
502 }
503 
504 static void
virDomainEventAgentLifecycleDispose(void * obj)505 virDomainEventAgentLifecycleDispose(void *obj)
506 {
507     virDomainEventAgentLifecycle *event = obj;
508     VIR_DEBUG("obj=%p", event);
509 };
510 
511 static void
virDomainEventMigrationIterationDispose(void * obj)512 virDomainEventMigrationIterationDispose(void *obj)
513 {
514     virDomainEventMigrationIteration *event = obj;
515     VIR_DEBUG("obj=%p", event);
516 };
517 
518 static void
virDomainEventJobCompletedDispose(void * obj)519 virDomainEventJobCompletedDispose(void *obj)
520 {
521     virDomainEventJobCompleted *event = obj;
522     VIR_DEBUG("obj=%p", event);
523 
524     virTypedParamsFree(event->params, event->nparams);
525 }
526 
527 
528 static void
virDomainEventMetadataChangeDispose(void * obj)529 virDomainEventMetadataChangeDispose(void *obj)
530 {
531     virDomainEventMetadataChange *event = obj;
532     VIR_DEBUG("obj=%p", event);
533 
534     g_free(event->nsuri);
535 }
536 
537 
538 static void
virDomainEventBlockThresholdDispose(void * obj)539 virDomainEventBlockThresholdDispose(void *obj)
540 {
541     virDomainEventBlockThreshold *event = obj;
542     VIR_DEBUG("obj=%p", event);
543 
544     g_free(event->dev);
545     g_free(event->path);
546 }
547 
548 
549 static void
virDomainEventMemoryFailureDispose(void * obj)550 virDomainEventMemoryFailureDispose(void *obj)
551 {
552     virDomainEventMemoryFailure *event = obj;
553     VIR_DEBUG("obj=%p", event);
554 }
555 
556 static void
virDomainEventMemoryDeviceSizeChangeDispose(void * obj)557 virDomainEventMemoryDeviceSizeChangeDispose(void *obj)
558 {
559     virDomainEventMemoryDeviceSizeChangePtr event = obj;
560     VIR_DEBUG("obj=%p", event);
561 
562     g_free(event->alias);
563 }
564 
565 static void *
virDomainEventNew(virClass * klass,int eventID,int id,const char * name,const unsigned char * uuid)566 virDomainEventNew(virClass *klass,
567                   int eventID,
568                   int id,
569                   const char *name,
570                   const unsigned char *uuid)
571 {
572     virDomainEvent *event;
573     char uuidstr[VIR_UUID_STRING_BUFLEN];
574 
575     if (virDomainEventsInitialize() < 0)
576         return NULL;
577 
578     if (!virClassIsDerivedFrom(klass, virDomainEventClass)) {
579         virReportInvalidArg(klass,
580                             _("Class %s must derive from virDomainEvent"),
581                             virClassName(klass));
582         return NULL;
583     }
584 
585     /* We use uuid for matching key. We ignore 'name' because
586      * Xen sometimes renames guests during migration, thus
587      * 'uuid' is the only truly reliable key we can use. */
588     virUUIDFormat(uuid, uuidstr);
589     if (!(event = virObjectEventNew(klass,
590                                     virDomainEventDispatchDefaultFunc,
591                                     eventID,
592                                     id, name, uuid, uuidstr)))
593         return NULL;
594 
595     return (virObjectEvent *)event;
596 }
597 
598 virObjectEvent *
virDomainEventLifecycleNew(int id,const char * name,const unsigned char * uuid,int type,int detail)599 virDomainEventLifecycleNew(int id,
600                            const char *name,
601                            const unsigned char *uuid,
602                            int type,
603                            int detail)
604 {
605     virDomainEventLifecycle *event;
606 
607     if (virDomainEventsInitialize() < 0)
608         return NULL;
609 
610     if (!(event = virDomainEventNew(virDomainEventLifecycleClass,
611                                     VIR_DOMAIN_EVENT_ID_LIFECYCLE,
612                                     id, name, uuid)))
613         return NULL;
614 
615     event->type = type;
616     event->detail = detail;
617 
618     return (virObjectEvent *)event;
619 }
620 
621 virObjectEvent *
virDomainEventLifecycleNewFromDom(virDomainPtr dom,int type,int detail)622 virDomainEventLifecycleNewFromDom(virDomainPtr dom,
623                                   int type,
624                                   int detail)
625 {
626     return virDomainEventLifecycleNew(dom->id, dom->name, dom->uuid,
627                                       type, detail);
628 }
629 
630 virObjectEvent *
virDomainEventLifecycleNewFromObj(virDomainObj * obj,int type,int detail)631 virDomainEventLifecycleNewFromObj(virDomainObj *obj,
632                                   int type,
633                                   int detail)
634 {
635     return virDomainEventLifecycleNewFromDef(obj->def, type, detail);
636 }
637 
638 virObjectEvent *
virDomainEventLifecycleNewFromDef(virDomainDef * def,int type,int detail)639 virDomainEventLifecycleNewFromDef(virDomainDef *def,
640                                   int type,
641                                   int detail)
642 {
643     return virDomainEventLifecycleNew(def->id, def->name, def->uuid,
644                                       type, detail);
645 }
646 
647 virObjectEvent *
virDomainEventRebootNew(int id,const char * name,const unsigned char * uuid)648 virDomainEventRebootNew(int id,
649                         const char *name,
650                         const unsigned char *uuid)
651 {
652     if (virDomainEventsInitialize() < 0)
653         return NULL;
654 
655     return virDomainEventNew(virDomainEventClass,
656                              VIR_DOMAIN_EVENT_ID_REBOOT,
657                              id, name, uuid);
658 }
659 
660 virObjectEvent *
virDomainEventRebootNewFromDom(virDomainPtr dom)661 virDomainEventRebootNewFromDom(virDomainPtr dom)
662 {
663     if (virDomainEventsInitialize() < 0)
664         return NULL;
665 
666     return virDomainEventNew(virDomainEventClass,
667                              VIR_DOMAIN_EVENT_ID_REBOOT,
668                              dom->id, dom->name, dom->uuid);
669 }
670 
671 virObjectEvent *
virDomainEventRebootNewFromObj(virDomainObj * obj)672 virDomainEventRebootNewFromObj(virDomainObj *obj)
673 {
674     if (virDomainEventsInitialize() < 0)
675         return NULL;
676 
677     return virDomainEventNew(virDomainEventClass,
678                              VIR_DOMAIN_EVENT_ID_REBOOT,
679                              obj->def->id, obj->def->name, obj->def->uuid);
680 }
681 
682 virObjectEvent *
virDomainEventRTCChangeNewFromDom(virDomainPtr dom,long long offset)683 virDomainEventRTCChangeNewFromDom(virDomainPtr dom,
684                                   long long offset)
685 {
686     virDomainEventRTCChange *ev;
687 
688     if (virDomainEventsInitialize() < 0)
689         return NULL;
690 
691     if (!(ev = virDomainEventNew(virDomainEventRTCChangeClass,
692                                  VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
693                                  dom->id, dom->name, dom->uuid)))
694         return NULL;
695 
696     ev->offset = offset;
697 
698     return (virObjectEvent *)ev;
699 }
700 virObjectEvent *
virDomainEventRTCChangeNewFromObj(virDomainObj * obj,long long offset)701 virDomainEventRTCChangeNewFromObj(virDomainObj *obj,
702                                   long long offset)
703 {
704     virDomainEventRTCChange *ev;
705 
706     if (virDomainEventsInitialize() < 0)
707         return NULL;
708 
709     if (!(ev = virDomainEventNew(virDomainEventRTCChangeClass,
710                                  VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
711                                  obj->def->id, obj->def->name,
712                                  obj->def->uuid)))
713         return NULL;
714 
715     ev->offset = offset;
716 
717     return (virObjectEvent *)ev;
718 }
719 
720 virObjectEvent *
virDomainEventWatchdogNewFromDom(virDomainPtr dom,int action)721 virDomainEventWatchdogNewFromDom(virDomainPtr dom,
722                                  int action)
723 {
724     virDomainEventWatchdog *ev;
725 
726     if (virDomainEventsInitialize() < 0)
727         return NULL;
728 
729     if (!(ev = virDomainEventNew(virDomainEventWatchdogClass,
730                                  VIR_DOMAIN_EVENT_ID_WATCHDOG,
731                                  dom->id, dom->name, dom->uuid)))
732         return NULL;
733 
734     ev->action = action;
735 
736     return (virObjectEvent *)ev;
737 }
738 virObjectEvent *
virDomainEventWatchdogNewFromObj(virDomainObj * obj,int action)739 virDomainEventWatchdogNewFromObj(virDomainObj *obj,
740                                  int action)
741 {
742     virDomainEventWatchdog *ev;
743 
744     if (virDomainEventsInitialize() < 0)
745         return NULL;
746 
747     if (!(ev = virDomainEventNew(virDomainEventWatchdogClass,
748                                  VIR_DOMAIN_EVENT_ID_WATCHDOG,
749                                  obj->def->id, obj->def->name,
750                                  obj->def->uuid)))
751         return NULL;
752 
753     ev->action = action;
754 
755     return (virObjectEvent *)ev;
756 }
757 
758 static virObjectEvent *
virDomainEventIOErrorNewFromDomImpl(int event,virDomainPtr dom,const char * srcPath,const char * devAlias,int action,const char * reason)759 virDomainEventIOErrorNewFromDomImpl(int event,
760                                     virDomainPtr dom,
761                                     const char *srcPath,
762                                     const char *devAlias,
763                                     int action,
764                                     const char *reason)
765 {
766     virDomainEventIOError *ev;
767 
768     if (virDomainEventsInitialize() < 0)
769         return NULL;
770 
771     if (!(ev = virDomainEventNew(virDomainEventIOErrorClass, event,
772                                  dom->id, dom->name, dom->uuid)))
773         return NULL;
774 
775     ev->action = action;
776     ev->srcPath = g_strdup(srcPath);
777     ev->devAlias = g_strdup(devAlias);
778     ev->reason = g_strdup(reason);
779 
780     return (virObjectEvent *)ev;
781 }
782 
783 static virObjectEvent *
virDomainEventIOErrorNewFromObjImpl(int event,virDomainObj * obj,const char * srcPath,const char * devAlias,int action,const char * reason)784 virDomainEventIOErrorNewFromObjImpl(int event,
785                                     virDomainObj *obj,
786                                     const char *srcPath,
787                                     const char *devAlias,
788                                     int action,
789                                     const char *reason)
790 {
791     virDomainEventIOError *ev;
792 
793     if (virDomainEventsInitialize() < 0)
794         return NULL;
795 
796     if (!(ev = virDomainEventNew(virDomainEventIOErrorClass, event,
797                                  obj->def->id, obj->def->name,
798                                  obj->def->uuid)))
799         return NULL;
800 
801     ev->action = action;
802     ev->srcPath = g_strdup(srcPath);
803     ev->devAlias = g_strdup(devAlias);
804     ev->reason = g_strdup(reason);
805 
806     return (virObjectEvent *)ev;
807 }
808 
809 virObjectEvent *
virDomainEventIOErrorNewFromDom(virDomainPtr dom,const char * srcPath,const char * devAlias,int action)810 virDomainEventIOErrorNewFromDom(virDomainPtr dom,
811                                 const char *srcPath,
812                                 const char *devAlias,
813                                 int action)
814 {
815     return virDomainEventIOErrorNewFromDomImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR,
816                                                dom, srcPath, devAlias,
817                                                action, NULL);
818 }
819 
820 virObjectEvent *
virDomainEventIOErrorNewFromObj(virDomainObj * obj,const char * srcPath,const char * devAlias,int action)821 virDomainEventIOErrorNewFromObj(virDomainObj *obj,
822                                 const char *srcPath,
823                                 const char *devAlias,
824                                 int action)
825 {
826     return virDomainEventIOErrorNewFromObjImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR,
827                                                obj, srcPath, devAlias,
828                                                action, NULL);
829 }
830 
831 virObjectEvent *
virDomainEventIOErrorReasonNewFromDom(virDomainPtr dom,const char * srcPath,const char * devAlias,int action,const char * reason)832 virDomainEventIOErrorReasonNewFromDom(virDomainPtr dom,
833                                       const char *srcPath,
834                                       const char *devAlias,
835                                       int action,
836                                       const char *reason)
837 {
838     return virDomainEventIOErrorNewFromDomImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON,
839                                                dom, srcPath, devAlias,
840                                                action, reason);
841 }
842 
843 virObjectEvent *
virDomainEventIOErrorReasonNewFromObj(virDomainObj * obj,const char * srcPath,const char * devAlias,int action,const char * reason)844 virDomainEventIOErrorReasonNewFromObj(virDomainObj *obj,
845                                       const char *srcPath,
846                                       const char *devAlias,
847                                       int action,
848                                       const char *reason)
849 {
850     return virDomainEventIOErrorNewFromObjImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON,
851                                                obj, srcPath, devAlias,
852                                                action, reason);
853 }
854 
855 
856 virObjectEvent *
virDomainEventGraphicsNewFromDom(virDomainPtr dom,int phase,virDomainEventGraphicsAddressPtr local,virDomainEventGraphicsAddressPtr remote,const char * authScheme,virDomainEventGraphicsSubjectPtr subject)857 virDomainEventGraphicsNewFromDom(virDomainPtr dom,
858                                  int phase,
859                                  virDomainEventGraphicsAddressPtr local,
860                                  virDomainEventGraphicsAddressPtr remote,
861                                  const char *authScheme,
862                                  virDomainEventGraphicsSubjectPtr subject)
863 {
864     virDomainEventGraphics *ev;
865 
866     if (virDomainEventsInitialize() < 0)
867         return NULL;
868 
869     if (!(ev = virDomainEventNew(virDomainEventGraphicsClass,
870                                  VIR_DOMAIN_EVENT_ID_GRAPHICS,
871                                  dom->id, dom->name, dom->uuid)))
872         return NULL;
873 
874     ev->phase = phase;
875     ev->authScheme = g_strdup(authScheme);
876     ev->local = local;
877     ev->remote = remote;
878     ev->subject = subject;
879 
880     return (virObjectEvent *)ev;
881 }
882 
883 virObjectEvent *
virDomainEventGraphicsNewFromObj(virDomainObj * obj,int phase,virDomainEventGraphicsAddressPtr local,virDomainEventGraphicsAddressPtr remote,const char * authScheme,virDomainEventGraphicsSubjectPtr subject)884 virDomainEventGraphicsNewFromObj(virDomainObj *obj,
885                                  int phase,
886                                  virDomainEventGraphicsAddressPtr local,
887                                  virDomainEventGraphicsAddressPtr remote,
888                                  const char *authScheme,
889                                  virDomainEventGraphicsSubjectPtr subject)
890 {
891     virDomainEventGraphics *ev;
892 
893     if (virDomainEventsInitialize() < 0)
894         return NULL;
895 
896     if (!(ev = virDomainEventNew(virDomainEventGraphicsClass,
897                                  VIR_DOMAIN_EVENT_ID_GRAPHICS,
898                                  obj->def->id, obj->def->name,
899                                  obj->def->uuid)))
900         return NULL;
901 
902     ev->phase = phase;
903     ev->authScheme = g_strdup(authScheme);
904     ev->local = local;
905     ev->remote = remote;
906     ev->subject = subject;
907 
908     return (virObjectEvent *)ev;
909 }
910 
911 static virObjectEvent *
virDomainEventBlockJobNew(int event,int id,const char * name,unsigned char * uuid,const char * disk,int type,int status)912 virDomainEventBlockJobNew(int event,
913                           int id,
914                           const char *name,
915                           unsigned char *uuid,
916                           const char *disk,
917                           int type,
918                           int status)
919 {
920     virDomainEventBlockJob *ev;
921 
922     if (virDomainEventsInitialize() < 0)
923         return NULL;
924 
925     if (!(ev = virDomainEventNew(virDomainEventBlockJobClass,
926                                  event,
927                                  id, name, uuid)))
928         return NULL;
929 
930     ev->disk = g_strdup(disk);
931     ev->type = type;
932     ev->status = status;
933 
934     return (virObjectEvent *)ev;
935 }
936 
937 virObjectEvent *
virDomainEventBlockJobNewFromObj(virDomainObj * obj,const char * path,int type,int status)938 virDomainEventBlockJobNewFromObj(virDomainObj *obj,
939                                  const char *path,
940                                  int type,
941                                  int status)
942 {
943     return virDomainEventBlockJobNew(VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
944                                      obj->def->id, obj->def->name,
945                                      obj->def->uuid, path, type, status);
946 }
947 
948 virObjectEvent *
virDomainEventBlockJobNewFromDom(virDomainPtr dom,const char * path,int type,int status)949 virDomainEventBlockJobNewFromDom(virDomainPtr dom,
950                                  const char *path,
951                                  int type,
952                                  int status)
953 {
954     return virDomainEventBlockJobNew(VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
955                                      dom->id, dom->name, dom->uuid,
956                                      path, type, status);
957 }
958 
959 virObjectEvent *
virDomainEventBlockJob2NewFromObj(virDomainObj * obj,const char * dst,int type,int status)960 virDomainEventBlockJob2NewFromObj(virDomainObj *obj,
961                                   const char *dst,
962                                   int type,
963                                   int status)
964 {
965     return virDomainEventBlockJobNew(VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2,
966                                      obj->def->id, obj->def->name,
967                                      obj->def->uuid, dst, type, status);
968 }
969 
970 virObjectEvent *
virDomainEventBlockJob2NewFromDom(virDomainPtr dom,const char * dst,int type,int status)971 virDomainEventBlockJob2NewFromDom(virDomainPtr dom,
972                                   const char *dst,
973                                   int type,
974                                   int status)
975 {
976     return virDomainEventBlockJobNew(VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2,
977                                      dom->id, dom->name, dom->uuid,
978                                      dst, type, status);
979 }
980 
981 virObjectEvent *
virDomainEventControlErrorNewFromDom(virDomainPtr dom)982 virDomainEventControlErrorNewFromDom(virDomainPtr dom)
983 {
984     virObjectEvent *ev;
985 
986     if (virDomainEventsInitialize() < 0)
987         return NULL;
988 
989     if (!(ev = virDomainEventNew(virDomainEventClass,
990                                  VIR_DOMAIN_EVENT_ID_CONTROL_ERROR,
991                                  dom->id, dom->name, dom->uuid)))
992         return NULL;
993     return ev;
994 }
995 
996 
997 virObjectEvent *
virDomainEventControlErrorNewFromObj(virDomainObj * obj)998 virDomainEventControlErrorNewFromObj(virDomainObj *obj)
999 {
1000     virObjectEvent *ev;
1001 
1002     if (virDomainEventsInitialize() < 0)
1003         return NULL;
1004 
1005     if (!(ev = virDomainEventNew(virDomainEventClass,
1006                                  VIR_DOMAIN_EVENT_ID_CONTROL_ERROR,
1007                                  obj->def->id, obj->def->name,
1008                                  obj->def->uuid)))
1009         return NULL;
1010     return ev;
1011 }
1012 
1013 static virObjectEvent *
virDomainEventDiskChangeNew(int id,const char * name,unsigned char * uuid,const char * oldSrcPath,const char * newSrcPath,const char * devAlias,int reason)1014 virDomainEventDiskChangeNew(int id,
1015                             const char *name,
1016                             unsigned char *uuid,
1017                             const char *oldSrcPath,
1018                             const char *newSrcPath,
1019                             const char *devAlias,
1020                             int reason)
1021 {
1022     virDomainEventDiskChange *ev;
1023 
1024     if (virDomainEventsInitialize() < 0)
1025         return NULL;
1026 
1027     if (!(ev = virDomainEventNew(virDomainEventDiskChangeClass,
1028                                  VIR_DOMAIN_EVENT_ID_DISK_CHANGE,
1029                                  id, name, uuid)))
1030         return NULL;
1031 
1032     ev->devAlias = g_strdup(devAlias);
1033     ev->oldSrcPath = g_strdup(oldSrcPath);
1034     ev->newSrcPath = g_strdup(newSrcPath);
1035 
1036     ev->reason = reason;
1037 
1038     return (virObjectEvent *)ev;
1039 }
1040 
1041 virObjectEvent *
virDomainEventDiskChangeNewFromObj(virDomainObj * obj,const char * oldSrcPath,const char * newSrcPath,const char * devAlias,int reason)1042 virDomainEventDiskChangeNewFromObj(virDomainObj *obj,
1043                                    const char *oldSrcPath,
1044                                    const char *newSrcPath,
1045                                    const char *devAlias,
1046                                    int reason)
1047 {
1048     return virDomainEventDiskChangeNew(obj->def->id, obj->def->name,
1049                                        obj->def->uuid, oldSrcPath,
1050                                        newSrcPath, devAlias, reason);
1051 }
1052 
1053 virObjectEvent *
virDomainEventDiskChangeNewFromDom(virDomainPtr dom,const char * oldSrcPath,const char * newSrcPath,const char * devAlias,int reason)1054 virDomainEventDiskChangeNewFromDom(virDomainPtr dom,
1055                                    const char *oldSrcPath,
1056                                    const char *newSrcPath,
1057                                    const char *devAlias,
1058                                    int reason)
1059 {
1060     return virDomainEventDiskChangeNew(dom->id, dom->name, dom->uuid,
1061                                        oldSrcPath, newSrcPath,
1062                                        devAlias, reason);
1063 }
1064 
1065 static virObjectEvent *
virDomainEventTrayChangeNew(int id,const char * name,unsigned char * uuid,const char * devAlias,int reason)1066 virDomainEventTrayChangeNew(int id,
1067                             const char *name,
1068                             unsigned char *uuid,
1069                             const char *devAlias,
1070                             int reason)
1071 {
1072     virDomainEventTrayChange *ev;
1073 
1074     if (virDomainEventsInitialize() < 0)
1075         return NULL;
1076 
1077     if (!(ev = virDomainEventNew(virDomainEventTrayChangeClass,
1078                                  VIR_DOMAIN_EVENT_ID_TRAY_CHANGE,
1079                                  id, name, uuid)))
1080         return NULL;
1081 
1082     ev->devAlias = g_strdup(devAlias);
1083 
1084     ev->reason = reason;
1085 
1086     return (virObjectEvent *)ev;
1087 }
1088 
1089 virObjectEvent *
virDomainEventTrayChangeNewFromObj(virDomainObj * obj,const char * devAlias,int reason)1090 virDomainEventTrayChangeNewFromObj(virDomainObj *obj,
1091                                   const char *devAlias,
1092                                   int reason)
1093 {
1094     return virDomainEventTrayChangeNew(obj->def->id,
1095                                        obj->def->name,
1096                                        obj->def->uuid,
1097                                        devAlias,
1098                                        reason);
1099 }
1100 
1101 virObjectEvent *
virDomainEventTrayChangeNewFromDom(virDomainPtr dom,const char * devAlias,int reason)1102 virDomainEventTrayChangeNewFromDom(virDomainPtr dom,
1103                                    const char *devAlias,
1104                                    int reason)
1105 {
1106     return virDomainEventTrayChangeNew(dom->id, dom->name, dom->uuid,
1107                                        devAlias, reason);
1108 }
1109 
1110 static virObjectEvent *
virDomainEventPMWakeupNew(int id,const char * name,unsigned char * uuid,int reason)1111 virDomainEventPMWakeupNew(int id,
1112                           const char *name,
1113                           unsigned char *uuid,
1114                           int reason)
1115 {
1116     virDomainEventPM *ev;
1117 
1118     if (virDomainEventsInitialize() < 0)
1119         return NULL;
1120 
1121     if (!(ev = virDomainEventNew(virDomainEventPMClass,
1122                                  VIR_DOMAIN_EVENT_ID_PMWAKEUP,
1123                                  id, name, uuid)))
1124         return NULL;
1125 
1126     ev->reason = reason;
1127     return (virObjectEvent *)ev;
1128 }
1129 
1130 virObjectEvent *
virDomainEventPMWakeupNewFromObj(virDomainObj * obj)1131 virDomainEventPMWakeupNewFromObj(virDomainObj *obj)
1132 {
1133     return virDomainEventPMWakeupNew(obj->def->id,
1134                                      obj->def->name,
1135                                      obj->def->uuid,
1136                                      0);
1137 }
1138 
1139 virObjectEvent *
virDomainEventPMWakeupNewFromDom(virDomainPtr dom,int reason)1140 virDomainEventPMWakeupNewFromDom(virDomainPtr dom, int reason)
1141 {
1142     return virDomainEventPMWakeupNew(dom->id, dom->name, dom->uuid, reason);
1143 }
1144 
1145 static virObjectEvent *
virDomainEventPMSuspendNew(int id,const char * name,unsigned char * uuid,int reason)1146 virDomainEventPMSuspendNew(int id,
1147                            const char *name,
1148                            unsigned char *uuid,
1149                            int reason)
1150 {
1151     virDomainEventPM *ev;
1152 
1153     if (virDomainEventsInitialize() < 0)
1154         return NULL;
1155 
1156     if (!(ev = virDomainEventNew(virDomainEventPMClass,
1157                                  VIR_DOMAIN_EVENT_ID_PMSUSPEND,
1158                                  id, name, uuid)))
1159         return NULL;
1160 
1161     ev->reason = reason;
1162     return (virObjectEvent *)ev;
1163 }
1164 
1165 virObjectEvent *
virDomainEventPMSuspendNewFromObj(virDomainObj * obj)1166 virDomainEventPMSuspendNewFromObj(virDomainObj *obj)
1167 {
1168     return virDomainEventPMSuspendNew(obj->def->id,
1169                                       obj->def->name,
1170                                       obj->def->uuid,
1171                                       0);
1172 }
1173 
1174 virObjectEvent *
virDomainEventPMSuspendNewFromDom(virDomainPtr dom,int reason)1175 virDomainEventPMSuspendNewFromDom(virDomainPtr dom, int reason)
1176 {
1177     return virDomainEventPMSuspendNew(dom->id, dom->name, dom->uuid, reason);
1178 }
1179 
1180 static virObjectEvent *
virDomainEventPMSuspendDiskNew(int id,const char * name,unsigned char * uuid,int reason)1181 virDomainEventPMSuspendDiskNew(int id,
1182                                const char *name,
1183                                unsigned char *uuid,
1184                                int reason)
1185 {
1186     virDomainEventPM *ev;
1187 
1188     if (virDomainEventsInitialize() < 0)
1189         return NULL;
1190 
1191     if (!(ev = virDomainEventNew(virDomainEventPMClass,
1192                                  VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK,
1193                                  id, name, uuid)))
1194         return NULL;
1195 
1196     ev->reason = reason;
1197     return (virObjectEvent *)ev;
1198 }
1199 
1200 virObjectEvent *
virDomainEventPMSuspendDiskNewFromObj(virDomainObj * obj)1201 virDomainEventPMSuspendDiskNewFromObj(virDomainObj *obj)
1202 {
1203     return virDomainEventPMSuspendDiskNew(obj->def->id,
1204                                           obj->def->name,
1205                                           obj->def->uuid,
1206                                           0);
1207 }
1208 
1209 virObjectEvent *
virDomainEventPMSuspendDiskNewFromDom(virDomainPtr dom,int reason)1210 virDomainEventPMSuspendDiskNewFromDom(virDomainPtr dom, int reason)
1211 {
1212     return virDomainEventPMSuspendDiskNew(dom->id, dom->name, dom->uuid,
1213                                           reason);
1214 }
1215 
1216 virObjectEvent *
virDomainEventBalloonChangeNewFromDom(virDomainPtr dom,unsigned long long actual)1217 virDomainEventBalloonChangeNewFromDom(virDomainPtr dom,
1218                                       unsigned long long actual)
1219 {
1220     virDomainEventBalloonChange *ev;
1221 
1222     if (virDomainEventsInitialize() < 0)
1223         return NULL;
1224 
1225     if (!(ev = virDomainEventNew(virDomainEventBalloonChangeClass,
1226                                  VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE,
1227                                  dom->id, dom->name, dom->uuid)))
1228         return NULL;
1229 
1230     ev->actual = actual;
1231 
1232     return (virObjectEvent *)ev;
1233 }
1234 virObjectEvent *
virDomainEventBalloonChangeNewFromObj(virDomainObj * obj,unsigned long long actual)1235 virDomainEventBalloonChangeNewFromObj(virDomainObj *obj,
1236                                       unsigned long long actual)
1237 {
1238     virDomainEventBalloonChange *ev;
1239 
1240     if (virDomainEventsInitialize() < 0)
1241         return NULL;
1242 
1243     if (!(ev = virDomainEventNew(virDomainEventBalloonChangeClass,
1244                                  VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE,
1245                                  obj->def->id, obj->def->name, obj->def->uuid)))
1246         return NULL;
1247 
1248     ev->actual = actual;
1249 
1250     return (virObjectEvent *)ev;
1251 }
1252 
1253 static virObjectEvent *
virDomainEventDeviceRemovedNew(int id,const char * name,unsigned char * uuid,const char * devAlias)1254 virDomainEventDeviceRemovedNew(int id,
1255                                const char *name,
1256                                unsigned char *uuid,
1257                                const char *devAlias)
1258 {
1259     virDomainEventDeviceRemoved *ev;
1260 
1261     if (virDomainEventsInitialize() < 0)
1262         return NULL;
1263 
1264     if (!(ev = virDomainEventNew(virDomainEventDeviceRemovedClass,
1265                                  VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED,
1266                                  id, name, uuid)))
1267         return NULL;
1268 
1269     ev->devAlias = g_strdup(devAlias);
1270 
1271     return (virObjectEvent *)ev;
1272 }
1273 
1274 virObjectEvent *
virDomainEventDeviceRemovedNewFromObj(virDomainObj * obj,const char * devAlias)1275 virDomainEventDeviceRemovedNewFromObj(virDomainObj *obj,
1276                                       const char *devAlias)
1277 {
1278     return virDomainEventDeviceRemovedNew(obj->def->id, obj->def->name,
1279                                           obj->def->uuid, devAlias);
1280 }
1281 
1282 virObjectEvent *
virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,const char * devAlias)1283 virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
1284                                       const char *devAlias)
1285 {
1286     return virDomainEventDeviceRemovedNew(dom->id, dom->name, dom->uuid,
1287                                           devAlias);
1288 }
1289 
1290 static virObjectEvent *
virDomainEventDeviceAddedNew(int id,const char * name,unsigned char * uuid,const char * devAlias)1291 virDomainEventDeviceAddedNew(int id,
1292                              const char *name,
1293                              unsigned char *uuid,
1294                              const char *devAlias)
1295 {
1296     virDomainEventDeviceAdded *ev;
1297 
1298     if (virDomainEventsInitialize() < 0)
1299         return NULL;
1300 
1301     if (!(ev = virDomainEventNew(virDomainEventDeviceAddedClass,
1302                                  VIR_DOMAIN_EVENT_ID_DEVICE_ADDED,
1303                                  id, name, uuid)))
1304         return NULL;
1305 
1306     ev->devAlias = g_strdup(devAlias);
1307 
1308     return (virObjectEvent *)ev;
1309 }
1310 
1311 virObjectEvent *
virDomainEventDeviceAddedNewFromObj(virDomainObj * obj,const char * devAlias)1312 virDomainEventDeviceAddedNewFromObj(virDomainObj *obj,
1313                                     const char *devAlias)
1314 {
1315     return virDomainEventDeviceAddedNew(obj->def->id, obj->def->name,
1316                                            obj->def->uuid, devAlias);
1317 }
1318 
1319 virObjectEvent *
virDomainEventDeviceAddedNewFromDom(virDomainPtr dom,const char * devAlias)1320 virDomainEventDeviceAddedNewFromDom(virDomainPtr dom,
1321                                     const char *devAlias)
1322 {
1323     return virDomainEventDeviceAddedNew(dom->id, dom->name, dom->uuid,
1324                                           devAlias);
1325 }
1326 
1327 
1328 static virObjectEvent *
virDomainEventDeviceRemovalFailedNew(int id,const char * name,unsigned char * uuid,const char * devAlias)1329 virDomainEventDeviceRemovalFailedNew(int id,
1330                                      const char *name,
1331                                      unsigned char *uuid,
1332                                      const char *devAlias)
1333 {
1334     virDomainEventDeviceRemovalFailed *ev;
1335 
1336     if (virDomainEventsInitialize() < 0)
1337         return NULL;
1338 
1339     if (!(ev = virDomainEventNew(virDomainEventDeviceRemovalFailedClass,
1340                                  VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED,
1341                                  id, name, uuid)))
1342         return NULL;
1343 
1344     ev->devAlias = g_strdup(devAlias);
1345 
1346     return (virObjectEvent *)ev;
1347 }
1348 
1349 virObjectEvent *
virDomainEventDeviceRemovalFailedNewFromObj(virDomainObj * obj,const char * devAlias)1350 virDomainEventDeviceRemovalFailedNewFromObj(virDomainObj *obj,
1351                                             const char *devAlias)
1352 {
1353     return virDomainEventDeviceRemovalFailedNew(obj->def->id, obj->def->name,
1354                                                 obj->def->uuid, devAlias);
1355 }
1356 
1357 virObjectEvent *
virDomainEventDeviceRemovalFailedNewFromDom(virDomainPtr dom,const char * devAlias)1358 virDomainEventDeviceRemovalFailedNewFromDom(virDomainPtr dom,
1359                                             const char *devAlias)
1360 {
1361     return virDomainEventDeviceRemovalFailedNew(dom->id, dom->name, dom->uuid,
1362                                                 devAlias);
1363 }
1364 
1365 
1366 static virObjectEvent *
virDomainEventAgentLifecycleNew(int id,const char * name,const unsigned char * uuid,int state,int reason)1367 virDomainEventAgentLifecycleNew(int id,
1368                                 const char *name,
1369                                 const unsigned char *uuid,
1370                                 int state,
1371                                 int reason)
1372 {
1373     virDomainEventAgentLifecycle *ev;
1374 
1375     if (virDomainEventsInitialize() < 0)
1376         return NULL;
1377 
1378     if (!(ev = virDomainEventNew(virDomainEventAgentLifecycleClass,
1379                                  VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE,
1380                                  id, name, uuid)))
1381         return NULL;
1382 
1383     ev->state = state;
1384     ev->reason = reason;
1385 
1386     return (virObjectEvent *)ev;
1387 }
1388 
1389 virObjectEvent *
virDomainEventAgentLifecycleNewFromObj(virDomainObj * obj,int state,int reason)1390 virDomainEventAgentLifecycleNewFromObj(virDomainObj *obj,
1391                                        int state,
1392                                        int reason)
1393 {
1394     return virDomainEventAgentLifecycleNew(obj->def->id, obj->def->name,
1395                                            obj->def->uuid, state, reason);
1396 }
1397 
1398 virObjectEvent *
virDomainEventAgentLifecycleNewFromDom(virDomainPtr dom,int state,int reason)1399 virDomainEventAgentLifecycleNewFromDom(virDomainPtr dom,
1400                                        int state,
1401                                        int reason)
1402 {
1403     return virDomainEventAgentLifecycleNew(dom->id, dom->name, dom->uuid,
1404                                            state, reason);
1405 }
1406 
1407 static virObjectEvent *
virDomainEventMigrationIterationNew(int id,const char * name,const unsigned char * uuid,int iteration)1408 virDomainEventMigrationIterationNew(int id,
1409                                     const char *name,
1410                                     const unsigned char *uuid,
1411                                     int iteration)
1412 {
1413     virDomainEventMigrationIteration *ev;
1414 
1415     if (virDomainEventsInitialize() < 0)
1416         return NULL;
1417 
1418     if (!(ev = virDomainEventNew(virDomainEventMigrationIterationClass,
1419                                  VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION,
1420                                  id, name, uuid)))
1421         return NULL;
1422 
1423     ev->iteration = iteration;
1424 
1425     return (virObjectEvent *)ev;
1426 }
1427 
1428 virObjectEvent *
virDomainEventMigrationIterationNewFromObj(virDomainObj * obj,int iteration)1429 virDomainEventMigrationIterationNewFromObj(virDomainObj *obj,
1430                                            int iteration)
1431 {
1432     return virDomainEventMigrationIterationNew(obj->def->id, obj->def->name,
1433                                                obj->def->uuid, iteration);
1434 }
1435 
1436 virObjectEvent *
virDomainEventMigrationIterationNewFromDom(virDomainPtr dom,int iteration)1437 virDomainEventMigrationIterationNewFromDom(virDomainPtr dom,
1438                                            int iteration)
1439 {
1440     return virDomainEventMigrationIterationNew(dom->id, dom->name, dom->uuid,
1441                                                iteration);
1442 }
1443 
1444 /* This function consumes @params, the caller must not free it.
1445  */
1446 static virObjectEvent *
virDomainEventJobCompletedNew(int id,const char * name,const unsigned char * uuid,virTypedParameterPtr params,int nparams)1447 virDomainEventJobCompletedNew(int id,
1448                               const char *name,
1449                               const unsigned char *uuid,
1450                               virTypedParameterPtr params,
1451                               int nparams)
1452 {
1453     virDomainEventJobCompleted *ev;
1454 
1455     if (virDomainEventsInitialize() < 0)
1456         goto error;
1457 
1458     if (!(ev = virDomainEventNew(virDomainEventJobCompletedClass,
1459                                  VIR_DOMAIN_EVENT_ID_JOB_COMPLETED,
1460                                  id, name, uuid)))
1461         goto error;
1462 
1463     ev->params = params;
1464     ev->nparams = nparams;
1465 
1466     return (virObjectEvent *) ev;
1467 
1468  error:
1469     virTypedParamsFree(params, nparams);
1470     return NULL;
1471 }
1472 
1473 virObjectEvent *
virDomainEventJobCompletedNewFromObj(virDomainObj * obj,virTypedParameterPtr params,int nparams)1474 virDomainEventJobCompletedNewFromObj(virDomainObj *obj,
1475                                      virTypedParameterPtr params,
1476                                      int nparams)
1477 {
1478     return virDomainEventJobCompletedNew(obj->def->id, obj->def->name,
1479                                          obj->def->uuid, params, nparams);
1480 }
1481 
1482 virObjectEvent *
virDomainEventJobCompletedNewFromDom(virDomainPtr dom,virTypedParameterPtr params,int nparams)1483 virDomainEventJobCompletedNewFromDom(virDomainPtr dom,
1484                                      virTypedParameterPtr params,
1485                                      int nparams)
1486 {
1487     return virDomainEventJobCompletedNew(dom->id, dom->name, dom->uuid,
1488                                          params, nparams);
1489 }
1490 
1491 
1492 /* This function consumes the params so caller don't have to care about
1493  * freeing it even if error occurs. The reason is to not have to do deep
1494  * copy of params.
1495  */
1496 static virObjectEvent *
virDomainEventTunableNew(int id,const char * name,unsigned char * uuid,virTypedParameterPtr params,int nparams)1497 virDomainEventTunableNew(int id,
1498                          const char *name,
1499                          unsigned char *uuid,
1500                          virTypedParameterPtr params,
1501                          int nparams)
1502 {
1503     virDomainEventTunable *ev;
1504 
1505     if (virDomainEventsInitialize() < 0)
1506         goto error;
1507 
1508     if (!(ev = virDomainEventNew(virDomainEventTunableClass,
1509                                  VIR_DOMAIN_EVENT_ID_TUNABLE,
1510                                  id, name, uuid)))
1511         goto error;
1512 
1513     ev->params = params;
1514     ev->nparams = nparams;
1515 
1516     return (virObjectEvent *)ev;
1517 
1518  error:
1519     virTypedParamsFree(params, nparams);
1520     return NULL;
1521 }
1522 
1523 virObjectEvent *
virDomainEventTunableNewFromObj(virDomainObj * obj,virTypedParameterPtr params,int nparams)1524 virDomainEventTunableNewFromObj(virDomainObj *obj,
1525                                 virTypedParameterPtr params,
1526                                 int nparams)
1527 {
1528     return virDomainEventTunableNew(obj->def->id,
1529                                     obj->def->name,
1530                                     obj->def->uuid,
1531                                     params,
1532                                     nparams);
1533 }
1534 
1535 virObjectEvent *
virDomainEventTunableNewFromDom(virDomainPtr dom,virTypedParameterPtr params,int nparams)1536 virDomainEventTunableNewFromDom(virDomainPtr dom,
1537                                 virTypedParameterPtr params,
1538                                 int nparams)
1539 {
1540     return virDomainEventTunableNew(dom->id,
1541                                     dom->name,
1542                                     dom->uuid,
1543                                     params,
1544                                     nparams);
1545 }
1546 
1547 
1548 static virObjectEvent *
virDomainEventMetadataChangeNew(int id,const char * name,unsigned char * uuid,int type,const char * nsuri)1549 virDomainEventMetadataChangeNew(int id,
1550                                 const char *name,
1551                                 unsigned char *uuid,
1552                                 int type,
1553                                 const char *nsuri)
1554 {
1555     virDomainEventMetadataChange *ev;
1556 
1557     if (virDomainEventsInitialize() < 0)
1558         return NULL;
1559 
1560     if (!(ev = virDomainEventNew(virDomainEventMetadataChangeClass,
1561                                  VIR_DOMAIN_EVENT_ID_METADATA_CHANGE,
1562                                  id, name, uuid)))
1563         return NULL;
1564 
1565     ev->type = type;
1566     if (nsuri)
1567         ev->nsuri = g_strdup(nsuri);
1568 
1569     return (virObjectEvent *)ev;
1570 }
1571 
1572 virObjectEvent *
virDomainEventMetadataChangeNewFromObj(virDomainObj * obj,int type,const char * nsuri)1573 virDomainEventMetadataChangeNewFromObj(virDomainObj *obj,
1574                                        int type,
1575                                        const char *nsuri)
1576 {
1577     return virDomainEventMetadataChangeNew(obj->def->id, obj->def->name,
1578                                            obj->def->uuid, type, nsuri);
1579 }
1580 
1581 virObjectEvent *
virDomainEventMetadataChangeNewFromDom(virDomainPtr dom,int type,const char * nsuri)1582 virDomainEventMetadataChangeNewFromDom(virDomainPtr dom,
1583                                        int type,
1584                                        const char *nsuri)
1585 {
1586     return virDomainEventMetadataChangeNew(dom->id, dom->name, dom->uuid,
1587                                            type, nsuri);
1588 }
1589 
1590 
1591 static virObjectEvent *
virDomainEventBlockThresholdNew(int id,const char * name,unsigned char * uuid,const char * dev,const char * path,unsigned long long threshold,unsigned long long excess)1592 virDomainEventBlockThresholdNew(int id,
1593                                 const char *name,
1594                                 unsigned char *uuid,
1595                                 const char *dev,
1596                                 const char *path,
1597                                 unsigned long long threshold,
1598                                 unsigned long long excess)
1599 {
1600     virDomainEventBlockThreshold *ev;
1601 
1602     if (virDomainEventsInitialize() < 0)
1603         return NULL;
1604 
1605     if (!(ev = virDomainEventNew(virDomainEventBlockThresholdClass,
1606                                  VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD,
1607                                  id, name, uuid)))
1608         return NULL;
1609 
1610     ev->dev = g_strdup(dev);
1611     ev->path = g_strdup(path);
1612     ev->threshold = threshold;
1613     ev->excess = excess;
1614 
1615     return (virObjectEvent *)ev;
1616 }
1617 
1618 virObjectEvent *
virDomainEventBlockThresholdNewFromObj(virDomainObj * obj,const char * dev,const char * path,unsigned long long threshold,unsigned long long excess)1619 virDomainEventBlockThresholdNewFromObj(virDomainObj *obj,
1620                                        const char *dev,
1621                                        const char *path,
1622                                        unsigned long long threshold,
1623                                        unsigned long long excess)
1624 {
1625     return virDomainEventBlockThresholdNew(obj->def->id, obj->def->name,
1626                                            obj->def->uuid, dev, path,
1627                                            threshold, excess);
1628 }
1629 
1630 virObjectEvent *
virDomainEventBlockThresholdNewFromDom(virDomainPtr dom,const char * dev,const char * path,unsigned long long threshold,unsigned long long excess)1631 virDomainEventBlockThresholdNewFromDom(virDomainPtr dom,
1632                                        const char *dev,
1633                                        const char *path,
1634                                        unsigned long long threshold,
1635                                        unsigned long long excess)
1636 {
1637     return virDomainEventBlockThresholdNew(dom->id, dom->name, dom->uuid,
1638                                            dev, path, threshold, excess);
1639 }
1640 
1641 
1642 static virObjectEvent *
virDomainEventMemoryFailureNew(int id,const char * name,unsigned char * uuid,int recipient,int action,unsigned int flags)1643 virDomainEventMemoryFailureNew(int id,
1644                                const char *name,
1645                                unsigned char *uuid,
1646                                int recipient,
1647                                int action,
1648                                unsigned int flags)
1649 {
1650     virDomainEventMemoryFailure *ev;
1651 
1652     if (virDomainEventsInitialize() < 0)
1653         return NULL;
1654 
1655     if (!(ev = virDomainEventNew(virDomainEventMemoryFailureClass,
1656                                  VIR_DOMAIN_EVENT_ID_MEMORY_FAILURE,
1657                                  id, name, uuid)))
1658         return NULL;
1659 
1660     ev->recipient = recipient;
1661     ev->action = action;
1662     ev->flags = flags;
1663 
1664     return (virObjectEvent *)ev;
1665 }
1666 
1667 virObjectEvent *
virDomainEventMemoryFailureNewFromObj(virDomainObj * obj,int recipient,int action,unsigned int flags)1668 virDomainEventMemoryFailureNewFromObj(virDomainObj *obj,
1669                                       int recipient,
1670                                       int action,
1671                                       unsigned int flags)
1672 {
1673     return virDomainEventMemoryFailureNew(obj->def->id, obj->def->name,
1674                                           obj->def->uuid, recipient, action,
1675                                           flags);
1676 }
1677 
1678 virObjectEvent *
virDomainEventMemoryFailureNewFromDom(virDomainPtr dom,int recipient,int action,unsigned int flags)1679 virDomainEventMemoryFailureNewFromDom(virDomainPtr dom,
1680                                       int recipient,
1681                                       int action,
1682                                       unsigned int flags)
1683 {
1684     return virDomainEventMemoryFailureNew(dom->id, dom->name, dom->uuid,
1685                                           recipient, action, flags);
1686 }
1687 
1688 
1689 static virObjectEvent *
virDomainEventMemoryDeviceSizeChangeNew(int id,const char * name,unsigned char * uuid,const char * alias,unsigned long long size)1690 virDomainEventMemoryDeviceSizeChangeNew(int id,
1691                                         const char *name,
1692                                         unsigned char *uuid,
1693                                         const char *alias,
1694                                         unsigned long long size)
1695 {
1696     virDomainEventMemoryDeviceSizeChangePtr ev;
1697 
1698     if (virDomainEventsInitialize() < 0)
1699         return NULL;
1700 
1701     if (!(ev = virDomainEventNew(virDomainEventMemoryDeviceSizeChangeClass,
1702                                  VIR_DOMAIN_EVENT_ID_MEMORY_DEVICE_SIZE_CHANGE,
1703                                  id, name, uuid)))
1704         return NULL;
1705 
1706     ev->alias = g_strdup(alias);
1707     ev->size = size;
1708 
1709     return (virObjectEvent *)ev;
1710 }
1711 
1712 
1713 virObjectEvent *
virDomainEventMemoryDeviceSizeChangeNewFromObj(virDomainObj * obj,const char * alias,unsigned long long size)1714 virDomainEventMemoryDeviceSizeChangeNewFromObj(virDomainObj *obj,
1715                                                const char *alias,
1716                                                unsigned long long size)
1717 {
1718     return virDomainEventMemoryDeviceSizeChangeNew(obj->def->id,
1719                                                    obj->def->name,
1720                                                    obj->def->uuid,
1721                                                    alias,
1722                                                    size);
1723 }
1724 
1725 
1726 virObjectEvent *
virDomainEventMemoryDeviceSizeChangeNewFromDom(virDomainPtr dom,const char * alias,unsigned long long size)1727 virDomainEventMemoryDeviceSizeChangeNewFromDom(virDomainPtr dom,
1728                                                const char *alias,
1729                                                unsigned long long size)
1730 {
1731     return virDomainEventMemoryDeviceSizeChangeNew(dom->id,
1732                                                    dom->name,
1733                                                    dom->uuid,
1734                                                    alias,
1735                                                    size);
1736 }
1737 
1738 
1739 static void
virDomainEventDispatchDefaultFunc(virConnectPtr conn,virObjectEvent * event,virConnectObjectEventGenericCallback cb,void * cbopaque)1740 virDomainEventDispatchDefaultFunc(virConnectPtr conn,
1741                                   virObjectEvent *event,
1742                                   virConnectObjectEventGenericCallback cb,
1743                                   void *cbopaque)
1744 {
1745     virDomainPtr dom = virGetDomain(conn, event->meta.name,
1746                                     event->meta.uuid, event->meta.id);
1747 
1748     if (!dom)
1749         return;
1750 
1751     switch ((virDomainEventID) event->eventID) {
1752     case VIR_DOMAIN_EVENT_ID_LIFECYCLE:
1753         {
1754             virDomainEventLifecycle *lifecycleEvent;
1755 
1756             lifecycleEvent = (virDomainEventLifecycle *)event;
1757             ((virConnectDomainEventCallback)cb)(conn, dom,
1758                                                 lifecycleEvent->type,
1759                                                 lifecycleEvent->detail,
1760                                                 cbopaque);
1761             goto cleanup;
1762         }
1763 
1764     case VIR_DOMAIN_EVENT_ID_REBOOT:
1765         (cb)(conn, dom,
1766              cbopaque);
1767         goto cleanup;
1768 
1769     case VIR_DOMAIN_EVENT_ID_RTC_CHANGE:
1770         {
1771             virDomainEventRTCChange *rtcChangeEvent;
1772 
1773             rtcChangeEvent = (virDomainEventRTCChange *)event;
1774             ((virConnectDomainEventRTCChangeCallback)cb)(conn, dom,
1775                                                          rtcChangeEvent->offset,
1776                                                          cbopaque);
1777             goto cleanup;
1778         }
1779 
1780     case VIR_DOMAIN_EVENT_ID_WATCHDOG:
1781         {
1782             virDomainEventWatchdog *watchdogEvent;
1783 
1784             watchdogEvent = (virDomainEventWatchdog *)event;
1785             ((virConnectDomainEventWatchdogCallback)cb)(conn, dom,
1786                                                         watchdogEvent->action,
1787                                                         cbopaque);
1788             goto cleanup;
1789         }
1790 
1791     case VIR_DOMAIN_EVENT_ID_IO_ERROR:
1792         {
1793             virDomainEventIOError *ioErrorEvent;
1794 
1795             ioErrorEvent = (virDomainEventIOError *)event;
1796             ((virConnectDomainEventIOErrorCallback)cb)(conn, dom,
1797                                                        ioErrorEvent->srcPath,
1798                                                        ioErrorEvent->devAlias,
1799                                                        ioErrorEvent->action,
1800                                                        cbopaque);
1801             goto cleanup;
1802         }
1803 
1804     case VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON:
1805         {
1806             virDomainEventIOError *ioErrorEvent;
1807 
1808             ioErrorEvent = (virDomainEventIOError *)event;
1809             ((virConnectDomainEventIOErrorReasonCallback)cb)(conn, dom,
1810                                                              ioErrorEvent->srcPath,
1811                                                              ioErrorEvent->devAlias,
1812                                                              ioErrorEvent->action,
1813                                                              ioErrorEvent->reason,
1814                                                              cbopaque);
1815             goto cleanup;
1816         }
1817 
1818     case VIR_DOMAIN_EVENT_ID_GRAPHICS:
1819         {
1820             virDomainEventGraphics *graphicsEvent;
1821 
1822             graphicsEvent = (virDomainEventGraphics *)event;
1823             ((virConnectDomainEventGraphicsCallback)cb)(conn, dom,
1824                                                         graphicsEvent->phase,
1825                                                         graphicsEvent->local,
1826                                                         graphicsEvent->remote,
1827                                                         graphicsEvent->authScheme,
1828                                                         graphicsEvent->subject,
1829                                                         cbopaque);
1830             goto cleanup;
1831         }
1832 
1833     case VIR_DOMAIN_EVENT_ID_CONTROL_ERROR:
1834         (cb)(conn, dom,
1835              cbopaque);
1836         goto cleanup;
1837 
1838     case VIR_DOMAIN_EVENT_ID_BLOCK_JOB:
1839     case VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2:
1840         {
1841             virDomainEventBlockJob *blockJobEvent;
1842 
1843             blockJobEvent = (virDomainEventBlockJob *)event;
1844             ((virConnectDomainEventBlockJobCallback)cb)(conn, dom,
1845                                                         blockJobEvent->disk,
1846                                                         blockJobEvent->type,
1847                                                         blockJobEvent->status,
1848                                                         cbopaque);
1849             goto cleanup;
1850         }
1851 
1852     case VIR_DOMAIN_EVENT_ID_DISK_CHANGE:
1853         {
1854             virDomainEventDiskChange *diskChangeEvent;
1855 
1856             diskChangeEvent = (virDomainEventDiskChange *)event;
1857             ((virConnectDomainEventDiskChangeCallback)cb)(conn, dom,
1858                                                           diskChangeEvent->oldSrcPath,
1859                                                           diskChangeEvent->newSrcPath,
1860                                                           diskChangeEvent->devAlias,
1861                                                           diskChangeEvent->reason,
1862                                                           cbopaque);
1863             goto cleanup;
1864         }
1865 
1866     case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE:
1867         {
1868             virDomainEventTrayChange *trayChangeEvent;
1869 
1870             trayChangeEvent = (virDomainEventTrayChange *)event;
1871             ((virConnectDomainEventTrayChangeCallback)cb)(conn, dom,
1872                                                           trayChangeEvent->devAlias,
1873                                                           trayChangeEvent->reason,
1874                                                           cbopaque);
1875             goto cleanup;
1876         }
1877 
1878     case VIR_DOMAIN_EVENT_ID_PMWAKEUP:
1879         {
1880             virDomainEventPM *pmEvent = (virDomainEventPM *)event;
1881 
1882             ((virConnectDomainEventPMWakeupCallback)cb)(conn, dom,
1883                                                         pmEvent->reason,
1884                                                         cbopaque);
1885             goto cleanup;
1886         }
1887 
1888     case VIR_DOMAIN_EVENT_ID_PMSUSPEND:
1889         {
1890             virDomainEventPM *pmEvent = (virDomainEventPM *)event;
1891 
1892             ((virConnectDomainEventPMSuspendCallback)cb)(conn, dom,
1893                                                          pmEvent->reason,
1894                                                          cbopaque);
1895             goto cleanup;
1896         }
1897 
1898     case VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE:
1899         {
1900             virDomainEventBalloonChange *balloonChangeEvent;
1901 
1902             balloonChangeEvent = (virDomainEventBalloonChange *)event;
1903             ((virConnectDomainEventBalloonChangeCallback)cb)(conn, dom,
1904                                                              balloonChangeEvent->actual,
1905                                                              cbopaque);
1906             goto cleanup;
1907         }
1908 
1909     case VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK:
1910         {
1911             virDomainEventPM *pmEvent = (virDomainEventPM *)event;
1912 
1913             ((virConnectDomainEventPMSuspendDiskCallback)cb)(conn, dom,
1914                                                              pmEvent->reason,
1915                                                              cbopaque);
1916             goto cleanup;
1917         }
1918 
1919     case VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED:
1920         {
1921             virDomainEventDeviceRemoved *deviceRemovedEvent;
1922 
1923             deviceRemovedEvent = (virDomainEventDeviceRemoved *)event;
1924             ((virConnectDomainEventDeviceRemovedCallback)cb)(conn, dom,
1925                                                              deviceRemovedEvent->devAlias,
1926                                                              cbopaque);
1927             goto cleanup;
1928         }
1929 
1930     case VIR_DOMAIN_EVENT_ID_TUNABLE:
1931         {
1932             virDomainEventTunable *tunableEvent;
1933             tunableEvent = (virDomainEventTunable *)event;
1934             ((virConnectDomainEventTunableCallback)cb)(conn, dom,
1935                                                        tunableEvent->params,
1936                                                        tunableEvent->nparams,
1937                                                        cbopaque);
1938             goto cleanup;
1939         }
1940 
1941     case VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE:
1942         {
1943             virDomainEventAgentLifecycle *agentLifecycleEvent;
1944             agentLifecycleEvent = (virDomainEventAgentLifecycle *)event;
1945             ((virConnectDomainEventAgentLifecycleCallback)cb)(conn, dom,
1946                                                               agentLifecycleEvent->state,
1947                                                               agentLifecycleEvent->reason,
1948                                                               cbopaque);
1949             goto cleanup;
1950         }
1951 
1952     case VIR_DOMAIN_EVENT_ID_DEVICE_ADDED:
1953         {
1954             virDomainEventDeviceAdded *deviceAddedEvent;
1955 
1956             deviceAddedEvent = (virDomainEventDeviceAdded *)event;
1957             ((virConnectDomainEventDeviceAddedCallback)cb)(conn, dom,
1958                                                            deviceAddedEvent->devAlias,
1959                                                            cbopaque);
1960             goto cleanup;
1961         }
1962 
1963     case VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION:
1964         {
1965             virDomainEventMigrationIteration *ev;
1966 
1967             ev = (virDomainEventMigrationIteration *) event;
1968             ((virConnectDomainEventMigrationIterationCallback)cb)(conn, dom,
1969                                                                   ev->iteration,
1970                                                                   cbopaque);
1971             goto cleanup;
1972         }
1973 
1974     case VIR_DOMAIN_EVENT_ID_JOB_COMPLETED:
1975         {
1976             virDomainEventJobCompleted *ev;
1977 
1978             ev = (virDomainEventJobCompleted *) event;
1979             ((virConnectDomainEventJobCompletedCallback) cb)(conn, dom,
1980                                                              ev->params,
1981                                                              ev->nparams,
1982                                                              cbopaque);
1983             goto cleanup;
1984         }
1985 
1986     case VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED:
1987         {
1988             virDomainEventDeviceRemovalFailed *deviceRemovalFailedEvent;
1989 
1990             deviceRemovalFailedEvent = (virDomainEventDeviceRemovalFailed *)event;
1991             ((virConnectDomainEventDeviceRemovalFailedCallback)cb)(conn, dom,
1992                                                                    deviceRemovalFailedEvent->devAlias,
1993                                                                    cbopaque);
1994             goto cleanup;
1995         }
1996 
1997     case VIR_DOMAIN_EVENT_ID_METADATA_CHANGE:
1998         {
1999             virDomainEventMetadataChange *metadataChangeEvent;
2000 
2001             metadataChangeEvent = (virDomainEventMetadataChange *)event;
2002             ((virConnectDomainEventMetadataChangeCallback)cb)(conn, dom,
2003                                                               metadataChangeEvent->type,
2004                                                               metadataChangeEvent->nsuri,
2005                                                               cbopaque);
2006             goto cleanup;
2007         }
2008 
2009     case VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD:
2010         {
2011             virDomainEventBlockThreshold *blockThresholdEvent;
2012 
2013             blockThresholdEvent = (virDomainEventBlockThreshold *)event;
2014             ((virConnectDomainEventBlockThresholdCallback)cb)(conn, dom,
2015                                                               blockThresholdEvent->dev,
2016                                                               blockThresholdEvent->path,
2017                                                               blockThresholdEvent->threshold,
2018                                                               blockThresholdEvent->excess,
2019                                                               cbopaque);
2020             goto cleanup;
2021         }
2022     case VIR_DOMAIN_EVENT_ID_MEMORY_FAILURE:
2023         {
2024             virDomainEventMemoryFailure *memoryFailureEvent;
2025 
2026             memoryFailureEvent = (virDomainEventMemoryFailure *)event;
2027             ((virConnectDomainEventMemoryFailureCallback)cb)(conn, dom,
2028                                                              memoryFailureEvent->recipient,
2029                                                              memoryFailureEvent->action,
2030                                                              memoryFailureEvent->flags,
2031                                                              cbopaque);
2032             goto cleanup;
2033         }
2034 
2035     case VIR_DOMAIN_EVENT_ID_MEMORY_DEVICE_SIZE_CHANGE:
2036         {
2037             virDomainEventMemoryDeviceSizeChangePtr memoryDeviceSizeChangeEvent;
2038 
2039             memoryDeviceSizeChangeEvent = (virDomainEventMemoryDeviceSizeChangePtr)event;
2040             ((virConnectDomainEventMemoryDeviceSizeChangeCallback)cb)(conn, dom,
2041                                                                       memoryDeviceSizeChangeEvent->alias,
2042                                                                       memoryDeviceSizeChangeEvent->size,
2043                                                                       cbopaque);
2044             goto cleanup;
2045         }
2046 
2047     case VIR_DOMAIN_EVENT_ID_LAST:
2048         break;
2049     }
2050 
2051     VIR_WARN("Unexpected event ID %d", event->eventID);
2052 
2053  cleanup:
2054     virObjectUnref(dom);
2055 }
2056 
2057 
2058 virObjectEvent *
virDomainQemuMonitorEventNew(int id,const char * name,const unsigned char * uuid,const char * event,long long seconds,unsigned int micros,const char * details)2059 virDomainQemuMonitorEventNew(int id,
2060                              const char *name,
2061                              const unsigned char *uuid,
2062                              const char *event,
2063                              long long seconds,
2064                              unsigned int micros,
2065                              const char *details)
2066 {
2067     virDomainQemuMonitorEvent *ev;
2068     char uuidstr[VIR_UUID_STRING_BUFLEN];
2069 
2070     if (virDomainEventsInitialize() < 0)
2071         return NULL;
2072 
2073     virUUIDFormat(uuid, uuidstr);
2074     if (!(ev = virObjectEventNew(virDomainQemuMonitorEventClass,
2075                                  virDomainQemuMonitorEventDispatchFunc,
2076                                  0, id, name, uuid, uuidstr)))
2077         return NULL;
2078 
2079     ev->event = g_strdup(event);
2080     ev->seconds = seconds;
2081     ev->micros = micros;
2082     ev->details = g_strdup(details);
2083 
2084     return (virObjectEvent *)ev;
2085 }
2086 
2087 
2088 /* In order to filter by event name, we need to store a copy of the
2089  * name to filter on.  By wrapping the caller's freecb, we can
2090  * piggyback our cleanup to happen at the same time the caller
2091  * deregisters.  */
2092 struct virDomainQemuMonitorEventData {
2093     char *event;
2094     GRegex *regex;
2095     unsigned int flags;
2096     void *opaque;
2097     virFreeCallback freecb;
2098 };
2099 typedef struct virDomainQemuMonitorEventData virDomainQemuMonitorEventData;
2100 
2101 
2102 static void
virDomainQemuMonitorEventDispatchFunc(virConnectPtr conn,virObjectEvent * event,virConnectObjectEventGenericCallback cb,void * cbopaque)2103 virDomainQemuMonitorEventDispatchFunc(virConnectPtr conn,
2104                                       virObjectEvent *event,
2105                                       virConnectObjectEventGenericCallback cb,
2106                                       void *cbopaque)
2107 {
2108     virDomainPtr dom;
2109     virDomainQemuMonitorEvent *qemuMonitorEvent;
2110     virDomainQemuMonitorEventData *data = cbopaque;
2111 
2112     if (!(dom = virGetDomain(conn, event->meta.name,
2113                              event->meta.uuid, event->meta.id)))
2114         return;
2115 
2116     qemuMonitorEvent = (virDomainQemuMonitorEvent *)event;
2117     ((virConnectDomainQemuMonitorEventCallback)cb)(conn, dom,
2118                                                    qemuMonitorEvent->event,
2119                                                    qemuMonitorEvent->seconds,
2120                                                    qemuMonitorEvent->micros,
2121                                                    qemuMonitorEvent->details,
2122                                                    data->opaque);
2123     virObjectUnref(dom);
2124 }
2125 
2126 
2127 /**
2128  * virDomainEventStateRegister:
2129  * @conn: connection to associate with callback
2130  * @state: object event state
2131  * @callback: the callback to add
2132  * @opaque: data blob to pass to @callback
2133  * @freecb: callback to free @opaque
2134  *
2135  * Register the function @callback with connection @conn,
2136  * from @state, for lifecycle events.
2137  *
2138  * Returns: the number of lifecycle callbacks now registered, or -1 on error
2139  */
2140 int
virDomainEventStateRegister(virConnectPtr conn,virObjectEventState * state,virConnectDomainEventCallback callback,void * opaque,virFreeCallback freecb)2141 virDomainEventStateRegister(virConnectPtr conn,
2142                             virObjectEventState *state,
2143                             virConnectDomainEventCallback callback,
2144                             void *opaque,
2145                             virFreeCallback freecb)
2146 {
2147     int callbackID;
2148 
2149     if (virDomainEventsInitialize() < 0)
2150         return -1;
2151 
2152     return virObjectEventStateRegisterID(conn, state, NULL,
2153                                          NULL, NULL, virDomainEventClass,
2154                                          VIR_DOMAIN_EVENT_ID_LIFECYCLE,
2155                                          VIR_OBJECT_EVENT_CALLBACK(callback),
2156                                          opaque, freecb,
2157                                          true, &callbackID, false);
2158 }
2159 
2160 
2161 /**
2162  * virDomainEventStateRegisterID:
2163  * @conn: connection to associate with callback
2164  * @state: object event state
2165  * @dom: optional domain for filtering the event
2166  * @eventID: ID of the event type to register for
2167  * @cb: function to invoke when event fires
2168  * @opaque: data blob to pass to @callback
2169  * @freecb: callback to free @opaque
2170  * @callbackID: filled with callback ID
2171  *
2172  * Register the function @cb with connection @conn, from @state, for
2173  * events of type @eventID, and return the registration handle in
2174  * @callbackID.
2175  *
2176  * Returns: the number of callbacks now registered, or -1 on error
2177  */
2178 int
virDomainEventStateRegisterID(virConnectPtr conn,virObjectEventState * state,virDomainPtr dom,int eventID,virConnectDomainEventGenericCallback cb,void * opaque,virFreeCallback freecb,int * callbackID)2179 virDomainEventStateRegisterID(virConnectPtr conn,
2180                               virObjectEventState *state,
2181                               virDomainPtr dom,
2182                               int eventID,
2183                               virConnectDomainEventGenericCallback cb,
2184                               void *opaque,
2185                               virFreeCallback freecb,
2186                               int *callbackID)
2187 {
2188     char uuidstr[VIR_UUID_STRING_BUFLEN];
2189 
2190     if (virDomainEventsInitialize() < 0)
2191         return -1;
2192 
2193     if (dom)
2194         virUUIDFormat(dom->uuid, uuidstr);
2195     return virObjectEventStateRegisterID(conn, state, dom ? uuidstr : NULL,
2196                                          NULL, NULL,
2197                                          virDomainEventClass, eventID,
2198                                          VIR_OBJECT_EVENT_CALLBACK(cb),
2199                                          opaque, freecb,
2200                                          false, callbackID, false);
2201 }
2202 
2203 
2204 /**
2205  * virDomainEventStateRegisterClient:
2206  * @conn: connection to associate with callback
2207  * @state: object event state
2208  * @dom: optional domain for filtering the event
2209  * @eventID: ID of the event type to register for
2210  * @cb: function to invoke when event fires
2211  * @opaque: data blob to pass to @callback
2212  * @freecb: callback to free @opaque
2213  * @legacy: true if callback is tracked by function instead of callbackID
2214  * @callbackID: filled with callback ID
2215  * @remoteID: true if server supports filtering
2216  *
2217  * Register the function @cb with connection @conn, from @state, for
2218  * events of type @eventID, and return the registration handle in
2219  * @callbackID.  This version is intended for use on the client side
2220  * of RPC.
2221  *
2222  * Returns: the number of callbacks now registered, or -1 on error
2223  */
2224 int
virDomainEventStateRegisterClient(virConnectPtr conn,virObjectEventState * state,virDomainPtr dom,int eventID,virConnectDomainEventGenericCallback cb,void * opaque,virFreeCallback freecb,bool legacy,int * callbackID,bool remoteID)2225 virDomainEventStateRegisterClient(virConnectPtr conn,
2226                                   virObjectEventState *state,
2227                                   virDomainPtr dom,
2228                                   int eventID,
2229                                   virConnectDomainEventGenericCallback cb,
2230                                   void *opaque,
2231                                   virFreeCallback freecb,
2232                                   bool legacy,
2233                                   int *callbackID,
2234                                   bool remoteID)
2235 {
2236     char uuidstr[VIR_UUID_STRING_BUFLEN];
2237 
2238     if (virDomainEventsInitialize() < 0)
2239         return -1;
2240 
2241     if (dom)
2242         virUUIDFormat(dom->uuid, uuidstr);
2243     return virObjectEventStateRegisterID(conn, state, dom ? uuidstr : NULL,
2244                                          NULL, NULL,
2245                                          virDomainEventClass, eventID,
2246                                          VIR_OBJECT_EVENT_CALLBACK(cb),
2247                                          opaque, freecb,
2248                                          legacy, callbackID, remoteID);
2249 }
2250 
2251 
2252 /**
2253  * virDomainEventStateCallbackID:
2254  * @conn: connection associated with callback
2255  * @state: object event state
2256  * @cb: function registered as a callback with virDomainEventStateRegister()
2257  * @remoteID: associated remote id of the callback
2258  *
2259  * Returns the callbackID of @cb, or -1 with an error issued if the
2260  * function is not currently registered.
2261  */
2262 int
virDomainEventStateCallbackID(virConnectPtr conn,virObjectEventState * state,virConnectDomainEventCallback cb,int * remoteID)2263 virDomainEventStateCallbackID(virConnectPtr conn,
2264                               virObjectEventState *state,
2265                               virConnectDomainEventCallback cb,
2266                               int *remoteID)
2267 {
2268     return virObjectEventStateCallbackID(conn, state, virDomainEventClass,
2269                                          VIR_DOMAIN_EVENT_ID_LIFECYCLE,
2270                                          VIR_OBJECT_EVENT_CALLBACK(cb),
2271                                          remoteID);
2272 }
2273 
2274 
2275 /**
2276  * virDomainEventStateDeregister:
2277  * @conn: connection to associate with callback
2278  * @state: object event state
2279  * @cb: function to remove from event
2280  *
2281  * Unregister the function @cb with connection @conn, from @state, for
2282  * lifecycle events.
2283  *
2284  * Returns: the number of lifecycle callbacks still registered, or -1 on error
2285  */
2286 int
virDomainEventStateDeregister(virConnectPtr conn,virObjectEventState * state,virConnectDomainEventCallback cb)2287 virDomainEventStateDeregister(virConnectPtr conn,
2288                               virObjectEventState *state,
2289                               virConnectDomainEventCallback cb)
2290 {
2291     int callbackID;
2292 
2293     callbackID = virObjectEventStateCallbackID(conn, state,
2294                                                virDomainEventClass,
2295                                                VIR_DOMAIN_EVENT_ID_LIFECYCLE,
2296                                                VIR_OBJECT_EVENT_CALLBACK(cb),
2297                                                NULL);
2298     if (callbackID < 0)
2299         return -1;
2300     return virObjectEventStateDeregisterID(conn, state, callbackID, true);
2301 }
2302 
2303 
2304 /**
2305  * virDomainQemuMonitorEventFilter:
2306  * @conn: the connection pointer
2307  * @event: the event about to be dispatched
2308  * @opaque: the opaque data registered with the filter
2309  *
2310  * Callback for filtering based on event names.  Returns true if the
2311  * event should be dispatched.
2312  */
2313 static bool
virDomainQemuMonitorEventFilter(virConnectPtr conn G_GNUC_UNUSED,virObjectEvent * event,void * opaque)2314 virDomainQemuMonitorEventFilter(virConnectPtr conn G_GNUC_UNUSED,
2315                                 virObjectEvent *event,
2316                                 void *opaque)
2317 {
2318     virDomainQemuMonitorEventData *data = opaque;
2319     virDomainQemuMonitorEvent *monitorEvent;
2320 
2321     monitorEvent = (virDomainQemuMonitorEvent *) event;
2322 
2323     if (data->flags == -1)
2324         return true;
2325     if (data->flags & VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX)
2326         return g_regex_match(data->regex, monitorEvent->event, 0, NULL) == TRUE;
2327     if (data->flags & VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_NOCASE)
2328         return STRCASEEQ(monitorEvent->event, data->event);
2329     return STREQ(monitorEvent->event, data->event);
2330 }
2331 
2332 
2333 static void
virDomainQemuMonitorEventCleanup(void * opaque)2334 virDomainQemuMonitorEventCleanup(void *opaque)
2335 {
2336     virDomainQemuMonitorEventData *data = opaque;
2337 
2338     VIR_FREE(data->event);
2339     if (data->regex)
2340         g_regex_unref(data->regex);
2341     if (data->freecb)
2342         (data->freecb)(data->opaque);
2343     VIR_FREE(data);
2344 }
2345 
2346 
2347 /**
2348  * virDomainQemuMonitorEventStateRegisterID:
2349  * @conn: connection to associate with callback
2350  * @state: object event state
2351  * @dom: optional domain where event must occur
2352  * @event: optional name of event to register for
2353  * @cb: function to invoke when event occurs
2354  * @opaque: data blob to pass to callback
2355  * @freecb: callback to free @opaque
2356  * @flags: -1 for client, valid virConnectDomainQemuMonitorEventRegisterFlags
2357  *         for server
2358  * @callbackID: filled with callback ID
2359  *
2360  * Register the function @cb with connection @conn, from @state, for
2361  * events of type @eventID.
2362  *
2363  * Returns: the number of callbacks now registered, or -1 on error
2364  */
2365 int
virDomainQemuMonitorEventStateRegisterID(virConnectPtr conn,virObjectEventState * state,virDomainPtr dom,const char * event,virConnectDomainQemuMonitorEventCallback cb,void * opaque,virFreeCallback freecb,unsigned int flags,int * callbackID)2366 virDomainQemuMonitorEventStateRegisterID(virConnectPtr conn,
2367                                          virObjectEventState *state,
2368                                          virDomainPtr dom,
2369                                          const char *event,
2370                                          virConnectDomainQemuMonitorEventCallback cb,
2371                                          void *opaque,
2372                                          virFreeCallback freecb,
2373                                          unsigned int flags,
2374                                          int *callbackID)
2375 {
2376     virDomainQemuMonitorEventData *data = NULL;
2377     virObjectEventCallbackFilter filter = NULL;
2378     char uuidstr[VIR_UUID_STRING_BUFLEN];
2379 
2380     if (virDomainEventsInitialize() < 0)
2381         return -1;
2382 
2383     if (flags != -1)
2384         virCheckFlags(VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX |
2385                       VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_NOCASE,
2386                       -1);
2387     data = g_new0(virDomainQemuMonitorEventData, 1);
2388     data->flags = flags;
2389     if (event && flags != -1) {
2390         if (flags & VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX) {
2391             int cflags = G_REGEX_OPTIMIZE;
2392             g_autoptr(GError) err = NULL;
2393 
2394             if (flags & VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_NOCASE)
2395                 cflags |= G_REGEX_CASELESS;
2396             data->regex = g_regex_new(event, cflags, 0, &err);
2397             if (!data->regex) {
2398                 virReportError(VIR_ERR_INVALID_ARG,
2399                                _("failed to compile regex '%s': %s"),
2400                                event, err->message);
2401                 VIR_FREE(data);
2402                 return -1;
2403             }
2404         } else {
2405             data->event = g_strdup(event);
2406         }
2407     }
2408     data->opaque = opaque;
2409     data->freecb = freecb;
2410     if (event)
2411         filter = virDomainQemuMonitorEventFilter;
2412     freecb = virDomainQemuMonitorEventCleanup;
2413 
2414     if (dom)
2415         virUUIDFormat(dom->uuid, uuidstr);
2416     return virObjectEventStateRegisterID(conn, state, dom ? uuidstr : NULL,
2417                                          filter, data,
2418                                          virDomainQemuMonitorEventClass, 0,
2419                                          VIR_OBJECT_EVENT_CALLBACK(cb),
2420                                          data, freecb,
2421                                          false, callbackID, false);
2422 }
2423