~ubuntu-branches/debian/stretch/lvm2/stretch

« back to all changes in this revision

Viewing changes to lib/metadata/metadata.c

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2011-08-27 18:45:21 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20110827184521-8lpc2gqp2ybhplzj
Tags: 2.02.86-1
* New upstream version.
* Remove leading article from short description.
* Update udev rules.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3
 
 * Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
 
3
 * Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
4
4
 *
5
5
 * This file is part of LVM2.
6
6
 *
37
37
static struct physical_volume *_pv_read(struct cmd_context *cmd,
38
38
                                        struct dm_pool *pvmem,
39
39
                                        const char *pv_name,
40
 
                                        struct dm_list *mdas,
41
 
                                        uint64_t *label_sector,
 
40
                                        struct format_instance *fid,
42
41
                                        int warnings, int scan_label_only);
43
42
 
44
43
static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd,
166
165
        dm_list_add(&vg->pvs, &pvl->list);
167
166
        vg->pv_count++;
168
167
        pvl->pv->vg = vg;
 
168
        pv_set_fid(pvl->pv, vg->fid);
169
169
}
170
170
 
171
171
void del_pvl_from_vgs(struct volume_group *vg, struct pv_list *pvl)
172
172
{
 
173
        struct format_instance_ctx fic;
 
174
        struct format_instance *fid;
 
175
 
173
176
        vg->pv_count--;
174
177
        dm_list_del(&pvl->list);
175
178
        pvl->pv->vg = NULL; /* orphan */
 
179
 
 
180
        /* Use a new PV-based format instance since the PV is orphan now. */
 
181
        fic.type = FMT_INSTANCE_PV | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
 
182
        fic.context.pv_id = (const char *) &pvl->pv->id;
 
183
        fid = pvl->pv->fid->fmt->ops->create_instance(pvl->pv->fid->fmt, &fic);
 
184
 
 
185
        pv_set_fid(pvl->pv, fid);
176
186
}
177
187
 
178
188
 
181
191
 * @vg - volume group to add to
182
192
 * @pv_name - name of the pv (to be removed)
183
193
 * @pv - physical volume to add to volume group
 
194
 * @pp - physical volume creation params (OPTIONAL)
184
195
 *
185
196
 * Returns:
186
197
 *  0 - failure
188
199
 * FIXME: remove pv_name - obtain safely from pv
189
200
 */
190
201
int add_pv_to_vg(struct volume_group *vg, const char *pv_name,
191
 
                 struct physical_volume *pv)
 
202
                 struct physical_volume *pv, struct pvcreate_params *pp)
