datatypes.c 34.3 KB
Newer Older
1 2 3
/*
 * datatypes.h: management of structs for public data types
 *
4
 * Copyright (C) 2006-2011 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 */

#include <config.h>
D
Daniel P. Berrange 已提交
23
#include <unistd.h>
24 25 26

#include "datatypes.h"
#include "virterror_internal.h"
27
#include "logging.h"
28
#include "memory.h"
29
#include "uuid.h"
C
Chris Lalancette 已提交
30
#include "util.h"
31

32 33
#define VIR_FROM_THIS VIR_FROM_NONE

34 35
#define virLibConnError(code, ...)                                \
    virReportErrorHelper(NULL, VIR_FROM_THIS, code, __FILE__,     \
36
                         __FUNCTION__, __LINE__, __VA_ARGS__)
37

38 39 40 41 42 43
/************************************************************************
 *									*
 *			Domain and Connections allocations		*
 *									*
 ************************************************************************/

C
Chris Lalancette 已提交
44

45 46 47 48 49 50 51 52 53 54 55 56
/**
 * virGetConnect:
 *
 * Allocates a new hypervisor connection structure
 *
 * Returns a new pointer or NULL in case of error.
 */
virConnectPtr
virGetConnect(void) {
    virConnectPtr ret;

    if (VIR_ALLOC(ret) < 0) {
57
        virReportOOMError();
58 59
        goto failed;
    }
60 61 62 63 64
    if (virMutexInit(&ret->lock) < 0) {
        VIR_FREE(ret);
        goto failed;
    }

65 66 67 68 69
    ret->magic = VIR_CONNECT_MAGIC;
    ret->driver = NULL;
    ret->networkDriver = NULL;
    ret->privateData = NULL;
    ret->networkPrivateData = NULL;
D
Daniel Veillard 已提交
70
    ret->interfacePrivateData = NULL;
71 72 73 74 75 76

    ret->refs = 1;
    return(ret);

failed:
    if (ret != NULL) {
77
        virMutexDestroy(&ret->lock);
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
        VIR_FREE(ret);
    }
    return(NULL);
}

/**
 * virReleaseConnect:
 * @conn: the hypervisor connection to release
 *
 * Unconditionally release all memory associated with a connection.
 * The conn.lock mutex must be held prior to calling this, and will
 * be released prior to this returning. The connection obj must not
 * be used once this method returns.
 */
static void
virReleaseConnect(virConnectPtr conn) {
94
    VIR_DEBUG("release connection %p", conn);
95 96

    /* make sure to release the connection lock before we call the
97
     * close callbacks, otherwise we will deadlock if an error
98 99 100 101
     * is raised by any of the callbacks */
    virMutexUnlock(&conn->lock);

    if (conn->networkDriver)
102
        conn->networkDriver->close(conn);
103
    if (conn->interfaceDriver)
104
        conn->interfaceDriver->close(conn);
105
    if (conn->storageDriver)
106
        conn->storageDriver->close(conn);
107
    if (conn->deviceMonitor)
108
        conn->deviceMonitor->close(conn);
109
    if (conn->secretDriver)
110
        conn->secretDriver->close(conn);
111
    if (conn->nwfilterDriver)
112
        conn->nwfilterDriver->close(conn);
113
    if (conn->driver)
114
        conn->driver->close(conn);
115 116 117

    virMutexLock(&conn->lock);

118 119
    virResetError(&conn->err);

120
    xmlFreeURI(conn->uri);
121

122 123
    virMutexUnlock(&conn->lock);
    virMutexDestroy(&conn->lock);
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
    VIR_FREE(conn);
}

/**
 * virUnrefConnect:
 * @conn: the hypervisor connection to unreference
 *
 * Unreference the connection. If the use count drops to zero, the structure is
 * actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
virUnrefConnect(virConnectPtr conn) {
    int refs;

    if ((!VIR_IS_CONNECT(conn))) {
141 142
        virLibConnError(VIR_ERR_INVALID_ARG, _("no connection"));
        return -1;
143
    }
144
    virMutexLock(&conn->lock);
145
    VIR_DEBUG("unref connection %p %d", conn, conn->refs);
146 147 148 149 150 151 152
    conn->refs--;
    refs = conn->refs;
    if (refs == 0) {
        virReleaseConnect(conn);
        /* Already unlocked mutex */
        return (0);
    }
153
    virMutexUnlock(&conn->lock);
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
    return (refs);
}

/**
 * virGetDomain:
 * @conn: the hypervisor connection
 * @name: pointer to the domain name
 * @uuid: pointer to the uuid
 *
 * Lookup if the domain is already registered for that connection,
 * if yes return a new pointer to it, if no allocate a new structure,
 * and register it in the table. In any case a corresponding call to
 * virUnrefDomain() is needed to not leak data.
 *
 * Returns a pointer to the domain, or NULL in case of failure
 */
