You need to sign in or sign up before continuing.
storage_backend_logical.c 34.2 KB
Newer Older
1
/*
2
 * storage_backend_logical.c: storage backend for logical volume handling
3
 *
4
 * Copyright (C) 2007-2016 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16 17
 * Copyright (C) 2007-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 29 30 31
 *
 * Author: Daniel P. Berrange <berrange@redhat.com>
 */

#include <config.h>

#include <sys/wait.h>
#include <sys/stat.h>
#include <regex.h>
#include <unistd.h>
#include <fcntl.h>

32
#include "virerror.h"
33 34
#include "storage_backend_logical.h"
#include "storage_conf.h"
35
#include "vircommand.h"
36
#include "viralloc.h"
37
#include "virlog.h"
E
Eric Blake 已提交
38
#include "virfile.h"
39
#include "virstring.h"
40
#include "storage_util.h"
41

42 43
#define VIR_FROM_THIS VIR_FROM_STORAGE

44 45
VIR_LOG_INIT("storage.storage_backend_logical");

46 47 48 49
#define PV_BLANK_SECTOR_SIZE 512


static int
50
virStorageBackendLogicalSetActive(virStoragePoolObjPtr pool,
51 52
                                  int on)
{
53
    int ret;
54
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
55 56 57
    virCommandPtr cmd =
        virCommandNewArgList(VGCHANGE,
                             on ? "-aly" : "-aln",
58
                             def->source.name,
59 60 61 62 63
                             NULL);

    ret = virCommandRun(cmd, NULL);
    virCommandFree(cmd);
    return ret;
64 65 66
}


67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
/*
 * @path: Path to the device
 *
 * Remove the pv device since we're done with it. This ensures a subsequent
 * create won't require special arguments in order for force recreation.
 */
static void
virStorageBackendLogicalRemoveDevice(const char *path)
{
    virCommandPtr cmd = virCommandNewArgList(PVREMOVE, path, NULL);

    if (virCommandRun(cmd, NULL) < 0)
        VIR_INFO("Failed to pvremove logical device '%s'", path);
    virCommandFree(cmd);
}


84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
/*
 * @path: Path to the device
 *
 * Initialize and pvcreate the device.
 *
 * Returns 0 on success, -1 on failure with error message set
 */
static int
virStorageBackendLogicalInitializeDevice(const char *path)
{
    int ret = -1;
    virCommandPtr pvcmd = NULL;

    /*
     * LVM requires that the first sector is blanked if using
     * a whole disk as a PV. So we just blank them out regardless
     * rather than trying to figure out if we're a disk or partition
     */
102
    if (virStorageBackendZeroPartitionTable(path, 1024 * 1024) < 0)
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
        return -1;

    /*
     * Initialize the physical volume because vgcreate is not
     * clever enough todo this for us :-(
     */
    pvcmd = virCommandNewArgList(PVCREATE, path, NULL);
    if (virCommandRun(pvcmd, NULL) < 0)
        goto cleanup;

    ret = 0;

 cleanup:
    virCommandFree(pvcmd);

    return ret;
}


122
#define VIR_STORAGE_VOL_LOGICAL_SEGTYPE_STRIPED "striped"
123 124
#define VIR_STORAGE_VOL_LOGICAL_SEGTYPE_MIRROR  "mirror"
#define VIR_STORAGE_VOL_LOGICAL_SEGTYPE_RAID    "raid"
125

126 127 128 129 130
struct virStorageBackendLogicalPoolVolData {
    virStoragePoolObjPtr pool;
    virStorageVolDefPtr vol;
};

131
static int
132 133
virStorageBackendLogicalParseVolExtents(virStorageVolDefPtr vol,
                                        char **const groups)
134
{
135
    int nextents, ret = -1;
136 137 138 139 140
    const char *regex_unit = "(\\S+)\\((\\S+)\\)";
    char *regex = NULL;
    regex_t *reg = NULL;
    regmatch_t *vars = NULL;
    char *p = NULL;
141
    size_t i;
142 143
    int err, nvars;
    unsigned long long offset, size, length;
144 145 146
    virStorageVolSourceExtent extent;

    memset(&extent, 0, sizeof(extent));
147

148 149 150 151 152 153 154
    /* Assume 1 extent (the regex for 'devices' is "(\\S+)") and only
     * check the 'stripes' field if we have a striped, mirror, or one of
     * the raid (raid1, raid4, raid5*, raid6*, or raid10) segtypes in which
     * case the stripes field will denote the number of lv's within the
     * 'devices' field in order to generate the proper regex to decode
     * the field
     */
155
    nextents = 1;
156 157 158
    if (STREQ(groups[4], VIR_STORAGE_VOL_LOGICAL_SEGTYPE_STRIPED) ||
        STREQ(groups[4], VIR_STORAGE_VOL_LOGICAL_SEGTYPE_MIRROR) ||
        STRPREFIX(groups[4], VIR_STORAGE_VOL_LOGICAL_SEGTYPE_RAID)) {
159
        if (virStrToLong_i(groups[5], NULL, 10, &nextents) < 0) {
160 161
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("malformed volume extent stripes value"));
162 163 164
            goto cleanup;
        }
    }
165

166
    if (virStrToLong_ull(groups[6], NULL, 10, &length) < 0) {
167 168
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("malformed volume extent length value"));
169 170
        goto cleanup;
    }
