storage_driver.c 87.6 KB
Newer Older
1 2 3
/*
 * storage_driver.c: core driver for storage APIs
 *
4
 * Copyright (C) 2006-2014 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 26 27 28
 *
 * Author: Daniel P. Berrange <berrange@redhat.com>
 */

#include <config.h>

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
29 30 31 32
#include <sys/stat.h>
#include <sys/param.h>
#include <fcntl.h>

R
Richard W.M. Jones 已提交
33
#if HAVE_PWD_H
34
# include <pwd.h>
R
Richard W.M. Jones 已提交
35
#endif
36 37 38
#include <errno.h>
#include <string.h>

39
#include "virerror.h"
40
#include "datatypes.h"
41 42 43
#include "driver.h"
#include "storage_driver.h"
#include "storage_conf.h"
44
#include "viralloc.h"
45
#include "storage_backend.h"
46
#include "virlog.h"
E
Eric Blake 已提交
47
#include "virfile.h"
48
#include "fdstream.h"
49
#include "configmake.h"
50
#include "virstring.h"
51
#include "viraccessapicheck.h"
52
#include "dirname.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 66 67
typedef struct _virStorageVolStreamInfo virStorageVolStreamInfo;
typedef virStorageVolStreamInfo *virStorageVolStreamInfoPtr;
struct _virStorageVolStreamInfo {
    char *pool_name;
};

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

static void
78
storageDriverAutostart(void)
79
{
80
    size_t i;
81 82 83
    virConnectPtr conn = NULL;

    /* XXX Remove hardcoding of QEMU URI */
84
    if (driver->privileged)
85 86 87 88
        conn = virConnectOpen("qemu:///system");
    else
        conn = virConnectOpen("qemu:///session");
    /* Ignoring NULL conn - let backends decide */
89

90
    for (i = 0; i < driver->pools.count; i++) {
91
        virStoragePoolObjPtr pool = driver->pools.objs[i];
92 93
        virStorageBackendPtr backend;
        bool started = false;
94

95
        virStoragePoolObjLock(pool);
96 97 98 99 100
        if ((backend = virStorageBackendForType(pool->def->type)) == NULL) {
            VIR_ERROR(_("Missing backend %d"), pool->def->type);
            virStoragePoolObjUnlock(pool);
            continue;
        }
101

102
        if (backend->checkPool &&
103
            backend->checkPool(conn, pool, &started) < 0) {
104 105 106 107 108 109 110 111 112 113 114
            virErrorPtr err = virGetLastError();
            VIR_ERROR(_("Failed to initialize storage pool '%s': %s"),
                      pool->def->name, err ? err->message :
                      _("no error message found"));
            virStoragePoolObjUnlock(pool);
            continue;
        }

        if (!started &&
            pool->autostart &&
            !virStoragePoolObjIsActive(pool)) {
115
            if (backend->startPool &&
116
                backend->startPool(conn, pool) < 0) {
117
                virErrorPtr err = virGetLastError();
118
                VIR_ERROR(_("Failed to autostart storage pool '%s': %s"),
119
                          pool->def->name, err ? err->message :
120
                          _("no error message found"));
121
                virStoragePoolObjUnlock(pool);
122 123
                continue;
            }
124 125
            started = true;
        }
126

127
        if (started) {
128
            if (backend->refreshPool(conn, pool) < 0) {
129 130
                virErrorPtr err = virGetLastError();
                if (backend->stopPool)
131
                    backend->stopPool(conn, pool);
132
                VIR_ERROR(_("Failed to autostart storage pool '%s': %s"),
133
                          pool->def->name, err ? err->message :
134
                          _("no error message found"));
135
                virStoragePoolObjUnlock(pool);
136 137 138 139
                continue;
            }
            pool->active = 1;
        }
140
        virStoragePoolObjUnlock(pool);
141
    }
142

143
    virObjectUnref(conn);
144 145 146 147 148 149 150 151
}

/**
 * virStorageStartup:
 *
 * Initialization function for the QEmu daemon
 */
static int
152 153 154
storageStateInitialize(bool privileged,
                       virStateInhibitCallback callback ATTRIBUTE_UNUSED,
                       void *opaque ATTRIBUTE_UNUSED)
155
{
156 157
    char *base = NULL;

158
    if (VIR_ALLOC(driver) < 0)
159 160
        return -1;

161 162
    if (virMutexInit(&driver->lock) < 0) {
        VIR_FREE(driver);
163 164
        return -1;
    }
165
    storageDriverLock();
166

167
    if (privileged) {
168 169
        if (VIR_STRDUP(base, SYSCONFDIR "/libvirt") < 0)
            goto error;
170
    } else {
171
        base = virGetUserConfigDirectory();
172
        if (!base)
173
            goto error;
174
    }
175
    driver->privileged = privileged;
176

177 178 179
    /*
     * Configuration paths are either $USER_CONFIG_HOME/libvirt/storage/...
     * (session) or /etc/libvirt/storage/... (system).
180
     */
181
    if (virAsprintf(&driver->configDir,
182
                    "%s/storage", base) == -1)
183
        goto error;
184

185
    if (virAsprintf(&driver->autostartDir,
186
                    "%s/storage/autostart", base) == -1)
187
        goto error;
188

189
    VIR_FREE(base);
190

191 192 193
    if (virStoragePoolLoadAllConfigs(&driver->pools,
                                     driver->configDir,
                                     driver->autostartDir) < 0)
194
        goto error;
195

196
    storageDriverUnlock();
197 198
    return 0;

199
 error:
200
    VIR_FREE(base);
201
    storageDriverUnlock();
202
    storageStateCleanup();
203 204 205
    return -1;
}

206 207 208 209 210 211 212 213
/**
 * storageStateAutoStart:
 *
 * Function to auto start the storage driver
 */
static void
storageStateAutoStart(void)
{
214
    if (!driver)
215 216
        return;

217 218 219
    storageDriverLock();
    storageDriverAutostart();
    storageDriverUnlock();
220 221
}

222
/**
223
 * storageStateReload:
224 225 226 227 228
 *
 * Function to restart the storage driver, it will recheck the configuration
 * files and update its state
 */
static int
229 230
storageStateReload(void)
{
231
    if (!driver)
232 233
        return -1;

234 235 236 237 238 239
    storageDriverLock();
    virStoragePoolLoadAllConfigs(&driver->pools,
                                 driver->configDir,
                                 driver->autostartDir);
    storageDriverAutostart();
    storageDriverUnlock();
240 241 242 243 244 245

    return 0;
}


/**
246
 * storageStateCleanup
247 248 249 250
 *
 * Shutdown the storage driver, it will stop all active storage pools
 */
static int
251 252
storageStateCleanup(void)
{
253
    if (!driver)
254 255
        return -1;

256
    storageDriverLock();
257 258

    /* free inactive pools */
259
    virStoragePoolObjListFree(&driver->pools);
260

261 262 263 264 265
    VIR_FREE(driver->configDir);
    VIR_FREE(driver->autostartDir);
    storageDriverUnlock();
    virMutexDestroy(&driver->lock);
    VIR_FREE(driver);
266 267 268 269 270 271 272 273

    return 0;
}



static virStoragePoolPtr
storagePoolLookupByUUID(virConnectPtr conn,
274 275
                        const unsigned char *uuid)
{
276 277
    virStoragePoolObjPtr pool;
    virStoragePoolPtr ret = NULL;
278

279
    storageDriverLock();
280
    pool = virStoragePoolObjFindByUUID(&driver->pools, uuid);
281
    storageDriverUnlock();
282

283
    if (!pool) {
284 285
        char uuidstr[VIR_UUID_STRING_BUFLEN];
        virUUIDFormat(uuid, uuidstr);
286
        virReportError(VIR_ERR_NO_STORAGE_POOL,
287 288
                       _("no storage pool with matching uuid '%s'"), uuidstr);
        return NULL;
289 290
    }

291 292 293
    if (virStoragePoolLookupByUUIDEnsureACL(conn, pool->def) < 0)
        goto cleanup;

294 295
    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid,
                            NULL, NULL);
296

297
 cleanup:
298
    virStoragePoolObjUnlock(pool);
299 300 301 302 303
    return ret;
}

static virStoragePoolPtr
storagePoolLookupByName(virConnectPtr conn,
304 305
                        const char *name)
{
306 307
    virStoragePoolObjPtr pool;
    virStoragePoolPtr ret = NULL;
308

309
    storageDriverLock();
310
    pool = virStoragePoolObjFindByName(&driver->pools, name);
311
    storageDriverUnlock();
312

313
    if (!pool) {
314
        virReportError(VIR_ERR_NO_STORAGE_POOL,
315
                       _("no storage pool with matching name '%s'"), name);
316
        return NULL;
317 318
    }

319 320 321
    if (virStoragePoolLookupByNameEnsureACL(conn, pool->def) < 0)
        goto cleanup;

322 323
    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid,
                            NULL, NULL);
324

325
 cleanup:
326
    virStoragePoolObjUnlock(pool);
327 328 329 330
    return ret;
}

static virStoragePoolPtr
331 332
storagePoolLookupByVolume(virStorageVolPtr vol)
{
333 334 335
    virStoragePoolObjPtr pool;
    virStoragePoolPtr ret = NULL;

336
    storageDriverLock();
337
    pool = virStoragePoolObjFindByName(&driver->pools, vol->pool);
338
    storageDriverUnlock();
339 340 341

    if (!pool) {
        virReportError(VIR_ERR_NO_STORAGE_POOL,
342 343
                       _("no storage pool with matching name '%s'"),
                       vol->pool);
344
        return NULL;
345 346 347 348 349 350 351 352
    }

    if (virStoragePoolLookupByVolumeEnsureACL(vol->conn, pool->def) < 0)
        goto cleanup;

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

353
 cleanup:
354
    virStoragePoolObjUnlock(pool);
355
    return ret;
356 357 358
}

static virDrvOpenStatus
359
storageOpen(virConnectPtr conn ATTRIBUTE_UNUSED,
360
            virConnectAuthPtr auth ATTRIBUTE_UNUSED,
E
Eric Blake 已提交
361 362 363 364
            unsigned int flags)
{
    virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);

365
    if (!driver)
366 367 368 369 370 371
        return VIR_DRV_OPEN_DECLINED;

    return VIR_DRV_OPEN_SUCCESS;
}

static int
372
storageClose(virConnectPtr conn ATTRIBUTE_UNUSED)
373
{
374 375 376 377
    return 0;
}

static int
378 379
storageConnectNumOfStoragePools(virConnectPtr conn)
{
380 381
    size_t i;
    int nactive = 0;
382

383 384 385
    if (virConnectNumOfStoragePoolsEnsureACL(conn) < 0)
        return -1;

386
    storageDriverLock();
387
    for (i = 0; i < driver->pools.count; i++) {
388 389 390
        virStoragePoolObjPtr obj = driver->pools.objs[i];
        virStoragePoolObjLock(obj);
        if (virConnectNumOfStoragePoolsCheckACL(conn, obj->def) &&
391
            virStoragePoolObjIsActive(obj))
392
            nactive++;
393
        virStoragePoolObjUnlock(obj);
394
    }
395
    storageDriverUnlock();
396 397

    return nactive;
398 399 400
}

static int
401 402
storageConnectListStoragePools(virConnectPtr conn,
                               char **const names,
403 404
                               int nnames)
{
405 406
    int got = 0;
    size_t i;
407

408 409 410
    if (virConnectListStoragePoolsEnsureACL(conn) < 0)
        return -1;

411
    storageDriverLock();
412
    for (i = 0; i < driver->pools.count && got < nnames; i++) {
413 414 415
        virStoragePoolObjPtr obj = driver->pools.objs[i];
        virStoragePoolObjLock(obj);
        if (virConnectListStoragePoolsCheckACL(conn, obj->def) &&
416
            virStoragePoolObjIsActive(obj)) {
417 418
            if (VIR_STRDUP(names[got], obj->def->name) < 0) {
                virStoragePoolObjUnlock(obj);
419 420 421 422
                goto cleanup;
            }
            got++;
        }
423
        virStoragePoolObjUnlock(obj);
424
    }
425
    storageDriverUnlock();
426 427 428
    return got;

 cleanup:
429
    storageDriverUnlock();
430
    for (i = 0; i < got; i++)
431
        VIR_FREE(names[i]);
432
    memset(names, 0, nnames * sizeof(*names));
433 434 435 436
    return -1;
}

