summaryrefslogtreecommitdiffstats
path: root/tools/vgreduce.c
diff options
context:
space:
mode:
authorAlasdair Kergon <agk@redhat.com>2008-04-08 12:49:21 +0000
committerAlasdair Kergon <agk@redhat.com>2008-04-08 12:49:21 +0000
commit6eb44b50913ae83449fef735dd9f356de2cb710a (patch)
tree4344136298268095e8e8c729c43fceb8f28a7440 /tools/vgreduce.c
parentad607a23f16ceda1824ed12462ccc557c85085e5 (diff)
downloadlvm2-6eb44b50913ae83449fef735dd9f356de2cb710a.tar.gz
lvm2-6eb44b50913ae83449fef735dd9f356de2cb710a.tar.xz
lvm2-6eb44b50913ae83449fef735dd9f356de2cb710a.zip
Fix vgreduce to use vg_split_mdas to check sufficient mdas remain.
Add (empty) orphan VGs to lvmcache during initialisation. Fix orphan VG name used for format_pool.
Diffstat (limited to 'tools/vgreduce.c')
-rw-r--r--tools/vgreduce.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/tools/vgreduce.c b/tools/vgreduce.c
index ccda5d96..5e613824 100644
--- a/tools/vgreduce.c
+++ b/tools/vgreduce.c
@@ -353,6 +353,8 @@ static int _vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
void *handle __attribute((unused)))
{
struct pv_list *pvl;
+ struct volume_group *orphan_vg;
+ int consistent = 1;
const char *name = pv_dev_name(pv);
if (pv_pe_alloc_count(pv)) {
@@ -366,10 +368,17 @@ static int _vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
return ECMD_FAILED;
}
+ if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE | LCK_NONBLOCK)) {
+ log_error("Can't get lock for orphan PVs");
+ return ECMD_FAILED;
+ }
+
pvl = find_pv_in_vg(vg, name);
- if (!archive(vg))
+ if (!archive(vg)) {
+ unlock_vg(cmd, VG_ORPHANS);
return ECMD_FAILED;
+ }
log_verbose("Removing \"%s\" from volume group \"%s\"", name, vg->name);
@@ -381,6 +390,7 @@ static int _vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
if (!dev_get_size(pv_dev(pv), &pv->size)) {
log_error("%s: Couldn't get size.", pv_dev_name(pv));
+ unlock_vg(cmd, VG_ORPHANS);
return ECMD_FAILED;
}
@@ -388,9 +398,24 @@ static int _vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
vg->free_count -= pv_pe_count(pv) - pv_pe_alloc_count(pv);
vg->extent_count -= pv_pe_count(pv);
+ if(!(orphan_vg = vg_read(cmd, vg->fid->fmt->orphan_vg_name, NULL, &consistent)) ||
+ !consistent) {
+ log_error("Unable to read existing orphan PVs");
+ unlock_vg(cmd, VG_ORPHANS);
+ return ECMD_FAILED;
+ }
+
+ if (!vg_split_mdas(cmd, vg, orphan_vg) || !vg->pv_count) {
+ log_error("Cannot remove final metadata area on \"%s\" from \"%s\"",
+ name, vg->name);
+ unlock_vg(cmd, VG_ORPHANS);
+ return ECMD_FAILED;
+ }
+
if (!vg_write(vg) || !vg_commit(vg)) {
log_error("Removal of physical volume \"%s\" from "
"\"%s\" failed", name, vg->name);
+ unlock_vg(cmd, VG_ORPHANS);
return ECMD_FAILED;
}
@@ -398,9 +423,11 @@ static int _vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
log_error("Failed to clear metadata from physical "
"volume \"%s\" "
"after removal from \"%s\"", name, vg->name);
+ unlock_vg(cmd, VG_ORPHANS);
return ECMD_FAILED;
}
+ unlock_vg(cmd, VG_ORPHANS);
backup(vg);
log_print("Removed \"%s\" from volume group \"%s\"", name, vg->name);