171

172
    if (virStrToLong_ull(groups[7], NULL, 10, &size) < 0) {
173 174
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("malformed volume extent size value"));
175 176 177
        goto cleanup;
    }

178 179
    /* Allocate space for 'nextents' regex_unit strings plus a comma for each */
    if (VIR_ALLOC_N(regex, nextents * (strlen(regex_unit) + 1) + 1) < 0)
180
        goto cleanup;
J
Ján Tomko 已提交
181
    strcat(regex, regex_unit);
182
    for (i = 1; i < nextents; i++) {
E
Eric Blake 已提交
183
        /* "," is the separator of "devices" field */
184
        strcat(regex, ",");
J
Ján Tomko 已提交
185
        strcat(regex, regex_unit);
186 187
    }

188
    if (VIR_ALLOC(reg) < 0)
189
        goto cleanup;
190

191 192 193 194
    /* Each extent has a "path:offset" pair, and vars[0] will
     * be the whole matched string.
     */
    nvars = (nextents * 2) + 1;
195
    if (VIR_ALLOC_N(vars, nvars) < 0)
196 197 198 199 200 201
        goto cleanup;

    err = regcomp(reg, regex, REG_EXTENDED);
    if (err != 0) {
        char error[100];
        regerror(err, reg, error, sizeof(error));
202 203 204
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to compile regex %s"),
                       error);
205
        goto cleanup;
206
    }
207

208 209 210
    err = regexec(reg, groups[3], nvars, vars, 0);
    regfree(reg);
    if (err != 0) {
211 212
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("malformed volume extent devices value"));
213
        goto cleanup;
214 215
    }

216
    p = groups[3];
217

218 219
    /* vars[0] is skipped */
    for (i = 0; i < nextents; i++) {
220 221
        size_t j;
        int len;
222
        char *offset_str = NULL;
223 224 225 226 227

        j = (i * 2) + 1;
        len = vars[j].rm_eo - vars[j].rm_so;
        p[vars[j].rm_eo] = '\0';

228
        if (VIR_STRNDUP(extent.path,
229
                        p + vars[j].rm_so, len) < 0)
230 231 232
            goto cleanup;

        len = vars[j + 1].rm_eo - vars[j + 1].rm_so;
233
        if (VIR_STRNDUP(offset_str, p + vars[j + 1].rm_so, len) < 0)
234 235 236
            goto cleanup;

        if (virStrToLong_ull(offset_str, NULL, 10, &offset) < 0) {
237 238
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("malformed volume extent offset value"));
E
Eric Blake 已提交
239
            VIR_FREE(offset_str);
240 241 242
            goto cleanup;
        }
        VIR_FREE(offset_str);
243 244
        extent.start = offset * size;
        extent.end = (offset * size) + length;
245

246 247 248
        if (VIR_APPEND_ELEMENT(vol->source.extents, vol->source.nextent,
                               extent) < 0)
            goto cleanup;
249 250
    }

251 252 253 254 255 256
    ret = 0;

 cleanup:
    VIR_FREE(regex);
    VIR_FREE(reg);
    VIR_FREE(vars);
257
    VIR_FREE(extent.path);
258 259 260 261 262 263 264 265 266 267
    return ret;
}


static int
virStorageBackendLogicalMakeVol(char **const groups,
                                void *opaque)
{
    struct virStorageBackendLogicalPoolVolData *data = opaque;
    virStoragePoolObjPtr pool = data->pool;
268
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
    virStorageVolDefPtr vol = NULL;
    bool is_new_vol = false;
    int ret = -1;
    const char *attrs = groups[9];

    /* Skip inactive volume */
    if (attrs[4] != 'a')
        return 0;

    /*
     * Skip thin pools(t). These show up in normal lvs output
     * but do not have a corresponding /dev/$vg/$lv device that
     * is created by udev. This breaks assumptions in later code.
     */
    if (attrs[0] == 't')
        return 0;

    /* See if we're only looking for a specific volume */
    if (data->vol != NULL) {
        vol = data->vol;
        if (STRNEQ(vol->name, groups[0]))
            return 0;
    }

    /* Or filling in more data on an existing volume */
    if (vol == NULL)
        vol = virStorageVolDefFindByName(pool, groups[0]);

    /* Or a completely new volume */
    if (vol == NULL) {
        if (VIR_ALLOC(vol) < 0)
            return -1;

        is_new_vol = true;
        vol->type = VIR_STORAGE_VOL_BLOCK;

        if (VIR_STRDUP(vol->name, groups[0]) < 0)
            goto cleanup;

    }

    if (vol->target.path == NULL) {
        if (virAsprintf(&vol->target.path, "%s/%s",
312
                        def->target.path, vol->name) < 0)
313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336
            goto cleanup;
    }

    /* Mark the (s) sparse/snapshot lv, e.g. the lv created using
     * the --virtualsize/-V option. We've already ignored the (t)hin
     * pool definition. In the manner libvirt defines these, the
     * thin pool is hidden to the lvs output, except as the name
     * in brackets [] described for the groups[1] (backingStore).
     */
    if (attrs[0] == 's')
        vol->target.sparse = true;

    /* Skips the backingStore of lv created with "--virtualsize",
     * its original device "/dev/$vgname/$lvname_vorigin" is
     * just for lvm internal use, one should never use it.
     *
     * (lvs outputs "[$lvname_vorigin] for field "origin" if the
     *  lv is created with "--virtualsize").
     */
    if (groups[1] && STRNEQ(groups[1], "") && (groups[1][0] != '[')) {
        if (VIR_ALLOC(vol->target.backingStore) < 0)
            goto cleanup;

        if (virAsprintf(&vol->target.backingStore->path, "%s/%s",
337
                        def->target.path, groups[1]) < 0)
338 339 340
            goto cleanup;

        vol->target.backingStore->format = VIR_STORAGE_POOL_LOGICAL_LVM2;
341
        vol->target.backingStore->type = VIR_STORAGE_TYPE_BLOCK;
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
    }

    if (!vol->key && VIR_STRDUP(vol->key, groups[2]) < 0)
        goto cleanup;

    if (virStorageBackendUpdateVolInfo(vol, false,
                                       VIR_STORAGE_VOL_OPEN_DEFAULT, 0) < 0)
        goto cleanup;

    if (virStrToLong_ull(groups[8], NULL, 10, &vol->target.allocation) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("malformed volume allocation value"));
        goto cleanup;
    }

    if (virStorageBackendLogicalParseVolExtents(vol, groups) < 0)
        goto cleanup;

