239
250
pv->pe_alloc_count = 0;
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.
251
if (!pv_mda_used_count(pv))
252
mdas = &fid->metadata_areas_ignored;
254
mdas = &fid->metadata_areas_in_use;
256
if (!fid->fmt->ops->pv_setup(fid->fmt, UINT64_C(0), 0,
257
vg->extent_size, 0, 0, 0UL, UINT64_C(0),
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);
662
672
* - pp: parameters to pass to implicit pvcreate; if NULL, do not pvcreate
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)
670
681
if (_vg_bad_status_bits(vg, RESIZEABLE_VG))
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))
686
if (!(pv_name = dm_strdup(pv_names[i]))) {
687
log_error("Failed to duplicate pv name %s.", pv_names[i]);
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);
680
700
/* FIXME Decide whether to initialise and add new mdahs to format instance */
685
log_error("Unable to add physical volume '%s' to "
686
"volume group '%s'.", pv_names[i], vg->name);
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)
693
708
struct physical_volume *pv;
694
709
struct pv_list *pvl;
1436
1436
pp->metadataignore = DEFAULT_PVMETADATAIGNORE;
1440
static int _pvcreate_write(struct cmd_context *cmd, struct pv_to_create *pvc)
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);
1447
/* Wipe existing label first */
1448
if (!label_remove(pv_dev(pv))) {
1449
log_error("Failed to wipe existing label on %s", pv_name);
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);
1460
if (!dev_set(dev, UINT64_C(0), (size_t) 2048, 0)) {
1461
log_error("%s not wiped: aborting", pv_name);
1468
log_error("Writing physical volume data to disk \"%s\"",
1471
if (!(pv_write(cmd, pv, 1))) {
1472
log_error("Failed to write physical volume \"%s\"", pv_name);
1476
log_print("Physical volume \"%s\" successfully created", pv_name);
1440
1481
* pvcreate_single() - initialize a device with PV label and metadata area
1462
1504
pp = &default_pp;
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)))
1470
1512
log_error("uuid %s already in use on \"%s\"", buffer,
1471
1513
dev_name(dev));
1476
1518
if (!pvcreate_check(cmd, pv_name, pp))
1479
1521
if (sigint_caught())
1482
1524
if (!(dev = dev_cache_get(pv_name, cmd->filter))) {
1483
1525
log_error("%s: Couldn't find device. Check your filters?",
1488
1530
dm_list_init(&mdas);
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);
1498
1542
log_verbose("Set up physical volume for \"%s\" with %" PRIu64
1499
1543
" available sectors", pv_name, pv_size(pv));
1501
/* Wipe existing label first */
1502
if (!label_remove(pv_dev(pv))) {
1503
log_error("Failed to wipe existing label on %s", pv_name);
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);
1514
if (!dev_set(dev, UINT64_C(0), (size_t) 2048, 0)) {
1515
log_error("%s not wiped: aborting", pv_name);
1522
log_very_verbose("Writing physical volume data to disk \"%s\"",
1525
if (!(pv_write(cmd, pv, &mdas, pp->labelsector))) {
1526
log_error("Failed to write physical volume \"%s\"", pv_name);
1530
log_print("Physical volume \"%s\" successfully created", pv_name);
1546
struct pv_to_create pvc;
1549
if (!_pvcreate_write(cmd, &pvc))
1552
pv->status |= UNLABELLED_PV;
1538
static void _free_pv(struct dm_pool *mem, struct physical_volume *pv)
1540
dm_pool_free(mem, pv);
1543
1562
static struct physical_volume *_alloc_pv(struct dm_pool *mem, struct device *dev)
1545
1564
struct physical_volume *pv = dm_pool_zalloc(mem, sizeof(*pv));
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));
1672
pv_set_fid(pv, fid);
1642
1675
pv->vg_name = fmt->orphan_vg_name;
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));
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,
1691
log_error("Failed to add metadata area for "
1692
"new physical volume %s", pv_dev_name(pv));
1701
dm_pool_free(mem, pv);
1802
1846
static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd,
1803
1847
const char *pv_name)
1805
struct dm_list mdas;
1806
1849
struct physical_volume *pv;
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);
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))
1818
if (!(pv = _pv_read(cmd, cmd->mem, pv_name, NULL, NULL, 1, 0))) {
1861
if (!(pv = _pv_read(cmd, cmd->mem, pv_name, NULL, 1, 0))) {
1819
1862
log_error("Physical volume %s not found", pv_name);
1824
1867
if (is_orphan_vg(pv->vg_name)) {
1825
1868
log_error("Physical volume %s not in a volume group", pv_name);
1832
1879
/* Find segment at a given logical extent in an LV */
1969
2016
int (*fn)(struct logical_volume *lv, void *data),
1972
static int _lv_postorder_level(struct logical_volume *lv, void *data)
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;
1984
2019
static int _lv_each_dependency(struct logical_volume *lv,
1985
2020
int (*fn)(struct logical_volume *lv, void *data),
1989
2024
struct lv_segment *lvseg;
1991
2026
struct logical_volume *deps[] = {
2098
static int _lv_mark_if_partial(struct logical_volume *lv)
2100
return _lv_postorder(lv, _lv_mark_if_partial_single, NULL);
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.
2108
int vg_mark_partial_lvs(struct volume_group *vg)
2174
int vg_mark_partial_lvs(struct volume_group *vg, int clear)
2110
struct logical_volume *lv;
2111
2176
struct lv_list *lvl;
2113
dm_list_iterate_items(lvl, &vg->lvs) {
2115
if (!_lv_mark_if_partial(lv))
2179
dm_list_iterate_items(lvl, &vg->lvs)
2180
lvl->lv->status &= ~PARTIAL_LV;
2182
if (!_lv_postorder_vg(vg, _lv_mark_if_partial_single, NULL))
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) {
2191
/* look up the reference in vg->pvs */
2192
dm_list_iterate_items(pvl, &vg->pvs) {
2193
if (pvl->pv == seg_pv(lvseg, s)) {
2200
log_error(INTERNAL_ERROR
2201
"Referenced PV %s not listed in VG %s.",
2202
pv_dev_name(seg_pv(lvseg, s)), vg->name);
2254
if (seg_type(lvseg, s) != AREA_PV)
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,
2260
log_error(INTERNAL_ERROR
2261
"Referenced PV %s not listed in VG %s.",
2262
pv_dev_name(pv), vg->name);
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.");
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? */
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");
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)
2250
dm_list_iterate_items(pvl2, &vg->pvs) {
2251
if (++loop_counter2 > pv_count)
2255
if (id_equal(&pvl->pv->id,
2257
if (!id_write_format(&pvl->pv->id, uuid,
2260
log_error(INTERNAL_ERROR "Duplicate PV id "
2261
"%s detected for %s in %s.",
2262
uuid, pv_dev_name(pvl->pv),
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));
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,
2320
log_error(INTERNAL_ERROR "Duplicate PV id "
2321
"%s detected for %s in %s.",
2322
uuid, pv_dev_name(pvl->pv),
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.");
2275
2336
if (!check_pv_segments(vg)) {
2276
2337
log_error(INTERNAL_ERROR "PV segments corrupted in %s.",
2338
2399
/* Avoid endless loop if lv->segments list is corrupt */
2342
loop_counter1 = loop_counter2 = 0;
2343
/* FIXME Use temp hash table instead? */
2403
if (!(vhash.lvname = dm_hash_create(lv_count))) {
2404
log_error("Failed to allocate lv_name hash");
2409
if (!(vhash.lvid = dm_hash_create(lv_count))) {
2410
log_error("Failed to allocate uuid hash");
2344
2415
dm_list_iterate_items(lvl, &vg->lvs) {
2345
if (++loop_counter1 > lv_count)
2347
dm_list_iterate_items(lvl2, &vg->lvs) {
2348
if (++loop_counter2 > lv_count)
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,
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,
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,
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);
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,
2428
log_error(INTERNAL_ERROR "Duplicate LV id "
2429
"%s detected for %s in %s.",
2430
uuid, lvl->lv->name, vg->name);
2371
2434
if (!check_lv_segments(lvl->lv, 1)) {
2599
2689
const char *orphan_vgname)
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;
2608
2699
lvmcache_label_scan(cmd, 0);
2610
2701
if (!(vginfo = vginfo_from_vgname(orphan_vgname, NULL)))
2613
if (!(mem = dm_pool_create("vg_read orphan", VG_MEMPOOL_CHUNK)))
2704
if (!(vg = alloc_vg("vg_read_orphans", cmd, orphan_vgname)))
2616
if (!(vg = dm_pool_zalloc(mem, sizeof(*vg)))) {
2617
log_error("vg allocation failed");
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);
2626
if (!(vg->name = dm_pool_strdup(mem, orphan_vgname))) {
2627
log_error("vg name allocation failed");
2631
2707
/* create format instance with appropriate metadata area */
2632
if (!(vg->fid = vginfo->fmt->ops->create_instance(vginfo->fmt,
2633
orphan_vgname, 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");
2715
vg_set_fid(vg, fid);
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))) {
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");
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.
3147
* Check whether all of the inconsistent MDAs were on
3148
* MISSING PVs -- in that case, we should be safe.
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;
3161
if (inconsistent_mda_count < 0)
3162
log_error(INTERNAL_ERROR "Too many inconsistent MDAs.");
3164
if (!inconsistent_mda_count) {
3045
3165
*consistent = 0;
3166
_free_pv_list(&all_pvs);
3046
3167
return correct_vg;
3169
_free_pv_list(&all_pvs);
3048
3170
free_vg(correct_vg);
3175
_free_pv_list(&all_pvs);
3053
3176
return correct_vg;
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;
3346
3487
* FIXME - liblvm todo - make into function that returns handle
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)
3491
int scan_label_only)
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);
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)
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;
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)
3509
3662
if (!pv->fmt->ops->pv_write) {
3510
3663
log_error("Format does not support writing physical volumes");
3514
if (!is_orphan_vg(pv->vg_name) || pv->pe_alloc_count) {
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.
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);
3520
if (!pv->fmt->ops->pv_write(pv->fmt, pv, mdas, label_sector))
3680
if (!pv->fmt->ops->pv_write(pv->fmt, pv))
3912
4072
return FAILED_EXIST;
3915
void fid_add_mda(struct format_instance *fid, struct metadata_area *mda)
4075
struct format_instance *alloc_fid(const struct format_type *fmt,
4076
const struct format_instance_ctx *fic)
4078
struct dm_pool *mem;
4079
struct format_instance *fid;
4081
if (!(mem = dm_pool_create("format_instance", 1024)))
4084
if (!(fid = dm_pool_zalloc(mem, sizeof(*fid)))) {
4085
log_error("Couldn't allocate format_instance object.");
4091
fid->type = fic->type;
4094
dm_list_init(&fid->metadata_areas_in_use);
4095
dm_list_init(&fid->metadata_areas_ignored);
4100
dm_pool_destroy(mem);
4104
void pv_set_fid(struct physical_volume *pv,
4105
struct format_instance *fid)
4111
pv->fid->fmt->ops->destroy_instance(pv->fid);
4116
void vg_set_fid(struct volume_group *vg,
4117
struct format_instance *fid)
4119
struct pv_list *pvl;
4124
dm_list_iterate_items(pvl, &vg->pvs)
4125
pv_set_fid(pvl->pv, fid);
4127
dm_list_iterate_items(pvl, &vg->removed_pvs)
4128
pv_set_fid(pvl->pv, fid);
4131
vg->fid->fmt->ops->destroy_instance(vg->fid);
4136
static int _convert_key_to_string(const char *key, size_t key_len,
4137
unsigned sub_key, char *buf, size_t buf_len)
4139
memcpy(buf, key, key_len);
4142
if ((dm_snprintf(buf, buf_len, "_%u", sub_key) == -1))
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)
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);
4155
/* Return if the mda is not supposed to be indexed. */
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))
4165
dm_hash_insert(fid->metadata_areas_index.hash,
4169
fid->metadata_areas_index.array[sub_key] = mda;
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)
3923
4177
struct metadata_area *mda, *mda_new;
4178
unsigned mda_index = 0;
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);
3929
fid_add_mda(fid, mda_new);
4184
fid_remove_mda(fid, NULL, key, key_len, mda_index);
4185
fid_add_mda(fid, mda_new, key, key_len, mda_index);
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)
4196
char full_key[PATH_MAX];
4197
struct metadata_area *mda = NULL;
4200
if (fid->type & FMT_INSTANCE_VG) {
4201
if (!_convert_key_to_string(key, key_len, sub_key,
4202
full_key, PATH_MAX))
4204
mda = (struct metadata_area *) dm_hash_lookup(fid->metadata_areas_index.hash,
4208
mda = fid->metadata_areas_index.array[sub_key];
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)
4216
struct metadata_area *mda_indexed = NULL;
4217
char full_key[PATH_MAX];
4219
/* At least one of mda or key must be specified. */
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.
4229
if (!(mda_indexed = fid_get_mda_indexed(fid, key, key_len, sub_key)) ||
4230
(mda && mda != mda_indexed))
4235
if (fid->type & FMT_INSTANCE_VG) {
4236
if (!_convert_key_to_string(key, key_len, sub_key,
4237
full_key, PATH_MAX))
4240
dm_hash_remove(fid->metadata_areas_index.hash, full_key);
4242
fid->metadata_areas_index.array[sub_key] = NULL;
4245
dm_list_del(&mda->list);