storage_driver.c 84.5 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 "storage_util.h"
J
Ján Tomko 已提交
52
#include "virutil.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
    virErrorPtr orig_err;
85

86
    virErrorPreserveLast(&orig_err);
87 88
    virStoragePoolObjClearVols(obj);

89
    if (stateFile)
90
        unlink(stateFile);
91 92
    if (backend->stopPool)
        backend->stopPool(obj);
93
    virErrorRestore(&orig_err);
94 95 96
}


97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
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;
}


112 113
/**
 * virStoragePoolUpdateInactive:
114
 * @obj: pool object
115 116 117 118 119 120
 *
 * 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
121
virStoragePoolUpdateInactive(virStoragePoolObjPtr obj)
122
{
123
    if (!virStoragePoolObjGetConfigFile(obj)) {
124
        virStoragePoolObjRemove(driver->pools, obj);
125 126
    } else if (virStoragePoolObjGetNewDef(obj)) {
        virStoragePoolObjDefUseNewDef(obj);
127 128 129 130
    }
}


131
static void
132
storagePoolUpdateStateCallback(virStoragePoolObjPtr obj,
J
Ján Tomko 已提交
133
                               const void *opaque G_GNUC_UNUSED)
134
{
135
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj);
136
    bool active = false;
137
    virStorageBackendPtr backend;
138
    g_autofree char *stateFile = NULL;
139

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

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

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

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

172
    virStoragePoolObjSetActive(obj, active);
173

174
    if (!virStoragePoolObjIsActive(obj))
175
        virStoragePoolUpdateInactive(obj);
176

177 178 179
    return;
}

180

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


static void
storageDriverAutostartCallback(virStoragePoolObjPtr obj,
J
Ján Tomko 已提交
192
                               const void *opaque G_GNUC_UNUSED)
193 194 195 196
{
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj);
    virStorageBackendPtr backend;
    bool started = false;
197

198 199
    if (!(backend = virStorageBackendForType(def->type)))
        return;
200

201 202
    if (virStoragePoolObjIsAutostart(obj) &&
        !virStoragePoolObjIsActive(obj)) {
203 204

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

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

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

 cleanup:
    if (virStoragePoolObjIsStarting(obj)) {
        if (!virStoragePoolObjIsActive(obj))
            virStoragePoolUpdateInactive(obj);
        virStoragePoolObjSetStarting(obj, false);
    }
236 237
}

238

239
static void
240
storageDriverAutostart(void)
241
{
242
    virStoragePoolObjListForEach(driver->pools,
243
                                 storageDriverAutostartCallback,
244
                                 NULL);
245 246 247 248 249
}

/**
 * virStorageStartup:
 *
250
 * Initialization function for the Storage Driver
251 252
 */
static int
253
storageStateInitialize(bool privileged,
254
                       const char *root,
J
Ján Tomko 已提交
255 256
                       virStateInhibitCallback callback G_GNUC_UNUSED,
                       void *opaque G_GNUC_UNUSED)
257
{
258 259
    g_autofree char *configdir = NULL;
    g_autofree char *rundir = NULL;
260
    bool autostart = true;
261

262 263 264 265 266 267
    if (root != NULL) {
        virReportError(VIR_ERR_INVALID_ARG, "%s",
                       _("Driver does not support embedded mode"));
        return -1;
    }

268
    if (VIR_ALLOC(driver) < 0)
269
        return VIR_DRV_STATE_INIT_ERROR;
270

271
    driver->lockFD = -1;
272 273
    if (virMutexInit(&driver->lock) < 0) {
        VIR_FREE(driver);
274
        return VIR_DRV_STATE_INIT_ERROR;
275
    }
276
    storageDriverLock();
277

278 279 280
    if (!(driver->pools = virStoragePoolObjListNew()))
        goto error;

281
    if (privileged) {
282 283 284
        driver->configDir = g_strdup(SYSCONFDIR "/libvirt/storage");
        driver->autostartDir = g_strdup(SYSCONFDIR "/libvirt/storage/autostart");
        driver->stateDir = g_strdup(RUNSTATEDIR "/libvirt/storage");
285
    } else {
286 287 288
        configdir = virGetUserConfigDirectory();
        rundir = virGetUserRuntimeDirectory();

289 290 291
        driver->configDir = g_strdup_printf("%s/storage", configdir);
        driver->autostartDir = g_strdup_printf("%s/storage/autostart", configdir);
        driver->stateDir = g_strdup_printf("%s/storage/run", rundir);
292
    }
293
    driver->privileged = privileged;
294

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

302 303
    if ((driver->lockFD =
         virPidFileAcquire(driver->stateDir, "driver",
304
                           false, getpid())) < 0)
305 306
        goto error;

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

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

316 317
    storagePoolUpdateAllState();

318 319 320 321 322
    if (virDriverShouldAutostart(driver->stateDir, &autostart) < 0)
        goto error;

    if (autostart)
        storageDriverAutostart();
323

324 325
    driver->storageEventState = virObjectEventStateNew();

326 327 328 329 330 331
    /* 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;

332
    storageDriverUnlock();
333

334
    return VIR_DRV_STATE_INIT_COMPLETE;
335

336
 error:
337
    storageDriverUnlock();
338
    storageStateCleanup();
339
    return VIR_DRV_STATE_INIT_ERROR;
340 341 342
}

/**
343
 * storageStateReload:
344 345 346 347 348
 *
 * Function to restart the storage driver, it will recheck the configuration
 * files and update its state
 */
static int
349 350
storageStateReload(void)
{
351
    if (!driver)
352 353
        return -1;

354
    storageDriverLock();
355
    virStoragePoolObjLoadAllState(driver->pools,
356
                                  driver->stateDir);
357
    virStoragePoolObjLoadAllConfigs(driver->pools,
358 359
                                    driver->configDir,
                                    driver->autostartDir);
360 361
    storageDriverAutostart();
    storageDriverUnlock();
362 363 364 365 366 367

    return 0;
}


/**
368
 * storageStateCleanup
369 370 371 372
 *
 * Shutdown the storage driver, it will stop all active storage pools
 */
static int
373 374
storageStateCleanup(void)
{
375
    if (!driver)
376 377
        return -1;

378
    storageDriverLock();
379

380
    virObjectUnref(driver->caps);
381
    virObjectUnref(driver->storageEventState);
382

383
    /* free inactive pools */
384
    virObjectUnref(driver->pools);
385

386 387 388 389
    if (driver->lockFD != -1)
        virPidFileRelease(driver->stateDir, "driver",
                          driver->lockFD);

390 391
    VIR_FREE(driver->configDir);
    VIR_FREE(driver->autostartDir);
392
    VIR_FREE(driver->stateDir);
393 394 395
    storageDriverUnlock();
    virMutexDestroy(&driver->lock);
    VIR_FREE(driver);
396 397 398 399

    return 0;
}

400 401
static virDrvOpenStatus
storageConnectOpen(virConnectPtr conn,
J
Ján Tomko 已提交
402 403
                   virConnectAuthPtr auth G_GNUC_UNUSED,
                   virConfPtr conf G_GNUC_UNUSED,
404 405 406 407
                   unsigned int flags)
{
    virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);

408 409 410 411 412 413
    if (driver == NULL) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("storage state driver is not active"));
        return VIR_DRV_OPEN_ERROR;
    }

414 415 416 417
    if (!virConnectValidateURIPath(conn->uri->path,
                                   "storage",
                                   driver->privileged))
        return VIR_DRV_OPEN_ERROR;
418 419 420 421 422 423 424

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

    return VIR_DRV_OPEN_SUCCESS;
}

J
Ján Tomko 已提交
425
static int storageConnectClose(virConnectPtr conn G_GNUC_UNUSED)
426 427 428 429 430
{
    return 0;
}


J
Ján Tomko 已提交
431
static int storageConnectIsSecure(virConnectPtr conn G_GNUC_UNUSED)
432 433 434 435 436 437
{
    /* Trivially secure, since always inside the daemon */
    return 1;
}


J
Ján Tomko 已提交
438
static int storageConnectIsEncrypted(virConnectPtr conn G_GNUC_UNUSED)
439 440 441 442 443 444
{
    /* Not encrypted, but remote driver takes care of that */
    return 0;
}


J
Ján Tomko 已提交
445
static int storageConnectIsAlive(virConnectPtr conn G_GNUC_UNUSED)
446 447 448 449
{
    return 1;
}

450

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

458
    if (!(obj = virStoragePoolObjFindByUUID(driver->pools, uuid))) {
459 460 461 462 463 464 465 466 467 468 469
        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);
    }

470
    return obj;
471 472 473 474 475 476
}


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


static virStoragePoolObjPtr
storagePoolObjFindByName(const char *name)
{
484
    virStoragePoolObjPtr obj;
485

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

492 493 494

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

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

506
    if (virStoragePoolLookupByUUIDEnsureACL(conn, def) < 0)
507 508
        goto cleanup;

509
    pool = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL);
510

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

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

524
    if (!(obj = storagePoolObjFindByName(name)))
525
        return NULL;
526
    def = virStoragePoolObjGetDef(obj);
527

528
    if (virStoragePoolLookupByNameEnsureACL(conn, def) < 0)
529 530
        goto cleanup;

531
    pool = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL);
532

533
 cleanup:
534
    virStoragePoolObjEndAPI(&obj);
535
    return pool;
536 537 538
}

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

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

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

552
    pool = virGetStoragePool(vol->conn, def->name, def->uuid, NULL, NULL);
553

554
 cleanup:
555
    virStoragePoolObjEndAPI(&obj);
556
    return pool;
557 558 559
}

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

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

569

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

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

583 584 585 586 587 588 589 590 591 592 593 594

static char *
storageConnectGetCapabilities(virConnectPtr conn)
{

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

    return virCapabilitiesFormatXML(driver->caps);
}


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

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

605

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

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

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

630 631 632
    if (virConnectFindStoragePoolSourcesEnsureACL(conn) < 0)
        return NULL;

