You need to sign in or sign up before continuing.
domain_event.c 46.5 KB
Newer Older
1 2 3
/*
 * domain_event.c: domain event queue processing helpers
 *
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 9 10 11 12 13 14 15 16 17 18
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library.  If not, see
O
Osier Yang 已提交
20
 * <http://www.gnu.org/licenses/>.
21 22 23 24 25 26 27
 *
 * Author: Ben Guthro
 */

#include <config.h>

#include "domain_event.h"
28 29
#include "object_event.h"
#include "object_event_private.h"
30
#include "virlog.h"
31
#include "datatypes.h"
32
#include "viralloc.h"
33
#include "virerror.h"
34
#include "virstring.h"
C
Cole Robinson 已提交
35 36 37

#define VIR_FROM_THIS VIR_FROM_NONE

38
VIR_LOG_INIT("util.domain_event");
39

C
Cédric Bosdonnat 已提交
40
static virClassPtr virDomainEventClass;
41
static virClassPtr virDomainEventLifecycleClass;
42
static virClassPtr virDomainEventRTCChangeClass;
43
static virClassPtr virDomainEventWatchdogClass;
44
static virClassPtr virDomainEventIOErrorClass;
45
static virClassPtr virDomainEventGraphicsClass;
46
static virClassPtr virDomainEventBlockJobClass;
47
static virClassPtr virDomainEventDiskChangeClass;
48
static virClassPtr virDomainEventTrayChangeClass;
49
static virClassPtr virDomainEventBalloonChangeClass;
50
static virClassPtr virDomainEventDeviceRemovedClass;
E
Eric Blake 已提交
51
static virClassPtr virDomainEventPMClass;
52

53

C
Cédric Bosdonnat 已提交
54
static void virDomainEventDispose(void *obj);
55
static void virDomainEventLifecycleDispose(void *obj);
56
static void virDomainEventRTCChangeDispose(void *obj);
57
static void virDomainEventWatchdogDispose(void *obj);
58
static void virDomainEventIOErrorDispose(void *obj);
59
static void virDomainEventGraphicsDispose(void *obj);
60
static void virDomainEventBlockJobDispose(void *obj);
61
static void virDomainEventDiskChangeDispose(void *obj);
62
static void virDomainEventTrayChangeDispose(void *obj);
63
static void virDomainEventBalloonChangeDispose(void *obj);
64
static void virDomainEventDeviceRemovedDispose(void *obj);
E
Eric Blake 已提交
65
static void virDomainEventPMDispose(void *obj);
C
Cédric Bosdonnat 已提交
66

67 68 69 70 71
static void
virDomainEventDispatchDefaultFunc(virConnectPtr conn,
                                  virObjectEventPtr event,
                                  virConnectObjectEventGenericCallback cb,
                                  void *cbopaque);
C
Cédric Bosdonnat 已提交
72 73 74

struct _virDomainEvent {
    virObjectEvent parent;
75

76
    /* Unused attribute to allow for subclass creation */
77
    bool dummy;
78
};
79 80
typedef struct _virDomainEvent virDomainEvent;
typedef virDomainEvent *virDomainEventPtr;
81

82 83 84 85 86 87 88 89 90
struct _virDomainEventLifecycle {
    virDomainEvent parent;

    int type;
    int detail;
};
typedef struct _virDomainEventLifecycle virDomainEventLifecycle;
typedef virDomainEventLifecycle *virDomainEventLifecyclePtr;

91 92 93 94 95 96 97
struct _virDomainEventRTCChange {
    virDomainEvent parent;

    long long offset;
};
typedef struct _virDomainEventRTCChange virDomainEventRTCChange;
typedef virDomainEventRTCChange *virDomainEventRTCChangePtr;
98

99 100 101 102 103 104 105 106
struct _virDomainEventWatchdog {
    virDomainEvent parent;

    int action;
};
typedef struct _virDomainEventWatchdog virDomainEventWatchdog;
typedef virDomainEventWatchdog *virDomainEventWatchdogPtr;

107 108 109 110 111 112 113 114 115 116 117
struct _virDomainEventIOError {
    virDomainEvent parent;

    char *srcPath;
    char *devAlias;
    int action;
    char *reason;
};
typedef struct _virDomainEventIOError virDomainEventIOError;
typedef virDomainEventIOError *virDomainEventIOErrorPtr;

118 119 120 121 122 123 124 125 126 127
struct _virDomainEventBlockJob {
    virDomainEvent parent;

    char *path;
    int type;
    int status;
};
typedef struct _virDomainEventBlockJob virDomainEventBlockJob;
typedef virDomainEventBlockJob *virDomainEventBlockJobPtr;

128 129 130 131 132 133 134 135 136 137 138 139
struct _virDomainEventGraphics {
    virDomainEvent parent;

    int phase;
    virDomainEventGraphicsAddressPtr local;
    virDomainEventGraphicsAddressPtr remote;
    char *authScheme;
    virDomainEventGraphicsSubjectPtr subject;
};
typedef struct _virDomainEventGraphics virDomainEventGraphics;
typedef virDomainEventGraphics *virDomainEventGraphicsPtr;

140 141 142 143 144 145 146 147 148 149 150
struct _virDomainEventDiskChange {
    virDomainEvent parent;

    char *oldSrcPath;
    char *newSrcPath;
    char *devAlias;
    int reason;
};
typedef struct _virDomainEventDiskChange virDomainEventDiskChange;
typedef virDomainEventDiskChange *virDomainEventDiskChangePtr;

151 152 153 154 155 156 157 158 159
struct _virDomainEventTrayChange {
    virDomainEvent parent;

    char *devAlias;
    int reason;
};
typedef struct _virDomainEventTrayChange virDomainEventTrayChange;
typedef virDomainEventTrayChange *virDomainEventTrayChangePtr;

160 161 162 163 164 165 166 167 168
struct _virDomainEventBalloonChange {
    virDomainEvent parent;

    /* In unit of 1024 bytes */
    unsigned long long actual;
};
typedef struct _virDomainEventBalloonChange virDomainEventBalloonChange;
typedef virDomainEventBalloonChange *virDomainEventBalloonChangePtr;

169 170 171 172 173 174 175 176
struct _virDomainEventDeviceRemoved {
    virDomainEvent parent;

    char *devAlias;
};
typedef struct _virDomainEventDeviceRemoved virDomainEventDeviceRemoved;
typedef virDomainEventDeviceRemoved *virDomainEventDeviceRemovedPtr;

E
Eric Blake 已提交
177 178 179 180 181 182 183 184
struct _virDomainEventPM {
    virDomainEvent parent;

    int reason;
};
typedef struct _virDomainEventPM virDomainEventPM;
typedef virDomainEventPM *virDomainEventPMPtr;

185