static int
437 438
storageConnectNumOfDefinedStoragePools(virConnectPtr conn)
{
439 440
    size_t i;
    int nactive = 0;
441

442 443 444
    if (virConnectNumOfDefinedStoragePoolsEnsureACL(conn) < 0)
        return -1;

445
    storageDriverLock();
446
    for (i = 0; i < driver->pools.count; i++) {
447 448 449
        virStoragePoolObjPtr obj = driver->pools.objs[i];
        virStoragePoolObjLock(obj);
        if (virConnectNumOfDefinedStoragePoolsCheckACL(conn, obj->def) &&
450
            !virStoragePoolObjIsActive(obj))
451
            nactive++;
452
        virStoragePoolObjUnlock(obj);
453
    }
454
    storageDriverUnlock();
455 456

    return nactive;
457 458 459
}

static int
460 461
storageConnectListDefinedStoragePools(virConnectPtr conn,
                                      char **const names,
462 463
                                      int nnames)
{
464 465
    int got = 0;
    size_t i;
466

467 468 469
    if (virConnectListDefinedStoragePoolsEnsureACL(conn) < 0)
        return -1;

470
    storageDriverLock();
471
    for (i = 0; i < driver->pools.count && got < nnames; i++) {
472 473 474
        virStoragePoolObjPtr obj = driver->pools.objs[i];
        virStoragePoolObjLock(obj);
        if (virConnectListDefinedStoragePoolsCheckACL(conn, obj->def) &&
475
            !virStoragePoolObjIsActive(obj)) {
476 477
            if (VIR_STRDUP(names[got], obj->def->name) < 0) {
                virStoragePoolObjUnlock(obj);
478 479 480 481
                goto cleanup;
            }
            got++;
        }
482
        virStoragePoolObjUnlock(obj);
483
    }
484
    storageDriverUnlock();
485 486 487
    return got;

 cleanup:
488
    storageDriverUnlock();
489
    for (i = 0; i < got; i++)
490
        VIR_FREE(names[i]);
491
    memset(names, 0, nnames * sizeof(*names));
492 493 494
    return -1;
}

495 496
/* This method is required to be re-entrant / thread safe, so
   uses no driver lock */
497
static char *
498 499 500 501
storageConnectFindStoragePoolSources(virConnectPtr conn,
                                     const char *type,
                                     const char *srcSpec,
                                     unsigned int flags)
502 503 504
{
    int backend_type;
    virStorageBackendPtr backend;
505
    char *ret = NULL;
506

507 508 509
    if (virConnectFindStoragePoolSourcesEnsureACL(conn) < 0)
        return NULL;

510
    backend_type = virStoragePoolTypeFromString(type);
511
    if (backend_type < 0) {
512 513
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unknown storage pool type %s"), type);
514
        goto cleanup;
515
    }
516 517 518

    backend = virStorageBackendForType(backend_type);
    if (backend == NULL)
519
        goto cleanup;
520

521
    if (!backend->findPoolSources) {
522 523 524
        virReportError(VIR_ERR_NO_SUPPORT,
                       _("pool type '%s' does not support source "
                         "discovery"), type);
525 526 527 528
        goto cleanup;
    }

    ret = backend->findPoolSources(conn, srcSpec, flags);
529

530
 cleanup:
531
    return ret;
532 533 534
}


535 536
static virStoragePoolObjPtr
virStoragePoolObjFromStoragePool(virStoragePoolPtr pool)
537
{
538 539
    char uuidstr[VIR_UUID_STRING_BUFLEN];
    virStoragePoolObjPtr ret;
540

541
    storageDriverLock();
542 543 544 545 546
    if (!(ret = virStoragePoolObjFindByUUID(&driver->pools, pool->uuid))) {
        virUUIDFormat(pool->uuid, uuidstr);
        virReportError(VIR_ERR_NO_STORAGE_POOL,
                       _("no storage pool with matching uuid '%s' (%s)"),
                       uuidstr, pool->name);
547
    }
548
    storageDriverUnlock();
549 550 551 552 553 554 555 556 557 558 559 560

    return ret;
}


static int storagePoolIsActive(virStoragePoolPtr pool)
{
    virStoragePoolObjPtr obj;
    int ret = -1;

    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
        return -1;
561 562 563 564

    if (virStoragePoolIsActiveEnsureACL(pool->conn, obj->def) < 0)
        goto cleanup;

565 566
    ret = virStoragePoolObjIsActive(obj);

567
 cleanup:
568
    virStoragePoolObjUnlock(obj);
569 570 571
    return ret;
}

572
static int storagePoolIsPersistent(virStoragePoolPtr pool)
573 574 575 576
{
    virStoragePoolObjPtr obj;
    int ret = -1;

577 578
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
        return -1;
579 580 581 582

    if (virStoragePoolIsPersistentEnsureACL(pool->conn, obj->def) < 0)
        goto cleanup;

583 584
    ret = obj->configFile ? 1 : 0;

585
 cleanup:
586
    virStoragePoolObjUnlock(obj);
587 588 589 590
    return ret;
}


591
static virStoragePoolPtr
592 593 594
storagePoolCreateXML(virConnectPtr conn,
                     const char *xml,
                     unsigned int flags)
E
Eric Blake 已提交
595
{
596
    virStoragePoolDefPtr def;
597
    virStoragePoolObjPtr pool = NULL;
598
    virStoragePoolPtr ret = NULL;
599 600
    virStorageBackendPtr backend;

E
Eric Blake 已提交
601 602
    virCheckFlags(0, NULL);

603
    storageDriverLock();
604
    if (!(def = virStoragePoolDefParseString(xml)))
605
        goto cleanup;
606

607 608 609
    if (virStoragePoolCreateXMLEnsureACL(conn, def) < 0)
        goto cleanup;

610
    if (virStoragePoolObjIsDuplicate(&driver->pools, def, 1) < 0)
611
        goto cleanup;
612

613
    if (virStoragePoolSourceFindDuplicate(conn, &driver->pools, def) < 0)
614 615
        goto cleanup;

616 617
    if ((backend = virStorageBackendForType(def->type)) == NULL)
        goto cleanup;
618

619
    if (!(pool = virStoragePoolObjAssignDef(&driver->pools, def)))
620 621
        goto cleanup;
    def = NULL;
622

623
    if (backend->startPool &&
624 625 626
        backend->startPool(conn, pool) < 0) {
        virStoragePoolObjRemove(&driver->pools, pool);
        pool = NULL;
627
        goto cleanup;
628
    }
629

630 631 632
    if (backend->refreshPool(conn, pool) < 0) {
        if (backend->stopPool)
            backend->stopPool(conn, pool);
633 634
        virStoragePoolObjRemove(&driver->pools, pool);
        pool = NULL;
635
        goto cleanup;
636
    }
637
    VIR_INFO("Creating storage pool '%s'", pool->def->name);
638 639
    pool->active = 1;

640 641
    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid,
                            NULL, NULL);
642

643
 cleanup:
644
    virStoragePoolDefFree(def);
645
    if (pool)
646
        virStoragePoolObjUnlock(pool);
647
    storageDriverUnlock();
648 649 650 651
    return ret;
}

static virStoragePoolPtr
652 653 654
storagePoolDefineXML(virConnectPtr conn,
                     const char *xml,
                     unsigned int flags)
E
Eric Blake 已提交
655
{
656
    virStoragePoolDefPtr def;
657
    virStoragePoolObjPtr pool = NULL;
658
    virStoragePoolPtr ret = NULL;
659

E
Eric Blake 已提交
660 661
    virCheckFlags(0, NULL);

662
    storageDriverLock();
663
    if (!(def = virStoragePoolDefParseString(xml)))
664
        goto cleanup;
665

666 667 668
    if (virStoragePoolDefineXMLEnsureACL(conn, def) < 0)
        goto cleanup;

669 670 671
    if (virStoragePoolObjIsDuplicate(&driver->pools, def, 0) < 0)
        goto cleanup;

672
    if (virStoragePoolSourceFindDuplicate(conn, &driver->pools, def) < 0)
673 674
        goto cleanup;

675
    if (virStorageBackendForType(def->type) == NULL)
676
        goto cleanup;
677

678
    if (!(pool = virStoragePoolObjAssignDef(&driver->pools, def)))
679
        goto cleanup;
680

681
    if (virStoragePoolObjSaveDef(driver, pool, def) < 0) {
682
        virStoragePoolObjRemove(&driver->pools, pool);
683
        def = NULL;
684
        goto cleanup;
685
    }
686
    def = NULL;
687

688
    VIR_INFO("Defining storage pool '%s'", pool->def->name);
689 690
    ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid,
                            NULL, NULL);
691

692
 cleanup:
693
    virStoragePoolDefFree(def);
694 695
    if (pool)
        virStoragePoolObjUnlock(pool);
696
    storageDriverUnlock();
697 698 699 700
    return ret;
}

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

706
    storageDriverLock();
707 708 709
    if (!(pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid))) {
        char uuidstr[VIR_UUID_STRING_BUFLEN];
        virUUIDFormat(obj->uuid, uuidstr);
710
        virReportError(VIR_ERR_NO_STORAGE_POOL,
711 712
                       _("no storage pool with matching uuid '%s' (%s)"),
                       uuidstr, obj->name);
713
        goto cleanup;
714 715
    }

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

719
    if (virStoragePoolObjIsActive(pool)) {
720
        virReportError(VIR_ERR_OPERATION_INVALID,
721 722
                       _("storage pool '%s' is still active"),
                       pool->def->name);
723
        goto cleanup;
724 725
    }

726
    if (pool->asyncjobs > 0) {
727 728 729
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("pool '%s' has asynchronous jobs running."),
                       pool->def->name);
730 731 732
        goto cleanup;
    }

733
    if (virStoragePoolObjDeleteDef(pool) < 0)
734
        goto cleanup;
735

736 737 738
    if (unlink(pool->autostartLink) < 0 &&
        errno != ENOENT &&
        errno != ENOTDIR) {
739
        char ebuf[1024];
740
        VIR_ERROR(_("Failed to delete autostart link '%s': %s"),
741
                  pool->autostartLink, virStrerror(errno, ebuf, sizeof(ebuf)));
742
    }
743

744 745
    VIR_FREE(pool->configFile);
    VIR_FREE(pool->autostartLink);
746

747
    VIR_INFO("Undefining storage pool '%s'", pool->def->name);
748
    virStoragePoolObjRemove(&driver->pools, pool);
749
    pool = NULL;
750
    ret = 0;
751

752
 cleanup:
753 754
    if (pool)
        virStoragePoolObjUnlock(pool);
755
    storageDriverUnlock();
756
    return ret;
757 758 759
}

static int
760 761
storagePoolCreate(virStoragePoolPtr obj,
                  unsigned int flags)
E
Eric Blake 已提交
762
{
763
    virStoragePoolObjPtr pool;
764
    virStorageBackendPtr backend;
765
    int ret = -1;
766

E
Eric Blake 已提交
767 768
    virCheckFlags(0, -1);

769 770
    if (!(pool = virStoragePoolObjFromStoragePool(obj)))
        return -1;
771

772 773 774
    if (virStoragePoolCreateEnsureACL(obj->conn, pool->def) < 0)
        goto cleanup;

775 776
    if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
        goto cleanup;
777 778

    if (virStoragePoolObjIsActive(pool)) {
779
        virReportError(VIR_ERR_OPERATION_INVALID,
780 781
                       _("storage pool '%s' is already active"),
                       pool->def->name);
782
        goto cleanup;
783 784 785
    }
    if (backend->startPool &&
        backend->startPool(obj->conn, pool) < 0)
786 787
        goto cleanup;

788 789 790
    if (backend->refreshPool(obj->conn, pool) < 0) {
        if (backend->stopPool)
            backend->stopPool(obj->conn, pool);
791
        goto cleanup;
792 793
    }

794
    VIR_INFO("Starting up storage pool '%s'", pool->def->name);
795
    pool->active = 1;
796
    ret = 0;
797

798
 cleanup:
799
    virStoragePoolObjUnlock(pool);
800
    return ret;
801 802 803 804
}

static int
storagePoolBuild(virStoragePoolPtr obj,
805 806
                 unsigned int flags)
{
807
    virStoragePoolObjPtr pool;
808
    virStorageBackendPtr backend;
809
    int ret = -1;
810

811 812
    if (!(pool = virStoragePoolObjFromStoragePool(obj)))
        return -1;
813

814 815 816
    if (virStoragePoolBuildEnsureACL(obj->conn, pool->def) < 0)
        goto cleanup;

817 818
    if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
        goto cleanup;
819 820

    if (virStoragePoolObjIsActive(pool)) {
821
        virReportError(VIR_ERR_OPERATION_INVALID,
822 823
                       _("storage pool '%s' is already active"),
                       pool->def->name);
824
        goto cleanup;
825 826 827 828
    }

    if (backend->buildPool &&
        backend->buildPool(obj->conn, pool, flags) < 0)
829 830
        goto cleanup;
    ret = 0;
831

832
 cleanup:
833
    virStoragePoolObjUnlock(pool);
834
    return ret;
835 836 837 838
}


