summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Asleson <tasleson@redhat.com>2013-09-03 17:31:45 -0500
committerTony Asleson <tasleson@redhat.com>2013-11-19 14:40:28 -0600
commitfe474e1452866476b7f17175d92417d6d827ae4c (patch)
treea46360191357af6758d4f518f52fe3dfb954247b
parent20ffb0f721e72fb25905e9ae77689e901babf4ce (diff)
downloadlvm2-fe474e1452866476b7f17175d92417d6d827ae4c.tar.gz
vgreduce: Move _vgreduce_single functionality
Moving the core functionality of vgreduce single into lib/metadata/vg.c so that the command line and lvm2app library can call the same core functionality. New function is vgreduce_single. Signed-off-by: Tony Asleson <tasleson@redhat.com>
-rw-r--r--lib/metadata/metadata-exported.h4
-rw-r--r--lib/metadata/vg.c87
-rw-r--r--tools/vgreduce.c81
3 files changed, 95 insertions, 77 deletions
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 1bf5236e0..cac5b3cfd 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -592,6 +592,10 @@ int vg_rename(struct cmd_context *cmd, struct volume_group *vg,
int vg_extend(struct volume_group *vg, int pv_count, const char *const *pv_names,
struct pvcreate_params *pp);
int vg_reduce(struct volume_group *vg, const char *pv_name);
+
+int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
+ struct physical_volume *pv);
+
int vg_change_tag(struct volume_group *vg, const char *tag, int add_tag);
int vg_split_mdas(struct cmd_context *cmd, struct volume_group *vg_from,
struct volume_group *vg_to);
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 476292e25..20b4b4df4 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -19,6 +19,7 @@
#include "activate.h"
#include "toolcontext.h"
#include "lvmcache.h"
+#include "archiver.h"
struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
const char *vg_name)
@@ -573,3 +574,89 @@ char *vg_attr_dup(struct dm_pool *mem, const struct volume_group *vg)
repstr[5] = (vg_is_clustered(vg)) ? 'c' : '-';
return repstr;
}
+
+int vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
+ struct physical_volume *pv)
+{
+ struct pv_list *pvl;
+ struct volume_group *orphan_vg = NULL;
+ int r = 0;
+ const char *name = pv_dev_name(pv);
+
+ if (!vg) {
+ log_error(INTERNAL_ERROR "VG is NULL.");
+ return r;
+ }
+
+ if (pv_pe_alloc_count(pv)) {
+ log_error("Physical volume \"%s\" still in use", name);
+ return r;
+ }
+
+ if (vg->pv_count == 1) {
+ log_error("Can't remove final physical volume \"%s\" from "
+ "volume group \"%s\"", name, vg->name);
+ return r;
+ }
+
+ if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
+ log_error("Can't get lock for orphan PVs");
+ return r;
+ }
+
+ pvl = find_pv_in_vg(vg, name);
+
+ if (!archive(vg))
+ goto_bad;
+
+ log_verbose("Removing \"%s\" from volume group \"%s\"", name, vg->name);
+
+ if (pvl)
+ del_pvl_from_vgs(vg, pvl);
+
+ pv->vg_name = vg->fid->fmt->orphan_vg_name;
+ pv->status = ALLOCATABLE_PV;
+
+ if (!dev_get_size(pv_dev(pv), &pv->size)) {
+ log_error("%s: Couldn't get size.", pv_dev_name(pv));
+ goto bad;
+ }
+
+ vg->free_count -= pv_pe_count(pv) - pv_pe_alloc_count(pv);
+ vg->extent_count -= pv_pe_count(pv);
+
+ orphan_vg = vg_read_for_update(cmd, vg->fid->fmt->orphan_vg_name,
+ NULL, 0);
+
+ if (vg_read_error(orphan_vg))
+ goto bad;
+
+ 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);
+ goto bad;
+ }
+
+ if (!vg_write(vg) || !vg_commit(vg)) {
+ log_error("Removal of physical volume \"%s\" from "
+ "\"%s\" failed", name, vg->name);
+ goto bad;
+ }
+
+ if (!pv_write(cmd, pv, 0)) {
+ log_error("Failed to clear metadata from physical "
+ "volume \"%s\" "
+ "after removal from \"%s\"", name, vg->name);
+ goto bad;
+ }
+
+ backup(vg);
+
+ log_print_unless_silent("Removed \"%s\" from volume group \"%s\"", name, vg->name);
+ r = 1;
+bad:
+ if (pvl)
+ free_pv_fid(pvl->pv);
+ unlock_and_release_vg(cmd, orphan_vg, VG_ORPHANS);
+ return r;
+}
diff --git a/tools/vgreduce.c b/tools/vgreduce.c
index 880389933..534a4fbbb 100644
--- a/tools/vgreduce.c
+++ b/tools/vgreduce.c
@@ -125,88 +125,15 @@ static int _vgreduce_single(struct cmd_context *cmd, struct volume_group *vg,
struct physical_volume *pv,
void *handle __attribute__((unused)))
{
- struct pv_list *pvl;
- struct volume_group *orphan_vg = NULL;
- int r = ECMD_FAILED;
- const char *name = pv_dev_name(pv);
-
- if (!vg) {
- log_error(INTERNAL_ERROR "VG is NULL.");
- return ECMD_FAILED;
- }
+ int r = vgreduce_single(cmd, vg, pv);
- if (pv_pe_alloc_count(pv)) {
- log_error("Physical volume \"%s\" still in use", name);
- return ECMD_FAILED;
- }
-
- if (vg->pv_count == 1) {
- log_error("Can't remove final physical volume \"%s\" from "
- "volume group \"%s\"", name, vg->name);
+ if (!r)
return ECMD_FAILED;
- }
-
- if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
- log_error("Can't get lock for orphan PVs");
- return ECMD_FAILED;
- }
-
- pvl = find_pv_in_vg(vg, name);
-
- if (!archive(vg))
- goto_bad;
-
- log_verbose("Removing \"%s\" from volume group \"%s\"", name, vg->name);
- if (pvl)
- del_pvl_from_vgs(vg, pvl);
-
- pv->vg_name = vg->fid->fmt->orphan_vg_name;
- pv->status = ALLOCATABLE_PV;
-
- if (!dev_get_size(pv_dev(pv), &pv->size)) {
- log_error("%s: Couldn't get size.", pv_dev_name(pv));
- goto bad;
- }
-
- vg->free_count -= pv_pe_count(pv) - pv_pe_alloc_count(pv);
- vg->extent_count -= pv_pe_count(pv);
-
- orphan_vg = vg_read_for_update(cmd, vg->fid->fmt->orphan_vg_name,
- NULL, 0);
-
- if (vg_read_error(orphan_vg))
- goto bad;
-
- 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);
- goto bad;
- }
-
- if (!vg_write(vg) || !vg_commit(vg)) {
- log_error("Removal of physical volume \"%s\" from "
- "\"%s\" failed", name, vg->name);
- goto bad;
- }
-
- if (!pv_write(cmd, pv, 0)) {
- log_error("Failed to clear metadata from physical "
- "volume \"%s\" "
- "after removal from \"%s\"", name, vg->name);
- goto bad;
- }
+ return ECMD_PROCESSED;
+}
- backup(vg);
- log_print_unless_silent("Removed \"%s\" from volume group \"%s\"", name, vg->name);
- r = ECMD_PROCESSED;
-bad:
- if (pvl)
- free_pv_fid(pvl->pv);
- unlock_and_release_vg(cmd, orphan_vg, VG_ORPHANS);
- return r;
-}
int vgreduce(struct cmd_context *cmd, int argc, char **argv)
{