360
    if (is_new_vol && virStoragePoolObjAddVol(pool, vol) < 0)
361
        goto cleanup;
362
    vol = NULL;
363

364 365
    ret = 0;

366
 cleanup:
367
    if (is_new_vol)
368 369
        virStorageVolDefFree(vol);
    return ret;
370 371
}

372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399
#define VIR_STORAGE_VOL_LOGICAL_PREFIX_REGEX "^\\s*"
#define VIR_STORAGE_VOL_LOGICAL_LV_NAME_REGEX "(\\S+)#"
#define VIR_STORAGE_VOL_LOGICAL_ORIGIN_REGEX "(\\S*)#"
#define VIR_STORAGE_VOL_LOGICAL_UUID_REGEX "(\\S+)#"
#define VIR_STORAGE_VOL_LOGICAL_DEVICES_REGEX "(\\S+)#"
#define VIR_STORAGE_VOL_LOGICAL_SEGTYPE_REGEX "(\\S+)#"
#define VIR_STORAGE_VOL_LOGICAL_STRIPES_REGEX "([0-9]+)#"
#define VIR_STORAGE_VOL_LOGICAL_SEG_SIZE_REGEX "(\\S+)#"
#define VIR_STORAGE_VOL_LOGICAL_VG_EXTENT_SIZE_REGEX "([0-9]+)#"
#define VIR_STORAGE_VOL_LOGICAL_SIZE_REGEX "([0-9]+)#"
#define VIR_STORAGE_VOL_LOGICAL_LV_ATTR_REGEX "(\\S+)#"
#define VIR_STORAGE_VOL_LOGICAL_SUFFIX_REGEX "?\\s*$"

#define VIR_STORAGE_VOL_LOGICAL_REGEX_COUNT 10
#define VIR_STORAGE_VOL_LOGICAL_REGEX \
           VIR_STORAGE_VOL_LOGICAL_PREFIX_REGEX \
           VIR_STORAGE_VOL_LOGICAL_LV_NAME_REGEX \
           VIR_STORAGE_VOL_LOGICAL_ORIGIN_REGEX \
           VIR_STORAGE_VOL_LOGICAL_UUID_REGEX \
           VIR_STORAGE_VOL_LOGICAL_DEVICES_REGEX \
           VIR_STORAGE_VOL_LOGICAL_SEGTYPE_REGEX \
           VIR_STORAGE_VOL_LOGICAL_STRIPES_REGEX \
           VIR_STORAGE_VOL_LOGICAL_SEG_SIZE_REGEX \
           VIR_STORAGE_VOL_LOGICAL_VG_EXTENT_SIZE_REGEX \
           VIR_STORAGE_VOL_LOGICAL_SIZE_REGEX \
           VIR_STORAGE_VOL_LOGICAL_LV_ATTR_REGEX \
           VIR_STORAGE_VOL_LOGICAL_SUFFIX_REGEX