186 187
static int
virDomainEventsOnceInit(void)
188
{
C
Cédric Bosdonnat 已提交
189
    if (!(virDomainEventClass =
190
          virClassNew(virClassForObjectEvent(),
C
Cédric Bosdonnat 已提交
191 192 193 194
                      "virDomainEvent",
                      sizeof(virDomainEvent),
                      virDomainEventDispose)))
        return -1;
195 196 197 198 199 200
    if (!(virDomainEventLifecycleClass =
          virClassNew(virDomainEventClass,
                      "virDomainEventLifecycle",
                      sizeof(virDomainEventLifecycle),
                      virDomainEventLifecycleDispose)))
        return -1;
201 202 203 204 205 206
    if (!(virDomainEventRTCChangeClass =
          virClassNew(virDomainEventClass,
                      "virDomainEventRTCChange",
                      sizeof(virDomainEventRTCChange),
                      virDomainEventRTCChangeDispose)))
        return -1;
207 208 209 210 211 212
    if (!(virDomainEventWatchdogClass =
          virClassNew(virDomainEventClass,
                      "virDomainEventWatchdog",
                      sizeof(virDomainEventWatchdog),
                      virDomainEventWatchdogDispose)))
        return -1;
213 214 215 216 217 218
    if (!(virDomainEventIOErrorClass =
          virClassNew(virDomainEventClass,
                      "virDomainEventIOError",
                      sizeof(virDomainEventIOError),
                      virDomainEventIOErrorDispose)))
        return -1;
219 220 221 222 223 224
    if (!(virDomainEventGraphicsClass =
          virClassNew(virDomainEventClass,
                      "virDomainEventGraphics",
                      sizeof(virDomainEventGraphics),
                      virDomainEventGraphicsDispose)))
        return -1;
225 226 227 228 229 230
    if (!(virDomainEventBlockJobClass =
          virClassNew(virDomainEventClass,
                      "virDomainEventBlockJob",
                      sizeof(virDomainEventBlockJob),
                      virDomainEventBlockJobDispose)))
        return -1;
231 232 233 234 235 236
    if (!(virDomainEventDiskChangeClass =
          virClassNew(virDomainEventClass,
                      "virDomainEventDiskChange",
                      sizeof(virDomainEventDiskChange),
                      virDomainEventDiskChangeDispose)))
        return -1;
237 238 239 240 241 242
    if (!(virDomainEventTrayChangeClass =
          virClassNew(virDomainEventClass,
                      "virDomainEventTrayChange",
                      sizeof(virDomainEventTrayChange),
                      virDomainEventTrayChangeDispose)))
        return -1;
243 244 245 246 247 248
    if (!(virDomainEventBalloonChangeClass =
          virClassNew(virDomainEventClass,
                      "virDomainEventBalloonChange",
                      sizeof(virDomainEventBalloonChange),
                      virDomainEventBalloonChangeDispose)))
        return -1;
249 250 251 252 253 254
    if (!(virDomainEventDeviceRemovedClass =
          virClassNew(virDomainEventClass,
                      "virDomainEventDeviceRemoved",
                      sizeof(virDomainEventDeviceRemoved),
                      virDomainEventDeviceRemovedDispose)))
        return -1;
E
Eric Blake 已提交
255 256 257 258 259 260
    if (!(virDomainEventPMClass =
          virClassNew(virDomainEventClass,
                      "virDomainEventPM",
                      sizeof(virDomainEventPM),
                      virDomainEventPMDispose)))
        return -1;
C
Cédric Bosdonnat 已提交
261 262 263
    return 0;
}

264
VIR_ONCE_GLOBAL_INIT(virDomainEvents)
C
Cédric Bosdonnat 已提交
265 266


267 268
static void
virDomainEventDispose(void *obj)
C
Cédric Bosdonnat 已提交
269 270 271 272 273 274
{
    virDomainEventPtr event = obj;

    VIR_DEBUG("obj=%p", event);
}

275 276
static void
virDomainEventLifecycleDispose(void *obj)
277 278 279 280 281
{
    virDomainEventLifecyclePtr event = obj;
    VIR_DEBUG("obj=%p", event);
}

282 283
static void
virDomainEventRTCChangeDispose(void *obj)
284 285 286 287 288
{
    virDomainEventRTCChangePtr event = obj;
    VIR_DEBUG("obj=%p", event);
}

289 290
static void
virDomainEventWatchdogDispose(void *obj)
291 292 293 294 295
{
    virDomainEventWatchdogPtr event = obj;
    VIR_DEBUG("obj=%p", event);
}

296 297
static void
virDomainEventIOErrorDispose(void *obj)
298 299 300 301 302 303 304 305 306
{
    virDomainEventIOErrorPtr event = obj;
    VIR_DEBUG("obj=%p", event);

    VIR_FREE(event->srcPath);
    VIR_FREE(event->devAlias);
    VIR_FREE(event->reason);
}

307 308
static void
virDomainEventGraphicsDispose(void *obj)
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
{
    virDomainEventGraphicsPtr event = obj;
    VIR_DEBUG("obj=%p", event);

    if (event->local) {
        VIR_FREE(event->local->node);
        VIR_FREE(event->local->service);
        VIR_FREE(event->local);
    }
    if (event->remote) {
        VIR_FREE(event->remote->node);
        VIR_FREE(event->remote->service);
        VIR_FREE(event->remote);
    }
    VIR_FREE(event->authScheme);
    if (event->subject) {
        size_t i;
        for (i = 0; i < event->subject->nidentity; i++) {
            VIR_FREE(event->subject->identities[i].type);
            VIR_FREE(event->subject->identities[i].name);
        }
        VIR_FREE(event->subject);
    }
}

334 335
static void
virDomainEventBlockJobDispose(void *obj)
336 337 338 339 340 341 342
{
    virDomainEventBlockJobPtr event = obj;
    VIR_DEBUG("obj=%p", event);

    VIR_FREE(event->path);
}

343 344
static void
virDomainEventDiskChangeDispose(void *obj)
345 346 347 348 349 350 351 352 353
{
    virDomainEventDiskChangePtr event = obj;
    VIR_DEBUG("obj=%p", event);

    VIR_FREE(event->oldSrcPath);
    VIR_FREE(event->newSrcPath);
    VIR_FREE(event->devAlias);
}

354 355
static void
virDomainEventTrayChangeDispose(void *obj)
356 357 358 359 360 361 362
{
    virDomainEventTrayChangePtr event = obj;
    VIR_DEBUG("obj=%p", event);

    VIR_FREE(event->devAlias);
}

363 364
static void
virDomainEventBalloonChangeDispose(void *obj)
365 366 367 368 369
{
    virDomainEventBalloonChangePtr event = obj;
    VIR_DEBUG("obj=%p", event);
}

370 371
static void
virDomainEventDeviceRemovedDispose(void *obj)
372 373 374 375 376 377 378
{
    virDomainEventDeviceRemovedPtr event = obj;
    VIR_DEBUG("obj=%p", event);

    VIR_FREE(event->devAlias);
}

