storage_backend_logical.c 33.4 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

54 55
    cmd = virStorageBackendLogicalChangeCmd(VGCHANGE, def, on);
    return virCommandRun(cmd, NULL);
56 57 58
}


59 60 61 62 63 64 65 66 67
/*
 * @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)
{
68
    VIR_AUTOPTR(virCommand) cmd = NULL;
69

70
    cmd = virCommandNewArgList(PVREMOVE, path, NULL);
71 72 73 74 75
    if (virCommandRun(cmd, NULL) < 0)
        VIR_INFO("Failed to pvremove logical device '%s'", path);
}


76 77 78 79 80 81 82 83 84 85
/*
 * @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)
{
86
    VIR_AUTOPTR(virCommand) pvcmd = NULL;
87 88 89 90 91 92

    /*
     * 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
     */
93
    if (virStorageBackendZeroPartitionTable(path, 1024 * 1024) < 0)
94 95 96 97 98 99 100
        return -1;

    /*
     * Initialize the physical volume because vgcreate is not
     * clever enough todo this for us :-(
     */
    pvcmd = virCommandNewArgList(PVCREATE, path, NULL);
101
    return virCommandRun(pvcmd, NULL);
102 103 104
}


105
#define VIR_STORAGE_VOL_LOGICAL_SEGTYPE_STRIPED "striped"
106 107
#define VIR_STORAGE_VOL_LOGICAL_SEGTYPE_MIRROR  "mirror"
#define VIR_STORAGE_VOL_LOGICAL_SEGTYPE_RAID    "raid"
108

109 110 111 112 113
struct virStorageBackendLogicalPoolVolData {
    virStoragePoolObjPtr pool;
    virStorageVolDefPtr vol;
};

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

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

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

149
    if (virStrToLong_ull(groups[6], NULL, 10, &length) < 0) {
150 151
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("malformed volume extent length value"));
152 153
        goto cleanup;
    }
154

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

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

171
    if (VIR_ALLOC(reg) < 0)
172
        goto cleanup;
173

174 175 176 177
    /* Each extent has a "path:offset" pair, and vars[0] will
     * be the whole matched string.
     */
    nvars = (nextents * 2) + 1;
178
    if (VIR_ALLOC_N(vars, nvars) < 0)
179 180 181 182 183 184
        goto cleanup;

    err = regcomp(reg, regex, REG_EXTENDED);
    if (err != 0) {
        char error[100];
        regerror(err, reg, error, sizeof(error));
185 186 187
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Failed to compile regex %s"),
                       error);
188
        goto cleanup;
189
    }
190

191 192 193
    err = regexec(reg, groups[3], nvars, vars, 0);
    regfree(reg);
    if (err != 0) {
194 195
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("malformed volume extent devices value"));
196
        goto cleanup;
197 198
    }

199
    p = groups[3];
200

201 202
    /* vars[0] is skipped */
    for (i = 0; i < nextents; i++) {
203 204
        size_t j;
        int len;
205
        char *offset_str = NULL;
206 207 208 209 210

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

211
        if (VIR_STRNDUP(extent.path,
212
                        p + vars[j].rm_so, len) < 0)
213 214 215
            goto cleanup;

        len = vars[j + 1].rm_eo - vars[j + 1].rm_so;
216
        if (VIR_STRNDUP(offset_str, p + vars[j + 1].rm_so, len) < 0)
217 218 219
            goto cleanup;

        if (virStrToLong_ull(offset_str, NULL, 10, &offset) < 0) {
220 221
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("malformed volume extent offset value"));
E
Eric Blake 已提交
222
            VIR_FREE(offset_str);
223 224 225
            goto cleanup;
        }
        VIR_FREE(offset_str);
226 227
        extent.start = offset * size;
        extent.end = (offset * size) + length;
228

229 230 231
        if (VIR_APPEND_ELEMENT(vol->source.extents, vol->source.nextent,
                               extent) < 0)
            goto cleanup;
232 233
    }

234 235 236 237 238 239
    ret = 0;

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


static int
virStorageBackendLogicalMakeVol(char **const groups,
                                void *opaque)
{
    struct virStorageBackendLogicalPoolVolData *data = opaque;
    virStoragePoolObjPtr pool = data->pool;
251
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
252 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
    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",
295
                        def->target.path, vol->name) < 0)
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
            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",
320
                        def->target.path, groups[1]) < 0)
321 322 323
            goto cleanup;

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

    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;

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

347 348
    ret = 0;

349
 cleanup:
350
    if (is_new_vol)