400
static int
401
virStorageBackendLogicalFindLVs(virStoragePoolObjPtr pool,
402 403 404
                                virStorageVolDefPtr vol)
{
    /*
405 406
     * # lvs --separator # --noheadings --units b --unbuffered --nosuffix --options \
     * "lv_name,origin,uuid,devices,segtype,stripes,seg_size,vg_extent_size,size,lv_attr" VGNAME
O
Osier Yang 已提交
407
     *
408 409 410 411 412 413
     * RootLV##06UgP5-2rhb-w3Bo-3mdR-WeoL-pytO-SAa2ky#/dev/hda2(0)#linear#1#5234491392#33554432#5234491392#-wi-ao
     * SwapLV##oHviCK-8Ik0-paqS-V20c-nkhY-Bm1e-zgzU0M#/dev/hda2(156)#linear#1#1040187392#33554432#1040187392#-wi-ao
     * Test2##3pg3he-mQsA-5Sui-h0i6-HNmc-Cz7W-QSndcR#/dev/hda2(219)#linear#1#1073741824#33554432#1073741824#owi-a-
     * Test3##UB5hFw-kmlm-LSoX-EI1t-ioVd-h7GL-M0W8Ht#/dev/hda2(251)#linear#1#2181038080#33554432#2181038080#-wi-a-
     * Test3#Test2#UB5hFw-kmlm-LSoX-EI1t-ioVd-h7GL-M0W8Ht#/dev/hda2(187)#linear#1#1040187392#33554432#1040187392#swi-a-
     * test_stripes##fSLSZH-zAS2-yAIb-n4mV-Al9u-HA3V-oo9K1B#/dev/sdc1(10240),/dev/sdd1(0)#striped#2#42949672960#4194304#-wi-a-
414
     *
O
Osier Yang 已提交
415 416
     * Pull out name, origin, & uuid, device, device extent start #,
     * segment size, extent size, size, attrs
417 418
     *
     * NB can be multiple rows per volume if they have many extents
419
     *
420 421
     * NB lvs from some distros (e.g. SLES10 SP2) outputs trailing ","
     * on each line
422 423 424
     *
     * NB Encrypted logical volumes can print ':' in their name, so it is
     *    not a suitable separator (rhbz 470693).
425
     *
426 427
     * NB "devices" field has multiple device paths and "," if the volume is
     *    striped, so "," is not a suitable separator either (rhbz 727474).
428 429
     */
    const char *regexes[] = {
430
        VIR_STORAGE_VOL_LOGICAL_REGEX
431 432
    };
    int vars[] = {
433
        VIR_STORAGE_VOL_LOGICAL_REGEX_COUNT
434
    };
435 436
    int ret = -1;
    virCommandPtr cmd;
437
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
438 439 440 441
    struct virStorageBackendLogicalPoolVolData cbdata = {
        .pool = pool,
        .vol = vol,
    };
442 443 444 445 446 447 448

    cmd = virCommandNewArgList(LVS,
                               "--separator", "#",
                               "--noheadings",
                               "--units", "b",
                               "--unbuffered",
                               "--nosuffix",
O
Osier Yang 已提交
449 450
                               "--options",
                               "lv_name,origin,uuid,devices,segtype,stripes,seg_size,vg_extent_size,size,lv_attr",
451
                               def->source.name,
452
                               NULL);
453 454 455 456 457 458
    if (virCommandRunRegex(cmd,
                           1,
                           regexes,
                           vars,
                           virStorageBackendLogicalMakeVol,
                           &cbdata,
459 460
                           "lvs",
                           NULL) < 0)
461
        goto cleanup;
462

463
    ret = 0;
464
 cleanup:
465 466
    virCommandFree(cmd);
    return ret;
467 468 469
}

static int
470 471
virStorageBackendLogicalRefreshPoolFunc(char **const groups,
                                        void *data)
472
{
473
    virStoragePoolObjPtr pool = data;
474 475 476
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);

    if (virStrToLong_ull(groups[0], NULL, 10, &def->capacity) < 0)
477
        return -1;
478
    if (virStrToLong_ull(groups[1], NULL, 10, &def->available) < 0)
479
        return -1;
480
    def->allocation = def->capacity - def->available;
481 482 483 484 485

    return 0;
}


486
static int
487
virStorageBackendLogicalFindPoolSourcesFunc(char **const groups,
488 489
                                            void *data)
{
490 491 492
    virStoragePoolSourceListPtr sourceList = data;
    char *pvname = NULL;
    char *vgname = NULL;
493
    size_t i;
494 495 496
    virStoragePoolSourceDevicePtr dev;
    virStoragePoolSource *thisSource;

497 498 499
    if (VIR_STRDUP(pvname, groups[0]) < 0 ||
        VIR_STRDUP(vgname, groups[1]) < 0)
        goto error;
500 501

    thisSource = NULL;
502
    for (i = 0; i < sourceList->nsources; i++) {
503 504 505 506 507
        if (STREQ(sourceList->sources[i].name, vgname)) {
            thisSource = &sourceList->sources[i];
            break;
        }
    }
508

509
    if (thisSource == NULL) {
510
        if (!(thisSource = virStoragePoolSourceListNewSource(sourceList)))
511
            goto error;
512 513

        thisSource->name = vgname;
514
    }
515 516
    else
        VIR_FREE(vgname);
517

518
    if (VIR_REALLOC_N(thisSource->devices, thisSource->ndevice + 1) != 0)
519
        goto error;
520

521 522
    dev = &thisSource->devices[thisSource->ndevice];
    thisSource->ndevice++;
523
    thisSource->format = VIR_STORAGE_POOL_LOGICAL_LVM2;
524 525 526

    memset(dev, 0, sizeof(*dev));
    dev->path = pvname;
527 528

    return 0;
529

530
 error:
531 532 533 534
    VIR_FREE(pvname);
    VIR_FREE(vgname);

    return -1;
535 536
}

537 538 539 540 541 542 543 544 545 546
/*
 * @sourceList: Pointer to a storage pool source list
 *
 * Use the pvs command to fill the list of pv_name and vg_name associated
 * into the passed sourceList.
 *
 * Returns 0 if successful, -1 and sets error on failure
 */
