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 116 117 118 119 120 121 122
/**
 * virStoragePoolUpdateInactive:
 * @poolptr: pointer to a variable holding the pool object pointer
 *
 * 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 *objptr)
124
{
125
    virStoragePoolObjPtr obj = *objptr;
126

127
    if (!virStoragePoolObjGetConfigFile(obj)) {
128
        virStoragePoolObjRemove(driver->pools, obj);
129
        virStoragePoolObjEndAPI(objptr);
130 131
    } else if (virStoragePoolObjGetNewDef(obj)) {
        virStoragePoolObjDefUseNewDef(obj);
132 133 134 135
    }
}


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

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

151 152 153
    if (!(stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml")))
        return;

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

    /* 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.
     */
169 170 171 172 173 174
    if (active &&
        storagePoolRefreshImpl(backend, obj, stateFile) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to restart storage pool '%s': %s"),
                       def->name, virGetLastErrorMessage());
        active = false;
175 176
    }

177
    virStoragePoolObjSetActive(obj, active);
178

179
    if (!virStoragePoolObjIsActive(obj))
180
        virStoragePoolUpdateInactive(&obj);
181

182 183 184
    return;
}

185

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


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

203 204
    if (!(backend = virStorageBackendForType(def->type)))
        return;
205

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

    if (started) {
219
        VIR_AUTOFREE(char *) stateFile = NULL;
220 221 222 223

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

234

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

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

256
    if (VIR_ALLOC(driver) < 0)
257
        return VIR_DRV_STATE_INIT_ERROR;
258

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

266 267 268
    if (!(driver->pools = virStoragePoolObjListNew()))
        goto error;

269
    if (privileged) {
270 271 272 273 274 275
        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)
276
            goto error;
277
    } else {
278 279 280 281 282 283 284 285
        configdir = virGetUserConfigDirectory();
        rundir = virGetUserRuntimeDirectory();
        if (!(configdir && rundir))
            goto error;

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

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

300 301 302 303 304
    if ((driver->lockFD =
         virPidFileAcquire(driver->stateDir, "driver",
                           true, getpid())) < 0)
        goto error;

305
    if (virStoragePoolObjLoadAllState(driver->pools,
306
                                      driver->stateDir) < 0)
307 308
        goto error;

309
    if (virStoragePoolObjLoadAllConfigs(driver->pools,
310 311
                                        driver->configDir,
                                        driver->autostartDir) < 0)
312
        goto error;
313

314 315
    storagePoolUpdateAllState();

316 317
    storageDriverAutostart();

318 319
    driver->storageEventState = virObjectEventStateNew();

320 321 322 323 324 325
    /* 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;

326
    storageDriverUnlock();
327

328
    return VIR_DRV_STATE_INIT_COMPLETE;
329

330
 error:
331
    storageDriverUnlock();
332
    storageStateCleanup();
333
    return VIR_DRV_STATE_INIT_ERROR;
334 335 336
}

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

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

    return 0;
}


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

372
    storageDriverLock();
373

374
    virObjectUnref(driver->caps);
375
    virObjectUnref(driver->storageEventState);
376

377
    /* free inactive pools */
378
    virObjectUnref(driver->pools);
379

380 381 382 383
    if (driver->lockFD != -1)
        virPidFileRelease(driver->stateDir, "driver",
                          driver->lockFD);

384 385
    VIR_FREE(driver->configDir);
    VIR_FREE(driver->autostartDir);
386
    VIR_FREE(driver->stateDir);
387 388 389
    storageDriverUnlock();
    virMutexDestroy(&driver->lock);
    VIR_FREE(driver);
390 391 392 393

    return 0;
}

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

402 403 404 405 406 407 408 409 410 411 412
    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);
413 414
            return VIR_DRV_OPEN_ERROR;
        }
415 416 417 418 419 420
    } 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;
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 452 453 454
        }
    }

    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;
}

455

456 457 458 459
static virStoragePoolObjPtr
storagePoolObjFindByUUID(const unsigned char *uuid,
                         const char *name)
{
460
    virStoragePoolObjPtr obj;
461 462
    char uuidstr[VIR_UUID_STRING_BUFLEN];

463
    if (!(obj = virStoragePoolObjFindByUUID(driver->pools, uuid))) {
464 465 466 467 468 469 470 471 472 473 474
        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);
    }

475
    return obj;
476 477 478 479 480 481
}


static virStoragePoolObjPtr
virStoragePoolObjFromStoragePool(virStoragePoolPtr pool)
{
482
    return storagePoolObjFindByUUID(pool->uuid, pool->name);
483 484 485 486 487 488
}


