storage_backend_logical.c 33.3 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
 */

#include <config.h>

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

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

40 41
#define VIR_FROM_THIS VIR_FROM_STORAGE

42 43
VIR_LOG_INIT("storage.storage_backend_logical");

44 45 46 47
#define PV_BLANK_SECTOR_SIZE 512


static int
48
virStorageBackendLogicalSetActive(virStoragePoolObjPtr pool,
J
John Ferlan 已提交
49
                                  bool on)
50
{
51
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
52
    VIR_AUTOPTR(virCommand) cmd = NULL;
53
    int ret;
54

55
    cmd = virStorageBackendLogicalChangeCmd(VGCHANGE, def, on);
56 57 58 59 60 61

    virObjectUnlock(pool);
    ret = virCommandRun(cmd, NULL);
    virObjectLock(pool);

    return ret;
62 63 64
}


65 66 67 68 69 70 71 72 73
/*
 * @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)
{
74
    VIR_AUTOPTR(virCommand) cmd = NULL;
75

76
    cmd = virCommandNewArgList(PVREMOVE, path, NULL);
77 78 79 80 81
    if (virCommandRun(cmd, NULL) < 0)
        VIR_INFO("Failed to pvremove logical device '%s'", path);
}


82 83 84 85 86 87 88 89 90 91
/*
 * @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)
{
92
    VIR_AUTOPTR(virCommand) pvcmd = NULL;
93 94 95 96 97 98

    /*
     * 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
     */
99
    if (virStorageBackendZeroPartitionTable(path, 1024 * 1024) < 0)
100 101 102 103 104 105 106
        return -1;

    /*
     * Initialize the physical volume because vgcreate is not
     * clever enough todo this for us :-(
     */
    pvcmd = virCommandNewArgList(PVCREATE, path, NULL);
107
    return virCommandRun(pvcmd, NULL);
108 109 110
}


111
#define VIR_STORAGE_VOL_LOGICAL_SEGTYPE_STRIPED "striped"
112 113
#define VIR_STORAGE_VOL_LOGICAL_SEGTYPE_MIRROR  "mirror"
#define VIR_STORAGE_VOL_LOGICAL_SEGTYPE_RAID    "raid"
114

115 116 117 118 119
struct virStorageBackendLogicalPoolVolData {
    virStoragePoolObjPtr pool;
    virStorageVolDefPtr vol;
};

120
static int
121 122
virStorageBackendLogicalParseVolExtents(virStorageVolDefPtr vol,
                                        char **const groups)
123
{
124
    int nextents, ret = -1;
125 126
    const char *regex_unit = "(\\S+)\\((\\S+)\\)";
    char *p = NULL;
127
    size_t i;
128 129
    int err, nvars;
    unsigned long long offset, size, length;
130
    virStorageVolSourceExtent extent;
131 132 133
    VIR_AUTOFREE(char *) regex = NULL;
    VIR_AUTOFREE(regex_t *) reg = NULL;
    VIR_AUTOFREE(regmatch_t *) vars = NULL;
134 135

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

137 138 139 140 141 142 143
    /* 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
     */
144
    nextents = 1;
145 146 147
    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)) {
148
        if (virStrToLong_i(groups[5], NULL, 10, &nextents) < 0) {
149 150
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("malformed volume extent stripes value"));
151 152 153
            goto cleanup;
        }
    }
154

155
    if (virStrToLong_ull(groups[6], NULL, 10, &length) < 0) {
156 157
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("malformed volume extent length value"));
158 159
        goto cleanup;
    }
160

161
    if (virStrToLong_ull(groups[7], NULL, 10, &size) < 0) {
162 163
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("malformed volume extent size value"));
164 165 166
        goto cleanup;
    }

167 168
    /* Allocate space for 'nextents' regex_unit strings plus a comma for each */
    if (VIR_ALLOC_N(regex, nextents * (strlen(regex_unit) + 1) + 1) < 0)
169
        goto cleanup;
J
Ján Tomko 已提交
170
    strcat(regex, regex_unit);
171
    for (i = 1; i < nextents; i++) {
E
Eric Blake 已提交
172
        /* "," is the separator of "devices" field */
173
        strcat(regex, ",");
J
Ján Tomko 已提交
174
        strcat(regex, regex_unit);
175 176
    }

177
    if (VIR_ALLOC(reg) < 0)
178
        goto cleanup;
179

180 181 182 183
    /* Each extent has a "path:offset" pair, and vars[0] will
     * be the whole matched string.
     */
    nvars = (nextents * 2) + 1;