static int
839 840
storagePoolDestroy(virStoragePoolPtr obj)
{
841
    virStoragePoolObjPtr pool;
842
    virStorageBackendPtr backend;
843
    int ret = -1;
844

845
    storageDriverLock();
846 847 848
    if (!(pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid))) {
        char uuidstr[VIR_UUID_STRING_BUFLEN];
        virUUIDFormat(obj->uuid, uuidstr);
849
        virReportError(VIR_ERR_NO_STORAGE_POOL,
850 851
                       _("no storage pool with matching uuid '%s' (%s)"),
                       uuidstr, obj->name);
852
        goto cleanup;
853 854
    }

855 856 857
    if (virStoragePoolDestroyEnsureACL(obj->conn, pool->def) < 0)
        goto cleanup;

858 859
    if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
        goto cleanup;
860 861

    if (!virStoragePoolObjIsActive(pool)) {
862
        virReportError(VIR_ERR_OPERATION_INVALID,
863
                       _("storage pool '%s' is not active"), pool->def->name);
864
        goto cleanup;
865 866
    }

867
    if (pool->asyncjobs > 0) {
868 869 870
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("pool '%s' has asynchronous jobs running."),
                       pool->def->name);
871 872 873
        goto cleanup;
    }

874 875
    if (backend->stopPool &&
        backend->stopPool(obj->conn, pool) < 0)
876
        goto cleanup;
877 878 879 880

    virStoragePoolObjClearVols(pool);

    pool->active = 0;
881
    VIR_INFO("Shutting down storage pool '%s'", pool->def->name);
882

883
    if (pool->configFile == NULL) {
884
        virStoragePoolObjRemove(&driver->pools, pool);
885
        pool = NULL;
886 887 888 889
    } else if (pool->newDef) {
        virStoragePoolDefFree(pool->def);
        pool->def = pool->newDef;
        pool->newDef = NULL;
890
    }
891
    ret = 0;
892

893
 cleanup:
894 895
    if (pool)
        virStoragePoolObjUnlock(pool);
896
    storageDriverUnlock();
897
    return ret;
898 899 900 901
}

static int
storagePoolDelete(virStoragePoolPtr obj,
902 903
                  unsigned int flags)
{
904
    virStoragePoolObjPtr pool;
905
    virStorageBackendPtr backend;
906
    int ret = -1;
907

908 909
    if (!(pool = virStoragePoolObjFromStoragePool(obj)))
        return -1;
910

911 912 913
    if (virStoragePoolDeleteEnsureACL(obj->conn, pool->def) < 0)
        goto cleanup;

914 915
    if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
        goto cleanup;
916 917

    if (virStoragePoolObjIsActive(pool)) {
918
        virReportError(VIR_ERR_OPERATION_INVALID,
919 920
                       _("storage pool '%s' is still active"),
                       pool->def->name);
921
        goto cleanup;
922 923
    }

924
    if (pool->asyncjobs > 0) {
925 926
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("pool '%s' has asynchronous jobs running."),
927 928 929 930
                              pool->def->name);
        goto cleanup;
    }

931
    if (!backend->deletePool) {
932 933
        virReportError(VIR_ERR_NO_SUPPORT,
                       "%s", _("pool does not support pool deletion"));
934
        goto cleanup;
935 936
    }
    if (backend->deletePool(obj->conn, pool, flags) < 0)
937
        goto cleanup;
938
    VIR_INFO("Deleting storage pool '%s'", pool->def->name);
939
    ret = 0;
940

941
 cleanup:
942
    virStoragePoolObjUnlock(pool);
943
    return ret;
944 945 946 947 948
}


static int
storagePoolRefresh(virStoragePoolPtr obj,
E
Eric Blake 已提交
949 950
                   unsigned int flags)
{
951
    virStoragePoolObjPtr pool;
952
    virStorageBackendPtr backend;
953
    int ret = -1;
954

E
Eric Blake 已提交
955 956
    virCheckFlags(0, -1);

957
    storageDriverLock();
958 959 960
    if (!(pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid))) {
        char uuidstr[VIR_UUID_STRING_BUFLEN];
        virUUIDFormat(obj->uuid, uuidstr);
961
        virReportError(VIR_ERR_NO_STORAGE_POOL,
962 963
                       _("no storage pool with matching uuid '%s' (%s)"),
                       uuidstr, obj->name);
964
        goto cleanup;
965 966
    }

967 968 969
    if (virStoragePoolRefreshEnsureACL(obj->conn, pool->def) < 0)
        goto cleanup;

970 971
    if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
        goto cleanup;
972 973

    if (!virStoragePoolObjIsActive(pool)) {
974
        virReportError(VIR_ERR_OPERATION_INVALID,
975
                       _("storage pool '%s' is not active"), pool->def->name);
976
        goto cleanup;
977 978
    }

979
    if (pool->asyncjobs > 0) {
980 981 982
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("pool '%s' has asynchronous jobs running."),
                       pool->def->name);
983 984 985
        goto cleanup;
    }

986
    virStoragePoolObjClearVols(pool);
987
    if (backend->refreshPool(obj->conn, pool) < 0) {
988 989 990 991 992
        if (backend->stopPool)
            backend->stopPool(obj->conn, pool);

        pool->active = 0;

993
        if (pool->configFile == NULL) {
994
            virStoragePoolObjRemove(&driver->pools, pool);
995 996
            pool = NULL;
        }
997
        goto cleanup;
998
    }
999
    ret = 0;
1000

1001
 cleanup:
1002 1003
    if (pool)
        virStoragePoolObjUnlock(pool);
1004
    storageDriverUnlock();
1005 1006 1007 1008 1009 1010
    return ret;
}


static int
storagePoolGetInfo(virStoragePoolPtr obj,
1011 1012
                   virStoragePoolInfoPtr info)
{
1013 1014
    virStoragePoolObjPtr pool;
    int ret = -1;
1015

1016 1017
    if (!(pool = virStoragePoolObjFromStoragePool(obj)))
        return -1;
1018

1019 1020 1021
    if (virStoragePoolGetInfoEnsureACL(obj->conn, pool->def) < 0)
        goto cleanup;

1022
    if (virStorageBackendForType(pool->def->type) == NULL)
1023
        goto cleanup;
1024 1025 1026 1027 1028 1029 1030 1031 1032

    memset(info, 0, sizeof(virStoragePoolInfo));
    if (pool->active)
        info->state = VIR_STORAGE_POOL_RUNNING;
    else
        info->state = VIR_STORAGE_POOL_INACTIVE;
    info->capacity = pool->def->capacity;
    info->allocation = pool->def->allocation;
    info->available = pool->def->available;
1033
    ret = 0;
1034

1035
 cleanup:
1036
    virStoragePoolObjUnlock(pool);
1037
    return ret;
1038 1039 1040
}

static char *
1041
storagePoolGetXMLDesc(virStoragePoolPtr obj,
E
Eric Blake 已提交
1042 1043
                      unsigned int flags)
{
1044
    virStoragePoolObjPtr pool;
1045
    virStoragePoolDefPtr def;
1046
    char *ret = NULL;
1047

1048
    virCheckFlags(VIR_STORAGE_XML_INACTIVE, NULL);
E
Eric Blake 已提交
1049

1050 1051
    if (!(pool = virStoragePoolObjFromStoragePool(obj)))
        return NULL;
1052

1053 1054 1055
    if (virStoragePoolGetXMLDescEnsureACL(obj->conn, pool->def) < 0)
        goto cleanup;

1056 1057 1058 1059 1060 1061
    if ((flags & VIR_STORAGE_XML_INACTIVE) && pool->newDef)
        def = pool->newDef;
    else
        def = pool->def;

    ret = virStoragePoolDefFormat(def);
1062

1063
 cleanup:
1064
    virStoragePoolObjUnlock(pool);
1065
    return ret;
1066 1067 1068 1069
}

static int
storagePoolGetAutostart(virStoragePoolPtr obj,
1070 1071
                        int *autostart)
{
1072 1073
    virStoragePoolObjPtr pool;
    int ret = -1;
1074

1075 1076
    if (!(pool = virStoragePoolObjFromStoragePool(obj)))
        return -1;
1077

1078 1079 1080
    if (virStoragePoolGetAutostartEnsureACL(obj->conn, pool->def) < 0)
        goto cleanup;

1081 1082 1083 1084 1085
    if (!pool->configFile) {
        *autostart = 0;
    } else {
        *autostart = pool->autostart;
    }
1086
    ret = 0;
1087

1088
 cleanup:
1089
    virStoragePoolObjUnlock(pool);
1090
    return ret;
1091 1092 1093 1094
}

static int
storagePoolSetAutostart(virStoragePoolPtr obj,
1095 1096
                        int autostart)
{
1097 1098
    virStoragePoolObjPtr pool;
    int ret = -1;
1099

1100
    storageDriverLock();
1101
    pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
1102

1103
    if (!pool) {
1104 1105
        char uuidstr[VIR_UUID_STRING_BUFLEN];
        virUUIDFormat(obj->uuid, uuidstr);
1106
        virReportError(VIR_ERR_NO_STORAGE_POOL,
1107 1108
                       _("no storage pool with matching uuid '%s' (%s)"),
                       uuidstr, obj->name);
1109
        goto cleanup;
1110 1111
    }

1112 1113 1114
    if (virStoragePoolSetAutostartEnsureACL(obj->conn, pool->def) < 0)
        goto cleanup;

1115
    if (!pool->configFile) {
1116 1117
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("pool has no config file"));
1118
        goto cleanup;
1119 1120 1121 1122
    }

    autostart = (autostart != 0);

1123 1124
    if (pool->autostart != autostart) {
        if (autostart) {
1125 1126
            if (virFileMakePath(driver->autostartDir) < 0) {
                virReportSystemError(errno,
1127 1128
                                     _("cannot create autostart directory %s"),
                                     driver->autostartDir);
1129 1130
                goto cleanup;
            }
1131

1132
            if (symlink(pool->configFile, pool->autostartLink) < 0) {
1133
                virReportSystemError(errno,
1134 1135
                                     _("Failed to create symlink '%s' to '%s'"),
                                     pool->autostartLink, pool->configFile);
1136 1137 1138 1139 1140
                goto cleanup;
            }
        } else {
            if (unlink(pool->autostartLink) < 0 &&
                errno != ENOENT && errno != ENOTDIR) {
1141
                virReportSystemError(errno,
1142 1143
                                     _("Failed to delete symlink '%s'"),
                                     pool->autostartLink);
1144 1145
                goto cleanup;
            }
1146
        }
1147
        pool->autostart = autostart;
1148
    }
1149
    ret = 0;
1150

1151
 cleanup:
1152 1153
    if (pool)
        virStoragePoolObjUnlock(pool);
1154
    storageDriverUnlock();
1155
    return ret;
1156 1157 1158 1159
}


static int
1160 1161
storagePoolNumOfVolumes(virStoragePoolPtr obj)
{
1162
    virStoragePoolObjPtr pool;
1163 1164
    int ret = -1;
    size_t i;
1165

1166 1167
    if (!(pool = virStoragePoolObjFromStoragePool(obj)))
        return -1;
1168

1169 1170 1171
    if (virStoragePoolNumOfVolumesEnsureACL(obj->conn, pool->def) < 0)
        goto cleanup;

1172
    if (!virStoragePoolObjIsActive(pool)) {
1173
        virReportError(VIR_ERR_OPERATION_INVALID,
1174
                       _("storage pool '%s' is not active"), pool->def->name);
1175
        goto cleanup;
1176
    }
1177 1178 1179 1180 1181 1182
    ret = 0;
    for (i = 0; i < pool->volumes.count; i++) {
        if (virStoragePoolNumOfVolumesCheckACL(obj->conn, pool->def,
                                               pool->volumes.objs[i]))
            ret++;
    }
1183

1184
 cleanup:
1185
    virStoragePoolObjUnlock(pool);
1186
    return ret;
1187 1188 1189 1190 1191
}

static int
storagePoolListVolumes(virStoragePoolPtr obj,
                       char **const names,
1192 1193
                       int maxnames)
{
1194
    virStoragePoolObjPtr pool;
1195 1196
    size_t i;
    int n = 0;
1197

1198 1199
    memset(names, 0, maxnames * sizeof(*names));

1200 1201
    if (!(pool = virStoragePoolObjFromStoragePool(obj)))
        return -1;
1202

1203 1204 1205
    if (virStoragePoolListVolumesEnsureACL(obj->conn, pool->def) < 0)
        goto cleanup;

1206
    if (!virStoragePoolObjIsActive(pool)) {
1207
        virReportError(VIR_ERR_OPERATION_INVALID,
1208
                       _("storage pool '%s' is not active"), pool->def->name);
1209
        goto cleanup;
1210 1211
    }

1212
    for (i = 0; i < pool->volumes.count && n < maxnames; i++) {
1213 1214 1215
        if (!virStoragePoolListVolumesCheckACL(obj->conn, pool->def,
                                               pool->volumes.objs[i]))
            continue;
1216
        if (VIR_STRDUP(names[n++], pool->volumes.objs[i]->name) < 0)
1217 1218 1219
            goto cleanup;
    }

1220
    virStoragePoolObjUnlock(pool);
1221
    return n;
1222 1223

 cleanup:
1224
    virStoragePoolObjUnlock(pool);
1225
    for (n = 0; n < maxnames; n++)
1226
        VIR_FREE(names[n]);
1227

1228
    memset(names, 0, maxnames * sizeof(*names));
1229 1230 1231
    return -1;
}

