1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

Work out some more details in metadata update in lvmetad.

This commit is contained in:
Petr Rockai 2011-07-19 16:48:13 +00:00
parent 7411a44871
commit 3c238baf03
4 changed files with 55 additions and 15 deletions

View File

@ -28,3 +28,6 @@ lvmetad: lvmetad-core.c ../common/daemon-server.c ../common/daemon-server.h ../c
check: testclient lvmetad check: testclient lvmetad
./test.sh "$(BUILDDIR)/libdm:$(BUILDDIR)/daemons/dmeventd" ./test.sh "$(BUILDDIR)/libdm:$(BUILDDIR)/daemons/dmeventd"
clean:
rm -f testclient lvmetad

View File

@ -18,10 +18,11 @@ static response vg_by_uuid(lvmetad_state *s, request r)
{ {
const char *uuid = daemon_request_str(r, "uuid", "NONE"); const char *uuid = daemon_request_str(r, "uuid", "NONE");
fprintf(stderr, "[D] vg_by_uuid: %s (vgs = %p)\n", uuid, s->vgs); fprintf(stderr, "[D] vg_by_uuid: %s (vgs = %p)\n", uuid, s->vgs);
struct config_node *metadata = dm_hash_lookup(s->vgs, uuid); struct config_tree *cft = dm_hash_lookup(s->vgs, uuid);
if (!metadata) if (!cft || !cft->root)
return daemon_reply_simple("failed", "reason = %s", "uuid not found", NULL); return daemon_reply_simple("failed", "reason = %s", "uuid not found", NULL);
fprintf(stderr, "[D] metadata: %p\n", metadata);
struct config_node *metadata = cft->root;
response res = { .buffer = NULL }; response res = { .buffer = NULL };
struct config_node *n; struct config_node *n;
@ -67,16 +68,16 @@ static void update_pv_status(lvmetad_state *s, const char *pvid)
if (pvid) { if (pvid) {
const char *vgid = dm_hash_lookup(s->pvid_to_vgid, pvid); const char *vgid = dm_hash_lookup(s->pvid_to_vgid, pvid);
assert(vgid); assert(vgid);
struct config_node *vg = dm_hash_lookup(s->vgs, vgid); struct config_tree *vg = dm_hash_lookup(s->vgs, vgid);
assert(vg); assert(vg);
update_pv_status_in_vg(s, vg); update_pv_status_in_vg(s, vg->root);
} else { } else {
struct dm_hash_node *n = dm_hash_get_first(s->vgs); struct dm_hash_node *n = dm_hash_get_first(s->vgs);
while (n) { while (n) {
struct config_node *vg = dm_hash_get_data(s->vgs, n); struct config_tree *vg = dm_hash_get_data(s->vgs, n);
fprintf(stderr, "[D] checking VG: %s\n", fprintf(stderr, "[D] checking VG: %s\n",
find_config_str(vg, "metadata/id", "?")); find_config_str(vg, "metadata/id", "?"));
update_pv_status_in_vg(s, vg); update_pv_status_in_vg(s, vg->root);
n = dm_hash_get_next(s->vgs, n); n = dm_hash_get_next(s->vgs, n);
} }
} }
@ -84,11 +85,38 @@ static void update_pv_status(lvmetad_state *s, const char *pvid)
static int update_metadata(lvmetad_state *s, const char *vgid, struct config_node *metadata) static int update_metadata(lvmetad_state *s, const char *vgid, struct config_node *metadata)
{ {
struct config_node *metadata_clone = struct config_tree *old = dm_hash_lookup(s->vgs, vgid);
clone_config_node_with_mem(s->mem, metadata, 0); int seq = find_config_int(metadata, "metadata/seqno", -1);
/* TODO: seqno-based comparison with existing metadata version */ int haveseq = -1;
dm_hash_insert(s->vgs, vgid, (void*) metadata_clone);
fprintf(stderr, "[D] metadata stored at %p\n", metadata_clone); if (old)
haveseq = find_config_int(old->root, "metadata/seqno", -1);
if (seq < 0)
return 0; /* bad */
if (seq == haveseq) {
// TODO: compare old->root with metadata to ensure equality
return 1;
}
if (seq < haveseq) {
// TODO: we may want to notify the client that their metadata is
// out of date?
return 1;
}
if (haveseq >= 0 && haveseq < seq) {
/* need to update what we have since we found a newer version */
destroy_config_tree(old);
dm_hash_remove(s->vgs, vgid);
}
struct config_tree *cft = create_config_tree(NULL, 0);
cft->root = clone_config_node(cft, metadata, 0);
dm_hash_insert(s->vgs, vgid, cft);
return 1;
} }
static response pv_add(lvmetad_state *s, request r) static response pv_add(lvmetad_state *s, request r)
@ -106,8 +134,12 @@ static response pv_add(lvmetad_state *s, request r)
const char *vgid = daemon_request_str(r, "metadata/id", NULL); const char *vgid = daemon_request_str(r, "metadata/id", NULL);
if (!vgid) if (!vgid)
return daemon_reply_simple("failed", "reason = %s", "need VG UUID", NULL); return daemon_reply_simple("failed", "reason = %s", "need VG UUID", NULL);
if (daemon_request_int(r, "metadata/seqno", -1) < 0)
return daemon_reply_simple("failed", "reason = %s", "need VG seqno", NULL);
update_metadata(s, vgid, metadata); if (!update_metadata(s, vgid, metadata))
return daemon_reply_simple("failed", "reason = %s",
"metadata update failed", NULL);
} }
update_pv_status(s, NULL); update_pv_status(s, NULL);

View File

@ -3,9 +3,11 @@
export LD_LIBRARY_PATH="$1" export LD_LIBRARY_PATH="$1"
test -n "$2" && { test -n "$2" && {
./lvmetad -f & rm -f /var/run/lvmetad.{socket,pid}
chmod +rx lvmetad
valgrind ./lvmetad -f &
PID=$! PID=$!
sleep .1 sleep 1
./testclient ./testclient
kill $PID kill $PID
exit 0 exit 0

View File

@ -17,6 +17,9 @@ const char *metadata2 = "{\n"
" pv1 {\n" " pv1 {\n"
" id = \"bbcd-efgh\"\n" " id = \"bbcd-efgh\"\n"
" }\n" " }\n"
" pv2 {\n"
" id = \"cbcd-efgh\"\n"
" }\n"
"}\n" "}\n"
"}\n"; "}\n";