storage_driver.c 82.9 KB
Newer Older
1 2 3
/*
 * storage_driver.c: core driver for storage APIs
 *
4
 * Copyright (C) 2006-2015 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16 17
 * Copyright (C) 2006-2008 Daniel P. Berrange
 *
 * 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
18
 * License along with this library.  If not, see
O
Osier Yang 已提交
19
 * <http://www.gnu.org/licenses/>.
20 21 22 23 24 25
 */

#include <config.h>

#include <unistd.h>
#include <sys/types.h>
26 27 28 29
#include <sys/stat.h>
#include <sys/param.h>
#include <fcntl.h>

R
Richard W.M. Jones 已提交
30
#if HAVE_PWD_H
31
# include <pwd.h>
R
Richard W.M. Jones 已提交
32
#endif
33

34
#include "virerror.h"
35
#include "datatypes.h"
36 37
#include "driver.h"
#include "storage_driver.h"
38
#include "storage_capabilities.h"
39
#include "storage_conf.h"
40
#include "storage_event.h"
41
#include "viralloc.h"
42
#include "storage_backend.h"
43
#include "virlog.h"
E
Eric Blake 已提交
44
#include "virfile.h"
45
#include "virfdstream.h"
46
#include "virpidfile.h"
47
#include "configmake.h"
48
#include "virsecret.h"
49
#include "virstring.h"
50
#include "viraccessapicheck.h"
51
//#include "dirname.h"
52
#include "storage_util.h"
53

54 55
#define VIR_FROM_THIS VIR_FROM_STORAGE

56 57
VIR_LOG_INIT("storage.storage_driver");

58
static virStorageDriverStatePtr driver;
59

60
static int storageStateCleanup(void);
61

62 63 64 65
typedef struct _virStorageVolStreamInfo virStorageVolStreamInfo;
typedef virStorageVolStreamInfo *virStorageVolStreamInfoPtr;
struct _virStorageVolStreamInfo {
    char *pool_name;
66
    char *vol_path;
67 68
};

69
static void storageDriverLock(void)
70
{
71
    virMutexLock(&driver->lock);
72
}
73
static void storageDriverUnlock(void)
74
{
75
    virMutexUnlock(&driver->lock);
76
}
77

78

79 80 81 82 83
static void
storagePoolRefreshFailCleanup(virStorageBackendPtr backend,
                              virStoragePoolObjPtr obj,
                              const char *stateFile)
{
84 85
    virErrorPtr orig_err = virSaveLastError();

86 87
    virStoragePoolObjClearVols(obj);

88
    if (stateFile)
89
        unlink(stateFile);
90 91
    if (backend->stopPool)
        backend->stopPool(obj);
92 93 94 95
    if (orig_err) {
        virSetError(orig_err);
        virFreeError(orig_err);
    }
96 97 98
}


99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
static int
storagePoolRefreshImpl(virStorageBackendPtr backend,
                       virStoragePoolObjPtr obj,
                       const char *stateFile)
{
    virStoragePoolObjClearVols(obj);
    if (backend->refreshPool(obj) < 0) {
        storagePoolRefreshFailCleanup(backend, obj, stateFile);
        return -1;
    }

    return 0;
}


114 115
/**
 * virStoragePoolUpdateInactive:
116
 * @obj: pool object
117 118 119 120 121 122
 *
 * This function is supposed to be called after a pool becomes inactive. The
 * function switches to the new config object for persistent pools. Inactive
 * pools are removed.
 */
static void
123
virStoragePoolUpdateInactive(virStoragePoolObjPtr obj)
124
{
125
    if (!virStoragePoolObjGetConfigFile(obj)) {
126
        virStoragePoolObjRemove(driver->pools, obj);
127 128
    } else if (virStoragePoolObjGetNewDef(obj)) {
        virStoragePoolObjDefUseNewDef(obj);
129 130 131 132
    }
}


133
static void
134 135
storagePoolUpdateStateCallback(virStoragePoolObjPtr obj,
                               const void *opaque ATTRIBUTE_UNUSED)
136
{
137
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj);
138
    bool active = false;
139
    virStorageBackendPtr backend;
140
    VIR_AUTOFREE(char *) stateFile = NULL;
141

142
    if ((backend = virStorageBackendForType(def->type)) == NULL) {
143
        virReportError(VIR_ERR_INTERNAL_ERROR,
144
                       _("Missing backend %d"), def->type);
145
        return;
146 147
    }

148 149 150
    if (!(stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml")))
        return;

151
    /* Backends which do not support 'checkPool' are considered
152
     * inactive by default. */
153
    if (backend->checkPool &&
154
        backend->checkPool(obj, &active) < 0) {
155 156
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to initialize storage pool '%s': %s"),
157
                       def->name, virGetLastErrorMessage());
158
        unlink(stateFile);
159
        active = false;
160 161 162 163 164 165
    }

    /* We can pass NULL as connection, most backends do not use
     * it anyway, but if they do and fail, we want to log error and
     * continue with other pools.
     */
166 167 168 169 170 171
    if (active &&
        storagePoolRefreshImpl(backend, obj, stateFile) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to restart storage pool '%s': %s"),
                       def->name, virGetLastErrorMessage());
        active = false;
172 173
    }

174
    virStoragePoolObjSetActive(obj, active);
175

176
    if (!virStoragePoolObjIsActive(obj))
177
        virStoragePoolUpdateInactive(obj);
178

179 180 181
    return;
}

182

183 184 185
static void
storagePoolUpdateAllState(void)
{
186
    virStoragePoolObjListForEach(driver->pools,
187 188 189 190 191 192 193
                                 storagePoolUpdateStateCallback,
                                 NULL);
}


static void
storageDriverAutostartCallback(virStoragePoolObjPtr obj,
194
                               const void *opaque ATTRIBUTE_UNUSED)
195 196 197 198
{
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj);
    virStorageBackendPtr backend;
    bool started = false;
199

200 201
    if (!(backend = virStorageBackendForType(def->type)))
        return;
202

203 204 205
    if (virStoragePoolObjIsAutostart(obj) &&
        !virStoragePoolObjIsActive(obj)) {
        if (backend->startPool &&
206
            backend->startPool(obj) < 0) {
207 208 209 210 211 212 213 214 215
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Failed to autostart storage pool '%s': %s"),
                           def->name, virGetLastErrorMessage());
            return;
        }
        started = true;
    }

    if (started) {
216
        VIR_AUTOFREE(char *) stateFile = NULL;
217 218 219 220

        stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml");
        if (!stateFile ||
            virStoragePoolSaveState(stateFile, def) < 0 ||
221
            storagePoolRefreshImpl(backend, obj, stateFile) < 0) {
222 223 224 225 226 227
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("Failed to autostart storage pool '%s': %s"),
                           def->name, virGetLastErrorMessage());
        } else {
            virStoragePoolObjSetActive(obj, true);
        }
228 229 230
    }
}

231

232
static void
233
storageDriverAutostart(void)
234
{
235
    virStoragePoolObjListForEach(driver->pools,
236
                                 storageDriverAutostartCallback,
237
                                 NULL);
238 239 240 241 242
}

/**
 * virStorageStartup:
 *
243
 * Initialization function for the Storage Driver
244 245
 */
static int
246 247 248
storageStateInitialize(bool privileged,
                       virStateInhibitCallback callback ATTRIBUTE_UNUSED,
                       void *opaque ATTRIBUTE_UNUSED)
249
{
250 251
    VIR_AUTOFREE(char *) configdir = NULL;
    VIR_AUTOFREE(char *) rundir = NULL;
252

253
    if (VIR_ALLOC(driver) < 0)
254
        return VIR_DRV_STATE_INIT_ERROR;
255

256
    driver->lockFD = -1;
257 258
    if (virMutexInit(&driver->lock) < 0) {
        VIR_FREE(driver);
259
        return VIR_DRV_STATE_INIT_ERROR;
260
    }
261
    storageDriverLock();
262

263 264 265
    if (!(driver->pools = virStoragePoolObjListNew()))
        goto error;

266
    if (privileged) {
267 268 269 270 271 272
        if (VIR_STRDUP(driver->configDir,
                       SYSCONFDIR "/libvirt/storage") < 0 ||
            VIR_STRDUP(driver->autostartDir,
                       SYSCONFDIR "/libvirt/storage/autostart") < 0 ||
            VIR_STRDUP(driver->stateDir,
                       LOCALSTATEDIR "/run/libvirt/storage") < 0)
273
            goto error;
274
    } else {
275 276 277 278 279 280 281 282
        configdir = virGetUserConfigDirectory();
        rundir = virGetUserRuntimeDirectory();
        if (!(configdir && rundir))
            goto error;

        if ((virAsprintf(&driver->configDir,
                        "%s/storage", configdir) < 0) ||
            (virAsprintf(&driver->autostartDir,
283
                        "%s/storage/autostart", configdir) < 0) ||
284 285
            (virAsprintf(&driver->stateDir,
                         "%s/storage/run", rundir) < 0))
286
            goto error;
287
    }
288
    driver->privileged = privileged;
289

290 291 292 293 294 295 296
    if (virFileMakePath(driver->stateDir) < 0) {
        virReportError(errno,
                       _("cannot create directory %s"),
                       driver->stateDir);
        goto error;
    }

297 298 299 300 301
    if ((driver->lockFD =
         virPidFileAcquire(driver->stateDir, "driver",
                           true, getpid())) < 0)
        goto error;

302
    if (virStoragePoolObjLoadAllState(driver->pools,
303
                                      driver->stateDir) < 0)
304 305
        goto error;

306
    if (virStoragePoolObjLoadAllConfigs(driver->pools,
307 308
                                        driver->configDir,
                                        driver->autostartDir) < 0)
309
        goto error;
310

311 312
    storagePoolUpdateAllState();

313 314
    storageDriverAutostart();

315 316
    driver->storageEventState = virObjectEventStateNew();

317 318 319 320 321 322
    /* Only one load of storage driver plus backends exists. Unlike
     * domains where new binaries could change the capabilities. A
     * new/changed backend requires a reinitialization. */
    if (!(driver->caps = virStorageBackendGetCapabilities()))
        goto error;

323
    storageDriverUnlock();
324

325
    return VIR_DRV_STATE_INIT_COMPLETE;
326

327
 error:
328
    storageDriverUnlock();
329
    storageStateCleanup();
330
    return VIR_DRV_STATE_INIT_ERROR;
331 332 333
}

/**
334
 * storageStateReload:
335 336 337 338 339
 *
 * Function to restart the storage driver, it will recheck the configuration
 * files and update its state
 */
static int
340 341
storageStateReload(void)
{
342
    if (!driver)
343 344
        return -1;

345
    storageDriverLock();
346
    virStoragePoolObjLoadAllState(driver->pools,
347
                                  driver->stateDir);
348
    virStoragePoolObjLoadAllConfigs(driver->pools,
349 350
                                    driver->configDir,
                                    driver->autostartDir);
351 352
    storageDriverAutostart();
    storageDriverUnlock();
353 354 355 356 357 358

    return 0;
}


/**
359
 * storageStateCleanup
360 361 362 363
 *
 * Shutdown the storage driver, it will stop all active storage pools
 */
static int
364 365
storageStateCleanup(void)
{
366
    if (!driver)
367 368
        return -1;

369
    storageDriverLock();
370

371
    virObjectUnref(driver->caps);
372
    virObjectUnref(driver->storageEventState);
373

374
    /* free inactive pools */
375
    virObjectUnref(driver->pools);
376

377 378 379 380
    if (driver->lockFD != -1)
        virPidFileRelease(driver->stateDir, "driver",
                          driver->lockFD);

381 382
    VIR_FREE(driver->configDir);
    VIR_FREE(driver->autostartDir);
383
    VIR_FREE(driver->stateDir);
384 385 386
    storageDriverUnlock();
    virMutexDestroy(&driver->lock);
    VIR_FREE(driver);
387 388 389 390

    return 0;
}

391 392 393 394 395 396 397 398
static virDrvOpenStatus
storageConnectOpen(virConnectPtr conn,
                   virConnectAuthPtr auth ATTRIBUTE_UNUSED,
                   virConfPtr conf ATTRIBUTE_UNUSED,
                   unsigned int flags)
{
    virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);

399 400 401 402 403 404 405 406 407 408 409
    if (driver == NULL) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("storage state driver is not active"));
        return VIR_DRV_OPEN_ERROR;
    }

    if (driver->privileged) {
        if (STRNEQ(conn->uri->path, "/system")) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unexpected storage URI path '%s', try storage:///system"),
                           conn->uri->path);
410 411
            return VIR_DRV_OPEN_ERROR;
        }
412 413 414 415 416 417
    } else {
        if (STRNEQ(conn->uri->path, "/session")) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unexpected storage URI path '%s', try storage:///session"),
                           conn->uri->path);
            return VIR_DRV_OPEN_ERROR;