192
203
{
 
204
        struct pv_to_create *pvc;
193
205
        struct pv_list *pvl;
194
206
        struct format_instance *fid = vg->fid;
195
207
        struct dm_pool *mem = vg->vgmem;
196
208
        char uuid[64] __attribute__((aligned(8)));
197
 
        struct dm_list *mdas;
198
209
 
199
210
        log_verbose("Adding physical volume '%s' to volume group '%s'",
200
211
                    pv_name, vg->name);
238
249
         */
239
250
        pv->pe_alloc_count = 0;
240
251
 
241
 
        /*
242
 
         * FIXME: this does not work entirely correctly in the case where a PV
243
 
         * has 2 mdas and only one is ignored; ideally all non-ignored mdas
244
 
         * should be placed on metadata_areas list and ignored on the
245
 
         * metadata_areas_ignored list; however this requires another
246
 
         * fairly complex refactoring to remove the 'mdas' parameter from both
247
 
         * pv_setup and pv_write.  For now, we only put ignored mdas on the
248
 
         * metadata_areas_ignored list if all mdas in the PV are ignored;
249
 
         * otherwise, we use the non-ignored list.
250
 
         */
251
 
        if (!pv_mda_used_count(pv))
252
 
                mdas = &fid->metadata_areas_ignored;
253
 
        else
254
 
                mdas = &fid->metadata_areas_in_use;
255
 
 
256
 
        if (!fid->fmt->ops->pv_setup(fid->fmt, UINT64_C(0), 0,
257
 
                                     vg->extent_size, 0, 0, 0UL, UINT64_C(0),
258
 
                                     0, mdas, pv, vg)) {
 
252
        if (!fid->fmt->ops->pv_setup(fid->fmt, pv, vg)) {
259
253
                log_error("Format-specific setup of physical volume '%s' "
260
254
                          "failed.", pv_name);
261
255
                return 0;
296
290
        vg->extent_count += pv->pe_count;
297
291
        vg->free_count += pv->pe_count;
298
292
 
 
293
        if (pv->status & UNLABELLED_PV) {
 
294
                if (!(pvc = dm_pool_zalloc(mem, sizeof(*pvc)))) {
 
295
                        log_error("pv_to_create allocation for '%s' failed", pv_name);
 
296
                        return 0;
 
297
                }
 
298
                pvc->pv = pv;
 
299
                pvc->pp = pp;
 
300
                dm_list_add(&vg->pvs_to_create, &pvc->list);
 
301
        }
 
302
 
299
303
        return 1;
300
304
}
301
305
 
305
309
{
306
310
        memcpy(pv_to, pv_from, sizeof(*pv_to));
307
311
 
 
312
        /* We must use pv_set_fid here to update the reference counter! */
 
313
        pv_to->fid = NULL;
 
314
        pv_set_fid(pv_to, pv_from->fid);
 
315
 
308
316
        if (!(pv_to->vg_name = dm_pool_strdup(pvmem, pv_from->vg_name)))
309
317
                return_0;
310
318
 
603
611
                }
604
612
 
605
613
                /* FIXME Write to same sector label was read from */
606
 
                if (!pv_write(vg->cmd, pv, NULL, INT64_C(-1))) {
 
614
                if (!pv_write(vg->cmd, pv, 0)) {
607
615
                        log_error("Failed to remove physical volume \"%s\""
608
616
                                  " from volume group \"%s\"",
609
617
                                  pv_dev_name(pv), vg->name);
643
651
                          "physical volume", pv_name);
644
652
                return 0;
645
653
        } else if (!pv && pp) {
646
 
                pv = pvcreate_single(vg->cmd, pv_name, pp);
 
654
                pv = pvcreate_single(vg->cmd, pv_name, pp, 0);
647
655
                if (!pv)
648
656
                        return 0;
649
657
        }
650
 
        if (!add_pv_to_vg(vg, pv_name, pv))
 
658
        if (!add_pv_to_vg(vg, pv_name, pv, pp)) {
 
659
                free_pv_fid(pv);
651
660
                return 0;
 
661
        }
652
662
        return 1;
653
663
}
654
664
 
662
672
 * - pp: parameters to pass to implicit pvcreate; if NULL, do not pvcreate
663
673
 *
664
674
 */
665
 
int vg_extend(struct volume_group *vg, int pv_count, char **pv_names,
 
675
int vg_extend(struct volume_group *vg, int pv_count, const char *const *pv_names,
666
676
              struct pvcreate_params *pp)
667
677
{
668
678
        int i;
 
679
        char *pv_name;
669
680
 
670
681
        if (_vg_bad_status_bits(vg, RESIZEABLE_VG))
671
682
                return 0;
672
683
 
673
684
        /* attach each pv */
674
685
        for (i = 0; i < pv_count; i++) {
675
 
                unescape_colons_and_at_signs(pv_names[i], NULL, NULL);
676
 
                if (!vg_extend_single_pv(vg, pv_names[i], pp))
677
 
                        goto bad;
 
686
                if (!(pv_name = dm_strdup(pv_names[i]))) {
 
687
                        log_error("Failed to duplicate pv name %s.", pv_names[i]);
 
688
                        return 0;
 
689
                }
 
690
                unescape_colons_and_at_signs(pv_name, NULL, NULL);
 
691
                if (!vg_extend_single_pv(vg, pv_name, pp)) {
 
692
                        log_error("Unable to add physical volume '%s' to "
 
693
                                  "volume group '%s'.", pv_name, vg->name);
 
694
                        dm_free(pv_name);
 
695
                        return 0;
 
696
                }
 
697
                dm_free(pv_name);
678
698
        }
679
699
 
680
700
/* FIXME Decide whether to initialise and add new mdahs to format instance */
681
701
 
682
702
        return 1;
683
 
 
684
 
      bad:
685
 
        log_error("Unable to add physical volume '%s' to "
686
 
                  "volume group '%s'.", pv_names[i], vg->name);
687
 
        return 0;
688
703
}
689
704
 
690
705
/* FIXME: use this inside vgreduce_single? */
691
 
int vg_reduce(struct volume_group *vg, char *pv_name)
 
706
int vg_reduce(struct volume_group *vg, const char *pv_name)
692
707
{
693
708
        struct physical_volume *pv;
694
709
        struct pv_list *pvl;
848
863
 * possible failure code or zero for success.
849
864
 */
850
865
static struct volume_group *_vg_make_handle(struct cmd_context *cmd,
851
 
                             struct volume_group *vg,
852
 
                             uint32_t failure)
 
866
                                            struct volume_group *vg,
 
867
                                            uint32_t failure)
853
868
{
854
 
        struct dm_pool *vgmem;
855
 
 
856
 
        if (!vg) {
857
 
                if (!(vgmem = dm_pool_create("lvm2 vg_handle", VG_MEMPOOL_CHUNK)) ||
858
 
                    !(vg = dm_pool_zalloc(vgmem, sizeof(*vg)))) {
859
 
                        log_error("Error allocating vg handle.");
860
 
                        if (vgmem)
861
 
                                dm_pool_destroy(vgmem);
862
 
                        return_NULL;
863
 
                }
864
 
                vg->vgmem = vgmem;
865
 
        }
866
 
 
867
 
        vg->read_status = failure;
868
 
 
869
 
        return (struct volume_group *)vg;
 
869
        if (!vg && !(vg = alloc_vg("vg_make_handle", cmd, NULL)))
 
870
                return_NULL;
 
871
 
 
872
        if (vg->read_status != failure)
 
873
                vg->read_status = failure;
 
874
 
 
875
        return vg;
870
876
}
871
877
 
872
878
int lv_has_unknown_segments(const struct logical_volume *lv)
901
907
struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name)
902
908
{
903
909
        struct volume_group *vg;
 
910
        struct format_instance_ctx fic;
 
911
        struct format_instance *fid;
904
912
        int consistent = 0;
905
 
        struct dm_pool *mem;
906
913
        uint32_t rc;
907
914
 
908
915
        if (!validate_name(vg_name)) {
925
932
                return _vg_make_handle(cmd, NULL, FAILED_EXIST);
926
933
        }
927
934
 
928
 
        if (!(mem = dm_pool_create("lvm2 vg_create", VG_MEMPOOL_CHUNK)))
929
 
                goto_bad;
 
935
        /* Strip dev_dir if present */
 
936
        vg_name = strip_dir(vg_name, cmd->dev_dir);
930
937
 
931
 
        if (!(vg = dm_pool_zalloc(mem, sizeof(*vg))))
 
938
        if (!(vg = alloc_vg("vg_create", cmd, vg_name)))
932
939
                goto_bad;
933
940
 
934
941
        if (!id_create(&vg->id)) {
937
944
                goto bad;
938
945
        }
939
946
 
940
 
        /* Strip dev_dir if present */
941
 
        vg_name = strip_dir(vg_name, cmd->dev_dir);
942
 
 
943
 
        vg->vgmem = mem;
944
 
        vg->cmd = cmd;
945
 
 
946
 
        if (!(vg->name = dm_pool_strdup(mem, vg_name)))
947
 
                goto_bad;
948
 
 
949
 
        vg->seqno = 0;
950
 
 
951
947
        vg->status = (RESIZEABLE_VG | LVM_READ | LVM_WRITE);
952
 
        if (!(vg->system_id = dm_pool_alloc(mem, NAME_LEN)))
 
948
        if (!(vg->system_id = dm_pool_zalloc(vg->vgmem, NAME_LEN + 1)))
953
949
                goto_bad;
954
950
 
955
951
        *vg->system_id = '\0';
965
961
        vg->mda_copies = DEFAULT_VGMETADATACOPIES;
966
962
 
967
963
        vg->pv_count = 0;
968
 
        dm_list_init(&vg->pvs);
969
 
 
970
 
        dm_list_init(&vg->lvs);
971
 
 
972
 
        dm_list_init(&vg->tags);
973
 
 
974
 
        /* initialize removed_pvs list */
975
 
        dm_list_init(&vg->removed_pvs);
976
 
 
977
 
        if (!(vg->fid = cmd->fmt->ops->create_instance(cmd->fmt, vg_name,
978
 
                                                       NULL, NULL))) {
 
964
 
 
965
        fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
 
966
        fic.context.vg_ref.vg_name = vg_name;
 
967
        fic.context.vg_ref.vg_id = NULL;
 
968
        if (!(fid = cmd->fmt->ops->create_instance(cmd->fmt, &fic))) {
979
969
                log_error("Failed to create format instance");
980
970
                goto bad;
981
971
        }
 
972
        vg_set_fid(vg, fid);
982
973
 
983
974
        if (vg->fid->fmt->ops->vg_setup &&
984
975
            !vg->fid->fmt->ops->vg_setup(vg->fid, vg)) {
1086
1077
                }
1087
1078
        }
1088
1079
 
 
1080
        if (!dm_pool_grow_object(mem, "\0", 1)) {
 
1081
                log_error("Failed to finish list of random bits.");
 
1082
                dm_pool_free(mem, bs);
 
1083
                return NULL;
 
1084
        }
 
1085
 
1089
1086
        log_debug("Selected %" PRIu32 " random bits from %" PRIu32 ": %s", num_set_bits, num_bits, (char *) dm_pool_end_object(mem));
1090
1087
 
1091
1088
        return bs;
1328
1325
{
1329
1326
        struct physical_volume *pv;
1330
1327
        struct device *dev;
1331
 
        struct dm_list mdas;
1332
 
 
1333
 
        dm_list_init(&mdas);
1334
1328
 
1335
1329
        /* FIXME Check partition type is LVM unless --force is given */
1336
1330
 
1337
1331
        /* Is there a pv here already? */
1338
 
        pv = pv_read(cmd, name, &mdas, NULL, 0, 0);
 
1332
        pv = pv_read(cmd, name, 0, 0);
1339
1333
 
1340
1334
        /*
1341
1335
         * If a PV has no MDAs it may appear to be an orphan until the
1343
1337
         * this means checking every VG by scanning every PV on the
1344
1338
         * system.
1345
1339
         */
1346
 
        if (pv && is_orphan(pv) && mdas_empty_or_ignored(&mdas)) {
 
1340
        if (pv && is_orphan(pv) && !dm_list_size(&pv->fid->metadata_areas_in_use)) {
 
1341
                free_pv_fid(pv);
1347
1342
                if (!scan_vgs_for_pvs(cmd, 0))
1348
1343
                        return_0;
1349
 
                pv = pv_read(cmd, name, NULL, NULL, 0, 0);
 
1344
                pv = pv_read(cmd, name, 0, 0);
1350
1345
        }
1351
1346
 
1352
1347
        /* Allow partial & exported VGs to be destroyed. */
1354
1349
        if (pv && !is_orphan(pv) && pp->force != DONT_PROMPT_OVERRIDE) {
1355
1350
                log_error("Can't initialize physical volume \"%s\" of "
1356
1351
                          "volume group \"%s\" without -ff", name, pv_vg_name(pv));
1357
 
                return 0;
 
1352
                goto bad;
1358
1353
        }
1359
1354
 
1360
1355
        /* prompt */
1361
1356
        if (pv && !is_orphan(pv) && !pp->yes &&
1362
1357
            yes_no_prompt(_really_init, name, pv_vg_name(pv)) == 'n') {
1363
1358
                log_error("%s: physical volume not initialized", name);
1364
 
                return 0;
 
1359
                goto bad;
1365
1360
        }
1366
1361
 
1367
1362
        if (sigint_caught())
1368
 
                return 0;
 
1363
                goto_bad;
1369
1364
 
1370
1365
        dev = dev_cache_get(name, cmd->filter);
1371
1366
 
1380
1375
 
1381
1376
        if (!dev) {
1382
1377
                log_error("Device %s not found (or ignored by filtering).", name);
1383
 
                return 0;
 
1378
                goto bad;
1384
1379
        }
1385
1380
 
1386
1381
        /*
1390
1385
                /* FIXME Detect whether device-mapper itself is still using it */
1391
1386
                log_error("Can't open %s exclusively.  Mounted filesystem?",
1392
1387
                          name);
1393
 
                return 0;
 
1388
                goto bad;
1394
1389
        }
1395
1390
 
1396
1391
        if (!_wipe_sb(dev, "software RAID md superblock", name, 4, pp, dev_is_md))
1397
 
                return 0;
 
1392
                goto_bad;
1398
1393
 
1399
1394
        if (!_wipe_sb(dev, "swap signature", name, 10, pp, dev_is_swap))
1400
 
                return 0;
 
1395
                goto_bad;
1401
1396
 
1402
1397
        if (!_wipe_sb(dev, "LUKS signature", name, 8, pp, dev_is_luks))
1403
 
                return 0;
 
1398
                goto_bad;
1404
1399
 
1405
1400
        if (sigint_caught())
1406
 
                return 0;
 
1401
                goto_bad;
1407
1402
 
1408
1403
        if (pv && !is_orphan(pv) && pp->force) {
1409
1404
                log_warn("WARNING: Forcing physical volume creation on "
1413
1408
                          !is_orphan(pv) ? "\"" : "");
1414
1409
        }
1415
1410
 
 
1411
        free_pv_fid(pv);
1416
1412
        return 1;
 
1413
 
 
1414
bad:
 
1415
        free_pv_fid(pv);
 
1416
        return 0;
1417
1417
}
1418
1418
 
1419
1419
void pvcreate_params_set_defaults(struct pvcreate_params *pp)
1436
1436
        pp->metadataignore = DEFAULT_PVMETADATAIGNORE;
1437
1437
}
1438
1438
 
 
1439
 
 
1440
static int _pvcreate_write(struct cmd_context *cmd, struct pv_to_create *pvc)
 
1441
{
 
1442
        int zero = pvc->pp->zero;
 
1443
        struct physical_volume *pv = pvc->pv;
 
1444
        struct device *dev = pv->dev;
 
1445
        const char *pv_name = dev_name(dev);
 
1446
 
 
1447
        /* Wipe existing label first */
 
1448
        if (!label_remove(pv_dev(pv))) {
 
1449
                log_error("Failed to wipe existing label on %s", pv_name);
 
1450
                return 0;
 
1451
        }
 
1452
 
 
1453
        if (zero) {
 
1454
                log_verbose("Zeroing start of device %s", pv_name);
 
1455
                if (!dev_open_quiet(dev)) {
 
1456
                        log_error("%s not opened: device not zeroed", pv_name);
 
1457
                        return 0;
 
1458
                }
 
1459
 
 
1460
                if (!dev_set(dev, UINT64_C(0), (size_t) 2048, 0)) {
 
1461
                        log_error("%s not wiped: aborting", pv_name);
 
1462
                        dev_close(dev);
 
1463
                        return 0;
 
1464
                }
 
1465
                dev_close(dev);
 
1466
        }
 
1467
 
 
1468
        log_error("Writing physical volume data to disk \"%s\"",
 
1469
                         pv_name);
 
1470
 
 
1471
        if (!(pv_write(cmd, pv, 1))) {
 
1472
                log_error("Failed to write physical volume \"%s\"", pv_name);
 
1473
                return 0;
 
1474
        }
 
1475
 
 
1476
        log_print("Physical volume \"%s\" successfully created", pv_name);
 
1477
        return 1;
 
1478
}
 
1479
 
1439
1480
/*
1440
1481
 * pvcreate_single() - initialize a device with PV label and metadata area
1441
1482
 *
1449
1490
 */
1450
1491
struct physical_volume * pvcreate_single(struct cmd_context *cmd,
1451
1492
                                         const char *pv_name,
1452
 
                                         struct pvcreate_params *pp)
 
1493
                                         struct pvcreate_params *pp,
 
1494
                                         int write_now)
1453
1495
{
1454
 
        struct physical_volume *pv;
 
1496
        struct physical_volume *pv = NULL;
1455
1497
        struct device *dev;
1456
1498
        struct dm_list mdas;
1457
1499
        struct pvcreate_params default_pp;
1462
1504
                pp = &default_pp;
1463
1505
 
1464
1506
        if (pp->idp) {
1465
 
                if ((dev = device_from_pvid(cmd, pp->idp, NULL)) &&
 
1507
                if ((dev = device_from_pvid(cmd, pp->idp, NULL, NULL)) &&
1466
1508
                    (dev != dev_cache_get(pv_name, cmd->filter))) {
1467
1509
                        if (!id_write_format((const struct id*)&pp->idp->uuid,
1468
1510
                            buffer, sizeof(buffer)))
1469
 
                                return_NULL;
 
1511
                                goto_bad;
1470
1512
                        log_error("uuid %s already in use on \"%s\"", buffer,
1471
1513
                                  dev_name(dev));
1472
 
                        return NULL;
 
1514
                        goto bad;;
1473
1515
                }
1474
1516
        }
1475
1517
 
1476
1518
        if (!pvcreate_check(cmd, pv_name, pp))
1477
 
                goto error;
 
1519
                goto_bad;
1478
1520
 
1479
1521
        if (sigint_caught())
1480
 
                goto error;
 
1522
                goto_bad;
1481
1523
 
1482
1524
        if (!(dev = dev_cache_get(pv_name, cmd->filter))) {
1483
1525
                log_error("%s: Couldn't find device.  Check your filters?",
1484
1526
                          pv_name);
1485
 
                goto error;
 
1527
                goto bad;
1486
1528
        }
1487
1529
 
1488
1530
        dm_list_init(&mdas);
 
1531
 
1489
1532
        if (!(pv = pv_create(cmd, dev, pp->idp, pp->size,
1490
1533
                             pp->data_alignment, pp->data_alignment_offset,
1491
 
                             pp->pe_start, pp->extent_count, pp->extent_size,
1492
 
                             pp->pvmetadatacopies, pp->pvmetadatasize,
1493
 
                             pp->metadataignore, &mdas))) {
 
1534
                             pp->pe_start ? pp->pe_start : PV_PE_START_CALC,
 
1535
                             pp->extent_count, pp->extent_size,
 
1536
                             pp->labelsector, pp->pvmetadatacopies,
 
1537
                             pp->pvmetadatasize, pp->metadataignore))) {
1494
1538
                log_error("Failed to setup physical volume \"%s\"", pv_name);
1495
 
                goto error;
 
1539
                goto bad;
1496
1540
        }
