1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-10-28 03:27:58 +03:00

Add "flags" metadata field (akin to "status") for backward-compatible flags.

The "status" field is treated as it ever has been, unknown flags there are
treated as fatal metadata errors. However, in the "flags" field, any unknown
flags will be ignored and silently dropped. This improves
backward-compatibility possibilities. (Any versions without support for this
new "flag" field will drop the field altogether, which is same as ignoring all
the flags there.)
This commit is contained in:
Petr Rockai 2008-07-10 11:30:57 +00:00
parent 367a0ac052
commit bc437feded
5 changed files with 88 additions and 66 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.40 -
================================
Add "flags" metadata field (akin to "status") for backward-compatible flags.
Fix dmeventd monitoring libraries to link against liblvm2cmd again. (2.02.39)
Version 2.02.39 - 27th June 2008

View File

@ -321,6 +321,20 @@ static int _print_header(struct formatter *f,
return 1;
}
static int _print_flag_config(struct formatter *f, int status, int type)
{
char buffer[4096];
if (!print_flags(status, type | STATUS_FLAG, buffer, sizeof(buffer)))
return_0;
outf(f, "status = %s", buffer);
if (!print_flags(status, type, buffer, sizeof(buffer)))
return_0;
outf(f, "flags = %s", buffer);
return 1;
}
static int _print_vg(struct formatter *f, struct volume_group *vg)
{
char buffer[4096];
@ -332,9 +346,8 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
outf(f, "seqno = %u", vg->seqno);
if (!print_flags(vg->status, VG_FLAGS, buffer, sizeof(buffer)))
if (!_print_flag_config(f, vg->status, VG_FLAGS))
return_0;
outf(f, "status = %s", buffer);
if (!list_empty(&vg->tags)) {
if (!print_tags(&vg->tags, buffer, sizeof(buffer)))
@ -408,9 +421,8 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
return_0;
outnl(f);
if (!print_flags(pv->status, PV_FLAGS, buffer, sizeof(buffer)))
if (!_print_flag_config(f, pv->status, PV_FLAGS))
return_0;
outf(f, "status = %s", buffer);
if (!list_empty(&pv->tags)) {
if (!print_tags(&pv->tags, buffer, sizeof(buffer)))
@ -520,9 +532,8 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
outf(f, "id = \"%s\"", buffer);
if (!print_flags(lv->status, LV_FLAGS, buffer, sizeof(buffer)))
if (!_print_flag_config(f, lv->status, LV_FLAGS))
return_0;
outf(f, "status = %s", buffer);
if (!list_empty(&lv->tags)) {
if (!print_tags(&lv->tags, buffer, sizeof(buffer)))

View File

@ -25,48 +25,49 @@
struct flag {
const int mask;
const char *description;
int kind;
};
static struct flag _vg_flags[] = {
{EXPORTED_VG, "EXPORTED"},
{RESIZEABLE_VG, "RESIZEABLE"},
{PARTIAL_VG, "PARTIAL"},
{PVMOVE, "PVMOVE"},
{LVM_READ, "READ"},
{LVM_WRITE, "WRITE"},
{CLUSTERED, "CLUSTERED"},
{SHARED, "SHARED"},
{PRECOMMITTED, NULL},
{0, NULL}
{EXPORTED_VG, "EXPORTED", STATUS_FLAG},
{RESIZEABLE_VG, "RESIZEABLE", STATUS_FLAG},
{PARTIAL_VG, "PARTIAL", STATUS_FLAG},
{PVMOVE, "PVMOVE", STATUS_FLAG},
{LVM_READ, "READ", STATUS_FLAG},
{LVM_WRITE, "WRITE", STATUS_FLAG},
{CLUSTERED, "CLUSTERED", STATUS_FLAG},
{SHARED, "SHARED", STATUS_FLAG},
{PRECOMMITTED, NULL, 0},
{0, NULL, 0}
};
static struct flag _pv_flags[] = {
{ALLOCATABLE_PV, "ALLOCATABLE"},
{EXPORTED_VG, "EXPORTED"},
{0, NULL}
{ALLOCATABLE_PV, "ALLOCATABLE", STATUS_FLAG},
{EXPORTED_VG, "EXPORTED", STATUS_FLAG},
{0, NULL, 0}
};
static struct flag _lv_flags[] = {
{LVM_READ, "READ"},
{LVM_WRITE, "WRITE"},
{FIXED_MINOR, "FIXED_MINOR"},
{VISIBLE_LV, "VISIBLE"},
{PVMOVE, "PVMOVE"},
{LOCKED, "LOCKED"},
{MIRROR_NOTSYNCED, "NOTSYNCED"},
{MIRROR_IMAGE, NULL},
{MIRROR_LOG, NULL},
{MIRRORED, NULL},
{VIRTUAL, NULL},
{SNAPSHOT, NULL},
{ACTIVATE_EXCL, NULL},
{CONVERTING, NULL},
{0, NULL}
{LVM_READ, "READ", STATUS_FLAG},
{LVM_WRITE, "WRITE", STATUS_FLAG},
{FIXED_MINOR, "FIXED_MINOR", STATUS_FLAG},
{VISIBLE_LV, "VISIBLE", STATUS_FLAG},
{PVMOVE, "PVMOVE", STATUS_FLAG},
{LOCKED, "LOCKED", STATUS_FLAG},
{MIRROR_NOTSYNCED, "NOTSYNCED", STATUS_FLAG},
{MIRROR_IMAGE, NULL, 0},
{MIRROR_LOG, NULL, 0},
{MIRRORED, NULL, 0},
{VIRTUAL, NULL, 0},
{SNAPSHOT, NULL, 0},
{ACTIVATE_EXCL, NULL, 0},
{CONVERTING, NULL, 0},
{0, NULL, 0}
};
static struct flag *_get_flags(int type)
{
switch (type) {
switch (type & ~STATUS_FLAG) {
case VG_FLAGS:
return _vg_flags;
@ -101,6 +102,9 @@ int print_flags(uint32_t status, int type, char *buffer, size_t size)
if (status & flags[f].mask) {
status &= ~flags[f].mask;
if ((type & STATUS_FLAG) != flags[f].kind)
continue;
/* Internal-only flag? */
if (!flags[f].description)
continue;
@ -151,7 +155,7 @@ int read_flags(uint32_t *status, int type, struct config_value *cv)
break;
}
if (!flags[f].description) {
if (!flags[f].description && (type & STATUS_FLAG)) {
log_err("Unknown status flag '%s'.", cv->v.str);
return 0;
}
@ -160,6 +164,6 @@ int read_flags(uint32_t *status, int type, struct config_value *cv)
}
out:
*status = s;
*status |= s;
return 1;
}

View File

@ -36,9 +36,11 @@
* common code for reading and writing them.
*/
enum {
COMPATIBLE_FLAG = 0x0,
VG_FLAGS,
PV_FLAGS,
LV_FLAGS
LV_FLAGS,
STATUS_FLAG = 0x8,
};
struct text_vg_version_ops {

View File

@ -125,6 +125,31 @@ static int _read_id(struct id *id, struct config_node *cn, const char *path)
return 1;
}
static int _read_flag_config(struct config_node *n, int *status, int type)
{
struct config_node *cn;
*status = 0;
if (!(cn = find_config_node(n, "status"))) {
log_error("Could not find status flags.");
return 0;
}
if (!(read_flags(status, type | STATUS_FLAG, cn->v))) {
log_error("Could not read status flags.");
return 0;
}
if (cn = find_config_node(n, "flags")) {
if (!(read_flags(status, type, cn->v))) {
log_error("Could not read flags.");
return 0;
}
}
return 1;
}
static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
struct volume_group *vg, struct config_node *pvn,
struct config_node *vgn __attribute((unused)),
@ -181,12 +206,7 @@ static int _read_pv(struct format_instance *fid, struct dm_pool *mem,
memcpy(&pv->vgid, &vg->id, sizeof(vg->id));
if (!(cn = find_config_node(pvn, "status"))) {
log_error("Couldn't find status flags for physical volume.");
return 0;
}
if (!(read_flags(&pv->status, PV_FLAGS, cn->v))) {
if (!_read_flag_config(pvn, &pv->status, PV_FLAGS)) {
log_error("Couldn't read status flags for physical volume.");
return 0;
}
@ -493,13 +513,9 @@ static int _read_lvnames(struct format_instance *fid __attribute((unused)),
return 0;
}
if (!(cn = find_config_node(lvn, "status"))) {
log_error("Couldn't find status flags for logical volume.");
return 0;
}
if (!(read_flags(&lv->status, LV_FLAGS, cn->v))) {
log_error("Couldn't read status flags for logical volume.");
if (!_read_flag_config(lvn, &lv->status, LV_FLAGS)) {
log_error("Couldn't read status flags for logical volume %s.",
lv->name);
return 0;
}
@ -692,14 +708,8 @@ static struct volume_group *_read_vg(struct format_instance *fid,
goto bad;
}
if (!(cn = find_config_node(vgn, "status"))) {
log_error("Couldn't find status flags for volume group %s.",
vg->name);
goto bad;
}
if (!(read_flags(&vg->status, VG_FLAGS, cn->v))) {
log_error("Couldn't read status flags for volume group %s.",
if (!_read_flag_config(vgn, &vg->status, VG_FLAGS)) {
log_error("Error reading flags of volume group %s.",
vg->name);
goto bad;
}
@ -855,18 +865,12 @@ static const char *_read_vgname(const struct format_type *fmt,
return 0;
}
if (!(cn = find_config_node(vgn, "status"))) {
if (!_read_flag_config(vgn, vgstatus, VG_FLAGS)) {
log_error("Couldn't find status flags for volume group %s.",
vgname);
return 0;
}
if (!(read_flags(vgstatus, VG_FLAGS, cn->v))) {
log_error("Couldn't read status flags for volume group %s.",
vgname);
return 0;
}
return vgname;
}