E
Eric Blake 已提交
379 380 381 382 383 384 385
static void
virDomainEventPMDispose(void *obj)
{
    virDomainEventPMPtr event = obj;
    VIR_DEBUG("obj=%p", event);
}

386

387 388 389 390 391 392
static void *
virDomainEventNew(virClassPtr klass,
                  int eventID,
                  int id,
                  const char *name,
                  const unsigned char *uuid)
C
Cédric Bosdonnat 已提交
393 394 395
{
    virDomainEventPtr event;

396
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
397 398 399 400 401 402 403 404 405
        return NULL;

    if (!virClassIsDerivedFrom(klass, virDomainEventClass)) {
        virReportInvalidArg(klass,
                            _("Class %s must derive from virDomainEvent"),
                            virClassName(klass));
        return NULL;
    }

406 407 408
    if (!(event = virObjectEventNew(klass,
                                    virDomainEventDispatchDefaultFunc,
                                    eventID,
409
                                    id, name, uuid)))
410
        return NULL;
411

412
    return (virObjectEventPtr)event;
413 414
}

415 416 417 418 419 420
virObjectEventPtr
virDomainEventLifecycleNew(int id,
                           const char *name,
                           const unsigned char *uuid,
                           int type,
                           int detail)
421
{
422
    virDomainEventLifecyclePtr event;
423

424
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
425 426
        return NULL;

427 428 429
    if (!(event = virDomainEventNew(virDomainEventLifecycleClass,
                                    VIR_DOMAIN_EVENT_ID_LIFECYCLE,
                                    id, name, uuid)))
C
Cédric Bosdonnat 已提交
430 431
        return NULL;

432 433
    event->type = type;
    event->detail = detail;
434

435
    return (virObjectEventPtr)event;
436 437
}

438 439 440 441
virObjectEventPtr
virDomainEventLifecycleNewFromDom(virDomainPtr dom,
                                  int type,
                                  int detail)
442
{
443 444
    return virDomainEventLifecycleNew(dom->id, dom->name, dom->uuid,
                                      type, detail);
445 446
}

447 448 449 450
virObjectEventPtr
virDomainEventLifecycleNewFromObj(virDomainObjPtr obj,
                                  int type,
                                  int detail)
451
{
452
    return virDomainEventLifecycleNewFromDef(obj->def, type, detail);
453 454
}

455 456 457 458
virObjectEventPtr
virDomainEventLifecycleNewFromDef(virDomainDefPtr def,
                                  int type,
                                  int detail)
459
{
460 461
    return virDomainEventLifecycleNew(def->id, def->name, def->uuid,
                                      type, detail);
462 463
}

464 465 466 467
virObjectEventPtr
virDomainEventRebootNew(int id,
                        const char *name,
                        const unsigned char *uuid)
M
Matthias Bolte 已提交
468
{
469
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
470 471
        return NULL;

472 473 474
    return virDomainEventNew(virDomainEventClass,
                             VIR_DOMAIN_EVENT_ID_REBOOT,
                             id, name, uuid);
M
Matthias Bolte 已提交
475 476
}

477 478
virObjectEventPtr
virDomainEventRebootNewFromDom(virDomainPtr dom)
479
{
480
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
481 482
        return NULL;

483 484 485
    return virDomainEventNew(virDomainEventClass,
                             VIR_DOMAIN_EVENT_ID_REBOOT,
                             dom->id, dom->name, dom->uuid);
486
}
M
Matthias Bolte 已提交
487

488 489
virObjectEventPtr
virDomainEventRebootNewFromObj(virDomainObjPtr obj)
490
{
491
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
492 493
        return NULL;

494 495 496
    return virDomainEventNew(virDomainEventClass,
                             VIR_DOMAIN_EVENT_ID_REBOOT,
                             obj->def->id, obj->def->name, obj->def->uuid);
497 498
}

499 500 501
virObjectEventPtr
virDomainEventRTCChangeNewFromDom(virDomainPtr dom,
                                  long long offset)
502
{
503
    virDomainEventRTCChangePtr ev;
C
Cédric Bosdonnat 已提交
504

505
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
506 507
        return NULL;

508
    if (!(ev = virDomainEventNew(virDomainEventRTCChangeClass,
509 510
                                 VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
                                 dom->id, dom->name, dom->uuid)))
C
Cédric Bosdonnat 已提交
511
        return NULL;
512

513
    ev->offset = offset;
514

515
    return (virObjectEventPtr)ev;
516
}
517 518 519
virObjectEventPtr
virDomainEventRTCChangeNewFromObj(virDomainObjPtr obj,
                                  long long offset)
520
{
521
    virDomainEventRTCChangePtr ev;
522

523
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
524 525
        return NULL;

526
    if (!(ev = virDomainEventNew(virDomainEventRTCChangeClass,
527 528 529
                                 VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
                                 obj->def->id, obj->def->name,
                                 obj->def->uuid)))
C
Cédric Bosdonnat 已提交
530 531
        return NULL;

532
    ev->offset = offset;
533

534
    return (virObjectEventPtr)ev;
535 536
}

537 538 539
virObjectEventPtr
virDomainEventWatchdogNewFromDom(virDomainPtr dom,
                                 int action)
540
{
541
    virDomainEventWatchdogPtr ev;
542

543
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
544 545
        return NULL;

546
    if (!(ev = virDomainEventNew(virDomainEventWatchdogClass,
547 548
                                 VIR_DOMAIN_EVENT_ID_WATCHDOG,
                                 dom->id, dom->name, dom->uuid)))
C
Cédric Bosdonnat 已提交
549 550
        return NULL;

551
    ev->action = action;
552

553
    return (virObjectEventPtr)ev;
554
}
555 556 557
virObjectEventPtr
virDomainEventWatchdogNewFromObj(virDomainObjPtr obj,
                                 int action)
558
{
559
    virDomainEventWatchdogPtr ev;
C
Cédric Bosdonnat 已提交
560

561
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
562
        return NULL;
563

564
    if (!(ev = virDomainEventNew(virDomainEventWatchdogClass,
565 566 567
                                 VIR_DOMAIN_EVENT_ID_WATCHDOG,
                                 obj->def->id, obj->def->name,
                                 obj->def->uuid)))
C
Cédric Bosdonnat 已提交
568 569
        return NULL;

570
    ev->action = action;
571

572
    return (virObjectEventPtr)ev;
573 574
}

575 576 577 578 579 580 581
static virObjectEventPtr
virDomainEventIOErrorNewFromDomImpl(int event,
                                    virDomainPtr dom,
                                    const char *srcPath,
                                    const char *devAlias,
                                    int action,
                                    const char *reason)