1497
1541
 
1498
1542
        log_verbose("Set up physical volume for \"%s\" with %" PRIu64
1499
1543
                    " available sectors", pv_name, pv_size(pv));
1500
1544
 
1501
 
        /* Wipe existing label first */
1502
 
        if (!label_remove(pv_dev(pv))) {
1503
 
                log_error("Failed to wipe existing label on %s", pv_name);
1504
 
                goto error;
1505
 
        }
1506
 
 
1507
 
        if (pp->zero) {
1508
 
                log_verbose("Zeroing start of device %s", pv_name);
1509
 
                if (!dev_open_quiet(dev)) {
1510
 
                        log_error("%s not opened: device not zeroed", pv_name);
1511
 
                        goto error;
1512
 
                }
1513
 
 
1514
 
                if (!dev_set(dev, UINT64_C(0), (size_t) 2048, 0)) {
1515
 
                        log_error("%s not wiped: aborting", pv_name);
1516
 
                        dev_close(dev);
1517
 
                        goto error;
1518
 
                }
1519
 
                dev_close(dev);
1520
 
        }
1521
 
 
1522
 
        log_very_verbose("Writing physical volume data to disk \"%s\"",
1523
 
                         pv_name);
1524
 
 
1525
 
        if (!(pv_write(cmd, pv, &mdas, pp->labelsector))) {
1526
 
                log_error("Failed to write physical volume \"%s\"", pv_name);
1527
 
                goto error;
1528
 
        }
1529
 
 
1530
 
        log_print("Physical volume \"%s\" successfully created", pv_name);
 
1545
        if (write_now) {
 
1546
                struct pv_to_create pvc;
 
1547
                pvc.pp = pp;
 
1548
                pvc.pv = pv;
 
1549
                if (!_pvcreate_write(cmd, &pvc))
 
1550
                        goto bad;
 
1551
        } else {
 
1552
                pv->status |= UNLABELLED_PV;
 
1553
        }
1531
1554
 
1532
1555
        return pv;
1533
1556
 
1534
 
      error:
 
1557
bad:
 
1558
        free_pv_fid(pv);
1535
1559
        return NULL;
1536
1560
}
1537
1561
 
1538
 
static void _free_pv(struct dm_pool *mem, struct physical_volume *pv)
1539
 
{
1540
 
        dm_pool_free(mem, pv);
1541
 
}
1542
 
 
1543
1562
static struct physical_volume *_alloc_pv(struct dm_pool *mem, struct device *dev)
1544
1563
{
1545
1564
        struct physical_volume *pv = dm_pool_zalloc(mem, sizeof(*pv));
1547
1566
        if (!pv)
1548
1567
                return_NULL;
1549
1568
 
 
1569
        pv_set_fid(pv, NULL);
1550
1570
        pv->pe_size = 0;
1551
1571
        pv->pe_start = 0;
1552
1572
        pv->pe_count = 0;
1594
1614
                                  uint64_t pe_start,
1595
1615
                                  uint32_t existing_extent_count,
1596
1616
                                  uint32_t existing_extent_size,
1597
 
                                  int pvmetadatacopies, uint64_t pvmetadatasize,
1598
 
                                  unsigned metadataignore, struct dm_list *mdas)
 
1617
                                  uint64_t label_sector,
 
1618
                                  int pvmetadatacopies,
 
1619
                                  uint64_t pvmetadatasize,
 
1620
                                  unsigned metadataignore)
1599
1621
{
1600
1622
        const struct format_type *fmt = cmd->fmt;
 
1623
        struct format_instance_ctx fic;
 
1624
        struct format_instance *fid;
1601
1625
        struct dm_pool *mem = fmt->cmd->mem;
1602
1626
        struct physical_volume *pv = _alloc_pv(mem, dev);
 
1627
        unsigned mda_index;
1603
1628
 
1604
1629
        if (!pv)
1605
1630
                return NULL;
1626
1651
                pv->size = size;
1627
1652
        }
1628
1653
 
1629
 
        if (pv->size < PV_MIN_SIZE) {
1630
 
                log_error("%s: Size must exceed minimum of %ld sectors.",
1631
 
                          pv_dev_name(pv), PV_MIN_SIZE);
 
1654
        if (pv->size < pv_min_size()) {
 
1655
                log_error("%s: Size must exceed minimum of %" PRIu64 " sectors.",
 
1656
                          pv_dev_name(pv), pv_min_size());
1632
1657
                goto bad;
1633
1658
        }
1634
1659
 
1638
1663
                goto bad;
1639
1664
        }
1640
1665
 
 
1666
        fic.type = FMT_INSTANCE_PV;
 
1667
        fic.context.pv_id = (const char *) &pv->id;
 
1668
        if (!(fid = fmt->ops->create_instance(fmt, &fic))) {
 
1669
                log_error("Couldn't create format instance for PV %s.", pv_dev_name(pv));
 
1670
                goto bad;
 
1671
        }
 
1672
        pv_set_fid(pv, fid);
 
1673
 
1641
1674
        pv->fmt = fmt;
1642
1675
        pv->vg_name = fmt->orphan_vg_name;
1643
1676
 
1644
 
        if (!fmt->ops->pv_setup(fmt, pe_start, existing_extent_count,
1645
 
                                existing_extent_size, data_alignment,
1646
 
                                data_alignment_offset,
1647
 
                                pvmetadatacopies, pvmetadatasize,
1648
 
                                metadataignore, mdas, pv, NULL)) {
1649
 
                log_error("%s: Format-specific setup of physical volume "
1650
 
                          "failed.", pv_dev_name(pv));
 
1677
        if (!fmt->ops->pv_initialise(fmt, label_sector, pe_start,
 
1678
                                     existing_extent_count, existing_extent_size,
 
1679
                                     data_alignment, data_alignment_offset, pv)) {
 
1680
                log_error("Format-specific initialisation of physical "
 
1681
                          "volume %s failed.", pv_dev_name(pv));
1651
1682
                goto bad;
1652
1683
        }
1653
1684
 
 
1685
        for (mda_index = 0; mda_index < pvmetadatacopies; mda_index++) {
 
1686
                if (pv->fmt->ops->pv_add_metadata_area &&
 
1687
                    !pv->fmt->ops->pv_add_metadata_area(pv->fmt, pv,
 
1688
                                        pe_start != PV_PE_START_CALC,
 
1689
                                        mda_index, pvmetadatasize,
 
1690
                                        metadataignore)) {
 
1691
                        log_error("Failed to add metadata area for "
 
1692
                                  "new physical volume %s", pv_dev_name(pv));
 
1693
                        goto bad;
 
1694
                }
 
1695
        }
 
1696
 
1654
1697
        return pv;
1655
1698
 
1656
1699
      bad:
1657
 
        _free_pv(mem, pv);
 
1700
        free_pv_fid(pv);
 
1701
        dm_pool_free(mem, pv);
1658
1702
        return NULL;
1659
1703
}
1660
1704
 
1802
1846
static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd,
1803
1847
                                                const char *pv_name)