633
    backend_type = virStoragePoolTypeFromString(type);
634
    if (backend_type < 0) {
635 636
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown storage pool type %s"), type);
637
        return NULL;
638
    }
639 640 641

    backend = virStorageBackendForType(backend_type);
    if (backend == NULL)
642
        return NULL;
643

644
    if (!backend->findPoolSources) {
645 646 647
        virReportError(VIR_ERR_NO_SUPPORT,
                       _("pool type '%s' does not support source "
                         "discovery"), type);
648
        return NULL;
649 650
    }

651
    return backend->findPoolSources(srcSpec, flags);
652 653 654
}


655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
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;
}


677 678
static int
storagePoolIsActive(virStoragePoolPtr pool)
679 680
{
    virStoragePoolObjPtr obj;
681
    virStoragePoolDefPtr def;
682 683 684 685
    int ret = -1;

    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
        return -1;
686
    def = virStoragePoolObjGetDef(obj);
687

688
    if (virStoragePoolIsActiveEnsureACL(pool->conn, def) < 0)
689 690
        goto cleanup;

691 692
    ret = virStoragePoolObjIsActive(obj);

693
 cleanup:
694
    virStoragePoolObjEndAPI(&obj);
695 696 697
    return ret;
}

698 699 700

static int
storagePoolIsPersistent(virStoragePoolPtr pool)
701 702
{
    virStoragePoolObjPtr obj;
703
    virStoragePoolDefPtr def;
704 705
    int ret = -1;

706 707
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
        return -1;
708
    def = virStoragePoolObjGetDef(obj);
709

710
    if (virStoragePoolIsPersistentEnsureACL(pool->conn, def) < 0)
711 712
        goto cleanup;

713
    ret = virStoragePoolObjGetConfigFile(obj) ? 1 : 0;
714

715
 cleanup:
716
    virStoragePoolObjEndAPI(&obj);
717 718 719 720
    return ret;
}


721
static virStoragePoolPtr
722 723 724
storagePoolCreateXML(virConnectPtr conn,
                     const char *xml,
                     unsigned int flags)
E
Eric Blake 已提交
725
{
726
    virStoragePoolObjPtr obj = NULL;
727
    virStoragePoolDefPtr def;
728
    virStoragePoolPtr pool = NULL;
729
    virStorageBackendPtr backend;
730
    virObjectEventPtr event = NULL;
731
    unsigned int build_flags = 0;
J
Ján Tomko 已提交
732
    g_autoptr(virStoragePoolDef) newDef = NULL;
733
    g_autofree char *stateFile = NULL;
734

735 736 737 738 739 740
    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 已提交
741

742
    if (!(newDef = virStoragePoolDefParseString(xml)))
743
        goto cleanup;
744

745
    if (virStoragePoolCreateXMLEnsureACL(conn, newDef) < 0)
746 747
        goto cleanup;

748
    if ((backend = virStorageBackendForType(newDef->type)) == NULL)
749
        goto cleanup;
750

751
    if (!(obj = virStoragePoolObjListAdd(driver->pools, newDef,
752
                                         VIR_STORAGE_POOL_OBJ_LIST_ADD_LIVE |
753
                                         VIR_STORAGE_POOL_OBJ_LIST_ADD_CHECK_LIVE)))
754
        goto cleanup;
755 756
    newDef = NULL;
    def = virStoragePoolObjGetDef(obj);
757

758 759
    virStoragePoolObjSetStarting(obj, true);

760 761 762 763 764 765 766 767
    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)) {
768 769
            if (backend->buildPool(obj, build_flags) < 0)
                goto error;
770 771 772
        }
    }

773
    if (backend->startPool &&
774 775
        backend->startPool(obj) < 0)
        goto error;
776

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

779 780 781
    if (!stateFile ||
        virStoragePoolSaveState(stateFile, def) < 0 ||
        storagePoolRefreshImpl(backend, obj, stateFile) < 0) {
782
        goto error;
783
    }
784

785 786
    event = virStoragePoolEventLifecycleNew(def->name,
                                            def->uuid,
787 788 789
                                            VIR_STORAGE_POOL_EVENT_STARTED,
                                            0);

790
    VIR_INFO("Creating storage pool '%s'", def->name);
791
    virStoragePoolObjSetActive(obj, true);
792

793
    pool = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL);
794

795
 cleanup:
796
    if (obj && virStoragePoolObjIsStarting(obj)) {
797 798 799 800
        if (!virStoragePoolObjIsActive(obj))
            virStoragePoolUpdateInactive(obj);
        virStoragePoolObjSetStarting(obj, false);
    }
801
    virObjectEventStateQueue(driver->storageEventState, event);
802
    virStoragePoolObjEndAPI(&obj);
803
    return pool;
804 805

 error:
806
    virStoragePoolUpdateInactive(obj);
807
    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;
J
Ján Tomko 已提交
819
    g_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 = virStoragePoolObjListAdd(driver->pools, newDef, 0)))
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 884 885 886 887 888 889
    if (virStoragePoolObjIsStarting(obj)) {
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is starting up"),
                       def->name);
        goto cleanup;
    }

890
    if (virStoragePoolObjGetAsyncjobs(obj) > 0) {
891 892
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("pool '%s' has asynchronous jobs running."),
893
                       def->name);
894 895 896
        goto cleanup;
    }

897
    autostartLink = virStoragePoolObjGetAutostartLink(obj);
898
    if (virStoragePoolObjDeleteDef(obj) < 0)
899
        goto cleanup;
900

901 902
    if (autostartLink && unlink(autostartLink) < 0 &&
        errno != ENOENT && errno != ENOTDIR) {
903
        VIR_ERROR(_("Failed to delete autostart link '%s': %s"),
904
                  autostartLink, g_strerror(errno));
905
    }
906

907 908
    event = virStoragePoolEventLifecycleNew(def->name,
                                            def->uuid,
909 910 911
                                            VIR_STORAGE_POOL_EVENT_UNDEFINED,
                                            0);

912
    VIR_INFO("Undefining storage pool '%s'", def->name);
913
    virStoragePoolObjRemove(driver->pools, obj);
914
    ret = 0;
915

916
 cleanup:
917
    virObjectEventStateQueue(driver->storageEventState, event);
918
    virStoragePoolObjEndAPI(&obj);
919
    return ret;
920 921 922
}

static int
923
storagePoolCreate(virStoragePoolPtr pool,
924
                  unsigned int flags)
E
Eric Blake 已提交
925
{
926
    virStoragePoolObjPtr obj;
927
    virStoragePoolDefPtr def;
928
    virStorageBackendPtr backend;
929
    virObjectEventPtr event = NULL;
930
    int ret = -1;
931
    unsigned int build_flags = 0;
932
    g_autofree char *stateFile = NULL;
933
    bool restoreStarting = false;
934

935 936 937 938 939 940
    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 已提交
941

942
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
943
        return -1;
944
    def = virStoragePoolObjGetDef(obj);
945

946
    if (virStoragePoolCreateEnsureACL(pool->conn, def) < 0)
947 948
        goto cleanup;

949
    if ((backend = virStorageBackendForType(def->type)) == NULL)
950
        goto cleanup;
951

952
    if (virStoragePoolObjIsActive(obj)) {
953
        virReportError(VIR_ERR_OPERATION_INVALID,
954
                       _("storage pool '%s' is already active"),
955
                       def->name);
956
        goto cleanup;
957
    }
958

959 960 961 962 963 964 965 966 967 968
    if (virStoragePoolObjIsStarting(obj)) {
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is starting up"),
                       def->name);
        goto cleanup;
    }

    virStoragePoolObjSetStarting(obj, true);
    restoreStarting = true;

969 970 971 972 973 974 975 976
    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)) {
977
            if (backend->buildPool(obj, build_flags) < 0)
978 979 980 981
                goto cleanup;
        }
    }

982
    VIR_INFO("Starting up storage pool '%s'", def->name);
983
    if (backend->startPool &&
984
        backend->startPool(obj) < 0)
985 986
        goto cleanup;

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

989 990 991
    if (!stateFile ||
        virStoragePoolSaveState(stateFile, def) < 0 ||
        storagePoolRefreshImpl(backend, obj, stateFile) < 0) {
992
        goto cleanup;
993 994
    }

995 996
    event = virStoragePoolEventLifecycleNew(def->name,
                                            def->uuid,
997 998 999
                                            VIR_STORAGE_POOL_EVENT_STARTED,
                                            0);

1000
    virStoragePoolObjSetActive(obj, true);
1001
    ret = 0;
1002

1003
 cleanup:
1004 1005 1006 1007 1008 1009
    if (restoreStarting &&
        virStoragePoolObjIsStarting(obj)) {
        if (!virStoragePoolObjIsActive(obj))
            virStoragePoolUpdateInactive(obj);
        virStoragePoolObjSetStarting(obj, false);
    }
1010
    virObjectEventStateQueue(driver->storageEventState, event);
1011
    virStoragePoolObjEndAPI(&obj);
1012
    return ret;
1013 1014 1015
}

static int
1016
storagePoolBuild(virStoragePoolPtr pool,
1017 1018
                 unsigned int flags)
{
1019
    virStoragePoolObjPtr obj;
1020
    virStoragePoolDefPtr def;
1021
    virStorageBackendPtr backend;
1022
    virObjectEventPtr event = NULL;
1023
    bool restoreStarting = false;
1024
    int ret = -1;
1025

1026
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1027
        return -1;
1028
    def = virStoragePoolObjGetDef(obj);
1029

1030
    if (virStoragePoolBuildEnsureACL(pool->conn, def) < 0)
1031 1032
        goto cleanup;

1033
    if ((backend = virStorageBackendForType(def->type)) == NULL)
1034
        goto cleanup;
1035

1036
    if (virStoragePoolObjIsActive(obj)) {
1037
        virReportError(VIR_ERR_OPERATION_INVALID,
1038
                       _("storage pool '%s' is already active"),
1039
                       def->name);
1040
        goto cleanup;
1041 1042
    }

1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
    if (virStoragePoolObjIsStarting(obj)) {
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is starting up"),
                       def->name);
        goto cleanup;
    }

    virStoragePoolObjSetStarting(obj, true);
    restoreStarting = true;