418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
        }
    }

    if (virConnectOpenEnsureACL(conn) < 0)
        return VIR_DRV_OPEN_ERROR;

    return VIR_DRV_OPEN_SUCCESS;
}

static int storageConnectClose(virConnectPtr conn ATTRIBUTE_UNUSED)
{
    return 0;
}


static int storageConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED)
{
    /* Trivially secure, since always inside the daemon */
    return 1;
}


static int storageConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED)
{
    /* Not encrypted, but remote driver takes care of that */
    return 0;
}


static int storageConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED)
{
    return 1;
}

452

453 454 455 456
static virStoragePoolObjPtr
storagePoolObjFindByUUID(const unsigned char *uuid,
                         const char *name)
{
457
    virStoragePoolObjPtr obj;
458 459
    char uuidstr[VIR_UUID_STRING_BUFLEN];

460
    if (!(obj = virStoragePoolObjFindByUUID(driver->pools, uuid))) {
461 462 463 464 465 466 467 468 469 470 471
        virUUIDFormat(uuid, uuidstr);
        if (name)
            virReportError(VIR_ERR_NO_STORAGE_POOL,
                           _("no storage pool with matching uuid '%s' (%s)"),
                           uuidstr, name);
        else
            virReportError(VIR_ERR_NO_STORAGE_POOL,
                           _("no storage pool with matching uuid '%s'"),
                           uuidstr);
    }

472
    return obj;
473 474 475 476 477 478
}


static virStoragePoolObjPtr
virStoragePoolObjFromStoragePool(virStoragePoolPtr pool)
{
479
    return storagePoolObjFindByUUID(pool->uuid, pool->name);
480 481 482 483 484 485
}


static virStoragePoolObjPtr
storagePoolObjFindByName(const char *name)
{
486
    virStoragePoolObjPtr obj;
487

488
    if (!(obj = virStoragePoolObjFindByName(driver->pools, name)))
489 490
        virReportError(VIR_ERR_NO_STORAGE_POOL,
                       _("no storage pool with matching name '%s'"), name);
491
    return obj;
492 493
}

494 495 496

static virStoragePoolPtr
storagePoolLookupByUUID(virConnectPtr conn,
497 498
                        const unsigned char *uuid)
{
499
    virStoragePoolObjPtr obj;
500
    virStoragePoolDefPtr def;
501
    virStoragePoolPtr pool = NULL;
502

503 504
    obj = storagePoolObjFindByUUID(uuid, NULL);
    if (!obj)
505
        return NULL;
506
    def = virStoragePoolObjGetDef(obj);
507

508
    if (virStoragePoolLookupByUUIDEnsureACL(conn, def) < 0)
509 510
        goto cleanup;

511
    pool = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL);
512

513
 cleanup:
514
    virStoragePoolObjEndAPI(&obj);
515
    return pool;
516 517 518 519
}

static virStoragePoolPtr
storagePoolLookupByName(virConnectPtr conn,
520 521
                        const char *name)
{
522
    virStoragePoolObjPtr obj;
523
    virStoragePoolDefPtr def;
524
    virStoragePoolPtr pool = NULL;
525

526
    if (!(obj = storagePoolObjFindByName(name)))
527
        return NULL;
528
    def = virStoragePoolObjGetDef(obj);
529

530
    if (virStoragePoolLookupByNameEnsureACL(conn, def) < 0)
531 532
        goto cleanup;

533
    pool = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL);
534

535
 cleanup:
536
    virStoragePoolObjEndAPI(&obj);
537
    return pool;
538 539 540
}

static virStoragePoolPtr
541 542
storagePoolLookupByVolume(virStorageVolPtr vol)
{
543
    virStoragePoolObjPtr obj;
544
    virStoragePoolDefPtr def;
545
    virStoragePoolPtr pool = NULL;
546

547
    if (!(obj = storagePoolObjFindByName(vol->pool)))
548
        return NULL;
549
    def = virStoragePoolObjGetDef(obj);
550

551
    if (virStoragePoolLookupByVolumeEnsureACL(vol->conn, def) < 0)
552 553
        goto cleanup;

554
    pool = virGetStoragePool(vol->conn, def->name, def->uuid, NULL, NULL);
555

556
 cleanup:
557
    virStoragePoolObjEndAPI(&obj);
558
    return pool;
559 560 561
}

static int
562 563
storageConnectNumOfStoragePools(virConnectPtr conn)
{
564 565 566
    if (virConnectNumOfStoragePoolsEnsureACL(conn) < 0)
        return -1;

567 568
    return virStoragePoolObjNumOfStoragePools(driver->pools, conn, true,
                                              virConnectNumOfStoragePoolsCheckACL);
569 570
}

571

572
static int
573 574
storageConnectListStoragePools(virConnectPtr conn,
                               char **const names,
575
                               int maxnames)
576
{
577 578 579
    if (virConnectListStoragePoolsEnsureACL(conn) < 0)
        return -1;

580 581 582
    return virStoragePoolObjGetNames(driver->pools, conn, true,
                                     virConnectListStoragePoolsCheckACL,
                                     names, maxnames);
583 584
}

585 586 587 588 589 590 591 592 593 594 595 596

static char *
storageConnectGetCapabilities(virConnectPtr conn)
{

    if (virConnectGetCapabilitiesEnsureACL(conn) < 0)
        return NULL;

    return virCapabilitiesFormatXML(driver->caps);
}


597
static int
598 599
storageConnectNumOfDefinedStoragePools(virConnectPtr conn)
{
600 601 602
    if (virConnectNumOfDefinedStoragePoolsEnsureACL(conn) < 0)
        return -1;

603 604
    return virStoragePoolObjNumOfStoragePools(driver->pools, conn, false,
                                               virConnectNumOfDefinedStoragePoolsCheckACL);
605 606
}

607

608
static int
609 610
storageConnectListDefinedStoragePools(virConnectPtr conn,
                                      char **const names,
611
                                      int maxnames)
612
{
613 614 615
    if (virConnectListDefinedStoragePoolsEnsureACL(conn) < 0)
        return -1;

616 617 618
    return virStoragePoolObjGetNames(driver->pools, conn, false,
                                     virConnectListDefinedStoragePoolsCheckACL,
                                     names, maxnames);
619 620
}

621 622
/* This method is required to be re-entrant / thread safe, so
   uses no driver lock */
623
static char *
624 625 626 627
storageConnectFindStoragePoolSources(virConnectPtr conn,
                                     const char *type,
                                     const char *srcSpec,
                                     unsigned int flags)
628 629 630
{
    int backend_type;
    virStorageBackendPtr backend;
631
    char *ret = NULL;
632

633 634 635
    if (virConnectFindStoragePoolSourcesEnsureACL(conn) < 0)
        return NULL;

636
    backend_type = virStoragePoolTypeFromString(type);
637
    if (backend_type < 0) {
638 639
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown storage pool type %s"), type);
640
        goto cleanup;
641
    }
642 643 644

    backend = virStorageBackendForType(backend_type);
    if (backend == NULL)
645
        goto cleanup;
646

647
    if (!backend->findPoolSources) {
648 649 650
        virReportError(VIR_ERR_NO_SUPPORT,
                       _("pool type '%s' does not support source "
                         "discovery"), type);
651 652 653
        goto cleanup;
    }

654
    ret = backend->findPoolSources(srcSpec, flags);
655

656
 cleanup:
657
    return ret;
658 659 660
}


661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682
static char *
storageConnectGetStoragePoolCapabilities(virConnectPtr conn,
                                         unsigned int flags)
{
    virStoragePoolCapsPtr caps = NULL;
    char *ret;

    virCheckFlags(0, NULL);

    if (virConnectGetStoragePoolCapabilitiesEnsureACL(conn) < 0)
        return NULL;

    if (!(caps = virStoragePoolCapsNew(driver->caps)))
        return NULL;

    ret = virStoragePoolCapsFormat(caps);

    virObjectUnref(caps);
    return ret;
}


683 684
static int
storagePoolIsActive(virStoragePoolPtr pool)
685 686
{
    virStoragePoolObjPtr obj;
687
    virStoragePoolDefPtr def;
688 689 690 691
    int ret = -1;

    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
        return -1;
692
    def = virStoragePoolObjGetDef(obj);
693

694
    if (virStoragePoolIsActiveEnsureACL(pool->conn, def) < 0)
695 696
        goto cleanup;

697 698
    ret = virStoragePoolObjIsActive(obj);

699
 cleanup:
700
    virStoragePoolObjEndAPI(&obj);
701 702 703
    return ret;
}

704 705 706

static int
storagePoolIsPersistent(virStoragePoolPtr pool)
707 708
{
    virStoragePoolObjPtr obj;
709
    virStoragePoolDefPtr def;
710 711
    int ret = -1;

712 713
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
        return -1;
714
    def = virStoragePoolObjGetDef(obj);
715

716
    if (virStoragePoolIsPersistentEnsureACL(pool->conn, def) < 0)
717 718
        goto cleanup;

719
    ret = virStoragePoolObjGetConfigFile(obj) ? 1 : 0;
720

721
 cleanup:
722
    virStoragePoolObjEndAPI(&obj);
723 724 725 726
    return ret;
}


727
static virStoragePoolPtr
728 729 730
storagePoolCreateXML(virConnectPtr conn,
                     const char *xml,
                     unsigned int flags)
E
Eric Blake 已提交
731
{
732
    virStoragePoolObjPtr obj = NULL;
733
    virStoragePoolDefPtr def;
734
    virStoragePoolPtr pool = NULL;
735
    virStorageBackendPtr backend;
736
    virObjectEventPtr event = NULL;
737
    unsigned int build_flags = 0;
738
    VIR_AUTOPTR(virStoragePoolDef) newDef = NULL;
739
    VIR_AUTOFREE(char *) stateFile = NULL;
740

741 742 743 744 745 746
    virCheckFlags(VIR_STORAGE_POOL_CREATE_WITH_BUILD |
                  VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE |
                  VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE, NULL);

    VIR_EXCLUSIVE_FLAGS_RET(VIR_STORAGE_POOL_BUILD_OVERWRITE,
                            VIR_STORAGE_POOL_BUILD_NO_OVERWRITE, NULL);
E
Eric Blake 已提交
747

748
    if (!(newDef = virStoragePoolDefParseString(xml)))
749
        goto cleanup;
750

751
    if (virStoragePoolCreateXMLEnsureACL(conn, newDef) < 0)
752 753
        goto cleanup;

754
    if ((backend = virStorageBackendForType(newDef->type)) == NULL)
755
        goto cleanup;
756

757
    if (!(obj = virStoragePoolObjListAdd(driver->pools, newDef,
758
                                         VIR_STORAGE_POOL_OBJ_LIST_ADD_LIVE |
759
                                         VIR_STORAGE_POOL_OBJ_LIST_ADD_CHECK_LIVE)))
760
        goto cleanup;
761 762
    newDef = NULL;
    def = virStoragePoolObjGetDef(obj);
763

764 765 766 767 768 769 770 771
    if (backend->buildPool) {
        if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE)
            build_flags |= VIR_STORAGE_POOL_BUILD_OVERWRITE;
        else if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE)
            build_flags |= VIR_STORAGE_POOL_BUILD_NO_OVERWRITE;

        if (build_flags ||
            (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD)) {
772 773
            if (backend->buildPool(obj, build_flags) < 0)
                goto error;
774 775 776
        }
    }

777
    if (backend->startPool &&
778 779
        backend->startPool(obj) < 0)
        goto error;
780

781
    stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml");
782

783 784 785
    if (!stateFile ||
        virStoragePoolSaveState(stateFile, def) < 0 ||
        storagePoolRefreshImpl(backend, obj, stateFile) < 0) {
786
        goto error;
787
    }
788

789 790
    event = virStoragePoolEventLifecycleNew(def->name,
                                            def->uuid,
791 792 793
                                            VIR_STORAGE_POOL_EVENT_STARTED,
                                            0);

794
    VIR_INFO("Creating storage pool '%s'", def->name);
795
    virStoragePoolObjSetActive(obj, true);
796

797
    pool = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL);
798

799
 cleanup:
800
    virObjectEventStateQueue(driver->storageEventState, event);
801
    virStoragePoolObjEndAPI(&obj);
802
    return pool;
803 804

 error:
805
    virStoragePoolUpdateInactive(obj);
806
    goto cleanup;
807 808 809
}

static virStoragePoolPtr
810 811 812
storagePoolDefineXML(virConnectPtr conn,
                     const char *xml,
                     unsigned int flags)