virDomainPtr
D
Daniel P. Berrange 已提交
171
virGetDomain(virConnectPtr conn, const char *name, const unsigned char *uuid) {
172
    virDomainPtr ret = NULL;
173
    char uuidstr[VIR_UUID_STRING_BUFLEN];
174

175 176 177 178 179 180 181 182 183 184 185
    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("no connection"));
        return NULL;
    }
    if (name == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing name"));
        return NULL;
    }
    if (uuid == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing uuid"));
        return NULL;
186
    }
187
    virMutexLock(&conn->lock);
188

189
    virUUIDFormat(uuid, uuidstr);
190

191 192 193 194 195 196 197 198 199 200
    if (VIR_ALLOC(ret) < 0) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
    }
    ret->name = strdup(name);
    if (ret->name == NULL) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
201
    }
202 203 204 205 206 207
    ret->magic = VIR_DOMAIN_MAGIC;
    ret->conn = conn;
    ret->id = -1;
    memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);

    conn->refs++;
208
    ret->refs++;
209
    virMutexUnlock(&conn->lock);
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
    return(ret);

 error:
    if (ret != NULL) {
        VIR_FREE(ret->name);
        VIR_FREE(ret);
    }
    return(NULL);
}

/**
 * virReleaseDomain:
 * @domain: the domain to release
 *
 * Unconditionally release all memory associated with a domain.
 * The conn.lock mutex must be held prior to calling this, and will
 * be released prior to this returning. The domain obj must not
 * be used once this method returns.
 *
 * It will also unreference the associated connection object,
 * which may also be released if its ref count hits zero.
 */
static void
virReleaseDomain(virDomainPtr domain) {
    virConnectPtr conn = domain->conn;
235
    char uuidstr[VIR_UUID_STRING_BUFLEN];
236

237
    virUUIDFormat(domain->uuid, uuidstr);
238
    VIR_DEBUG("release domain %p %s %s", domain, domain->name, uuidstr);
239

240 241 242 243 244
    domain->magic = -1;
    domain->id = -1;
    VIR_FREE(domain->name);
    VIR_FREE(domain);

245
    if (conn) {
246
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
247 248 249 250 251 252 253
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
    }
}


/**
 * virUnrefDomain:
 * @domain: the domain to unreference
 *
 * Unreference the domain. If the use count drops to zero, the structure is
 * actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
virUnrefDomain(virDomainPtr domain) {
    int refs;

    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
272 273
        virLibConnError(VIR_ERR_INVALID_ARG, _("bad domain or no connection"));
        return -1;
274
    }
275
    virMutexLock(&domain->conn->lock);
276
    VIR_DEBUG("unref domain %p %s %d", domain, domain->name, domain->refs);
277 278 279 280 281 282 283 284
    domain->refs--;
    refs = domain->refs;
    if (refs == 0) {
        virReleaseDomain(domain);
        /* Already unlocked mutex */
        return (0);
    }

285
    virMutexUnlock(&domain->conn->lock);
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
    return (refs);
}

/**
 * virGetNetwork:
 * @conn: the hypervisor connection
 * @name: pointer to the network name
 * @uuid: pointer to the uuid
 *
 * Lookup if the network is already registered for that connection,
 * if yes return a new pointer to it, if no allocate a new structure,
 * and register it in the table. In any case a corresponding call to
 * virUnrefNetwork() is needed to not leak data.
 *
 * Returns a pointer to the network, or NULL in case of failure
 */
virNetworkPtr
D
Daniel P. Berrange 已提交
303
virGetNetwork(virConnectPtr conn, const char *name, const unsigned char *uuid) {
304
    virNetworkPtr ret = NULL;
305
    char uuidstr[VIR_UUID_STRING_BUFLEN];
306

307 308 309 310 311 312 313 314 315 316 317
    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("no connection"));
        return NULL;
    }
    if (name == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing name"));
        return NULL;
    }
    if (uuid == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing uuid"));
        return NULL;
318
    }
319
    virMutexLock(&conn->lock);
320

321
    virUUIDFormat(uuid, uuidstr);
322

323 324 325 326 327 328 329 330 331 332
    if (VIR_ALLOC(ret) < 0) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
    }
    ret->name = strdup(name);
    if (ret->name == NULL) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
333
    }
334 335 336 337 338
    ret->magic = VIR_NETWORK_MAGIC;
    ret->conn = conn;
    memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);

    conn->refs++;
339
    ret->refs++;
340
    virMutexUnlock(&conn->lock);
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
    return(ret);

 error:
    if (ret != NULL) {
        VIR_FREE(ret->name);
        VIR_FREE(ret);
    }
    return(NULL);
}

/**
 * virReleaseNetwork:
 * @network: the network to release
 *
 * Unconditionally release all memory associated with a network.
 * The conn.lock mutex must be held prior to calling this, and will
 * be released prior to this returning. The network obj must not
 * be used once this method returns.
 *
 * It will also unreference the associated connection object,
 * which may also be released if its ref count hits zero.
 */
