1 /*
2  * datatypes.c: management of structs for public data types
3  *
4  * Copyright (C) 2006-2019 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library.  If not, see
18  * <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #include <config.h>
23 #include <unistd.h>
24 
25 #include "datatypes.h"
26 #include "virerror.h"
27 #include "virlog.h"
28 #include "viralloc.h"
29 #include "viruuid.h"
30 #include "virstring.h"
31 
32 #define VIR_FROM_THIS VIR_FROM_NONE
33 
34 VIR_LOG_INIT("datatypes");
35 
36 virClass *virConnectClass;
37 virClass *virConnectCloseCallbackDataClass;
38 virClass *virDomainClass;
39 virClass *virDomainCheckpointClass;
40 virClass *virDomainSnapshotClass;
41 virClass *virInterfaceClass;
42 virClass *virNetworkClass;
43 virClass *virNetworkPortClass;
44 virClass *virNodeDeviceClass;
45 virClass *virNWFilterClass;
46 virClass *virNWFilterBindingClass;
47 virClass *virSecretClass;
48 virClass *virStreamClass;
49 virClass *virStorageVolClass;
50 virClass *virStoragePoolClass;
51 
52 static void virConnectDispose(void *obj);
53 static void virConnectCloseCallbackDataDispose(void *obj);
54 static void virDomainDispose(void *obj);
55 static void virDomainCheckpointDispose(void *obj);
56 static void virDomainSnapshotDispose(void *obj);
57 static void virInterfaceDispose(void *obj);
58 static void virNetworkDispose(void *obj);
59 static void virNetworkPortDispose(void *obj);
60 static void virNodeDeviceDispose(void *obj);
61 static void virNWFilterDispose(void *obj);
62 static void virNWFilterBindingDispose(void *obj);
63 static void virSecretDispose(void *obj);
64 static void virStreamDispose(void *obj);
65 static void virStorageVolDispose(void *obj);
66 static void virStoragePoolDispose(void *obj);
67 
68 virClass *virAdmConnectClass;
69 virClass *virAdmConnectCloseCallbackDataClass;
70 
71 static void virAdmConnectDispose(void *obj);
72 static void virAdmConnectCloseCallbackDataDispose(void *obj);
73 
74 virClass *virAdmServerClass;
75 virClass *virAdmClientClass;
76 static void virAdmServerDispose(void *obj);
77 static void virAdmClientDispose(void *obj);
78 
79 static __thread bool connectDisposed;
80 static __thread bool admConnectDisposed;
81 
82 static int
virDataTypesOnceInit(void)83 virDataTypesOnceInit(void)
84 {
85 #define DECLARE_CLASS_COMMON(basename, parent) \
86     if (!(VIR_CLASS_NEW(basename, parent))) \
87         return -1;
88 #define DECLARE_CLASS(basename) \
89     DECLARE_CLASS_COMMON(basename, virClassForObject())
90 #define DECLARE_CLASS_LOCKABLE(basename) \
91     DECLARE_CLASS_COMMON(basename, virClassForObjectLockable())
92 
93     DECLARE_CLASS_LOCKABLE(virConnect);
94     DECLARE_CLASS_LOCKABLE(virConnectCloseCallbackData);
95     DECLARE_CLASS(virDomain);
96     DECLARE_CLASS(virDomainCheckpoint);
97     DECLARE_CLASS(virDomainSnapshot);
98     DECLARE_CLASS(virInterface);
99     DECLARE_CLASS(virNetwork);
100     DECLARE_CLASS(virNetworkPort);
101     DECLARE_CLASS(virNodeDevice);
102     DECLARE_CLASS(virNWFilter);
103     DECLARE_CLASS(virNWFilterBinding);
104     DECLARE_CLASS(virSecret);
105     DECLARE_CLASS(virStream);
106     DECLARE_CLASS(virStorageVol);
107     DECLARE_CLASS(virStoragePool);
108 
109     DECLARE_CLASS_LOCKABLE(virAdmConnect);
110     DECLARE_CLASS_LOCKABLE(virAdmConnectCloseCallbackData);
111     DECLARE_CLASS(virAdmServer);
112     DECLARE_CLASS(virAdmClient);
113 
114 #undef DECLARE_CLASS_COMMON
115 #undef DECLARE_CLASS_LOCKABLE
116 #undef DECLARE_CLASS
117 
118     return 0;
119 }
120 
121 VIR_ONCE_GLOBAL_INIT(virDataTypes);
122 
123 /**
124  * virGetConnect:
125  *
126  * Allocates a new hypervisor connection object.
127  *
128  * Returns a pointer to the connection object, or NULL on error.
129  */
130 virConnectPtr
virGetConnect(void)131 virGetConnect(void)
132 {
133     if (virDataTypesInitialize() < 0)
134         return NULL;
135 
136     return virObjectLockableNew(virConnectClass);
137 }
138 
139 
virConnectWatchDispose(void)140 void virConnectWatchDispose(void)
141 {
142     connectDisposed = false;
143 }
144 
virConnectWasDisposed(void)145 bool virConnectWasDisposed(void)
146 {
147     return connectDisposed;
148 }
149 
virAdmConnectWatchDispose(void)150 void virAdmConnectWatchDispose(void)
151 {
152     admConnectDisposed = false;
153 }
154 
virAdmConnectWasDisposed(void)155 bool virAdmConnectWasDisposed(void)
156 {
157     return admConnectDisposed;
158 }
159 
160 /**
161  * virConnectDispose:
162  * @obj: the hypervisor connection to release
163  *
164  * Unconditionally release all memory associated with a connection.
165  * The connection object must not be used once this method returns.
166  */
167 static void
virConnectDispose(void * obj)168 virConnectDispose(void *obj)
169 {
170     virConnectPtr conn = obj;
171 
172     connectDisposed = true;
173     if (conn->driver)
174         conn->driver->connectClose(conn);
175 
176     virResetError(&conn->err);
177 
178     virURIFree(conn->uri);
179 }
180 
181 
182 static void
virConnectCloseCallbackDataReset(virConnectCloseCallbackData * closeData)183 virConnectCloseCallbackDataReset(virConnectCloseCallbackData *closeData)
184 {
185     if (closeData->freeCallback)
186         closeData->freeCallback(closeData->opaque);
187 
188     closeData->freeCallback = NULL;
189     closeData->opaque = NULL;
190     virObjectUnref(closeData->conn);
191     closeData->conn = NULL;
192 }
193 
194 /**
195  * virConnectCloseCallbackDataDispose:
196  * @obj: the close callback data to release
197  *
198  * Release resources bound to the connection close callback.
199  */
200 static void
virConnectCloseCallbackDataDispose(void * obj)201 virConnectCloseCallbackDataDispose(void *obj)
202 {
203     virConnectCloseCallbackDataReset(obj);
204 }
205 
206 virConnectCloseCallbackData *
virNewConnectCloseCallbackData(void)207 virNewConnectCloseCallbackData(void)
208 {
209     if (virDataTypesInitialize() < 0)
210         return NULL;
211 
212     return virObjectLockableNew(virConnectCloseCallbackDataClass);
213 }
214 
virConnectCloseCallbackDataRegister(virConnectCloseCallbackData * closeData,virConnectPtr conn,virConnectCloseFunc cb,void * opaque,virFreeCallback freecb)215 void virConnectCloseCallbackDataRegister(virConnectCloseCallbackData *closeData,
216                                          virConnectPtr conn,
217                                          virConnectCloseFunc cb,
218                                          void *opaque,
219                                          virFreeCallback freecb)
220 {
221     virObjectLock(closeData);
222 
223     if (closeData->callback != NULL) {
224         VIR_WARN("Attempt to register callback on armed"
225                  " close callback object %p", closeData);
226         goto cleanup;
227     }
228 
229     closeData->conn = virObjectRef(conn);
230     closeData->callback = cb;
231     closeData->opaque = opaque;
232     closeData->freeCallback = freecb;
233 
234  cleanup:
235 
236     virObjectUnlock(closeData);
237 }
238 
virConnectCloseCallbackDataUnregister(virConnectCloseCallbackData * closeData,virConnectCloseFunc cb)239 void virConnectCloseCallbackDataUnregister(virConnectCloseCallbackData *closeData,
240                                            virConnectCloseFunc cb)
241 {
242     virObjectLock(closeData);
243 
244     if (closeData->callback != cb) {
245         VIR_WARN("Attempt to unregister different callback on "
246                  " close callback object %p", closeData);
247         goto cleanup;
248     }
249 
250     virConnectCloseCallbackDataReset(closeData);
251     closeData->callback = NULL;
252 
253  cleanup:
254 
255     virObjectUnlock(closeData);
256 }
257 
virConnectCloseCallbackDataCall(virConnectCloseCallbackData * closeData,int reason)258 void virConnectCloseCallbackDataCall(virConnectCloseCallbackData *closeData,
259                                      int reason)
260 {
261     virObjectLock(closeData);
262 
263     if (!closeData->conn)
264         goto exit;
265 
266     VIR_DEBUG("Triggering connection close callback %p reason=%d, opaque=%p",
267               closeData->callback, reason, closeData->opaque);
268     closeData->callback(closeData->conn, reason, closeData->opaque);
269 
270     virConnectCloseCallbackDataReset(closeData);
271 
272  exit:
273     virObjectUnlock(closeData);
274 }
275 
276 virConnectCloseFunc
virConnectCloseCallbackDataGetCallback(virConnectCloseCallbackData * closeData)277 virConnectCloseCallbackDataGetCallback(virConnectCloseCallbackData *closeData)
278 {
279     virConnectCloseFunc cb;
280 
281     virObjectLock(closeData);
282     cb = closeData->callback;
283     virObjectUnlock(closeData);
284 
285     return cb;
286 }
287 
288 /**
289  * virGetDomain:
290  * @conn: the hypervisor connection
291  * @name: pointer to the domain name
292  * @uuid: pointer to the uuid
293  * @id: domain ID
294  *
295  * Allocates a new domain object. When the object is no longer needed,
296  * virObjectUnref() must be called in order to not leak data.
297  *
298  * Returns a pointer to the domain object, or NULL on error.
299  */
300 virDomainPtr
virGetDomain(virConnectPtr conn,const char * name,const unsigned char * uuid,int id)301 virGetDomain(virConnectPtr conn,
302              const char *name,
303              const unsigned char *uuid,
304              int id)
305 {
306     virDomainPtr ret = NULL;
307 
308     if (virDataTypesInitialize() < 0)
309         return NULL;
310 
311     virCheckConnectGoto(conn, error);
312     virCheckNonNullArgGoto(name, error);
313     virCheckNonNullArgGoto(uuid, error);
314 
315     if (!(ret = virObjectNew(virDomainClass)))
316         goto error;
317 
318     ret->name = g_strdup(name);
319 
320     ret->conn = virObjectRef(conn);
321     ret->id = id;
322     memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
323 
324     return ret;
325 
326  error:
327     virObjectUnref(ret);
328     return NULL;
329 }
330 
331 /**
332  * virDomainDispose:
333  * @obj: the domain to release
334  *
335  * Unconditionally release all memory associated with a domain.
336  * The domain object must not be used once this method returns.
337  *
338  * It will also unreference the associated connection object,
339  * which may also be released if its ref count hits zero.
340  */
341 static void
virDomainDispose(void * obj)342 virDomainDispose(void *obj)
343 {
344     virDomainPtr domain = obj;
345     char uuidstr[VIR_UUID_STRING_BUFLEN];
346 
347     virUUIDFormat(domain->uuid, uuidstr);
348     VIR_DEBUG("release domain %p %s %s", domain, domain->name, uuidstr);
349 
350     g_free(domain->name);
351     virObjectUnref(domain->conn);
352 }
353 
354 
355 /**
356  * virGetNetwork:
357  * @conn: the hypervisor connection
358  * @name: pointer to the network name
359  * @uuid: pointer to the uuid
360  *
361  * Allocates a new network object. When the object is no longer needed,
362  * virObjectUnref() must be called in order to not leak data.
363  *
364  * Returns a pointer to the network object, or NULL on error.
365  */
366 virNetworkPtr
virGetNetwork(virConnectPtr conn,const char * name,const unsigned char * uuid)367 virGetNetwork(virConnectPtr conn, const char *name, const unsigned char *uuid)
368 {
369     virNetworkPtr ret = NULL;
370 
371     if (virDataTypesInitialize() < 0)
372         return NULL;
373 
374     virCheckConnectGoto(conn, error);
375     virCheckNonNullArgGoto(name, error);
376     virCheckNonNullArgGoto(uuid, error);
377 
378     if (!(ret = virObjectNew(virNetworkClass)))
379         goto error;
380 
381     ret->name = g_strdup(name);
382 
383     ret->conn = virObjectRef(conn);
384     memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
385 
386     return ret;
387 
388  error:
389     virObjectUnref(ret);
390     return NULL;
391 }
392 
393 /**
394  * virNetworkDispose:
395  * @obj: the network to release
396  *
397  * Unconditionally release all memory associated with a network.
398  * The network object must not be used once this method returns.
399  *
400  * It will also unreference the associated connection object,
401  * which may also be released if its ref count hits zero.
402  */
403 static void
virNetworkDispose(void * obj)404 virNetworkDispose(void *obj)
405 {
406     virNetworkPtr network = obj;
407     char uuidstr[VIR_UUID_STRING_BUFLEN];
408 
409     virUUIDFormat(network->uuid, uuidstr);
410     VIR_DEBUG("release network %p %s %s", network, network->name, uuidstr);
411 
412     g_free(network->name);
413     virObjectUnref(network->conn);
414 }
415 
416 
417 /**
418  * virGetNetworkPort:
419  * @net: the network object
420  * @uuid: pointer to the uuid
421  *
422  * Allocates a new network port object. When the object is no longer needed,
423  * virObjectUnref() must be called in order to not leak data.
424  *
425  * Returns a pointer to the network port object, or NULL on error.
426  */
427 virNetworkPortPtr
virGetNetworkPort(virNetworkPtr net,const unsigned char * uuid)428 virGetNetworkPort(virNetworkPtr net, const unsigned char *uuid)
429 {
430     virNetworkPortPtr ret = NULL;
431 
432     if (virDataTypesInitialize() < 0)
433         return NULL;
434 
435     virCheckNetworkGoto(net, error);
436     virCheckNonNullArgGoto(uuid, error);
437 
438     if (!(ret = virObjectNew(virNetworkPortClass)))
439         goto error;
440 
441     ret->net = virObjectRef(net);
442     memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
443 
444     return ret;
445 
446  error:
447     virObjectUnref(ret);
448     return NULL;
449 }
450 
451 /**
452  * virNetworkPortDispose:
453  * @obj: the network port to release
454  *
455  * Unconditionally release all memory associated with a network port.
456  * The network port object must not be used once this method returns.
457  *
458  * It will also unreference the associated network object,
459  * which may also be released if its ref count hits zero.
460  */
461 static void
virNetworkPortDispose(void * obj)462 virNetworkPortDispose(void *obj)
463 {
464     virNetworkPortPtr port = obj;
465     char uuidstr[VIR_UUID_STRING_BUFLEN];
466 
467     virUUIDFormat(port->uuid, uuidstr);
468     VIR_DEBUG("release network port %p %s", port, uuidstr);
469 
470     virObjectUnref(port->net);
471 }
472 
473 
474 /**
475  * virGetInterface:
476  * @conn: the hypervisor connection
477  * @name: pointer to the interface name
478  * @mac: pointer to the mac
479  *
480  * Allocates a new interface object. When the object is no longer needed,
481  * virObjectUnref() must be called in order to not leak data.
482  *
483  * Returns a pointer to the interface object, or NULL on error.
484  */
485 virInterfacePtr
virGetInterface(virConnectPtr conn,const char * name,const char * mac)486 virGetInterface(virConnectPtr conn, const char *name, const char *mac)
487 {
488     virInterfacePtr ret = NULL;
489 
490     if (virDataTypesInitialize() < 0)
491         return NULL;
492 
493     virCheckConnectGoto(conn, error);
494     virCheckNonNullArgGoto(name, error);
495 
496     /* a NULL mac from caller is okay. Treat it as blank */
497     if (mac == NULL)
498        mac = "";
499 
500     if (!(ret = virObjectNew(virInterfaceClass)))
501         goto error;
502 
503     ret->name = g_strdup(name);
504     ret->mac = g_strdup(mac);
505 
506     ret->conn = virObjectRef(conn);
507 
508     return ret;
509 
510  error:
511     virObjectUnref(ret);
512     return NULL;
513 }
514 
515 /**
516  * virInterfaceDispose:
517  * @obj: the interface to release
518  *
519  * Unconditionally release all memory associated with an interface.
520  * The interface object must not be used once this method returns.
521  *
522  * It will also unreference the associated connection object,
523  * which may also be released if its ref count hits zero.
524  */
525 static void
virInterfaceDispose(void * obj)526 virInterfaceDispose(void *obj)
527 {
528     virInterfacePtr iface = obj;
529     VIR_DEBUG("release interface %p %s", iface, iface->name);
530 
531     g_free(iface->name);
532     g_free(iface->mac);
533     virObjectUnref(iface->conn);
534 }
535 
536 
537 /**
538  * virGetStoragePool:
539  * @conn: the hypervisor connection
540  * @name: pointer to the storage pool name
541  * @uuid: pointer to the uuid
542  * @privateData: pointer to driver specific private data
543  * @freeFunc: private data cleanup function pointer specific to driver
544  *
545  * Allocates a new storage pool object. When the object is no longer needed,
546  * virObjectUnref() must be called in order to not leak data.
547  *
548  * Returns a pointer to the storage pool object, or NULL on error.
549  */
550 virStoragePoolPtr
virGetStoragePool(virConnectPtr conn,const char * name,const unsigned char * uuid,void * privateData,virFreeCallback freeFunc)551 virGetStoragePool(virConnectPtr conn, const char *name,
552                   const unsigned char *uuid,
553                   void *privateData, virFreeCallback freeFunc)
554 {
555     virStoragePoolPtr ret = NULL;
556 
557     if (virDataTypesInitialize() < 0)
558         return NULL;
559 
560     virCheckConnectGoto(conn, error);
561     virCheckNonNullArgGoto(name, error);
562     virCheckNonNullArgGoto(uuid, error);
563 
564     if (!(ret = virObjectNew(virStoragePoolClass)))
565         goto error;
566 
567     ret->name = g_strdup(name);
568 
569     ret->conn = virObjectRef(conn);
570     memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
571 
572     /* set the driver specific data */
573     ret->privateData = privateData;
574     ret->privateDataFreeFunc = freeFunc;
575 
576     return ret;
577 
578  error:
579     virObjectUnref(ret);
580     return NULL;
581 }
582 
583 
584 /**
585  * virStoragePoolDispose:
586  * @obj: the storage pool to release
587  *
588  * Unconditionally release all memory associated with a pool.
589  * The pool object must not be used once this method returns.
590  *
591  * It will also unreference the associated connection object,
592  * which may also be released if its ref count hits zero.
593  */
594 static void
virStoragePoolDispose(void * obj)595 virStoragePoolDispose(void *obj)
596 {
597     virStoragePoolPtr pool = obj;
598     char uuidstr[VIR_UUID_STRING_BUFLEN];
599 
600     virUUIDFormat(pool->uuid, uuidstr);
601     VIR_DEBUG("release pool %p %s %s", pool, pool->name, uuidstr);
602 
603     if (pool->privateDataFreeFunc)
604         pool->privateDataFreeFunc(pool->privateData);
605 
606     g_free(pool->name);
607     virObjectUnref(pool->conn);
608 }
609 
610 
611 /**
612  * virGetStorageVol:
613  * @conn: the hypervisor connection
614  * @pool: pool owning the volume
615  * @name: pointer to the storage vol name
616  * @key: pointer to unique key of the volume
617  * @privateData: pointer to driver specific private data
618  * @freeFunc: private data cleanup function pointer specific to driver
619  *
620  * Allocates a new storage volume object. When the object is no longer needed,
621  * virObjectUnref() must be called in order to not leak data.
622  *
623  * Returns a pointer to the storage volume object, or NULL on error.
624  */
625 virStorageVolPtr
virGetStorageVol(virConnectPtr conn,const char * pool,const char * name,const char * key,void * privateData,virFreeCallback freeFunc)626 virGetStorageVol(virConnectPtr conn, const char *pool, const char *name,
627                  const char *key, void *privateData, virFreeCallback freeFunc)
628 {
629     virStorageVolPtr ret = NULL;
630 
631     if (virDataTypesInitialize() < 0)
632         return NULL;
633 
634     virCheckConnectGoto(conn, error);
635     virCheckNonNullArgGoto(pool, error);
636     virCheckNonNullArgGoto(name, error);
637     virCheckNonNullArgGoto(key, error);
638 
639     if (!(ret = virObjectNew(virStorageVolClass)))
640         goto error;
641 
642     ret->pool = g_strdup(pool);
643     ret->name = g_strdup(name);
644     ret->key = g_strdup(key);
645 
646     ret->conn = virObjectRef(conn);
647 
648     /* set driver specific data */
649     ret->privateData = privateData;
650     ret->privateDataFreeFunc = freeFunc;
651 
652     return ret;
653 
654  error:
655     virObjectUnref(ret);
656     return NULL;
657 }
658 
659 
660 /**
661  * virStorageVolDispose:
662  * @obj: the storage volume to release
663  *
664  * Unconditionally release all memory associated with a volume.
665  * The volume object must not be used once this method returns.
666  *
667  * It will also unreference the associated connection object,
668  * which may also be released if its ref count hits zero.
669  */
670 static void
virStorageVolDispose(void * obj)671 virStorageVolDispose(void *obj)
672 {
673     virStorageVolPtr vol = obj;
674     VIR_DEBUG("release vol %p %s", vol, vol->name);
675 
676     if (vol->privateDataFreeFunc)
677         vol->privateDataFreeFunc(vol->privateData);
678 
679     g_free(vol->key);
680     g_free(vol->name);
681     g_free(vol->pool);
682     virObjectUnref(vol->conn);
683 }
684 
685 
686 /**
687  * virGetNodeDevice:
688  * @conn: the hypervisor connection
689  * @name: device name (unique on node)
690  *
691  * Allocates a new node device object. When the object is no longer needed,
692  * virObjectUnref() must be called in order to not leak data.
693  *
694  * Returns a pointer to the node device object, or NULL on error.
695  */
696 virNodeDevicePtr
virGetNodeDevice(virConnectPtr conn,const char * name)697 virGetNodeDevice(virConnectPtr conn, const char *name)
698 {
699     virNodeDevicePtr ret = NULL;
700 
701     if (virDataTypesInitialize() < 0)
702         return NULL;
703 
704     virCheckConnectGoto(conn, error);
705     virCheckNonNullArgGoto(name, error);
706 
707     if (!(ret = virObjectNew(virNodeDeviceClass)))
708         goto error;
709 
710     ret->name = g_strdup(name);
711 
712     ret->conn = virObjectRef(conn);
713     return ret;
714 
715  error:
716     virObjectUnref(ret);
717     return NULL;
718 }
719 
720 
721 /**
722  * virNodeDeviceDispose:
723  * @obj: the node device to release
724  *
725  * Unconditionally release all memory associated with a device.
726  * The device object must not be used once this method returns.
727  *
728  * It will also unreference the associated connection object,
729  * which may also be released if its ref count hits zero.
730  */
731 static void
virNodeDeviceDispose(void * obj)732 virNodeDeviceDispose(void *obj)
733 {
734     virNodeDevicePtr dev = obj;
735     VIR_DEBUG("release dev %p %s", dev, dev->name);
736 
737     g_free(dev->name);
738     g_free(dev->parentName);
739 
740     virObjectUnref(dev->conn);
741 }
742 
743 
744 /**
745  * virGetSecret:
746  * @conn: the hypervisor connection
747  * @uuid: secret UUID
748  *
749  * Allocates a new secret object. When the object is no longer needed,
750  * virObjectUnref() must be called in order to not leak data.
751  *
752  * Returns a pointer to the secret object, or NULL on error.
753  */
754 virSecretPtr
virGetSecret(virConnectPtr conn,const unsigned char * uuid,int usageType,const char * usageID)755 virGetSecret(virConnectPtr conn, const unsigned char *uuid,
756              int usageType, const char *usageID)
757 {
758     virSecretPtr ret = NULL;
759 
760     if (virDataTypesInitialize() < 0)
761         return NULL;
762 
763     virCheckConnectGoto(conn, error);
764     virCheckNonNullArgGoto(uuid, error);
765 
766     if (!(ret = virObjectNew(virSecretClass)))
767         return NULL;
768 
769     memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
770     ret->usageType = usageType;
771     ret->usageID = g_strdup(NULLSTR_EMPTY(usageID));
772 
773     ret->conn = virObjectRef(conn);
774 
775     return ret;
776 
777  error:
778     virObjectUnref(ret);
779     return NULL;
780 }
781 
782 /**
783  * virSecretDispose:
784  * @obj: the secret to release
785  *
786  * Unconditionally release all memory associated with a secret.
787  * The secret object must not be used once this method returns.
788  *
789  * It will also unreference the associated connection object,
790  * which may also be released if its ref count hits zero.
791  */
792 static void
virSecretDispose(void * obj)793 virSecretDispose(void *obj)
794 {
795     virSecretPtr secret = obj;
796     char uuidstr[VIR_UUID_STRING_BUFLEN];
797 
798     virUUIDFormat(secret->uuid, uuidstr);
799     VIR_DEBUG("release secret %p %s", secret, uuidstr);
800 
801     g_free(secret->usageID);
802     virObjectUnref(secret->conn);
803 }
804 
805 
806 /**
807  * virGetStream:
808  * @conn: the hypervisor connection
809  *
810  * Allocates a new stream object. When the object is no longer needed,
811  * virObjectUnref() must be called in order to not leak data.
812  *
813  * Returns a pointer to the stream object, or NULL on error.
814  */
815 virStreamPtr
virGetStream(virConnectPtr conn)816 virGetStream(virConnectPtr conn)
817 {
818     virStreamPtr ret = NULL;
819 
820     if (virDataTypesInitialize() < 0)
821         return NULL;
822 
823     if (!(ret = virObjectNew(virStreamClass)))
824         return NULL;
825 
826     ret->conn = virObjectRef(conn);
827 
828     return ret;
829 }
830 
831 /**
832  * virStreamDispose:
833  * @obj: the stream to release
834  *
835  * Unconditionally release all memory associated with a stream.
836  * The stream object must not be used once this method returns.
837  *
838  * It will also unreference the associated connection object,
839  * which may also be released if its ref count hits zero.
840  */
841 static void
virStreamDispose(void * obj)842 virStreamDispose(void *obj)
843 {
844     virStreamPtr st = obj;
845     VIR_DEBUG("release dev %p", st);
846 
847     if (st->ff)
848         st->ff(st->privateData);
849     virObjectUnref(st->conn);
850 }
851 
852 
853 /**
854  * virGetNWFilter:
855  * @conn: the hypervisor connection
856  * @name: pointer to the network filter pool name
857  * @uuid: pointer to the uuid
858  *
859  * Allocates a new network filter object. When the object is no longer needed,
860  * virObjectUnref() must be called in order to not leak data.
861  *
862  * Returns a pointer to the network filter object, or NULL on error.
863  */
864 virNWFilterPtr
virGetNWFilter(virConnectPtr conn,const char * name,const unsigned char * uuid)865 virGetNWFilter(virConnectPtr conn, const char *name,
866                const unsigned char *uuid)
867 {
868     virNWFilterPtr ret = NULL;
869 
870     if (virDataTypesInitialize() < 0)
871         return NULL;
872 
873     virCheckConnectGoto(conn, error);
874     virCheckNonNullArgGoto(name, error);
875     virCheckNonNullArgGoto(uuid, error);
876 
877     if (!(ret = virObjectNew(virNWFilterClass)))
878         goto error;
879 
880     ret->name = g_strdup(name);
881 
882     memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
883 
884     ret->conn = virObjectRef(conn);
885 
886     return ret;
887 
888  error:
889     virObjectUnref(ret);
890     return NULL;
891 }
892 
893 
894 /**
895  * virNWFilterDispose:
896  * @obj: the network filter to release
897  *
898  * Unconditionally release all memory associated with a nwfilter.
899  * The nwfilter object must not be used once this method returns.
900  *
901  * It will also unreference the associated connection object,
902  * which may also be released if its ref count hits zero.
903  */
904 static void
virNWFilterDispose(void * obj)905 virNWFilterDispose(void *obj)
906 {
907     virNWFilterPtr nwfilter = obj;
908     char uuidstr[VIR_UUID_STRING_BUFLEN];
909 
910     virUUIDFormat(nwfilter->uuid, uuidstr);
911     VIR_DEBUG("release nwfilter %p %s %s", nwfilter, nwfilter->name, uuidstr);
912 
913     g_free(nwfilter->name);
914     virObjectUnref(nwfilter->conn);
915 }
916 
917 
918 /**
919  * virGetNWFilterBinding:
920  * @conn: the hypervisor connection
921  * @portdev: pointer to the network filter port device name
922  * @filtername: name of the network filter
923  *
924  * Allocates a new network filter binding object. When the object is no longer
925  * needed, virObjectUnref() must be called in order to not leak data.
926  *
927  * Returns a pointer to the network filter binding object, or NULL on error.
928  */
929 virNWFilterBindingPtr
virGetNWFilterBinding(virConnectPtr conn,const char * portdev,const char * filtername)930 virGetNWFilterBinding(virConnectPtr conn, const char *portdev,
931                       const char *filtername)
932 {
933     virNWFilterBindingPtr ret = NULL;
934 
935     if (virDataTypesInitialize() < 0)
936         return NULL;
937 
938     virCheckConnectGoto(conn, error);
939     virCheckNonNullArgGoto(portdev, error);
940 
941     if (!(ret = virObjectNew(virNWFilterBindingClass)))
942         goto error;
943 
944     ret->portdev = g_strdup(portdev);
945 
946     ret->filtername = g_strdup(filtername);
947 
948     ret->conn = virObjectRef(conn);
949 
950     return ret;
951 
952  error:
953     virObjectUnref(ret);
954     return NULL;
955 }
956 
957 
958 /**
959  * virNWFilterBindingDispose:
960  * @obj: the network filter binding to release
961  *
962  * Unconditionally release all memory associated with a nwfilter binding.
963  * The nwfilter binding object must not be used once this method returns.
964  *
965  * It will also unreference the associated connection object,
966  * which may also be released if its ref count hits zero.
967  */
968 static void
virNWFilterBindingDispose(void * obj)969 virNWFilterBindingDispose(void *obj)
970 {
971     virNWFilterBindingPtr binding = obj;
972 
973     VIR_DEBUG("release binding %p %s", binding, binding->portdev);
974 
975     g_free(binding->portdev);
976     g_free(binding->filtername);
977     virObjectUnref(binding->conn);
978 }
979 
980 
981 /**
982  * virGetDomainCheckpoint:
983  * @domain: the domain to checkpoint
984  * @name: pointer to the domain checkpoint name
985  *
986  * Allocates a new domain checkpoint object. When the object is no longer needed,
987  * virObjectUnref() must be called in order to not leak data.
988  *
989  * Returns a pointer to the domain checkpoint object, or NULL on error.
990  */
991 virDomainCheckpointPtr
virGetDomainCheckpoint(virDomainPtr domain,const char * name)992 virGetDomainCheckpoint(virDomainPtr domain,
993                        const char *name)
994 {
995     virDomainCheckpointPtr ret = NULL;
996 
997     if (virDataTypesInitialize() < 0)
998         return NULL;
999 
1000     virCheckDomainGoto(domain, error);
1001     virCheckNonNullArgGoto(name, error);
1002 
1003     if (!(ret = virObjectNew(virDomainCheckpointClass)))
1004         goto error;
1005     ret->name = g_strdup(name);
1006 
1007     ret->domain = virObjectRef(domain);
1008 
1009     return ret;
1010 
1011  error:
1012     virObjectUnref(ret);
1013     return NULL;
1014 }
1015 
1016 
1017 /**
1018  * virDomainCheckpointDispose:
1019  * @obj: the domain checkpoint to release
1020  *
1021  * Unconditionally release all memory associated with a checkpoint.
1022  * The checkpoint object must not be used once this method returns.
1023  *
1024  * It will also unreference the associated connection object,
1025  * which may also be released if its ref count hits zero.
1026  */
1027 static void
virDomainCheckpointDispose(void * obj)1028 virDomainCheckpointDispose(void *obj)
1029 {
1030     virDomainCheckpointPtr checkpoint = obj;
1031     VIR_DEBUG("release checkpoint %p %s", checkpoint, checkpoint->name);
1032 
1033     g_free(checkpoint->name);
1034     virObjectUnref(checkpoint->domain);
1035 }
1036 
1037 
1038 /**
1039  * virGetDomainSnapshot:
1040  * @domain: the domain to snapshot
1041  * @name: pointer to the domain snapshot name
1042  *
1043  * Allocates a new domain snapshot object. When the object is no longer needed,
1044  * virObjectUnref() must be called in order to not leak data.
1045  *
1046  * Returns a pointer to the domain snapshot object, or NULL on error.
1047  */
1048 virDomainSnapshotPtr
virGetDomainSnapshot(virDomainPtr domain,const char * name)1049 virGetDomainSnapshot(virDomainPtr domain, const char *name)
1050 {
1051     virDomainSnapshotPtr ret = NULL;
1052 
1053     if (virDataTypesInitialize() < 0)
1054         return NULL;
1055 
1056     virCheckDomainGoto(domain, error);
1057     virCheckNonNullArgGoto(name, error);
1058 
1059     if (!(ret = virObjectNew(virDomainSnapshotClass)))
1060         goto error;
1061     ret->name = g_strdup(name);
1062 
1063     ret->domain = virObjectRef(domain);
1064 
1065     return ret;
1066 
1067  error:
1068     virObjectUnref(ret);
1069     return NULL;
1070 }
1071 
1072 
1073 /**
1074  * virDomainSnapshotDispose:
1075  * @obj: the domain snapshot to release
1076  *
1077  * Unconditionally release all memory associated with a snapshot.
1078  * The snapshot object must not be used once this method returns.
1079  *
1080  * It will also unreference the associated connection object,
1081  * which may also be released if its ref count hits zero.
1082  */
1083 static void
virDomainSnapshotDispose(void * obj)1084 virDomainSnapshotDispose(void *obj)
1085 {
1086     virDomainSnapshotPtr snapshot = obj;
1087     VIR_DEBUG("release snapshot %p %s", snapshot, snapshot->name);
1088 
1089     g_free(snapshot->name);
1090     virObjectUnref(snapshot->domain);
1091 }
1092 
1093 
1094 virAdmConnectPtr
virAdmConnectNew(void)1095 virAdmConnectNew(void)
1096 {
1097     virAdmConnectPtr ret;
1098 
1099     if (virDataTypesInitialize() < 0)
1100         return NULL;
1101 
1102     if (!(ret = virObjectLockableNew(virAdmConnectClass)))
1103         return NULL;
1104 
1105     if (!(ret->closeCallback = virObjectLockableNew(virAdmConnectCloseCallbackDataClass)))
1106         goto error;
1107 
1108     return ret;
1109 
1110  error:
1111     virObjectUnref(ret);
1112     return NULL;
1113 }
1114 
1115 static void
virAdmConnectDispose(void * obj)1116 virAdmConnectDispose(void *obj)
1117 {
1118     virAdmConnectPtr conn = obj;
1119 
1120     admConnectDisposed = true;
1121     if (conn->privateDataFreeFunc)
1122         conn->privateDataFreeFunc(conn);
1123 
1124     virURIFree(conn->uri);
1125     virObjectUnref(conn->closeCallback);
1126 }
1127 
1128 static void
virAdmConnectCloseCallbackDataDispose(void * obj)1129 virAdmConnectCloseCallbackDataDispose(void *obj)
1130 {
1131     virAdmConnectCloseCallbackData *cb_data = obj;
1132 
1133     virObjectLock(cb_data);
1134     virAdmConnectCloseCallbackDataReset(cb_data);
1135     virObjectUnlock(cb_data);
1136 }
1137 
1138 void
virAdmConnectCloseCallbackDataReset(virAdmConnectCloseCallbackData * cbdata)1139 virAdmConnectCloseCallbackDataReset(virAdmConnectCloseCallbackData *cbdata)
1140 {
1141     if (cbdata->freeCallback)
1142         cbdata->freeCallback(cbdata->opaque);
1143 
1144     virObjectUnref(cbdata->conn);
1145     cbdata->conn = NULL;
1146     cbdata->freeCallback = NULL;
1147     cbdata->callback = NULL;
1148     cbdata->opaque = NULL;
1149 }
1150 
1151 int
virAdmConnectCloseCallbackDataUnregister(virAdmConnectCloseCallbackData * cbdata,virAdmConnectCloseFunc cb)1152 virAdmConnectCloseCallbackDataUnregister(virAdmConnectCloseCallbackData *cbdata,
1153                                          virAdmConnectCloseFunc cb)
1154 {
1155     int ret = -1;
1156 
1157     virObjectLock(cbdata);
1158     if (cbdata->callback != cb) {
1159         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
1160                        _("A different callback was requested"));
1161         goto cleanup;
1162     }
1163 
1164     virAdmConnectCloseCallbackDataReset(cbdata);
1165     ret = 0;
1166  cleanup:
1167     virObjectUnlock(cbdata);
1168     return ret;
1169 }
1170 
1171 int
virAdmConnectCloseCallbackDataRegister(virAdmConnectCloseCallbackData * cbdata,virAdmConnectPtr conn,virAdmConnectCloseFunc cb,void * opaque,virFreeCallback freecb)1172 virAdmConnectCloseCallbackDataRegister(virAdmConnectCloseCallbackData *cbdata,
1173                                        virAdmConnectPtr conn,
1174                                        virAdmConnectCloseFunc cb,
1175                                        void *opaque,
1176                                        virFreeCallback freecb)
1177 {
1178     int ret = -1;
1179 
1180     virObjectLock(cbdata);
1181 
1182     if (cbdata->callback) {
1183         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
1184                        _("A close callback is already registered"));
1185         goto cleanup;
1186     }
1187 
1188     cbdata->conn = virObjectRef(conn);
1189     cbdata->callback = cb;
1190     cbdata->opaque = opaque;
1191     cbdata->freeCallback = freecb;
1192 
1193     ret = 0;
1194  cleanup:
1195     virObjectUnlock(conn->closeCallback);
1196     return ret;
1197 }
1198 
1199 virAdmServerPtr
virAdmGetServer(virAdmConnectPtr conn,const char * name)1200 virAdmGetServer(virAdmConnectPtr conn, const char *name)
1201 {
1202     virAdmServerPtr ret = NULL;
1203 
1204     if (virDataTypesInitialize() < 0)
1205         goto error;
1206 
1207     if (!(ret = virObjectNew(virAdmServerClass)))
1208         goto error;
1209     ret->name = g_strdup(name);
1210 
1211     ret->conn = virObjectRef(conn);
1212 
1213     return ret;
1214  error:
1215     virObjectUnref(ret);
1216     return NULL;
1217 }
1218 
1219 static void
virAdmServerDispose(void * obj)1220 virAdmServerDispose(void *obj)
1221 {
1222     virAdmServerPtr srv = obj;
1223     VIR_DEBUG("release server srv=%p name=%s", srv, srv->name);
1224 
1225     g_free(srv->name);
1226     virObjectUnref(srv->conn);
1227 }
1228 
1229 virAdmClientPtr
virAdmGetClient(virAdmServerPtr srv,const unsigned long long id,unsigned long long timestamp,unsigned int transport)1230 virAdmGetClient(virAdmServerPtr srv, const unsigned long long id,
1231                 unsigned long long timestamp, unsigned int transport)
1232 {
1233     virAdmClientPtr ret = NULL;
1234 
1235     if (virDataTypesInitialize() < 0)
1236         goto error;
1237 
1238     if (!(ret = virObjectNew(virAdmClientClass)))
1239         goto error;
1240 
1241     ret->id = id;
1242     ret->timestamp = timestamp;
1243     ret->transport = transport;
1244     ret->srv = virObjectRef(srv);
1245 
1246     return ret;
1247  error:
1248     virObjectUnref(ret);
1249     return NULL;
1250 }
1251 
1252 static void
virAdmClientDispose(void * obj)1253 virAdmClientDispose(void *obj)
1254 {
1255     virAdmClientPtr clt = obj;
1256     VIR_DEBUG("release client clt=%p, id=%llu", clt, clt->id);
1257 
1258     virObjectUnref(clt->srv);
1259 }
1260