summaryrefslogtreecommitdiffstats
path: root/liblvm
diff options
context:
space:
mode:
authorDave Wysochanski <dwysocha@redhat.com>2009-07-27 17:44:29 +0000
committerDave Wysochanski <dwysocha@redhat.com>2009-07-27 17:44:29 +0000
commitdfe213f8049b941ff1d5894c4b518198de8fdf40 (patch)
tree08b0e49fb09b01d969caa30d015422c86b48d1b3 /liblvm
parent1bd72d90a4e9dac6c96618a4a69ce8c5d7fd0b02 (diff)
downloadlvm2-dfe213f8049b941ff1d5894c4b518198de8fdf40.tar.gz
lvm2-dfe213f8049b941ff1d5894c4b518198de8fdf40.tar.xz
lvm2-dfe213f8049b941ff1d5894c4b518198de8fdf40.zip
Add lvm_vg_reduce to liblvm2app
Extend lvm_vg_write to remove pvs removed in lvm_vg_reduce. The lvm volume_group internal structure removed_pvs is used for that. The list is empty afterwards. Add new test for vg->pvs emptyness to lvm_vg_write to prevent to write empty vgs. This is needed because of lvm_vg_reduce and lv_vg_create, which creates empty vgs. Signed-off-by: Thomas Woerner <twoerner@redhat.com> Acked-by: Dave Wysochanski <dwysocha@redhat.com> Author: Dave Wysochanski <dwysocha@redhat.com>
Diffstat (limited to 'liblvm')
-rw-r--r--liblvm/.exported_symbols1
-rw-r--r--liblvm/lvm.h18
-rw-r--r--liblvm/lvm_vg.c35
3 files changed, 54 insertions, 0 deletions
diff --git a/liblvm/.exported_symbols b/liblvm/.exported_symbols
index 99114230..68edb870 100644
--- a/liblvm/.exported_symbols
+++ b/liblvm/.exported_symbols
@@ -21,6 +21,7 @@ lvm_lv_is_active
lvm_lv_is_suspended
lvm_vg_create
lvm_vg_extend
+lvm_vg_reduce
lvm_vg_set_extent_size
lvm_vg_write
lvm_vg_open
diff --git a/liblvm/lvm.h b/liblvm/lvm.h
index 73ba6d94..1247d44b 100644
--- a/liblvm/lvm.h
+++ b/liblvm/lvm.h
@@ -331,6 +331,24 @@ int lvm_vg_close(vg_t *vg);
int lvm_vg_extend(vg_t *vg, const char *device);
/**
+ * Reduce a VG by removing an unused device.
+ *
+ * This API requires calling lvm_vg_write to commit the change to disk.
+ * After successfully removing a device, use lvm_vg_write to commit the new VG
+ * to disk. Upon failure, retry the operation or release the VG handle with
+ * lvm_vg_close.
+ *
+ * \param vg
+ * VG handle obtained from lvm_vg_create or lvm_vg_open.
+ *
+ * \param device
+ * Name of device to remove from VG.
+ *
+ * \return 0 (success) or -1 (failure).
+ */
+int lvm_vg_reduce(vg_t *vg, const char *device);
+
+/**
* Set the extent size of a VG.
*
* This API requires calling lvm_vg_write to commit the change to disk.
diff --git a/liblvm/lvm_vg.c b/liblvm/lvm_vg.c
index cd2ef46c..b83e31c9 100644
--- a/liblvm/lvm_vg.c
+++ b/liblvm/lvm_vg.c
@@ -68,6 +68,16 @@ int lvm_vg_extend(vg_t *vg, const char *device)
return 0;
}
+int lvm_vg_reduce(vg_t *vg, const char *device)
+{
+ if (vg_read_error(vg))
+ return -1;
+
+ if (!vg_reduce(vg, (char *)device))
+ return -1;
+ return 0;
+}
+
int lvm_vg_set_extent_size(vg_t *vg, uint32_t new_size)
{
if (vg_read_error(vg))
@@ -80,15 +90,40 @@ int lvm_vg_set_extent_size(vg_t *vg, uint32_t new_size)
int lvm_vg_write(vg_t *vg)
{
+ struct pv_list *pvl;
+
if (vg_read_error(vg))
return -1;
+ if (dm_list_empty(&vg->pvs)) {
+ log_error("Volume group %s does not contain any "
+ "physical volumes.\n", vg->name);
+ return -1;
+ }
+
+ if (! dm_list_empty(&vg->removed_pvs)) {
+ if (!lock_vol(vg->cmd, VG_ORPHANS, LCK_VG_WRITE)) {
+ log_error("Can't get lock for orphan PVs");
+ return 0;
+ }
+ }
+
if (!archive(vg))
return -1;
/* Store VG on disk(s) */
if (!vg_write(vg) || !vg_commit(vg))
return -1;
+
+ if (! dm_list_empty(&vg->removed_pvs)) {
+ dm_list_iterate_items(pvl, &vg->removed_pvs) {
+ pv_write_orphan(vg->cmd, pvl->pv);
+ /* FIXME: do pvremove / label_remove()? */
+ }
+ dm_list_init(&vg->removed_pvs);
+ unlock_vg(vg->cmd, VG_ORPHANS);
+ }
+
return 0;
}