184
    if (VIR_ALLOC_N(vars, nvars) < 0)
185 186 187 188 189 190
        goto cleanup;

    err = regcomp(reg, regex, REG_EXTENDED);
    if (err != 0) {
        char error[100];
        regerror(err, reg, error, sizeof(error));
191 192 193
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to compile regex %s"),
                       error);
194
        goto cleanup;
195
    }
196

197 198 199
    err = regexec(reg, groups[3], nvars, vars, 0);
    regfree(reg);
    if (err != 0) {
200 201
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("malformed volume extent devices value"));
202
        goto cleanup;
203 204
    }

205
    p = groups[3];
206

207 208
    /* vars[0] is skipped */
    for (i = 0; i < nextents; i++) {
209 210
        size_t j;
        int len;
211
        VIR_AUTOFREE(char *) offset_str = NULL;
212 213 214 215 216

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

217
        if (VIR_STRNDUP(extent.path,
218
                        p + vars[j].rm_so, len) < 0)
219 220 221
            goto cleanup;

        len = vars[j + 1].rm_eo - vars[j + 1].rm_so;
222
        if (VIR_STRNDUP(offset_str, p + vars[j + 1].rm_so, len) < 0)
223 224 225
            goto cleanup;

        if (virStrToLong_ull(offset_str, NULL, 10, &offset) < 0) {
226 227
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("malformed volume extent offset value"));
228 229
            goto cleanup;
        }
230 231
        extent.start = offset * size;
        extent.end = (offset * size) + length;
232

233 234 235
        if (VIR_APPEND_ELEMENT(vol->source.extents, vol->source.nextent,
                               extent) < 0)
            goto cleanup;
236 237
    }

238 239 240
    ret = 0;

 cleanup:
241
    VIR_FREE(extent.path);
242 243 244 245 246 247 248 249 250 251
    return ret;
}


static int
virStorageBackendLogicalMakeVol(char **const groups,
                                void *opaque)
{
    struct virStorageBackendLogicalPoolVolData *data = opaque;
    virStoragePoolObjPtr pool = data->pool;
252
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 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
    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",
296
                        def->target.path, vol->name) < 0)
297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
            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] != '[')) {
317
        if (!(vol->target.backingStore = virStorageSourceNew()))
318 319 320
            goto cleanup;

        if (virAsprintf(&vol->target.backingStore->path, "%s/%s",
321
                        def->target.path, groups[1]) < 0)
322 323 324
            goto cleanup;

        vol->target.backingStore->format = VIR_STORAGE_POOL_LOGICAL_LVM2;
325
        vol->target.backingStore->type = VIR_STORAGE_TYPE_BLOCK;
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
    }

    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;

344
    if (is_new_vol && virStoragePoolObjAddVol(pool, vol) < 0)
345
        goto cleanup;
346
    vol = NULL;
347

348 349
    ret = 0;

350
 cleanup:
351
    if (is_new_vol)
352 353
        virStorageVolDefFree(vol);
    return ret;
354 355
}

356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
#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

384
static int
385
virStorageBackendLogicalFindLVs(virStoragePoolObjPtr pool,
386 387 388
                                virStorageVolDefPtr vol)
{
    /*
389 390
     * # 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 已提交
391
     *
392 393 394 395 396 397
     * 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-
398
     *
O
Osier Yang 已提交
399 400
     * Pull out name, origin, & uuid, device, device extent start #,
     * segment size, extent size, size, attrs
401 402
     *
     * NB can be multiple rows per volume if they have many extents
403
     *
404 405
     * NB lvs from some distros (e.g. SLES10 SP2) outputs trailing ","
     * on each line
406 407 408
     *
     * NB Encrypted logical volumes can print ':' in their name, so it is
     *    not a suitable separator (rhbz 470693).
409
     *
410 411
     * NB "devices" field has multiple device paths and "," if the volume is
     *    striped, so "," is not a suitable separator either (rhbz 727474).
412 413
     */
    const char *regexes[] = {
414
        VIR_STORAGE_VOL_LOGICAL_REGEX
415 416
    };
    int vars[] = {
417
        VIR_STORAGE_VOL_LOGICAL_REGEX_COUNT
418
    };
419
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
420 421 422 423
    struct virStorageBackendLogicalPoolVolData cbdata = {
        .pool = pool,
        .vol = vol,
    };
424
    VIR_AUTOPTR(virCommand) cmd = NULL;
425 426 427 428 429 430 431

    cmd = virCommandNewArgList(LVS,
                               "--separator", "#",
                               "--noheadings",
                               "--units", "b",
                               "--unbuffered",
                               "--nosuffix",
O
Osier Yang 已提交
432 433
                               "--options",
                               "lv_name,origin,uuid,devices,segtype,stripes,seg_size,vg_extent_size,size,lv_attr",
434
                               def->source.name,
435
                               NULL);
436 437 438
    return virCommandRunRegex(cmd, 1, regexes, vars,
                              virStorageBackendLogicalMakeVol,
                              &cbdata, "lvs", NULL);
439 440 441
}