static int
virStorageBackendLogicalGetPoolSources(virStoragePoolSourceListPtr sourceList)
547 548
{
    /*
549 550 551
     * # pvs --noheadings -o pv_name,vg_name
     *   /dev/sdb
     *   /dev/sdc VolGroup00
552 553
     */
    const char *regexes[] = {
554
        "^\\s*(\\S+)\\s+(\\S+)\\s*$"
555 556
    };
    int vars[] = {
557
        2
558
    };
559
    virCommandPtr cmd;
560
    int ret = -1;
E
Eric Blake 已提交
561

562 563 564 565 566
    /*
     * NOTE: ignoring errors here; this is just to "touch" any logical volumes
     * that might be hanging around, so if this fails for some reason, the
     * worst that happens is that scanning doesn't pick everything up
     */
567 568
    cmd = virCommandNew(VGSCAN);
    if (virCommandRun(cmd, NULL) < 0)
569
        VIR_WARN("Failure when running vgscan to refresh physical volumes");
570
    virCommandFree(cmd);
571

572 573 574
    cmd = virCommandNewArgList(PVS,
                               "--noheadings",
                               "-o", "pv_name,vg_name",
575
                               NULL, NULL);
576 577
    if (virCommandRunRegex(cmd, 1, regexes, vars,
                           virStorageBackendLogicalFindPoolSourcesFunc,
578
                           sourceList, "pvs", NULL) < 0)
579 580 581 582
        goto cleanup;
    ret = 0;

 cleanup:
583
    virCommandFree(cmd);
584 585 586 587 588
    return ret;
}


static char *
589
virStorageBackendLogicalFindPoolSources(const char *srcSpec ATTRIBUTE_UNUSED,
590 591 592 593 594 595 596 597 598 599 600 601 602
                                        unsigned int flags)
{
    virStoragePoolSourceList sourceList;
    size_t i;
    char *retval = NULL;

    virCheckFlags(0, NULL);

    memset(&sourceList, 0, sizeof(sourceList));
    sourceList.type = VIR_STORAGE_POOL_LOGICAL;

    if (virStorageBackendLogicalGetPoolSources(&sourceList) < 0)
        goto cleanup;
603

604
    retval = virStoragePoolSourceListFormat(&sourceList);
605
    if (retval == NULL) {
606 607
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to get source from sourceList"));
608 609 610 611
        goto cleanup;
    }

 cleanup:
612
    for (i = 0; i < sourceList.nsources; i++)
613
        virStoragePoolSourceClear(&sourceList.sources[i]);
614
    VIR_FREE(sourceList.sources);
615 616 617 618 619

    return retval;
}


620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
/*
 * virStorageBackendLogicalMatchPoolSource
 * @pool: Pointer to the source pool object
 *
 * Search the output generated by a 'pvs --noheadings -o pv_name,vg_name'
 * to match the 'vg_name' with the pool def->source.name and for the list
 * of pool def->source.devices[].
 *
 * Returns true if the volume group name matches the pool's source.name
 * and at least one of the pool's def->source.devices[] matches the
 * list of physical device names listed for the pool. Return false if
 * we cannot find a matching volume group name and if we cannot match
 * the any device list members.
 */
static bool
virStorageBackendLogicalMatchPoolSource(virStoragePoolObjPtr pool)
{
637
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
638
    virStoragePoolSourceList sourceList;
639
    virStoragePoolSource *thisSource = NULL;
640 641 642 643 644 645 646 647 648 649 650 651 652
    size_t i, j;
    int matchcount = 0;
    bool ret = false;

    memset(&sourceList, 0, sizeof(sourceList));
    sourceList.type = VIR_STORAGE_POOL_LOGICAL;

    if (virStorageBackendLogicalGetPoolSources(&sourceList) < 0)
        goto cleanup;

    /* Search the pvs output for this pool's source.name */
    for (i = 0; i < sourceList.nsources; i++) {
        thisSource = &sourceList.sources[i];
653
        if (STREQ(thisSource->name, def->source.name))
654 655 656 657 658 659
            break;
    }

    if (i == sourceList.nsources) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("cannot find logical volume group name '%s'"),
660
                       def->source.name);
661 662 663
        goto cleanup;
    }

664 665 666 667
    /* If the pool has defined source device(s), then let's make sure
     * they match as well; otherwise, matching can only occur on the
     * pool's name.
     */
668
   if (!def->source.ndevice) {
669 670 671 672
        ret = true;
        goto cleanup;
    }

673 674 675
    /* Let's make sure the pool's device(s) match what the pvs output has
     * for volume group devices.
     */
676
    for (i = 0; i < def->source.ndevice; i++) {
677
        for (j = 0; j < thisSource->ndevice; j++) {
678
            if (STREQ(def->source.devices[i].path,
679 680 681 682 683 684 685 686 687 688 689
                      thisSource->devices[j].path))
                matchcount++;
        }
    }

    /* If we didn't find any matches, then this pool has listed (a) source
     * device path(s) that don't/doesn't match what was created for the pool
     */
    if (matchcount == 0) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("cannot find any matching source devices for logical "
690
                         "volume group '%s'"), def->source.name);
691 692 693 694 695 696 697 698
        goto cleanup;
    }

    /* Either there's more devices in the pool source device list or there's
     * more devices in the pvs output. Could easily happen if someone decides
     * to 'add' to or 'remove' from the volume group outside of libvirt's
     * knowledge. Rather than fail on that, provide a warning and move on.
     */