1232 1233 1234
static int
storagePoolListAllVolumes(virStoragePoolPtr pool,
                          virStorageVolPtr **vols,
1235 1236
                          unsigned int flags)
{
1237
    virStoragePoolObjPtr obj;
1238
    size_t i;
1239 1240 1241 1242 1243 1244 1245
    virStorageVolPtr *tmp_vols = NULL;
    virStorageVolPtr vol = NULL;
    int nvols = 0;
    int ret = -1;

    virCheckFlags(0, -1);

1246 1247
    if (!(obj = virStoragePoolObjFromStoragePool(pool)))
        return -1;
1248

1249 1250 1251
    if (virStoragePoolListAllVolumesEnsureACL(pool->conn, obj->def) < 0)
        goto cleanup;

1252
    if (!virStoragePoolObjIsActive(obj)) {
1253 1254
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("storage pool '%s' is not active"), obj->def->name);
1255 1256 1257 1258 1259 1260 1261 1262 1263
        goto cleanup;
    }

     /* Just returns the volumes count */
    if (!vols) {
        ret = obj->volumes.count;
        goto cleanup;
    }

1264
    if (VIR_ALLOC_N(tmp_vols, obj->volumes.count + 1) < 0)
1265
        goto cleanup;
1266

1267
    for (i = 0; i < obj->volumes.count; i++) {
1268 1269 1270
        if (!virStoragePoolListAllVolumesCheckACL(pool->conn, obj->def,
                                                  obj->volumes.objs[i]))
            continue;
1271 1272
        if (!(vol = virGetStorageVol(pool->conn, obj->def->name,
                                     obj->volumes.objs[i]->name,
1273 1274
                                     obj->volumes.objs[i]->key,
                                     NULL, NULL)))
1275 1276 1277 1278 1279 1280 1281 1282 1283 1284
            goto cleanup;
        tmp_vols[nvols++] = vol;
    }

    *vols = tmp_vols;
    tmp_vols = NULL;
    ret = nvols;

 cleanup:
    if (tmp_vols) {
1285 1286
        for (i = 0; i < nvols; i++)
            virObjectUnref(tmp_vols[i]);
1287
        VIR_FREE(tmp_vols);
1288 1289
    }

1290
    virStoragePoolObjUnlock(obj);
1291 1292 1293

    return ret;
}
1294 1295

static virStorageVolPtr
1296
storageVolLookupByName(virStoragePoolPtr obj,
1297 1298
                       const char *name)
{
1299
    virStoragePoolObjPtr pool;
1300
    virStorageVolDefPtr vol;
1301
    virStorageVolPtr ret = NULL;
1302

1303 1304
    if (!(pool = virStoragePoolObjFromStoragePool(obj)))
        return NULL;
1305 1306

    if (!virStoragePoolObjIsActive(pool)) {
1307
        virReportError(VIR_ERR_OPERATION_INVALID,
1308
                       _("storage pool '%s' is not active"), pool->def->name);
1309
        goto cleanup;
1310 1311 1312 1313 1314
    }

    vol = virStorageVolDefFindByName(pool, name);

    if (!vol) {
1315 1316 1317
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"),
                       name);
1318
        goto cleanup;
1319 1320
    }

1321 1322 1323
    if (virStorageVolLookupByNameEnsureACL(obj->conn, pool->def, vol) < 0)
        goto cleanup;

1324 1325
    ret = virGetStorageVol(obj->conn, pool->def->name, vol->name, vol->key,
                           NULL, NULL);
1326

1327
 cleanup:
1328
    virStoragePoolObjUnlock(pool);
1329
    return ret;
1330 1331 1332 1333
}


static virStorageVolPtr
1334
storageVolLookupByKey(virConnectPtr conn,
1335 1336
                      const char *key)
{
1337
    size_t i;
1338
    virStorageVolPtr ret = NULL;
1339

1340
    storageDriverLock();
1341
    for (i = 0; i < driver->pools.count && !ret; i++) {
1342
        virStoragePoolObjLock(driver->pools.objs[i]);
1343 1344 1345
        if (virStoragePoolObjIsActive(driver->pools.objs[i])) {
            virStorageVolDefPtr vol =
                virStorageVolDefFindByKey(driver->pools.objs[i], key);
1346

1347
            if (vol) {
1348 1349
                virStoragePoolDefPtr def = driver->pools.objs[i]->def;
                if (virStorageVolLookupByKeyEnsureACL(conn, def, vol) < 0) {
1350
                    virStoragePoolObjUnlock(driver->pools.objs[i]);
1351
                    goto cleanup;
1352
                }
1353

1354
                ret = virGetStorageVol(conn,
1355
                                       def->name,
1356
                                       vol->name,
1357 1358
                                       vol->key,
                                       NULL, NULL);
1359
            }
1360
        }
1361
        virStoragePoolObjUnlock(driver->pools.objs[i]);
1362 1363
    }

1364
    if (!ret)
1365
        virReportError(VIR_ERR_NO_STORAGE_VOL,
1366
                       _("no storage vol with matching key %s"), key);
1367

1368
 cleanup:
1369
    storageDriverUnlock();
1370
    return ret;
1371 1372 1373
}

static virStorageVolPtr
1374
storageVolLookupByPath(virConnectPtr conn,
1375 1376
                       const char *path)
{
1377
    size_t i;
1378
    virStorageVolPtr ret = NULL;
1379 1380 1381 1382 1383
    char *cleanpath;

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

1385
    storageDriverLock();
1386
    for (i = 0; i < driver->pools.count && !ret; i++) {
1387 1388 1389 1390 1391
        virStoragePoolObjPtr pool = driver->pools.objs[i];
        virStorageVolDefPtr vol;
        char *stable_path = NULL;

        virStoragePoolObjLock(pool);
1392

1393 1394 1395 1396
        if (!virStoragePoolObjIsActive(pool)) {
           virStoragePoolObjUnlock(pool);
           continue;
        }
1397

1398
        switch ((virStoragePoolType) pool->def->type) {
1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423
            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:
            case VIR_STORAGE_POOL_SCSI:
            case VIR_STORAGE_POOL_MPATH:
                stable_path = virStorageBackendStablePath(pool,
                                                          cleanpath,
                                                          false);
                if (stable_path == NULL) {
                    /* Don't break the whole lookup process if it fails on
                     * getting the stable path for some of the pools.
                     */
                    VIR_WARN("Failed to get stable path for pool '%s'",
                             pool->def->name);
                    virStoragePoolObjUnlock(pool);
                    continue;
                }
                break;

            case VIR_STORAGE_POOL_GLUSTER:
            case VIR_STORAGE_POOL_RBD:
            case VIR_STORAGE_POOL_SHEEPDOG:
R
Roman Bogorodskiy 已提交
1424
            case VIR_STORAGE_POOL_ZFS:
1425 1426 1427
            case VIR_STORAGE_POOL_LAST:
                if (VIR_STRDUP(stable_path, path) < 0) {
                     virStoragePoolObjUnlock(pool);
1428
                    goto cleanup;
1429
                }
1430 1431
                break;
        }
1432

1433 1434 1435 1436 1437 1438 1439
        vol = virStorageVolDefFindByPath(pool, stable_path);
        VIR_FREE(stable_path);

        if (vol) {
            if (virStorageVolLookupByPathEnsureACL(conn, pool->def, vol) < 0) {
                virStoragePoolObjUnlock(pool);
                goto cleanup;
1440
            }
1441 1442 1443 1444

            ret = virGetStorageVol(conn, pool->def->name,
                                   vol->name, vol->key,
                                   NULL, NULL);
1445
        }
1446 1447

        virStoragePoolObjUnlock(pool);
1448 1449
    }

1450 1451 1452 1453 1454 1455 1456 1457 1458 1459
    if (!ret) {
        if (STREQ(path, cleanpath)) {
            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)"),
                           path, cleanpath);
        }
    }
1460

1461
 cleanup:
1462
    VIR_FREE(cleanpath);
1463
    storageDriverUnlock();
1464
    return ret;
1465 1466
}

1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508
virStoragePoolPtr
storagePoolLookupByTargetPath(virConnectPtr conn,
                              const char *path)
{
    size_t i;
    virStoragePoolPtr ret = NULL;
    char *cleanpath;

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

    storageDriverLock();
    for (i = 0; i < driver->pools.count && !ret; i++) {
        virStoragePoolObjPtr pool = driver->pools.objs[i];

        virStoragePoolObjLock(pool);

        if (!virStoragePoolObjIsActive(pool)) {
            virStoragePoolObjUnlock(pool);
            continue;
        }

        if (STREQ(path, pool->def->target.path)) {
            ret = virGetStoragePool(conn, pool->def->name, pool->def->uuid,
                                    NULL, NULL);
        }

        virStoragePoolObjUnlock(pool);
    }
    storageDriverUnlock();

    if (!ret) {
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage pool with matching target path '%s'"),
                       path);
    }

    VIR_FREE(cleanpath);
    return ret;
}

1509

1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555
static int
storageVolDeleteInternal(virStorageVolPtr obj,
                         virStorageBackendPtr backend,
                         virStoragePoolObjPtr pool,
                         virStorageVolDefPtr vol,
                         unsigned int flags,
                         bool updateMeta)
{
    size_t i;
    int ret = -1;

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

        goto cleanup;
    }

    if (backend->deleteVol(obj->conn, pool, vol, flags) < 0)
        goto cleanup;

    /* Update pool metadata - don't update meta data from error paths
     * in this module since the allocation/available weren't adjusted yet
     */
    if (updateMeta) {
        pool->def->allocation -= vol->target.allocation;
        pool->def->available += vol->target.allocation;
    }

    for (i = 0; i < pool->volumes.count; i++) {
        if (pool->volumes.objs[i] == vol) {
            VIR_INFO("Deleting volume '%s' from storage pool '%s'",
                     vol->name, pool->def->name);
            virStorageVolDefFree(vol);

            VIR_DELETE_ELEMENT(pool->volumes.objs, i, pool->volumes.count);
            break;
        }
    }
    ret = 0;

 cleanup:
    return ret;
}


1556 1557 1558 1559
static virStorageVolDefPtr
virStorageVolDefFromVol(virStorageVolPtr obj,
                        virStoragePoolObjPtr *pool,
                        virStorageBackendPtr *backend)
1560 1561
{
    virStorageVolDefPtr vol = NULL;
1562 1563

    *pool = NULL;
1564

1565
    storageDriverLock();
1566
    *pool = virStoragePoolObjFindByName(&driver->pools, obj->pool);
1567
    storageDriverUnlock();
1568

1569
    if (!*pool) {
1570 1571 1572
        virReportError(VIR_ERR_NO_STORAGE_POOL,
                       _("no storage pool with matching name '%s'"),
                       obj->pool);
1573
        return NULL;
1574 1575
    }

1576
    if (!virStoragePoolObjIsActive(*pool)) {
1577
        virReportError(VIR_ERR_OPERATION_INVALID,
1578 1579 1580
                       _("storage pool '%s' is not active"),
                       (*pool)->def->name);
        goto error;
1581 1582
    }

1583
    if (!(vol = virStorageVolDefFindByName(*pool, obj->name))) {
1584 1585 1586
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"),
                       obj->name);
1587
        goto error;
1588 1589
    }

1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616
    if (backend) {
        if (!(*backend = virStorageBackendForType((*pool)->def->type)))
            goto error;
    }

    return vol;

 error:
    virStoragePoolObjUnlock(*pool);
    *pool = NULL;

    return NULL;
}


static int
storageVolDelete(virStorageVolPtr obj,
                 unsigned int flags)
{
    virStoragePoolObjPtr pool;
    virStorageBackendPtr backend;
    virStorageVolDefPtr vol = NULL;
    int ret = -1;

    if (!(vol = virStorageVolDefFromVol(obj, &pool, &backend)))
        return -1;

1617 1618 1619
    if (virStorageVolDeleteEnsureACL(obj->conn, pool->def, vol) < 0)
        goto cleanup;

1620 1621 1622 1623 1624 1625 1626
    if (vol->in_use) {
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still in use."),
                       vol->name);
        goto cleanup;
    }

