[lvm-devel] [PATCH] Add an open_mode to the vg struct for liblvm - enforce read / write semantics.
Dave Wysochanski
dwysocha at redhat.com
Tue Jul 28 15:03:13 UTC 2009
For now, a simple way to enforce the read/write semantics is to just save the
open mode of the VG. If the caller uses lvm_vg_create, the mode is write.
The caller using lvm_vg_open can use either read or write to open the VG.
Once we have this, we enforce the permissions on each API call and don't allow
a caller to modify a VG that has not been opened properly.
This may be better combined with the locking mode, but I view that as future
cleanup, past this initial release. The intial release should enforce the
basic object semantics though, as described in the lvm.h file.
Signed-off-by: Dave Wysochanski <dwysocha at redhat.com>
---
lib/metadata/metadata-exported.h | 2 ++
lib/metadata/metadata.c | 10 ++++++++++
liblvm/lvm_lv.c | 5 ++++-
liblvm/lvm_vg.c | 14 ++++++++++++++
4 files changed, 30 insertions(+), 1 deletions(-)
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 0ed48e3..bd207da 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -247,6 +247,7 @@ struct volume_group {
* They have to get cleared on vg_commit.
*/
struct dm_list removed_pvs;
+ uint32_t open_mode; /* FIXME: read or write - check lock type? */
/*
* Store result of the last vg_read().
@@ -713,6 +714,7 @@ uint64_t vg_extent_size(const vg_t *vg);
uint64_t vg_extent_count(const vg_t *vg);
uint64_t vg_free_count(const vg_t *vg);
uint64_t vg_pv_count(const vg_t *vg);
+int vg_check_write_mode(vg_t *vg);
#define vg_is_clustered(vg) (vg_status((vg)) & CLUSTERED)
struct vgcreate_params {
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index d25ad68..75e4495 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3042,6 +3042,16 @@ int pv_analyze(struct cmd_context *cmd, const char *pv_name,
return 1;
}
+/* FIXME: remove / combine this with locking? */
+int vg_check_write_mode(vg_t *vg)
+{
+ if (vg->open_mode != 'w') {
+ log_errno(EPERM, "Attempt to modify a read-only VG\n");
+ return 0;
+ }
+ return 1;
+}
+
/*
* Performs a set of checks against a VG according to bits set in status
* and returns FAILED_* bits for those that aren't acceptable.
diff --git a/liblvm/lvm_lv.c b/liblvm/lvm_lv.c
index 188b9b4..46b0360 100644
--- a/liblvm/lvm_lv.c
+++ b/liblvm/lvm_lv.c
@@ -107,9 +107,10 @@ lv_t *lvm_vg_create_lv_linear(vg_t *vg, const char *name, uint64_t size)
uint64_t extents;
struct lv_list *lvl;
- /* FIXME: check for proper VG access */
if (vg_read_error(vg))
return NULL;
+ if (!vg_check_write_mode(vg))
+ return NULL;
memset(&lp, 0, sizeof(lp));
extents = extents_from_size(vg->cmd, size, vg->extent_size);
_lv_set_default_params(&lp, vg, name, extents);
@@ -130,6 +131,8 @@ int lvm_vg_remove_lv(lv_t *lv)
{
if (!lv || !lv->vg || vg_read_error(lv->vg))
return -1;
+ if (!vg_check_write_mode(lv->vg))
+ return -1;
if (!lv_remove_single(lv->vg->cmd, lv, DONT_PROMPT))
return -1;
return 0;
diff --git a/liblvm/lvm_vg.c b/liblvm/lvm_vg.c
index bd04d81..048cae9 100644
--- a/liblvm/lvm_vg.c
+++ b/liblvm/lvm_vg.c
@@ -35,6 +35,7 @@ vg_t *lvm_vg_create(lvm_t libh, const char *vg_name)
vg_release(vg);
return NULL;
}
+ vg->open_mode = 'w';
return vg;
}
@@ -43,6 +44,9 @@ int lvm_vg_extend(vg_t *vg, const char *device)
if (vg_read_error(vg))
return -1;
+ if (!vg_check_write_mode(vg))
+ return -1;
+
if (!lock_vol(vg->cmd, VG_ORPHANS, LCK_VG_WRITE)) {
log_error("Can't get lock for orphan PVs");
return -1;
@@ -72,6 +76,8 @@ int lvm_vg_reduce(vg_t *vg, const char *device)
{
if (vg_read_error(vg))
return -1;
+ if (!vg_check_write_mode(vg))
+ return -1;
if (!vg_reduce(vg, (char *)device))
return -1;
@@ -82,6 +88,8 @@ int lvm_vg_set_extent_size(vg_t *vg, uint32_t new_size)
{
if (vg_read_error(vg))
return -1;
+ if (!vg_check_write_mode(vg))
+ return -1;
if (!vg_set_extent_size(vg, new_size))
return -1;
@@ -94,6 +102,8 @@ int lvm_vg_write(vg_t *vg)
if (vg_read_error(vg))
return -1;
+ if (!vg_check_write_mode(vg))
+ return -1;
if (dm_list_empty(&vg->pvs)) {
log_error("Volume group %s does not contain any "
@@ -140,6 +150,8 @@ int lvm_vg_remove(vg_t *vg)
{
if (vg_read_error(vg))
return -1;
+ if (!vg_check_write_mode(vg))
+ return -1;
if (!vg_remove_single(vg))
return -1;
@@ -165,6 +177,8 @@ vg_t *lvm_vg_open(lvm_t libh, const char *vgname, const char *mode,
vg_release(vg);
return NULL;
}
+ /* FIXME: combine this with locking ? */
+ vg->open_mode = mode[0];
return vg;
}
--
1.6.0.6
More information about the lvm-devel
mailing list