1 /*
2 * storage_event.c: storage 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 "storage_event.h"
26 #include "object_event.h"
27 #include "object_event_private.h"
28 #include "datatypes.h"
29 #include "virlog.h"
30
31 VIR_LOG_INIT("conf.storage_event");
32
33 struct _virStoragePoolEvent {
34 virObjectEvent parent;
35
36 /* Unused attribute to allow for subclass creation */
37 bool dummy;
38 };
39 typedef struct _virStoragePoolEvent virStoragePoolEvent;
40
41 struct _virStoragePoolEventLifecycle {
42 virStoragePoolEvent parent;
43
44 int type;
45 int detail;
46 };
47 typedef struct _virStoragePoolEventLifecycle virStoragePoolEventLifecycle;
48
49 struct _virStoragePoolEventRefresh {
50 virStoragePoolEvent parent;
51
52 bool dummy;
53 };
54 typedef struct _virStoragePoolEventRefresh virStoragePoolEventRefresh;
55
56 static virClass *virStoragePoolEventClass;
57 static virClass *virStoragePoolEventLifecycleClass;
58 static virClass *virStoragePoolEventRefreshClass;
59 static void virStoragePoolEventDispose(void *obj);
60 static void virStoragePoolEventLifecycleDispose(void *obj);
61 static void virStoragePoolEventRefreshDispose(void *obj);
62
63 static int
virStoragePoolEventsOnceInit(void)64 virStoragePoolEventsOnceInit(void)
65 {
66 if (!VIR_CLASS_NEW(virStoragePoolEvent, virClassForObjectEvent()))
67 return -1;
68
69 if (!VIR_CLASS_NEW(virStoragePoolEventLifecycle, virStoragePoolEventClass))
70 return -1;
71
72 if (!VIR_CLASS_NEW(virStoragePoolEventRefresh, virStoragePoolEventClass))
73 return -1;
74
75 return 0;
76 }
77
78 VIR_ONCE_GLOBAL_INIT(virStoragePoolEvents);
79
80 static void
virStoragePoolEventDispose(void * obj)81 virStoragePoolEventDispose(void *obj)
82 {
83 virStoragePoolEvent *event = obj;
84 VIR_DEBUG("obj=%p", event);
85 }
86
87
88 static void
virStoragePoolEventLifecycleDispose(void * obj)89 virStoragePoolEventLifecycleDispose(void *obj)
90 {
91 virStoragePoolEventLifecycle *event = obj;
92 VIR_DEBUG("obj=%p", event);
93 }
94
95
96 static void
virStoragePoolEventRefreshDispose(void * obj)97 virStoragePoolEventRefreshDispose(void *obj)
98 {
99 virStoragePoolEventRefresh *event = obj;
100 VIR_DEBUG("obj=%p", event);
101 }
102
103
104 static void
virStoragePoolEventDispatchDefaultFunc(virConnectPtr conn,virObjectEvent * event,virConnectObjectEventGenericCallback cb,void * cbopaque)105 virStoragePoolEventDispatchDefaultFunc(virConnectPtr conn,
106 virObjectEvent *event,
107 virConnectObjectEventGenericCallback cb,
108 void *cbopaque)
109 {
110 virStoragePoolPtr pool = virGetStoragePool(conn,
111 event->meta.name,
112 event->meta.uuid,
113 NULL, NULL);
114 if (!pool)
115 return;
116
117 switch ((virStoragePoolEventID)event->eventID) {
118 case VIR_STORAGE_POOL_EVENT_ID_LIFECYCLE:
119 {
120 virStoragePoolEventLifecycle *storagePoolLifecycleEvent;
121
122 storagePoolLifecycleEvent = (virStoragePoolEventLifecycle *)event;
123 ((virConnectStoragePoolEventLifecycleCallback)cb)(conn, pool,
124 storagePoolLifecycleEvent->type,
125 storagePoolLifecycleEvent->detail,
126 cbopaque);
127 goto cleanup;
128 }
129
130 case VIR_STORAGE_POOL_EVENT_ID_REFRESH:
131 {
132 ((virConnectStoragePoolEventGenericCallback)cb)(conn, pool,
133 cbopaque);
134 goto cleanup;
135 }
136
137 case VIR_STORAGE_POOL_EVENT_ID_LAST:
138 break;
139 }
140 VIR_WARN("Unexpected event ID %d", event->eventID);
141
142 cleanup:
143 virObjectUnref(pool);
144 }
145
146
147 /**
148 * virStoragePoolEventStateRegisterID:
149 * @conn: connection to associate with callback
150 * @state: object event state
151 * @pool: storage pool to filter on or NULL for all storage pools
152 * @eventID: ID of the event type to register for
153 * @cb: function to invoke when event occurs
154 * @opaque: data blob to pass to @callback
155 * @freecb: callback to free @opaque
156 * @callbackID: filled with callback ID
157 *
158 * Register the function @cb with connection @conn, from @state, for
159 * events of type @eventID, and return the registration handle in
160 * @callbackID.
161 *
162 * Returns: the number of callbacks now registered, or -1 on error
163 */
164 int
virStoragePoolEventStateRegisterID(virConnectPtr conn,virObjectEventState * state,virStoragePoolPtr pool,int eventID,virConnectStoragePoolEventGenericCallback cb,void * opaque,virFreeCallback freecb,int * callbackID)165 virStoragePoolEventStateRegisterID(virConnectPtr conn,
166 virObjectEventState *state,
167 virStoragePoolPtr pool,
168 int eventID,
169 virConnectStoragePoolEventGenericCallback cb,
170 void *opaque,
171 virFreeCallback freecb,
172 int *callbackID)
173 {
174 char uuidstr[VIR_UUID_STRING_BUFLEN];
175
176 if (virStoragePoolEventsInitialize() < 0)
177 return -1;
178
179 if (pool)
180 virUUIDFormat(pool->uuid, uuidstr);
181 return virObjectEventStateRegisterID(conn, state, pool ? uuidstr : NULL,
182 NULL, NULL,
183 virStoragePoolEventClass, eventID,
184 VIR_OBJECT_EVENT_CALLBACK(cb),
185 opaque, freecb,
186 false, callbackID, false);
187 }
188
189
190 /**
191 * virStoragePoolEventStateRegisterClient:
192 * @conn: connection to associate with callback
193 * @state: object event state
194 * @pool: storage pool to filter on or NULL for all storage pools
195 * @eventID: ID of the event type to register for
196 * @cb: function to invoke when event occurs
197 * @opaque: data blob to pass to @callback
198 * @freecb: callback to free @opaque
199 * @callbackID: filled with callback ID
200 *
201 * Register the function @cb with connection @conn, from @state, for
202 * events of type @eventID, and return the registration handle in
203 * @callbackID. This version is intended for use on the client side
204 * of RPC.
205 *
206 * Returns: the number of callbacks now registered, or -1 on error
207 */
208 int
virStoragePoolEventStateRegisterClient(virConnectPtr conn,virObjectEventState * state,virStoragePoolPtr pool,int eventID,virConnectStoragePoolEventGenericCallback cb,void * opaque,virFreeCallback freecb,int * callbackID)209 virStoragePoolEventStateRegisterClient(virConnectPtr conn,
210 virObjectEventState *state,
211 virStoragePoolPtr pool,
212 int eventID,
213 virConnectStoragePoolEventGenericCallback cb,
214 void *opaque,
215 virFreeCallback freecb,
216 int *callbackID)
217 {
218 char uuidstr[VIR_UUID_STRING_BUFLEN];
219
220 if (virStoragePoolEventsInitialize() < 0)
221 return -1;
222
223 if (pool)
224 virUUIDFormat(pool->uuid, uuidstr);
225 return virObjectEventStateRegisterID(conn, state, pool ? uuidstr : NULL,
226 NULL, NULL,
227 virStoragePoolEventClass, eventID,
228 VIR_OBJECT_EVENT_CALLBACK(cb),
229 opaque, freecb,
230 false, callbackID, true);
231 }
232
233
234 /**
235 * virStoragePoolEventLifecycleNew:
236 * @name: name of the storage pool object the event describes
237 * @uuid: uuid of the storage pool object the event describes
238 * @type: type of lifecycle event
239 * @detail: more details about @type
240 *
241 * Create a new storage pool lifecycle event.
242 */
243 virObjectEvent *
virStoragePoolEventLifecycleNew(const char * name,const unsigned char * uuid,int type,int detail)244 virStoragePoolEventLifecycleNew(const char *name,
245 const unsigned char *uuid,
246 int type,
247 int detail)
248 {
249 virStoragePoolEventLifecycle *event;
250 char uuidstr[VIR_UUID_STRING_BUFLEN];
251
252 if (virStoragePoolEventsInitialize() < 0)
253 return NULL;
254
255 virUUIDFormat(uuid, uuidstr);
256 if (!(event = virObjectEventNew(virStoragePoolEventLifecycleClass,
257 virStoragePoolEventDispatchDefaultFunc,
258 VIR_STORAGE_POOL_EVENT_ID_LIFECYCLE,
259 0, name, uuid, uuidstr)))
260 return NULL;
261
262 event->type = type;
263 event->detail = detail;
264
265 return (virObjectEvent *)event;
266 }
267
268
269 /**
270 * virStoragePoolEventRefreshNew:
271 * @name: name of the storage pool object the event describes
272 * @uuid: uuid of the storage pool object the event describes
273 *
274 * Create a new storage pool refresh event.
275 */
276 virObjectEvent *
virStoragePoolEventRefreshNew(const char * name,const unsigned char * uuid)277 virStoragePoolEventRefreshNew(const char *name,
278 const unsigned char *uuid)
279 {
280 virStoragePoolEventRefresh *event;
281 char uuidstr[VIR_UUID_STRING_BUFLEN];
282
283 if (virStoragePoolEventsInitialize() < 0)
284 return NULL;
285
286 virUUIDFormat(uuid, uuidstr);
287 if (!(event = virObjectEventNew(virStoragePoolEventRefreshClass,
288 virStoragePoolEventDispatchDefaultFunc,
289 VIR_STORAGE_POOL_EVENT_ID_REFRESH,
290 0, name, uuid, uuidstr)))
291 return NULL;
292
293 return (virObjectEvent *)event;
294 }
295