static void
virReleaseNetwork(virNetworkPtr network) {
    virConnectPtr conn = network->conn;
366
    char uuidstr[VIR_UUID_STRING_BUFLEN];
367

368
    virUUIDFormat(network->uuid, uuidstr);
369
    VIR_DEBUG("release network %p %s %s", network, network->name, uuidstr);
370

371 372 373 374
    network->magic = -1;
    VIR_FREE(network->name);
    VIR_FREE(network);

375
    if (conn) {
376
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
377 378 379 380 381 382 383
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
    }
}


/**
 * virUnrefNetwork:
 * @network: the network to unreference
 *
 * Unreference the network. If the use count drops to zero, the structure is
 * actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
virUnrefNetwork(virNetworkPtr network) {
    int refs;

    if (!VIR_IS_CONNECTED_NETWORK(network)) {
402 403 404
        virLibConnError(VIR_ERR_INVALID_ARG,
                        _("bad network or no connection"));
        return -1;
405
    }
406
    virMutexLock(&network->conn->lock);
407
    VIR_DEBUG("unref network %p %s %d", network, network->name, network->refs);
408 409 410 411 412 413 414 415
    network->refs--;
    refs = network->refs;
    if (refs == 0) {
        virReleaseNetwork(network);
        /* Already unlocked mutex */
        return (0);
    }

416
    virMutexUnlock(&network->conn->lock);
417 418 419 420
    return (refs);
}


D
Daniel Veillard 已提交
421 422 423 424 425 426 427
/**
 * virGetInterface:
 * @conn: the hypervisor connection
 * @name: pointer to the interface name
 * @mac: pointer to the mac
 *
 * Lookup if the interface is already registered for that connection,
428 429 430 431
 * if yes return a new pointer to it (possibly updating the MAC
 * address), if no allocate a new structure, and register it in the
 * table. In any case a corresponding call to virUnrefInterface() is
 * needed to not leak data.
D
Daniel Veillard 已提交
432 433 434 435 436 437 438
 *
 * Returns a pointer to the interface, or NULL in case of failure
 */
virInterfacePtr
virGetInterface(virConnectPtr conn, const char *name, const char *mac) {
    virInterfacePtr ret = NULL;

439 440 441 442 443 444 445
    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("no connection"));
        return NULL;
    }
    if (name == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing name"));
        return NULL;
D
Daniel Veillard 已提交
446
    }
447 448 449 450 451

    /* a NULL mac from caller is okay. Treat it as blank */
    if (mac == NULL)
       mac = "";

D
Daniel Veillard 已提交
452 453
    virMutexLock(&conn->lock);

454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470
    if (VIR_ALLOC(ret) < 0) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
    }
    ret->name = strdup(name);
    if (ret->name == NULL) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
    }
    ret->mac = strdup(mac);
    if (ret->mac == NULL) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
    }
D
Daniel Veillard 已提交
471

472 473
    ret->magic = VIR_INTERFACE_MAGIC;
    ret->conn = conn;
D
Daniel Veillard 已提交
474

475
    conn->refs++;
D
Daniel Veillard 已提交
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
    ret->refs++;
    virMutexUnlock(&conn->lock);
    return(ret);

 error:
    if (ret != NULL) {
        VIR_FREE(ret->name);
        VIR_FREE(ret->mac);
        VIR_FREE(ret);
    }
    return(NULL);
}

/**
 * virReleaseInterface:
 * @interface: the interface to release
 *
D
Dan Kenigsberg 已提交
493
 * Unconditionally release all memory associated with an interface.
D
Daniel Veillard 已提交
494 495 496 497 498 499 500 501
 * The conn.lock mutex must be held prior to calling this, and will
 * be released prior to this returning. The interface obj must not
 * be used once this method returns.
 *
 * It will also unreference the associated connection object,
 * which may also be released if its ref count hits zero.
 */
static void
502 503
virReleaseInterface(virInterfacePtr iface) {
    virConnectPtr conn = iface->conn;
504
    VIR_DEBUG("release interface %p %s", iface, iface->name);
D
Daniel Veillard 已提交
505

506 507 508 509
    iface->magic = -1;
    VIR_FREE(iface->name);
    VIR_FREE(iface->mac);
    VIR_FREE(iface);
D
Daniel Veillard 已提交
510

511
    if (conn) {
512
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
513 514 515 516 517 518 519
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
D
Daniel Veillard 已提交
520 521 522 523 524 525 526 527 528 529 530 531 532 533
    }
}