351 352
        virStorageVolDefFree(vol);
    return ret;
353 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
#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

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

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

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

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

    return 0;
}


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

469 470 471
    if (VIR_STRDUP(pvname, groups[0]) < 0 ||
        VIR_STRDUP(vgname, groups[1]) < 0)
        goto error;
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
            goto error;
484

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

488
    if (VIR_REALLOC_N(thisSource->devices, thisSource->ndevice + 1) != 0)
489
        goto error;
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
    retval = 0;
499

500
 error:
501 502 503
    VIR_FREE(pvname);
    VIR_FREE(vgname);

504
    return retval;
505 506
}

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

531 532 533 534 535
    /*
     * 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
     */
536 537
    cmd = virCommandNew(VGSCAN);
    if (virCommandRun(cmd, NULL) < 0)
538
        VIR_WARN("Failure when running vgscan to refresh physical volumes");
539
    virCommandFree(cmd);
540

541 542 543
    cmd = virCommandNewArgList(PVS,
                               "--noheadings",
                               "-o", "pv_name,vg_name",
544
                               NULL, NULL);
545 546 547
    return virCommandRunRegex(cmd, 1, regexes, vars,
                              virStorageBackendLogicalFindPoolSourcesFunc,
                              sourceList, "pvs", NULL);
548 549 550 551
}


static char *
552
virStorageBackendLogicalFindPoolSources(const char *srcSpec ATTRIBUTE_UNUSED,
553 554 555 556 557 558 559 560 561 562 563 564 565
                                        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;
566

567
    retval = virStoragePoolSourceListFormat(&sourceList);
568
    if (retval == NULL) {
569 570
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("failed to get source from sourceList"));
571 572 573 574
        goto cleanup;
    }

 cleanup:
575
    for (i = 0; i < sourceList.nsources; i++)
576
        virStoragePoolSourceClear(&sourceList.sources[i]);
577
    VIR_FREE(sourceList.sources);
578 579 580 581 582

    return retval;
}


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

    if (i == sourceList.nsources) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("cannot find logical volume group name '%s'"),
623
                       def->source.name);
624 625 626
        goto cleanup;
    }

627 628 629 630
    /* 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.
     */
631
   if (!def->source.ndevice) {
632 633 634 635
        ret = true;
        goto cleanup;
    }

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


676
static int
677
virStorageBackendLogicalCheckPool(virStoragePoolObjPtr pool,
678 679
                                  bool *isActive)
{
680 681
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);

682 683 684
    /* If we can find the target.path as well as ensure that the
     * pool's def source
     */
685
    *isActive = virFileExists(def->target.path) &&
686
                virStorageBackendLogicalMatchPoolSource(pool);
687 688 689
    return 0;
}

690
static int
691
virStorageBackendLogicalStartPool(virStoragePoolObjPtr pool)
692
{
693 694 695 696
    /* 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 已提交
697
        virStorageBackendLogicalSetActive(pool, true) < 0)
698 699 700 701 702 703 704
        return -1;

    return 0;
}


static int
705
virStorageBackendLogicalBuildPool(virStoragePoolObjPtr pool,
E
Eric Blake 已提交
706
                                  unsigned int flags)
707
{
708
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
709
    int ret = -1;
710
    size_t i = 0;
711
    VIR_AUTOPTR(virCommand) vgcmd = NULL;
712 713 714

    virCheckFlags(VIR_STORAGE_POOL_BUILD_OVERWRITE |
                  VIR_STORAGE_POOL_BUILD_NO_OVERWRITE, ret);
715

716 717 718
    VIR_EXCLUSIVE_FLAGS_GOTO(VIR_STORAGE_POOL_BUILD_OVERWRITE,
                             VIR_STORAGE_POOL_BUILD_NO_OVERWRITE,
                             cleanup);
E
Eric Blake 已提交
719

720
    vgcmd = virCommandNewArgList(VGCREATE, def->source.name, NULL);
721

722 723
    for (i = 0; i < def->source.ndevice; i++) {
        const char *path = def->source.devices[i].path;
724

725 726 727 728 729 730 731
        /* 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;

732
        if (virStorageBackendLogicalInitializeDevice(path) < 0)
733 734
            goto cleanup;

735
        virCommandAddArg(vgcmd, path);
736
    }
737 738

    /* Now create the volume group itself */
739
    if (virCommandRun(vgcmd, NULL) < 0)
740 741
        goto cleanup;

742
    ret = 0;
743

744
 cleanup:
745 746 747 748 749 750
    /* 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++)
751
            virStorageBackendLogicalRemoveDevice(def->source.devices[j].path);
752
    }
753
    return ret;
754 755 756 757
}


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

J
John Ferlan 已提交
778
    virWaitForDevices();
779

780
    /* Get list of all logical volumes */
781 782 783 784 785 786 787 788 789 790
    if (virStorageBackendLogicalFindLVs(pool, NULL) < 0)
        goto cleanup;

    cmd = virCommandNewArgList(VGS,
                               "--separator", ":",
                               "--noheadings",
                               "--units", "b",
                               "--unbuffered",
                               "--nosuffix",
                               "--options", "vg_size,vg_free",
791
                               def->source.name,
792
                               NULL);
793 794

    /* Now get basic volgrp metadata */
795 796 797 798 799 800
    if (virCommandRunRegex(cmd,
                           1,
                           regexes,
                           vars,
                           virStorageBackendLogicalRefreshPoolFunc,
                           pool,
801 802
                           "vgs",
                           NULL) < 0)
803
        goto cleanup;
804

805 806
    ret = 0;

807
 cleanup:
808 809 810
    if (ret < 0)
        virStoragePoolObjClearVols(pool);
    return ret;
811 812
}