582
{
583
    virDomainEventIOErrorPtr ev;
C
Cédric Bosdonnat 已提交
584

585
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
586 587
        return NULL;

588
    if (!(ev = virDomainEventNew(virDomainEventIOErrorClass, event,
589
                                 dom->id, dom->name, dom->uuid)))
C
Cédric Bosdonnat 已提交
590 591
        return NULL;

592 593 594 595
    ev->action = action;
    if (VIR_STRDUP(ev->srcPath, srcPath) < 0 ||
        VIR_STRDUP(ev->devAlias, devAlias) < 0 ||
        VIR_STRDUP(ev->reason, reason) < 0) {
C
Cédric Bosdonnat 已提交
596 597
        virObjectUnref(ev);
        ev = NULL;
598 599
    }

600
    return (virObjectEventPtr)ev;
601
}
602

603 604 605 606 607 608 609
static virObjectEventPtr
virDomainEventIOErrorNewFromObjImpl(int event,
                                    virDomainObjPtr obj,
                                    const char *srcPath,
                                    const char *devAlias,
                                    int action,
                                    const char *reason)
610
{
611
    virDomainEventIOErrorPtr ev;
C
Cédric Bosdonnat 已提交
612

613
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
614 615
        return NULL;

616
    if (!(ev = virDomainEventNew(virDomainEventIOErrorClass, event,
617 618
                                 obj->def->id, obj->def->name,
                                 obj->def->uuid)))
C
Cédric Bosdonnat 已提交
619 620
        return NULL;

621 622 623 624
    ev->action = action;
    if (VIR_STRDUP(ev->srcPath, srcPath) < 0 ||
        VIR_STRDUP(ev->devAlias, devAlias) < 0 ||
        VIR_STRDUP(ev->reason, reason) < 0) {
C
Cédric Bosdonnat 已提交
625 626
        virObjectUnref(ev);
        ev = NULL;
627 628
    }

629
    return (virObjectEventPtr)ev;
630 631
}

632 633 634 635 636
virObjectEventPtr
virDomainEventIOErrorNewFromDom(virDomainPtr dom,
                                const char *srcPath,
                                const char *devAlias,
                                int action)
637 638 639 640 641 642
{
    return virDomainEventIOErrorNewFromDomImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR,
                                               dom, srcPath, devAlias,
                                               action, NULL);
}

643 644 645 646 647
virObjectEventPtr
virDomainEventIOErrorNewFromObj(virDomainObjPtr obj,
                                const char *srcPath,
                                const char *devAlias,
                                int action)
648 649 650 651 652 653
{
    return virDomainEventIOErrorNewFromObjImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR,
                                               obj, srcPath, devAlias,
                                               action, NULL);
}

654 655 656 657 658 659
virObjectEventPtr
virDomainEventIOErrorReasonNewFromDom(virDomainPtr dom,
                                      const char *srcPath,
                                      const char *devAlias,
                                      int action,
                                      const char *reason)
660 661 662 663 664 665
{
    return virDomainEventIOErrorNewFromDomImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON,
                                               dom, srcPath, devAlias,
                                               action, reason);
}

666 667 668 669 670 671
virObjectEventPtr
virDomainEventIOErrorReasonNewFromObj(virDomainObjPtr obj,
                                      const char *srcPath,
                                      const char *devAlias,
                                      int action,
                                      const char *reason)
672 673 674 675 676 677
{
    return virDomainEventIOErrorNewFromObjImpl(VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON,
                                               obj, srcPath, devAlias,
                                               action, reason);
}

678

679 680 681 682 683 684 685
virObjectEventPtr
virDomainEventGraphicsNewFromDom(virDomainPtr dom,
                                 int phase,
                                 virDomainEventGraphicsAddressPtr local,
                                 virDomainEventGraphicsAddressPtr remote,
                                 const char *authScheme,
                                 virDomainEventGraphicsSubjectPtr subject)
686
{
687
    virDomainEventGraphicsPtr ev;
688

689
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
690 691
        return NULL;

692
    if (!(ev = virDomainEventNew(virDomainEventGraphicsClass,
693 694
                                 VIR_DOMAIN_EVENT_ID_GRAPHICS,
                                 dom->id, dom->name, dom->uuid)))
C
Cédric Bosdonnat 已提交
695 696
        return NULL;

697 698
    ev->phase = phase;
    if (VIR_STRDUP(ev->authScheme, authScheme) < 0) {
C
Cédric Bosdonnat 已提交
699 700
        virObjectUnref(ev);
        return NULL;
701
    }
702 703 704
    ev->local = local;
    ev->remote = remote;
    ev->subject = subject;
705

706
    return (virObjectEventPtr)ev;
707 708
}

709 710 711 712 713 714 715
virObjectEventPtr
virDomainEventGraphicsNewFromObj(virDomainObjPtr obj,
                                 int phase,
                                 virDomainEventGraphicsAddressPtr local,
                                 virDomainEventGraphicsAddressPtr remote,
                                 const char *authScheme,
                                 virDomainEventGraphicsSubjectPtr subject)
716
{
717
    virDomainEventGraphicsPtr ev;
718

719
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
720 721
        return NULL;

722
    if (!(ev = virDomainEventNew(virDomainEventGraphicsClass,
723 724 725
                                 VIR_DOMAIN_EVENT_ID_GRAPHICS,
                                 obj->def->id, obj->def->name,
                                 obj->def->uuid)))
C
Cédric Bosdonnat 已提交
726 727
        return NULL;

728 729
    ev->phase = phase;
    if (VIR_STRDUP(ev->authScheme, authScheme) < 0) {
C
Cédric Bosdonnat 已提交
730 731
        virObjectUnref(ev);
        return NULL;
732
    }
733 734 735
    ev->local = local;
    ev->remote = remote;
    ev->subject = subject;
736

737
    return (virObjectEventPtr)ev;
738 739
}

740 741 742 743 744 745 746
static virObjectEventPtr
virDomainEventBlockJobNew(int id,
                          const char *name,
                          unsigned char *uuid,
                          const char *path,
                          int type,
                          int status)
747
{
748
    virDomainEventBlockJobPtr ev;
749

750
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
751 752
        return NULL;

753
    if (!(ev = virDomainEventNew(virDomainEventBlockJobClass,
754 755
                                 VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
                                 id, name, uuid)))
C
Cédric Bosdonnat 已提交
756 757
        return NULL;

758
    if (VIR_STRDUP(ev->path, path) < 0) {
C
Cédric Bosdonnat 已提交
759 760
        virObjectUnref(ev);
        return NULL;
761
    }
762 763
    ev->type = type;
    ev->status = status;
764

765
    return (virObjectEventPtr)ev;
766 767
}

768 769 770 771 772
virObjectEventPtr
virDomainEventBlockJobNewFromObj(virDomainObjPtr obj,
                                 const char *path,
                                 int type,
                                 int status)
773 774 775 776 777
{
    return virDomainEventBlockJobNew(obj->def->id, obj->def->name,
                                     obj->def->uuid, path, type, status);
}

778 779 780 781 782
virObjectEventPtr
virDomainEventBlockJobNewFromDom(virDomainPtr dom,
                                 const char *path,
                                 int type,
                                 int status)