/**
 * virUnrefInterface:
 * @interface: the interface to unreference
 *
 * Unreference the interface. If the use count drops to zero, the structure is
 * actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
534
virUnrefInterface(virInterfacePtr iface) {
D
Daniel Veillard 已提交
535 536
    int refs;

537
    if (!VIR_IS_CONNECTED_INTERFACE(iface)) {
538 539 540
        virLibConnError(VIR_ERR_INVALID_ARG,
                        _("bad interface or no connection"));
        return -1;
D
Daniel Veillard 已提交
541
    }
542
    virMutexLock(&iface->conn->lock);
543
    VIR_DEBUG("unref interface %p %s %d", iface, iface->name, iface->refs);
544 545
    iface->refs--;
    refs = iface->refs;
D
Daniel Veillard 已提交
546
    if (refs == 0) {
547
        virReleaseInterface(iface);
D
Daniel Veillard 已提交
548 549 550 551
        /* Already unlocked mutex */
        return (0);
    }

552
    virMutexUnlock(&iface->conn->lock);
D
Daniel Veillard 已提交
553 554 555 556
    return (refs);
}


557 558 559 560 561 562 563 564 565
/**
 * virGetStoragePool:
 * @conn: the hypervisor connection
 * @name: pointer to the storage pool name
 * @uuid: pointer to the uuid
 *
 * Lookup if the storage pool is already registered for that connection,
 * if yes return a new pointer to it, if no allocate a new structure,
 * and register it in the table. In any case a corresponding call to
566
 * virUnrefStoragePool() is needed to not leak data.
567 568 569 570
 *
 * Returns a pointer to the network, or NULL in case of failure
 */
virStoragePoolPtr
571 572
virGetStoragePool(virConnectPtr conn, const char *name,
                  const unsigned char *uuid) {
573
    virStoragePoolPtr ret = NULL;
574
    char uuidstr[VIR_UUID_STRING_BUFLEN];
575

576 577 578 579 580 581 582 583 584 585 586
    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("no connection"));
        return NULL;
    }
    if (name == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing name"));
        return NULL;
    }
    if (uuid == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing uuid"));
        return NULL;
587
    }
588
    virMutexLock(&conn->lock);
589

590
    virUUIDFormat(uuid, uuidstr);
591

592 593 594 595 596 597 598 599 600 601
    if (VIR_ALLOC(ret) < 0) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
    }
    ret->name = strdup(name);
    if (ret->name == NULL) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
602
    }
603 604 605 606 607
    ret->magic = VIR_STORAGE_POOL_MAGIC;
    ret->conn = conn;
    memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);

    conn->refs++;
608
    ret->refs++;
609
    virMutexUnlock(&conn->lock);
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
    return(ret);

error:
    if (ret != NULL) {
        VIR_FREE(ret->name);
        VIR_FREE(ret);
    }
    return(NULL);
}


/**
 * virReleaseStoragePool:
 * @pool: the pool to release
 *
 * Unconditionally release all memory associated with a pool.
 * The conn.lock mutex must be held prior to calling this, and will
 * be released prior to this returning. The pool obj must not
 * be used once this method returns.
 *
 * It will also unreference the associated connection object,
 * which may also be released if its ref count hits zero.
 */
static void
virReleaseStoragePool(virStoragePoolPtr pool) {
    virConnectPtr conn = pool->conn;
636
    char uuidstr[VIR_UUID_STRING_BUFLEN];
637

638
    virUUIDFormat(pool->uuid, uuidstr);
639
    VIR_DEBUG("release pool %p %s %s", pool, pool->name, uuidstr);
640

641 642 643 644
    pool->magic = -1;
    VIR_FREE(pool->name);
    VIR_FREE(pool);

645
    if (conn) {
646
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
647 648 649 650 651 652 653
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
    }
}


/**
 * virUnrefStoragePool:
 * @pool: the pool to unreference
 *
 * Unreference the pool. If the use count drops to zero, the structure is
 * actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
virUnrefStoragePool(virStoragePoolPtr pool) {
    int refs;

    if (!VIR_IS_CONNECTED_STORAGE_POOL(pool)) {
672 673 674
        virLibConnError(VIR_ERR_INVALID_ARG,
                        _("bad storage pool or no connection"));
        return -1;
675
    }
676
    virMutexLock(&pool->conn->lock);
677
    VIR_DEBUG("unref pool %p %s %d", pool, pool->name, pool->refs);
678 679 680 681 682 683 684 685
    pool->refs--;
    refs = pool->refs;
    if (refs == 0) {
        virReleaseStoragePool(pool);
        /* Already unlocked mutex */
        return (0);
    }

686
    virMutexUnlock(&pool->conn->lock);
687 688 689 690 691 692 693 694 695
    return (refs);
}


/**
 * virGetStorageVol:
 * @conn: the hypervisor connection
 * @pool: pool owning the volume
 * @name: pointer to the storage vol name
J
Jiri Denemark 已提交
696
 * @key: pointer to unique key of the volume
697 698 699 700
 *
 * Lookup if the storage vol is already registered for that connection,
 * if yes return a new pointer to it, if no allocate a new structure,
 * and register it in the table. In any case a corresponding call to
701
 * virUnrefStorageVol() is needed to not leak data.
702 703 704 705
 *
 * Returns a pointer to the storage vol, or NULL in case of failure
 */