699
    if (matchcount != def->source.ndevice)
700 701 702 703 704 705 706 707 708 709 710 711 712
        VIR_WARN("pool device list count doesn't match pvs device list count");

    ret = true;

 cleanup:
    for (i = 0; i < sourceList.nsources; i++)
        virStoragePoolSourceClear(&sourceList.sources[i]);
    VIR_FREE(sourceList.sources);

    return ret;
}


713
static int
714
virStorageBackendLogicalCheckPool(virStoragePoolObjPtr pool,
715 716
                                  bool *isActive)
{
717 718
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);

719 720 721
    /* If we can find the target.path as well as ensure that the
     * pool's def source
     */
722
    *isActive = virFileExists(def->target.path) &&
723
                virStorageBackendLogicalMatchPoolSource(pool);
724 725 726
    return 0;
}

727
static int
728
virStorageBackendLogicalStartPool(virStoragePoolObjPtr pool)
729
{
730 731 732 733 734
    /* Let's make sure that the pool's name matches the pvs output and
     * that the pool's source devices match the pvs output.
     */
    if (!virStorageBackendLogicalMatchPoolSource(pool) ||
        virStorageBackendLogicalSetActive(pool, 1) < 0)
735 736 737 738 739 740 741
        return -1;

    return 0;
}


static int
742
virStorageBackendLogicalBuildPool(virStoragePoolObjPtr pool,
E
Eric Blake 已提交
743
                                  unsigned int flags)
744
{
745
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
746
    virCommandPtr vgcmd = NULL;
747
    int ret = -1;
748 749 750 751
    size_t i = 0;

    virCheckFlags(VIR_STORAGE_POOL_BUILD_OVERWRITE |
                  VIR_STORAGE_POOL_BUILD_NO_OVERWRITE, ret);
752

753 754 755
    VIR_EXCLUSIVE_FLAGS_GOTO(VIR_STORAGE_POOL_BUILD_OVERWRITE,
                             VIR_STORAGE_POOL_BUILD_NO_OVERWRITE,
                             cleanup);
E
Eric Blake 已提交
756

757
    vgcmd = virCommandNewArgList(VGCREATE, def->source.name, NULL);
758

759 760
    for (i = 0; i < def->source.ndevice; i++) {
        const char *path = def->source.devices[i].path;
761

762 763 764 765 766 767 768
        /* The blkid FS and Part probing code doesn't know "lvm2" (this
         * pool's only format type), but it does know "LVM2_member", so
         * we'll pass that here */
        if (!(flags & VIR_STORAGE_POOL_BUILD_OVERWRITE) &&
            !virStorageBackendDeviceIsEmpty(path, "LVM2_member", true))
            goto cleanup;

769
        if (virStorageBackendLogicalInitializeDevice(path) < 0)
770 771
            goto cleanup;

772
        virCommandAddArg(vgcmd, path);
773
    }
774 775

    /* Now create the volume group itself */
776
    if (virCommandRun(vgcmd, NULL) < 0)
777 778
        goto cleanup;

779
    ret = 0;
780

781
 cleanup:
782
    virCommandFree(vgcmd);
783 784 785 786 787 788 789

    /* On any failure, run through the devices that had pvcreate run in
     * in order to run pvremove on the device; otherwise, subsequent build
     * will fail if a pvcreate had been run already. */
    if (ret < 0) {
        size_t j;
        for (j = 0; j < i; j++)
790
            virStorageBackendLogicalRemoveDevice(def->source.devices[j].path);
791
    }
792
    return ret;
793 794 795 796
}


static int
797
virStorageBackendLogicalRefreshPool(virStoragePoolObjPtr pool)
798 799 800 801 802 803
{
    /*
     *  # vgs --separator : --noheadings --units b --unbuffered --nosuffix --options "vg_size,vg_free" VGNAME
     *    10603200512:4328521728
     *
     * Pull out size & free
804 805
     *
     * NB vgs from some distros (e.g. SLES10 SP2) outputs trailing ":" on each line
806 807
     */
    const char *regexes[] = {
808
        "^\\s*(\\S+):([0-9]+):?\\s*$"
809 810 811 812
    };
    int vars[] = {
        2
    };
813
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
814 815
    virCommandPtr cmd = NULL;
    int ret = -1;
816

J
John Ferlan 已提交
817
    virWaitForDevices();
818

819
    /* Get list of all logical volumes */
820 821 822 823 824 825 826 827 828 829
    if (virStorageBackendLogicalFindLVs(pool, NULL) < 0)
        goto cleanup;

    cmd = virCommandNewArgList(VGS,
                               "--separator", ":",
                               "--noheadings",
                               "--units", "b",
                               "--unbuffered",
                               "--nosuffix",
                               "--options", "vg_size,vg_free",
830
                               def->source.name,
831
                               NULL);
832 833

    /* Now get basic volgrp metadata */
834 835 836 837 838 839
    if (virCommandRunRegex(cmd,
                           1,
                           regexes,
                           vars,
                           virStorageBackendLogicalRefreshPoolFunc,
                           pool,
840 841
                           "vgs",
                           NULL) < 0)
842
        goto cleanup;
843

844 845
    ret = 0;

846
 cleanup:
847 848 849 850
    virCommandFree(cmd);
    if (ret < 0)
        virStoragePoolObjClearVols(pool);
    return ret;
851 852
}