static int
442 443
virStorageBackendLogicalRefreshPoolFunc(char **const groups,
                                        void *data)
444
{
445
    virStoragePoolObjPtr pool = data;
446 447 448
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);

    if (virStrToLong_ull(groups[0], NULL, 10, &def->capacity) < 0)
449
        return -1;
450
    if (virStrToLong_ull(groups[1], NULL, 10, &def->available) < 0)
451
        return -1;
452
    def->allocation = def->capacity - def->available;
453 454 455 456 457

    return 0;
}


458
static int
459
virStorageBackendLogicalFindPoolSourcesFunc(char **const groups,
460 461
                                            void *data)
{
462
    virStoragePoolSourceListPtr sourceList = data;
463
    size_t i;
464 465
    virStoragePoolSourceDevicePtr dev;
    virStoragePoolSource *thisSource;
466 467
    VIR_AUTOFREE(char *) pvname = NULL;
    VIR_AUTOFREE(char *) vgname = NULL;
468

469 470
    if (VIR_STRDUP(pvname, groups[0]) < 0 ||
        VIR_STRDUP(vgname, groups[1]) < 0)
471
        return -1;
472 473

    thisSource = NULL;
474
    for (i = 0; i < sourceList->nsources; i++) {
475 476 477 478 479
        if (STREQ(sourceList->sources[i].name, vgname)) {
            thisSource = &sourceList->sources[i];
            break;
        }
    }
480

481
    if (thisSource == NULL) {
482
        if (!(thisSource = virStoragePoolSourceListNewSource(sourceList)))
483
            return -1;
484

485
        VIR_STEAL_PTR(thisSource->name, vgname);
486 487
    }

488
    if (VIR_REALLOC_N(thisSource->devices, thisSource->ndevice + 1) != 0)
489
        return -1;
490

491 492
    dev = &thisSource->devices[thisSource->ndevice];
    thisSource->ndevice++;
493
    thisSource->format = VIR_STORAGE_POOL_LOGICAL_LVM2;
494 495

    memset(dev, 0, sizeof(*dev));
496
    VIR_STEAL_PTR(dev->path, pvname);
497

498
    return 0;
499 500
}

501 502 503 504 505 506 507 508 509 510
/*
 * @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)
511 512
{
    /*
513 514 515
     * # pvs --noheadings -o pv_name,vg_name
     *   /dev/sdb
     *   /dev/sdc VolGroup00
516 517
     */
    const char *regexes[] = {
518
        "^\\s*(\\S+)\\s+(\\S+)\\s*$"
519 520
    };
    int vars[] = {
521
        2
522
    };
523
    VIR_AUTOPTR(virCommand) cmd = NULL;
E
Eric Blake 已提交
524

525 526 527 528 529
    /*
     * 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
     */
530 531
    cmd = virCommandNew(VGSCAN);
    if (virCommandRun(cmd, NULL) < 0)
532
        VIR_WARN("Failure when running vgscan to refresh physical volumes");
533
    virCommandFree(cmd);
534

535 536 537
    cmd = virCommandNewArgList(PVS,
                               "--noheadings",
                               "-o", "pv_name,vg_name",
538
                               NULL, NULL);
539 540 541
    return virCommandRunRegex(cmd, 1, regexes, vars,
                              virStorageBackendLogicalFindPoolSourcesFunc,
                              sourceList, "pvs", NULL);
542 543 544 545
}


static char *
546
virStorageBackendLogicalFindPoolSources(const char *srcSpec ATTRIBUTE_UNUSED,
547 548 549 550 551 552 553 554 555 556 557 558 559
                                        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;
560

561
    retval = virStoragePoolSourceListFormat(&sourceList);
562
    if (retval == NULL) {
563 564
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to get source from sourceList"));
565 566 567 568
        goto cleanup;
    }

 cleanup:
569
    for (i = 0; i < sourceList.nsources; i++)
570
        virStoragePoolSourceClear(&sourceList.sources[i]);
571
    VIR_FREE(sourceList.sources);
572 573 574 575 576

    return retval;
}