virStorageVolPtr
706 707
virGetStorageVol(virConnectPtr conn, const char *pool, const char *name,
                 const char *key) {
708 709
    virStorageVolPtr ret = NULL;

710 711 712 713 714 715 716 717 718 719 720
    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("no connection"));
        return NULL;
    }
    if (name == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing name"));
        return NULL;
    }
    if (key == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing key"));
        return NULL;
721
    }
722
    virMutexLock(&conn->lock);
723

724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
    if (VIR_ALLOC(ret) < 0) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
    }
    ret->pool = strdup(pool);
    if (ret->pool == NULL) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
    }
    ret->name = strdup(name);
    if (ret->name == NULL) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
    }
    if (virStrcpyStatic(ret->key, key) == NULL) {
        virMutexUnlock(&conn->lock);
        virLibConnError(VIR_ERR_INTERNAL_ERROR,
                        _("Volume key %s too large for destination"), key);
        goto error;
746
    }
747 748 749 750
    ret->magic = VIR_STORAGE_VOL_MAGIC;
    ret->conn = conn;

    conn->refs++;
751
    ret->refs++;
752
    virMutexUnlock(&conn->lock);
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779
    return(ret);

error:
    if (ret != NULL) {
        VIR_FREE(ret->name);
        VIR_FREE(ret->pool);
        VIR_FREE(ret);
    }
    return(NULL);
}


/**
 * virReleaseStorageVol:
 * @vol: the vol to release
 *
 * Unconditionally release all memory associated with a vol.
 * The conn.lock mutex must be held prior to calling this, and will
 * be released prior to this returning. The vol obj must not
 * be used once this method returns.
 *
 * It will also unreference the associated connection object,
 * which may also be released if its ref count hits zero.
 */
static void
virReleaseStorageVol(virStorageVolPtr vol) {
    virConnectPtr conn = vol->conn;
780
    VIR_DEBUG("release vol %p %s", vol, vol->name);
781 782 783 784 785 786

    vol->magic = -1;
    VIR_FREE(vol->name);
    VIR_FREE(vol->pool);
    VIR_FREE(vol);

787
    if (conn) {
788
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
789 790 791 792 793 794 795
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813
    }
}


/**
 * virUnrefStorageVol:
 * @vol: the vol to unreference
 *
 * Unreference the vol. If the use count drops to zero, the structure is
 * actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
virUnrefStorageVol(virStorageVolPtr vol) {
    int refs;

    if (!VIR_IS_CONNECTED_STORAGE_VOL(vol)) {
814 815 816
        virLibConnError(VIR_ERR_INVALID_ARG,
                        _("bad storage volume or no connection"));
        return -1;
817
    }
818
    virMutexLock(&vol->conn->lock);
819
    VIR_DEBUG("unref vol %p %s %d", vol, vol->name, vol->refs);
820 821 822 823 824 825 826 827
    vol->refs--;
    refs = vol->refs;
    if (refs == 0) {
        virReleaseStorageVol(vol);
        /* Already unlocked mutex */
        return (0);
    }

828
    virMutexUnlock(&vol->conn->lock);
829 830
    return (refs);
}
831 832 833 834 835 836 837 838 839 840


/**
 * virGetNodeDevice:
 * @conn: the hypervisor connection
 * @name: device name (unique on node)
 *
 * Lookup if the device is already registered for that connection,
 * if yes return a new pointer to it, if no allocate a new structure,
 * and register it in the table. In any case a corresponding call to
841
 * virUnrefNodeDevice() is needed to not leak data.
842 843 844 845 846 847 848 849
 *
 * Returns a pointer to the node device, or NULL in case of failure
 */
virNodeDevicePtr
virGetNodeDevice(virConnectPtr conn, const char *name)
{
    virNodeDevicePtr ret = NULL;

850 851 852 853 854 855 856
    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("no connection"));
        return NULL;
    }
    if (name == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing name"));
        return NULL;
857
    }
858
    virMutexLock(&conn->lock);
859

860 861 862 863
    if (VIR_ALLOC(ret) < 0) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
864
    }
865 866 867 868 869 870 871 872 873 874
    ret->magic = VIR_NODE_DEVICE_MAGIC;
    ret->conn = conn;
    ret->name = strdup(name);
    if (ret->name == NULL) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
    }

    conn->refs++;
875
    ret->refs++;
876
    virMutexUnlock(&conn->lock);
877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
    return(ret);

error:
    if (ret != NULL) {
        VIR_FREE(ret->name);
        VIR_FREE(ret);
    }
    return(NULL);
}


/**
 * virReleaseNodeDevice:
 * @dev: the dev to release
 *
 * Unconditionally release all memory associated with a dev.
 * The conn.lock mutex must be held prior to calling this, and will
 * be released prior to this returning. The dev obj must not
 * be used once this method returns.
 *
 * It will also unreference the associated connection object,
 * which may also be released if its ref count hits zero.
 */