853 854 855 856
/*
 * This is actually relatively safe; if you happen to try to "stop" the
 * pool that your / is on, for instance, you will get failure like:
 * "Can't deactivate volume group "VolGroup00" with 3 open logical volume(s)"
857 858
 */
static int
859
virStorageBackendLogicalStopPool(virStoragePoolObjPtr pool)
860
{
861
    if (virStorageBackendLogicalSetActive(pool, 0) < 0)
862 863 864 865 866 867
        return -1;

    return 0;
}

static int
868
virStorageBackendLogicalDeletePool(virStoragePoolObjPtr pool,
E
Eric Blake 已提交
869
                                   unsigned int flags)
870
{
871
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
872 873 874
    virCommandPtr cmd = NULL;
    size_t i;
    int ret = -1;
875

E
Eric Blake 已提交
876 877
    virCheckFlags(0, -1);

878
    /* first remove the volume group */
879
    cmd = virCommandNewArgList(VGREMOVE,
880
                               "-f", def->source.name,
881 882 883
                               NULL);
    if (virCommandRun(cmd, NULL) < 0)
        goto cleanup;
884

885
    /* now remove the pv devices and clear them out */
886 887
    for (i = 0; i < def->source.ndevice; i++)
        virStorageBackendLogicalRemoveDevice(def->source.devices[i].path);
888

889
    ret = 0;
890

891
 cleanup:
892 893
    virCommandFree(cmd);
    return ret;
894 895 896 897
}


static int
898
virStorageBackendLogicalDeleteVol(virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
899
                                  virStorageVolDefPtr vol,
900 901 902 903 904 905 906 907 908
                                  unsigned int flags)
{
    int ret = -1;

    virCommandPtr lvchange_cmd = NULL;
    virCommandPtr lvremove_cmd = NULL;

    virCheckFlags(0, -1);

J
John Ferlan 已提交
909
    virWaitForDevices();
910 911 912 913 914 915 916 917 918 919 920 921 922 923

    lvchange_cmd = virCommandNewArgList(LVCHANGE, "-aln", vol->target.path, NULL);
    lvremove_cmd = virCommandNewArgList(LVREMOVE, "-f", vol->target.path, NULL);

    if (virCommandRun(lvremove_cmd, NULL) < 0) {
        if (virCommandRun(lvchange_cmd, NULL) < 0) {
            goto cleanup;
        } else {
            if (virCommandRun(lvremove_cmd, NULL) < 0)
                goto cleanup;
        }
    }

    ret = 0;
924
 cleanup:
925 926 927 928
    virCommandFree(lvchange_cmd);
    virCommandFree(lvremove_cmd);
    return ret;
}
929 930 931


static int
J
John Ferlan 已提交
932 933
virStorageBackendLogicalLVCreate(virStorageVolDefPtr vol,
                                 virStoragePoolDefPtr def)
934
{
J
John Ferlan 已提交
935
    int ret;
936
    unsigned long long capacity = vol->target.capacity;
937
    virCommandPtr cmd = NULL;
938

939 940 941 942 943 944 945
    if (vol->target.encryption &&
        vol->target.encryption->format != VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                       _("storage pool only supports LUKS encrypted volumes"));
        return -1;
    }

946 947 948 949
    cmd = virCommandNewArgList(LVCREATE,
                               "--name", vol->name,
                               NULL);
    virCommandAddArg(cmd, "-L");
950
    if (capacity != vol->target.allocation) {
951
        virCommandAddArgFormat(cmd, "%lluK",
952 953
                               VIR_DIV_UP(vol->target.allocation
                                          ? vol->target.allocation : 1, 1024));
954
        virCommandAddArgList(cmd, "--type", "snapshot", NULL);
955
        virCommandAddArg(cmd, "--virtualsize");
956
        vol->target.sparse = true;
957
    }
958 959 960

    /* If we're going to encrypt using LUKS, then we could need up to
     * an extra 2MB for the LUKS header - so account for that now */
961
    if (vol->target.encryption)
962 963 964
        capacity += 2 * 1024 * 1024;
    virCommandAddArgFormat(cmd, "%lluK", VIR_DIV_UP(capacity, 1024));

965
    if (virStorageSourceHasBacking(&vol->target))
966
        virCommandAddArgList(cmd, "-s", vol->target.backingStore->path, NULL);
967
    else
968
        virCommandAddArg(cmd, def->source.name);
969

J
John Ferlan 已提交
970
    ret = virCommandRun(cmd, NULL);
971
    virCommandFree(cmd);
J
John Ferlan 已提交
972 973 974 975 976
    return ret;
}