1053
    if (backend->buildPool &&
1054
        backend->buildPool(obj, flags) < 0)
1055
        goto cleanup;
1056

1057 1058
    event = virStoragePoolEventLifecycleNew(def->name,
                                            def->uuid,
1059 1060 1061
                                            VIR_STORAGE_POOL_EVENT_CREATED,
                                            0);

1062
    ret = 0;
1063

1064
 cleanup:
1065 1066 1067 1068 1069
    if (restoreStarting &&
        virStoragePoolObjIsStarting(obj)) {
        virStoragePoolUpdateInactive(obj);
        virStoragePoolObjSetStarting(obj, false);
    }
1070
    virObjectEventStateQueue(driver->storageEventState, event);
1071
    virStoragePoolObjEndAPI(&obj);
1072
    return ret;
1073 1074 1075 1076
}


static int
1077
storagePoolDestroy(virStoragePoolPtr pool)
1078
{
1079
    virStoragePoolObjPtr obj;
1080
    virStoragePoolDefPtr def;
1081
    virStorageBackendPtr backend;
1082
    virObjectEventPtr event = NULL;
1083
    int ret = -1;
1084
    g_autofree char *stateFile = NULL;
1085

1086
    if (!(obj = storagePoolObjFindByUUID(pool->uuid, pool->name)))
1087
        goto cleanup;
1088
    def = virStoragePoolObjGetDef(obj);
1089

1090
    if (virStoragePoolDestroyEnsureACL(pool->conn, def) < 0)
1091 1092
        goto cleanup;

1093
    if ((backend = virStorageBackendForType(def->type)) == NULL)
1094
        goto cleanup;
1095

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

1098
    if (!virStoragePoolObjIsActive(obj)) {
1099
        virReportError(VIR_ERR_OPERATION_INVALID,
1100
                       _("storage pool '%s' is not active"), def->name);
1101
        goto cleanup;
1102 1103
    }

1104 1105 1106 1107 1108 1109 1110
    if (virStoragePoolObjIsStarting(obj)) {
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is starting up"),
                       def->name);
        goto cleanup;
    }

1111
    if (virStoragePoolObjGetAsyncjobs(obj) > 0) {
1112 1113
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("pool '%s' has asynchronous jobs running."),
1114
                       def->name);
1115 1116 1117
        goto cleanup;
    }

1118
    if (!(stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml")))
1119 1120 1121 1122
        goto cleanup;

    unlink(stateFile);

1123
    if (backend->stopPool &&
1124
        backend->stopPool(obj) < 0)
1125
        goto cleanup;
1126

1127
    virStoragePoolObjClearVols(obj);
1128

1129 1130
    event = virStoragePoolEventLifecycleNew(def->name,
                                            def->uuid,
1131 1132 1133
                                            VIR_STORAGE_POOL_EVENT_STOPPED,
                                            0);

1134
    virStoragePoolObjSetActive(obj, false);
1135

1136
    virStoragePoolUpdateInactive(obj);
1137

1138
    ret = 0;
1139

1140
 cleanup:
1141
    virObjectEventStateQueue(driver->storageEventState, event);
1142
    virStoragePoolObjEndAPI(&obj);
1143
    return ret;
1144 1145 1146
}

static int
1147
storagePoolDelete(virStoragePoolPtr pool,
1148 1149
                  unsigned int flags)
{
1150
    virStoragePoolObjPtr obj;
1151
    virStoragePoolDefPtr def;
1152
    virStorageBackendPtr backend;
1153
    virObjectEventPtr event = NULL;
1154
    int ret = -1;
1155
    g_autofree char *stateFile = NULL;
1156

1157
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1158
        return -1;
1159
    def = virStoragePoolObjGetDef(obj);
1160

1161
    if (virStoragePoolDeleteEnsureACL(pool->conn, def) < 0)
1162 1163
        goto cleanup;

1164
    if ((backend = virStorageBackendForType(def->type)) == NULL)
1165
        goto cleanup;
1166

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

1169
    if (virStoragePoolObjIsActive(obj)) {
1170
        virReportError(VIR_ERR_OPERATION_INVALID,
1171
                       _("storage pool '%s' is still active"),
1172
                       def->name);
1173
        goto cleanup;
1174 1175
    }

1176 1177 1178 1179 1180 1181 1182
    if (virStoragePoolObjIsStarting(obj)) {
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is starting up"),
                       def->name);
        goto cleanup;
    }

1183
    if (virStoragePoolObjGetAsyncjobs(obj) > 0) {
1184 1185
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("pool '%s' has asynchronous jobs running."),
1186
                       def->name);
1187 1188 1189
        goto cleanup;
    }

1190
    if (!(stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml")))
1191 1192 1193 1194
        goto cleanup;

    unlink(stateFile);

1195
    if (!backend->deletePool) {
1196 1197
        virReportError(VIR_ERR_NO_SUPPORT,
                       "%s", _("pool does not support pool deletion"));
1198
        goto cleanup;
1199
    }
1200
    if (backend->deletePool(obj, flags) < 0)
1201
        goto cleanup;
1202

1203 1204
    event = virStoragePoolEventLifecycleNew(def->name,
                                            def->uuid,
1205 1206 1207
                                            VIR_STORAGE_POOL_EVENT_DELETED,
                                            0);

1208
    ret = 0;
1209

1210
 cleanup:
1211
    virObjectEventStateQueue(driver->storageEventState, event);
1212
    virStoragePoolObjEndAPI(&obj);
1213
    return ret;
1214 1215 1216 1217
}


static int
1218
storagePoolRefresh(virStoragePoolPtr pool,
E
Eric Blake 已提交
1219 1220
                   unsigned int flags)
{
1221
    virStoragePoolObjPtr obj;
1222
    virStoragePoolDefPtr def;
1223
    virStorageBackendPtr backend;
1224
    g_autofree char *stateFile = NULL;
1225
    int ret = -1;
1226
    virObjectEventPtr event = NULL;
1227

E
Eric Blake 已提交
1228 1229
    virCheckFlags(0, -1);

1230
    if (!(obj = storagePoolObjFindByUUID(pool->uuid, pool->name)))
1231
        goto cleanup;
1232
    def = virStoragePoolObjGetDef(obj);
1233

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

1237
    if ((backend = virStorageBackendForType(def->type)) == NULL)
1238
        goto cleanup;
1239

1240
    if (!virStoragePoolObjIsActive(obj)) {
1241
        virReportError(VIR_ERR_OPERATION_INVALID,
1242
                       _("storage pool '%s' is not active"), def->name);
1243
        goto cleanup;
1244 1245
    }

1246 1247 1248 1249 1250 1251 1252
    if (virStoragePoolObjIsStarting(obj)) {
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is starting up"),
                       def->name);
        goto cleanup;
    }

1253
    if (virStoragePoolObjGetAsyncjobs(obj) > 0) {
1254 1255
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("pool '%s' has asynchronous jobs running."),
1256
                       def->name);
1257 1258 1259
        goto cleanup;
    }

1260 1261
    stateFile = virFileBuildPath(driver->stateDir, def->name, ".xml");
    if (storagePoolRefreshImpl(backend, obj, stateFile) < 0) {
1262 1263
        event = virStoragePoolEventLifecycleNew(def->name,
                                                def->uuid,
1264 1265
                                                VIR_STORAGE_POOL_EVENT_STOPPED,
                                                0);
1266
        virStoragePoolObjSetActive(obj, false);
1267

1268
        virStoragePoolUpdateInactive(obj);
1269

1270
        goto cleanup;
1271
    }
1272

1273 1274
    event = virStoragePoolEventRefreshNew(def->name,
                                          def->uuid);
1275
    ret = 0;
1276

1277
 cleanup:
1278
    virObjectEventStateQueue(driver->storageEventState, event);
1279
    virStoragePoolObjEndAPI(&obj);
1280 1281 1282 1283 1284
    return ret;
}


static int
1285
storagePoolGetInfo(virStoragePoolPtr pool,
1286 1287
                   virStoragePoolInfoPtr info)
{
1288
    virStoragePoolObjPtr obj;
1289
    virStoragePoolDefPtr def;
1290
    int ret = -1;
1291

1292
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1293
        return -1;
1294
    def = virStoragePoolObjGetDef(obj);
1295

1296
    if (virStoragePoolGetInfoEnsureACL(pool->conn, def) < 0)
1297 1298
        goto cleanup;

1299
    if (virStorageBackendForType(def->type) == NULL)
1300
        goto cleanup;
1301 1302

    memset(info, 0, sizeof(virStoragePoolInfo));
1303
    if (virStoragePoolObjIsActive(obj))
1304 1305 1306
        info->state = VIR_STORAGE_POOL_RUNNING;
    else
        info->state = VIR_STORAGE_POOL_INACTIVE;
1307 1308 1309
    info->capacity = def->capacity;
    info->allocation = def->allocation;
    info->available = def->available;
1310
    ret = 0;
1311

1312
 cleanup:
1313
    virStoragePoolObjEndAPI(&obj);
1314
    return ret;
1315 1316 1317
}