577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
/*
 * 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)
{
594
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
595
    virStoragePoolSourceList sourceList;
596
    virStoragePoolSource *thisSource = NULL;
597 598 599 600 601 602 603 604 605 606 607 608 609
    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];
610
        if (STREQ(thisSource->name, def->source.name))
611 612 613 614 615 616
            break;
    }

    if (i == sourceList.nsources) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("cannot find logical volume group name '%s'"),
617
                       def->source.name);
618 619 620
        goto cleanup;
    }

621 622 623 624
    /* 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.
     */
625
   if (!def->source.ndevice) {
626 627 628 629
        ret = true;
        goto cleanup;
    }

630 631 632
    /* Let's make sure the pool's device(s) match what the pvs output has
     * for volume group devices.
     */
633
    for (i = 0; i < def->source.ndevice; i++) {
634
        for (j = 0; j < thisSource->ndevice; j++) {
635
            if (STREQ(def->source.devices[i].path,
636 637 638 639 640 641 642 643 644 645 646
                      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 "
647
                         "volume group '%s'"), def->source.name);
648 649 650 651 652 653 654 655
        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.
     */
656
    if (matchcount != def->source.ndevice)
657 658 659 660 661 662 663 664 665 666 667 668 669
        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;
}


670
static int
671
virStorageBackendLogicalCheckPool(virStoragePoolObjPtr pool,
672 673
                                  bool *isActive)
{
674 675
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);

676 677 678
    /* If we can find the target.path as well as ensure that the
     * pool's def source
     */
679
    *isActive = virFileExists(def->target.path) &&
680
                virStorageBackendLogicalMatchPoolSource(pool);
681 682 683
    return 0;
}

684
static int
685
virStorageBackendLogicalStartPool(virStoragePoolObjPtr pool)
686
{
687 688 689 690
    /* 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) ||
J
John Ferlan 已提交
691
        virStorageBackendLogicalSetActive(pool, true) < 0)
692 693 694 695 696 697 698
        return -1;

    return 0;
}


static int
699
virStorageBackendLogicalBuildPool(virStoragePoolObjPtr pool,
E
Eric Blake 已提交
700
                                  unsigned int flags)
701
{
702
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
703
    int ret = -1;
704
    size_t i = 0;
705
    VIR_AUTOPTR(virCommand) vgcmd = NULL;
706 707 708

    virCheckFlags(VIR_STORAGE_POOL_BUILD_OVERWRITE |
                  VIR_STORAGE_POOL_BUILD_NO_OVERWRITE, ret);
709

710 711 712
    VIR_EXCLUSIVE_FLAGS_GOTO(VIR_STORAGE_POOL_BUILD_OVERWRITE,
                             VIR_STORAGE_POOL_BUILD_NO_OVERWRITE,
                             cleanup);
E
Eric Blake 已提交
713

714
    vgcmd = virCommandNewArgList(VGCREATE, def->source.name, NULL);
715

716 717
    for (i = 0; i < def->source.ndevice; i++) {
        const char *path = def->source.devices[i].path;
718

719 720 721 722 723 724 725
        /* 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;

726
        if (virStorageBackendLogicalInitializeDevice(path) < 0)
727 728
            goto cleanup;

729
        virCommandAddArg(vgcmd, path);
730
    }
731

732
    virObjectUnlock(pool);
733
    /* Now create the volume group itself */
734 735
    ret = virCommandRun(vgcmd, NULL);
    virObjectLock(pool);
736

737
 cleanup:
738 739 740 741 742 743
    /* 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++)
744
            virStorageBackendLogicalRemoveDevice(def->source.devices[j].path);
745
    }
746
    return ret;
747 748 749 750
}


static int
751
virStorageBackendLogicalRefreshPool(virStoragePoolObjPtr pool)
752 753 754 755 756 757
{
    /*
     *  # vgs --separator : --noheadings --units b --unbuffered --nosuffix --options "vg_size,vg_free" VGNAME
     *    10603200512:4328521728
     *
     * Pull out size & free
758 759
     *
     * NB vgs from some distros (e.g. SLES10 SP2) outputs trailing ":" on each line
760 761
     */
    const char *regexes[] = {
762
        "^\\s*(\\S+):([0-9]+):?\\s*$"
763 764 765 766
    };
    int vars[] = {
        2
    };
767
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
768
    VIR_AUTOPTR(virCommand) cmd = NULL;
769

J
John Ferlan 已提交
770
    virWaitForDevices();
771

772
    /* Get list of all logical volumes */
773
    if (virStorageBackendLogicalFindLVs(pool, NULL) < 0)
774
        return -1;
775 776 777 778 779 780 781 782

    cmd = virCommandNewArgList(VGS,
                               "--separator", ":",
                               "--noheadings",
                               "--units", "b",
                               "--unbuffered",
                               "--nosuffix",
                               "--options", "vg_size,vg_free",
783
                               def->source.name,
784
                               NULL);
785 786

    /* Now get basic volgrp metadata */
787 788 789 790 791 792
    if (virCommandRunRegex(cmd,
                           1,
                           regexes,
                           vars,
                           virStorageBackendLogicalRefreshPoolFunc,
                           pool,
793 794
                           "vgs",
                           NULL) < 0)
795
        return -1;
796

797
    return 0;
798 799
}