783 784 785 786
{
    return virDomainEventBlockJobNew(dom->id, dom->name, dom->uuid,
                                     path, type, status);
}
787

788 789
virObjectEventPtr
virDomainEventControlErrorNewFromDom(virDomainPtr dom)
790
{
791
    virObjectEventPtr ev;
C
Cédric Bosdonnat 已提交
792

793
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
794 795
        return NULL;

796 797 798
    if (!(ev = virDomainEventNew(virDomainEventClass,
                                 VIR_DOMAIN_EVENT_ID_CONTROL_ERROR,
                                 dom->id, dom->name, dom->uuid)))
C
Cédric Bosdonnat 已提交
799
        return NULL;
800 801 802 803
    return ev;
}


804 805
virObjectEventPtr
virDomainEventControlErrorNewFromObj(virDomainObjPtr obj)
806
{
807
    virObjectEventPtr ev;
C
Cédric Bosdonnat 已提交
808

809
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
810 811
        return NULL;

812 813 814 815
    if (!(ev = virDomainEventNew(virDomainEventClass,
                                 VIR_DOMAIN_EVENT_ID_CONTROL_ERROR,
                                 obj->def->id, obj->def->name,
                                 obj->def->uuid)))
C
Cédric Bosdonnat 已提交
816
        return NULL;
817 818 819
    return ev;
}

820 821 822 823 824 825 826 827
static virObjectEventPtr
virDomainEventDiskChangeNew(int id,
                            const char *name,
                            unsigned char *uuid,
                            const char *oldSrcPath,
                            const char *newSrcPath,
                            const char *devAlias,
                            int reason)
828
{
829
    virDomainEventDiskChangePtr ev;
830

831
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
832
        return NULL;
833

834
    if (!(ev = virDomainEventNew(virDomainEventDiskChangeClass,
835 836
                                 VIR_DOMAIN_EVENT_ID_DISK_CHANGE,
                                 id, name, uuid)))
C
Cédric Bosdonnat 已提交
837
        return NULL;
838

839
    if (VIR_STRDUP(ev->devAlias, devAlias) < 0)
C
Cédric Bosdonnat 已提交
840
        goto error;
841

842
    if (VIR_STRDUP(ev->oldSrcPath, oldSrcPath) < 0)
C
Cédric Bosdonnat 已提交
843 844
        goto error;

845
    if (VIR_STRDUP(ev->newSrcPath, newSrcPath) < 0)
C
Cédric Bosdonnat 已提交
846 847
        goto error;

848
    ev->reason = reason;
849

850
    return (virObjectEventPtr)ev;
851 852

error:
C
Cédric Bosdonnat 已提交
853
    virObjectUnref(ev);
854 855 856
    return NULL;
}

857 858 859 860 861 862
virObjectEventPtr
virDomainEventDiskChangeNewFromObj(virDomainObjPtr obj,
                                   const char *oldSrcPath,
                                   const char *newSrcPath,
                                   const char *devAlias,
                                   int reason)
863 864 865 866 867 868
{
    return virDomainEventDiskChangeNew(obj->def->id, obj->def->name,
                                       obj->def->uuid, oldSrcPath,
                                       newSrcPath, devAlias, reason);
}

869 870 871 872 873 874
virObjectEventPtr
virDomainEventDiskChangeNewFromDom(virDomainPtr dom,
                                   const char *oldSrcPath,
                                   const char *newSrcPath,
                                   const char *devAlias,
                                   int reason)
875 876 877 878 879
{
    return virDomainEventDiskChangeNew(dom->id, dom->name, dom->uuid,
                                       oldSrcPath, newSrcPath,
                                       devAlias, reason);
}
880

881
static virObjectEventPtr
882 883
virDomainEventTrayChangeNew(int id,
                            const char *name,
884 885 886 887
                            unsigned char *uuid,
                            const char *devAlias,
                            int reason)
{
888
    virDomainEventTrayChangePtr ev;
889

890
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
891
        return NULL;
892

893
    if (!(ev = virDomainEventNew(virDomainEventTrayChangeClass,
894 895
                                 VIR_DOMAIN_EVENT_ID_TRAY_CHANGE,
                                 id, name, uuid)))
C
Cédric Bosdonnat 已提交
896 897
        return NULL;

898
    if (VIR_STRDUP(ev->devAlias, devAlias) < 0)
C
Cédric Bosdonnat 已提交
899 900
        goto error;

901
    ev->reason = reason;
902

903
    return (virObjectEventPtr)ev;
904 905

error:
C
Cédric Bosdonnat 已提交
906
    virObjectUnref(ev);
907 908 909
    return NULL;
}

910 911 912 913
virObjectEventPtr
virDomainEventTrayChangeNewFromObj(virDomainObjPtr obj,
                                  const char *devAlias,
                                  int reason)
914 915 916 917 918 919 920 921
{
    return virDomainEventTrayChangeNew(obj->def->id,
                                       obj->def->name,
                                       obj->def->uuid,
                                       devAlias,
                                       reason);
}

922 923 924 925
virObjectEventPtr
virDomainEventTrayChangeNewFromDom(virDomainPtr dom,
                                   const char *devAlias,
                                   int reason)
926 927 928 929 930
{
    return virDomainEventTrayChangeNew(dom->id, dom->name, dom->uuid,
                                       devAlias, reason);
}

931
static virObjectEventPtr
932 933
virDomainEventPMWakeupNew(int id,
                          const char *name,
E
Eric Blake 已提交
934 935
                          unsigned char *uuid,
                          int reason)
O
Osier Yang 已提交
936
{
E
Eric Blake 已提交
937
    virDomainEventPMPtr ev;
C
Cédric Bosdonnat 已提交
938

939
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
940 941
        return NULL;

E
Eric Blake 已提交
942
    if (!(ev = virDomainEventNew(virDomainEventPMClass,
943 944
                                 VIR_DOMAIN_EVENT_ID_PMWAKEUP,
                                 id, name, uuid)))
C
Cédric Bosdonnat 已提交
945
        return NULL;
O
Osier Yang 已提交
946

E
Eric Blake 已提交
947 948
    ev->reason = reason;
    return (virObjectEventPtr)ev;
O
Osier Yang 已提交
949 950
}

951
virObjectEventPtr
O
Osier Yang 已提交
952 953 954 955
virDomainEventPMWakeupNewFromObj(virDomainObjPtr obj)
{
    return virDomainEventPMWakeupNew(obj->def->id,
                                     obj->def->name,
E
Eric Blake 已提交
956 957
                                     obj->def->uuid,
                                     0);
O
Osier Yang 已提交
958 959
}

960
virObjectEventPtr
E
Eric Blake 已提交
961
virDomainEventPMWakeupNewFromDom(virDomainPtr dom, int reason)
O
Osier Yang 已提交
962
{
E
Eric Blake 已提交
963
    return virDomainEventPMWakeupNew(dom->id, dom->name, dom->uuid, reason);
O
Osier Yang 已提交
964
}
965