static char *
1318
storagePoolGetXMLDesc(virStoragePoolPtr pool,
E
Eric Blake 已提交
1319 1320
                      unsigned int flags)
{
1321
    virStoragePoolObjPtr obj;
1322
    virStoragePoolDefPtr def;
1323 1324
    virStoragePoolDefPtr newDef;
    virStoragePoolDefPtr curDef;
1325
    char *ret = NULL;
1326

1327
    virCheckFlags(VIR_STORAGE_XML_INACTIVE, NULL);
E
Eric Blake 已提交
1328

1329
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1330
        return NULL;
1331 1332
    def = virStoragePoolObjGetDef(obj);
    newDef = virStoragePoolObjGetNewDef(obj);
1333

1334
    if (virStoragePoolGetXMLDescEnsureACL(pool->conn, def) < 0)
1335 1336
        goto cleanup;

1337 1338
    if ((flags & VIR_STORAGE_XML_INACTIVE) && newDef)
        curDef = newDef;
1339
    else
1340
        curDef = def;
1341

1342
    ret = virStoragePoolDefFormat(curDef);
1343

1344
 cleanup:
1345
    virStoragePoolObjEndAPI(&obj);
1346
    return ret;
1347 1348 1349
}

static int
1350
storagePoolGetAutostart(virStoragePoolPtr pool,
1351 1352
                        int *autostart)
{
1353
    virStoragePoolObjPtr obj;
1354
    int ret = -1;
1355

1356
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1357
        return -1;
1358

1359 1360
    if (virStoragePoolGetAutostartEnsureACL(pool->conn,
                                            virStoragePoolObjGetDef(obj)) < 0)
1361 1362
        goto cleanup;

1363
    *autostart = virStoragePoolObjIsAutostart(obj) ? 1 : 0;
1364

1365
    ret = 0;
1366

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

static int
1373
storagePoolSetAutostart(virStoragePoolPtr pool,
1374 1375
                        int autostart)
{
1376
    virStoragePoolObjPtr obj;
1377
    const char *configFile;
1378
    const char *autostartLink;
1379 1380
    bool new_autostart;
    bool cur_autostart;
1381
    int ret = -1;
1382

1383
    if (!(obj = storagePoolObjFindByUUID(pool->uuid, pool->name)))
1384
        goto cleanup;
1385

1386 1387
    if (virStoragePoolSetAutostartEnsureACL(pool->conn,
                                            virStoragePoolObjGetDef(obj)) < 0)
1388 1389
        goto cleanup;

1390
    if (!(configFile = virStoragePoolObjGetConfigFile(obj))) {
1391 1392
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("pool has no config file"));
1393
        goto cleanup;
1394 1395
    }

1396 1397
    autostartLink = virStoragePoolObjGetAutostartLink(obj);

1398 1399 1400 1401
    new_autostart = (autostart != 0);
    cur_autostart = virStoragePoolObjIsAutostart(obj);
    if (cur_autostart != new_autostart) {
        if (new_autostart) {
1402 1403
            if (virFileMakePath(driver->autostartDir) < 0) {
                virReportSystemError(errno,
1404 1405
                                     _("cannot create autostart directory %s"),
                                     driver->autostartDir);
1406 1407
                goto cleanup;
            }
1408

1409
            if (symlink(configFile, autostartLink) < 0) {
1410
                virReportSystemError(errno,
1411
                                     _("Failed to create symlink '%s' to '%s'"),
1412
                                     autostartLink, configFile);
1413 1414 1415
                goto cleanup;
            }
        } else {
1416
            if (autostartLink && unlink(autostartLink) < 0 &&
1417
                errno != ENOENT && errno != ENOTDIR) {
1418
                virReportSystemError(errno,
1419
                                     _("Failed to delete symlink '%s'"),
1420
                                     autostartLink);
1421 1422
                goto cleanup;
            }
1423
        }
1424
        virStoragePoolObjSetAutostart(obj, new_autostart);
1425
    }
1426

1427
    ret = 0;
1428

1429
 cleanup:
1430
    virStoragePoolObjEndAPI(&obj);
1431
    return ret;
1432 1433 1434 1435
}


static int
1436
storagePoolNumOfVolumes(virStoragePoolPtr pool)
1437
{
1438
    virStoragePoolObjPtr obj;
1439
    virStoragePoolDefPtr def;
1440
    int ret = -1;
1441

1442
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1443
        return -1;
1444
    def = virStoragePoolObjGetDef(obj);
1445

1446
    if (virStoragePoolNumOfVolumesEnsureACL(pool->conn, def) < 0)
1447 1448
        goto cleanup;

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

1455
    ret = virStoragePoolObjNumOfVolumes(obj, pool->conn,
1456
                                        virStoragePoolNumOfVolumesCheckACL);
1457

1458
 cleanup:
1459
    virStoragePoolObjEndAPI(&obj);
1460
    return ret;
1461 1462
}

1463

1464
static int
1465
storagePoolListVolumes(virStoragePoolPtr pool,
1466
                       char **const names,
1467 1468
                       int maxnames)
{
1469
    virStoragePoolObjPtr obj;
1470
    virStoragePoolDefPtr def;
1471
    int n = -1;
1472

1473
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1474
        return -1;
1475
    def = virStoragePoolObjGetDef(obj);
1476

1477
    if (virStoragePoolListVolumesEnsureACL(pool->conn, def) < 0)
1478 1479
        goto cleanup;

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

1486
    n = virStoragePoolObjVolumeGetNames(obj, pool->conn,
1487 1488
                                        virStoragePoolListVolumesCheckACL,
                                        names, maxnames);
1489
 cleanup:
1490
    virStoragePoolObjEndAPI(&obj);
1491
    return n;
1492 1493
}

1494

1495 1496 1497
static int
storagePoolListAllVolumes(virStoragePoolPtr pool,
                          virStorageVolPtr **vols,
1498 1499
                          unsigned int flags)
{
1500
    virStoragePoolObjPtr obj;
1501
    virStoragePoolDefPtr def;
1502 1503 1504 1505
    int ret = -1;

    virCheckFlags(0, -1);

1506 1507
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
        return -1;
1508
    def = virStoragePoolObjGetDef(obj);
1509

1510
    if (virStoragePoolListAllVolumesEnsureACL(pool->conn, def) < 0)
1511 1512
        goto cleanup;

1513
    if (!virStoragePoolObjIsActive(obj)) {
1514
        virReportError(VIR_ERR_OPERATION_INVALID,
1515
                       _("storage pool '%s' is not active"), def->name);
1516 1517 1518
        goto cleanup;
    }

1519
    ret = virStoragePoolObjVolumeListExport(pool->conn, obj, vols,
1520
                                            virStoragePoolListAllVolumesCheckACL);
1521 1522 1523


 cleanup:
1524
    virStoragePoolObjEndAPI(&obj);
1525 1526 1527

    return ret;
}
1528 1529

static virStorageVolPtr
1530
storageVolLookupByName(virStoragePoolPtr pool,
1531 1532
                       const char *name)
{
1533
    virStoragePoolObjPtr obj;
1534
    virStoragePoolDefPtr def;
1535 1536
    virStorageVolDefPtr voldef;
    virStorageVolPtr vol = NULL;
1537

1538
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1539
        return NULL;
1540
    def = virStoragePoolObjGetDef(obj);
1541

1542
    if (!virStoragePoolObjIsActive(obj)) {
1543
        virReportError(VIR_ERR_OPERATION_INVALID,
1544
                       _("storage pool '%s' is not active"), def->name);
1545
        goto cleanup;
1546 1547
    }

1548
    voldef = virStorageVolDefFindByName(obj, name);
1549

1550
    if (!voldef) {
1551 1552 1553
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"),
                       name);
1554
        goto cleanup;
1555 1556
    }

1557
    if (virStorageVolLookupByNameEnsureACL(pool->conn, def, voldef) < 0)
1558 1559
        goto cleanup;

1560
    vol = virGetStorageVol(pool->conn, def->name, voldef->name,
1561
                           voldef->key, NULL, NULL);
1562

1563
 cleanup:
1564
    virStoragePoolObjEndAPI(&obj);
1565
    return vol;
1566 1567 1568
}


1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579
struct storageVolLookupData {
    const char *key;
    char *cleanpath;
    const char *path;
    virStorageVolDefPtr voldef;
};

static bool
storageVolLookupByKeyCallback(virStoragePoolObjPtr obj,
                              const void *opaque)
{
1580
    struct storageVolLookupData *data = (struct storageVolLookupData *)opaque;
1581 1582 1583 1584 1585 1586 1587 1588

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

    return !!data->voldef;
}


1589
static virStorageVolPtr
1590
storageVolLookupByKey(virConnectPtr conn,
1591 1592
                      const char *key)
{
1593 1594 1595
    virStoragePoolObjPtr obj;
    virStoragePoolDefPtr def;
    struct storageVolLookupData data = {
1596
        .key = key, .voldef = NULL };
1597
    virStorageVolPtr vol = NULL;
1598

1599
    if ((obj = virStoragePoolObjListSearch(driver->pools,
1600 1601
                                           storageVolLookupByKeyCallback,
                                           &data)) && data.voldef) {
1602
        def = virStoragePoolObjGetDef(obj);
1603 1604 1605 1606
        if (virStorageVolLookupByKeyEnsureACL(conn, def, data.voldef) == 0) {
            vol = virGetStorageVol(conn, def->name,
                                   data.voldef->name, data.voldef->key,
                                   NULL, NULL);
1607
        }
1608
        virStoragePoolObjEndAPI(&obj);
1609 1610
    }

1611
    if (!vol)
1612
        virReportError(VIR_ERR_NO_STORAGE_VOL,
1613
                       _("no storage vol with matching key %s"), key);
1614

1615
    return vol;
1616 1617
}

1618 1619 1620 1621 1622

