Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=6dc... Commit: 6dc56fc71790f1eac600012d030f8da26a6d62e5 Parent: fb3ce7fd9b9bf8fa2b89e1525cd73bd4f832ecb4 Author: David Teigland teigland@redhat.com AuthorDate: Tue Aug 17 15:39:40 2010 -0500 Committer: David Teigland teigland@redhat.com CommitterDate: Mon Nov 15 13:28:08 2010 -0600
gfs_controld: fix plock owner in unmount
When a node owns any plock resources on a file system and that fs is unmounted, the remaining nodes do nothing to change the owner value on those resources. Any process that attempts to access those plock resources will become stuck and require a reboot. The fix is to change the owner to 0 (unowned) on any resources owned by a node that unmounts.
bz 624822
Signed-off-by: David Teigland teigland@redhat.com --- group/gfs_controld/cpg-old.c | 9 +++++++++ group/gfs_controld/gfs_daemon.h | 1 + group/gfs_controld/plock.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/group/gfs_controld/cpg-old.c b/group/gfs_controld/cpg-old.c index 5342025..55353d0 100644 --- a/group/gfs_controld/cpg-old.c +++ b/group/gfs_controld/cpg-old.c @@ -2123,6 +2123,14 @@ static void reset_unfinished_recoveries(struct mountgroup *mg) } }
+static void reset_plock_resources(struct mountgroup *mg) +{ + struct mg_member *memb; + + list_for_each_entry(memb, &mg->members_gone, list) + remove_resource_owner(mg, memb->nodeid); +} + /* old method: A is rw mount, B mounts rw @@ -2170,6 +2178,7 @@ void do_start(struct mountgroup *mg, int type, int member_count, int *nodeids)
recover_members(mg, member_count, nodeids, &pos, &neg); reset_unfinished_recoveries(mg); + reset_plock_resources(mg);
if (mg->init) { if (member_count == 1) diff --git a/group/gfs_controld/gfs_daemon.h b/group/gfs_controld/gfs_daemon.h index af7ed45..db8b7d9 100644 --- a/group/gfs_controld/gfs_daemon.h +++ b/group/gfs_controld/gfs_daemon.h @@ -317,6 +317,7 @@ void retrieve_plocks(struct mountgroup *mg); void purge_plocks(struct mountgroup *mg, int nodeid, int unmount); int fill_plock_dump_buf(struct mountgroup *mg); int setup_misc_devices(void); +void remove_resource_owner(struct mountgroup *mg, int nodeid);
/* util.c */ int we_are_in_fence_domain(void); diff --git a/group/gfs_controld/plock.c b/group/gfs_controld/plock.c index e487d41..4de793d 100644 --- a/group/gfs_controld/plock.c +++ b/group/gfs_controld/plock.c @@ -2205,6 +2205,37 @@ void purge_plocks(struct mountgroup *mg, int nodeid, int unmount) unlink_checkpoint(mg); }
+/* when a node unmounts we need to remove it as the owner of any resources */ + +void remove_resource_owner(struct mountgroup *mg, int nodeid) +{ + struct resource *r, *r2; + int rem = 0; + + if (!cfgd_plock_ownership) + return; + + list_for_each_entry_safe(r, r2, &mg->plock_resources, list) { + if (r->owner == nodeid) { + log_plock(mg, "rem owner %d from %llu", + nodeid, (unsigned long long)r->number); + r->owner = 0; + r->flags |= R_GOT_UNOWN; + rem++; + + /* should probably wait to do this until after + the finish barrier when we know everyone has + changed owner to 0 */ + send_pending_plocks(mg, r); + } + } + + if (rem) + mg->last_plock_time = time(NULL); + + log_group(mg, "removed owner %d from %d resources", nodeid, rem); +} + int fill_plock_dump_buf(struct mountgroup *mg) { struct posix_lock *po;
cluster-commits@lists.fedorahosted.org