E
Eric Blake 已提交
813
{
814
    virStoragePoolObjPtr obj = NULL;
815
    virStoragePoolDefPtr def;
816
    virStoragePoolPtr pool = NULL;
817
    virObjectEventPtr event = NULL;
818
    VIR_AUTOPTR(virStoragePoolDef) newDef = NULL;
819

E
Eric Blake 已提交
820 821
    virCheckFlags(0, NULL);

822
    if (!(newDef = virStoragePoolDefParseString(xml)))
823
        goto cleanup;
824

825
    if (virXMLCheckIllegalChars("name", newDef->name, "\n") < 0)
826 827
        goto cleanup;

828
    if (virStoragePoolDefineXMLEnsureACL(conn, newDef) < 0)
829 830
        goto cleanup;

831
    if (virStorageBackendForType(newDef->type) == NULL)
832
        goto cleanup;
833

834
    if (!(obj = virStoragePoolObjListAdd(driver->pools, newDef, 0)))
835
        goto cleanup;
836
    newDef = virStoragePoolObjGetNewDef(obj);
837
    def = virStoragePoolObjGetDef(obj);
838

839
    if (virStoragePoolObjSaveDef(driver, obj, newDef ? newDef : def) < 0) {
840
        virStoragePoolObjRemove(driver->pools, obj);
841
        newDef = NULL;
842
        goto cleanup;
843
    }
844 845 846 847 848

    event = virStoragePoolEventLifecycleNew(def->name, def->uuid,
                                            VIR_STORAGE_POOL_EVENT_DEFINED,
                                            0);

849 850
    VIR_INFO("Defining storage pool '%s'", def->name);
    pool = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL);
851
    newDef = NULL;
852

853
 cleanup:
854
    virObjectEventStateQueue(driver->storageEventState, event);
855
    virStoragePoolObjEndAPI(&obj);
856
    return pool;
857 858 859
}

static int
860
storagePoolUndefine(virStoragePoolPtr pool)
861
{
862
    virStoragePoolObjPtr obj;
863
    virStoragePoolDefPtr def;
864
    const char *autostartLink;
865
    virObjectEventPtr event = NULL;
866
    int ret = -1;
867

868
    if (!(obj = storagePoolObjFindByUUID(pool->uuid, pool->name)))
869
        goto cleanup;
870
    def = virStoragePoolObjGetDef(obj);
871

872
    if (virStoragePoolUndefineEnsureACL(pool->conn, def) < 0)
873 874
        goto cleanup;

875
    if (virStoragePoolObjIsActive(obj)) {
876
        virReportError(VIR_ERR_OPERATION_INVALID,
877
                       _("storage pool '%s' is still active"),
878
                       def->name);
879
        goto cleanup;
880 881
    }

882
    if (virStoragePoolObjGetAsyncjobs(obj) > 0) {
883 884
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("pool '%s' has asynchronous jobs running."),
885
                       def->name);
886 887 888
        goto cleanup;
    }

889
    autostartLink = virStoragePoolObjGetAutostartLink(obj);
890
    if (virStoragePoolObjDeleteDef(obj) < 0)
891
        goto cleanup;
892

893 894
    if (autostartLink && unlink(autostartLink) < 0 &&
        errno != ENOENT && errno != ENOTDIR) {
895
        char ebuf[1024];
896
        VIR_ERROR(_("Failed to delete autostart link '%s': %s"),
897
                  autostartLink, virStrerror(errno, ebuf, sizeof(ebuf)));
898
    }
899

900 901
    event = virStoragePoolEventLifecycleNew(def->name,
                                            def->uuid,
902 903 904
                                            VIR_STORAGE_POOL_EVENT_UNDEFINED,
                                            0);

905
    VIR_INFO("Undefining storage pool '%s'", def->name);
906
    virStoragePoolObjRemove(driver->pools, obj);
907
    ret = 0;
908

909
 cleanup:
910
    virObjectEventStateQueue(driver->storageEventState, event);
911
    virStoragePoolObjEndAPI(&obj);
912
    return ret;
913 914 915
}

static int
916
storagePoolCreate(virStoragePoolPtr pool,
917
                  unsigned int flags)
E
Eric Blake 已提交
918
{
919
    virStoragePoolObjPtr obj;
920
    virStoragePoolDefPtr def;
921
    virStorageBackendPtr backend;
922
    virObjectEventPtr event = NULL;
923
    int ret = -1;
924
    unsigned int build_flags = 0;
925
    VIR_AUTOFREE(char *) stateFile = NULL;
926

927 928 929 930 931 932
    virCheckFlags(VIR_STORAGE_POOL_CREATE_WITH_BUILD |
                  VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE |
                  VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE, -1);

    VIR_EXCLUSIVE_FLAGS_RET(VIR_STORAGE_POOL_BUILD_OVERWRITE,
                            VIR_STORAGE_POOL_BUILD_NO_OVERWRITE, -1);
E
Eric Blake 已提交
933

934
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
935
        return -1;
936
    def = virStoragePoolObjGetDef(obj);
937

938
    if (virStoragePoolCreateEnsureACL(pool->conn, def) < 0)
939 940
        goto cleanup;

941
    if ((backend = virStorageBackendForType(def->type)) == NULL)
942
        goto cleanup;
943

944
    if (virStoragePoolObjIsActive(obj)) {
945
        virReportError(VIR_ERR_OPERATION_INVALID,
946
                       _("storage pool '%s' is already active"),
947
                       def->name);
948
        goto cleanup;
949
    }
950

951 952 953 954 955 956 957 958
    if (backend->buildPool) {
        if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE)
            build_flags |= VIR_STORAGE_POOL_BUILD_OVERWRITE;
        else if (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE)
            build_flags |= VIR_STORAGE_POOL_BUILD_NO_OVERWRITE;

        if (build_flags ||
            (flags & VIR_STORAGE_POOL_CREATE_WITH_BUILD)) {
959
            if (backend->buildPool(obj, build_flags) < 0)
960 961 962 963
                goto cleanup;
        }
    }

964
    VIR_INFO("Starting up storage pool '%s'", def->name);
965
    if (backend->startPool &&
966
        backend->startPool(obj) < 0)
967 968
        goto cleanup;

969
    stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml");
970

971 972 973
    if (!stateFile ||
        virStoragePoolSaveState(stateFile, def) < 0 ||
        storagePoolRefreshImpl(backend, obj, stateFile) < 0) {
974
        goto cleanup;
975 976
    }

977 978
    event = virStoragePoolEventLifecycleNew(def->name,
                                            def->uuid,
979 980 981
                                            VIR_STORAGE_POOL_EVENT_STARTED,
                                            0);

982
    virStoragePoolObjSetActive(obj, true);
983
    ret = 0;
984

985
 cleanup:
986
    virObjectEventStateQueue(driver->storageEventState, event);
987
    virStoragePoolObjEndAPI(&obj);
988
    return ret;
989 990 991
}

static int
992
storagePoolBuild(virStoragePoolPtr pool,
993 994
                 unsigned int flags)
{
995
    virStoragePoolObjPtr obj;
996
    virStoragePoolDefPtr def;
997
    virStorageBackendPtr backend;
998
    virObjectEventPtr event = NULL;
999
    int ret = -1;
1000

1001
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1002
        return -1;
1003
    def = virStoragePoolObjGetDef(obj);
1004

1005
    if (virStoragePoolBuildEnsureACL(pool->conn, def) < 0)
1006 1007
        goto cleanup;

1008
    if ((backend = virStorageBackendForType(def->type)) == NULL)
1009
        goto cleanup;
1010

1011
    if (virStoragePoolObjIsActive(obj)) {
1012
        virReportError(VIR_ERR_OPERATION_INVALID,
1013
                       _("storage pool '%s' is already active"),
1014
                       def->name);
1015
        goto cleanup;
1016 1017 1018
    }

    if (backend->buildPool &&
1019
        backend->buildPool(obj, flags) < 0)
1020
        goto cleanup;
1021

1022 1023
    event = virStoragePoolEventLifecycleNew(def->name,
                                            def->uuid,
1024 1025 1026
                                            VIR_STORAGE_POOL_EVENT_CREATED,
                                            0);

1027
    ret = 0;
1028

1029
 cleanup:
1030
    virObjectEventStateQueue(driver->storageEventState, event);
1031
    virStoragePoolObjEndAPI(&obj);
1032
    return ret;
1033 1034 1035 1036
}


static int
1037
storagePoolDestroy(virStoragePoolPtr pool)
1038
{
1039
    virStoragePoolObjPtr obj;
1040
    virStoragePoolDefPtr def;
1041
    virStorageBackendPtr backend;
1042
    virObjectEventPtr event = NULL;
1043
    int ret = -1;
1044
    VIR_AUTOFREE(char *) stateFile = NULL;
1045

1046
    if (!(obj = storagePoolObjFindByUUID(pool->uuid, pool->name)))
1047
        goto cleanup;
1048
    def = virStoragePoolObjGetDef(obj);
1049

1050
    if (virStoragePoolDestroyEnsureACL(pool->conn, def) < 0)
1051 1052
        goto cleanup;

1053
    if ((backend = virStorageBackendForType(def->type)) == NULL)
1054
        goto cleanup;
1055

1056
    VIR_INFO("Destroying storage pool '%s'", def->name);
1057

1058
    if (!virStoragePoolObjIsActive(obj)) {
1059
        virReportError(VIR_ERR_OPERATION_INVALID,
1060
                       _("storage pool '%s' is not active"), def->name);
1061
        goto cleanup;
1062 1063
    }

1064
    if (virStoragePoolObjGetAsyncjobs(obj) > 0) {
1065 1066
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("pool '%s' has asynchronous jobs running."),
1067
                       def->name);
1068 1069 1070
        goto cleanup;
    }