static void
virReleaseNodeDevice(virNodeDevicePtr dev) {
    virConnectPtr conn = dev->conn;
903
    VIR_DEBUG("release dev %p %s", dev, dev->name);
904 905 906

    dev->magic = -1;
    VIR_FREE(dev->name);
907
    VIR_FREE(dev->parent);
908 909
    VIR_FREE(dev);

910
    if (conn) {
911
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
912 913 914 915 916 917 918
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935
    }
}


/**
 * virUnrefNodeDevice:
 * @dev: the dev to unreference
 *
 * Unreference the dev. If the use count drops to zero, the structure is
 * actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
virUnrefNodeDevice(virNodeDevicePtr dev) {
    int refs;

936
    virMutexLock(&dev->conn->lock);
937
    VIR_DEBUG("unref dev %p %s %d", dev, dev->name, dev->refs);
938 939 940 941 942 943 944 945
    dev->refs--;
    refs = dev->refs;
    if (refs == 0) {
        virReleaseNodeDevice(dev);
        /* Already unlocked mutex */
        return (0);
    }

946
    virMutexUnlock(&dev->conn->lock);
947 948
    return (refs);
}
949

950

951 952 953 954 955 956 957
/**
 * virGetSecret:
 * @conn: the hypervisor connection
 * @uuid: secret UUID
 *
 * Lookup if the secret is already registered for that connection, if so return
 * a pointer to it, otherwise allocate a new structure, and register it in the
958
 * table. In any case a corresponding call to virUnrefSecret() is needed to not
959 960 961 962 963
 * leak data.
 *
 * Returns a pointer to the secret, or NULL in case of failure
 */
virSecretPtr
964 965
virGetSecret(virConnectPtr conn, const unsigned char *uuid,
             int usageType, const char *usageID)
966 967
{
    virSecretPtr ret = NULL;
968
    char uuidstr[VIR_UUID_STRING_BUFLEN];
969

970 971 972 973 974 975 976 977 978 979
    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("no connection"));
        return NULL;
    }
    if (uuid == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing uuid"));
        return NULL;
    }
    if (usageID == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing usageID"));
980 981 982 983
        return NULL;
    }
    virMutexLock(&conn->lock);

984 985
    virUUIDFormat(uuid, uuidstr);

986 987 988 989 990 991 992 993 994 995 996 997 998
    if (VIR_ALLOC(ret) < 0) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
    }
    ret->magic = VIR_SECRET_MAGIC;
    ret->conn = conn;
    memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
    ret->usageType = usageType;
    if (!(ret->usageID = strdup(usageID))) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
999
    }
1000
    conn->refs++;
1001 1002 1003 1004 1005 1006
    ret->refs++;
    virMutexUnlock(&conn->lock);
    return ret;

error:
    if (ret != NULL) {
1007
        VIR_FREE(ret->usageID);
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
        VIR_FREE(ret);
    }
    return NULL;
}

/**
 * virReleaseSecret:
 * @secret: the secret to release
 *
 * Unconditionally release all memory associated with a secret.  The conn.lock
 * mutex must be held prior to calling this, and will be released prior to this
 * returning. The secret obj must not be used once this method returns.
 *
 * It will also unreference the associated connection object, which may also be
 * released if its ref count hits zero.
 */
static void
virReleaseSecret(virSecretPtr secret) {
    virConnectPtr conn = secret->conn;
1027
    char uuidstr[VIR_UUID_STRING_BUFLEN];
1028

1029
    virUUIDFormat(secret->uuid, uuidstr);
1030
    VIR_DEBUG("release secret %p %s", secret, uuidstr);
J
Jiri Denemark 已提交
1031

1032
    VIR_FREE(secret->usageID);
1033 1034 1035 1036
    secret->magic = -1;
    VIR_FREE(secret);

    if (conn) {
1037
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
    }
}

/**
 * virUnrefSecret:
 * @secret: the secret to unreference
 *
 * Unreference the secret. If the use count drops to zero, the structure is
 * actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
virUnrefSecret(virSecretPtr secret) {
    int refs;

    if (!VIR_IS_CONNECTED_SECRET(secret)) {
1062
        virLibConnError(VIR_ERR_INVALID_ARG, _("bad secret or no connection"));
1063 1064 1065
        return -1;
    }
    virMutexLock(&secret->conn->lock);
1066
    VIR_DEBUG("unref secret %p %p %d", secret, secret->uuid, secret->refs);
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077
    secret->refs--;
    refs = secret->refs;
    if (refs == 0) {
        virReleaseSecret(secret);
        /* Already unlocked mutex */
        return 0;
    }

    virMutexUnlock(&secret->conn->lock);
    return refs;
}
1078 1079 1080 1081 1082 1083 1084