static int
977
virStorageBackendLogicalCreateVol(virStoragePoolObjPtr pool,
J
John Ferlan 已提交
978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993
                                  virStorageVolDefPtr vol)
{
    int fd = -1;
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
    virErrorPtr err;
    struct stat sb;

    vol->type = VIR_STORAGE_VOL_BLOCK;

    VIR_FREE(vol->target.path);
    if (virAsprintf(&vol->target.path, "%s/%s",
                    def->target.path, vol->name) < 0)
        return -1;

    if (virStorageBackendLogicalLVCreate(vol, def) < 0)
        return -1;
994

995
    if (vol->target.encryption &&
996
        virStorageBackendCreateVolUsingQemuImg(pool, vol, NULL, 0) < 0)
997 998
        goto error;

999 1000
    if ((fd = virStorageBackendVolOpen(vol->target.path, &sb,
                                       VIR_STORAGE_VOL_OPEN_DEFAULT)) < 0)
1001
        goto error;
1002 1003

    /* We can only chown/grp if root */
1004
    if (geteuid() == 0) {
1005
        if (fchown(fd, vol->target.perms->uid, vol->target.perms->gid) < 0) {
1006
            virReportSystemError(errno,
1007 1008
                                 _("cannot set file owner '%s'"),
                                 vol->target.path);
1009
            goto error;
1010 1011
        }
    }
1012
    if (fchmod(fd, (vol->target.perms->mode == (mode_t)-1 ?
1013 1014
                    VIR_STORAGE_DEFAULT_VOL_PERM_MODE :
                    vol->target.perms->mode)) < 0) {
1015
        virReportSystemError(errno,
1016 1017
                             _("cannot set file mode '%s'"),
                             vol->target.path);
1018
        goto error;
1019 1020
    }

1021
    if (VIR_CLOSE(fd) < 0) {
1022
        virReportSystemError(errno,
1023 1024
                             _("cannot close file '%s'"),
                             vol->target.path);
1025
        goto error;
1026 1027 1028
    }

    /* Fill in data about this new vol */
1029
    if (virStorageBackendLogicalFindLVs(pool, vol) < 0) {
1030
        virReportSystemError(errno,
1031 1032
                             _("cannot find newly created volume '%s'"),
                             vol->target.path);
1033
        goto error;
1034 1035 1036 1037
    }

    return 0;

1038
 error:
1039
    err = virSaveLastError();
1040
    VIR_FORCE_CLOSE(fd);
1041
    virStorageBackendLogicalDeleteVol(pool, vol, 0);
1042
    virSetError(err);
1043
    virFreeError(err);
1044 1045 1046
    return -1;
}

1047
static int
1048
virStorageBackendLogicalBuildVolFrom(virStoragePoolObjPtr pool,
1049 1050 1051 1052 1053 1054
                                     virStorageVolDefPtr vol,
                                     virStorageVolDefPtr inputvol,
                                     unsigned int flags)
{
    virStorageBackendBuildVolFrom build_func;

1055
    build_func = virStorageBackendGetBuildVolFromFunction(vol, inputvol);
1056 1057 1058
    if (!build_func)
        return -1;

1059
    return build_func(pool, vol, inputvol, flags);
1060 1061
}

1062
static int
1063
virStorageBackendLogicalVolWipe(virStoragePoolObjPtr pool,
1064 1065 1066 1067 1068
                                virStorageVolDefPtr vol,
                                unsigned int algorithm,
                                unsigned int flags)
{
    if (!vol->target.sparse)
1069
        return virStorageBackendVolWipeLocal(pool, vol, algorithm, flags);
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083

    /* The wiping algorithms will write something to the logical volume.
     * Writing to a sparse logical volume causes it to be filled resulting
     * in the volume becoming INACTIVE because there is some amount of
     * metadata contained within the sparse lv. Choosing to only write
     * a wipe pattern to the already written portion lv based on what
     * 'lvs' shows in the "Data%" column/field for the sparse lv was
     * considered. However, there is no guarantee that sparse lv could
     * grow or shrink outside of libvirt's knowledge and thus still render
     * the volume INACTIVE. Until there is some sort of wipe function
     * implemented by lvm for one of these sparse lv, we'll just return
     * unsupported.
     */
    virReportError(VIR_ERR_NO_SUPPORT,
J
John Ferlan 已提交
1084 1085
                   _("logical volume '%s' is sparse, volume wipe "
                     "not supported"),
1086 1087 1088
                   vol->target.path);
    return -1;
}
1089 1090 1091 1092

virStorageBackend virStorageBackendLogical = {
    .type = VIR_STORAGE_POOL_LOGICAL,

1093
    .findPoolSources = virStorageBackendLogicalFindPoolSources,
1094
    .checkPool = virStorageBackendLogicalCheckPool,
1095 1096 1097 1098 1099
    .startPool = virStorageBackendLogicalStartPool,
    .buildPool = virStorageBackendLogicalBuildPool,
    .refreshPool = virStorageBackendLogicalRefreshPool,
    .stopPool = virStorageBackendLogicalStopPool,
    .deletePool = virStorageBackendLogicalDeletePool,
1100
    .buildVol = NULL,
1101
    .buildVolFrom = virStorageBackendLogicalBuildVolFrom,
1102 1103
    .createVol = virStorageBackendLogicalCreateVol,
    .deleteVol = virStorageBackendLogicalDeleteVol,
1104 1105
    .uploadVol = virStorageBackendVolUploadLocal,
    .downloadVol = virStorageBackendVolDownloadLocal,
1106
    .wipeVol = virStorageBackendLogicalVolWipe,
1107
};
1108 1109 1110 1111 1112 1113 1114


int
virStorageBackendLogicalRegister(void)
{
    return virStorageBackendRegister(&virStorageBackendLogical);
}