966
static virObjectEventPtr
967 968
virDomainEventPMSuspendNew(int id,
                           const char *name,
E
Eric Blake 已提交
969 970
                           unsigned char *uuid,
                           int reason)
O
Osier Yang 已提交
971
{
E
Eric Blake 已提交
972
    virDomainEventPMPtr ev;
C
Cédric Bosdonnat 已提交
973

974
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
975 976
        return NULL;

E
Eric Blake 已提交
977
    if (!(ev = virDomainEventNew(virDomainEventPMClass,
978 979
                                 VIR_DOMAIN_EVENT_ID_PMSUSPEND,
                                 id, name, uuid)))
C
Cédric Bosdonnat 已提交
980
        return NULL;
O
Osier Yang 已提交
981

E
Eric Blake 已提交
982 983
    ev->reason = reason;
    return (virObjectEventPtr)ev;
O
Osier Yang 已提交
984 985
}

986
virObjectEventPtr
O
Osier Yang 已提交
987 988 989 990
virDomainEventPMSuspendNewFromObj(virDomainObjPtr obj)
{
    return virDomainEventPMSuspendNew(obj->def->id,
                                      obj->def->name,
E
Eric Blake 已提交
991 992
                                      obj->def->uuid,
                                      0);
O
Osier Yang 已提交
993 994
}

995
virObjectEventPtr
E
Eric Blake 已提交
996
virDomainEventPMSuspendNewFromDom(virDomainPtr dom, int reason)
O
Osier Yang 已提交
997
{
E
Eric Blake 已提交
998
    return virDomainEventPMSuspendNew(dom->id, dom->name, dom->uuid, reason);
O
Osier Yang 已提交
999 1000
}

1001
static virObjectEventPtr
1002 1003
virDomainEventPMSuspendDiskNew(int id,
                               const char *name,
E
Eric Blake 已提交
1004 1005
                               unsigned char *uuid,
                               int reason)
1006
{
E
Eric Blake 已提交
1007
    virDomainEventPMPtr ev;
C
Cédric Bosdonnat 已提交
1008

1009
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
1010 1011
        return NULL;

E
Eric Blake 已提交
1012
    if (!(ev = virDomainEventNew(virDomainEventPMClass,
1013 1014
                                 VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK,
                                 id, name, uuid)))
C
Cédric Bosdonnat 已提交
1015
        return NULL;
E
Eric Blake 已提交
1016 1017 1018

    ev->reason = reason;
    return (virObjectEventPtr)ev;
1019 1020
}

1021
virObjectEventPtr
1022 1023 1024 1025
virDomainEventPMSuspendDiskNewFromObj(virDomainObjPtr obj)
{
    return virDomainEventPMSuspendDiskNew(obj->def->id,
                                          obj->def->name,
E
Eric Blake 已提交
1026 1027
                                          obj->def->uuid,
                                          0);
1028 1029
}

1030
virObjectEventPtr
E
Eric Blake 已提交
1031
virDomainEventPMSuspendDiskNewFromDom(virDomainPtr dom, int reason)
1032
{
E
Eric Blake 已提交
1033 1034
    return virDomainEventPMSuspendDiskNew(dom->id, dom->name, dom->uuid,
                                          reason);
1035 1036
}

1037 1038 1039
virObjectEventPtr
virDomainEventBalloonChangeNewFromDom(virDomainPtr dom,
                                      unsigned long long actual)
1040
{
1041
    virDomainEventBalloonChangePtr ev;
C
Cédric Bosdonnat 已提交
1042

1043
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
1044 1045
        return NULL;

1046
    if (!(ev = virDomainEventNew(virDomainEventBalloonChangeClass,
1047 1048
                                 VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE,
                                 dom->id, dom->name, dom->uuid)))
C
Cédric Bosdonnat 已提交
1049
        return NULL;
1050

1051
    ev->actual = actual;
1052

1053
    return (virObjectEventPtr)ev;
1054
}
1055 1056 1057
virObjectEventPtr
virDomainEventBalloonChangeNewFromObj(virDomainObjPtr obj,
                                      unsigned long long actual)
1058
{
1059
    virDomainEventBalloonChangePtr ev;
C
Cédric Bosdonnat 已提交
1060

1061
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
1062 1063
        return NULL;

1064
    if (!(ev = virDomainEventNew(virDomainEventBalloonChangeClass,
1065 1066
                                 VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE,
                                 obj->def->id, obj->def->name, obj->def->uuid)))
C
Cédric Bosdonnat 已提交
1067
        return NULL;
1068

1069
    ev->actual = actual;
1070

1071
    return (virObjectEventPtr)ev;
1072 1073
}

1074 1075 1076 1077 1078
static virObjectEventPtr
virDomainEventDeviceRemovedNew(int id,
                               const char *name,
                               unsigned char *uuid,
                               const char *devAlias)
1079
{
1080
    virDomainEventDeviceRemovedPtr ev;
1081

1082
    if (virDomainEventsInitialize() < 0)
C
Cédric Bosdonnat 已提交
1083 1084
        return NULL;

1085
    if (!(ev = virDomainEventNew(virDomainEventDeviceRemovedClass,
1086 1087
                                 VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED,
                                 id, name, uuid)))
C
Cédric Bosdonnat 已提交
1088 1089
        return NULL;

1090
    if (VIR_STRDUP(ev->devAlias, devAlias) < 0)
C
Cédric Bosdonnat 已提交
1091
        goto error;
1092

1093
    return (virObjectEventPtr)ev;
1094 1095

error:
C
Cédric Bosdonnat 已提交
1096
    virObjectUnref(ev);
1097 1098 1099
    return NULL;
}

1100 1101 1102
virObjectEventPtr
virDomainEventDeviceRemovedNewFromObj(virDomainObjPtr obj,
                                      const char *devAlias)
1103 1104 1105 1106 1107
{
    return virDomainEventDeviceRemovedNew(obj->def->id, obj->def->name,
                                          obj->def->uuid, devAlias);
}

1108 1109 1110
virObjectEventPtr
virDomainEventDeviceRemovedNewFromDom(virDomainPtr dom,
                                      const char *devAlias)
1111 1112 1113 1114 1115
{
    return virDomainEventDeviceRemovedNew(dom->id, dom->name, dom->uuid,
                                          devAlias);
}

1116

1117
static void
1118
virDomainEventDispatchDefaultFunc(virConnectPtr conn,
1119
                                  virObjectEventPtr event,
1120 1121
                                  virConnectObjectEventGenericCallback cb,
                                  void *cbopaque)