static bool
storageVolLookupByPathCallback(virStoragePoolObjPtr obj,
                               const void *opaque)
{
1623
    struct storageVolLookupData *data = (struct storageVolLookupData *)opaque;
1624
    virStoragePoolDefPtr def;
1625
    g_autofree char *stable_path = NULL;
1626 1627 1628 1629 1630 1631

    if (!virStoragePoolObjIsActive(obj))
        return false;

    def = virStoragePoolObjGetDef(obj);

1632
    switch ((virStoragePoolType)def->type) {
1633 1634 1635 1636 1637 1638
        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:
1639
        case VIR_STORAGE_POOL_ISCSI_DIRECT:
1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651
        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:
1652
            stable_path = g_strdup(data->path);
1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668
            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;
}


1669
static virStorageVolPtr
1670
storageVolLookupByPath(virConnectPtr conn,
1671 1672
                       const char *path)
{
1673 1674 1675
    virStoragePoolObjPtr obj;
    virStoragePoolDefPtr def;
    struct storageVolLookupData data = {
1676
        .path = path, .voldef = NULL };
1677
    virStorageVolPtr vol = NULL;
1678

1679
    if (!(data.cleanpath = virFileSanitizePath(path)))
1680
        return NULL;
1681

1682
    if ((obj = virStoragePoolObjListSearch(driver->pools,
1683 1684
                                           storageVolLookupByPathCallback,
                                           &data)) && data.voldef) {
1685
        def = virStoragePoolObjGetDef(obj);
1686

1687
        if (virStorageVolLookupByPathEnsureACL(conn, def, data.voldef) == 0) {
1688
            vol = virGetStorageVol(conn, def->name,
1689
                                   data.voldef->name, data.voldef->key,
1690
                                   NULL, NULL);
1691
        }
1692
        virStoragePoolObjEndAPI(&obj);
1693 1694
    }

1695
    if (!vol) {
1696
        if (STREQ(path, data.cleanpath)) {
1697 1698 1699 1700 1701
            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)"),
1702
                           path, data.cleanpath);
1703 1704
        }
    }
1705

1706
    VIR_FREE(data.cleanpath);
1707
    return vol;
1708 1709
}

1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721

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

    if (!virStoragePoolObjIsActive(obj))
        return false;

    def = virStoragePoolObjGetDef(obj);
1722
    return STREQ_NULLABLE(path, def->target.path);
1723 1724 1725
}


1726 1727 1728 1729
virStoragePoolPtr
storagePoolLookupByTargetPath(virConnectPtr conn,
                              const char *path)
{
1730 1731
    virStoragePoolObjPtr obj;
    virStoragePoolDefPtr def;
1732
    virStoragePoolPtr pool = NULL;
1733
    g_autofree char *cleanpath = NULL;
1734 1735 1736 1737 1738

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

1739
    if ((obj = virStoragePoolObjListSearch(driver->pools,
1740
                                           storagePoolLookupByTargetPathCallback,
1741
                                           cleanpath))) {
1742
        def = virStoragePoolObjGetDef(obj);
1743
        if (virStoragePoolLookupByTargetPathEnsureACL(conn, def) < 0)
1744
            return NULL;
1745

1746
        pool = virGetStoragePool(conn, def->name, def->uuid, NULL, NULL);
1747
        virStoragePoolObjEndAPI(&obj);
1748 1749
    }

1750
    if (!pool) {
1751 1752 1753 1754 1755 1756 1757 1758 1759
        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);
        }
1760 1761
    }

1762
    return pool;
1763 1764
}

1765

1766
static int
1767
storageVolDeleteInternal(virStorageBackendPtr backend,
1768 1769
                         virStoragePoolObjPtr obj,
                         virStorageVolDefPtr voldef,
1770 1771 1772
                         unsigned int flags,
                         bool updateMeta)
{
1773
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj);
1774 1775 1776 1777 1778

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

1779
        return -1;
1780 1781
    }

1782
    if (backend->deleteVol(obj, voldef, flags) < 0)
1783
        return -1;
1784

1785 1786 1787
    /* The disk backend updated the pool data including removing the
     * voldef from the pool (for both the deleteVol and the createVol
     * failure path. */
1788 1789
    if (def->type == VIR_STORAGE_POOL_DISK)
        return 0;
1790

1791
    /* Update pool metadata - don't update meta data from error paths
1792 1793
     * in this module since the allocation/available weren't adjusted yet.
     * Ignore the disk backend since it updates the pool values.
1794 1795
     */
    if (updateMeta) {
1796 1797
        def->allocation -= voldef->target.allocation;
        def->available += voldef->target.allocation;
1798 1799
    }

1800
    virStoragePoolObjRemoveVol(obj, voldef);
1801

1802
    return 0;
1803 1804 1805
}


1806
static virStorageVolDefPtr
1807 1808
virStorageVolDefFromVol(virStorageVolPtr vol,
                        virStoragePoolObjPtr *obj,
1809
                        virStorageBackendPtr *backend)
1810
{
1811
    virStorageVolDefPtr voldef = NULL;
1812
    virStoragePoolDefPtr def;
1813

1814
    if (!(*obj = storagePoolObjFindByName(vol->pool)))
1815
        return NULL;
1816
    def = virStoragePoolObjGetDef(*obj);
1817

1818
    if (!virStoragePoolObjIsActive(*obj)) {
1819
        virReportError(VIR_ERR_OPERATION_INVALID,
1820
                       _("storage pool '%s' is not active"),
1821
                       def->name);
1822
        goto error;
1823 1824
    }

1825
    if (!(voldef = virStorageVolDefFindByName(*obj, vol->name))) {
1826 1827
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"),
1828
                       vol->name);
1829
        goto error;
1830 1831
    }

1832
    if (backend) {
1833
        if (!(*backend = virStorageBackendForType(def->type)))
1834 1835 1836
            goto error;
    }

1837
    return voldef;
1838 1839

 error:
1840
    virStoragePoolObjEndAPI(obj);
1841 1842 1843 1844 1845 1846

    return NULL;
}


static int
1847
storageVolDelete(virStorageVolPtr vol,
1848 1849
                 unsigned int flags)
{
1850
    virStoragePoolObjPtr obj;
1851
    virStorageBackendPtr backend;
1852
    virStorageVolDefPtr voldef = NULL;
1853 1854
    int ret = -1;

1855
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend)))
1856 1857
        return -1;

1858 1859
    if (virStorageVolDeleteEnsureACL(vol->conn, virStoragePoolObjGetDef(obj),
                                     voldef) < 0)
1860 1861
        goto cleanup;

1862
    if (voldef->in_use) {
1863 1864
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still in use."),
1865
                       voldef->name);
1866 1867 1868
        goto cleanup;
    }

1869
    if (voldef->building) {
1870 1871
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
1872
                       voldef->name);
1873 1874 1875
        goto cleanup;
    }

1876
    if (storageVolDeleteInternal(backend, obj, voldef, flags, true) < 0)
1877 1878 1879 1880
        goto cleanup;

    ret = 0;

1881
 cleanup:
1882
    virStoragePoolObjEndAPI(&obj);
1883 1884 1885
    return ret;
}

1886

1887
static virStorageVolPtr
1888
storageVolCreateXML(virStoragePoolPtr pool,
1889 1890
                    const char *xmldesc,
                    unsigned int flags)
E
Eric Blake 已提交
1891
{
1892
    virStoragePoolObjPtr obj;
1893
    virStoragePoolDefPtr def;
1894
    virStorageBackendPtr backend;
1895
    virStorageVolPtr vol = NULL, newvol = NULL;
J
Ján Tomko 已提交
1896
    g_autoptr(virStorageVolDef) voldef = NULL;
1897

1898
    virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, NULL);
E
Eric Blake 已提交
1899

1900
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
1901
        return NULL;
1902
    def = virStoragePoolObjGetDef(obj);
1903

1904
    if (!virStoragePoolObjIsActive(obj)) {
1905
        virReportError(VIR_ERR_OPERATION_INVALID,
1906
                       _("storage pool '%s' is not active"), def->name);
1907
        goto cleanup;
1908 1909
    }

1910
    if ((backend = virStorageBackendForType(def->type)) == NULL)
1911
        goto cleanup;
1912

1913
    voldef = virStorageVolDefParseString(def, xmldesc,
1914
                                         VIR_VOL_XML_PARSE_OPT_CAPACITY);
1915
    if (voldef == NULL)
1916
        goto cleanup;
1917

1918 1919 1920 1921 1922 1923 1924
    if (!voldef->target.capacity && !backend->buildVol) {
        virReportError(VIR_ERR_NO_SUPPORT,
                       "%s", _("volume capacity required for this "
                               "storage pool"));
        goto cleanup;
    }

1925
    if (virStorageVolCreateXMLEnsureACL(pool->conn, def, voldef) < 0)
1926 1927
        goto cleanup;

1928
    if (virStorageVolDefFindByName(obj, voldef->name)) {
1929
        virReportError(VIR_ERR_STORAGE_VOL_EXIST,
1930
                       _("'%s'"), voldef->name);
1931
        goto cleanup;
1932 1933 1934
    }

    if (!backend->createVol) {
1935 1936 1937
        virReportError(VIR_ERR_NO_SUPPORT,
                       "%s", _("storage pool does not support volume "
                               "creation"));
1938
        goto cleanup;
1939 1940
    }

1941 1942 1943
    /* Wipe any key the user may have suggested, as volume creation
     * will generate the canonical key.  */
    VIR_FREE(voldef->key);
1944
    if (backend->createVol(obj, voldef) < 0)
1945
        goto cleanup;
1946

1947
    if (!(newvol = virGetStorageVol(pool->conn, def->name, voldef->name,
1948
                                    voldef->key, NULL, NULL)))
1949 1950
        goto cleanup;

1951 1952 1953
    /* NB: Upon success voldef "owned" by storage pool for deletion purposes */
    if (virStoragePoolObjAddVol(obj, voldef) < 0)
        goto cleanup;
1954

1955 1956
    if (backend->buildVol) {
        int buildret;
1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968
        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));
1969 1970

        /* Drop the pool lock during volume allocation */
1971
        virStoragePoolObjIncrAsyncjobs(obj);
1972
        voldef->building = true;
1973
        virObjectUnlock(obj);
1974

1975
        buildret = backend->buildVol(obj, buildvoldef, flags);
1976

1977 1978
        VIR_FREE(buildvoldef);

1979
        virObjectLock(obj);
1980

1981
        voldef->building = false;
1982
        virStoragePoolObjDecrAsyncjobs(obj);