800 801 802 803
/*
 * 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)"
804 805
 */
static int
806
virStorageBackendLogicalStopPool(virStoragePoolObjPtr pool)
807
{
J
John Ferlan 已提交
808
    if (virStorageBackendLogicalSetActive(pool, false) < 0)
809 810 811 812 813 814
        return -1;

    return 0;
}

static int
815
virStorageBackendLogicalDeletePool(virStoragePoolObjPtr pool,
E
Eric Blake 已提交
816
                                   unsigned int flags)
817
{
818
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
819
    size_t i;
820
    VIR_AUTOPTR(virCommand) cmd = NULL;
821

E
Eric Blake 已提交
822 823
    virCheckFlags(0, -1);

824
    /* first remove the volume group */
825
    cmd = virCommandNewArgList(VGREMOVE,
826
                               "-f", def->source.name,
827 828
                               NULL);
    if (virCommandRun(cmd, NULL) < 0)
829
        return -1;
830

831
    /* now remove the pv devices and clear them out */
832 833
    for (i = 0; i < def->source.ndevice; i++)
        virStorageBackendLogicalRemoveDevice(def->source.devices[i].path);
834

835
    return 0;
836 837 838 839
}


static int
840
virStorageBackendLogicalDeleteVol(virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
841
                                  virStorageVolDefPtr vol,
842 843
                                  unsigned int flags)
{
844 845
    VIR_AUTOPTR(virCommand) lvchange_cmd = NULL;
    VIR_AUTOPTR(virCommand) lvremove_cmd = NULL;
846 847 848

    virCheckFlags(0, -1);

J
John Ferlan 已提交
849
    virWaitForDevices();
850 851 852 853 854 855

    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) {
856
            return -1;
857 858
        } else {
            if (virCommandRun(lvremove_cmd, NULL) < 0)
859
                return -1;
860 861 862
        }
    }

863
    return 0;
864
}
865 866 867


static int
J
John Ferlan 已提交
868 869
virStorageBackendLogicalLVCreate(virStorageVolDefPtr vol,
                                 virStoragePoolDefPtr def)
870
{
871
    unsigned long long capacity = vol->target.capacity;
872
    VIR_AUTOPTR(virCommand) cmd = NULL;
873

874 875 876 877 878 879 880
    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;
    }

881 882 883 884
    cmd = virCommandNewArgList(LVCREATE,
                               "--name", vol->name,
                               NULL);
    virCommandAddArg(cmd, "-L");
885
    if (capacity != vol->target.allocation) {
886
        virCommandAddArgFormat(cmd, "%lluK",
887 888
                               VIR_DIV_UP(vol->target.allocation
                                          ? vol->target.allocation : 1, 1024));
889
        virCommandAddArgList(cmd, "--type", "snapshot", NULL);
890
        virCommandAddArg(cmd, "--virtualsize");
891
        vol->target.sparse = true;
892
    }
893 894 895

    /* 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 */
896
    if (vol->target.encryption)
897 898 899
        capacity += 2 * 1024 * 1024;
    virCommandAddArgFormat(cmd, "%lluK", VIR_DIV_UP(capacity, 1024));

900
    if (virStorageSourceHasBacking(&vol->target))
901
        virCommandAddArgList(cmd, "-s", vol->target.backingStore->path, NULL);
902
    else
903
        virCommandAddArg(cmd, def->source.name);
904

905
    return virCommandRun(cmd, NULL);
J
John Ferlan 已提交
906 907 908 909
}