1122
{
1123
    virDomainPtr dom = virGetDomain(conn, event->meta.name, event->meta.uuid);
1124 1125
    if (!dom)
        return;
1126
    dom->id = event->meta.id;
1127

1128
    switch ((virDomainEventID) event->eventID) {
1129
    case VIR_DOMAIN_EVENT_ID_LIFECYCLE:
1130 1131 1132 1133 1134 1135 1136 1137 1138 1139
        {
            virDomainEventLifecyclePtr lifecycleEvent;

            lifecycleEvent = (virDomainEventLifecyclePtr)event;
            ((virConnectDomainEventCallback)cb)(conn, dom,
                                                lifecycleEvent->type,
                                                lifecycleEvent->detail,
                                                cbopaque);
            goto cleanup;
        }
1140

1141 1142 1143
    case VIR_DOMAIN_EVENT_ID_REBOOT:
        (cb)(conn, dom,
             cbopaque);
1144
        goto cleanup;
1145

1146
    case VIR_DOMAIN_EVENT_ID_RTC_CHANGE:
1147 1148 1149 1150 1151 1152 1153 1154 1155
        {
            virDomainEventRTCChangePtr rtcChangeEvent;

            rtcChangeEvent = (virDomainEventRTCChangePtr)event;
            ((virConnectDomainEventRTCChangeCallback)cb)(conn, dom,
                                                         rtcChangeEvent->offset,
                                                         cbopaque);
            goto cleanup;
        }
1156

1157
    case VIR_DOMAIN_EVENT_ID_WATCHDOG:
1158 1159 1160 1161 1162 1163 1164 1165 1166
        {
            virDomainEventWatchdogPtr watchdogEvent;

            watchdogEvent = (virDomainEventWatchdogPtr)event;
            ((virConnectDomainEventWatchdogCallback)cb)(conn, dom,
                                                        watchdogEvent->action,
                                                        cbopaque);
            goto cleanup;
        }
1167

1168
    case VIR_DOMAIN_EVENT_ID_IO_ERROR:
1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179
        {
            virDomainEventIOErrorPtr ioErrorEvent;

            ioErrorEvent = (virDomainEventIOErrorPtr)event;
            ((virConnectDomainEventIOErrorCallback)cb)(conn, dom,
                                                       ioErrorEvent->srcPath,
                                                       ioErrorEvent->devAlias,
                                                       ioErrorEvent->action,
                                                       cbopaque);
            goto cleanup;
        }
1180

1181
    case VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON:
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
        {
            virDomainEventIOErrorPtr ioErrorEvent;

            ioErrorEvent = (virDomainEventIOErrorPtr)event;
            ((virConnectDomainEventIOErrorReasonCallback)cb)(conn, dom,
                                                             ioErrorEvent->srcPath,
                                                             ioErrorEvent->devAlias,
                                                             ioErrorEvent->action,
                                                             ioErrorEvent->reason,
                                                             cbopaque);
            goto cleanup;
        }
1194

1195
    case VIR_DOMAIN_EVENT_ID_GRAPHICS:
1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208
        {
            virDomainEventGraphicsPtr graphicsEvent;

            graphicsEvent = (virDomainEventGraphicsPtr)event;
            ((virConnectDomainEventGraphicsCallback)cb)(conn, dom,
                                                        graphicsEvent->phase,
                                                        graphicsEvent->local,
                                                        graphicsEvent->remote,
                                                        graphicsEvent->authScheme,
                                                        graphicsEvent->subject,
                                                        cbopaque);
            goto cleanup;
        }
1209

1210 1211 1212
    case VIR_DOMAIN_EVENT_ID_CONTROL_ERROR:
        (cb)(conn, dom,
             cbopaque);
1213
        goto cleanup;
1214

1215
    case VIR_DOMAIN_EVENT_ID_BLOCK_JOB:
1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226
        {
            virDomainEventBlockJobPtr blockJobEvent;

            blockJobEvent = (virDomainEventBlockJobPtr)event;
            ((virConnectDomainEventBlockJobCallback)cb)(conn, dom,
                                                        blockJobEvent->path,
                                                        blockJobEvent->type,
                                                        blockJobEvent->status,
                                                        cbopaque);
            goto cleanup;
        }
1227

1228
    case VIR_DOMAIN_EVENT_ID_DISK_CHANGE:
1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
        {
            virDomainEventDiskChangePtr diskChangeEvent;

            diskChangeEvent = (virDomainEventDiskChangePtr)event;
            ((virConnectDomainEventDiskChangeCallback)cb)(conn, dom,
                                                          diskChangeEvent->oldSrcPath,
                                                          diskChangeEvent->newSrcPath,
                                                          diskChangeEvent->devAlias,
                                                          diskChangeEvent->reason,
                                                          cbopaque);
            goto cleanup;
        }
1241

1242
    case VIR_DOMAIN_EVENT_ID_TRAY_CHANGE:
1243 1244 1245 1246 1247 1248 1249 1250 1251 1252
        {
            virDomainEventTrayChangePtr trayChangeEvent;

            trayChangeEvent = (virDomainEventTrayChangePtr)event;
            ((virConnectDomainEventTrayChangeCallback)cb)(conn, dom,
                                                          trayChangeEvent->devAlias,
                                                          trayChangeEvent->reason,
                                                          cbopaque);
            goto cleanup;
        }
1253

O
Osier Yang 已提交
1254
    case VIR_DOMAIN_EVENT_ID_PMWAKEUP:
E
Eric Blake 已提交
1255 1256 1257 1258 1259 1260 1261 1262
        {
            virDomainEventPMPtr pmEvent = (virDomainEventPMPtr)event;

            ((virConnectDomainEventPMWakeupCallback)cb)(conn, dom,
                                                        pmEvent->reason,
                                                        cbopaque);
            goto cleanup;
        }
O
Osier Yang 已提交
1263

O
Osier Yang 已提交
1264
    case VIR_DOMAIN_EVENT_ID_PMSUSPEND:
E
Eric Blake 已提交
1265 1266 1267 1268 1269 1270 1271 1272
        {
            virDomainEventPMPtr pmEvent = (virDomainEventPMPtr)event;

            ((virConnectDomainEventPMSuspendCallback)cb)(conn, dom,
                                                         pmEvent->reason,
                                                         cbopaque);
            goto cleanup;
        }
O
Osier Yang 已提交
1273

1274
    case VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE:
1275 1276 1277 1278 1279 1280 1281 1282 1283
        {
            virDomainEventBalloonChangePtr balloonChangeEvent;

            balloonChangeEvent = (virDomainEventBalloonChangePtr)event;
            ((virConnectDomainEventBalloonChangeCallback)cb)(conn, dom,
                                                             balloonChangeEvent->actual,
                                                             cbopaque);
            goto cleanup;
        }
1284

1285
    case VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK:
E
Eric Blake 已提交
1286 1287 1288 1289 1290 1291 1292 1293
        {
            virDomainEventPMPtr pmEvent = (virDomainEventPMPtr)event;

            ((virConnectDomainEventPMSuspendDiskCallback)cb)(conn, dom,
                                                             pmEvent->reason,
                                                             cbopaque);
            goto cleanup;
        }
1294

1295
    case VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED:
1296 1297 1298 1299 1300 1301 1302 1303 1304
        {
            virDomainEventDeviceRemovedPtr deviceRemovedEvent;

            deviceRemovedEvent = (virDomainEventDeviceRemovedPtr)event;
            ((virConnectDomainEventDeviceRemovedCallback)cb)(conn, dom,
                                                             deviceRemovedEvent->devAlias,
                                                             cbopaque);
            goto cleanup;
        }
1305 1306

    case VIR_DOMAIN_EVENT_ID_LAST:
1307
        break;
1308
    }
1309

1310
    VIR_WARN("Unexpected event ID %d", event->eventID);
1311 1312

cleanup:
1313
    virDomainFree(dom);
1314 1315 1316
}