813 814 815 816
/*
 * 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)"
817 818
 */
static int
819
virStorageBackendLogicalStopPool(virStoragePoolObjPtr pool)
820
{
J
John Ferlan 已提交
821
    if (virStorageBackendLogicalSetActive(pool, false) < 0)
822 823 824 825 826 827
        return -1;

    return 0;
}

static int
828
virStorageBackendLogicalDeletePool(virStoragePoolObjPtr pool,
E
Eric Blake 已提交
829
                                   unsigned int flags)
830
{
831
    virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
832
    size_t i;
833
    VIR_AUTOPTR(virCommand) cmd = NULL;
834

E
Eric Blake 已提交
835 836
    virCheckFlags(0, -1);

837
    /* first remove the volume group */
838
    cmd = virCommandNewArgList(VGREMOVE,
839
                               "-f", def->source.name,
840 841
                               NULL);
    if (virCommandRun(cmd, NULL) < 0)
842
        return -1;
843

844
    /* now remove the pv devices and clear them out */
845 846
    for (i = 0; i < def->source.ndevice; i++)
        virStorageBackendLogicalRemoveDevice(def->source.devices[i].path);
847

848
    return 0;
849 850 851 852
}


static int
853
virStorageBackendLogicalDeleteVol(virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
854
                                  virStorageVolDefPtr vol,
855 856
                                  unsigned int flags)
{
857 858
    VIR_AUTOPTR(virCommand) lvchange_cmd = NULL;
    VIR_AUTOPTR(virCommand) lvremove_cmd = NULL;
859 860 861

    virCheckFlags(0, -1);

J
John Ferlan 已提交
862
    virWaitForDevices();
863 864 865 866 867 868

    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) {
869
            return -1;
870 871
        } else {
            if (virCommandRun(lvremove_cmd, NULL) < 0)
872
                return -1;
873 874 875
        }
    }

876
    return 0;
877
}
878 879 880


static int
J
John Ferlan 已提交
881 882
virStorageBackendLogicalLVCreate(virStorageVolDefPtr vol,
                                 virStoragePoolDefPtr def)
883
{
884
    unsigned long long capacity = vol->target.capacity;
885
    VIR_AUTOPTR(virCommand) cmd = NULL;
886

887 888 889 890 891 892 893
    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;
    }

894 895 896 897
    cmd = virCommandNewArgList(LVCREATE,
                               "--name", vol->name,
                               NULL);
    virCommandAddArg(cmd, "-L");
898
    if (capacity != vol->target.allocation) {
899
        virCommandAddArgFormat(cmd, "%lluK",
900 901
                               VIR_DIV_UP(vol->target.allocation
                                          ? vol->target.allocation : 1, 1024));
902
        virCommandAddArgList(cmd, "--type", "snapshot", NULL);
903
        virCommandAddArg(cmd, "--virtualsize");
904
        vol->target.sparse = true;
905
    }
906 907 908

    /* 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 */
909
    if (vol->target.encryption)
910 911 912
        capacity += 2 * 1024 * 1024;
    virCommandAddArgFormat(cmd, "%lluK", VIR_DIV_UP(capacity, 1024));

913
    if (virStorageSourceHasBacking(&vol->target))
914
        virCommandAddArgList(cmd, "-s", vol->target.backingStore->path, NULL);
915
    else
916
        virCommandAddArg(cmd, def->source.name);
