From 3cac20f850d76f373e9bcf672bf8c3f5d9283c78 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Wed, 1 Jun 2011 19:29:31 +0000 Subject: [PATCH] Defer writing PV labels to vg_write. Store label_sector only in struct physical_volume. --- WHATS_NEW | 2 + lib/cache/lvmcache.c | 46 ++++++------ lib/cache/lvmcache.h | 2 +- lib/format1/format1.c | 20 +++++- lib/format1/import-export.c | 4 +- lib/format_text/format-text.c | 35 ++------- lib/format_text/import_vsn1.c | 5 +- lib/metadata/metadata.c | 129 ++++++++++++++++++++++------------ lib/metadata/metadata.h | 3 +- lib/metadata/pv.h | 6 ++ lib/metadata/vg.c | 1 + lib/metadata/vg.h | 13 ++++ tools/pvcreate.c | 2 +- tools/pvremove.c | 4 +- tools/pvresize.c | 2 +- tools/toollib.c | 6 +- 16 files changed, 171 insertions(+), 109 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 246d5caa1..a638ef9ff 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,7 @@ Version 2.02.86 - ================================= + Defer writing PV labels to vg_write. + Store label_sector only in struct physical_volume. Permit --available with lvcreate so non-snapshot LVs need not be activated. Report sector containing label in verbose message. Clarify error message when unable to convert an LV into a snapshot of an LV. diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c index 80eb510e7..b448acabc 100644 --- a/lib/cache/lvmcache.c +++ b/lib/cache/lvmcache.c @@ -539,7 +539,7 @@ char *lvmcache_vgname_from_pvid(struct cmd_context *cmd, const char *pvid) struct lvmcache_info *info; char *vgname; - if (!device_from_pvid(cmd, (const struct id *)pvid, NULL)) { + if (!device_from_pvid(cmd, (const struct id *)pvid, NULL, NULL)) { log_error("Couldn't find device with uuid %s.", pvid); return NULL; } @@ -769,31 +769,41 @@ struct dm_list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname, return pvids; } -struct device *device_from_pvid(struct cmd_context *cmd, const struct id *pvid, - unsigned *scan_done_once) +static struct device *_device_from_pvid(const struct id *pvid, + uint64_t *label_sector) { - struct label *label; struct lvmcache_info *info; + struct label *label; - /* Already cached ? */ if ((info = info_from_pvid((const char *) pvid, 0))) { if (label_read(info->dev, &label, UINT64_C(0))) { info = (struct lvmcache_info *) label->info; - if (id_equal(pvid, (struct id *) &info->dev->pvid)) + if (id_equal(pvid, (struct id *) &info->dev->pvid)) { + if (label_sector) + *label_sector = label->sector; return info->dev; + } } } + return NULL; +} + +struct device *device_from_pvid(struct cmd_context *cmd, const struct id *pvid, + unsigned *scan_done_once, uint64_t *label_sector) +{ + struct device *dev; + + /* Already cached ? */ + dev = _device_from_pvid(pvid, label_sector); + if (dev) + return dev; lvmcache_label_scan(cmd, 0); /* Try again */ - if ((info = info_from_pvid((const char *) pvid, 0))) { - if (label_read(info->dev, &label, UINT64_C(0))) { - info = (struct lvmcache_info *) label->info; - if (id_equal(pvid, (struct id *) &info->dev->pvid)) - return info->dev; - } - } + dev = _device_from_pvid(pvid, label_sector); + if (dev) + return dev; if (critical_section() || (scan_done_once && *scan_done_once)) return NULL; @@ -803,13 +813,9 @@ struct device *device_from_pvid(struct cmd_context *cmd, const struct id *pvid, *scan_done_once = 1; /* Try again */ - if ((info = info_from_pvid((const char *) pvid, 0))) { - if (label_read(info->dev, &label, UINT64_C(0))) { - info = (struct lvmcache_info *) label->info; - if (id_equal(pvid, (struct id *) &info->dev->pvid)) - return info->dev; - } - } + dev = _device_from_pvid(pvid, label_sector); + if (dev) + return dev; return NULL; } diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h index f13cad2bb..9aafff5a6 100644 --- a/lib/cache/lvmcache.h +++ b/lib/cache/lvmcache.h @@ -99,7 +99,7 @@ struct lvmcache_vginfo *vginfo_from_vgid(const char *vgid); struct lvmcache_info *info_from_pvid(const char *pvid, int valid_only); const char *vgname_from_vgid(struct dm_pool *mem, const char *vgid); struct device *device_from_pvid(struct cmd_context *cmd, const struct id *pvid, - unsigned *scan_done_once); + unsigned *scan_done_once, uint64_t *label_sector); const char *pvid_from_devname(struct cmd_context *cmd, const char *dev_name); char *lvmcache_vgname_from_pvid(struct cmd_context *cmd, const char *pvid); diff --git a/lib/format1/format1.c b/lib/format1/format1.c index 4a91aac74..9b9df0f81 100644 --- a/lib/format1/format1.c +++ b/lib/format1/format1.c @@ -406,6 +406,8 @@ static int _format1_pv_write(const struct format_type *fmt, struct physical_volu struct disk_list *dl; struct dm_list pvs; struct lvmcache_info *info; + int pe_count, pe_size, pe_start; + int r = 1; if (!(info = lvmcache_add(fmt->labeller, (char *) &pv->id, pv->dev, pv->vg_name, NULL, 0))) @@ -418,6 +420,10 @@ static int _format1_pv_write(const struct format_type *fmt, struct physical_volu dm_list_init(&pvs); + pe_count = pv->pe_count; + pe_size = pv->pe_size; + pe_start = pv->pe_start; + /* Ensure any residual PE structure is gone */ pv->pe_size = pv->pe_count = 0; pv->pe_start = LVM1_PE_ALIGN; @@ -430,6 +436,8 @@ static int _format1_pv_write(const struct format_type *fmt, struct physical_volu dl->mem = mem; dl->dev = pv->dev; + dm_list_init(&dl->uuids); + dm_list_init(&dl->lvds); if (!export_pv(fmt->cmd, mem, NULL, &dl->pvd, pv)) goto_bad; @@ -444,12 +452,18 @@ static int _format1_pv_write(const struct format_type *fmt, struct physical_volu if (!write_disks(fmt, &pvs)) goto_bad; - dm_pool_destroy(mem); - return 1; + goto out; bad: + r = 0; + + out: + pv->pe_size = pe_size; + pv->pe_count = pe_count; + pv->pe_start = pe_start; + dm_pool_destroy(mem); - return 0; + return r; } static int _format1_vg_setup(struct format_instance *fid, struct volume_group *vg) diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c index c065016bd..f1a874d89 100644 --- a/lib/format1/import-export.c +++ b/lib/format1/import-export.c @@ -96,6 +96,8 @@ int import_pv(const struct format_type *fmt, struct dm_pool *mem, pv->pe_count = pvd->pe_total; pv->pe_alloc_count = 0; pv->pe_align = 0; + pv->is_labelled = 0; /* format1 PVs have no label */ + pv->label_sector = 0; /* Fix up pv size if missing or impossibly large */ if (!pv->size || pv->size > (1ULL << 62)) { @@ -149,7 +151,7 @@ int export_pv(struct cmd_context *cmd, struct dm_pool *mem __attribute__((unused memcpy(pvd->pv_uuid, pv->id.uuid, ID_LEN); - if (pv->vg_name && !is_orphan(pv)) { + if (pv->vg_name && !is_orphan(pv) && !(pv->status & UNLABELLED_PV)) { if (!_check_vg_name(pv->vg_name)) return_0; strncpy((char *)pvd->vg_name, pv->vg_name, sizeof(pvd->vg_name)); diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c index 383cae146..9a630aa3b 100644 --- a/lib/format_text/format-text.c +++ b/lib/format_text/format-text.c @@ -45,10 +45,6 @@ struct text_fid_context { uint32_t raw_metadata_buf_size; }; -struct text_fid_pv_context { - int64_t label_sector; -}; - struct dir_list { struct dm_list list; char dir[0]; @@ -1252,11 +1248,9 @@ static int _text_scan(const struct format_type *fmt, const char *vgname) /* Only for orphans */ static int _text_pv_write(const struct format_type *fmt, struct physical_volume *pv) { - struct text_fid_pv_context *fid_pv_tc; struct format_instance *fid = pv->fid; const char *pvid = (const char *) (*pv->old_id.uuid ? &pv->old_id : &pv->id); struct label *label; - int64_t label_sector; struct lvmcache_info *info; struct mda_context *mdac; struct metadata_area *mda; @@ -1271,15 +1265,7 @@ static int _text_pv_write(const struct format_type *fmt, struct physical_volume return_0; label = info->label; - - /* - * We can change the label sector for a - * plain PV that is not part of a VG only! - */ - if (fid && (!fid->type & FMT_INSTANCE_VG) && - (fid_pv_tc = (struct text_fid_pv_context *) pv->fid->private) && - ((label_sector = fid_pv_tc->label_sector) != -1)) - label->sector = label_sector; + label->sector = pv->label_sector; info->device_size = pv->size << SECTOR_SHIFT; info->fmt = fmt; @@ -1517,8 +1503,6 @@ static int _text_pv_initialise(const struct format_type *fmt, unsigned long data_alignment_offset, struct physical_volume *pv) { - struct text_fid_pv_context *fid_pv_tc; - /* * Try to keep the value of PE start set to a firm value if requested. * This is usefull when restoring existing PE start value (backups etc.). @@ -1569,10 +1553,8 @@ static int _text_pv_initialise(const struct format_type *fmt, return 0; } - if (label_sector != -1) { - fid_pv_tc = (struct text_fid_pv_context *) pv->fid->private; - fid_pv_tc->label_sector = label_sector; - } + if (label_sector != -1) + pv->label_sector = label_sector; return 1; } @@ -1735,16 +1717,9 @@ static int _text_pv_setup(const struct format_type *fmt, static int _create_pv_text_instance(struct format_instance *fid, const struct format_instance_ctx *fic) { - struct text_fid_pv_context *fid_pv_tc; struct lvmcache_info *info; - if (!(fid_pv_tc = (struct text_fid_pv_context *) - dm_pool_zalloc(fid->mem, sizeof(*fid_pv_tc)))) { - log_error("Couldn't allocate text_fid_pv_context."); - return 0; - } - fid_pv_tc->label_sector = -1; - fid->private = (void *) fid_pv_tc; + fid->private = NULL; if (!(fid->metadata_areas_index.array = dm_pool_zalloc(fid->mem, FMT_TEXT_MAX_MDAS_PER_PV * @@ -2332,7 +2307,7 @@ static int _get_config_disk_area(struct cmd_context *cmd, return 0; } - if (!(dev_area.dev = device_from_pvid(cmd, &id, NULL))) { + if (!(dev_area.dev = device_from_pvid(cmd, &id, NULL, NULL))) { char buffer[64] __attribute__((aligned(8))); if (!id_write_format(&id, buffer, sizeof(buffer))) diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c index f22ace233..b068a0017 100644 --- a/lib/format_text/import_vsn1.c +++ b/lib/format_text/import_vsn1.c @@ -190,10 +190,13 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem, return 0; } + pv->is_labelled = 1; /* All format_text PVs are labelled. */ + /* * Convert the uuid into a device. */ - if (!(pv->dev = device_from_pvid(fid->fmt->cmd, &pv->id, scan_done_once))) { + if (!(pv->dev = device_from_pvid(fid->fmt->cmd, &pv->id, scan_done_once, + &pv->label_sector))) { char buffer[64] __attribute__((aligned(8))); if (!id_write_format(&pv->id, buffer, sizeof(buffer))) diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c index 756ed6044..d50e6fce1 100644 --- a/lib/metadata/metadata.c +++ b/lib/metadata/metadata.c @@ -38,7 +38,6 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd, struct dm_pool *pvmem, const char *pv_name, struct format_instance *fid, - uint64_t *label_sector, int warnings, int scan_label_only); static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd, @@ -192,6 +191,7 @@ void del_pvl_from_vgs(struct volume_group *vg, struct pv_list *pvl) * @vg - volume group to add to * @pv_name - name of the pv (to be removed) * @pv - physical volume to add to volume group + * @pp - physical volume creation params (OPTIONAL) * * Returns: * 0 - failure @@ -199,8 +199,9 @@ void del_pvl_from_vgs(struct volume_group *vg, struct pv_list *pvl) * FIXME: remove pv_name - obtain safely from pv */ int add_pv_to_vg(struct volume_group *vg, const char *pv_name, - struct physical_volume *pv) + struct physical_volume *pv, struct pvcreate_params *pp) { + struct pv_to_create *pvc; struct pv_list *pvl; struct format_instance *fid = vg->fid; struct dm_pool *mem = vg->vgmem; @@ -289,6 +290,16 @@ int add_pv_to_vg(struct volume_group *vg, const char *pv_name, vg->extent_count += pv->pe_count; vg->free_count += pv->pe_count; + if (pv->status & UNLABELLED_PV) { + if (!(pvc = dm_pool_zalloc(mem, sizeof(*pvc)))) { + log_error("pv_to_create allocation for '%s' failed", pv_name); + return 0; + } + pvc->pv = pv; + pvc->pp = pp; + dm_list_add(&vg->pvs_to_create, &pvc->list); + } + return 1; } @@ -640,11 +651,11 @@ static int vg_extend_single_pv(struct volume_group *vg, char *pv_name, "physical volume", pv_name); return 0; } else if (!pv && pp) { - pv = pvcreate_single(vg->cmd, pv_name, pp); + pv = pvcreate_single(vg->cmd, pv_name, pp, 0); if (!pv) return 0; } - if (!add_pv_to_vg(vg, pv_name, pv)) { + if (!add_pv_to_vg(vg, pv_name, pv, pp)) { free_pv_fid(pv); return 0; } @@ -1318,7 +1329,7 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name, /* FIXME Check partition type is LVM unless --force is given */ /* Is there a pv here already? */ - pv = pv_read(cmd, name, NULL, 0, 0); + pv = pv_read(cmd, name, 0, 0); /* * If a PV has no MDAs it may appear to be an orphan until the @@ -1330,7 +1341,7 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name, free_pv_fid(pv); if (!scan_vgs_for_pvs(cmd, 0)) return_0; - pv = pv_read(cmd, name, NULL, 0, 0); + pv = pv_read(cmd, name, 0, 0); } /* Allow partial & exported VGs to be destroyed. */ @@ -1425,6 +1436,47 @@ void pvcreate_params_set_defaults(struct pvcreate_params *pp) pp->metadataignore = DEFAULT_PVMETADATAIGNORE; } + +static int _pvcreate_write(struct cmd_context *cmd, struct pv_to_create *pvc) +{ + int zero = pvc->pp->zero; + struct physical_volume *pv = pvc->pv; + struct device *dev = pv->dev; + const char *pv_name = dev_name(dev); + + /* Wipe existing label first */ + if (!label_remove(pv_dev(pv))) { + log_error("Failed to wipe existing label on %s", pv_name); + return 0; + } + + if (zero) { + log_verbose("Zeroing start of device %s", pv_name); + if (!dev_open_quiet(dev)) { + log_error("%s not opened: device not zeroed", pv_name); + return 0; + } + + if (!dev_set(dev, UINT64_C(0), (size_t) 2048, 0)) { + log_error("%s not wiped: aborting", pv_name); + dev_close(dev); + return 0; + } + dev_close(dev); + } + + log_error("Writing physical volume data to disk \"%s\"", + pv_name); + + if (!(pv_write(cmd, pv, 1))) { + log_error("Failed to write physical volume \"%s\"", pv_name); + return 0; + } + + log_print("Physical volume \"%s\" successfully created", pv_name); + return 1; +} + /* * pvcreate_single() - initialize a device with PV label and metadata area * @@ -1438,7 +1490,8 @@ void pvcreate_params_set_defaults(struct pvcreate_params *pp) */ struct physical_volume * pvcreate_single(struct cmd_context *cmd, const char *pv_name, - struct pvcreate_params *pp) + struct pvcreate_params *pp, + int write_now) { struct physical_volume *pv = NULL; struct device *dev; @@ -1451,7 +1504,7 @@ struct physical_volume * pvcreate_single(struct cmd_context *cmd, pp = &default_pp; if (pp->idp) { - if ((dev = device_from_pvid(cmd, pp->idp, NULL)) && + if ((dev = device_from_pvid(cmd, pp->idp, NULL, NULL)) && (dev != dev_cache_get(pv_name, cmd->filter))) { if (!id_write_format((const struct id*)&pp->idp->uuid, buffer, sizeof(buffer))) @@ -1475,6 +1528,7 @@ struct physical_volume * pvcreate_single(struct cmd_context *cmd, } dm_list_init(&mdas); + if (!(pv = pv_create(cmd, dev, pp->idp, pp->size, pp->data_alignment, pp->data_alignment_offset, pp->pe_start ? pp->pe_start : PV_PE_START_CALC, @@ -1488,37 +1542,16 @@ struct physical_volume * pvcreate_single(struct cmd_context *cmd, log_verbose("Set up physical volume for \"%s\" with %" PRIu64 " available sectors", pv_name, pv_size(pv)); - /* Wipe existing label first */ - if (!label_remove(pv_dev(pv))) { - log_error("Failed to wipe existing label on %s", pv_name); - goto bad; - } - - if (pp->zero) { - log_verbose("Zeroing start of device %s", pv_name); - if (!dev_open_quiet(dev)) { - log_error("%s not opened: device not zeroed", pv_name); + if (write_now) { + struct pv_to_create pvc; + pvc.pp = pp; + pvc.pv = pv; + if (!_pvcreate_write(cmd, &pvc)) goto bad; - } - - if (!dev_set(dev, UINT64_C(0), (size_t) 2048, 0)) { - log_error("%s not wiped: aborting", pv_name); - dev_close(dev); - goto bad; - } - dev_close(dev); + } else { + pv->status |= UNLABELLED_PV; } - log_very_verbose("Writing physical volume data to disk \"%s\"", - pv_name); - - if (!(pv_write(cmd, pv, 0))) { - log_error("Failed to write physical volume \"%s\"", pv_name); - goto bad; - } - - log_print("Physical volume \"%s\" successfully created", pv_name); - return pv; bad: @@ -1815,7 +1848,7 @@ static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd, { struct physical_volume *pv; - if (!(pv = _pv_read(cmd, cmd->mem, pv_name, NULL, NULL, 1, 0))) { + if (!(pv = _pv_read(cmd, cmd->mem, pv_name, NULL, 1, 0))) { log_error("Physical volume %s not found", pv_name); goto bad; } @@ -1825,7 +1858,7 @@ static struct physical_volume *_find_pv_by_name(struct cmd_context *cmd, if (!scan_vgs_for_pvs(cmd, 1)) goto_bad; free_pv_fid(pv); - if (!(pv = _pv_read(cmd, cmd->mem, pv_name, NULL, NULL, 1, 0))) { + if (!(pv = _pv_read(cmd, cmd->mem, pv_name, NULL, 1, 0))) { log_error("Physical volume %s not found", pv_name); goto bad; } @@ -2470,6 +2503,7 @@ out: int vg_write(struct volume_group *vg) { struct dm_list *mdah; + struct pv_to_create *pv_to_create; struct metadata_area *mda; if (!vg_validate(vg)) @@ -2507,6 +2541,12 @@ int vg_write(struct volume_group *vg) vg->seqno++; + dm_list_iterate_items(pv_to_create, &vg->pvs_to_create) { + if (!_pvcreate_write(vg->cmd, pv_to_create)) + return 0; + pv_to_create->pv->status &= ~UNLABELLED_PV; + } + /* Write to each copy of the metadata area */ dm_list_iterate_items(mda, &vg->fid->metadata_areas_in_use) { if (!mda->ops->vg_write) { @@ -2676,7 +2716,7 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd, dm_list_iterate_items(info, &vginfo->infos) { if (!(pv = _pv_read(cmd, vg->vgmem, dev_name(info->dev), - vg->fid, NULL, warnings, 0))) { + vg->fid, warnings, 0))) { continue; } if (!(pvl = dm_pool_zalloc(vg->vgmem, sizeof(*pvl)))) { @@ -3429,10 +3469,10 @@ const char *find_vgname_from_pvname(struct cmd_context *cmd, * FIXME - liblvm todo - make into function that returns handle */ struct physical_volume *pv_read(struct cmd_context *cmd, const char *pv_name, - uint64_t *label_sector, int warnings, + int warnings, int scan_label_only) { - return _pv_read(cmd, cmd->mem, pv_name, NULL, label_sector, warnings, scan_label_only); + return _pv_read(cmd, cmd->mem, pv_name, NULL, warnings, scan_label_only); } /* FIXME Use label functions instead of PV functions */ @@ -3440,7 +3480,6 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd, struct dm_pool *pvmem, const char *pv_name, struct format_instance *fid, - uint64_t *label_sector, int warnings, int scan_label_only) { struct physical_volume *pv; @@ -3460,8 +3499,6 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd, } info = (struct lvmcache_info *) label->info; - if (label_sector && *label_sector) - *label_sector = label->sector; pv = _alloc_pv(pvmem, dev); if (!pv) { @@ -3469,6 +3506,8 @@ static struct physical_volume *_pv_read(struct cmd_context *cmd, return NULL; } + pv->label_sector = label->sector; + /* FIXME Move more common code up here */ if (!(info->fmt->ops->pv_read(info->fmt, pv_name, pv, scan_label_only))) { log_error("Failed to read existing physical volume '%s'", @@ -4367,5 +4406,5 @@ char *tags_format_and_copy(struct dm_pool *mem, const struct dm_list *tags) */ struct physical_volume *pv_by_path(struct cmd_context *cmd, const char *pv_name) { - return _pv_read(cmd, cmd->mem, pv_name, NULL, NULL, 1, 0); + return _pv_read(cmd, cmd->mem, pv_name, NULL, 1, 0); } diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index 4b298832a..07a32b0db 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -470,7 +470,8 @@ struct id pv_vgid(const struct physical_volume *pv); struct physical_volume *pv_by_path(struct cmd_context *cmd, const char *pv_name); int add_pv_to_vg(struct volume_group *vg, const char *pv_name, - struct physical_volume *pv); + struct physical_volume *pv, struct pvcreate_params *pp); + int is_mirror_image_removable(struct logical_volume *mimage_lv, void *baton); uint64_t find_min_mda_size(struct dm_list *mdas); diff --git a/lib/metadata/pv.h b/lib/metadata/pv.h index af6361034..b80472ad8 100644 --- a/lib/metadata/pv.h +++ b/lib/metadata/pv.h @@ -51,6 +51,12 @@ struct physical_volume { unsigned long pe_align; unsigned long pe_align_offset; + /* This is true whenever the represented PV has a label associated. */ + uint64_t is_labelled:1; + + /* NB. label_sector is valid whenever is_labelled is true */ + uint64_t label_sector; + struct dm_list segments; /* Ordered pv_segments covering complete PV */ struct dm_list tags; }; diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c index 5bd00aeec..af286fc4c 100644 --- a/lib/metadata/vg.c +++ b/lib/metadata/vg.c @@ -43,6 +43,7 @@ struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd, vg->alloc = ALLOC_NORMAL; dm_list_init(&vg->pvs); + dm_list_init(&vg->pvs_to_create); dm_list_init(&vg->lvs); dm_list_init(&vg->tags); dm_list_init(&vg->removed_pvs); diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h index 0f8282480..bebe6cffa 100644 --- a/lib/metadata/vg.h +++ b/lib/metadata/vg.h @@ -31,6 +31,12 @@ typedef enum { ALLOC_INHERIT } alloc_policy_t; +struct pv_to_create { + struct dm_list list; + struct physical_volume *pv; + struct pvcreate_params *pp; +}; + struct volume_group { struct cmd_context *cmd; struct dm_pool *vgmem; @@ -58,6 +64,13 @@ struct volume_group { uint32_t pv_count; struct dm_list pvs; + /* + * List of physical volumes that were used in vgextend but do not carry + * a PV label yet. They need to be pvcreate'd at vg_write time. + */ + + struct dm_list pvs_to_create; + /* * logical volumes * The following relationship should always hold: diff --git a/tools/pvcreate.c b/tools/pvcreate.c index 90fd2b4c4..0108d775e 100644 --- a/tools/pvcreate.c +++ b/tools/pvcreate.c @@ -112,7 +112,7 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv) unescape_colons_and_at_signs(argv[i], NULL, NULL); - if (!(pv = pvcreate_single(cmd, argv[i], &pp))) { + if (!(pv = pvcreate_single(cmd, argv[i], &pp, 1))) { stack; ret = ECMD_FAILED; } diff --git a/tools/pvremove.c b/tools/pvremove.c index 060303eee..5a2a43e00 100644 --- a/tools/pvremove.c +++ b/tools/pvremove.c @@ -30,7 +30,7 @@ static int pvremove_check(struct cmd_context *cmd, const char *name) /* Is there a pv here already? */ /* If not, this is an error unless you used -f. */ - if (!(pv = pv_read(cmd, name, NULL, 1, 0))) { + if (!(pv = pv_read(cmd, name, 1, 0))) { if (arg_count(cmd, force_ARG)) return 1; log_error("Physical Volume %s not found", name); @@ -52,7 +52,7 @@ static int pvremove_check(struct cmd_context *cmd, const char *name) goto bad; } free_pv_fid(pv); - if (!(pv = pv_read(cmd, name, NULL, 1, 0))) { + if (!(pv = pv_read(cmd, name, 1, 0))) { log_error("Failed to read physical volume %s", name); goto bad; } diff --git a/tools/pvresize.c b/tools/pvresize.c index b12fcbcce..1c80c942f 100644 --- a/tools/pvresize.c +++ b/tools/pvresize.c @@ -43,7 +43,7 @@ static int _pv_resize_single(struct cmd_context *cmd, return 0; } - if (!(pv = pv_read(cmd, pv_name, NULL, 1, 0))) { + if (!(pv = pv_read(cmd, pv_name, 1, 0))) { unlock_vg(cmd, vg_name); log_error("Unable to read PV \"%s\"", pv_name); return 0; diff --git a/tools/toollib.c b/tools/toollib.c index e839d44b2..2aa5506eb 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -651,7 +651,7 @@ static int _process_all_devs(struct cmd_context *cmd, void *handle, } while ((dev = dev_iter_get(iter))) { - if (!(pv = pv_read(cmd, dev_name(dev), NULL, 0, 0))) { + if (!(pv = pv_read(cmd, dev_name(dev), 0, 0))) { memset(&pv_dummy, 0, sizeof(pv_dummy)); dm_list_init(&pv_dummy.tags); dm_list_init(&pv_dummy.segments); @@ -737,7 +737,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, } pv = pvl->pv; } else { - if (!(pv = pv_read(cmd, argv[opt], NULL, + if (!(pv = pv_read(cmd, argv[opt], 1, scan_label_only))) { log_error("Failed to read physical " "volume \"%s\"", argv[opt]); @@ -764,7 +764,7 @@ int process_each_pv(struct cmd_context *cmd, int argc, char **argv, scanned = 1; free_pv_fid(pv); if (!(pv = pv_read(cmd, argv[opt], - NULL, 1, + 1, scan_label_only))) { log_error("Failed to read " "physical volume "