static virStoragePoolObjPtr
storagePoolObjFindByName(const char *name)
{
489
    virStoragePoolObjPtr obj;
490

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

497 498 499

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

506 507
    obj = storagePoolObjFindByUUID(uuid, NULL);
    if (!obj)
508
        return NULL;
509
    def = virStoragePoolObjGetDef(obj);
510

511
    if (virStoragePoolLookupByUUIDEnsureACL(conn, def) < 0)
512 513
        goto cleanup;

514
    pool = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL);
515

516
 cleanup:
517
    virStoragePoolObjEndAPI(&obj);
518
    return pool;
519 520 521 522
}

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

529
    if (!(obj = storagePoolObjFindByName(name)))
530
        return NULL;
531
    def = virStoragePoolObjGetDef(obj);
532

533
    if (virStoragePoolLookupByNameEnsureACL(conn, def) < 0)
534 535
        goto cleanup;

536
    pool = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL);
537

538
 cleanup:
539
    virStoragePoolObjEndAPI(&obj);
540
    return pool;
541 542 543
}

static virStoragePoolPtr
544 545
storagePoolLookupByVolume(virStorageVolPtr vol)
{
546
    virStoragePoolObjPtr obj;
547
    virStoragePoolDefPtr def;
548
    virStoragePoolPtr pool = NULL;
549

550
    if (!(obj = storagePoolObjFindByName(vol->pool)))
551
        return NULL;
552
    def = virStoragePoolObjGetDef(obj);
553

554
    if (virStoragePoolLookupByVolumeEnsureACL(vol->conn, def) < 0)
555 556
        goto cleanup;

557
    pool = virGetStoragePool(vol->conn, def->name, def->uuid, NULL, NULL);
558

559
 cleanup:
560
    virStoragePoolObjEndAPI(&obj);
561
    return pool;
562 563 564
}

static int
565 566
storageConnectNumOfStoragePools(virConnectPtr conn)
{
567 568 569
    if (virConnectNumOfStoragePoolsEnsureACL(conn) < 0)
        return -1;

570 571
    return virStoragePoolObjNumOfStoragePools(driver->pools, conn, true,
                                              virConnectNumOfStoragePoolsCheckACL);
572 573
}

574

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

583 584 585
    return virStoragePoolObjGetNames(driver->pools, conn, true,
                                     virConnectListStoragePoolsCheckACL,
                                     names, maxnames);
586 587
}

588 589 590 591 592 593 594 595 596 597 598 599

static char *
storageConnectGetCapabilities(virConnectPtr conn)
{

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

    return virCapabilitiesFormatXML(driver->caps);
}


600
static int
601 602
storageConnectNumOfDefinedStoragePools(virConnectPtr conn)
{
603 604 605
    if (virConnectNumOfDefinedStoragePoolsEnsureACL(conn) < 0)
        return -1;

606 607
    return virStoragePoolObjNumOfStoragePools(driver->pools, conn, false,
                                               virConnectNumOfDefinedStoragePoolsCheckACL);
608 609
}

610

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

619 620 621
    return virStoragePoolObjGetNames(driver->pools, conn, false,
                                     virConnectListDefinedStoragePoolsCheckACL,
                                     names, maxnames);
622 623
}

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

636 637 638
    if (virConnectFindStoragePoolSourcesEnsureACL(conn) < 0)
        return NULL;

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

    backend = virStorageBackendForType(backend_type);
    if (backend == NULL)
648
        goto cleanup;
649

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

657
    ret = backend->findPoolSources(srcSpec, flags);
658

659
 cleanup:
660
    return ret;
661 662 663
}


664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
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;
}


686 687
static int
storagePoolIsActive(virStoragePoolPtr pool)
688 689
{
    virStoragePoolObjPtr obj;
690
    virStoragePoolDefPtr def;
691 692 693 694
    int ret = -1;

    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
        return -1;
695
    def = virStoragePoolObjGetDef(obj);
696

697
    if (virStoragePoolIsActiveEnsureACL(pool->conn, def) < 0)
698 699
        goto cleanup;

700 701
    ret = virStoragePoolObjIsActive(obj);

702
 cleanup:
703
    virStoragePoolObjEndAPI(&obj);
704 705 706
    return ret;
}

707 708 709

static int
storagePoolIsPersistent(virStoragePoolPtr pool)
710 711
{
    virStoragePoolObjPtr obj;
712
    virStoragePoolDefPtr def;
713 714
    int ret = -1;

715 716
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
        return -1;
717
    def = virStoragePoolObjGetDef(obj);
718

719
    if (virStoragePoolIsPersistentEnsureACL(pool->conn, def) < 0)
720 721
        goto cleanup;

722
    ret = virStoragePoolObjGetConfigFile(obj) ? 1 : 0;
723

724
 cleanup:
725
    virStoragePoolObjEndAPI(&obj);
726 727 728 729
    return ret;
}


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