virStreamPtr virGetStream(virConnectPtr conn) {
    virStreamPtr ret = NULL;

    virMutexLock(&conn->lock);

    if (VIR_ALLOC(ret) < 0) {
1085
        virReportOOMError();
1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103
        goto error;
    }
    ret->magic = VIR_STREAM_MAGIC;
    ret->conn = conn;
    conn->refs++;
    ret->refs++;
    virMutexUnlock(&conn->lock);
    return(ret);

error:
    virMutexUnlock(&conn->lock);
    VIR_FREE(ret);
    return(NULL);
}

static void
virReleaseStream(virStreamPtr st) {
    virConnectPtr conn = st->conn;
1104
    VIR_DEBUG("release dev %p", st);
1105 1106 1107 1108

    st->magic = -1;
    VIR_FREE(st);

1109
    VIR_DEBUG("unref connection %p %d", conn, conn->refs);
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
    conn->refs--;
    if (conn->refs == 0) {
        virReleaseConnect(conn);
        /* Already unlocked mutex */
        return;
    }

    virMutexUnlock(&conn->lock);
}

int virUnrefStream(virStreamPtr st) {
    int refs;

    virMutexLock(&st->conn->lock);
1124
    VIR_DEBUG("unref stream %p %d", st, st->refs);
1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135
    st->refs--;
    refs = st->refs;
    if (refs == 0) {
        virReleaseStream(st);
        /* Already unlocked mutex */
        return (0);
    }

    virMutexUnlock(&st->conn->lock);
    return (refs);
}
S
Stefan Berger 已提交
1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146


/**
 * virGetNWFilter:
 * @conn: the hypervisor connection
 * @name: pointer to the network filter pool name
 * @uuid: pointer to the uuid
 *
 * Lookup if the network filter is already registered for that connection,
 * if yes return a new pointer to it, if no allocate a new structure,
 * and register it in the table. In any case a corresponding call to
1147
 * virUnrefNWFilter() is needed to not leak data.
S
Stefan Berger 已提交
1148 1149 1150 1151 1152 1153
 *
 * Returns a pointer to the network, or NULL in case of failure
 */
virNWFilterPtr
virGetNWFilter(virConnectPtr conn, const char *name, const unsigned char *uuid) {
    virNWFilterPtr ret = NULL;
1154
    char uuidstr[VIR_UUID_STRING_BUFLEN];
S
Stefan Berger 已提交
1155

1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166
    if (!VIR_IS_CONNECT(conn)) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("no connection"));
        return NULL;
    }
    if (name == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing name"));
        return NULL;
    }
    if (uuid == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing uuid"));
        return NULL;
S
Stefan Berger 已提交
1167 1168 1169
    }
    virMutexLock(&conn->lock);

1170
    virUUIDFormat(uuid, uuidstr);
S
Stefan Berger 已提交
1171

1172 1173 1174 1175 1176 1177 1178 1179 1180 1181
    if (VIR_ALLOC(ret) < 0) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
    }
    ret->name = strdup(name);
    if (ret->name == NULL) {
        virMutexUnlock(&conn->lock);
        virReportOOMError();
        goto error;
S
Stefan Berger 已提交
1182
    }
1183 1184 1185 1186 1187
    ret->magic = VIR_NWFILTER_MAGIC;
    ret->conn = conn;
    memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);

    conn->refs++;
S
Stefan Berger 已提交
1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201
    ret->refs++;
    virMutexUnlock(&conn->lock);
    return(ret);

error:
    if (ret != NULL) {
        VIR_FREE(ret->name);
        VIR_FREE(ret);
    }
    return(NULL);
}


/**
1202 1203
 * virReleaseNWFilter:
 * @nwfilter: the nwfilter to release
S
Stefan Berger 已提交
1204
 *
1205
 * Unconditionally release all memory associated with a nwfilter.
S
Stefan Berger 已提交
1206
 * The conn.lock mutex must be held prior to calling this, and will
1207
 * be released prior to this returning. The nwfilter obj must not
S
Stefan Berger 已提交
1208 1209 1210 1211 1212 1213
 * be used once this method returns.
 *
 * It will also unreference the associated connection object,
 * which may also be released if its ref count hits zero.
 */
static void
1214 1215 1216
virReleaseNWFilter(virNWFilterPtr nwfilter)
{
    virConnectPtr conn = nwfilter->conn;
1217
    char uuidstr[VIR_UUID_STRING_BUFLEN];
S
Stefan Berger 已提交
1218

1219
    virUUIDFormat(nwfilter->uuid, uuidstr);
1220
    VIR_DEBUG("release nwfilter %p %s %s", nwfilter, nwfilter->name, uuidstr);
1221

1222 1223 1224
    nwfilter->magic = -1;
    VIR_FREE(nwfilter->name);
    VIR_FREE(nwfilter);
S
Stefan Berger 已提交
1225 1226

    if (conn) {
1227
        VIR_DEBUG("unref connection %p %d", conn, conn->refs);
S
Stefan Berger 已提交
1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
        conn->refs--;
        if (conn->refs == 0) {
            virReleaseConnect(conn);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&conn->lock);
    }
}