static int
910
virStorageBackendLogicalCreateVol(virStoragePoolObjPtr pool,
J
John Ferlan 已提交
911 912 913 914 915
                                  virStorageVolDefPtr vol)
{
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
    virErrorPtr err;
    struct stat sb;
J
John Ferlan 已提交
916
    VIR_AUTOCLOSE fd = -1;
J
John Ferlan 已提交
917 918 919 920 921 922 923 924 925 926

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

928
    if (vol->target.encryption &&
929
        virStorageBackendCreateVolUsingQemuImg(pool, vol, NULL, 0) < 0)
930 931
        goto error;

932 933
    if ((fd = virStorageBackendVolOpen(vol->target.path, &sb,
                                       VIR_STORAGE_VOL_OPEN_DEFAULT)) < 0)
934
        goto error;
935 936

    /* We can only chown/grp if root */
937
    if (geteuid() == 0) {
938
        if (fchown(fd, vol->target.perms->uid, vol->target.perms->gid) < 0) {
939
            virReportSystemError(errno,
940 941
                                 _("cannot set file owner '%s'"),
                                 vol->target.path);
942
            goto error;
943 944
        }
    }
945
    if (fchmod(fd, (vol->target.perms->mode == (mode_t)-1 ?
946 947
                    VIR_STORAGE_DEFAULT_VOL_PERM_MODE :
                    vol->target.perms->mode)) < 0) {
948
        virReportSystemError(errno,
949 950
                             _("cannot set file mode '%s'"),
                             vol->target.path);
951
        goto error;
952 953
    }

954
    if (VIR_CLOSE(fd) < 0) {
955
        virReportSystemError(errno,
956 957
                             _("cannot close file '%s'"),
                             vol->target.path);
958
        goto error;
959 960 961
    }

    /* Fill in data about this new vol */
962
    if (virStorageBackendLogicalFindLVs(pool, vol) < 0) {
963
        virReportSystemError(errno,
964 965
                             _("cannot find newly created volume '%s'"),
                             vol->target.path);
966
        goto error;
967 968 969 970
    }

    return 0;

971
 error:
972
    err = virSaveLastError();
973
    virStorageBackendLogicalDeleteVol(pool, vol, 0);
974
    virSetError(err);
975
    virFreeError(err);
976 977 978
    return -1;
}

979
static int
980
virStorageBackendLogicalBuildVolFrom(virStoragePoolObjPtr pool,
981 982 983 984 985 986
                                     virStorageVolDefPtr vol,
                                     virStorageVolDefPtr inputvol,
                                     unsigned int flags)
{
    virStorageBackendBuildVolFrom build_func;

987
    build_func = virStorageBackendGetBuildVolFromFunction(vol, inputvol);
988 989 990
    if (!build_func)
        return -1;

991
    return build_func(pool, vol, inputvol, flags);
992 993
}

994
static int
995
virStorageBackendLogicalVolWipe(virStoragePoolObjPtr pool,
996 997 998 999 1000
                                virStorageVolDefPtr vol,
                                unsigned int algorithm,
                                unsigned int flags)
{
    if (!vol->target.sparse)
1001
        return virStorageBackendVolWipeLocal(pool, vol, algorithm, flags);
1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015

    /* 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 已提交
1016 1017
                   _("logical volume '%s' is sparse, volume wipe "
                     "not supported"),
1018 1019 1020
                   vol->target.path);
    return -1;
}
1021 1022 1023 1024

virStorageBackend virStorageBackendLogical = {
    .type = VIR_STORAGE_POOL_LOGICAL,

1025
    .findPoolSources = virStorageBackendLogicalFindPoolSources,
1026
    .checkPool = virStorageBackendLogicalCheckPool,
1027 1028 1029 1030 1031
    .startPool = virStorageBackendLogicalStartPool,
    .buildPool = virStorageBackendLogicalBuildPool,
    .refreshPool = virStorageBackendLogicalRefreshPool,
    .stopPool = virStorageBackendLogicalStopPool,
    .deletePool = virStorageBackendLogicalDeletePool,
1032
    .buildVol = NULL,
1033
    .buildVolFrom = virStorageBackendLogicalBuildVolFrom,
1034 1035
    .createVol = virStorageBackendLogicalCreateVol,
    .deleteVol = virStorageBackendLogicalDeleteVol,
1036 1037
    .uploadVol = virStorageBackendVolUploadLocal,
    .downloadVol = virStorageBackendVolDownloadLocal,
1038
    .wipeVol = virStorageBackendLogicalVolWipe,
1039
};
1040 1041 1042 1043 1044 1045 1046


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