1627 1628 1629 1630 1631 1632 1633
    if (vol->building) {
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
                       vol->name);
        goto cleanup;
    }

1634
    if (storageVolDeleteInternal(obj, backend, pool, vol, flags, true) < 0)
1635 1636 1637 1638
        goto cleanup;

    ret = 0;

1639
 cleanup:
1640
    virStoragePoolObjUnlock(pool);
1641 1642 1643
    return ret;
}

1644

1645
static virStorageVolPtr
1646 1647 1648
storageVolCreateXML(virStoragePoolPtr obj,
                    const char *xmldesc,
                    unsigned int flags)
E
Eric Blake 已提交
1649
{
1650
    virStoragePoolObjPtr pool;
1651
    virStorageBackendPtr backend;
1652 1653
    virStorageVolDefPtr voldef = NULL;
    virStorageVolPtr ret = NULL, volobj = NULL;
1654
    virStorageVolDefPtr buildvoldef = NULL;
1655

1656
    virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, NULL);
E
Eric Blake 已提交
1657

1658 1659
    if (!(pool = virStoragePoolObjFromStoragePool(obj)))
        return NULL;
1660 1661

    if (!virStoragePoolObjIsActive(pool)) {
1662
        virReportError(VIR_ERR_OPERATION_INVALID,
1663
                       _("storage pool '%s' is not active"), pool->def->name);
1664
        goto cleanup;
1665 1666 1667
    }

    if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
1668
        goto cleanup;
1669

1670
    voldef = virStorageVolDefParseString(pool->def, xmldesc);
1671
    if (voldef == NULL)
1672
        goto cleanup;
1673

1674 1675 1676
    if (virStorageVolCreateXMLEnsureACL(obj->conn, pool->def, voldef) < 0)
        goto cleanup;

1677
    if (virStorageVolDefFindByName(pool, voldef->name)) {
1678
        virReportError(VIR_ERR_STORAGE_VOL_EXIST,
1679
                       _("'%s'"), voldef->name);
1680
        goto cleanup;
1681 1682
    }

1683
    if (VIR_REALLOC_N(pool->volumes.objs,
1684
                      pool->volumes.count+1) < 0)
1685
        goto cleanup;
1686

1687
    if (!backend->createVol) {
1688 1689 1690
        virReportError(VIR_ERR_NO_SUPPORT,
                       "%s", _("storage pool does not support volume "
                               "creation"));
1691
        goto cleanup;
1692 1693
    }

1694 1695 1696
    /* Wipe any key the user may have suggested, as volume creation
     * will generate the canonical key.  */
    VIR_FREE(voldef->key);
1697
    if (backend->createVol(obj->conn, pool, voldef) < 0)
1698
        goto cleanup;
1699

1700 1701
    pool->volumes.objs[pool->volumes.count++] = voldef;
    volobj = virGetStorageVol(obj->conn, pool->def->name, voldef->name,
1702
                              voldef->key, NULL, NULL);
1703 1704 1705 1706
    if (!volobj) {
        pool->volumes.count--;
        goto cleanup;
    }
1707

1708 1709 1710 1711
    if (VIR_ALLOC(buildvoldef) < 0) {
        voldef = NULL;
        goto cleanup;
    }
1712

1713 1714 1715 1716 1717
    /* 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));
1718

1719 1720
    if (backend->buildVol) {
        int buildret;
1721 1722 1723

        /* Drop the pool lock during volume allocation */
        pool->asyncjobs++;
1724
        voldef->building = true;
1725 1726
        virStoragePoolObjUnlock(pool);

1727
        buildret = backend->buildVol(obj->conn, pool, buildvoldef, flags);
1728

1729
        storageDriverLock();
1730
        virStoragePoolObjLock(pool);
1731
        storageDriverUnlock();
1732

1733
        voldef->building = false;
1734 1735 1736
        pool->asyncjobs--;

        if (buildret < 0) {
1737 1738
            VIR_FREE(buildvoldef);
            storageVolDeleteInternal(volobj, backend, pool, voldef,
1739
                                     0, false);
1740
            voldef = NULL;
1741 1742 1743 1744 1745
            goto cleanup;
        }

    }

1746
    /* Update pool metadata */
1747 1748
    pool->def->allocation += buildvoldef->target.allocation;
    pool->def->available -= buildvoldef->target.allocation;
1749

1750
    VIR_INFO("Creating volume '%s' in storage pool '%s'",
1751
             volobj->name, pool->def->name);
1752 1753 1754
    ret = volobj;
    volobj = NULL;
    voldef = NULL;
1755

1756
 cleanup:
1757
    virObjectUnref(volobj);
1758
    virStorageVolDefFree(voldef);
1759
    VIR_FREE(buildvoldef);
1760 1761
    if (pool)
        virStoragePoolObjUnlock(pool);
1762
    return ret;
1763 1764
}

1765
static virStorageVolPtr
1766 1767 1768 1769
storageVolCreateXMLFrom(virStoragePoolPtr obj,
                        const char *xmldesc,
                        virStorageVolPtr vobj,
                        unsigned int flags)
E
Eric Blake 已提交
1770
{
1771 1772 1773 1774
    virStoragePoolObjPtr pool, origpool = NULL;
    virStorageBackendPtr backend;
    virStorageVolDefPtr origvol = NULL, newvol = NULL;
    virStorageVolPtr ret = NULL, volobj = NULL;
O
Osier Yang 已提交
1775
    unsigned long long allocation;
1776
    int buildret;
1777

1778
    virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, NULL);
E
Eric Blake 已提交
1779

1780
    storageDriverLock();
1781
    pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
1782
    if (pool && STRNEQ(obj->name, vobj->pool)) {
1783
        virStoragePoolObjUnlock(pool);
1784
        origpool = virStoragePoolObjFindByName(&driver->pools, vobj->pool);
1785
        virStoragePoolObjLock(pool);
1786
    }
1787
    storageDriverUnlock();
1788
    if (!pool) {
1789 1790
        char uuidstr[VIR_UUID_STRING_BUFLEN];
        virUUIDFormat(obj->uuid, uuidstr);
1791
        virReportError(VIR_ERR_NO_STORAGE_POOL,
1792 1793
                       _("no storage pool with matching uuid '%s' (%s)"),
                       uuidstr, obj->name);
1794 1795 1796
        goto cleanup;
    }

1797
    if (STRNEQ(obj->name, vobj->pool) && !origpool) {
1798 1799 1800
        virReportError(VIR_ERR_NO_STORAGE_POOL,
                       _("no storage pool with matching name '%s'"),
                       vobj->pool);
1801 1802 1803 1804
        goto cleanup;
    }

    if (!virStoragePoolObjIsActive(pool)) {
1805
        virReportError(VIR_ERR_OPERATION_INVALID,
1806
                       _("storage pool '%s' is not active"), pool->def->name);
1807 1808 1809
        goto cleanup;
    }

1810
    if (origpool && !virStoragePoolObjIsActive(origpool)) {
1811
        virReportError(VIR_ERR_OPERATION_INVALID,
1812 1813
                       _("storage pool '%s' is not active"),
                       origpool->def->name);
1814 1815 1816 1817 1818 1819
        goto cleanup;
    }

    if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
        goto cleanup;

1820 1821
    origvol = virStorageVolDefFindByName(origpool ?
                                         origpool : pool, vobj->name);
1822
    if (!origvol) {
1823 1824 1825
        virReportError(VIR_ERR_NO_STORAGE_VOL,
                       _("no storage vol with matching name '%s'"),
                       vobj->name);
1826 1827 1828
        goto cleanup;
    }

1829
    newvol = virStorageVolDefParseString(pool->def, xmldesc);
1830 1831 1832
    if (newvol == NULL)
        goto cleanup;

1833 1834 1835
    if (virStorageVolCreateXMLFromEnsureACL(obj->conn, pool->def, newvol) < 0)
        goto cleanup;

1836
    if (virStorageVolDefFindByName(pool, newvol->name)) {
1837 1838 1839
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("storage volume name '%s' already in use."),
                       newvol->name);
1840 1841 1842 1843
        goto cleanup;
    }

    /* Is there ever a valid case for this? */
1844 1845
    if (newvol->target.capacity < origvol->target.capacity)
        newvol->target.capacity = origvol->target.capacity;
1846

1847 1848
    /* Make sure allocation is at least as large as the destination cap,
     * to make absolutely sure we copy all possible contents */
1849 1850
    if (newvol->target.allocation < origvol->target.capacity)
        newvol->target.allocation = origvol->target.capacity;
1851

1852
    if (!backend->buildVolFrom) {
1853
        virReportError(VIR_ERR_NO_SUPPORT,
1854 1855
                       "%s", _("storage pool does not support"
                               " volume creation from an existing volume"));
1856 1857 1858 1859
        goto cleanup;
    }

    if (origvol->building) {
1860 1861 1862
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
                       origvol->name);
1863 1864 1865 1866 1867 1868 1869 1870
        goto cleanup;
    }

    if (backend->refreshVol &&
        backend->refreshVol(obj->conn, pool, origvol) < 0)
        goto cleanup;

    if (VIR_REALLOC_N(pool->volumes.objs,
1871
                      pool->volumes.count+1) < 0)
1872 1873
        goto cleanup;

1874 1875 1876 1877
    /* '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.  */
    VIR_FREE(newvol->key);
1878
    if (backend->createVol(obj->conn, pool, newvol) < 0)
1879 1880 1881 1882
        goto cleanup;

    pool->volumes.objs[pool->volumes.count++] = newvol;
    volobj = virGetStorageVol(obj->conn, pool->def->name, newvol->name,
1883
                              newvol->key, NULL, NULL);
1884 1885 1886 1887
    if (!volobj) {
        pool->volumes.count--;
        goto cleanup;
    }
1888 1889 1890

    /* Drop the pool lock during volume allocation */
    pool->asyncjobs++;
1891
    newvol->building = true;
1892
    origvol->in_use++;
1893 1894
    virStoragePoolObjUnlock(pool);

1895
    if (origpool) {
1896 1897 1898 1899
        origpool->asyncjobs++;
        virStoragePoolObjUnlock(origpool);
    }

1900
    buildret = backend->buildVolFrom(obj->conn, pool, newvol, origvol, flags);
1901

1902
    storageDriverLock();
1903
    virStoragePoolObjLock(pool);
1904
    if (origpool)
1905
        virStoragePoolObjLock(origpool);
1906
    storageDriverUnlock();
1907

1908
    origvol->in_use--;
1909
    newvol->building = false;
1910
    allocation = newvol->target.allocation;
1911 1912
    pool->asyncjobs--;

1913
    if (origpool) {
1914 1915 1916 1917 1918 1919
        origpool->asyncjobs--;
        virStoragePoolObjUnlock(origpool);
        origpool = NULL;
    }

    if (buildret < 0) {
1920 1921
        storageVolDeleteInternal(volobj, backend, pool, newvol, 0, false);
        newvol = NULL;
1922 1923
        goto cleanup;
    }
1924
    newvol = NULL;
1925

1926
    /* Updating pool metadata */
O
Osier Yang 已提交
1927 1928
    pool->def->allocation += allocation;
    pool->def->available -= allocation;
1929

1930
    VIR_INFO("Creating volume '%s' in storage pool '%s'",
1931
             volobj->name, pool->def->name);
1932 1933 1934
    ret = volobj;
    volobj = NULL;

1935
 cleanup:
1936
    virObjectUnref(volobj);
1937 1938 1939
    virStorageVolDefFree(newvol);
    if (pool)
        virStoragePoolObjUnlock(pool);
1940
    if (origpool)
1941 1942 1943 1944
        virStoragePoolObjUnlock(origpool);
    return ret;
}

1945

1946
static int
1947 1948 1949 1950 1951
storageVolDownload(virStorageVolPtr obj,
                   virStreamPtr stream,
                   unsigned long long offset,
                   unsigned long long length,
                   unsigned int flags)
1952
{
1953
    virStorageBackendPtr backend;
1954 1955 1956 1957 1958 1959
    virStoragePoolObjPtr pool = NULL;
    virStorageVolDefPtr vol = NULL;
    int ret = -1;

    virCheckFlags(0, -1);

1960
    if (!(vol = virStorageVolDefFromVol(obj, &pool, &backend)))
1961
        return -1;
1962

1963
    if (virStorageVolDownloadEnsureACL(obj->conn, pool->def, vol) < 0)
1964
        goto cleanup;
1965

1966
    if (vol->building) {
1967 1968 1969
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
                       vol->name);
1970
        goto cleanup;
1971 1972
    }

1973 1974 1975
    if (!backend->downloadVol) {
        virReportError(VIR_ERR_NO_SUPPORT, "%s",
                       _("storage pool doesn't support volume download"));
1976
        goto cleanup;
1977
    }
1978

1979 1980
    ret = backend->downloadVol(obj->conn, pool, vol, stream,
                               offset, length, flags);