744 745 746 747 748 749
    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 已提交
750

751
    if (!(newDef = virStoragePoolDefParseString(xml)))
752
        goto cleanup;
753

754
    if (virStoragePoolCreateXMLEnsureACL(conn, newDef) < 0)
755 756
        goto cleanup;

757
    if ((backend = virStorageBackendForType(newDef->type)) == NULL)
758
        goto cleanup;
759

760
    if (!(obj = virStoragePoolObjAssignDef(driver->pools, newDef, true)))
761
        goto cleanup;
762 763
    newDef = NULL;
    def = virStoragePoolObjGetDef(obj);
764

765 766 767 768 769 770 771 772
    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)) {
773 774
            if (backend->buildPool(obj, build_flags) < 0)
                goto error;
775 776 777
        }
    }

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

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

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

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

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

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

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

 error:
    virStoragePoolObjRemove(driver->pools, obj);
    goto cleanup;
808 809 810
}

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

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

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

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

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

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

835
    if (!(obj = virStoragePoolObjAssignDef(driver->pools, newDef, false)))
836
        goto cleanup;
837
    newDef = virStoragePoolObjGetNewDef(obj);
838
    def = virStoragePoolObjGetDef(obj);
839

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

928 929 930 931 932 933
    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 已提交
934

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

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

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

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

952 953 954 955 956 957 958 959
    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)) {
960
            if (backend->buildPool(obj, build_flags) < 0)
961 962 963 964
                goto cleanup;
        }
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

1028
    ret = 0;
1029

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


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

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

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

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

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

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

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

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

    unlink(stateFile);

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

1081
    virStoragePoolObjClearVols(obj);
1082

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

1088
    virStoragePoolObjSetActive(obj, false);
1089

1090
    virStoragePoolUpdateInactive(&obj);
1091

1092
    ret = 0;
1093

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

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

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

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

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

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

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

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

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

    unlink(stateFile);

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

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

1155
    ret = 0;
1156

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


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

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

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

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

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

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

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

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

1208
        virStoragePoolUpdateInactive(&obj);
1209

1210
        goto cleanup;
1211
    }
1212

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

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


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

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

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

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

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

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

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

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

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

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

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

1282
    ret = virStoragePoolDefFormat(curDef);
1283

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

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

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

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

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

1305
    ret = 0;
1306

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

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

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

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

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

1336 1337
    autostartLink = virStoragePoolObjGetAutostartLink(obj);

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

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

1367
    ret = 0;
1368

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


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

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

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

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

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

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

1403

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

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

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

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

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

1434

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

    virCheckFlags(0, -1);

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

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

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

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


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

    return ret;
}
1468 1469

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

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

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

1488
    voldef = virStorageVolDefFindByName(obj, name);
1489

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

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

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

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


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

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

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

    return !!data->voldef;
}


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

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

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

1555
    return vol;
1556 1557
}

1558 1559 1560 1561 1562

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

    if (!virStoragePoolObjIsActive(obj))
        return false;

    def = virStoragePoolObjGetDef(obj);

1572
    switch ((virStoragePoolType)def->type) {
1573 1574 1575 1576 1577 1578
        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:
1579
        case VIR_STORAGE_POOL_ISCSI_DIRECT:
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 1608
        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;
}


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

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

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

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

1635
    if (!vol) {
1636
        if (STREQ(path, data.cleanpath)) {
1637 1638 1639 1640 1641
            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)"),
1642
                           path, data.cleanpath);
1643 1644
        }
    }
1645

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

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

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);
}


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

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

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

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

1690
    if (!pool) {
1691 1692 1693 1694 1695 1696 1697 1698 1699
        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);
        }
1700 1701
    }

1702
    return pool;
1703 1704
}

1705

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

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

        goto cleanup;
    }

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

1726 1727 1728 1729 1730 1731 1732 1733
    /* 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;
    }

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

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

 cleanup:
    return ret;
}


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

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

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

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

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

1782
    return voldef;
1783 1784

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

    return NULL;
}


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

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

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

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

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

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

    ret = 0;

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

1831

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

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

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

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

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

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

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

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

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

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

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

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

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

1900 1901
    if (backend->buildVol) {
        int buildret;
1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913
        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));
1914 1915

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

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

1922 1923
        VIR_FREE(buildvoldef);

1924
        virObjectLock(obj);
1925

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

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

1936
    }
1937

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2055 2056 2057 2058
    /* 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. */
2059 2060
    if (!voldef->target.has_allocation)
        voldef->target.allocation = voldef->target.capacity;
2061

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

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

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

2080 2081 2082
    /* '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.  */
2083
    VIR_FREE(voldef->key);
2084
    if (backend->createVol(obj, voldef) < 0)
2085 2086
        goto cleanup;