1804
1848
{
1805
 
        struct dm_list mdas;
1806
1849
        struct physical_volume *pv;
1807
1850
 
1808
 
        dm_list_init(&mdas);
1809
 
        if (!(pv = _pv_read(cmd, cmd->mem, pv_name, &mdas, NULL, 1, 0))) {
 
1851
        if (!(pv = _pv_read(cmd, cmd->mem, pv_name, NULL, 1, 0))) {
1810
1852
                log_error("Physical volume %s not found", pv_name);
1811
 
                return NULL;
 
1853
                goto bad;
1812
1854
        }
1813
1855
 
1814
 
        if (is_orphan_vg(pv->vg_name) && mdas_empty_or_ignored(&mdas)) {
 
1856
        if (is_orphan_vg(pv->vg_name) && !dm_list_size(&pv->fid->metadata_areas_in_use)) {
1815
1857
                /* If a PV has no MDAs - need to search all VGs for it */
1816
1858
                if (!scan_vgs_for_pvs(cmd, 1))
1817
 
                        return_NULL;
1818
 
                if (!(pv = _pv_read(cmd, cmd->mem, pv_name, NULL, NULL, 1, 0))) {
 
1859
                        goto_bad;
 
1860
                free_pv_fid(pv);
 
1861
                if (!(pv = _pv_read(cmd, cmd->mem, pv_name, NULL, 1, 0))) {
1819
1862
                        log_error("Physical volume %s not found", pv_name);
1820
 
                        return NULL;
 
1863
                        goto bad;
1821
1864
                }
1822
1865
        }
1823
1866
 
1824
1867
        if (is_orphan_vg(pv->vg_name)) {
1825
1868
                log_error("Physical volume %s not in a volume group", pv_name);
1826
 
                return NULL;
 
1869
                goto bad;
1827
1870
        }
1828
1871
 
1829
1872
        return pv;
 
1873
 
 
1874
bad:
 
1875
        free_pv_fid(pv);
 
1876
        return NULL;
1830
1877
}
1831
1878
 
1832
1879
/* Find segment at a given logical extent in an LV */
1875
1922
{
1876
1923
        struct lv_list *lvl1, *lvl2;
1877
1924
        struct pv_list *pvl;
1878
 
        char *name1, *name2;
 
1925
        const char *name1, *name2;
1879
1926
 
1880
1927
        if (lvs_in_vg_activated(vg_from)) {
1881
1928
                log_error("Logical volumes in \"%s\" must be inactive",
1969
2016
                               int (*fn)(struct logical_volume *lv, void *data),
1970
2017
                               void *data);
1971
2018
 
1972
 
static int _lv_postorder_level(struct logical_volume *lv, void *data)
1973
 
{
1974
 
        struct _lv_postorder_baton *baton = data;
1975
 
        if (lv->status & POSTORDER_OPEN_FLAG)
1976
 
                return 1; // a data structure loop has closed...
1977
 
        lv->status |= POSTORDER_OPEN_FLAG;
1978
 
        int r =_lv_postorder_visit(lv, baton->fn, baton->data);
1979
 
        lv->status &= ~POSTORDER_OPEN_FLAG;
1980
 
        lv->status |= POSTORDER_FLAG;
1981
 
        return r;
1982
 
};
1983
 
 
1984
2019
static int _lv_each_dependency(struct logical_volume *lv,
1985
2020
                               int (*fn)(struct logical_volume *lv, void *data),
1986
2021
                               void *data)
1987
2022
{
1988
 
        int i, s;
 
2023
        unsigned i, s;
1989
2024
        struct lv_segment *lvseg;
1990
2025
 
1991
2026
        struct logical_volume *deps[] = {
2022
2057
        return 1;
2023
2058
}
2024
2059
 
 
2060
static int _lv_postorder_level(struct logical_volume *lv, void *data)
 
2061
{
 
2062
        struct _lv_postorder_baton *baton = data;
 
2063
        return _lv_postorder_visit(lv, baton->fn, baton->data);
 
2064
};
 
2065
 
2025
2066
static int _lv_postorder_visit(struct logical_volume *lv,
2026
2067
                               int (*fn)(struct logical_volume *lv, void *data),
2027
2068
                               void *data)
2031
2072
 
2032
2073
        if (lv->status & POSTORDER_FLAG)
2033
2074
                return 1;
 
2075
        if (lv->status & POSTORDER_OPEN_FLAG)
 
2076
                return 1; // a data structure loop has closed...
 
2077
        lv->status |= POSTORDER_OPEN_FLAG;
2034
2078
 
2035
2079
        baton.fn = fn;
2036
2080
        baton.data = data;
2037
2081
        r = _lv_each_dependency(lv, _lv_postorder_level, &baton);
 
2082
 
2038
2083
        if (r)
2039
2084
                r = fn(lv, data);
2040
2085
 
 
2086
        lv->status &= ~POSTORDER_OPEN_FLAG;
 
2087
        lv->status |= POSTORDER_FLAG;
 
2088
 
2041
2089
        return r;
2042
2090
}
2043
2091
 
2058
2106
        return r;
2059
2107
}
2060
2108
 
 
2109
/*
 
2110
 * Calls _lv_postorder() on each LV from VG. Avoids duplicate transitivity visits.
 
2111
 * Clears with _lv_postorder_cleanup() when all LVs were visited by postorder.
 
2112
 */
 
2113
static int _lv_postorder_vg(struct volume_group *vg,
 
2114
                            int (*fn)(struct logical_volume *lv, void *data),
 
2115
                            void *data)
 
2116
{
 
2117
        struct lv_list *lvl;
 
2118
        int r = 1;
 
2119
 
 
2120
        dm_list_iterate_items(lvl, &vg->lvs)
 
2121
                if (!_lv_postorder_visit(lvl->lv, fn, data)) {
 
2122
                        stack;
 
2123
                        r = 0;
 
2124
                }
 
2125
 
 
2126
        dm_list_iterate_items(lvl, &vg->lvs)
 
2127
                _lv_postorder_cleanup(lvl->lv, 0);
 
2128
 
 
2129
        return r;
 
2130
}
 
2131
 
2061
2132
struct _lv_mark_if_partial_baton {
2062
2133
        int partial;
2063
2134
};
2073
2144
 
2074
2145
static int _lv_mark_if_partial_single(struct logical_volume *lv, void *data)
2075
2146
{
2076
 
        int s;
 
2147
        unsigned s;
2077
2148
        struct _lv_mark_if_partial_baton baton;
2078
2149
        struct lv_segment *lvseg;
2079
2150
 
2095
2166
        return 1;
2096
2167
}
2097
2168
 
2098
 
static int _lv_mark_if_partial(struct logical_volume *lv)
2099
 
{
2100
 
        return _lv_postorder(lv, _lv_mark_if_partial_single, NULL);
2101
 
}
2102
 
 
2103
2169
/*
2104
2170
 * Mark LVs with missing PVs using PARTIAL_LV status flag. The flag is
2105
2171
 * propagated transitively, so LVs referencing other LVs are marked
2106
2172
 * partial as well, if any of their referenced LVs are marked partial.
2107
2173
 */
2108
 
int vg_mark_partial_lvs(struct volume_group *vg)
 
2174
int vg_mark_partial_lvs(struct volume_group *vg, int clear)
2109
2175
{
2110
 
        struct logical_volume *lv;
2111
2176
        struct lv_list *lvl;
2112
2177
 
2113
 
        dm_list_iterate_items(lvl, &vg->lvs) {
2114
 
                lv = lvl->lv;
2115
 
                if (!_lv_mark_if_partial(lv))
2116
 
                        return_0;
2117
 
        }
 
2178
        if (clear)
 
2179
                dm_list_iterate_items(lvl, &vg->lvs)
 
2180
                        lvl->lv->status &= ~PARTIAL_LV;
 
2181
 
 
2182
        if (!_lv_postorder_vg(vg, _lv_mark_if_partial_single, NULL))
 
2183
                return_0;
2118
2184
        return 1;
2119
2185
}
2120
2186
 
2154
2220
        }
2155
2221
}
2156
2222
 
 
2223
struct validate_hash {
 
2224
        struct dm_hash_table *lvname;
 
2225
        struct dm_hash_table *lvid;
 
2226
        struct dm_hash_table *pvid;
 
2227
};
 
2228
 
2157
2229
/*
2158
2230
 * Check that an LV and all its PV references are correctly listed in vg->lvs
2159
2231
 * and vg->pvs, respectively. This only looks at a single LV, but *not* at the
2163
2235
static int _lv_validate_references_single(struct logical_volume *lv, void *data)
2164
2236
{
2165
2237
        struct volume_group *vg = lv->vg;
 
2238
        struct validate_hash *vhash = data;
2166
2239
        struct lv_segment *lvseg;
2167
 
        struct pv_list *pvl;
2168
 
        struct lv_list *lvl;
2169
 
        int s;
 
2240
        struct physical_volume *pv;
 
2241
        unsigned s;
2170
2242
        int r = 1;
2171
 
        int ok = 0;
2172
 
 
2173
 
        dm_list_iterate_items(lvl, &vg->lvs) {
2174
 
                if (lvl->lv == lv) {
2175
 
                        ok = 1;
2176
 
                        break;
2177
 
                }
2178
 
        }
2179
 
 
2180
 
        if (!ok) {
 
2243
 
 
2244
        if (lv != dm_hash_lookup_binary(vhash->lvid, &lv->lvid.id[1],
 
2245
                                        sizeof(lv->lvid.id[1]))) {
2181
2246
                log_error(INTERNAL_ERROR
2182
2247
                          "Referenced LV %s not listed in VG %s.",
2183
2248
                          lv->name, vg->name);
2186
2251
 
2187
2252
        dm_list_iterate_items(lvseg, &lv->segments) {
2188
2253
                for (s = 0; s < lvseg->area_count; ++s) {
2189
 
                        if (seg_type(lvseg, s) == AREA_PV) {
2190
 
                                ok = 0;
2191
 
                                /* look up the reference in vg->pvs */
2192
 
                                dm_list_iterate_items(pvl, &vg->pvs) {
2193
 
                                        if (pvl->pv == seg_pv(lvseg, s)) {
2194
 
                                                ok = 1;
2195
 
                                                break;
2196
 
                                        }
2197
 
                                }
2198
 
 
2199
 
                                if (!ok) {
2200
 
                                        log_error(INTERNAL_ERROR
2201
 
                                                  "Referenced PV %s not listed in VG %s.",
2202
 
                                                  pv_dev_name(seg_pv(lvseg, s)), vg->name);
2203
 
                                        r = 0;
2204
 
                                }
 
2254
                        if (seg_type(lvseg, s) != AREA_PV)
 
2255
                                continue;
 
2256
                        pv = seg_pv(lvseg, s);
 
2257
                        /* look up the reference in vg->pvs */
 
2258
                        if (pv != dm_hash_lookup_binary(vhash->pvid, &pv->id,
 
2259
                                                        sizeof(pv->id))) {
 
2260
                                log_error(INTERNAL_ERROR
 
2261
                                          "Referenced PV %s not listed in VG %s.",
 
2262
                                          pv_dev_name(pv), vg->name);
 
2263
                                r = 0;
2205
2264
                        }
2206
2265
                }
2207
2266
        }
2211
2270
 