1071
    if (!(stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml")))
1072 1073 1074 1075
        goto cleanup;

    unlink(stateFile);

1076
    if (backend->stopPool &&
1077
        backend->stopPool(obj) < 0)
1078
        goto cleanup;
1079

1080
    virStoragePoolObjClearVols(obj);
1081

1082 1083
    event = virStoragePoolEventLifecycleNew(def->name,
                                            def->uuid,
1084 1085 1086
                                            VIR_STORAGE_POOL_EVENT_STOPPED,
                                            0);

1087
    virStoragePoolObjSetActive(obj, false);
1088

1089
    virStoragePoolUpdateInactive(obj);
1090

1091
    ret = 0;
1092

1093
 cleanup:
1094
    virObjectEventStateQueue(driver->storageEventState, event);
1095
    virStoragePoolObjEndAPI(&obj);
1096
    return ret;
1097 1098 1099
}

static int
1100
storagePoolDelete(virStoragePoolPtr pool,
1101 1102
                  unsigned int flags)
{
1103
    virStoragePoolObjPtr obj;
1104
    virStoragePoolDefPtr def;
1105
    virStorageBackendPtr backend;
1106
    virObjectEventPtr event = NULL;
1107
    int ret = -1;
1108
    VIR_AUTOFREE(char *) stateFile = NULL;
1109

1110
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1111
        return -1;
1112
    def = virStoragePoolObjGetDef(obj);
1113

1114
    if (virStoragePoolDeleteEnsureACL(pool->conn, def) < 0)
1115 1116
        goto cleanup;

1117
    if ((backend = virStorageBackendForType(def->type)) == NULL)
1118
        goto cleanup;
1119

1120
    VIR_INFO("Deleting storage pool '%s'", def->name);
1121

1122
    if (virStoragePoolObjIsActive(obj)) {
1123
        virReportError(VIR_ERR_OPERATION_INVALID,
1124
                       _("storage pool '%s' is still active"),
1125
                       def->name);
1126
        goto cleanup;
1127 1128
    }

1129
    if (virStoragePoolObjGetAsyncjobs(obj) > 0) {
1130 1131
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("pool '%s' has asynchronous jobs running."),
1132
                       def->name);
1133 1134 1135
        goto cleanup;
    }

1136
    if (!(stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml")))
1137 1138 1139 1140
        goto cleanup;

    unlink(stateFile);

1141
    if (!backend->deletePool) {
1142 1143
        virReportError(VIR_ERR_NO_SUPPORT,
                       "%s", _("pool does not support pool deletion"));
1144
        goto cleanup;
1145
    }
1146
    if (backend->deletePool(obj, flags) < 0)
1147
        goto cleanup;
1148

1149 1150
    event = virStoragePoolEventLifecycleNew(def->name,
                                            def->uuid,
1151 1152 1153
                                            VIR_STORAGE_POOL_EVENT_DELETED,
                                            0);

1154
    ret = 0;
1155

1156
 cleanup:
1157
    virObjectEventStateQueue(driver->storageEventState, event);
1158
    virStoragePoolObjEndAPI(&obj);
1159
    return ret;
1160 1161 1162 1163
}


static int
1164
storagePoolRefresh(virStoragePoolPtr pool,
E
Eric Blake 已提交
1165 1166
                   unsigned int flags)
{
1167
    virStoragePoolObjPtr obj;
1168
    virStoragePoolDefPtr def;
1169
    virStorageBackendPtr backend;
1170
    VIR_AUTOFREE(char *) stateFile = NULL;
1171
    int ret = -1;
1172
    virObjectEventPtr event = NULL;
1173

E
Eric Blake 已提交
1174 1175
    virCheckFlags(0, -1);

1176
    if (!(obj = storagePoolObjFindByUUID(pool->uuid, pool->name)))
1177
        goto cleanup;
1178
    def = virStoragePoolObjGetDef(obj);
1179

1180
    if (virStoragePoolRefreshEnsureACL(pool->conn, def) < 0)
1181 1182
        goto cleanup;

1183
    if ((backend = virStorageBackendForType(def->type)) == NULL)
1184
        goto cleanup;
1185

1186
    if (!virStoragePoolObjIsActive(obj)) {
1187
        virReportError(VIR_ERR_OPERATION_INVALID,
1188
                       _("storage pool '%s' is not active"), def->name);
1189
        goto cleanup;
1190 1191
    }

1192
    if (virStoragePoolObjGetAsyncjobs(obj) > 0) {
1193 1194
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("pool '%s' has asynchronous jobs running."),
1195
                       def->name);
1196 1197 1198
        goto cleanup;
    }

1199 1200
    stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml");
    if (storagePoolRefreshImpl(backend, obj, stateFile) < 0) {
1201 1202
        event = virStoragePoolEventLifecycleNew(def->name,
                                                def->uuid,
1203 1204
                                                VIR_STORAGE_POOL_EVENT_STOPPED,
                                                0);
1205
        virStoragePoolObjSetActive(obj, false);
1206

1207
        virStoragePoolUpdateInactive(obj);
1208

1209
        goto cleanup;
1210
    }
1211

1212 1213
    event = virStoragePoolEventRefreshNew(def->name,
                                          def->uuid);
1214
    ret = 0;
1215

1216
 cleanup:
1217
    virObjectEventStateQueue(driver->storageEventState, event);
1218
    virStoragePoolObjEndAPI(&obj);
1219 1220 1221 1222 1223
    return ret;
}


static int
1224
storagePoolGetInfo(virStoragePoolPtr pool,
1225 1226
                   virStoragePoolInfoPtr info)
{
1227
    virStoragePoolObjPtr obj;
1228
    virStoragePoolDefPtr def;
1229
    int ret = -1;
1230

1231
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1232
        return -1;
1233
    def = virStoragePoolObjGetDef(obj);
1234

1235
    if (virStoragePoolGetInfoEnsureACL(pool->conn, def) < 0)
1236 1237
        goto cleanup;

1238
    if (virStorageBackendForType(def->type) == NULL)
1239
        goto cleanup;
1240 1241

    memset(info, 0, sizeof(virStoragePoolInfo));
1242
    if (virStoragePoolObjIsActive(obj))
1243 1244 1245
        info->state = VIR_STORAGE_POOL_RUNNING;
    else
        info->state = VIR_STORAGE_POOL_INACTIVE;
1246 1247 1248
    info->capacity = def->capacity;
    info->allocation = def->allocation;
    info->available = def->available;
1249
    ret = 0;
1250

1251
 cleanup:
1252
    virStoragePoolObjEndAPI(&obj);
1253
    return ret;
1254 1255 1256
}

static char *
1257
storagePoolGetXMLDesc(virStoragePoolPtr pool,
E
Eric Blake 已提交
1258 1259
                      unsigned int flags)
{
1260
    virStoragePoolObjPtr obj;
1261
    virStoragePoolDefPtr def;
1262 1263
    virStoragePoolDefPtr newDef;
    virStoragePoolDefPtr curDef;
1264
    char *ret = NULL;
1265

1266
    virCheckFlags(VIR_STORAGE_XML_INACTIVE, NULL);
E
Eric Blake 已提交
1267

1268
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1269
        return NULL;
1270 1271
    def = virStoragePoolObjGetDef(obj);
    newDef = virStoragePoolObjGetNewDef(obj);
1272

1273
    if (virStoragePoolGetXMLDescEnsureACL(pool->conn, def) < 0)
1274 1275
        goto cleanup;

1276 1277
    if ((flags & VIR_STORAGE_XML_INACTIVE) && newDef)
        curDef = newDef;
1278
    else
1279
        curDef = def;
1280

1281
    ret = virStoragePoolDefFormat(curDef);
1282

1283
 cleanup:
1284
    virStoragePoolObjEndAPI(&obj);
1285
    return ret;
1286 1287 1288
}

static int
1289
storagePoolGetAutostart(virStoragePoolPtr pool,
1290 1291
                        int *autostart)
{
1292
    virStoragePoolObjPtr obj;
1293
    int ret = -1;
1294

1295
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1296
        return -1;
1297

1298 1299
    if (virStoragePoolGetAutostartEnsureACL(pool->conn,
                                            virStoragePoolObjGetDef(obj)) < 0)
1300 1301
        goto cleanup;

1302
    *autostart = virStoragePoolObjIsAutostart(obj) ? 1 : 0;
1303

1304
    ret = 0;
1305

1306
 cleanup:
1307
    virStoragePoolObjEndAPI(&obj);
1308
    return ret;
1309 1310 1311
}

static int
1312
storagePoolSetAutostart(virStoragePoolPtr pool,
1313 1314
                        int autostart)
{
1315
    virStoragePoolObjPtr obj;
1316
    const char *configFile;
1317
    const char *autostartLink;
1318 1319
    bool new_autostart;
    bool cur_autostart;
1320
    int ret = -1;
1321

1322
    if (!(obj = storagePoolObjFindByUUID(pool->uuid, pool->name)))
1323
        goto cleanup;
1324

1325 1326
    if (virStoragePoolSetAutostartEnsureACL(pool->conn,
                                            virStoragePoolObjGetDef(obj)) < 0)
1327 1328
        goto cleanup;

1329
    if (!(configFile = virStoragePoolObjGetConfigFile(obj))) {
1330 1331
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("pool has no config file"));
1332
        goto cleanup;
1333 1334
    }

1335 1336
    autostartLink = virStoragePoolObjGetAutostartLink(obj);

1337 1338 1339 1340
    new_autostart = (autostart != 0);
    cur_autostart = virStoragePoolObjIsAutostart(obj);
    if (cur_autostart != new_autostart) {
        if (new_autostart) {
1341 1342
            if (virFileMakePath(driver->autostartDir) < 0) {
                virReportSystemError(errno,
1343 1344
                                     _("cannot create autostart directory %s"),
                                     driver->autostartDir);
1345 1346
                goto cleanup;
            }
1347

1348
            if (symlink(configFile, autostartLink) < 0) {
1349
                virReportSystemError(errno,
1350
                                     _("Failed to create symlink '%s' to '%s'"),
1351
                                     autostartLink, configFile);
1352 1353 1354
                goto cleanup;
            }
        } else {
1355
            if (autostartLink && unlink(autostartLink) < 0 &&
1356
                errno != ENOENT && errno != ENOTDIR) {
1357
                virReportSystemError(errno,
1358
                                     _("Failed to delete symlink '%s'"),
1359
                                     autostartLink);
1360 1361
                goto cleanup;
            }
1362
        }
1363
        virStoragePoolObjSetAutostart(obj, new_autostart);
1364
    }
1365

1366
    ret = 0;
1367

1368
 cleanup:
1369
    virStoragePoolObjEndAPI(&obj);
1370
    return ret;
1371 1372 1373 1374
}


static int
1375
storagePoolNumOfVolumes(virStoragePoolPtr pool)
1376
{
1377
    virStoragePoolObjPtr obj;
1378
    virStoragePoolDefPtr def;
1379
    int ret = -1;
1380

1381
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1382
        return -1;
1383
    def = virStoragePoolObjGetDef(obj);
1384

1385
    if (virStoragePoolNumOfVolumesEnsureACL(pool->conn, def) < 0)
1386 1387
        goto cleanup;

1388
    if (!virStoragePoolObjIsActive(obj)) {
1389
        virReportError(VIR_ERR_OPERATION_INVALID,
1390
                       _("storage pool '%s' is not active"), def->name);
1391
        goto cleanup;
1392
    }
1393

1394
    ret = virStoragePoolObjNumOfVolumes(obj, pool->conn,
1395
                                        virStoragePoolNumOfVolumesCheckACL);
1396

1397
 cleanup:
1398
    virStoragePoolObjEndAPI(&obj);
1399
    return ret;
1400 1401
}

1402

1403
static int
1404
storagePoolListVolumes(virStoragePoolPtr pool,
1405
                       char **const names,
1406 1407
                       int maxnames)
{
1408
    virStoragePoolObjPtr obj;
1409
    virStoragePoolDefPtr def;
1410
    int n = -1;
1411

1412
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1413
        return -1;
1414
    def = virStoragePoolObjGetDef(obj);
1415

1416
    if (virStoragePoolListVolumesEnsureACL(pool->conn, def) < 0)
1417 1418
        goto cleanup;

1419
    if (!virStoragePoolObjIsActive(obj)) {
1420
        virReportError(VIR_ERR_OPERATION_INVALID,
1421
                       _("storage pool '%s' is not active"), def->name);
1422
        goto cleanup;
1423 1424
    }

1425
    n = virStoragePoolObjVolumeGetNames(obj, pool->conn,
1426 1427
                                        virStoragePoolListVolumesCheckACL,
                                        names, maxnames);
1428
 cleanup:
1429
    virStoragePoolObjEndAPI(&obj);
1430
    return n;
1431 1432
}

1433

1434 1435 1436
static int
storagePoolListAllVolumes(virStoragePoolPtr pool,
                          virStorageVolPtr **vols,
1437 1438
                          unsigned int flags)
{
1439
    virStoragePoolObjPtr obj;
1440
    virStoragePoolDefPtr def;
1441 1442 1443 1444
    int ret = -1;

    virCheckFlags(0, -1);

1445 1446
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
        return -1;
1447
    def = virStoragePoolObjGetDef(obj);
1448

1449
    if (virStoragePoolListAllVolumesEnsureACL(pool->conn, def) < 0)
1450 1451
        goto cleanup;

1452
    if (!virStoragePoolObjIsActive(obj)) {
1453
        virReportError(VIR_ERR_OPERATION_INVALID,
1454
                       _("storage pool '%s' is not active"), def->name);
1455 1456 1457
        goto cleanup;
    }

1458
    ret = virStoragePoolObjVolumeListExport(pool->conn, obj, vols,
1459
                                            virStoragePoolListAllVolumesCheckACL);
1460 1461 1462


 cleanup:
1463
    virStoragePoolObjEndAPI(&obj);
1464 1465 1466

    return ret;
}
1467 1468

static virStorageVolPtr
1469
storageVolLookupByName(virStoragePoolPtr pool,
1470 1471
                       const char *name)
{
1472
    virStoragePoolObjPtr obj;
1473
    virStoragePoolDefPtr def;
1474 1475
    virStorageVolDefPtr voldef;
    virStorageVolPtr vol = NULL;
1476

1477
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1478
        return NULL;
1479
    def = virStoragePoolObjGetDef(obj);
1480

1481
    if (!virStoragePoolObjIsActive(obj)) {
1482
        virReportError(VIR_ERR_OPERATION_INVALID,
1483
                       _("storage pool '%s' is not active"), def->name);
1484
        goto cleanup;
1485 1486
    }

1487
    voldef = virStorageVolDefFindByName(obj, name);
1488

1489
    if (!voldef) {
1490 1491 1492
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"),
                       name);
1493
        goto cleanup;
1494 1495
    }

1496
    if (virStorageVolLookupByNameEnsureACL(pool->conn, def, voldef) < 0)
1497 1498
        goto cleanup;

1499
    vol = virGetStorageVol(pool->conn, def->name, voldef->name,
1500
                           voldef->key, NULL, NULL);
1501

1502
 cleanup:
1503
    virStoragePoolObjEndAPI(&obj);
1504
    return vol;
1505 1506 1507
}


1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518
struct storageVolLookupData {
    const char *key;
    char *cleanpath;
    const char *path;
    virStorageVolDefPtr voldef;
};

static bool
storageVolLookupByKeyCallback(virStoragePoolObjPtr obj,
                              const void *opaque)
{
1519
    struct storageVolLookupData *data = (struct storageVolLookupData *)opaque;
1520 1521 1522 1523 1524 1525 1526 1527

    if (virStoragePoolObjIsActive(obj))
        data->voldef = virStorageVolDefFindByKey(obj, data->key);

    return !!data->voldef;
}