917

918
    return virCommandRun(cmd, NULL);
J
John Ferlan 已提交
919 920 921 922
}


static int
923
virStorageBackendLogicalCreateVol(virStoragePoolObjPtr pool,
J
John Ferlan 已提交
924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939
                                  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;
940

941
    if (vol->target.encryption &&
942
        virStorageBackendCreateVolUsingQemuImg(pool, vol, NULL, 0) < 0)
943 944
        goto error;

945 946
    if ((fd = virStorageBackendVolOpen(vol->target.path, &sb,
                                       VIR_STORAGE_VOL_OPEN_DEFAULT)) < 0)
947
        goto error;
948 949

    /* We can only chown/grp if root */
950
    if (geteuid() == 0) {
951
        if (fchown(fd, vol->target.perms->uid, vol->target.perms->gid) < 0) {
952
            virReportSystemError(errno,
953 954
                                 _("cannot set file owner '%s'"),
                                 vol->target.path);
955
            goto error;
956 957
        }
    }
958
    if (fchmod(fd, (vol->target.perms->mode == (mode_t)-1 ?
959 960
                    VIR_STORAGE_DEFAULT_VOL_PERM_MODE :
                    vol->target.perms->mode)) < 0) {
961
        virReportSystemError(errno,
962 963
                             _("cannot set file mode '%s'"),
                             vol->target.path);
964
        goto error;
965 966
    }

967
    if (VIR_CLOSE(fd) < 0) {
968
        virReportSystemError(errno,
969 970
                             _("cannot close file '%s'"),
                             vol->target.path);
971
        goto error;
972 973 974
    }

    /* Fill in data about this new vol */
975
    if (virStorageBackendLogicalFindLVs(pool, vol) < 0) {
976
        virReportSystemError(errno,
977 978
                             _("cannot find newly created volume '%s'"),
                             vol->target.path);
979
        goto error;
980 981 982 983
    }

    return 0;

984
 error:
985
    err = virSaveLastError();
986
    VIR_FORCE_CLOSE(fd);
987
    virStorageBackendLogicalDeleteVol(pool, vol, 0);
988
    virSetError(err);
989
    virFreeError(err);
990 991 992
    return -1;
}

993
static int
994
virStorageBackendLogicalBuildVolFrom(virStoragePoolObjPtr pool,
995 996 997 998 999 1000
                                     virStorageVolDefPtr vol,
                                     virStorageVolDefPtr inputvol,
                                     unsigned int flags)
{
    virStorageBackendBuildVolFrom build_func;

1001
    build_func = virStorageBackendGetBuildVolFromFunction(vol, inputvol);
1002 1003 1004
    if (!build_func)
        return -1;

1005
    return build_func(pool, vol, inputvol, flags);
1006 1007
}

1008
static int
1009
virStorageBackendLogicalVolWipe(virStoragePoolObjPtr pool,
1010 1011 1012 1013 1014
                                virStorageVolDefPtr vol,
                                unsigned int algorithm,
                                unsigned int flags)
{
    if (!vol->target.sparse)
1015
        return virStorageBackendVolWipeLocal(pool, vol, algorithm, flags);
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029

    /* 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 已提交
1030 1031
                   _("logical volume '%s' is sparse, volume wipe "
                     "not supported"),
1032 1033 1034
                   vol->target.path);
    return -1;
}
1035 1036 1037 1038

virStorageBackend virStorageBackendLogical = {
    .type = VIR_STORAGE_POOL_LOGICAL,

1039
    .findPoolSources = virStorageBackendLogicalFindPoolSources,
1040
    .checkPool = virStorageBackendLogicalCheckPool,
1041 1042 1043 1044 1045
    .startPool = virStorageBackendLogicalStartPool,
    .buildPool = virStorageBackendLogicalBuildPool,
    .refreshPool = virStorageBackendLogicalRefreshPool,
    .stopPool = virStorageBackendLogicalStopPool,
    .deletePool = virStorageBackendLogicalDeletePool,
1046
    .buildVol = NULL,
1047
    .buildVolFrom = virStorageBackendLogicalBuildVolFrom,
1048 1049
    .createVol = virStorageBackendLogicalCreateVol,
    .deleteVol = virStorageBackendLogicalDeleteVol,
1050 1051
    .uploadVol = virStorageBackendVolUploadLocal,
    .downloadVol = virStorageBackendVolDownloadLocal,
1052
    .wipeVol = virStorageBackendLogicalVolWipe,
1053
};
1054 1055 1056 1057 1058 1059 1060


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