1983

1984
        if (buildret < 0) {
1985
            /* buildVol handles deleting volume on failure */
1986
            virStoragePoolObjRemoveVol(obj, voldef);
1987
            voldef = NULL;
1988
            goto cleanup;
1989
        }
1990

1991
    }
1992

1993
    if (backend->refreshVol &&
1994 1995
        backend->refreshVol(obj, voldef) < 0) {
        storageVolDeleteInternal(backend, obj, voldef,
1996 1997
                                 0, false);
        voldef = NULL;
1998
        goto cleanup;
1999
    }
2000

2001 2002 2003
    /* Update pool metadata ignoring the disk backend since
     * it updates the pool values.
     */
2004 2005 2006
    if (def->type != VIR_STORAGE_POOL_DISK) {
        def->allocation += voldef->target.allocation;
        def->available -= voldef->target.allocation;
2007
    }
2008

2009
    VIR_INFO("Creating volume '%s' in storage pool '%s'",
2010
             newvol->name, def->name);
2011
    vol = g_steal_pointer(&newvol);
2012
    voldef = NULL;
2013

2014
 cleanup:
2015
    virObjectUnref(newvol);
2016
    virStoragePoolObjEndAPI(&obj);
2017
    return vol;
2018 2019
}

2020
static virStorageVolPtr
2021
storageVolCreateXMLFrom(virStoragePoolPtr pool,
2022
                        const char *xmldesc,
2023
                        virStorageVolPtr volsrc,
2024
                        unsigned int flags)
E
Eric Blake 已提交
2025
{
2026
    virStoragePoolObjPtr obj;
2027
    virStoragePoolDefPtr def;
2028
    virStoragePoolObjPtr objsrc = NULL;
2029
    virStorageBackendPtr backend;
2030 2031 2032 2033
    virStorageVolDefPtr voldefsrc = NULL;
    virStorageVolDefPtr shadowvol = NULL;
    virStorageVolPtr newvol = NULL;
    virStorageVolPtr vol = NULL;
2034
    int buildret;
J
Ján Tomko 已提交
2035
    g_autoptr(virStorageVolDef) voldef = NULL;
2036

2037 2038 2039
    virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA |
                  VIR_STORAGE_VOL_CREATE_REFLINK,
                  NULL);
E
Eric Blake 已提交
2040

2041
    obj = virStoragePoolObjFindByUUID(driver->pools, pool->uuid);
2042
    if (obj && STRNEQ(pool->name, volsrc->pool)) {
2043
        virObjectUnlock(obj);
2044
        objsrc = virStoragePoolObjFindByName(driver->pools, volsrc->pool);
2045
        virObjectLock(obj);
2046
    }
2047
    if (!obj) {
2048
        char uuidstr[VIR_UUID_STRING_BUFLEN];
2049
        virUUIDFormat(pool->uuid, uuidstr);
2050
        virReportError(VIR_ERR_NO_STORAGE_POOL,
2051
                       _("no storage pool with matching uuid '%s' (%s)"),
2052
                       uuidstr, pool->name);
2053 2054
        goto cleanup;
    }
2055
    def = virStoragePoolObjGetDef(obj);
2056

2057
    if (STRNEQ(pool->name, volsrc->pool) && !objsrc) {
2058 2059
        virReportError(VIR_ERR_NO_STORAGE_POOL,
                       _("no storage pool with matching name '%s'"),
2060
                       volsrc->pool);
2061 2062 2063
        goto cleanup;
    }

2064
    if (!virStoragePoolObjIsActive(obj)) {
2065
        virReportError(VIR_ERR_OPERATION_INVALID,
2066
                       _("storage pool '%s' is not active"), def->name);
2067 2068 2069
        goto cleanup;
    }

2070
    if (objsrc && !virStoragePoolObjIsActive(objsrc)) {
2071
        virStoragePoolDefPtr objsrcdef = virStoragePoolObjGetDef(objsrc);
2072
        virReportError(VIR_ERR_OPERATION_INVALID,
2073
                       _("storage pool '%s' is not active"),
2074
                       objsrcdef->name);
2075 2076 2077
        goto cleanup;
    }

2078
    if ((backend = virStorageBackendForType(def->type)) == NULL)
2079 2080
        goto cleanup;

2081 2082 2083
    voldefsrc = virStorageVolDefFindByName(objsrc ?
                                           objsrc : obj, volsrc->name);
    if (!voldefsrc) {
2084 2085
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"),
2086
                       volsrc->name);
2087 2088 2089
        goto cleanup;
    }

2090
    voldef = virStorageVolDefParseString(def, xmldesc,
2091
                                         VIR_VOL_XML_PARSE_NO_CAPACITY);
2092
    if (voldef == NULL)
2093 2094
        goto cleanup;

2095
    if (virStorageVolCreateXMLFromEnsureACL(pool->conn, def, voldef) < 0)
2096 2097
        goto cleanup;

2098
    if (virStorageVolDefFindByName(obj, voldef->name)) {
2099 2100
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("storage volume name '%s' already in use."),
2101
                       voldef->name);
2102 2103 2104
        goto cleanup;
    }

2105 2106
    /* Use the original volume's capacity in case the new capacity
     * is less than that, or it was omitted */
2107 2108
    if (voldef->target.capacity < voldefsrc->target.capacity)
        voldef->target.capacity = voldefsrc->target.capacity;
2109

2110 2111 2112 2113
    /* 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. */
2114 2115
    if (!voldef->target.has_allocation)
        voldef->target.allocation = voldef->target.capacity;
2116

2117
    if (!backend->buildVolFrom) {
2118
        virReportError(VIR_ERR_NO_SUPPORT,
2119 2120
                       "%s", _("storage pool does not support"
                               " volume creation from an existing volume"));
2121 2122 2123
        goto cleanup;
    }

2124
    if (voldefsrc->building) {
2125 2126
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
2127
                       voldefsrc->name);
2128 2129 2130 2131
        goto cleanup;
    }

    if (backend->refreshVol &&
2132
        backend->refreshVol(obj, voldefsrc) < 0)
2133 2134
        goto cleanup;

2135 2136 2137
    /* '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.  */
2138
    VIR_FREE(voldef->key);
2139
    if (backend->createVol(obj, voldef) < 0)
2140 2141
        goto cleanup;

2142 2143 2144 2145 2146 2147 2148
    /* 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;

2149
    memcpy(shadowvol, voldef, sizeof(*voldef));
2150

2151
    if (!(newvol = virGetStorageVol(pool->conn, def->name, voldef->name,
2152 2153 2154 2155 2156
                                    voldef->key, NULL, NULL)))
        goto cleanup;

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

    /* Drop the pool lock during volume allocation */
2160
    virStoragePoolObjIncrAsyncjobs(obj);
2161 2162
    voldef->building = true;
    voldefsrc->in_use++;
2163
    virObjectUnlock(obj);
2164

2165
    if (objsrc) {
2166
        virStoragePoolObjIncrAsyncjobs(objsrc);
2167
        virObjectUnlock(objsrc);
2168 2169
    }

2170
    buildret = backend->buildVolFrom(obj, shadowvol, voldefsrc, flags);
2171

2172
    virObjectLock(obj);
2173
    if (objsrc)
2174
        virObjectLock(objsrc);
2175

2176 2177
    voldefsrc->in_use--;
    voldef->building = false;
2178
    virStoragePoolObjDecrAsyncjobs(obj);
2179

2180
    if (objsrc) {
2181
        virStoragePoolObjDecrAsyncjobs(objsrc);
2182
        virStoragePoolObjEndAPI(&objsrc);
2183 2184
    }

2185 2186
    if (buildret < 0 ||
        (backend->refreshVol &&
2187 2188
         backend->refreshVol(obj, voldef) < 0)) {
        storageVolDeleteInternal(backend, obj, voldef, 0, false);
2189
        voldef = NULL;
2190 2191 2192
        goto cleanup;
    }

2193 2194 2195
    /* Updating pool metadata ignoring the disk backend since
     * it updates the pool values
     */
2196 2197 2198
    if (def->type != VIR_STORAGE_POOL_DISK) {
        def->allocation += voldef->target.allocation;
        def->available -= voldef->target.allocation;
2199
    }
2200

2201
    VIR_INFO("Creating volume '%s' in storage pool '%s'",
2202
             newvol->name, def->name);
2203
    vol = g_steal_pointer(&newvol);
2204
    voldef = NULL;
2205

2206
 cleanup:
2207
    virObjectUnref(newvol);
2208
    VIR_FREE(shadowvol);
2209 2210
    virStoragePoolObjEndAPI(&obj);
    virStoragePoolObjEndAPI(&objsrc);
2211
    return vol;
2212 2213
}

2214

2215
static int
2216
storageVolDownload(virStorageVolPtr vol,
2217 2218 2219 2220
                   virStreamPtr stream,
                   unsigned long long offset,
                   unsigned long long length,
                   unsigned int flags)
2221
{
2222
    virStorageBackendPtr backend;
2223 2224
    virStoragePoolObjPtr obj = NULL;
    virStorageVolDefPtr voldef = NULL;
2225 2226
    int ret = -1;

2227
    virCheckFlags(VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM, -1);
2228

2229
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend)))
2230
        return -1;
2231

2232 2233
    if (virStorageVolDownloadEnsureACL(vol->conn, virStoragePoolObjGetDef(obj),
                                       voldef) < 0)
2234
        goto cleanup;
2235

2236
    if (voldef->building) {
2237 2238
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
2239
                       voldef->name);
2240
        goto cleanup;
2241 2242
    }

2243 2244 2245
    if (!backend->downloadVol) {
        virReportError(VIR_ERR_NO_SUPPORT, "%s",
                       _("storage pool doesn't support volume download"));
2246
        goto cleanup;
2247
    }
2248

2249 2250
    virStoragePoolObjIncrAsyncjobs(obj);
    voldef->in_use++;
