diff options
author | Petr Rockai <prockai@redhat.com> | 2011-07-25 15:51:51 +0000 |
---|---|---|
committer | Petr Rockai <prockai@redhat.com> | 2011-07-25 15:51:51 +0000 |
commit | 059ee25951458128a119581c62703d83961b6097 (patch) | |
tree | 5c5be96310332678c5e96ad6cec77d7bc66ae975 /daemons/lvmetad/lvmetad-core.c | |
parent | 9474992482a23f03dab183d16a483a2124f25195 (diff) | |
download | lvm2-059ee25951458128a119581c62703d83961b6097.tar.gz lvm2-059ee25951458128a119581c62703d83961b6097.tar.xz lvm2-059ee25951458128a119581c62703d83961b6097.zip |
lvmetad: Check integrity of multiple metadata copies, i.e. ensure that seqno
equality implies metadata equality. Signal error in response to any update
requests that try to overwrite metadata without providing a higher seqno.
Diffstat (limited to 'daemons/lvmetad/lvmetad-core.c')
-rw-r--r-- | daemons/lvmetad/lvmetad-core.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c index 04f517dd..4dfb0a27 100644 --- a/daemons/lvmetad/lvmetad-core.c +++ b/daemons/lvmetad/lvmetad-core.c @@ -96,6 +96,54 @@ static response vg_by_uuid(lvmetad_state *s, request r) } /* + * TODO: Accept different flag permutations? Or else, ensure fixed ordering of + * flags in set_flag below (following the same order as we have in + * lib/format_text/flags.c). + */ +static int compare_value(struct config_value *a, struct config_value *b) +{ + if (a->type > b->type) + return 1; + if (a->type < b->type) + return -1; + + switch (a->type) { + case CFG_STRING: return strcmp(a->v.str, b->v.str); + case CFG_FLOAT: return a->v.r == b->v.r; + case CFG_INT: return a->v.i == b->v.i; + case CFG_EMPTY_ARRAY: return 0; + } + + if (a->next && b->next) + return compare_value(a->next, b->next); +} + +static int compare_config(struct config_node *a, struct config_node *b) +{ + int result = 0; + if (a->v && b->v) + result = compare_value(a->v, b->v); + if (a->v && !b->v) + result = 1; + if (!a->v && b->v) + result = -1; + if (a->child && b->child) + result = compare_config(a->child, b->child); + + if (result) + return result; + + if (a->sib && b->sib) + result = compare_config(a->sib, b->sib); + if (a->sib && !b->sib) + result = 1; + if (!a->sib && b->sib) + result = -1; + + return result; +} + +/* * TODO: This set_flag function is pretty generic and might make sense in a * library here or there. */ @@ -212,8 +260,10 @@ static int update_metadata(lvmetad_state *s, const char *_vgid, struct config_no goto out; if (seq == haveseq) { - // TODO: compare old->root with metadata to ensure equality retval = 1; + // TODO: disregard the MISSING_PV flag status in this comparison + if (compare_config(metadata, old->root)) + retval = 0; goto out; } |