1528
static virStorageVolPtr
1529
storageVolLookupByKey(virConnectPtr conn,
1530 1531
                      const char *key)
{
1532 1533 1534
    virStoragePoolObjPtr obj;
    virStoragePoolDefPtr def;
    struct storageVolLookupData data = {
1535
        .key = key, .voldef = NULL };
1536
    virStorageVolPtr vol = NULL;
1537

1538
    if ((obj = virStoragePoolObjListSearch(driver->pools,
1539 1540
                                           storageVolLookupByKeyCallback,
                                           &data)) && data.voldef) {
1541
        def = virStoragePoolObjGetDef(obj);
1542 1543 1544 1545
        if (virStorageVolLookupByKeyEnsureACL(conn, def, data.voldef) == 0) {
            vol = virGetStorageVol(conn, def->name,
                                   data.voldef->name, data.voldef->key,
                                   NULL, NULL);
1546
        }
1547
        virStoragePoolObjEndAPI(&obj);
1548 1549
    }

1550
    if (!vol)
1551
        virReportError(VIR_ERR_NO_STORAGE_VOL,
1552
                       _("no storage vol with matching key %s"), key);
1553

1554
    return vol;
1555 1556
}

1557 1558 1559 1560 1561

static bool
storageVolLookupByPathCallback(virStoragePoolObjPtr obj,
                               const void *opaque)
{
1562
    struct storageVolLookupData *data = (struct storageVolLookupData *)opaque;
1563
    virStoragePoolDefPtr def;
1564
    VIR_AUTOFREE(char *) stable_path = NULL;
1565 1566 1567 1568 1569 1570

    if (!virStoragePoolObjIsActive(obj))
        return false;

    def = virStoragePoolObjGetDef(obj);

1571
    switch ((virStoragePoolType)def->type) {
1572 1573 1574 1575 1576 1577
        case VIR_STORAGE_POOL_DIR:
        case VIR_STORAGE_POOL_FS:
        case VIR_STORAGE_POOL_NETFS:
        case VIR_STORAGE_POOL_LOGICAL:
        case VIR_STORAGE_POOL_DISK:
        case VIR_STORAGE_POOL_ISCSI:
1578
        case VIR_STORAGE_POOL_ISCSI_DIRECT:
1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607
        case VIR_STORAGE_POOL_SCSI:
        case VIR_STORAGE_POOL_MPATH:
        case VIR_STORAGE_POOL_VSTORAGE:
            stable_path = virStorageBackendStablePath(obj, data->cleanpath,
                                                      false);
            break;

        case VIR_STORAGE_POOL_GLUSTER:
        case VIR_STORAGE_POOL_RBD:
        case VIR_STORAGE_POOL_SHEEPDOG:
        case VIR_STORAGE_POOL_ZFS:
        case VIR_STORAGE_POOL_LAST:
            ignore_value(VIR_STRDUP(stable_path, data->path));
            break;
    }

    /* Don't break the whole lookup process if it fails on
     * getting the stable path for some of the pools. */
    if (!stable_path) {
        VIR_WARN("Failed to get stable path for pool '%s'", def->name);
        return false;
    }

    data->voldef = virStorageVolDefFindByPath(obj, stable_path);

    return !!data->voldef;
}


1608
static virStorageVolPtr
1609
storageVolLookupByPath(virConnectPtr conn,
1610 1611
                       const char *path)
{
1612 1613 1614
    virStoragePoolObjPtr obj;
    virStoragePoolDefPtr def;
    struct storageVolLookupData data = {
1615
        .path = path, .voldef = NULL };
1616
    virStorageVolPtr vol = NULL;
1617

1618
    if (!(data.cleanpath = virFileSanitizePath(path)))
1619
        return NULL;
1620

1621
    if ((obj = virStoragePoolObjListSearch(driver->pools,
1622 1623
                                           storageVolLookupByPathCallback,
                                           &data)) && data.voldef) {
1624
        def = virStoragePoolObjGetDef(obj);
1625

1626
        if (virStorageVolLookupByPathEnsureACL(conn, def, data.voldef) == 0) {
1627
            vol = virGetStorageVol(conn, def->name,
1628
                                   data.voldef->name, data.voldef->key,
1629
                                   NULL, NULL);
1630
        }
1631
        virStoragePoolObjEndAPI(&obj);
1632 1633
    }

1634
    if (!vol) {
1635
        if (STREQ(path, data.cleanpath)) {
1636 1637 1638 1639 1640
            virReportError(VIR_ERR_NO_STORAGE_VOL,
                           _("no storage vol with matching path '%s'"), path);
        } else {
            virReportError(VIR_ERR_NO_STORAGE_VOL,
                           _("no storage vol with matching path '%s' (%s)"),
1641
                           path, data.cleanpath);
1642 1643
        }
    }
1644

1645
    VIR_FREE(data.cleanpath);
1646
    return vol;
1647 1648
}

1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664

static bool
storagePoolLookupByTargetPathCallback(virStoragePoolObjPtr obj,
                                      const void *opaque)
{
    const char *path = opaque;
    virStoragePoolDefPtr def;

    if (!virStoragePoolObjIsActive(obj))
        return false;

    def = virStoragePoolObjGetDef(obj);
    return STREQ(path, def->target.path);
}


1665 1666 1667 1668
virStoragePoolPtr
storagePoolLookupByTargetPath(virConnectPtr conn,
                              const char *path)
{
1669 1670
    virStoragePoolObjPtr obj;
    virStoragePoolDefPtr def;
1671
    virStoragePoolPtr pool = NULL;
1672
    VIR_AUTOFREE(char *) cleanpath = NULL;
1673 1674 1675 1676 1677

    cleanpath = virFileSanitizePath(path);
    if (!cleanpath)
        return NULL;

1678
    if ((obj = virStoragePoolObjListSearch(driver->pools,
1679
                                           storagePoolLookupByTargetPathCallback,
1680
                                           cleanpath))) {
1681
        def = virStoragePoolObjGetDef(obj);
1682
        if (virStoragePoolLookupByTargetPathEnsureACL(conn, def) < 0)
1683
            return NULL;
1684

1685
        pool = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL);
1686
        virStoragePoolObjEndAPI(&obj);
1687 1688
    }

1689
    if (!pool) {
1690 1691 1692 1693 1694 1695 1696 1697 1698
        if (STREQ(path, cleanpath)) {
            virReportError(VIR_ERR_NO_STORAGE_POOL,
                           _("no storage pool with matching target path '%s'"),
                           path);
        } else {
            virReportError(VIR_ERR_NO_STORAGE_POOL,
                           _("no storage pool with matching target path '%s' (%s)"),
                           path, cleanpath);
        }
1699 1700
    }

1701
    return pool;
1702 1703
}

1704

1705
static int
1706
storageVolDeleteInternal(virStorageBackendPtr backend,
1707 1708
                         virStoragePoolObjPtr obj,
                         virStorageVolDefPtr voldef,
1709 1710 1711
                         unsigned int flags,
                         bool updateMeta)
{
1712
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj);
1713 1714 1715 1716 1717 1718 1719 1720 1721
    int ret = -1;

    if (!backend->deleteVol) {
        virReportError(VIR_ERR_NO_SUPPORT,
                       "%s", _("storage pool does not support vol deletion"));

        goto cleanup;
    }

1722
    if (backend->deleteVol(obj, voldef, flags) < 0)
1723 1724
        goto cleanup;

1725 1726 1727 1728 1729 1730 1731 1732
    /* The disk backend updated the pool data including removing the
     * voldef from the pool (for both the deleteVol and the createVol
     * failure path. */
    if (def->type == VIR_STORAGE_POOL_DISK) {
        ret = 0;
        goto cleanup;
    }

1733
    /* Update pool metadata - don't update meta data from error paths
1734 1735
     * in this module since the allocation/available weren't adjusted yet.
     * Ignore the disk backend since it updates the pool values.
1736 1737
     */
    if (updateMeta) {
1738 1739
        def->allocation -= voldef->target.allocation;
        def->available += voldef->target.allocation;
1740 1741
    }

1742
    virStoragePoolObjRemoveVol(obj, voldef);
1743 1744 1745 1746 1747 1748 1749
    ret = 0;

 cleanup:
    return ret;
}


1750
static virStorageVolDefPtr
1751 1752
virStorageVolDefFromVol(virStorageVolPtr vol,
                        virStoragePoolObjPtr *obj,
1753
                        virStorageBackendPtr *backend)
1754
{
1755
    virStorageVolDefPtr voldef = NULL;
1756
    virStoragePoolDefPtr def;
1757

1758
    if (!(*obj = storagePoolObjFindByName(vol->pool)))
1759
        return NULL;
1760
    def = virStoragePoolObjGetDef(*obj);
1761

1762
    if (!virStoragePoolObjIsActive(*obj)) {
1763
        virReportError(VIR_ERR_OPERATION_INVALID,
1764
                       _("storage pool '%s' is not active"),
1765
                       def->name);
1766
        goto error;
1767 1768
    }

1769
    if (!(voldef = virStorageVolDefFindByName(*obj, vol->name))) {
1770 1771
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"),
1772
                       vol->name);
1773
        goto error;
1774 1775
    }

1776
    if (backend) {
1777
        if (!(*backend = virStorageBackendForType(def->type)))
1778 1779 1780
            goto error;
    }

1781
    return voldef;
1782 1783

 error:
1784
    virStoragePoolObjEndAPI(obj);
1785 1786 1787 1788 1789 1790

    return NULL;
}


static int
1791
storageVolDelete(virStorageVolPtr vol,
1792 1793
                 unsigned int flags)
{
1794
    virStoragePoolObjPtr obj;
1795
    virStorageBackendPtr backend;
1796
    virStorageVolDefPtr voldef = NULL;
1797 1798
    int ret = -1;

1799
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend)))
1800 1801
        return -1;

1802 1803
    if (virStorageVolDeleteEnsureACL(vol->conn, virStoragePoolObjGetDef(obj),
                                     voldef) < 0)
1804 1805
        goto cleanup;

1806
    if (voldef->in_use) {
1807 1808
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still in use."),
1809
                       voldef->name);
1810 1811 1812
        goto cleanup;
    }

1813
    if (voldef->building) {
1814 1815
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
1816
                       voldef->name);
1817 1818 1819
        goto cleanup;
    }

1820
    if (storageVolDeleteInternal(backend, obj, voldef, flags, true) < 0)
1821 1822 1823 1824
        goto cleanup;

    ret = 0;

1825
 cleanup:
1826
    virStoragePoolObjEndAPI(&obj);
1827 1828 1829
    return ret;
}

1830

1831
static virStorageVolPtr
1832
storageVolCreateXML(virStoragePoolPtr pool,
1833 1834
                    const char *xmldesc,
                    unsigned int flags)
E
Eric Blake 已提交
1835
{
1836
    virStoragePoolObjPtr obj;
1837
    virStoragePoolDefPtr def;
1838
    virStorageBackendPtr backend;
1839
    virStorageVolPtr vol = NULL, newvol = NULL;
1840
    VIR_AUTOPTR(virStorageVolDef) voldef = NULL;
1841

1842
    virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, NULL);
E
Eric Blake 已提交
1843

1844
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1845
        return NULL;
1846
    def = virStoragePoolObjGetDef(obj);
1847

1848
    if (!virStoragePoolObjIsActive(obj)) {
1849
        virReportError(VIR_ERR_OPERATION_INVALID,
1850
                       _("storage pool '%s' is not active"), def->name);
1851
        goto cleanup;
1852 1853
    }

1854
    if ((backend = virStorageBackendForType(def->type)) == NULL)
1855
        goto cleanup;
1856

1857
    voldef = virStorageVolDefParseString(def, xmldesc,
1858
                                         VIR_VOL_XML_PARSE_OPT_CAPACITY);
1859
    if (voldef == NULL)
1860
        goto cleanup;
1861

1862 1863 1864 1865 1866 1867 1868
    if (!voldef->target.capacity && !backend->buildVol) {
        virReportError(VIR_ERR_NO_SUPPORT,
                       "%s", _("volume capacity required for this "
                               "storage pool"));
        goto cleanup;
    }

1869
    if (virStorageVolCreateXMLEnsureACL(pool->conn, def, voldef) < 0)
1870 1871
        goto cleanup;

1872
    if (virStorageVolDefFindByName(obj, voldef->name)) {
1873
        virReportError(VIR_ERR_STORAGE_VOL_EXIST,
1874
                       _("'%s'"), voldef->name);
1875
        goto cleanup;
1876 1877 1878
    }

    if (!backend->createVol) {
1879 1880 1881
        virReportError(VIR_ERR_NO_SUPPORT,
                       "%s", _("storage pool does not support volume "
                               "creation"));
1882
        goto cleanup;
1883 1884
    }

1885 1886 1887
    /* Wipe any key the user may have suggested, as volume creation
     * will generate the canonical key.  */
    VIR_FREE(voldef->key);
1888
    if (backend->createVol(obj, voldef) < 0)
1889
        goto cleanup;
1890

1891
    if (!(newvol = virGetStorageVol(pool->conn, def->name, voldef->name,
1892
                                    voldef->key, NULL, NULL)))
1893 1894
        goto cleanup;