2212
2271
int vg_validate(struct volume_group *vg)
2213
2272
{
2214
 
        struct pv_list *pvl, *pvl2;
2215
 
        struct lv_list *lvl, *lvl2;
 
2273
        struct pv_list *pvl;
 
2274
        struct lv_list *lvl;
2216
2275
        struct lv_segment *seg;
2217
2276
        char uuid[64] __attribute__((aligned(8)));
2218
2277
        int r = 1;
2219
2278
        uint32_t hidden_lv_count = 0, lv_count = 0, lv_visible_count = 0;
2220
2279
        uint32_t pv_count = 0;
2221
2280
        uint32_t num_snapshots = 0;
2222
 
        uint32_t loop_counter1, loop_counter2;
 
2281
        struct validate_hash vhash = { NULL };
2223
2282
 
2224
2283
        if (vg->alloc == ALLOC_CLING_BY_TAGS) {
2225
2284
                log_error(INTERNAL_ERROR "VG %s allocation policy set to invalid cling_by_tags.",
2228
2287
        }
2229
2288
 
2230
2289
        /* FIXME Also check there's no data/metadata overlap */
 
2290
        if (!(vhash.pvid = dm_hash_create(vg->pv_count))) {
 
2291
                log_error("Failed to allocate pvid hash.");
 
2292
                return 0;
 
2293
        }
 
2294
 
2231
2295
        dm_list_iterate_items(pvl, &vg->pvs) {
2232
2296
                if (++pv_count > vg->pv_count) {
2233
2297
                        log_error(INTERNAL_ERROR "PV list corruption detected in VG %s.", vg->name);
2234
2298
                        /* FIXME Dump list structure? */
2235
2299
                        r = 0;
2236
2300
                }
 
2301
 
2237
2302
                if (pvl->pv->vg != vg) {
2238
2303
                        log_error(INTERNAL_ERROR "VG %s PV list entry points "
2239
 
                                  "to different VG %s", vg->name,
 
2304
                                  "to different VG %s.", vg->name,
2240
2305
                                  pvl->pv->vg ? pvl->pv->vg->name : "NULL");
2241
2306
                        r = 0;
2242
2307
                }
2243
 
        }
2244
 
 
2245
 
        loop_counter1 = loop_counter2 = 0;
2246
 
        /* FIXME Use temp hash table instead? */
2247
 
        dm_list_iterate_items(pvl, &vg->pvs) {
2248
 
                if (++loop_counter1 > pv_count)
2249
 
                        break;
2250
 
                dm_list_iterate_items(pvl2, &vg->pvs) {
2251
 
                        if (++loop_counter2 > pv_count)
2252
 
                                break;
2253
 
                        if (pvl == pvl2)
2254
 
                                break;
2255
 
                        if (id_equal(&pvl->pv->id,
2256
 
                                     &pvl2->pv->id)) {
2257
 
                                if (!id_write_format(&pvl->pv->id, uuid,
2258
 
                                                     sizeof(uuid)))
2259
 
                                         stack;
2260
 
                                log_error(INTERNAL_ERROR "Duplicate PV id "
2261
 
                                          "%s detected for %s in %s.",
2262
 
                                          uuid, pv_dev_name(pvl->pv),
2263
 
                                          vg->name);
2264
 
                                r = 0;
2265
 
                        }
2266
 
                }
2267
2308
 
2268
2309
                if (strcmp(pvl->pv->vg_name, vg->name)) {
2269
2310
                        log_error(INTERNAL_ERROR "VG name for PV %s is corrupted.",
2270
2311
                                  pv_dev_name(pvl->pv));
2271
2312
                        r = 0;
2272
2313
                }
 
2314
 
 
2315
                if (dm_hash_lookup_binary(vhash.pvid, &pvl->pv->id,
 
2316
                                          sizeof(pvl->pv->id))) {
 
2317
                        if (!id_write_format(&pvl->pv->id, uuid,
 
2318
                                             sizeof(uuid)))
 
2319
                                stack;
 
2320
                        log_error(INTERNAL_ERROR "Duplicate PV id "
 
2321
                                  "%s detected for %s in %s.",
 
2322
                                  uuid, pv_dev_name(pvl->pv),
 
2323
                                  vg->name);
 
2324
                        r = 0;
 
2325
                }
 
2326
 
 
2327
                if (!dm_hash_insert_binary(vhash.pvid, &pvl->pv->id,
 
2328
                                           sizeof(pvl->pv->id), pvl->pv)) {
 
2329
                        log_error("Failed to hash pvid.");
 
2330
                        r = 0;
 
2331
                        break;
 
2332
                }
2273
2333
        }
2274
2334
 
 
2335
 
2275
2336
        if (!check_pv_segments(vg)) {
2276
2337
                log_error(INTERNAL_ERROR "PV segments corrupted in %s.",
2277
2338
                          vg->name);
2337
2398
 
2338
2399
        /* Avoid endless loop if lv->segments list is corrupt */
2339
2400
        if (!r)
2340
 
                return r;
2341
 
 
2342
 
        loop_counter1 = loop_counter2 = 0;
2343
 
        /* FIXME Use temp hash table instead? */
 
2401
                goto out;
 
2402
 
 
2403
        if (!(vhash.lvname = dm_hash_create(lv_count))) {
 
2404
                log_error("Failed to allocate lv_name hash");
 
2405
                r = 0;
 
2406
                goto out;
 
2407
        }
 
2408
 
 
2409
        if (!(vhash.lvid = dm_hash_create(lv_count))) {
 
2410
                log_error("Failed to allocate uuid hash");
 
2411
                r = 0;
 
2412
                goto out;
 
2413
        }
 
2414
 
2344
2415
        dm_list_iterate_items(lvl, &vg->lvs) {
2345
 
                if (++loop_counter1 > lv_count)
2346
 
                        break;
2347
 
                dm_list_iterate_items(lvl2, &vg->lvs) {
2348
 
                        if (++loop_counter2 > lv_count)
2349
 
                                break;
2350
 
                        if (lvl == lvl2)
2351
 
                                break;
2352
 
                        if (!strcmp(lvl->lv->name, lvl2->lv->name)) {
2353
 
                                log_error(INTERNAL_ERROR "Duplicate LV name "
2354
 
                                          "%s detected in %s.", lvl->lv->name,
2355
 
                                          vg->name);
2356
 
                                r = 0;
2357
 
                        }
2358
 
                        if (id_equal(&lvl->lv->lvid.id[1],
2359
 
                                     &lvl2->lv->lvid.id[1])) {
2360
 
                                if (!id_write_format(&lvl->lv->lvid.id[1], uuid,
2361
 
                                                     sizeof(uuid)))
2362
 
                                         stack;
2363
 
                                log_error(INTERNAL_ERROR "Duplicate LV id "
2364
 
                                          "%s detected for %s and %s in %s.",
2365
 
                                          uuid, lvl->lv->name, lvl2->lv->name,
2366
 
                                          vg->name);
2367
 
                                r = 0;
2368
 
                        }
 
2416
                if (dm_hash_lookup(vhash.lvname, lvl->lv->name)) {
 
2417
                        log_error(INTERNAL_ERROR
 
2418
                                  "Duplicate LV name %s detected in %s.",
 
2419
                                  lvl->lv->name, vg->name);
 
2420
                        r = 0;
 
2421
                }
 
2422
 
 
2423
                if (dm_hash_lookup_binary(vhash.lvid, &lvl->lv->lvid.id[1],
 
2424
                                          sizeof(lvl->lv->lvid.id[1]))) {
 
2425
                        if (!id_write_format(&lvl->lv->lvid.id[1], uuid,
 
2426
                                             sizeof(uuid)))
 
2427
                                stack;
 
2428
                        log_error(INTERNAL_ERROR "Duplicate LV id "
 
2429
                                  "%s detected for %s in %s.",
 
2430
                                  uuid, lvl->lv->name, vg->name);
 
2431
                        r = 0;
2369
2432
                }
2370
2433
 
2371
2434
                if (!check_lv_segments(lvl->lv, 1)) {
2373
2436
                                  lvl->lv->name);
2374
2437
                        r = 0;
2375
2438
                }
 
2439
 
 
2440
                if (!dm_hash_insert(vhash.lvname, lvl->lv->name, lvl)) {
 
2441
                        log_error("Failed to hash lvname.");
 
2442
                        r = 0;
 
2443
                        break;
 
2444
                }
 
2445
 
 
2446
                if (!dm_hash_insert_binary(vhash.lvid, &lvl->lv->lvid.id[1],
 
2447
                                           sizeof(lvl->lv->lvid.id[1]), lvl->lv)) {
 
2448
                        log_error("Failed to hash lvid.");
 
2449
                        r = 0;
 
2450
                        break;
 
2451
                }
2376
2452
        }
2377
2453
 
2378
 
        dm_list_iterate_items(lvl, &vg->lvs) {
2379
 
                if (!_lv_postorder(lvl->lv, _lv_validate_references_single, NULL))
2380
 
                        r = 0;
 
2454
        if (!_lv_postorder_vg(vg, _lv_validate_references_single, &vhash)) {
 
2455
                stack;
 
2456
                r = 0;
2381
2457
        }
2382
2458
 
2383
2459
        dm_list_iterate_items(lvl, &vg->lvs) {
2387
2463
                        if (seg_is_mirrored(seg)) {
2388
2464
                                if (seg->area_count != 2) {
2389
2465
                                        log_error(INTERNAL_ERROR
2390
 
                                                  "Segment %d in %s is not 2-way.",
2391
 
                                                  loop_counter1, lvl->lv->name);
 
2466
                                                  "Segment in %s is not 2-way.",
 
2467
                                                  lvl->lv->name);
2392
2468
                                        r = 0;
2393
2469
                                }
2394
2470
                        } else if (seg->area_count != 1) {
2395
2471
                                log_error(INTERNAL_ERROR
2396
 
                                          "Segment %d in %s has wrong number of areas: %d.",
2397
 
                                          loop_counter1, lvl->lv->name, seg->area_count);
 
2472
                                          "Segment in %s has wrong number of areas: %d.",
 
2473
                                          lvl->lv->name, seg->area_count);
2398
2474
                                r = 0;
2399
2475
                        }
2400
2476
                }
2409
2485
 
2410
2486
        if (vg_max_lv_reached(vg))
2411
2487
                stack;
 
2488
out:
 
2489
        if (vhash.lvid)
 
2490
                dm_hash_destroy(vhash.lvid);
 
2491
        if (vhash.lvname)
 
2492
                dm_hash_destroy(vhash.lvname);
 
2493
        if (vhash.pvid)
 
2494
                dm_hash_destroy(vhash.pvid);
2412
2495
 
2413
2496
        return r;
2414
2497
}
2420
2503
int vg_write(struct volume_group *vg)
2421
2504
{
2422
2505
        struct dm_list *mdah;
 
2506
        struct pv_to_create *pv_to_create;
2423
2507
        struct metadata_area *mda;
2424
2508
 
2425
2509
        if (!vg_validate(vg))
2457
2541
 
2458
2542
        vg->seqno++;
2459
2543
 
 
2544
        dm_list_iterate_items(pv_to_create, &vg->pvs_to_create) {
 
2545
                if (!_pvcreate_write(vg->cmd, pv_to_create))
 
2546
                        return 0;
 
2547
                pv_to_create->pv->status &= ~UNLABELLED_PV;
 
2548
        }
 
2549
 
2460
2550
        /* Write to each copy of the metadata area */
2461
2551
        dm_list_iterate_items(mda, &vg->fid->metadata_areas_in_use) {
2462
2552
                if (!mda->ops->vg_write) {
2598
2688
                                             int warnings,
2599
2689
                                             const char *orphan_vgname)
2600
2690
{
 
2691
        struct format_instance_ctx fic;
 
2692
        struct format_instance *fid;
2601
2693
        struct lvmcache_vginfo *vginfo;
2602
2694
        struct lvmcache_info *info;
2603
2695
        struct pv_list *pvl;
2604
 
        struct volume_group *vg;
2605
 
        struct physical_volume *pv;
2606
 
        struct dm_pool *mem;
 
2696
        struct volume_group *vg = NULL;
 
2697
        struct physical_volume *pv = NULL;
2607
2698
 
2608
2699
        lvmcache_label_scan(cmd, 0);
2609
2700
 
2610
2701
        if (!(vginfo = vginfo_from_vgname(orphan_vgname, NULL)))
2611
2702
                return_NULL;
2612
2703
 
2613
 
        if (!(mem = dm_pool_create("vg_read orphan", VG_MEMPOOL_CHUNK)))
 
2704
        if (!(vg = alloc_vg("vg_read_orphans", cmd, orphan_vgname)))
2614
2705
                return_NULL;
2615
2706
 
2616
 
        if (!(vg = dm_pool_zalloc(mem, sizeof(*vg)))) {
2617
 
                log_error("vg allocation failed");
2618
 
                goto bad;
2619
 
        }
2620
 
        dm_list_init(&vg->pvs);
2621
 
        dm_list_init(&vg->lvs);
2622
 
        dm_list_init(&vg->tags);
2623
 
        dm_list_init(&vg->removed_pvs);
2624
 
        vg->vgmem = mem;
2625
 
        vg->cmd = cmd;
2626
 
        if (!(vg->name = dm_pool_strdup(mem, orphan_vgname))) {
2627
 
                log_error("vg name allocation failed");
2628
 
                goto bad;
2629
 
        }
2630
 
 
2631
2707
        /* create format instance with appropriate metadata area */
2632
 
        if (!(vg->fid = vginfo->fmt->ops->create_instance(vginfo->fmt,
2633
 
                                                          orphan_vgname, NULL,
2634
 
                                                          NULL))) {
 
2708
        fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_AUX_MDAS;
 
2709
        fic.context.vg_ref.vg_name = orphan_vgname;
 
2710
        fic.context.vg_ref.vg_id = NULL;
 
2711
        if (!(fid = vginfo->fmt->ops->create_instance(vginfo->fmt, &fic))) {
2635
2712
                log_error("Failed to create format instance");
2636
2713
                goto bad;
2637
2714
        }
 
2715
        vg_set_fid(vg, fid);
2638
2716
 
2639
2717
        dm_list_iterate_items(info, &vginfo->infos) {
2640
 
                if (!(pv = _pv_read(cmd, mem, dev_name(info->dev), NULL, NULL, warnings, 0))) {
 
2718
                if (!(pv = _pv_read(cmd, vg->vgmem, dev_name(info->dev),
 
2719
                                    vg->fid, warnings, 0))) {
2641
2720
                        continue;
2642
2721
                }
2643
 
                if (!(pvl = dm_pool_zalloc(mem, sizeof(*pvl)))) {
 
2722
                if (!(pvl = dm_pool_zalloc(vg->vgmem, sizeof(*pvl)))) {
2644
2723
                        log_error("pv_list allocation failed");
2645
2724
                        goto bad;
2646
2725
                }
2650
2729
 
2651
2730
        return vg;
2652
2731
bad:
2653
 
        dm_pool_destroy(mem);
 
2732
        free_pv_fid(pv);
 
2733
        free_vg(vg);
2654
2734
        return NULL;
2655
2735
}
2656
2736
 
2680
2760
        return 1;
2681
2761
}
2682
2762
 
 
2763
static void _free_pv_list(struct dm_list *all_pvs)
 
2764
{
 
2765
        struct pv_list *pvl;
 
2766
 
 
2767
        dm_list_iterate_items(pvl, all_pvs)
 
2768
                pvl->pv->fid->fmt->ops->destroy_instance(pvl->pv->fid);
 
2769
}
 
2770
 
2683
2771
int vg_missing_pv_count(const struct volume_group *vg)
2684
2772
{
2685
2773
        int ret = 0;
2728
2816
 * If precommitted is set, use precommitted metadata if present.
2729
2817
 *
2730
2818
 * Either of vgname or vgid may be NULL.
 
2819
 *
 
2820
 * Note: vginfo structs must not be held or used as parameters
 
2821
 *       across the call to this function.
2731
2822
 */
2732
2823
static struct volume_group *_vg_read(struct cmd_context *cmd,
2733
2824
                                     const char *vgname,
2736
2827
                                     int *consistent, unsigned precommitted)
2737
2828
{
2738
2829
        struct format_instance *fid;
 
2830
        struct format_instance_ctx fic;
2739
2831
        const struct format_type *fmt;
2740
2832
        struct volume_group *vg, *correct_vg = NULL;
2741
2833
        struct metadata_area *mda;
2745
2837
        int inconsistent_pvs = 0;
2746
2838
        int inconsistent_seqno = 0;
2747
2839
        int inconsistent_mdas = 0;
 
2840
        int inconsistent_mda_count = 0;
2748
2841
        unsigned use_precommitted = precommitted;
2749
2842
        unsigned saved_handles_missing_pvs = cmd->handles_missing_pvs;
2750
2843
        struct dm_list *pvids;
2775
2868
                else    /* Inconsistent but we can't repair it */
2776
2869
                        correct_vg->status &= ~INCONSISTENT_VG;
2777
2870
 
2778
 
                if (vg_missing_pv_count(correct_vg)) {
2779
 
                        log_verbose("There are %d physical volumes missing.",
2780
 
                                    vg_missing_pv_count(correct_vg));
2781
 
                        vg_mark_partial_lvs(correct_vg);
2782
 
                }
2783
2871
                return correct_vg;
2784
2872
        } else {
2785
2873
                free_vg(correct_vg);
2792
2880
                lvmcache_label_scan(cmd, 0);
2793
2881
                if (!(fmt = fmt_from_vgname(vgname, vgid, 1))) {
2794
2882
                        /* Independent MDAs aren't supported under low memory */
2795
 
                        if (!cmd->independent_metadata_areas && memlock())
 
2883
                        if (!cmd->independent_metadata_areas && critical_section())
2796
2884
                                return_NULL;
2797
2885
                        lvmcache_label_scan(cmd, 2);
2798
2886
                        if (!(fmt = fmt_from_vgname(vgname, vgid, 0)))
2808
2896
                use_precommitted = 0;
2809
2897
 
2810
2898
        /* create format instance with appropriate metadata area */
2811
 
        if (!(fid = fmt->ops->create_instance(fmt, vgname, vgid, NULL))) {
 
2899
        fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
 
2900
        fic.context.vg_ref.vg_name = vgname;
 
2901
        fic.context.vg_ref.vg_id = vgid;
 
2902
        if (!(fid = fmt->ops->create_instance(fmt, &fic))) {
2812
2903
                log_error("Failed to create format instance");
2813
2904
                return NULL;
2814
2905
        }
2818
2909
                return_NULL;
2819
2910
 
2820
2911
        /* Ensure contents of all metadata areas match - else do recovery */
 
2912
        inconsistent_mda_count=0;
2821
2913
        dm_list_iterate_items(mda, &fid->metadata_areas_in_use) {
2822
2914
                if ((use_precommitted &&
2823
2915
                     !(vg = mda->ops->vg_read_precommit(fid, vgname, mda))) ||
2827
2919
                        free_vg(vg);
2828
2920
                        continue;
2829
2921
                }
 
2922
 
2830
2923
                if (!correct_vg) {
2831
2924
                        correct_vg = vg;
2832
2925
                        continue;
2845
2938
                        if (vg->seqno > correct_vg->seqno) {
2846
2939
                                free_vg(correct_vg);
2847
2940
                                correct_vg = vg;
 
2941
                        } else {
 
2942
                                mda->status |= MDA_INCONSISTENT;
 
2943
                                ++inconsistent_mda_count;
2848
2944
                        }
2849
2945
                }
2850
2946
 
2881
2977
                                        break;
2882
2978
                                }
2883
2979
                                if (dm_list_size(&info->mdas)) {
2884
 
                                        if (!fid_add_mdas(fid, &info->mdas))
 
2980
                                        if (!fid_add_mdas(fid, &info->mdas,
 
2981
                                                          info->dev->pvid, ID_LEN))
2885
2982
                                                return_NULL;
2886
2983
                                         
2887
2984
                                        log_debug("Empty mda found for VG %s.", vgname);
2921
3018
                        log_debug("Cached VG %s had incorrect PV list",
2922
3019
                                  vgname);
2923
3020
 
2924
 
                        if (memlock())
 
3021
                        if (critical_section())
2925
3022
                                inconsistent = 1;
2926
3023
                        else {
2927
3024
                                free_vg(correct_vg);
2952
3049
                inconsistent = 0;
2953
3050
 
2954
3051
                /* Independent MDAs aren't supported under low memory */
2955
 
                if (!cmd->independent_metadata_areas && memlock())
 
3052
                if (!cmd->independent_metadata_areas && critical_section())
2956
3053
                        return_NULL;
2957
3054
                lvmcache_label_scan(cmd, 2);
2958
3055
                if (!(fmt = fmt_from_vgname(vgname, vgid, 0)))
2962
3059
                        use_precommitted = 0;
2963
3060
 
2964
3061
                /* create format instance with appropriate metadata area */
2965
 
                if (!(fid = fmt->ops->create_instance(fmt, vgname, vgid, NULL))) {
 
3062
                fic.type = FMT_INSTANCE_VG | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
 
3063
                fic.context.vg_ref.vg_name = vgname;
 
3064
                fic.context.vg_ref.vg_id = vgid;
 
3065
                if (!(fid = fmt->ops->create_instance(fmt, &fic))) {
2966
3066
                        log_error("Failed to create format instance");
2967
3067
                        return NULL;
2968
3068
                }
2969
3069
 
2970
3070
                /* Ensure contents of all metadata areas match - else recover */
 
3071
                inconsistent_mda_count=0;
2971
3072
                dm_list_iterate_items(mda, &fid->metadata_areas_in_use) {
2972
3073
                        if ((use_precommitted &&
2973
3074
                             !(vg = mda->ops->vg_read_precommit(fid, vgname,
2980
3081
                        if (!correct_vg) {
2981
3082
                                correct_vg = vg;
2982
3083
                                if (!_update_pv_list(cmd->mem, &all_pvs, correct_vg)) {
 
3084
                                        _free_pv_list(&all_pvs);
2983
3085
                                        free_vg(vg);
2984
3086
                                        return_NULL;
2985
3087
                                }
2986
3088
                                continue;
2987
3089
                        }
2988
3090
 
2989
 
                        if (strncmp((char *)vg->id.uuid,
2990
 
                            (char *)correct_vg->id.uuid, ID_LEN)) {
 
3091
                        if (!id_equal(&vg->id, &correct_vg->id)) {
2991
3092
                                inconsistent = 1;
2992
3093
                                inconsistent_vgid = 1;
2993
3094
                        }
3004
3105
                                        inconsistent_seqno = 1;
3005
3106
                                }
3006
3107
                                if (!_update_pv_list(cmd->mem, &all_pvs, vg)) {
 
3108
                                        _free_pv_list(&all_pvs);
3007
3109
                                        free_vg(vg);
3008
3110
                                        free_vg(correct_vg);
3009
3111
                                        return_NULL;
3011
3113
                                if (vg->seqno > correct_vg->seqno) {
3012
3114
                                        free_vg(correct_vg);
3013
3115
                                        correct_vg = vg;
 
3116
                                } else {
 
3117
                                        mda->status |= MDA_INCONSISTENT;
 
3118
                                        ++inconsistent_mda_count;
3014
3119
                                }
3015
3120
                        }
3016
3121
 
3019
3124
                }
3020
3125
 
3021
3126
                /* Give up looking */
3022
 
                if (!correct_vg)
 
3127
                if (!correct_vg) {
 
3128
                        _free_pv_list(&all_pvs);
3023
3129
                        return_NULL;
 
3130
                }
3024
3131
        }
3025
3132
 
3026
3133
        /*
3035
3142
                if (use_precommitted) {
3036
3143
                        log_error("Inconsistent pre-commit metadata copies "
3037
3144
                                  "for volume group %s", vgname);
3038
 
                        /* FIXME: during repair, there is inconsistent flag set because some metadata areas
3039
 
                         * are missing (on missing PVs). Code should create list of missing PVs, compare it
3040
 
                         * with PV marked missing in metadata and if equals, use it as consistent vg.
3041
 
                         * For now, return precommited metadata if remainng seq match here to allow
3042
 
                         * preloading table in suspend call.
 
3145
 
 
3146
                        /*
 
3147
                         * Check whether all of the inconsistent MDAs were on
 
3148
                         * MISSING PVs -- in that case, we should be safe.
3043
3149
                         */
3044
 
                        if (!inconsistent_seqno) {
 
3150
                        dm_list_iterate_items(mda, &fid->metadata_areas_in_use) {
 
3151
                                if (mda->status & MDA_INCONSISTENT) {
 
3152
                                        log_debug("Checking inconsistent MDA: %s", dev_name(mda_get_device(mda)));
 
3153
                                        dm_list_iterate_items(pvl, &correct_vg->pvs) {
 
3154
                                                if (mda_get_device(mda) == pvl->pv->dev &&
 
3155
                                                    (pvl->pv->status & MISSING_PV))
 
3156
                                                        --inconsistent_mda_count;
 
3157
                                        }
 
3158
                                }
 
3159
                        }
 
3160
 
 
3161
                        if (inconsistent_mda_count < 0)
 
3162
                                log_error(INTERNAL_ERROR "Too many inconsistent MDAs.");
 
3163
 
 
3164
                        if (!inconsistent_mda_count) {
3045
3165
                                *consistent = 0;
 
3166
                                _free_pv_list(&all_pvs);
3046
3167
                                return correct_vg;
3047
3168
                        }
 
3169
                        _free_pv_list(&all_pvs);
3048
3170
                        free_vg(correct_vg);
3049
3171
                        return NULL;
3050
3172
                }
3051
3173
 
3052
 
                if (!*consistent)
 
3174
                if (!*consistent) {
 
3175
                        _free_pv_list(&all_pvs);
3053
3176
                        return correct_vg;
 
3177
                }
3054
3178
 
3055
3179
                /* Don't touch if vgids didn't match */
3056
3180
                if (inconsistent_vgid) {
3057
3181
                        log_error("Inconsistent metadata UUIDs found for "
3058
3182
                                  "volume group %s", vgname);
3059
3183
                        *consistent = 0;
 
3184
                        _free_pv_list(&all_pvs);
3060
3185
                        return correct_vg;
3061
3186
                }
3062
3187
 
3073
3198
                cmd->handles_missing_pvs = 1;
3074
3199
                if (!vg_write(correct_vg)) {
3075
3200
                        log_error("Automatic metadata correction failed");
 
3201
                        _free_pv_list(&all_pvs);
3076
3202
                        free_vg(correct_vg);
3077
3203
                        cmd->handles_missing_pvs = saved_handles_missing_pvs;
3078
3204
                        return NULL;
3092
3218
                                        goto next_pv;
3093
3219
                        }
3094
3220
                        if (!id_write_format(&pvl->pv->id, uuid, sizeof(uuid))) {
 
3221
                                _free_pv_list(&all_pvs);
3095
3222
                                free_vg(correct_vg);
3096
3223
                                return_NULL;
3097
3224
                        }
3098
3225
                        log_error("Removing PV %s (%s) that no longer belongs to VG %s",
3099
3226
                                  pv_dev_name(pvl->pv), uuid, correct_vg->name);
3100
3227
                        if (!pv_write_orphan(cmd, pvl->pv)) {
 
3228
                                _free_pv_list(&all_pvs);
3101
3229
                                free_vg(correct_vg);
3102
3230
                                return_NULL;
3103
3231
                        }
3109
3237
                }
3110
3238
        }
3111
3239
 
 
3240
        _free_pv_list(&all_pvs);
 
3241
 
3112
3242
        if (vg_missing_pv_count(correct_vg)) {
3113
3243
                log_verbose("There are %d physical volumes missing.",
3114
3244
                            vg_missing_pv_count(correct_vg));
3115
 
                vg_mark_partial_lvs(correct_vg);
 
3245
                vg_mark_partial_lvs(correct_vg, 1);
3116
3246
        }
3117
3247
 
3118
3248
        if ((correct_vg->status & PVMOVE) && !pvmove_mode()) {
3168
3298
        return vg;
3169
3299
}
3170
3300
 
 
3301
void free_pv_fid(struct physical_volume *pv)
 
3302
{
 
3303
        if (!pv)
 
3304
                return;
 
3305
 
 
3306
        if (pv->fid)
 
3307
                pv->fid->fmt->ops->destroy_instance(pv->fid);
 
3308
}
 
3309
 
3171
3310
void free_vg(struct volume_group *vg)
3172
3311
{
3173
3312
        if (!vg)
3174
3313
                return;
3175
3314
 
 
3315
        vg_set_fid(vg, NULL);
 
3316
 
3176
3317
        if (vg->cmd && vg->vgmem == vg->cmd->mem) {
3177
3318
                log_error(INTERNAL_ERROR "global memory pool used for VG %s",
3178
3319
                          vg->name);
3202
3343
            vginfo->vgname && !is_orphan_vg(vginfo->vgname)) {
3203
3344
                if ((vg = _vg_read(cmd, NULL, vgid, 1,
3204
3345
                                   &consistent, precommitted)) &&
3205
 
                    !strncmp((char *)vg->id.uuid, vgid, ID_LEN)) {
 
3346
                    id_equal(&vg->id, (const struct id *)vgid)) {
3206
3347
                        if (!consistent)
3207
3348
                                log_error("Volume group %s metadata is "
3208
3349
                                          "inconsistent", vg->name);
3212
3353
        }
3213
3354
 
3214
3355
        /* Mustn't scan if memory locked: ensure cache gets pre-populated! */
3215
 
        if (memlock())
 
3356
        if (critical_section())
3216
3357
                return_NULL;
3217
3358
 
3218
3359
        /* FIXME Need a genuine read by ID here - don't vg_read_internal by name! */
3233
3374
                consistent = 0;
3234
3375
                if ((vg = _vg_read(cmd, vgname, vgid, 1, &consistent,
3235
3376
                                   precommitted)) &&
3236
 
                    !strncmp((char *)vg->id.uuid, vgid, ID_LEN)) {
 
3377
                    id_equal(&vg->id, (const struct id *)vgid)) {
3237
3378
                        if (!consistent) {
3238
3379
                                log_error("Volume group %s metadata is "
3239
3380
                                          "inconsistent", vgname);
3346
3487
 *   FIXME - liblvm todo - make into function that returns handle
3347
3488
 */
3348
3489
struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name,
3349
 
                                struct dm_list *mdas, uint64_t *label_sector,
3350
 
                                int warnings, int scan_label_only)
 
3490
                                int warnings,
 
3491
                                int scan_label_only)
3351
3492
{
3352
 
        return _pv_read(cmd, cmd->mem, pv_name, mdas, label_sector, warnings, scan_label_only);
 
3493
        return _pv_read(cmd, cmd->mem, pv_name, NULL, warnings, scan_label_only);
3353
3494
}
3354
3495
 
3355
3496
/* FIXME Use label functions instead of PV functions */
3356
3497
static struct physical_volume *_pv_read(struct cmd_context *cmd,
3357
3498
                                        struct dm_pool *pvmem,
3358
3499
                                        const char *pv_name,
3359
 
                                        struct dm_list *mdas,
3360
 
                                        uint64_t *label_sector,
 
3500
                                        struct format_instance *fid,
3361
3501
                                        int warnings, int scan_label_only)
3362
3502
{
3363
3503
        struct physical_volume *pv;
 
3504
        struct format_instance_ctx fic;
3364
3505
        struct label *label;
3365
3506
        struct lvmcache_info *info;
3366
3507
        struct device *dev;
3376
3517
        }
3377
3518
 
3378
3519
        info = (struct lvmcache_info *) label->info;
3379
 
        if (label_sector && *label_sector)
3380
 
                *label_sector = label->sector;
3381
3520
 
3382
3521
        pv = _alloc_pv(pvmem, dev);
3383
3522
        if (!pv) {
3385
3524
                return NULL;
3386
3525
        }
3387
3526
 
 
3527
        pv->label_sector = label->sector;
 
3528
 
3388
3529
        /* FIXME Move more common code up here */
3389
 
        if (!(info->fmt->ops->pv_read(info->fmt, pv_name, pv, mdas,
3390
 
              scan_label_only))) {
 
3530
        if (!(info->fmt->ops->pv_read(info->fmt, pv_name, pv, scan_label_only))) {
3391
3531
                log_error("Failed to read existing physical volume '%s'",
3392
3532
                          pv_name);
3393
3533
                goto bad;
3399
3539
        if (!alloc_pv_segment_whole_pv(pvmem, pv))
3400
3540
                goto_bad;
3401
3541
 
 
3542
        if (fid)
 
3543
                fid_add_mdas(fid, &info->mdas, (const char *) &pv->id, ID_LEN);
 
3544
        else {
 
3545
                fic.type = FMT_INSTANCE_PV | FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
 
3546
                fic.context.pv_id = (const char *) &pv->id;
 
3547
                if (!(fid = pv->fmt->ops->create_instance(pv->fmt, &fic))) {
 
3548
                        log_error("_pv_read: Couldn't create format instance "
 
3549
                                  "for PV %s", pv_name);
 
3550
                        goto bad;
 
3551
                }
 
3552
                pv_set_fid(pv, fid);
 
3553
        }
 
3554
 
3402
3555
        return pv;
3403
3556
bad:
3404
 
        _free_pv(pvmem, pv);
 
3557
        free_pv_fid(pv);
 
3558
        dm_pool_free(pvmem, pv);
3405
3559
        return NULL;
3406
3560
}
3407
3561
 
3503
3657
}
3504
3658
 
3505
3659
int pv_write(struct cmd_context *cmd __attribute__((unused)),
3506
 
             struct physical_volume *pv,
3507
 
             struct dm_list *mdas, int64_t label_sector)
 
3660
             struct physical_volume *pv, int allow_non_orphan)
3508
3661
{
3509
3662
        if (!pv->fmt->ops->pv_write) {
3510
3663
                log_error("Format does not support writing physical volumes");
3511
3664
                return 0;
3512
3665
        }
3513
3666
 
3514
 
        if (!is_orphan_vg(pv->vg_name) || pv->pe_alloc_count) {
 
3667
        /*
 
3668
         * FIXME: Try to remove this restriction. This requires checking
 
3669
         *        that the PV and the VG are in a consistent state. We need
 
3670
         *        to provide some revert mechanism since PV label together
 
3671
         *        with VG metadata write is not atomic.
 
3672
         */
 
3673
        if (!allow_non_orphan &&
 
3674
            (!is_orphan_vg(pv->vg_name) || pv->pe_alloc_count)) {
3515
3675
                log_error("Assertion failed: can't _pv_write non-orphan PV "
3516
3676
                          "(in VG %s)", pv->vg_name);
3517
3677
                return 0;
3518
3678
        }
3519
3679
 
3520
 
        if (!pv->fmt->ops->pv_write(pv->fmt, pv, mdas, label_sector))
 
3680
        if (!pv->fmt->ops->pv_write(pv->fmt, pv))
3521
3681
                return_0;
3522
3682
 
3523
3683
        return 1;
3536
3696
                return 0;
3537
3697
        }
3538
3698
 
3539
 
        if (!pv_write(cmd, pv, NULL, INT64_C(-1))) {
 
3699
        if (!pv_write(cmd, pv, 0)) {
3540
3700
                log_error("Failed to clear metadata from physical "
3541
3701
                          "volume \"%s\" after removal from \"%s\"",
3542
3702
                          pv_dev_name(pv), old_vg_name);
3891
4051
                lvmcache_label_scan(cmd, 0);
3892
4052
                if (!fmt_from_vgname(vgname, NULL, 1)) {
3893
4053
                        /* Independent MDAs aren't supported under low memory */
3894
 
                        if (!cmd->independent_metadata_areas && memlock()) {
 
4054
                        if (!cmd->independent_metadata_areas && critical_section()) {
3895
4055
                                /*
3896
4056
                                 * FIXME: Disallow calling this function if
3897
 
                                 * memlock() is true.
 
4057
                                 * critical_section() is true.
3898
4058
                                 */
3899
4059
                                unlock_vg(cmd, vgname);
3900
4060
                                return FAILED_LOCKING;
3912
4072
        return FAILED_EXIST;
3913
4073
}
3914
4074
 
3915
 
void fid_add_mda(struct format_instance *fid, struct metadata_area *mda)
3916
 
{
 
4075
struct format_instance *alloc_fid(const struct format_type *fmt,
 
4076
                                  const struct format_instance_ctx *fic)
 
4077
{
 
4078
        struct dm_pool *mem;
 
4079
        struct format_instance *fid;
 
4080
 
 
4081
        if (!(mem = dm_pool_create("format_instance", 1024)))
 
4082
                return_NULL;
 
4083
 
 
4084
        if (!(fid = dm_pool_zalloc(mem, sizeof(*fid)))) {
 
4085
                log_error("Couldn't allocate format_instance object.");
 
4086
                goto bad;
 
4087
        }
 
4088
 
 
4089
        fid->ref_count = 1;
 
4090
        fid->mem = mem;
 
4091
        fid->type = fic->type;
 
4092
        fid->fmt = fmt;
 
4093
 
 
4094
        dm_list_init(&fid->metadata_areas_in_use);
 
4095
        dm_list_init(&fid->metadata_areas_ignored);
 
4096
 
 
4097
        return fid;
 
4098
 
 
4099
bad:
 
4100
        dm_pool_destroy(mem);
 
4101
        return NULL;
 
4102
}
 
4103
 
 
4104
void pv_set_fid(struct physical_volume *pv,
 
4105
                struct format_instance *fid)
 
4106
{
 
4107
        if (fid)
 
4108
                fid->ref_count++;
 
4109
 
 
4110
        if (pv->fid)
 
4111
                pv->fid->fmt->ops->destroy_instance(pv->fid);
 
4112
 
 
4113
        pv->fid = fid;
 
4114
}
 
4115
 
 
4116
void vg_set_fid(struct volume_group *vg,
 
4117
                 struct format_instance *fid)
 
4118
{
 
4119
        struct pv_list *pvl;
 
4120
 
 
4121
        if (fid)
 
4122
                fid->ref_count++;
 
4123
 
 
4124
        dm_list_iterate_items(pvl, &vg->pvs)
 
4125
                pv_set_fid(pvl->pv, fid);
 
4126
 
 
4127
        dm_list_iterate_items(pvl, &vg->removed_pvs)
 
4128
                pv_set_fid(pvl->pv, fid);
 
4129
 
 
4130
        if (vg->fid)
 
4131
                vg->fid->fmt->ops->destroy_instance(vg->fid);
 
4132
 
 
4133
        vg->fid = fid;
 
4134
}
 
4135
 
 
4136
static int _convert_key_to_string(const char *key, size_t key_len,
 
4137
                                  unsigned sub_key, char *buf, size_t buf_len)
 
4138
{
 
4139
        memcpy(buf, key, key_len);
 
4140
        buf += key_len;
 
4141
        buf_len -= key_len;
 
4142
        if ((dm_snprintf(buf, buf_len, "_%u", sub_key) == -1))
 
4143
                return_0;
 
4144
 
 
4145
        return 1;
 
4146
}
 
4147
 
 
4148
int fid_add_mda(struct format_instance *fid, struct metadata_area *mda,
 
4149
                 const char *key, size_t key_len, const unsigned sub_key)
 
4150
{
 
4151
        char full_key[PATH_MAX];
3917
4152
        dm_list_add(mda_is_ignored(mda) ? &fid->metadata_areas_ignored :
3918
4153
                                          &fid->metadata_areas_in_use, &mda->list);
 
4154
 
 
4155
        /* Return if the mda is not supposed to be indexed. */
 
4156
        if (!key)
 
4157
                return 1;
 
4158
 
 
4159
        /* Add metadata area to index. */
 
4160
        if (fid->type & FMT_INSTANCE_VG) {
 
4161
                if (!_convert_key_to_string(key, key_len, sub_key,
 
4162
                                            full_key, PATH_MAX))
 
4163
                return_0;
 
4164
 
 
4165
                dm_hash_insert(fid->metadata_areas_index.hash,
 
4166
                               full_key, mda);
 
4167
        }
 
4168
        else
 
4169
                fid->metadata_areas_index.array[sub_key] = mda;
 
4170
 
 
4171
        return 1;
3919
4172
}
3920
4173
 
3921
 
int fid_add_mdas(struct format_instance *fid, struct dm_list *mdas)
 
4174
int fid_add_mdas(struct format_instance *fid, struct dm_list *mdas,
 
4175
                 const char *key, size_t key_len)
3922
4176
{
3923
4177
        struct metadata_area *mda, *mda_new;
 
4178
        unsigned mda_index = 0;
3924
4179
 
3925
4180
        dm_list_iterate_items(mda, mdas) {
3926
 
                mda_new = mda_copy(fid->fmt->cmd->mem, mda);
 
4181
                mda_new = mda_copy(fid->mem, mda);
3927
4182
                if (!mda_new)
3928
4183
                        return_0;
3929
 
                fid_add_mda(fid, mda_new);
3930
 
        }
 
4184
                fid_remove_mda(fid, NULL, key, key_len, mda_index);
 
4185
                fid_add_mda(fid, mda_new, key, key_len, mda_index);
 
4186
                mda_index++;
 
4187
        }
 
4188
 
 
4189
        return 1;
 
4190
}
 
4191
 
 
4192
struct metadata_area *fid_get_mda_indexed(struct format_instance *fid,
 
4193
                                          const char *key, size_t key_len,
 
4194
                                          const unsigned sub_key)
 
4195
{
 
4196
        char full_key[PATH_MAX];
 
4197
        struct metadata_area *mda = NULL;
 
4198
 
 
4199
 
 
4200
        if (fid->type & FMT_INSTANCE_VG) {
 
4201
                if (!_convert_key_to_string(key, key_len, sub_key,
 
4202
                                            full_key, PATH_MAX))
 
4203
                        return_NULL;
 
4204
                mda = (struct metadata_area *) dm_hash_lookup(fid->metadata_areas_index.hash,
 
4205
                                                              full_key);
 
4206
        }
 
4207
        else
 
4208
                mda = fid->metadata_areas_index.array[sub_key];
 
4209
 
 
4210
        return mda;
 
4211
}
 
4212
 
 
4213
int fid_remove_mda(struct format_instance *fid, struct metadata_area *mda,
 
4214
                   const char *key, size_t key_len, const unsigned sub_key)
 
4215
{
 
4216
        struct metadata_area *mda_indexed = NULL;
 
4217
        char full_key[PATH_MAX];
 
4218
 
 
4219
        /* At least one of mda or key must be specified. */
 
4220
        if (!mda && !key)
 
4221
                return 1;
 
4222
 
 
4223
        if (key) {
 
4224
                /*
 
4225
                 * If both mda and key specified, check given mda
 
4226
                 * with what we find using the index and return
 
4227
                 * immediately if these two do not match.
 
4228
                 */
 
4229
                if (!(mda_indexed = fid_get_mda_indexed(fid, key, key_len, sub_key)) ||
 
4230
                     (mda && mda != mda_indexed))
 
4231
                        return 1;
 
4232
 
 
4233
                mda = mda_indexed;
 
4234
 
 
4235
                if (fid->type & FMT_INSTANCE_VG) {
 
4236
                        if (!_convert_key_to_string(key, key_len, sub_key,
 
4237
                                            full_key, PATH_MAX))
 
4238
                                return_0;
 
4239
 
 
4240
                        dm_hash_remove(fid->metadata_areas_index.hash, full_key);
 
4241
                } else
 
4242
                        fid->metadata_areas_index.array[sub_key] = NULL;
 
4243
        }
 
4244
 
 
4245
        dm_list_del(&mda->list);
 
4246
 
3931
4247
        return 1;
3932
4248
}
3933
4249
 
3987
4303
        return mda1->ops->mda_locns_match(mda1, mda2);
3988
4304
}
3989
4305
 
 
4306
struct device *mda_get_device(struct metadata_area *mda)
 
4307
{
 
4308
        if (!mda->ops->mda_get_device)
 
4309
                return NULL;
 
4310
        return mda->ops->mda_get_device(mda);
 
4311
}
 
4312
 
3990
4313
unsigned mda_is_ignored(struct metadata_area *mda)
3991
4314
{
3992
4315
        return (mda->status & MDA_IGNORED);
4108
4431
 */
4109
4432
struct physical_volume *pv_by_path(struct cmd_context *cmd, const char *pv_name)
4110
4433
{
4111
 
        struct dm_list mdas;
4112
 
 
4113
 
        dm_list_init(&mdas);
4114
 
        return _pv_read(cmd, cmd->mem, pv_name, &mdas, NULL, 1, 0);
 
4434
        return _pv_read(cmd, cmd->mem, pv_name, NULL, 1, 0);
4115
4435
}