1981

1982
 cleanup:
1983
    virStoragePoolObjUnlock(pool);
1984 1985 1986 1987 1988

    return ret;
}


1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
/**
 * Frees opaque data.
 *
 * @opaque Data to be freed.
 */
static void
virStorageVolPoolRefreshDataFree(void *opaque)
{
    virStorageVolStreamInfoPtr cbdata = opaque;

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

/**
 * 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;
    virStoragePoolObjPtr pool = NULL;
    virStorageBackendPtr backend;

2017 2018
    storageDriverLock();
    if (!(pool = virStoragePoolObjFindByName(&driver->pools,
2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031
                                             cbdata->pool_name)))
        goto cleanup;

    if (!(backend = virStorageBackendForType(pool->def->type)))
        goto cleanup;

    virStoragePoolObjClearVols(pool);
    if (backend->refreshPool(NULL, pool) < 0)
        VIR_DEBUG("Failed to refresh storage pool");

 cleanup:
    if (pool)
        virStoragePoolObjUnlock(pool);
2032
    storageDriverUnlock();
2033 2034 2035 2036 2037 2038 2039 2040
    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 已提交
2041
 * @opaque Buffer to hold the pool name to be refreshed
2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060
 */
static void
virStorageVolFDStreamCloseCb(virStreamPtr st ATTRIBUTE_UNUSED,
                             void *opaque)
{
    virThread thread;

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

 error:
    virStorageVolPoolRefreshDataFree(opaque);
}

2061
static int
2062 2063 2064 2065 2066
storageVolUpload(virStorageVolPtr obj,
                 virStreamPtr stream,
                 unsigned long long offset,
                 unsigned long long length,
                 unsigned int flags)
2067
{
2068
    virStorageBackendPtr backend;
2069 2070
    virStoragePoolObjPtr pool = NULL;
    virStorageVolDefPtr vol = NULL;
2071
    virStorageVolStreamInfoPtr cbdata = NULL;
2072 2073 2074 2075
    int ret = -1;

    virCheckFlags(0, -1);

2076
    if (!(vol = virStorageVolDefFromVol(obj, &pool, &backend)))
2077
        return -1;
2078

2079
    if (virStorageVolUploadEnsureACL(obj->conn, pool->def, vol) < 0)
2080
        goto cleanup;
2081

2082 2083 2084 2085 2086 2087 2088
    if (vol->in_use) {
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still in use."),
                       vol->name);
        goto cleanup;
    }

2089
    if (vol->building) {
2090 2091 2092
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
                       vol->name);
2093
        goto cleanup;
2094 2095
    }

2096 2097 2098
    if (!backend->uploadVol) {
        virReportError(VIR_ERR_NO_SUPPORT, "%s",
                       _("storage pool doesn't support volume upload"));
2099
        goto cleanup;
2100
    }
2101

2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113
    /* If we have a refreshPool, use the callback routine in order to
     * 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.
     */
    if (backend->refreshPool) {
        if (VIR_ALLOC(cbdata) < 0 ||
            VIR_STRDUP(cbdata->pool_name, pool->def->name) < 0)
            goto cleanup;
    }

2114 2115 2116
    if ((ret = backend->uploadVol(obj->conn, pool, vol, stream,
                                  offset, length, flags)) < 0)
        goto cleanup;
2117

2118 2119 2120 2121 2122 2123 2124 2125 2126 2127
    /* Add cleanup callback - call after uploadVol since the stream
     * is then fully set up
     */
    if (cbdata) {
        virFDStreamSetInternalCloseCb(stream,
                                      virStorageVolFDStreamCloseCb,
                                      cbdata, NULL);
        cbdata = NULL;
    }

2128
 cleanup:
2129
    virStoragePoolObjUnlock(pool);
2130 2131
    if (cbdata)
        virStorageVolPoolRefreshDataFree(cbdata);
2132 2133 2134 2135

    return ret;
}

2136
static int
2137 2138 2139
storageVolResize(virStorageVolPtr obj,
                 unsigned long long capacity,
                 unsigned int flags)
2140 2141 2142 2143 2144 2145 2146
{
    virStorageBackendPtr backend;
    virStoragePoolObjPtr pool = NULL;
    virStorageVolDefPtr vol = NULL;
    unsigned long long abs_capacity;
    int ret = -1;

2147
    virCheckFlags(VIR_STORAGE_VOL_RESIZE_ALLOCATE |
2148 2149
                  VIR_STORAGE_VOL_RESIZE_DELTA |
                  VIR_STORAGE_VOL_RESIZE_SHRINK, -1);
2150

2151 2152
    if (!(vol = virStorageVolDefFromVol(obj, &pool, &backend)))
        return -1;
2153

2154
    if (virStorageVolResizeEnsureACL(obj->conn, pool->def, vol) < 0)
2155
        goto cleanup;
2156

2157 2158 2159 2160 2161 2162 2163
    if (vol->in_use) {
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still in use."),
                       vol->name);
        goto cleanup;
    }

2164
    if (vol->building) {
2165 2166 2167
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
                       vol->name);
2168
        goto cleanup;
2169
    }
2170

2171
    if (flags & VIR_STORAGE_VOL_RESIZE_DELTA) {
2172
        abs_capacity = vol->target.capacity + capacity;
2173 2174 2175 2176 2177
        flags &= ~VIR_STORAGE_VOL_RESIZE_DELTA;
    } else {
        abs_capacity = capacity;
    }

2178
    if (abs_capacity < vol->target.allocation) {
2179
        virReportError(VIR_ERR_INVALID_ARG, "%s",
2180 2181
                       _("can't shrink capacity below "
                         "existing allocation"));
2182
        goto cleanup;
2183 2184
    }

2185
    if (abs_capacity < vol->target.capacity &&
2186 2187 2188 2189
        !(flags & VIR_STORAGE_VOL_RESIZE_SHRINK)) {
        virReportError(VIR_ERR_INVALID_ARG, "%s",
                       _("Can't shrink capacity below current "
                         "capacity with shrink flag explicitly specified"));
2190
        goto cleanup;
2191 2192
    }

2193
    if (abs_capacity > vol->target.capacity + pool->def->available) {
2194
        virReportError(VIR_ERR_OPERATION_FAILED, "%s",
2195
                       _("Not enough space left on storage pool"));
2196
        goto cleanup;
2197 2198 2199
    }

    if (!backend->resizeVol) {
2200
        virReportError(VIR_ERR_NO_SUPPORT, "%s",
2201 2202
                       _("storage pool does not support changing of "
                         "volume capacity"));
2203
        goto cleanup;
2204 2205 2206
    }

    if (backend->resizeVol(obj->conn, pool, vol, abs_capacity, flags) < 0)
2207
        goto cleanup;
2208

2209
    vol->target.capacity = abs_capacity;
2210
    if (flags & VIR_STORAGE_VOL_RESIZE_ALLOCATE)
2211
        vol->target.allocation = abs_capacity;
2212 2213

    /* Update pool metadata */
2214 2215
    pool->def->allocation += (abs_capacity - vol->target.capacity);
    pool->def->available -= (abs_capacity - vol->target.capacity);
2216

O
Osier Yang 已提交
2217
    ret = 0;
2218

2219
 cleanup:
2220
    virStoragePoolObjUnlock(pool);
2221 2222 2223

    return ret;
}
2224

2225 2226

static int
2227 2228 2229
storageVolWipePattern(virStorageVolPtr obj,
                      unsigned int algorithm,
                      unsigned int flags)
2230
{
2231
    virStorageBackendPtr backend;
2232 2233 2234 2235
    virStoragePoolObjPtr pool = NULL;
    virStorageVolDefPtr vol = NULL;
    int ret = -1;

2236
    virCheckFlags(0, -1);
2237

2238
    if (algorithm >= VIR_STORAGE_VOL_WIPE_ALG_LAST) {
2239 2240 2241
        virReportError(VIR_ERR_INVALID_ARG,
                       _("wiping algorithm %d not supported"),
                       algorithm);
2242 2243 2244
        return -1;
    }

2245
    if (!(vol = virStorageVolDefFromVol(obj, &pool, &backend)))
2246
        return -1;
2247 2248


2249
    if (virStorageVolWipePatternEnsureACL(obj->conn, pool->def, vol) < 0)
2250
        goto cleanup;
2251

2252 2253 2254 2255 2256 2257 2258
    if (vol->in_use) {
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still in use."),
                       vol->name);
        goto cleanup;
    }

2259
    if (vol->building) {
2260 2261 2262
        virReportError(VIR_ERR_OPERATION_INVALID,
                       _("volume '%s' is still being allocated."),
                       vol->name);
2263
        goto cleanup;
2264 2265
    }

2266 2267 2268
    if (!backend->wipeVol) {
        virReportError(VIR_ERR_NO_SUPPORT, "%s",
                       _("storage pool doesn't support volume wiping"));
2269
        goto cleanup;
2270
    }
2271

2272
    ret = backend->wipeVol(obj->conn, pool, vol, algorithm, flags);
2273

2274
 cleanup:
2275
    virStoragePoolObjUnlock(pool);
2276 2277 2278 2279

    return ret;
}

2280
static int
2281 2282
storageVolWipe(virStorageVolPtr obj,
               unsigned int flags)
2283
{
2284
    return storageVolWipePattern(obj, VIR_STORAGE_VOL_WIPE_ALG_ZERO, flags);
2285 2286
}

2287 2288

static int
2289
storageVolGetInfo(virStorageVolPtr obj,
2290 2291
                  virStorageVolInfoPtr info)
{
2292
    virStoragePoolObjPtr pool;
2293 2294
    virStorageBackendPtr backend;
    virStorageVolDefPtr vol;
2295
    int ret = -1;
2296

2297 2298
    if (!(vol = virStorageVolDefFromVol(obj, &pool, &backend)))
        return -1;
2299

2300 2301 2302
    if (virStorageVolGetInfoEnsureACL(obj->conn, pool->def, vol) < 0)
        goto cleanup;

2303 2304
    if (backend->refreshVol &&
        backend->refreshVol(obj->conn, pool, vol) < 0)
2305
        goto cleanup;
2306 2307

    memset(info, 0, sizeof(*info));
2308
    info->type = vol->type;
2309 2310
    info->capacity = vol->target.capacity;
    info->allocation = vol->target.allocation;
2311
    ret = 0;
2312

2313
 cleanup:
2314
    virStoragePoolObjUnlock(pool);
2315
    return ret;
2316 2317 2318
}

static char *
2319 2320
storageVolGetXMLDesc(virStorageVolPtr obj,
                     unsigned int flags)
E
Eric Blake 已提交
2321
{
2322
    virStoragePoolObjPtr pool;
2323 2324
    virStorageBackendPtr backend;
    virStorageVolDefPtr vol;
2325
    char *ret = NULL;
2326

E
Eric Blake 已提交
2327 2328
    virCheckFlags(0, NULL);

2329 2330
    if (!(vol = virStorageVolDefFromVol(obj, &pool, &backend)))
        return NULL;
2331

2332 2333 2334
    if (virStorageVolGetXMLDescEnsureACL(obj->conn, pool->def, vol) < 0)
        goto cleanup;

2335 2336 2337
    if (backend->refreshVol &&
        backend->refreshVol(obj->conn, pool, vol) < 0)
        goto cleanup;
2338

2339
    ret = virStorageVolDefFormat(pool->def, vol);
2340

2341
 cleanup:
2342
    virStoragePoolObjUnlock(pool);
2343

2344
    return ret;
2345 2346 2347
}

static char *
2348 2349
storageVolGetPath(virStorageVolPtr obj)
{
2350
    virStoragePoolObjPtr pool;
2351
    virStorageVolDefPtr vol;
2352
    char *ret = NULL;
2353

2354 2355
    if (!(vol = virStorageVolDefFromVol(obj, &pool, NULL)))
        return NULL;
2356

2357 2358 2359
    if (virStorageVolGetPathEnsureACL(obj->conn, pool->def, vol) < 0)
        goto cleanup;

2360
    ignore_value(VIR_STRDUP(ret, vol->target.path));
2361

2362
 cleanup:
2363
    virStoragePoolObjUnlock(pool);
2364 2365 2366
    return ret;
}

2367
static int
2368 2369 2370
storageConnectListAllStoragePools(virConnectPtr conn,
                                  virStoragePoolPtr **pools,
                                  unsigned int flags)
2371 2372 2373 2374 2375
{
    int ret = -1;

    virCheckFlags(VIR_CONNECT_LIST_STORAGE_POOLS_FILTERS_ALL, -1);

2376 2377 2378
    if (virConnectListAllStoragePoolsEnsureACL(conn) < 0)
        goto cleanup;

2379
    storageDriverLock();
2380
    ret = virStoragePoolObjListExport(conn, driver->pools, pools,
2381 2382
                                      virConnectListAllStoragePoolsCheckACL,
                                      flags);
2383
    storageDriverUnlock();
2384

2385
 cleanup:
2386 2387 2388
    return ret;
}