1895 1896 1897
    /* NB: Upon success voldef "owned" by storage pool for deletion purposes */
    if (virStoragePoolObjAddVol(obj, voldef) < 0)
        goto cleanup;
1898

1899 1900
    if (backend->buildVol) {
        int buildret;
1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912
        virStorageVolDefPtr buildvoldef = NULL;

        if (VIR_ALLOC(buildvoldef) < 0) {
            voldef = NULL;
            goto cleanup;
        }

        /* Make a shallow copy of the 'defined' volume definition, since the
         * original allocation value will change as the user polls 'info',
         * but we only need the initial requested values
         */
        memcpy(buildvoldef, voldef, sizeof(*voldef));
1913 1914

        /* Drop the pool lock during volume allocation */
1915
        virStoragePoolObjIncrAsyncjobs(obj);
1916
        voldef->building = true;
1917
        virObjectUnlock(obj);
1918

1919
        buildret = backend->buildVol(obj, buildvoldef, flags);
1920

1921 1922
        VIR_FREE(buildvoldef);

1923
        virObjectLock(obj);
1924

1925
        voldef->building = false;
1926
        virStoragePoolObjDecrAsyncjobs(obj);
1927

1928
        if (buildret < 0) {
1929
            /* buildVol handles deleting volume on failure */
1930
            virStoragePoolObjRemoveVol(obj, voldef);
1931
            voldef = NULL;
1932
            goto cleanup;
1933
        }
1934

1935
    }
1936

1937
    if (backend->refreshVol &&
1938 1939
        backend->refreshVol(obj, voldef) < 0) {
        storageVolDeleteInternal(backend, obj, voldef,
1940 1941
                                 0, false);
        voldef = NULL;
1942
        goto cleanup;
1943
    }
1944

1945 1946 1947
    /* Update pool metadata ignoring the disk backend since
     * it updates the pool values.
     */
1948 1949 1950
    if (def->type != VIR_STORAGE_POOL_DISK) {
        def->allocation += voldef->target.allocation;
        def->available -= voldef->target.allocation;
1951
    }
1952

1953
    VIR_INFO("Creating volume '%s' in storage pool '%s'",
1954
             newvol->name, def->name);
1955
    VIR_STEAL_PTR(vol, newvol);
1956
    voldef = NULL;
1957

1958
 cleanup:
1959
    virObjectUnref(newvol);
1960
    virStoragePoolObjEndAPI(&obj);
1961
    return vol;
1962 1963
}

1964
static virStorageVolPtr
1965
storageVolCreateXMLFrom(virStoragePoolPtr pool,
1966
                        const char *xmldesc,
1967
                        virStorageVolPtr volsrc,
1968
                        unsigned int flags)
E
Eric Blake 已提交
1969
{
1970
    virStoragePoolObjPtr obj;
1971
    virStoragePoolDefPtr def;
1972
    virStoragePoolObjPtr objsrc = NULL;
1973
    virStorageBackendPtr backend;
1974 1975 1976 1977
    virStorageVolDefPtr voldefsrc = NULL;
    virStorageVolDefPtr shadowvol = NULL;
    virStorageVolPtr newvol = NULL;
    virStorageVolPtr vol = NULL;
1978
    int buildret;
1979
    VIR_AUTOPTR(virStorageVolDef) voldef = NULL;
1980

1981 1982 1983
    virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA |
                  VIR_STORAGE_VOL_CREATE_REFLINK,
                  NULL);
E
Eric Blake 已提交
1984

1985
    obj = virStoragePoolObjFindByUUID(driver->pools, pool->uuid);
1986
    if (obj && STRNEQ(pool->name, volsrc->pool)) {
1987
        virObjectUnlock(obj);
1988
        objsrc = virStoragePoolObjFindByName(driver->pools, volsrc->pool);
1989
        virObjectLock(obj);
1990
    }
1991
    if (!obj) {
1992
        char uuidstr[VIR_UUID_STRING_BUFLEN];
1993
        virUUIDFormat(pool->uuid, uuidstr);
1994
        virReportError(VIR_ERR_NO_STORAGE_POOL,
1995
                       _("no storage pool with matching uuid '%s' (%s)"),
1996
                       uuidstr, pool->name);
1997 1998
        goto cleanup;
    }
1999
    def = virStoragePoolObjGetDef(obj);
2000

2001
    if (STRNEQ(pool->name, volsrc->pool) && !objsrc) {
2002 2003
        virReportError(VIR_ERR_NO_STORAGE_POOL,
                       _("no storage pool with matching name '%s'"),
2004
                       volsrc->pool);
2005 2006 2007
        goto cleanup;
    }

2008
    if (!virStoragePoolObjIsActive(obj)) {
2009
        virReportError(VIR_ERR_OPERATION_INVALID,
2010
                       _("storage pool '%s' is not active"), def->name);
2011 2012 2013
        goto cleanup;
    }

2014
    if (objsrc && !virStoragePoolObjIsActive(objsrc)) {
2015
        virStoragePoolDefPtr objsrcdef = virStoragePoolObjGetDef(objsrc);
2016
        virReportError(VIR_ERR_OPERATION_INVALID,
2017
                       _("storage pool '%s' is not active"),
2018
                       objsrcdef->name);
2019 2020 2021
        goto cleanup;
    }

2022
    if ((backend = virStorageBackendForType(def->type)) == NULL)
2023 2024
        goto cleanup;

2025 2026 2027
    voldefsrc = virStorageVolDefFindByName(objsrc ?
                                           objsrc : obj, volsrc->name);
    if (!voldefsrc) {
2028 2029
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"),
2030
                       volsrc->name);
2031 2032 2033
        goto cleanup;
    }

2034
    voldef = virStorageVolDefParseString(def, xmldesc,
2035
                                         VIR_VOL_XML_PARSE_NO_CAPACITY);
2036
    if (voldef == NULL)
2037 2038
        goto cleanup;

2039
    if (virStorageVolCreateXMLFromEnsureACL(pool->conn, def, voldef) < 0)
2040 2041
        goto cleanup;

2042
    if (virStorageVolDefFindByName(obj, voldef->name)) {
2043 2044
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("storage volume name '%s' already in use."),
2045
                       voldef->name);
2046 2047 2048
        goto cleanup;
    }

2049 2050
    /* Use the original volume's capacity in case the new capacity
     * is less than that, or it was omitted */
2051 2052
    if (voldef->target.capacity < voldefsrc->target.capacity)
        voldef->target.capacity = voldefsrc->target.capacity;
2053

2054 2055 2056 2057
    /* If the allocation was not provided in the XML, then use capacity
     * as it's specifically documented "If omitted when creating a volume,
     * the  volume will be fully allocated at time of creation.". This
     * is especially important for logical volume creation. */
2058 2059
    if (!voldef->target.has_allocation)
        voldef->target.allocation = voldef->target.capacity;
2060

2061
    if (!backend->buildVolFrom) {
2062
        virReportError(VIR_ERR_NO_SUPPORT,
2063 2064
                       "%s", _("storage pool does not support"
                               " volume creation from an existing volume"));
2065 2066 2067
        goto cleanup;
    }

2068
    if (voldefsrc->building) {
2069 2070
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
2071
                       voldefsrc->name);
2072 2073 2074 2075
        goto cleanup;
    }

    if (backend->refreshVol &&
2076
        backend->refreshVol(obj, voldefsrc) < 0)
2077 2078
        goto cleanup;

2079 2080 2081
    /* 'Define' the new volume so we get async progress reporting.
     * Wipe any key the user may have suggested, as volume creation
     * will generate the canonical key.  */
2082
    VIR_FREE(voldef->key);
2083
    if (backend->createVol(obj, voldef) < 0)
2084 2085
        goto cleanup;

2086 2087 2088 2089 2090 2091 2092
    /* Make a shallow copy of the 'defined' volume definition, since the
     * original allocation value will change as the user polls 'info',
     * but we only need the initial requested values
     */
    if (VIR_ALLOC(shadowvol) < 0)
        goto cleanup;

2093
    memcpy(shadowvol, voldef, sizeof(*voldef));
2094

2095
    if (!(newvol = virGetStorageVol(pool->conn, def->name, voldef->name,
2096 2097 2098 2099 2100
                                    voldef->key, NULL, NULL)))
        goto cleanup;

    /* NB: Upon success voldef "owned" by storage pool for deletion purposes */
    if (virStoragePoolObjAddVol(obj, voldef) < 0)
2101
        goto cleanup;
2102 2103

    /* Drop the pool lock during volume allocation */
2104
    virStoragePoolObjIncrAsyncjobs(obj);
2105 2106
    voldef->building = true;
    voldefsrc->in_use++;
2107
    virObjectUnlock(obj);
2108

2109
    if (objsrc) {
2110
        virStoragePoolObjIncrAsyncjobs(objsrc);
2111
        virObjectUnlock(objsrc);
2112 2113
    }

2114
    buildret = backend->buildVolFrom(obj, shadowvol, voldefsrc, flags);
2115

2116
    virObjectLock(obj);
2117
    if (objsrc)
2118
        virObjectLock(objsrc);
2119

2120 2121
    voldefsrc->in_use--;
    voldef->building = false;
2122
    virStoragePoolObjDecrAsyncjobs(obj);
2123

2124
    if (objsrc) {
2125
        virStoragePoolObjDecrAsyncjobs(objsrc);
2126
        virStoragePoolObjEndAPI(&objsrc);
2127 2128
    }

2129 2130
    if (buildret < 0 ||
        (backend->refreshVol &&
2131 2132
         backend->refreshVol(obj, voldef) < 0)) {
        storageVolDeleteInternal(backend, obj, voldef, 0, false);
2133
        voldef = NULL;
2134 2135 2136
        goto cleanup;
    }

2137 2138 2139
    /* Updating pool metadata ignoring the disk backend since
     * it updates the pool values
     */
2140 2141 2142
    if (def->type != VIR_STORAGE_POOL_DISK) {
        def->allocation += voldef->target.allocation;
        def->available -= voldef->target.allocation;
2143
    }
2144

2145
    VIR_INFO("Creating volume '%s' in storage pool '%s'",
2146
             newvol->name, def->name);
2147
    VIR_STEAL_PTR(vol, newvol);
2148
    voldef = NULL;
2149

2150
 cleanup:
2151
    virObjectUnref(newvol);
2152
    VIR_FREE(shadowvol);
2153 2154
    virStoragePoolObjEndAPI(&obj);
    virStoragePoolObjEndAPI(&objsrc);
2155
    return vol;
2156 2157
}

2158

2159
static int
2160
storageVolDownload(virStorageVolPtr vol,
2161 2162 2163 2164
                   virStreamPtr stream,
                   unsigned long long offset,
                   unsigned long long length,
                   unsigned int flags)
2165
{
2166
    virStorageBackendPtr backend;
2167 2168
    virStoragePoolObjPtr obj = NULL;
    virStorageVolDefPtr voldef = NULL;
2169 2170
    int ret = -1;

2171
    virCheckFlags(VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM, -1);
2172

2173
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend)))
2174
        return -1;
2175

2176 2177
    if (virStorageVolDownloadEnsureACL(vol->conn, virStoragePoolObjGetDef(obj),
                                       voldef) < 0)
2178
        goto cleanup;
2179

2180
    if (voldef->building) {
2181 2182
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
2183
                       voldef->name);
2184
        goto cleanup;
2185 2186
    }

2187 2188 2189
    if (!backend->downloadVol) {
        virReportError(VIR_ERR_NO_SUPPORT, "%s",
                       _("storage pool doesn't support volume download"));
2190
        goto cleanup;
2191
    }
2192

2193 2194
    virStoragePoolObjIncrAsyncjobs(obj);
    voldef->in_use++;
2195
    virObjectUnlock(obj);
2196 2197 2198

    ret = backend->downloadVol(obj, voldef, stream, offset, length, flags);

2199
    virObjectLock(obj);
2200 2201
    voldef->in_use--;
    virStoragePoolObjDecrAsyncjobs(obj);
2202

2203
 cleanup:
2204
    virStoragePoolObjEndAPI(&obj);
2205 2206 2207 2208 2209

    return ret;
}


2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223
/**
 * Frees opaque data.
 *
 * @opaque Data to be freed.
 */
static void
virStorageVolPoolRefreshDataFree(void *opaque)
{
    virStorageVolStreamInfoPtr cbdata = opaque;

    VIR_FREE(cbdata->pool_name);
    VIR_FREE(cbdata);
}

2224 2225 2226
static int
virStorageBackendPloopRestoreDesc(char *path)
{
2227
    VIR_AUTOPTR(virCommand) cmd = NULL;
2228 2229
    VIR_AUTOFREE(char *) refresh_tool = NULL;
    VIR_AUTOFREE(char *) desc = NULL;
2230 2231

    if (virAsprintf(&desc, "%s/DiskDescriptor.xml", path) < 0)
2232
        return -1;
2233 2234 2235 2236

    if (virFileRemove(desc, 0, 0) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("refresh ploop failed:"
Y
Yuri Chornoivan 已提交
2237
                         " unable to delete DiskDescriptor.xml"));
2238
        return -1;
2239 2240 2241 2242 2243 2244
    }

    refresh_tool = virFindFileInPath("ploop");
    if (!refresh_tool) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("unable to find ploop, please install ploop tools"));