2251
    virObjectUnlock(obj);
2252 2253 2254

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

2255
    virObjectLock(obj);
2256 2257
    voldef->in_use--;
    virStoragePoolObjDecrAsyncjobs(obj);
2258

2259
 cleanup:
2260
    virStoragePoolObjEndAPI(&obj);
2261 2262 2263 2264 2265

    return ret;
}


2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279
/**
 * Frees opaque data.
 *
 * @opaque Data to be freed.
 */
static void
virStorageVolPoolRefreshDataFree(void *opaque)
{
    virStorageVolStreamInfoPtr cbdata = opaque;

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

2280 2281 2282
static int
virStorageBackendPloopRestoreDesc(char *path)
{
J
Ján Tomko 已提交
2283
    g_autoptr(virCommand) cmd = NULL;
2284 2285
    g_autofree char *refresh_tool = NULL;
    g_autofree char *desc = NULL;
2286

2287
    desc = g_strdup_printf("%s/DiskDescriptor.xml", path);
2288 2289 2290 2291

    if (virFileRemove(desc, 0, 0) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("refresh ploop failed:"
Y
Yuri Chornoivan 已提交
2292
                         " unable to delete DiskDescriptor.xml"));
2293
        return -1;
2294 2295 2296 2297 2298 2299
    }

    refresh_tool = virFindFileInPath("ploop");
    if (!refresh_tool) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("unable to find ploop, please install ploop tools"));
2300
        return -1;
2301 2302 2303 2304 2305
    }

    cmd = virCommandNewArgList(refresh_tool, "restore-descriptor",
                               path, NULL);
    virCommandAddArgFormat(cmd, "%s/root.hds", path);
2306
    return virCommandRun(cmd, NULL);
2307 2308 2309 2310
}



2311 2312 2313 2314 2315 2316 2317 2318 2319 2320
/**
 * 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;
2321
    virStoragePoolObjPtr obj = NULL;
2322
    virStoragePoolDefPtr def;
2323
    virStorageBackendPtr backend;
2324
    virObjectEventPtr event = NULL;
2325

2326 2327 2328 2329
    if (cbdata->vol_path) {
        if (virStorageBackendPloopRestoreDesc(cbdata->vol_path) < 0)
            goto cleanup;
    }
2330
    if (!(obj = virStoragePoolObjFindByName(driver->pools,
2331
                                            cbdata->pool_name)))
2332
        goto cleanup;
2333
    def = virStoragePoolObjGetDef(obj);
2334

2335 2336 2337 2338 2339 2340 2341
    /* 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;
    }

2342
    if (!(backend = virStorageBackendForType(def->type)))
2343 2344
        goto cleanup;

2345
    if (storagePoolRefreshImpl(backend, obj, NULL) < 0)
2346 2347
        VIR_DEBUG("Failed to refresh storage pool");

2348
    event = virStoragePoolEventRefreshNew(def->name, def->uuid);
2349

2350
 cleanup:
2351
    virObjectEventStateQueue(driver->storageEventState, event);
2352
    virStoragePoolObjEndAPI(&obj);
2353 2354 2355 2356 2357 2358 2359 2360
    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 已提交
2361
 * @opaque Buffer to hold the pool name to be refreshed
2362 2363
 */
static void
J
Ján Tomko 已提交
2364
virStorageVolFDStreamCloseCb(virStreamPtr st G_GNUC_UNUSED,
2365 2366 2367 2368
                             void *opaque)
{
    virThread thread;

2369 2370
    if (virThreadCreateFull(&thread, false, virStorageVolPoolRefreshThread,
                            "vol-refresh", false, opaque) < 0) {
2371 2372 2373 2374 2375 2376 2377 2378 2379 2380
        /* 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);
}

2381
static int
2382
storageVolUpload(virStorageVolPtr vol,
2383 2384 2385 2386
                 virStreamPtr stream,
                 unsigned long long offset,
                 unsigned long long length,
                 unsigned int flags)
2387
{
2388
    virStorageBackendPtr backend;
2389
    virStoragePoolObjPtr obj = NULL;
2390
    virStoragePoolDefPtr def;
2391
    virStorageVolDefPtr voldef = NULL;
2392
    virStorageVolStreamInfoPtr cbdata = NULL;
2393
    int rc;
2394 2395
    int ret = -1;

2396
    virCheckFlags(VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM, -1);
2397

2398
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend)))
2399
        return -1;
2400
    def = virStoragePoolObjGetDef(obj);
2401

2402
    if (virStorageVolUploadEnsureACL(vol->conn, def, voldef) < 0)
2403
        goto cleanup;
2404

2405
    if (voldef->in_use) {
2406 2407
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still in use."),
2408
                       voldef->name);
2409 2410 2411
        goto cleanup;
    }

2412
    if (voldef->building) {
2413 2414
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
2415
                       voldef->name);
2416
        goto cleanup;
2417 2418
    }

2419 2420 2421
    if (!backend->uploadVol) {
        virReportError(VIR_ERR_NO_SUPPORT, "%s",
                       _("storage pool doesn't support volume upload"));
2422
        goto cleanup;
2423
    }
2424

2425
    /* Use the callback routine in order to
2426 2427 2428 2429 2430
     * 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.
     */
2431
    if (VIR_ALLOC(cbdata) < 0)
2432
        goto cleanup;
2433 2434 2435
    cbdata->pool_name = g_strdup(def->name);
    if (voldef->type == VIR_STORAGE_VOL_PLOOP)
        cbdata->vol_path = g_strdup(voldef->target.path);
2436

2437 2438
    virStoragePoolObjIncrAsyncjobs(obj);
    voldef->in_use++;
2439
    virObjectUnlock(obj);
2440 2441 2442

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

2443
    virObjectLock(obj);
2444 2445 2446 2447
    voldef->in_use--;
    virStoragePoolObjDecrAsyncjobs(obj);

    if (rc < 0)
2448
        goto cleanup;
2449

2450 2451 2452
    /* Add cleanup callback - call after uploadVol since the stream
     * is then fully set up
     */
C
Cole Robinson 已提交
2453 2454 2455 2456
    virFDStreamSetInternalCloseCb(stream,
                                  virStorageVolFDStreamCloseCb,
                                  cbdata, NULL);
    cbdata = NULL;
2457
    ret = 0;
2458
 cleanup:
2459
    virStoragePoolObjEndAPI(&obj);
2460 2461
    if (cbdata)
        virStorageVolPoolRefreshDataFree(cbdata);
2462 2463 2464 2465

    return ret;
}

2466
static int
2467
storageVolResize(virStorageVolPtr vol,
2468 2469
                 unsigned long long capacity,
                 unsigned int flags)
2470 2471
{
    virStorageBackendPtr backend;
2472
    virStoragePoolObjPtr obj = NULL;
2473
    virStoragePoolDefPtr def;
2474
    virStorageVolDefPtr voldef = NULL;
2475
    unsigned long long abs_capacity, delta = 0;
2476 2477
    int ret = -1;

2478
    virCheckFlags(VIR_STORAGE_VOL_RESIZE_ALLOCATE |
2479 2480
                  VIR_STORAGE_VOL_RESIZE_DELTA |
                  VIR_STORAGE_VOL_RESIZE_SHRINK, -1);
2481

2482
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend)))
2483
        return -1;
2484
    def = virStoragePoolObjGetDef(obj);
2485

2486
    if (virStorageVolResizeEnsureACL(vol->conn, def, voldef) < 0)
2487
        goto cleanup;
2488

2489
    if (voldef->in_use) {
2490 2491
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still in use."),
2492
                       voldef->name);
2493 2494 2495
        goto cleanup;
    }

2496
    if (voldef->building) {
2497 2498
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
2499
                       voldef->name);
2500
        goto cleanup;
2501
    }
2502

2503
    if (flags & VIR_STORAGE_VOL_RESIZE_DELTA) {
2504
        if (flags & VIR_STORAGE_VOL_RESIZE_SHRINK)
2505
            abs_capacity = voldef->target.capacity - MIN(capacity, voldef->target.capacity);
2506
        else
2507
            abs_capacity = voldef->target.capacity + capacity;
2508 2509 2510 2511 2512
        flags &= ~VIR_STORAGE_VOL_RESIZE_DELTA;
    } else {
        abs_capacity = capacity;
    }

2513
    if (abs_capacity < voldef->target.allocation) {
2514
        virReportError(VIR_ERR_INVALID_ARG, "%s",
2515 2516
                       _("can't shrink capacity below "
                         "existing allocation"));
2517
        goto cleanup;
2518 2519
    }

2520
    if (abs_capacity < voldef->target.capacity &&
2521 2522 2523
        !(flags & VIR_STORAGE_VOL_RESIZE_SHRINK)) {
        virReportError(VIR_ERR_INVALID_ARG, "%s",
                       _("Can't shrink capacity below current "
2524
                         "capacity unless shrink flag explicitly specified"));
2525
        goto cleanup;
2526 2527
    }

2528
    if (flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE)
2529
        delta = abs_capacity - voldef->target.allocation;
2530

2531
    if (delta > def->available) {
2532
        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
2533
                       _("Not enough space left in storage pool"));
2534
        goto cleanup;
2535 2536 2537
    }

    if (!backend->resizeVol) {
2538
        virReportError(VIR_ERR_NO_SUPPORT, "%s",
2539 2540
                       _("storage pool does not support changing of "
                         "volume capacity"));
2541
        goto cleanup;
2542 2543
    }

2544
    if (backend->resizeVol(obj, voldef, abs_capacity, flags) < 0)
2545
        goto cleanup;
2546

2547
    voldef->target.capacity = abs_capacity;