2087 2088 2089 2090 2091 2092 2093
    /* 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;

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

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

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

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

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

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

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

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

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

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

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

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

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

2159

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

2172
    virCheckFlags(VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM, -1);
2173

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

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

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

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

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

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

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

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

    return ret;
}


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

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

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

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

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

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

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



2257 2258 2259 2260 2261 2262 2263 2264 2265 2266
/**
 * 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;
2267
    virStoragePoolObjPtr obj = NULL;
2268
    virStoragePoolDefPtr def;
2269
    virStorageBackendPtr backend;
2270
    virObjectEventPtr event = NULL;
2271

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

2281 2282 2283 2284 2285 2286 2287
    /* 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;
    }

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

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

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

2296
 cleanup:
2297
    virObjectEventStateQueue(driver->storageEventState, event);
2298
    virStoragePoolObjEndAPI(&obj);
2299 2300 2301 2302 2303 2304 2305 2306
    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 已提交
2307
 * @opaque Buffer to hold the pool name to be refreshed
2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326
 */
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);
}

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

2342
    virCheckFlags(VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM, -1);
2343

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

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

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

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

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

2371
    /* Use the callback routine in order to
2372 2373 2374 2375 2376
     * 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.
     */
2377
    if (VIR_ALLOC(cbdata) < 0 ||
2378
        VIR_STRDUP(cbdata->pool_name, def->name) < 0)
2379
        goto cleanup;
2380 2381
    if (voldef->type == VIR_STORAGE_VOL_PLOOP &&
        VIR_STRDUP(cbdata->vol_path, voldef->target.path) < 0)
2382
        goto cleanup;
2383

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

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

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

    if (rc < 0)
2395
        goto cleanup;
2396

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

    return ret;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

2494
    voldef->target.capacity = abs_capacity;
2495 2496 2497 2498 2499
    /* 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) {
2500
        voldef->target.allocation = abs_capacity;
2501 2502
        def->allocation += delta;
        def->available -= delta;
2503
    }
2504

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

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

    return ret;
}
2512

2513 2514

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

2525
    virCheckFlags(0, -1);
2526

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

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

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

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

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

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

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

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

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

    if (rc < 0)
2573 2574
        goto cleanup;

2575 2576 2577 2578 2579 2580 2581 2582 2583 2584
    /* 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)
2585 2586 2587
        goto cleanup;

    ret = 0;
2588

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

    return ret;
}

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

2602 2603

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

2613 2614
    virCheckFlags(VIR_STORAGE_VOL_GET_PHYSICAL, -1);

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

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

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

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

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

2641 2642

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


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

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

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

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

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

2673
    ret = virStorageVolDefFormat(def, voldef);
2674

2675
 cleanup:
2676
    virStoragePoolObjEndAPI(&obj);
2677

2678
    return ret;
2679 2680 2681
}

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

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

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

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

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

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

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

2712 2713 2714
    return virStoragePoolObjListExport(conn, driver->pools, pools,
                                       virConnectListAllStoragePoolsCheckACL,
                                       flags);
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 2748
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,
2749
                                        callbackID, true) < 0)
2750 2751 2752 2753 2754 2755 2756 2757 2758
        goto cleanup;

    ret = 0;

 cleanup:
    return ret;
}


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


/*
 * 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)
{
2773
    return virStoragePoolObjFindByUUID(driver->pools, uuid);
2774
}
2775 2776 2777 2778


/*
 * virStoragePoolObjBuildTempFilePath
2779
 * @obj: pool object pointer
2780 2781 2782 2783 2784 2785 2786 2787 2788
 * @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 *
2789 2790
virStoragePoolObjBuildTempFilePath(virStoragePoolObjPtr obj,
                                   virStorageVolDefPtr voldef)
2791 2792

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

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


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 */
2812
    .connectGetStoragePoolCapabilities = storageConnectGetStoragePoolCapabilities, /* 5.2.0 */
2813 2814 2815
    .storagePoolLookupByName = storagePoolLookupByName, /* 0.4.0 */
    .storagePoolLookupByUUID = storagePoolLookupByUUID, /* 0.4.0 */
    .storagePoolLookupByVolume = storagePoolLookupByVolume, /* 0.4.0 */
2816
    .storagePoolLookupByTargetPath = storagePoolLookupByTargetPath, /* 4.1.0 */
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 2853
    .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 */
};


2854 2855 2856 2857 2858 2859 2860
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 */
2861
    .connectGetCapabilities = storageConnectGetCapabilities, /* 5.2.0 */
2862 2863 2864
};

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


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


static int
storageRegisterFull(bool allbackends)
{
2883 2884
    if (virRegisterConnectDriver(&storageConnectDriver, false) < 0)
        return -1;
2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906
    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);
}