2245
        return -1;
2246 2247 2248 2249 2250
    }

    cmd = virCommandNewArgList(refresh_tool, "restore-descriptor",
                               path, NULL);
    virCommandAddArgFormat(cmd, "%s/root.hds", path);
2251
    return virCommandRun(cmd, NULL);
2252 2253 2254 2255
}



2256 2257 2258 2259 2260 2261 2262 2263 2264 2265
/**
 * Thread to handle the pool refresh
 *
 * @st Pointer to stream being closed.
 * @opaque Domain's device information structure.
 */
static void
virStorageVolPoolRefreshThread(void *opaque)
{
    virStorageVolStreamInfoPtr cbdata = opaque;
2266
    virStoragePoolObjPtr obj = NULL;
2267
    virStoragePoolDefPtr def;
2268
    virStorageBackendPtr backend;
2269
    virObjectEventPtr event = NULL;
2270

2271 2272 2273 2274
    if (cbdata->vol_path) {
        if (virStorageBackendPloopRestoreDesc(cbdata->vol_path) < 0)
            goto cleanup;
    }
2275
    if (!(obj = virStoragePoolObjFindByName(driver->pools,
2276
                                            cbdata->pool_name)))
2277
        goto cleanup;
2278
    def = virStoragePoolObjGetDef(obj);
2279

2280 2281 2282 2283 2284 2285 2286
    /* If some thread is building a new volume in the pool, then we cannot
     * clear out all vols and refresh the pool. So we'll just pass. */
    if (virStoragePoolObjGetAsyncjobs(obj) > 0) {
        VIR_DEBUG("Asyncjob in process, cannot refresh storage pool");
        goto cleanup;
    }

2287
    if (!(backend = virStorageBackendForType(def->type)))
2288 2289
        goto cleanup;

2290
    if (storagePoolRefreshImpl(backend, obj, NULL) < 0)
2291 2292
        VIR_DEBUG("Failed to refresh storage pool");

2293
    event = virStoragePoolEventRefreshNew(def->name, def->uuid);
2294

2295
 cleanup:
2296
    virObjectEventStateQueue(driver->storageEventState, event);
2297
    virStoragePoolObjEndAPI(&obj);
2298 2299 2300 2301 2302 2303 2304 2305
    virStorageVolPoolRefreshDataFree(cbdata);
}

/**
 * Callback being called if a FDstream is closed. Will spin off a thread
 * to perform a pool refresh.
 *
 * @st Pointer to stream being closed.
C
Chen Hanxiao 已提交
2306
 * @opaque Buffer to hold the pool name to be refreshed
2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325
 */
static void
virStorageVolFDStreamCloseCb(virStreamPtr st ATTRIBUTE_UNUSED,
                             void *opaque)
{
    virThread thread;

    if (virThreadCreate(&thread, false, virStorageVolPoolRefreshThread,
                        opaque) < 0) {
        /* Not much else can be done */
        VIR_ERROR(_("Failed to create thread to handle pool refresh"));
        goto error;
    }
    return; /* Thread will free opaque data */

 error:
    virStorageVolPoolRefreshDataFree(opaque);
}

2326
static int
2327
storageVolUpload(virStorageVolPtr vol,
2328 2329 2330 2331
                 virStreamPtr stream,
                 unsigned long long offset,
                 unsigned long long length,
                 unsigned int flags)
2332
{
2333
    virStorageBackendPtr backend;
2334
    virStoragePoolObjPtr obj = NULL;
2335
    virStoragePoolDefPtr def;
2336
    virStorageVolDefPtr voldef = NULL;
2337
    virStorageVolStreamInfoPtr cbdata = NULL;
2338
    int rc;
2339 2340
    int ret = -1;

2341
    virCheckFlags(VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM, -1);
2342

2343
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend)))
2344
        return -1;
2345
    def = virStoragePoolObjGetDef(obj);
2346

2347
    if (virStorageVolUploadEnsureACL(vol->conn, def, voldef) < 0)
2348
        goto cleanup;
2349

2350
    if (voldef->in_use) {
2351 2352
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still in use."),
2353
                       voldef->name);
2354 2355 2356
        goto cleanup;
    }

2357
    if (voldef->building) {
2358 2359
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
2360
                       voldef->name);
2361
        goto cleanup;
2362 2363
    }

2364 2365 2366
    if (!backend->uploadVol) {
        virReportError(VIR_ERR_NO_SUPPORT, "%s",
                       _("storage pool doesn't support volume upload"));
2367
        goto cleanup;
2368
    }
2369

2370
    /* Use the callback routine in order to
2371 2372 2373 2374 2375
     * refresh the pool after the volume upload stream closes. This way
     * we make sure the volume and pool data are refreshed without user
     * interaction and we can just lookup the backend in the callback
     * routine in order to call the refresh API.
     */
2376
    if (VIR_ALLOC(cbdata) < 0 ||
2377
        VIR_STRDUP(cbdata->pool_name, def->name) < 0)
2378
        goto cleanup;
2379 2380
    if (voldef->type == VIR_STORAGE_VOL_PLOOP &&
        VIR_STRDUP(cbdata->vol_path, voldef->target.path) < 0)
2381
        goto cleanup;
2382

2383 2384
    virStoragePoolObjIncrAsyncjobs(obj);
    voldef->in_use++;
2385
    virObjectUnlock(obj);
2386 2387 2388

    rc = backend->uploadVol(obj, voldef, stream, offset, length, flags);

2389
    virObjectLock(obj);
2390 2391 2392 2393
    voldef->in_use--;
    virStoragePoolObjDecrAsyncjobs(obj);

    if (rc < 0)
2394
        goto cleanup;
2395

2396 2397 2398
    /* Add cleanup callback - call after uploadVol since the stream
     * is then fully set up
     */
C
Cole Robinson 已提交
2399 2400 2401 2402
    virFDStreamSetInternalCloseCb(stream,
                                  virStorageVolFDStreamCloseCb,
                                  cbdata, NULL);
    cbdata = NULL;
2403
    ret = 0;
2404
 cleanup:
2405
    virStoragePoolObjEndAPI(&obj);
2406 2407
    if (cbdata)
        virStorageVolPoolRefreshDataFree(cbdata);
2408 2409 2410 2411

    return ret;
}

2412
static int
2413
storageVolResize(virStorageVolPtr vol,
2414 2415
                 unsigned long long capacity,
                 unsigned int flags)
2416 2417
{
    virStorageBackendPtr backend;
2418
    virStoragePoolObjPtr obj = NULL;
2419
    virStoragePoolDefPtr def;
2420
    virStorageVolDefPtr voldef = NULL;
2421
    unsigned long long abs_capacity, delta = 0;
2422 2423
    int ret = -1;

2424
    virCheckFlags(VIR_STORAGE_VOL_RESIZE_ALLOCATE |
2425 2426
                  VIR_STORAGE_VOL_RESIZE_DELTA |
                  VIR_STORAGE_VOL_RESIZE_SHRINK, -1);
2427

2428
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend)))
2429
        return -1;
2430
    def = virStoragePoolObjGetDef(obj);
2431

2432
    if (virStorageVolResizeEnsureACL(vol->conn, def, voldef) < 0)
2433
        goto cleanup;
2434

2435
    if (voldef->in_use) {
2436 2437
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still in use."),
2438
                       voldef->name);
2439 2440 2441
        goto cleanup;
    }

2442
    if (voldef->building) {
2443 2444
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
2445
                       voldef->name);
2446
        goto cleanup;
2447
    }
2448

2449
    if (flags & VIR_STORAGE_VOL_RESIZE_DELTA) {
2450
        if (flags & VIR_STORAGE_VOL_RESIZE_SHRINK)
2451
            abs_capacity = voldef->target.capacity - MIN(capacity, voldef->target.capacity);
2452
        else
2453
            abs_capacity = voldef->target.capacity + capacity;
2454 2455 2456 2457 2458
        flags &= ~VIR_STORAGE_VOL_RESIZE_DELTA;
    } else {
        abs_capacity = capacity;
    }

2459
    if (abs_capacity < voldef->target.allocation) {
2460
        virReportError(VIR_ERR_INVALID_ARG, "%s",
2461 2462
                       _("can't shrink capacity below "
                         "existing allocation"));
2463
        goto cleanup;
2464 2465
    }

2466
    if (abs_capacity < voldef->target.capacity &&
2467 2468 2469
        !(flags & VIR_STORAGE_VOL_RESIZE_SHRINK)) {
        virReportError(VIR_ERR_INVALID_ARG, "%s",
                       _("Can't shrink capacity below current "
2470
                         "capacity unless shrink flag explicitly specified"));
2471
        goto cleanup;
2472 2473
    }

2474
    if (flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE)
2475
        delta = abs_capacity - voldef->target.allocation;
2476

2477
    if (delta > def->available) {
2478
        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
2479
                       _("Not enough space left in storage pool"));
2480
        goto cleanup;
2481 2482 2483
    }

    if (!backend->resizeVol) {
2484
        virReportError(VIR_ERR_NO_SUPPORT, "%s",
2485 2486
                       _("storage pool does not support changing of "
                         "volume capacity"));
2487
        goto cleanup;
2488 2489
    }

2490
    if (backend->resizeVol(obj, voldef, abs_capacity, flags) < 0)
2491
        goto cleanup;
2492

2493
    voldef->target.capacity = abs_capacity;
2494 2495 2496 2497 2498
    /* Only update the allocation and pool values if we actually did the
     * allocation; otherwise, this is akin to a create operation with a
     * capacity value different and potentially much larger than available
     */
    if (flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE) {
2499
        voldef->target.allocation = abs_capacity;
2500 2501
        def->allocation += delta;
        def->available -= delta;
2502
    }
2503

O
Osier Yang 已提交
2504
    ret = 0;
2505

2506
 cleanup:
2507
    virStoragePoolObjEndAPI(&obj);
2508 2509 2510

    return ret;
}
2511

2512 2513

static int
2514
storageVolWipePattern(virStorageVolPtr vol,
2515 2516
                      unsigned int algorithm,
                      unsigned int flags)
2517
{
2518
    virStorageBackendPtr backend;
2519 2520
    virStoragePoolObjPtr obj = NULL;
    virStorageVolDefPtr voldef = NULL;
2521
    int rc;
2522 2523
    int ret = -1;

2524
    virCheckFlags(0, -1);
2525

2526
    if (algorithm >= VIR_STORAGE_VOL_WIPE_ALG_LAST) {
2527 2528 2529
        virReportError(VIR_ERR_INVALID_ARG,
                       _("wiping algorithm %d not supported"),
                       algorithm);
2530 2531 2532
        return -1;
    }

2533
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend)))
2534
        return -1;
2535

2536 2537 2538
    if (virStorageVolWipePatternEnsureACL(vol->conn,
                                          virStoragePoolObjGetDef(obj),
                                          voldef) < 0)
2539
        goto cleanup;
2540

2541
    if (voldef->in_use) {
2542 2543
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still in use."),
2544
                       voldef->name);
2545 2546 2547
        goto cleanup;
    }

2548
    if (voldef->building) {
2549 2550
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
2551
                       voldef->name);
2552
        goto cleanup;
2553 2554
    }

2555 2556 2557
    if (!backend->wipeVol) {
        virReportError(VIR_ERR_NO_SUPPORT, "%s",
                       _("storage pool doesn't support volume wiping"));
2558
        goto cleanup;
2559
    }
2560

2561 2562
    virStoragePoolObjIncrAsyncjobs(obj);
    voldef->in_use++;
2563
    virObjectUnlock(obj);
2564 2565 2566

    rc = backend->wipeVol(obj, voldef, algorithm, flags);

2567
    virObjectLock(obj);
2568 2569 2570 2571
    voldef->in_use--;
    virStoragePoolObjDecrAsyncjobs(obj);

    if (rc < 0)
2572 2573
        goto cleanup;

2574 2575 2576 2577 2578 2579 2580 2581 2582 2583
    /* For local volumes, Instead of using the refreshVol, since
     * much changes on the target volume, let's update using the
     * same function as refreshPool would use when it discovers a
     * volume. The only failure to capture is -1, we can ignore
     * -2. */
    if ((backend->type == VIR_STORAGE_POOL_DIR ||
         backend->type == VIR_STORAGE_POOL_FS ||
         backend->type == VIR_STORAGE_POOL_NETFS ||
         backend->type == VIR_STORAGE_POOL_VSTORAGE) &&
        virStorageBackendRefreshVolTargetUpdate(voldef) == -1)