2389

2390
static virStorageDriver storageDriver = {
2391
    .name = "storage",
2392 2393
    .storageOpen = storageOpen, /* 0.4.0 */
    .storageClose = storageClose, /* 0.4.0 */
2394 2395 2396 2397 2398 2399
    .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 */
    .connectFindStoragePoolSources = storageConnectFindStoragePoolSources, /* 0.4.0 */
2400 2401 2402
    .storagePoolLookupByName = storagePoolLookupByName, /* 0.4.0 */
    .storagePoolLookupByUUID = storagePoolLookupByUUID, /* 0.4.0 */
    .storagePoolLookupByVolume = storagePoolLookupByVolume, /* 0.4.0 */
2403 2404
    .storagePoolCreateXML = storagePoolCreateXML, /* 0.4.0 */
    .storagePoolDefineXML = storagePoolDefineXML, /* 0.4.0 */
2405 2406
    .storagePoolBuild = storagePoolBuild, /* 0.4.0 */
    .storagePoolUndefine = storagePoolUndefine, /* 0.4.0 */
2407
    .storagePoolCreate = storagePoolCreate, /* 0.4.0 */
2408 2409 2410 2411 2412 2413 2414
    .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 */
2415
    .storagePoolNumOfVolumes = storagePoolNumOfVolumes, /* 0.4.0 */
2416 2417 2418
    .storagePoolListVolumes = storagePoolListVolumes, /* 0.4.0 */
    .storagePoolListAllVolumes = storagePoolListAllVolumes, /* 0.10.2 */

2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432
    .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 */
    .storageVolGetXMLDesc = storageVolGetXMLDesc, /* 0.4.0 */
    .storageVolGetPath = storageVolGetPath, /* 0.4.0 */
    .storageVolResize = storageVolResize, /* 0.9.10 */
2433 2434 2435

    .storagePoolIsActive = storagePoolIsActive, /* 0.7.3 */
    .storagePoolIsPersistent = storagePoolIsPersistent, /* 0.7.3 */
2436 2437 2438 2439
};


static virStateDriver stateDriver = {
2440
    .name = "Storage",
2441
    .stateInitialize = storageStateInitialize,
2442
    .stateAutoStart = storageStateAutoStart,
2443 2444
    .stateCleanup = storageStateCleanup,
    .stateReload = storageStateReload,
2445 2446
};

2447 2448 2449 2450
int storageRegister(void)
{
    if (virRegisterStorageDriver(&storageDriver) < 0)
        return -1;
2451 2452
    if (virRegisterStateDriver(&stateDriver) < 0)
        return -1;
2453 2454
    return 0;
}
2455 2456 2457


/* ----------- file handlers cooperating with storage driver --------------- */
2458 2459 2460
static bool
virStorageFileIsInitialized(virStorageSourcePtr src)
{
2461
    return src && src->drv;
2462 2463
}

2464 2465 2466 2467

static bool
virStorageFileSupportsBackingChainTraversal(virStorageSourcePtr src)
{
2468
    int actualType;
2469 2470 2471 2472
    virStorageFileBackendPtr backend;

    if (!src)
        return false;
2473
    actualType = virStorageSourceGetActualType(src);
2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488

    if (src->drv) {
        backend = src->drv->backend;
    } else {
        if (!(backend = virStorageFileBackendForTypeInternal(actualType,
                                                             src->protocol,
                                                             false)))
            return false;
    }

    return backend->storageFileGetUniqueIdentifier &&
           backend->storageFileReadHeader &&
           backend->storageFileAccess;
}

2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500

/**
 * virStorageFileSupportsSecurityDriver:
 *
 * @src: a storage file structure
 *
 * Check if a storage file supports operations needed by the security
 * driver to perform labelling
 */
bool
virStorageFileSupportsSecurityDriver(virStorageSourcePtr src)
{
2501
    int actualType;
2502 2503 2504 2505
    virStorageFileBackendPtr backend;

    if (!src)
        return false;
2506
    actualType = virStorageSourceGetActualType(src);
2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520

    if (src->drv) {
        backend = src->drv->backend;
    } else {
        if (!(backend = virStorageFileBackendForTypeInternal(actualType,
                                                             src->protocol,
                                                             false)))
            return false;
    }

    return !!backend->storageFileChown;
}


2521
void
2522
virStorageFileDeinit(virStorageSourcePtr src)
2523
{
2524
    if (!virStorageFileIsInitialized(src))
2525 2526
        return;

2527 2528 2529
    if (src->drv->backend &&
        src->drv->backend->backendDeinit)
        src->drv->backend->backendDeinit(src);
2530

2531
    VIR_FREE(src->drv);
2532 2533 2534
}


2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547
/**
 * virStorageFileInitAs:
 *
 * @src: storage source definition
 * @uid: uid used to access the file, or -1 for current uid
 * @gid: gid used to access the file, or -1 for current gid
 *
 * Initialize a storage source to be used with storage driver. Use the provided
 * uid and gid if possible for the operations.
 *
 * Returns 0 if the storage file was successfully initialized, -1 if the
 * initialization failed. Libvirt error is reported.
 */
2548
int
2549 2550
virStorageFileInitAs(virStorageSourcePtr src,
                     uid_t uid, gid_t gid)
2551
{
2552 2553 2554
    int actualType = virStorageSourceGetActualType(src);
    if (VIR_ALLOC(src->drv) < 0)
        return -1;
2555

2556 2557 2558 2559 2560 2561 2562 2563 2564 2565
    if (uid == (uid_t) -1)
        src->drv->uid = geteuid();
    else
        src->drv->uid = uid;

    if (gid == (gid_t) -1)
        src->drv->gid = getegid();
    else
        src->drv->gid = gid;

2566 2567
    if (!(src->drv->backend = virStorageFileBackendForType(actualType,
                                                           src->protocol)))
2568 2569
        goto error;

2570 2571
    if (src->drv->backend->backendInit &&
        src->drv->backend->backendInit(src) < 0)
2572 2573
        goto error;

2574
    return 0;
2575

2576
 error:
2577 2578
    VIR_FREE(src->drv);
    return -1;
2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591
}


/**
 * virStorageFileInit:
 *
 * See virStorageFileInitAs. The file is initialized to be accessed by the
 * current user.
 */
int
virStorageFileInit(virStorageSourcePtr src)
{
    return virStorageFileInitAs(src, -1, -1);
2592 2593 2594 2595 2596 2597
}


/**
 * virStorageFileCreate: Creates an empty storage file via storage driver
 *
2598
 * @src: file structure pointing to the file
2599 2600 2601 2602 2603
 *
 * Returns 0 on success, -2 if the function isn't supported by the backend,
 * -1 on other failure. Errno is set in case of failure.
 */
int
2604
virStorageFileCreate(virStorageSourcePtr src)
2605
{
2606 2607
    int ret;

2608 2609
    if (!virStorageFileIsInitialized(src) ||
        !src->drv->backend->storageFileCreate) {
2610 2611 2612 2613
        errno = ENOSYS;
        return -2;
    }

2614 2615 2616 2617 2618 2619
    ret = src->drv->backend->storageFileCreate(src);

    VIR_DEBUG("created storage file %p: ret=%d, errno=%d",
              src, ret, errno);

    return ret;
2620 2621 2622 2623 2624 2625
}


/**
 * virStorageFileUnlink: Unlink storage file via storage driver
 *
2626
 * @src: file structure pointing to the file
2627 2628 2629 2630 2631 2632 2633
 *
 * Unlinks the file described by the @file structure.
 *
 * Returns 0 on success, -2 if the function isn't supported by the backend,
 * -1 on other failure. Errno is set in case of failure.
 */
int
2634
virStorageFileUnlink(virStorageSourcePtr src)
2635
{
2636 2637
    int ret;

2638 2639
    if (!virStorageFileIsInitialized(src) ||
        !src->drv->backend->storageFileUnlink) {
2640 2641 2642 2643
        errno = ENOSYS;
        return -2;
    }

2644 2645 2646 2647 2648 2649
    ret = src->drv->backend->storageFileUnlink(src);

    VIR_DEBUG("unlinked storage file %p: ret=%d, errno=%d",
              src, ret, errno);

    return ret;
2650 2651 2652 2653 2654 2655
}


/**
 * virStorageFileStat: returns stat struct of a file via storage driver
 *
2656
 * @src: file structure pointing to the file
2657 2658 2659 2660 2661 2662
 * @stat: stat structure to return data
 *
 * Returns 0 on success, -2 if the function isn't supported by the backend,
 * -1 on other failure. Errno is set in case of failure.
*/
int
2663
virStorageFileStat(virStorageSourcePtr src,
2664 2665
                   struct stat *st)
{
2666 2667
    int ret;

2668 2669
    if (!virStorageFileIsInitialized(src) ||
        !src->drv->backend->storageFileStat) {
2670 2671 2672 2673
        errno = ENOSYS;
        return -2;
    }

2674 2675 2676 2677 2678 2679
    ret = src->drv->backend->storageFileStat(src, st);

    VIR_DEBUG("stat of storage file %p: ret=%d, errno=%d",
              src, ret, errno);

    return ret;
2680
}
2681 2682 2683 2684 2685 2686 2687 2688 2689 2690


/**
 * virStorageFileReadHeader: read the beginning bytes of a file into a buffer
 *
 * @src: file structure pointing to the file
 * @max_len: maximum number of bytes read from the storage file
 * @buf: buffer to read the data into. buffer shall be freed by caller)
 *
 * Returns the count of bytes read on success and -1 on failure, -2 if the
2691 2692
 * function isn't supported by the backend.
 * Libvirt error is reported on failure.
2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709
 */
ssize_t
virStorageFileReadHeader(virStorageSourcePtr src,
                         ssize_t max_len,
                         char **buf)
{
    ssize_t ret;

    if (!virStorageFileIsInitialized(src)) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("storage file backend not initialized"));
        return -1;
    }

    if (!src->drv->backend->storageFileReadHeader) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("storage file header reading is not supported for "
2710
                         "storage type %s (protocol: %s)"),
2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721
                       virStorageTypeToString(src->type),
                       virStorageNetProtocolTypeToString(src->protocol));
        return -2;
    }

    ret = src->drv->backend->storageFileReadHeader(src, max_len, buf);

    VIR_DEBUG("read of storage header %p: ret=%zd", src, ret);

    return ret;
}
2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751


/*
 * virStorageFileGetUniqueIdentifier: Get a unique string describing the volume
 *
 * @src: file structure pointing to the file
 *
 * Returns a string uniquely describing a single volume (canonical path).
 * The string shall not be freed and is valid until the storage file is
 * deinitialized. Returns NULL on error and sets a libvirt error code */
const char *
virStorageFileGetUniqueIdentifier(virStorageSourcePtr src)
{
    if (!virStorageFileIsInitialized(src)) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("storage file backend not initialized"));
        return NULL;
    }

    if (!src->drv->backend->storageFileGetUniqueIdentifier) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unique storage file identifier not implemented for "
                          "storage type %s (protocol: %s)'"),
                       virStorageTypeToString(src->type),
                       virStorageNetProtocolTypeToString(src->protocol));
        return NULL;
    }

    return src->drv->backend->storageFileGetUniqueIdentifier(src);
}
2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775


/**
 * virStorageFileAccess: Check accessibility of a storage file
 *
 * @src: storage file to check access permissions
 * @mode: accessibility check options (see man 2 access)
 *
 * Returns 0 on success, -1 on error and sets errno. No libvirt
 * error is reported. Returns -2 if the operation isn't supported
 * by libvirt storage backend.
 */
int
virStorageFileAccess(virStorageSourcePtr src,
                     int mode)
{
    if (!virStorageFileIsInitialized(src) ||
        !src->drv->backend->storageFileAccess) {
        errno = ENOSYS;
        return -2;
    }

    return src->drv->backend->storageFileAccess(src, mode);
}
2776 2777


2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805
/**
 * virStorageFileChown: Change owner of a storage file
 *
 * @src: storage file to change owner of
 * @uid: new owner id
 * @gid: new group id
 *
 * Returns 0 on success, -1 on error and sets errno. No libvirt
 * error is reported. Returns -2 if the operation isn't supported
 * by libvirt storage backend.
 */
int
virStorageFileChown(virStorageSourcePtr src,
                    uid_t uid,
                    gid_t gid)
{
    if (!virStorageFileIsInitialized(src) ||
        !src->drv->backend->storageFileChown) {
        errno = ENOSYS;
        return -2;
    }

    VIR_DEBUG("chown of storage file %p to %d:%d", src, uid, gid);

    return src->drv->backend->storageFileChown(src, uid, gid);
}