2548 2549 2550 2551 2552
    /* 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) {
2553
        voldef->target.allocation = abs_capacity;
2554 2555
        def->allocation += delta;
        def->available -= delta;
2556
    }
2557

O
Osier Yang 已提交
2558
    ret = 0;
2559

2560
 cleanup:
2561
    virStoragePoolObjEndAPI(&obj);
2562 2563 2564

    return ret;
}
2565

2566 2567

static int
2568
storageVolWipePattern(virStorageVolPtr vol,
2569 2570
                      unsigned int algorithm,
                      unsigned int flags)
2571
{
2572
    virStorageBackendPtr backend;
2573 2574
    virStoragePoolObjPtr obj = NULL;
    virStorageVolDefPtr voldef = NULL;
2575
    int rc;
2576 2577
    int ret = -1;

2578
    virCheckFlags(0, -1);
2579

2580
    if (algorithm >= VIR_STORAGE_VOL_WIPE_ALG_LAST) {
2581 2582 2583
        virReportError(VIR_ERR_INVALID_ARG,
                       _("wiping algorithm %d not supported"),
                       algorithm);
2584 2585 2586
        return -1;
    }

2587
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend)))
2588
        return -1;
2589

2590 2591 2592
    if (virStorageVolWipePatternEnsureACL(vol->conn,
                                          virStoragePoolObjGetDef(obj),
                                          voldef) < 0)
2593
        goto cleanup;
2594

2595
    if (voldef->in_use) {
2596 2597
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still in use."),
2598
                       voldef->name);
2599 2600 2601
        goto cleanup;
    }

2602
    if (voldef->building) {
2603 2604
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
2605
                       voldef->name);
2606
        goto cleanup;
2607 2608
    }

2609 2610 2611
    if (!backend->wipeVol) {
        virReportError(VIR_ERR_NO_SUPPORT, "%s",
                       _("storage pool doesn't support volume wiping"));
2612
        goto cleanup;
2613
    }
2614

2615 2616
    virStoragePoolObjIncrAsyncjobs(obj);
    voldef->in_use++;
2617
    virObjectUnlock(obj);
2618 2619 2620

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

2621
    virObjectLock(obj);
2622 2623 2624 2625
    voldef->in_use--;
    virStoragePoolObjDecrAsyncjobs(obj);

    if (rc < 0)
2626 2627
        goto cleanup;

2628 2629 2630 2631 2632 2633 2634 2635 2636 2637
    /* 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)
2638 2639 2640
        goto cleanup;

    ret = 0;
2641

2642
 cleanup:
2643
    virStoragePoolObjEndAPI(&obj);
2644 2645 2646 2647

    return ret;
}

2648
static int
2649
storageVolWipe(virStorageVolPtr vol,
2650
               unsigned int flags)
2651
{
2652
    return storageVolWipePattern(vol, VIR_STORAGE_VOL_WIPE_ALG_ZERO, flags);
2653 2654
}

2655 2656

static int
2657
storageVolGetInfoFlags(virStorageVolPtr vol,
2658 2659
                       virStorageVolInfoPtr info,
                       unsigned int flags)
2660
{
2661
    virStoragePoolObjPtr obj;
2662
    virStorageBackendPtr backend;
2663
    virStorageVolDefPtr voldef;
2664
    int ret = -1;
2665

2666 2667
    virCheckFlags(VIR_STORAGE_VOL_GET_PHYSICAL, -1);

2668
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend)))
2669
        return -1;
2670

2671 2672 2673
    if (virStorageVolGetInfoFlagsEnsureACL(vol->conn,
                                           virStoragePoolObjGetDef(obj),
                                           voldef) < 0)
2674 2675
        goto cleanup;

2676
    if (backend->refreshVol &&
2677
        backend->refreshVol(obj, voldef) < 0)
2678
        goto cleanup;
2679 2680

    memset(info, 0, sizeof(*info));
2681 2682
    info->type = voldef->type;
    info->capacity = voldef->target.capacity;
2683
    if (flags & VIR_STORAGE_VOL_GET_PHYSICAL)
2684
        info->allocation = voldef->target.physical;
2685
    else
2686
        info->allocation = voldef->target.allocation;
2687
    ret = 0;
2688

2689
 cleanup:
2690
    virStoragePoolObjEndAPI(&obj);
2691
    return ret;
2692 2693
}

2694 2695

static int
2696
storageVolGetInfo(virStorageVolPtr vol,
2697 2698
                  virStorageVolInfoPtr info)
{
2699
    return storageVolGetInfoFlags(vol, info, 0);
2700 2701 2702
}


2703
static char *
2704
storageVolGetXMLDesc(virStorageVolPtr vol,
2705
                     unsigned int flags)
E
Eric Blake 已提交
2706
{
2707
    virStoragePoolObjPtr obj;
2708
    virStoragePoolDefPtr def;
2709
    virStorageBackendPtr backend;
2710
    virStorageVolDefPtr voldef;
2711
    char *ret = NULL;
2712

E
Eric Blake 已提交
2713 2714
    virCheckFlags(0, NULL);

2715
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, &backend)))
2716
        return NULL;
2717
    def = virStoragePoolObjGetDef(obj);
2718

2719
    if (virStorageVolGetXMLDescEnsureACL(vol->conn, def, voldef) < 0)
2720 2721
        goto cleanup;

2722
    if (backend->refreshVol &&
2723
        backend->refreshVol(obj, voldef) < 0)
2724
        goto cleanup;
2725

2726
    ret = virStorageVolDefFormat(def, voldef);
2727

2728
 cleanup:
2729
    virStoragePoolObjEndAPI(&obj);
2730

2731
    return ret;
2732 2733 2734
}

static char *
2735
storageVolGetPath(virStorageVolPtr vol)
2736
{
2737 2738
    virStoragePoolObjPtr obj;
    virStorageVolDefPtr voldef;
2739
    char *ret = NULL;
2740

2741
    if (!(voldef = virStorageVolDefFromVol(vol, &obj, NULL)))
2742
        return NULL;
2743

2744 2745
    if (virStorageVolGetPathEnsureACL(vol->conn, virStoragePoolObjGetDef(obj),
                                      voldef) < 0)
2746 2747
        goto cleanup;

2748
    ret = g_strdup(voldef->target.path);
2749

2750
 cleanup:
2751
    virStoragePoolObjEndAPI(&obj);
2752 2753 2754
    return ret;
}

2755
static int
2756 2757 2758
storageConnectListAllStoragePools(virConnectPtr conn,
                                  virStoragePoolPtr **pools,
                                  unsigned int flags)
2759 2760 2761
{
    virCheckFlags(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ALL, -1);

2762
    if (virConnectListAllStoragePoolsEnsureACL(conn) < 0)
2763
        return -1;
2764

2765 2766 2767
    return virStoragePoolObjListExport(conn, driver->pools, pools,
                                       virConnectListAllStoragePoolsCheckACL,
                                       flags);
2768 2769
}

2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780
static int
storageConnectStoragePoolEventRegisterAny(virConnectPtr conn,
                                          virStoragePoolPtr pool,
                                          int eventID,
                                          virConnectStoragePoolEventGenericCallback callback,
                                          void *opaque,
                                          virFreeCallback freecb)
{
    int callbackID = -1;

    if (virConnectStoragePoolEventRegisterAnyEnsureACL(conn) < 0)
2781
        return -1;
2782 2783 2784 2785 2786

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

2788 2789 2790 2791 2792 2793 2794 2795
    return callbackID;
}

static int
storageConnectStoragePoolEventDeregisterAny(virConnectPtr conn,
                                            int callbackID)
{
    if (virConnectStoragePoolEventDeregisterAnyEnsureACL(conn) < 0)
2796
        return -1;
2797 2798 2799

    if (virObjectEventStateDeregisterID(conn,
                                        driver->storageEventState,
2800
                                        callbackID, true) < 0)
2801
        return -1;
2802

2803
    return 0;
2804 2805 2806
}


2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820


/*
 * 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)
{
2821
    return virStoragePoolObjFindByUUID(driver->pools, uuid);
2822
}
2823 2824 2825 2826


/*
 * virStoragePoolObjBuildTempFilePath
2827
 * @obj: pool object pointer
2828 2829 2830 2831
 * @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
2832
 * for mkstemp
2833 2834 2835 2836
 *
 * Returns a string pointer on success, NULL on failure
 */
char *
2837 2838
virStoragePoolObjBuildTempFilePath(virStoragePoolObjPtr obj,
                                   virStorageVolDefPtr voldef)
2839 2840

{
2841
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(obj);
2842 2843
    char *tmp = NULL;

2844 2845
    tmp = g_strdup_printf("%s/%s.%s.secret.XXXXXX",
                          driver->stateDir, def->name, voldef->name);
2846 2847
    return tmp;
}
2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859


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 */
2860
    .connectGetStoragePoolCapabilities = storageConnectGetStoragePoolCapabilities, /* 5.2.0 */
2861 2862 2863
    .storagePoolLookupByName = storagePoolLookupByName, /* 0.4.0 */
    .storagePoolLookupByUUID = storagePoolLookupByUUID, /* 0.4.0 */
    .storagePoolLookupByVolume = storagePoolLookupByVolume, /* 0.4.0 */
2864
    .storagePoolLookupByTargetPath = storagePoolLookupByTargetPath, /* 4.1.0 */
2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901
    .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 */
};


2902 2903 2904 2905 2906 2907 2908
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 */
2909
    .connectGetCapabilities = storageConnectGetCapabilities, /* 5.2.0 */
2910 2911 2912
};

static virConnectDriver storageConnectDriver = {
2913
    .localOnly = true,
2914
    .uriSchemes = (const char *[]){ "storage", NULL },
2915 2916 2917 2918 2919
    .hypervisorDriver = &storageHypervisorDriver,
    .storageDriver = &storageDriver,
};


2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930
static virStateDriver stateDriver = {
    .name = "storage",
    .stateInitialize = storageStateInitialize,
    .stateCleanup = storageStateCleanup,
    .stateReload = storageStateReload,
};


static int
storageRegisterFull(bool allbackends)
{
2931 2932
    if (virRegisterConnectDriver(&storageConnectDriver, false) < 0)
        return -1;
2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954
    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);
}