/**
 * virUnrefNWFilter:
1241
 * @nwfilter: the nwfilter to unreference
S
Stefan Berger 已提交
1242 1243 1244 1245 1246 1247 1248
 *
 * Unreference the networkf itler. If the use count drops to zero, the
 * structure is actually freed.
 *
 * Returns the reference count or -1 in case of failure.
 */
int
1249 1250
virUnrefNWFilter(virNWFilterPtr nwfilter)
{
S
Stefan Berger 已提交
1251 1252
    int refs;

1253
    if (!VIR_IS_CONNECTED_NWFILTER(nwfilter)) {
1254 1255
        virLibConnError(VIR_ERR_INVALID_ARG,
                        _("bad nwfilter or no connection"));
S
Stefan Berger 已提交
1256 1257
        return -1;
    }
1258
    virMutexLock(&nwfilter->conn->lock);
1259 1260
    VIR_DEBUG("unref nwfilter %p %s %d", nwfilter, nwfilter->name,
              nwfilter->refs);
1261 1262
    nwfilter->refs--;
    refs = nwfilter->refs;
S
Stefan Berger 已提交
1263
    if (refs == 0) {
1264
        virReleaseNWFilter(nwfilter);
S
Stefan Berger 已提交
1265 1266 1267 1268
        /* Already unlocked mutex */
        return (0);
    }

1269
    virMutexUnlock(&nwfilter->conn->lock);
S
Stefan Berger 已提交
1270 1271
    return (refs);
}
C
Chris Lalancette 已提交
1272 1273 1274 1275 1276 1277 1278


virDomainSnapshotPtr
virGetDomainSnapshot(virDomainPtr domain, const char *name)
{
    virDomainSnapshotPtr ret = NULL;

1279 1280 1281 1282 1283 1284 1285
    if (!VIR_IS_DOMAIN(domain)) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("bad domain"));
        return NULL;
    }
    if (name == NULL) {
        virLibConnError(VIR_ERR_INVALID_ARG, _("missing name"));
        return NULL;
C
Chris Lalancette 已提交
1286 1287 1288
    }
    virMutexLock(&domain->conn->lock);

1289 1290 1291 1292 1293 1294 1295 1296 1297 1298
    if (VIR_ALLOC(ret) < 0) {
        virMutexUnlock(&domain->conn->lock);
        virReportOOMError();
        goto error;
    }
    ret->name = strdup(name);
    if (ret->name == NULL) {
        virMutexUnlock(&domain->conn->lock);
        virReportOOMError();
        goto error;
C
Chris Lalancette 已提交
1299
    }
1300 1301 1302 1303
    ret->magic = VIR_SNAPSHOT_MAGIC;
    ret->domain = domain;

    domain->refs++;
C
Chris Lalancette 已提交
1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320
    ret->refs++;
    virMutexUnlock(&domain->conn->lock);
    return(ret);

 error:
    if (ret != NULL) {
        VIR_FREE(ret->name);
        VIR_FREE(ret);
    }
    return(NULL);
}


static void
virReleaseDomainSnapshot(virDomainSnapshotPtr snapshot)
{
    virDomainPtr domain = snapshot->domain;
1321
    VIR_DEBUG("release snapshot %p %s", snapshot, snapshot->name);
C
Chris Lalancette 已提交
1322 1323 1324 1325 1326 1327

    snapshot->magic = -1;
    VIR_FREE(snapshot->name);
    VIR_FREE(snapshot);

    if (domain) {
1328
        VIR_DEBUG("unref domain %p %d", domain, domain->refs);
C
Chris Lalancette 已提交
1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344
        domain->refs--;
        if (domain->refs == 0) {
            virReleaseDomain(domain);
            /* Already unlocked mutex */
            return;
        }
        virMutexUnlock(&domain->conn->lock);
    }
}

int
virUnrefDomainSnapshot(virDomainSnapshotPtr snapshot)
{
    int refs;

    if (!VIR_IS_DOMAIN_SNAPSHOT(snapshot)) {
1345 1346
        virLibConnError(VIR_ERR_INVALID_ARG, _("not a snapshot"));
        return -1;
C
Chris Lalancette 已提交
1347 1348 1349
    }

    virMutexLock(&snapshot->domain->conn->lock);
1350
    VIR_DEBUG("unref snapshot %p %s %d", snapshot, snapshot->name, snapshot->refs);
C
Chris Lalancette 已提交
1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361
    snapshot->refs--;
    refs = snapshot->refs;
    if (refs == 0) {
        virReleaseDomainSnapshot(snapshot);
        /* Already unlocked mutex */
        return (0);
    }

    virMutexUnlock(&snapshot->domain->conn->lock);
    return (refs);
}