1317
/**
1318 1319
 * virDomainEventStateRegister:
 * @conn: connection to associate with callback
1320
 * @state: object event state
1321 1322
 * @callback: the callback to add
 * @opaque: data blob to pass to @callback
1323 1324 1325 1326 1327 1328 1329
 * @freecb: callback to free @opaque
 *
 * Register the function @callback with connection @conn,
 * from @state, for lifecycle events.
 *
 * Returns: the number of lifecycle callbacks now registered, or -1 on error
 */
1330 1331
int
virDomainEventStateRegister(virConnectPtr conn,
1332
                            virObjectEventStatePtr state,
1333 1334 1335
                            virConnectDomainEventCallback callback,
                            void *opaque,
                            virFreeCallback freecb)
1336
{
1337 1338
    int callbackID;

1339 1340 1341
    if (virDomainEventsInitialize() < 0)
        return -1;

1342
    return virObjectEventStateRegisterID(conn, state, NULL,
1343
                                         NULL, NULL, virDomainEventClass,
1344 1345
                                         VIR_DOMAIN_EVENT_ID_LIFECYCLE,
                                         VIR_OBJECT_EVENT_CALLBACK(callback),
1346 1347
                                         opaque, freecb,
                                         true, &callbackID, false);
1348 1349 1350 1351 1352 1353
}


/**
 * virDomainEventStateRegisterID:
 * @conn: connection to associate with callback
1354
 * @state: object event state
1355
 * @dom: optional domain for filtering the event
1356
 * @eventID: ID of the event type to register for
1357 1358
 * @cb: function to invoke when event fires
 * @opaque: data blob to pass to @callback
1359 1360 1361
 * @freecb: callback to free @opaque
 * @callbackID: filled with callback ID
 *
1362 1363 1364
 * Register the function @cb with connection @conn, from @state, for
 * events of type @eventID, and return the registration handle in
 * @callbackID.
1365 1366 1367
 *
 * Returns: the number of callbacks now registered, or -1 on error
 */
1368 1369
int
virDomainEventStateRegisterID(virConnectPtr conn,
1370
                              virObjectEventStatePtr state,
1371 1372 1373 1374 1375 1376
                              virDomainPtr dom,
                              int eventID,
                              virConnectDomainEventGenericCallback cb,
                              void *opaque,
                              virFreeCallback freecb,
                              int *callbackID)
1377
{
1378 1379 1380
    if (virDomainEventsInitialize() < 0)
        return -1;

1381
    return virObjectEventStateRegisterID(conn, state, dom ? dom->uuid : NULL,
1382 1383
                                         NULL, NULL,
                                         virDomainEventClass, eventID,
1384
                                         VIR_OBJECT_EVENT_CALLBACK(cb),
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453
                                         opaque, freecb,
                                         false, callbackID, false);
}


/**
 * virDomainEventStateRegisterClient:
 * @conn: connection to associate with callback
 * @state: object event state
 * @dom: optional domain for filtering the event
 * @eventID: ID of the event type to register for
 * @cb: function to invoke when event fires
 * @opaque: data blob to pass to @callback
 * @freecb: callback to free @opaque
 * @legacy: true if callback is tracked by function instead of callbackID
 * @callbackID: filled with callback ID
 * @remoteID: true if server supports filtering
 *
 * Register the function @cb with connection @conn, from @state, for
 * events of type @eventID, and return the registration handle in
 * @callbackID.  This version is intended for use on the client side
 * of RPC.
 *
 * Returns: the number of callbacks now registered, or -1 on error
 */
int
virDomainEventStateRegisterClient(virConnectPtr conn,
                                  virObjectEventStatePtr state,
                                  virDomainPtr dom,
                                  int eventID,
                                  virConnectDomainEventGenericCallback cb,
                                  void *opaque,
                                  virFreeCallback freecb,
                                  bool legacy,
                                  int *callbackID,
                                  bool remoteID)
{
    if (virDomainEventsInitialize() < 0)
        return -1;

    return virObjectEventStateRegisterID(conn, state, dom ? dom->uuid : NULL,
                                         NULL, NULL,
                                         virDomainEventClass, eventID,
                                         VIR_OBJECT_EVENT_CALLBACK(cb),
                                         opaque, freecb,
                                         legacy, callbackID, remoteID);
}


/**
 * virDomainEventStateCallbackID:
 * @conn: connection associated with callback
 * @state: object event state
 * @cb: function registered as a callback with virDomainEventStateRegister()
 * @remoteID: associated remote id of the callback
 *
 * Returns the callbackID of @cb, or -1 with an error issued if the
 * function is not currently registered.
 */
int
virDomainEventStateCallbackID(virConnectPtr conn,
                              virObjectEventStatePtr state,
                              virConnectDomainEventCallback cb,
                              int *remoteID)
{
    return virObjectEventStateCallbackID(conn, state, virDomainEventClass,
                                         VIR_DOMAIN_EVENT_ID_LIFECYCLE,
                                         VIR_OBJECT_EVENT_CALLBACK(cb),
                                         remoteID);
1454 1455 1456 1457 1458
}


/**
 * virDomainEventStateDeregister:
1459
 * @conn: connection to associate with callback
1460
 * @state: object event state
1461
 * @cb: function to remove from event
1462
 *
1463 1464
 * Unregister the function @cb with connection @conn, from @state, for
 * lifecycle events.
1465 1466 1467
 *
 * Returns: the number of lifecycle callbacks still registered, or -1 on error
 */
1468 1469
int
virDomainEventStateDeregister(virConnectPtr conn,
1470
                              virObjectEventStatePtr state,
1471
                              virConnectDomainEventCallback cb)
1472
{
1473
    int callbackID;
1474

1475 1476 1477
    callbackID = virObjectEventStateCallbackID(conn, state,
                                               virDomainEventClass,
                                               VIR_DOMAIN_EVENT_ID_LIFECYCLE,
1478 1479
                                               VIR_OBJECT_EVENT_CALLBACK(cb),
                                               NULL);
1480 1481 1482
    if (callbackID < 0)
        return -1;
    return virObjectEventStateDeregisterID(conn, state, callbackID);
1483
}