LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File gfs_controld_fix_plock_owner_in_umount.patch of Package cluster (Project home:sschapiro:openstack:upstream)

commit 6dc56fc71790f1eac600012d030f8da26a6d62e5
Author: David Teigland <teigland@redhat.com>
Date:   Tue Aug 17 15:39:40 2010 -0500

    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>

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;