network_event.c 7.5 KB
Newer Older
1 2 3
/*
 * network_event.c: network event queue processing helpers
 *
4
 * Copyright (C) 2014 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
 * Copyright (C) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * Author: Cedric Bosdonnat
 */

#include <config.h>

#include "network_event.h"
#include "object_event.h"
#include "object_event_private.h"
#include "datatypes.h"
#include "virlog.h"

32
struct _virNetworkEvent {
33 34
    virObjectEvent parent;

35
    /* Unused attribute to allow for subclass creation */
36 37 38 39 40 41 42 43
    bool dummy;
};
typedef struct _virNetworkEvent virNetworkEvent;
typedef virNetworkEvent *virNetworkEventPtr;

struct _virNetworkEventLifecycle {
    virNetworkEvent parent;

44
    int type;
45
    int detail;
46 47 48 49
};
typedef struct _virNetworkEventLifecycle virNetworkEventLifecycle;
typedef virNetworkEventLifecycle *virNetworkEventLifecyclePtr;

50
static virClassPtr virNetworkEventClass;
51
static virClassPtr virNetworkEventLifecycleClass;
52
static void virNetworkEventDispose(void *obj);
53 54 55 56 57
static void virNetworkEventLifecycleDispose(void *obj);

static int
virNetworkEventsOnceInit(void)
{
58
    if (!(virNetworkEventClass =
59
          virClassNew(virClassForObjectEvent(),
60 61 62 63 64 65
                      "virNetworkEvent",
                      sizeof(virNetworkEvent),
                      virNetworkEventDispose)))
        return -1;
    if (!(virNetworkEventLifecycleClass =
          virClassNew(virNetworkEventClass,
66 67 68 69 70 71 72 73 74
                      "virNetworkEventLifecycle",
                      sizeof(virNetworkEventLifecycle),
                      virNetworkEventLifecycleDispose)))
        return -1;
    return 0;
}

VIR_ONCE_GLOBAL_INIT(virNetworkEvents)

75
static void
76 77 78 79 80 81 82
virNetworkEventDispose(void *obj)
{
    virNetworkEventPtr event = obj;
    VIR_DEBUG("obj=%p", event);
}


83
static void
84 85 86 87 88 89 90
virNetworkEventLifecycleDispose(void *obj)
{
    virNetworkEventLifecyclePtr event = obj;
    VIR_DEBUG("obj=%p", event);
}


91
static void
92 93
virNetworkEventDispatchDefaultFunc(virConnectPtr conn,
                                   virObjectEventPtr event,
94 95
                                   virConnectObjectEventGenericCallback cb,
                                   void *cbopaque)
96 97 98 99 100
{
    virNetworkPtr net = virGetNetwork(conn, event->meta.name, event->meta.uuid);
    if (!net)
        return;

101
    switch ((virNetworkEventID)event->eventID) {
102 103 104 105 106 107 108
    case VIR_NETWORK_EVENT_ID_LIFECYCLE:
        {
            virNetworkEventLifecyclePtr networkLifecycleEvent;

            networkLifecycleEvent = (virNetworkEventLifecyclePtr)event;
            ((virConnectNetworkEventLifecycleCallback)cb)(conn, net,
                                                          networkLifecycleEvent->type,
109
                                                          networkLifecycleEvent->detail,
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
                                                          cbopaque);
            goto cleanup;
        }

    case VIR_NETWORK_EVENT_ID_LAST:
        break;
    }
    VIR_WARN("Unexpected event ID %d", event->eventID);

cleanup:
    virNetworkFree(net);
}


/**
 * virNetworkEventStateRegisterID:
 * @conn: connection to associate with callback
 * @state: object event state
 * @net: network to filter on or NULL for all networks
 * @eventID: ID of the event type to register for
130 131
 * @cb: function to invoke when event occurs
 * @opaque: data blob to pass to @callback
132 133 134
 * @freecb: callback to free @opaque
 * @callbackID: filled with callback ID
 *
135 136 137
 * Register the function @cb with connection @conn, from @state, for
 * events of type @eventID, and return the registration handle in
 * @callbackID.
138 139 140 141 142 143 144 145
 *
 * Returns: the number of callbacks now registered, or -1 on error
 */
int
virNetworkEventStateRegisterID(virConnectPtr conn,
                               virObjectEventStatePtr state,
                               virNetworkPtr net,
                               int eventID,
146
                               virConnectNetworkEventGenericCallback cb,
147 148 149 150
                               void *opaque,
                               virFreeCallback freecb,
                               int *callbackID)
{
151 152 153
    if (virNetworkEventsInitialize() < 0)
        return -1;

154 155
    return virObjectEventStateRegisterID(conn, state, net ? net->uuid : NULL,
                                         virNetworkEventClass, eventID,
156
                                         VIR_OBJECT_EVENT_CALLBACK(cb),
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
                                         opaque, freecb, callbackID, false);
}


/**
 * virNetworkEventStateRegisterClient:
 * @conn: connection to associate with callback
 * @state: object event state
 * @net: network to filter on or NULL for all networks
 * @eventID: ID of the event type to register for
 * @cb: function to invoke when event occurs
 * @opaque: data blob to pass to @callback
 * @freecb: callback to free @opaque
 * @callbackID: filled with callback ID
 *
 * Register the function @cb with connection @conn, from @state, for
 * events of type @eventID, and return the registration handle in
 * @callbackID.  This version is intended for use on the client side
 * of RPC.
 *
 * Returns: the number of callbacks now registered, or -1 on error
 */
int
virNetworkEventStateRegisterClient(virConnectPtr conn,
                                   virObjectEventStatePtr state,
                                   virNetworkPtr net,
                                   int eventID,
                                   virConnectNetworkEventGenericCallback cb,
                                   void *opaque,
                                   virFreeCallback freecb,
                                   int *callbackID)
{
    if (virNetworkEventsInitialize() < 0)
        return -1;

    /* FIXME: All servers that support network events should also support
     * per-object filtering.  */
    return virObjectEventStateRegisterID(conn, state, net ? net->uuid : NULL,
                                         virNetworkEventClass, eventID,
                                         VIR_OBJECT_EVENT_CALLBACK(cb),
                                         opaque, freecb, callbackID, false);
198 199
}

200 201 202 203 204 205 206 207 208 209

/**
 * virNetworkEventLifecycleNew:
 * @name: name of the network object the event describes
 * @uuid: uuid of the network object the event describes
 * @type: type of lifecycle event
 * @detail: more details about @type
 *
 * Create a new network lifecycle event.
 */
210 211 212
virObjectEventPtr
virNetworkEventLifecycleNew(const char *name,
                            const unsigned char *uuid,
213 214
                            int type,
                            int detail)
215 216 217 218 219 220 221
{
    virNetworkEventLifecyclePtr event;

    if (virNetworkEventsInitialize() < 0)
        return NULL;

    if (!(event = virObjectEventNew(virNetworkEventLifecycleClass,
222
                                    virNetworkEventDispatchDefaultFunc,
223
                                    VIR_NETWORK_EVENT_ID_LIFECYCLE,
224 225 226 227
                                    0, name, uuid)))
        return NULL;

    event->type = type;
228
    event->detail = detail;
229 230 231

    return (virObjectEventPtr)event;
}