2584 2585 2586
        goto cleanup;

    ret = 0;
2587

2588
 cleanup:
2589
    virStoragePoolObjEndAPI(&obj);
2590 2591 2592 2593

    return ret;
}

2594
static int
2595
storageVolWipe(virStorageVolPtr vol,
2596
               unsigned int flags)
2597
{
2598
    return storageVolWipePattern(vol, VIR_STORAGE_VOL_WIPE_ALG_ZERO, flags);
2599 2600
}

2601 2602

static int
2603
storageVolGetInfoFlags(virStorageVolPtr vol,
2604 2605
                       virStorageVolInfoPtr info,
                       unsigned int flags)
2606
{
2607
    virStoragePoolObjPtr obj;
2608
    virStorageBackendPtr backend;
2609
    virStorageVolDefPtr voldef;
2610
    int ret = -1;
2611

2612 2613
    virCheckFlags(VIR_STORAGE_VOL_GET_PHYSICAL, -1);

2614
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend)))
2615
        return -1;
2616

2617 2618 2619
    if (virStorageVolGetInfoFlagsEnsureACL(vol->conn,
                                           virStoragePoolObjGetDef(obj),
                                           voldef) < 0)
2620 2621
        goto cleanup;

2622
    if (backend->refreshVol &&
2623
        backend->refreshVol(obj, voldef) < 0)
2624
        goto cleanup;
2625 2626

    memset(info, 0, sizeof(*info));
2627 2628
    info->type = voldef->type;
    info->capacity = voldef->target.capacity;
2629
    if (flags & VIR_STORAGE_VOL_GET_PHYSICAL)
2630
        info->allocation = voldef->target.physical;
2631
    else
2632
        info->allocation = voldef->target.allocation;
2633
    ret = 0;
2634

2635
 cleanup:
2636
    virStoragePoolObjEndAPI(&obj);
2637
    return ret;
2638 2639
}

2640 2641

static int
2642
storageVolGetInfo(virStorageVolPtr vol,
2643 2644
                  virStorageVolInfoPtr info)
{
2645
    return storageVolGetInfoFlags(vol, info, 0);
2646 2647 2648
}


2649
static char *
2650
storageVolGetXMLDesc(virStorageVolPtr vol,
2651
                     unsigned int flags)
E
Eric Blake 已提交
2652
{
2653
    virStoragePoolObjPtr obj;
2654
    virStoragePoolDefPtr def;
2655
    virStorageBackendPtr backend;
2656
    virStorageVolDefPtr voldef;
2657
    char *ret = NULL;
2658

E
Eric Blake 已提交
2659 2660
    virCheckFlags(0, NULL);

2661
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend)))
2662
        return NULL;
2663
    def = virStoragePoolObjGetDef(obj);
2664

2665
    if (virStorageVolGetXMLDescEnsureACL(vol->conn, def, voldef) < 0)
2666 2667
        goto cleanup;

2668
    if (backend->refreshVol &&
2669
        backend->refreshVol(obj, voldef) < 0)
2670
        goto cleanup;
2671

2672
    ret = virStorageVolDefFormat(def, voldef);
2673

2674
 cleanup:
2675
    virStoragePoolObjEndAPI(&obj);
2676

2677
    return ret;
2678 2679 2680
}

static char *
2681
storageVolGetPath(virStorageVolPtr vol)
2682
{
2683 2684
    virStoragePoolObjPtr obj;
    virStorageVolDefPtr voldef;
2685
    char *ret = NULL;
2686

2687
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, NULL)))
2688
        return NULL;
2689

2690 2691
    if (virStorageVolGetPathEnsureACL(vol->conn, virStoragePoolObjGetDef(obj),
                                      voldef) < 0)
2692 2693
        goto cleanup;

2694
    ignore_value(VIR_STRDUP(ret, voldef->target.path));
2695

2696
 cleanup:
2697
    virStoragePoolObjEndAPI(&obj);
2698 2699 2700
    return ret;
}

2701
static int
2702 2703 2704
storageConnectListAllStoragePools(virConnectPtr conn,
                                  virStoragePoolPtr **pools,
                                  unsigned int flags)
2705 2706 2707
{
    virCheckFlags(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ALL, -1);

2708
    if (virConnectListAllStoragePoolsEnsureACL(conn) < 0)
2709
        return -1;
2710

2711 2712 2713
    return virStoragePoolObjListExport(conn, driver->pools, pools,
                                       virConnectListAllStoragePoolsCheckACL,
                                       flags);
2714 2715
}

2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747
static int
storageConnectStoragePoolEventRegisterAny(virConnectPtr conn,
                                          virStoragePoolPtr pool,
                                          int eventID,
                                          virConnectStoragePoolEventGenericCallback callback,
                                          void *opaque,
                                          virFreeCallback freecb)
{
    int callbackID = -1;

    if (virConnectStoragePoolEventRegisterAnyEnsureACL(conn) < 0)
        goto cleanup;

    if (virStoragePoolEventStateRegisterID(conn, driver->storageEventState,
                                           pool, eventID, callback,
                                           opaque, freecb, &callbackID) < 0)
        callbackID = -1;
 cleanup:
    return callbackID;
}

static int
storageConnectStoragePoolEventDeregisterAny(virConnectPtr conn,
                                            int callbackID)
{
    int ret = -1;

    if (virConnectStoragePoolEventDeregisterAnyEnsureACL(conn) < 0)
        goto cleanup;

    if (virObjectEventStateDeregisterID(conn,
                                        driver->storageEventState,
2748
                                        callbackID, true) < 0)
2749 2750 2751 2752 2753 2754 2755 2756 2757
        goto cleanup;

    ret = 0;

 cleanup:
    return ret;
}


2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771


/*
 * virStoragePoolObjFindPoolByUUID
 * @uuid: The uuid to lookup
 *
 * Using the passed @uuid, search the driver pools for a matching uuid.
 * If found, then lock the pool
 *
 * Returns NULL if pool is not found or a locked pool object pointer
 */
virStoragePoolObjPtr
virStoragePoolObjFindPoolByUUID(const unsigned char *uuid)
{
2772
    return virStoragePoolObjFindByUUID(driver->pools, uuid);
2773
}
2774 2775 2776 2777


/*
 * virStoragePoolObjBuildTempFilePath
2778
 * @obj: pool object pointer
2779 2780 2781 2782 2783 2784 2785 2786 2787
 * @vol: volume definition
 *
 * Generate a name for a temporary file using the driver stateDir
 * as a path, the pool name, and the volume name to be used as input
 * for a mkostemp
 *
 * Returns a string pointer on success, NULL on failure
 */
char *
2788 2789
virStoragePoolObjBuildTempFilePath(virStoragePoolObjPtr obj,
                                   virStorageVolDefPtr voldef)
2790 2791

{
2792
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj);
2793 2794 2795
    char *tmp = NULL;

    ignore_value(virAsprintf(&tmp, "%s/%s.%s.secret.XXXXXX",
2796
                             driver->stateDir, def->name, voldef->name));
2797 2798
    return tmp;
}
2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810


static virStorageDriver storageDriver = {
    .name = "storage",
    .connectNumOfStoragePools = storageConnectNumOfStoragePools, /* 0.4.0 */
    .connectListStoragePools = storageConnectListStoragePools, /* 0.4.0 */
    .connectNumOfDefinedStoragePools = storageConnectNumOfDefinedStoragePools, /* 0.4.0 */
    .connectListDefinedStoragePools = storageConnectListDefinedStoragePools, /* 0.4.0 */
    .connectListAllStoragePools = storageConnectListAllStoragePools, /* 0.10.2 */
    .connectStoragePoolEventRegisterAny = storageConnectStoragePoolEventRegisterAny, /* 2.0.0 */
    .connectStoragePoolEventDeregisterAny = storageConnectStoragePoolEventDeregisterAny, /* 2.0.0 */
    .connectFindStoragePoolSources = storageConnectFindStoragePoolSources, /* 0.4.0 */
2811
    .connectGetStoragePoolCapabilities = storageConnectGetStoragePoolCapabilities, /* 5.2.0 */
2812 2813 2814
    .storagePoolLookupByName = storagePoolLookupByName, /* 0.4.0 */
    .storagePoolLookupByUUID = storagePoolLookupByUUID, /* 0.4.0 */
    .storagePoolLookupByVolume = storagePoolLookupByVolume, /* 0.4.0 */
2815
    .storagePoolLookupByTargetPath = storagePoolLookupByTargetPath, /* 4.1.0 */
2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852
    .storagePoolCreateXML = storagePoolCreateXML, /* 0.4.0 */
    .storagePoolDefineXML = storagePoolDefineXML, /* 0.4.0 */
    .storagePoolBuild = storagePoolBuild, /* 0.4.0 */
    .storagePoolUndefine = storagePoolUndefine, /* 0.4.0 */
    .storagePoolCreate = storagePoolCreate, /* 0.4.0 */
    .storagePoolDestroy = storagePoolDestroy, /* 0.4.0 */
    .storagePoolDelete = storagePoolDelete, /* 0.4.0 */
    .storagePoolRefresh = storagePoolRefresh, /* 0.4.0 */
    .storagePoolGetInfo = storagePoolGetInfo, /* 0.4.0 */
    .storagePoolGetXMLDesc = storagePoolGetXMLDesc, /* 0.4.0 */
    .storagePoolGetAutostart = storagePoolGetAutostart, /* 0.4.0 */
    .storagePoolSetAutostart = storagePoolSetAutostart, /* 0.4.0 */
    .storagePoolNumOfVolumes = storagePoolNumOfVolumes, /* 0.4.0 */
    .storagePoolListVolumes = storagePoolListVolumes, /* 0.4.0 */
    .storagePoolListAllVolumes = storagePoolListAllVolumes, /* 0.10.2 */

    .storageVolLookupByName = storageVolLookupByName, /* 0.4.0 */
    .storageVolLookupByKey = storageVolLookupByKey, /* 0.4.0 */
    .storageVolLookupByPath = storageVolLookupByPath, /* 0.4.0 */
    .storageVolCreateXML = storageVolCreateXML, /* 0.4.0 */
    .storageVolCreateXMLFrom = storageVolCreateXMLFrom, /* 0.6.4 */
    .storageVolDownload = storageVolDownload, /* 0.9.0 */
    .storageVolUpload = storageVolUpload, /* 0.9.0 */
    .storageVolDelete = storageVolDelete, /* 0.4.0 */
    .storageVolWipe = storageVolWipe, /* 0.8.0 */
    .storageVolWipePattern = storageVolWipePattern, /* 0.9.10 */
    .storageVolGetInfo = storageVolGetInfo, /* 0.4.0 */
    .storageVolGetInfoFlags = storageVolGetInfoFlags, /* 3.0.0 */
    .storageVolGetXMLDesc = storageVolGetXMLDesc, /* 0.4.0 */
    .storageVolGetPath = storageVolGetPath, /* 0.4.0 */
    .storageVolResize = storageVolResize, /* 0.9.10 */

    .storagePoolIsActive = storagePoolIsActive, /* 0.7.3 */
    .storagePoolIsPersistent = storagePoolIsPersistent, /* 0.7.3 */
};


2853 2854 2855 2856 2857 2858 2859
static virHypervisorDriver storageHypervisorDriver = {
    .name = "storage",
    .connectOpen = storageConnectOpen, /* 4.1.0 */
    .connectClose = storageConnectClose, /* 4.1.0 */
    .connectIsEncrypted = storageConnectIsEncrypted, /* 4.1.0 */
    .connectIsSecure = storageConnectIsSecure, /* 4.1.0 */
    .connectIsAlive = storageConnectIsAlive, /* 4.1.0 */
2860
    .connectGetCapabilities = storageConnectGetCapabilities, /* 5.2.0 */
2861 2862 2863
};

static virConnectDriver storageConnectDriver = {
2864
    .localOnly = true,
2865
    .uriSchemes = (const char *[]){ "storage", NULL },
2866 2867 2868 2869 2870
    .hypervisorDriver = &storageHypervisorDriver,
    .storageDriver = &storageDriver,
};


2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881
static virStateDriver stateDriver = {
    .name = "storage",
    .stateInitialize = storageStateInitialize,
    .stateCleanup = storageStateCleanup,
    .stateReload = storageStateReload,
};


static int
storageRegisterFull(bool allbackends)
{
2882 2883
    if (virRegisterConnectDriver(&storageConnectDriver, false) < 0)
        return -1;
2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905
    if (virStorageBackendDriversRegister(allbackends) < 0)
        return -1;
    if (virSetSharedStorageDriver(&storageDriver) < 0)
        return -1;
    if (virRegisterStateDriver(&stateDriver) < 0)
        return -1;
    return 0;
}


int
storageRegister(void)
{
    return storageRegisterFull(false);
}


int
storageRegisterAll(void)
{
    return storageRegisterFull(true);
}