2806 2807 2808
/* Recursive workhorse for virStorageFileGetMetadata.  */
static int
virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
2809
                                 virStorageSourcePtr parent,
2810 2811
                                 uid_t uid, gid_t gid,
                                 bool allow_probe,
2812
                                 bool report_broken,
2813 2814 2815
                                 virHashTablePtr cycle)
{
    int ret = -1;
2816
    const char *uniqueName;
2817 2818
    char *buf = NULL;
    ssize_t headerLen;
2819 2820 2821
    virStorageSourcePtr backingStore = NULL;
    int backingFormat;

2822 2823
    VIR_DEBUG("path=%s format=%d uid=%d gid=%d probe=%d",
              src->path, src->format,
2824 2825
              (int)uid, (int)gid, allow_probe);

2826 2827 2828 2829 2830
    /* exit if we can't load information about the current image */
    if (!virStorageFileSupportsBackingChainTraversal(src))
        return 0;

    if (virStorageFileInitAs(src, uid, gid) < 0)
2831
        return -1;
2832

2833
    if (virStorageFileAccess(src, F_OK) < 0) {
2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845
        if (src == parent) {
            virReportSystemError(errno,
                                 _("Cannot access storage file '%s' "
                                   "(as uid:%d, gid:%d)"),
                                 src->path, (int)uid, (int)gid);
        } else {
            virReportSystemError(errno,
                                 _("Cannot access backing file '%s' "
                                   "of storage file '%s' (as uid:%d, gid:%d)"),
                                 src->path, parent->path, (int)uid, (int)gid);
        }

2846 2847 2848
        goto cleanup;
    }

2849 2850 2851 2852 2853 2854 2855 2856
    if (!(uniqueName = virStorageFileGetUniqueIdentifier(src)))
        goto cleanup;

    if (virHashLookup(cycle, uniqueName)) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("backing store for %s (%s) is self-referential"),
                       src->path, uniqueName);
        goto cleanup;
2857 2858
    }

2859 2860
    if (virHashAddEntry(cycle, uniqueName, (void *)1) < 0)
        goto cleanup;
2861

2862 2863 2864
    if ((headerLen = virStorageFileReadHeader(src, VIR_STORAGE_MAX_HEADER,
                                              &buf)) < 0)
        goto cleanup;
2865

2866 2867
    if (virStorageFileGetMetadataInternal(src, buf, headerLen,
                                          &backingFormat) < 0)
2868
        goto cleanup;
2869 2870

    /* check whether we need to go deeper */
2871 2872 2873 2874
    if (!src->backingStoreRaw) {
        ret = 0;
        goto cleanup;
    }
2875

2876
    if (!(backingStore = virStorageSourceNewFromBacking(src)))
2877
        goto cleanup;
2878 2879 2880 2881 2882 2883 2884 2885

    if (backingFormat == VIR_STORAGE_FILE_AUTO && !allow_probe)
        backingStore->format = VIR_STORAGE_FILE_RAW;
    else if (backingFormat == VIR_STORAGE_FILE_AUTO_SAFE)
        backingStore->format = VIR_STORAGE_FILE_AUTO;
    else
        backingStore->format = backingFormat;

2886
    if ((ret = virStorageFileGetMetadataRecurse(backingStore, parent,
2887 2888 2889 2890 2891 2892
                                                uid, gid,
                                                allow_probe, report_broken,
                                                cycle)) < 0) {
        if (report_broken)
            goto cleanup;

2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903
        /* if we fail somewhere midway, just accept and return a
         * broken chain */
        ret = 0;
        goto cleanup;
    }

    src->backingStore = backingStore;
    backingStore = NULL;
    ret = 0;

 cleanup:
2904
    VIR_FREE(buf);
2905
    virStorageFileDeinit(src);
2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925
    virStorageSourceFree(backingStore);
    return ret;
}


/**
 * virStorageFileGetMetadata:
 *
 * Extract metadata about the storage volume with the specified
 * image format. If image format is VIR_STORAGE_FILE_AUTO, it
 * will probe to automatically identify the format.  Recurses through
 * the entire chain.
 *
 * Open files using UID and GID (or pass -1 for the current user/group).
 * Treat any backing files without explicit type as raw, unless ALLOW_PROBE.
 *
 * Callers are advised never to use VIR_STORAGE_FILE_AUTO as a
 * format, since a malicious guest can turn a raw file into any
 * other non-raw format at will.
 *
2926 2927 2928
 * If @report_broken is true, the whole function fails with a possibly sane
 * error instead of just returning a broken chain.
 *
2929 2930 2931 2932 2933
 * Caller MUST free result after use via virStorageSourceFree.
 */
int
virStorageFileGetMetadata(virStorageSourcePtr src,
                          uid_t uid, gid_t gid,
2934 2935
                          bool allow_probe,
                          bool report_broken)
2936
{
2937 2938 2939
    VIR_DEBUG("path=%s format=%d uid=%d gid=%d probe=%d, report_broken=%d",
              src->path, src->format, (int)uid, (int)gid,
              allow_probe, report_broken);
2940 2941 2942 2943 2944 2945 2946 2947

    virHashTablePtr cycle = NULL;
    int ret = -1;

    if (!(cycle = virHashCreate(5, NULL)))
        return -1;

    if (src->format <= VIR_STORAGE_FILE_NONE)
2948 2949
        src->format = allow_probe ?
            VIR_STORAGE_FILE_AUTO : VIR_STORAGE_FILE_RAW;
2950

2951
    ret = virStorageFileGetMetadataRecurse(src, src, uid, gid,
2952
                                           allow_probe, report_broken, cycle);
2953 2954 2955 2956

    virHashFree(cycle);
    return ret;
}
2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162


static int
virStorageAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
                                 virStoragePoolDefPtr pooldef)
{
    int ret = -1;
    char **tokens = NULL;

    /* Only support one host */
    if (pooldef->source.nhost != 1) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("Expected exactly 1 host for the storage pool"));
        goto cleanup;
    }

    /* iscsi pool only supports one host */
    def->src->nhosts = 1;

    if (VIR_ALLOC_N(def->src->hosts, def->src->nhosts) < 0)
        goto cleanup;

    if (VIR_STRDUP(def->src->hosts[0].name, pooldef->source.hosts[0].name) < 0)
        goto cleanup;

    if (virAsprintf(&def->src->hosts[0].port, "%d",
                    pooldef->source.hosts[0].port ?
                    pooldef->source.hosts[0].port :
                    3260) < 0)
        goto cleanup;

    /* iscsi volume has name like "unit:0:0:1" */
    if (!(tokens = virStringSplit(def->src->srcpool->volume, ":", 0)))
        goto cleanup;

    if (virStringListLength(tokens) != 4) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("unexpected iscsi volume name '%s'"),
                       def->src->srcpool->volume);
        goto cleanup;
    }

    /* iscsi pool has only one source device path */
    if (virAsprintf(&def->src->path, "%s/%s",
                    pooldef->source.devices[0].path,
                    tokens[3]) < 0)
        goto cleanup;

    /* Storage pool have not supported these 2 attributes yet,
     * use the defaults.
     */
    def->src->hosts[0].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
    def->src->hosts[0].socket = NULL;

    def->src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;

    ret = 0;

 cleanup:
    virStringFreeList(tokens);
    return ret;
}


static int
virStorageTranslateDiskSourcePoolAuth(virDomainDiskDefPtr def,
                                      virStoragePoolSourcePtr source)
{
    int ret = -1;

    /* Only necessary when authentication set */
    if (!source->auth) {
        ret = 0;
        goto cleanup;
    }
    def->src->auth = virStorageAuthDefCopy(source->auth);
    if (!def->src->auth)
        goto cleanup;
    ret = 0;

 cleanup:
    return ret;
}


int
virStorageTranslateDiskSourcePool(virConnectPtr conn,
                                  virDomainDiskDefPtr def)
{
    virStoragePoolDefPtr pooldef = NULL;
    virStoragePoolPtr pool = NULL;
    virStorageVolPtr vol = NULL;
    char *poolxml = NULL;
    virStorageVolInfo info;
    int ret = -1;

    if (def->src->type != VIR_STORAGE_TYPE_VOLUME)
        return 0;

    if (!def->src->srcpool)
        return 0;

    if (!(pool = virStoragePoolLookupByName(conn, def->src->srcpool->pool)))
        return -1;

    if (virStoragePoolIsActive(pool) != 1) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("storage pool '%s' containing volume '%s' "
                         "is not active"),
                       def->src->srcpool->pool, def->src->srcpool->volume);
        goto cleanup;
    }

    if (!(vol = virStorageVolLookupByName(pool, def->src->srcpool->volume)))
        goto cleanup;

    if (virStorageVolGetInfo(vol, &info) < 0)
        goto cleanup;

    if (!(poolxml = virStoragePoolGetXMLDesc(pool, 0)))
        goto cleanup;

    if (!(pooldef = virStoragePoolDefParseString(poolxml)))
        goto cleanup;

    def->src->srcpool->pooltype = pooldef->type;
    def->src->srcpool->voltype = info.type;

    if (def->src->srcpool->mode && pooldef->type != VIR_STORAGE_POOL_ISCSI) {
        virReportError(VIR_ERR_XML_ERROR, "%s",
                       _("disk source mode is only valid when "
                         "storage pool is of iscsi type"));
        goto cleanup;
    }

    VIR_FREE(def->src->path);
    virStorageNetHostDefFree(def->src->nhosts, def->src->hosts);
    virStorageAuthDefFree(def->src->auth);

    switch ((virStoragePoolType) pooldef->type) {
    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_SCSI:
    case VIR_STORAGE_POOL_ZFS:
        if (!(def->src->path = virStorageVolGetPath(vol)))
            goto cleanup;

        if (def->startupPolicy && info.type != VIR_STORAGE_VOL_FILE) {
            virReportError(VIR_ERR_XML_ERROR, "%s",
                           _("'startupPolicy' is only valid for "
                             "'file' type volume"));
            goto cleanup;
        }


        switch (info.type) {
        case VIR_STORAGE_VOL_FILE:
            def->src->srcpool->actualtype = VIR_STORAGE_TYPE_FILE;
            break;

        case VIR_STORAGE_VOL_DIR:
            def->src->srcpool->actualtype = VIR_STORAGE_TYPE_DIR;
            break;

        case VIR_STORAGE_VOL_BLOCK:
            def->src->srcpool->actualtype = VIR_STORAGE_TYPE_BLOCK;
            break;

        case VIR_STORAGE_VOL_NETWORK:
        case VIR_STORAGE_VOL_NETDIR:
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unexpected storage volume type '%s' "
                             "for storage pool type '%s'"),
                           virStorageVolTypeToString(info.type),
                           virStoragePoolTypeToString(pooldef->type));
            goto cleanup;
        }

        break;

    case VIR_STORAGE_POOL_ISCSI:
        if (def->startupPolicy) {
            virReportError(VIR_ERR_XML_ERROR, "%s",
                           _("'startupPolicy' is only valid for "
                             "'file' type volume"));
            goto cleanup;
        }

       switch (def->src->srcpool->mode) {
       case VIR_STORAGE_SOURCE_POOL_MODE_DEFAULT:
       case VIR_STORAGE_SOURCE_POOL_MODE_LAST:
           def->src->srcpool->mode = VIR_STORAGE_SOURCE_POOL_MODE_HOST;
           /* fallthrough */
       case VIR_STORAGE_SOURCE_POOL_MODE_HOST:
           def->src->srcpool->actualtype = VIR_STORAGE_TYPE_BLOCK;
           if (!(def->src->path = virStorageVolGetPath(vol)))
               goto cleanup;
           break;

       case VIR_STORAGE_SOURCE_POOL_MODE_DIRECT:
           def->src->srcpool->actualtype = VIR_STORAGE_TYPE_NETWORK;
           def->src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;

3163 3164
           if (virStorageTranslateDiskSourcePoolAuth(def,
                                                     &pooldef->source) < 0)
3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186
               goto cleanup;

           if (virStorageAddISCSIPoolSourceHost(def, pooldef) < 0)
               goto cleanup;
           break;
       }
       break;

    case VIR_STORAGE_POOL_MPATH:
    case VIR_STORAGE_POOL_RBD:
    case VIR_STORAGE_POOL_SHEEPDOG:
    case VIR_STORAGE_POOL_GLUSTER:
    case VIR_STORAGE_POOL_LAST:
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("using '%s' pools for backing 'volume' disks "
                         "isn't yet supported"),
                       virStoragePoolTypeToString(pooldef->type));
        goto cleanup;
    }

    ret = 0;
 cleanup:
3187
    virObjectUnref(pool);
3188
    virObjectUnref(vol);
3189 3190 3191 3192
    VIR_FREE(poolxml);
    virStoragePoolDefFree(pooldef);
    return ret;
}