[DRBD-cvs] svn commit by phil - r2446 - in trunk/drbd: . linux - It was possible to issue 'drbdadm invalidate r0' or inv

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Fri Sep 22 14:12:00 CEST 2006


Author: phil
Date: 2006-09-22 14:11:59 +0200 (Fri, 22 Sep 2006)
New Revision: 2446

Modified:
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_strings.c
   trunk/drbd/linux/drbd.h
Log:
It was possible to issue 'drbdadm invalidate r0' or invalidate-remote
while the resync process was alrady running, resulting in complete
chaos of course.

FIXED that, by introducing a new error value of drbd_request_state():
SS_ResyncRunning


Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-09-21 13:52:30 UTC (rev 2445)
+++ trunk/drbd/drbd_main.c	2006-09-22 12:11:59 UTC (rev 2446)
@@ -430,7 +430,8 @@
 	drbd_change_state(mdev,ChgStateHard,mask,val);
 }
 
-STATIC int pre_state_checks(drbd_dev* mdev, drbd_state_t ns);
+STATIC int is_valid_state(drbd_dev* mdev, drbd_state_t ns);
+STATIC int is_valid_state_transition(drbd_dev*, drbd_state_t, drbd_state_t);
 STATIC int drbd_send_state_req(drbd_dev *, drbd_state_t, drbd_state_t);
 
 set_st_err_t _req_st_cond(drbd_dev* mdev,drbd_state_t mask, drbd_state_t val)
@@ -451,8 +452,11 @@
 	ns.i = (os.i & ~mask.i) | val.i;
 	if( !cl_wide_st_chg(mdev,os,ns) ) rv = SS_CW_NoNeed;
 	if( !rv ) {
-		rv = pre_state_checks(mdev,ns);
-		if(rv==SS_Success) rv = 0; // cont waiting, otherwise fail.
+		rv = is_valid_state(mdev,ns);
+		if(rv==SS_Success) {
+			rv = is_valid_state_transition(mdev,ns,os);
+			if(rv==SS_Success) rv = 0; // cont waiting, otherwise fail.
+		}
 	}
 	spin_unlock_irqrestore(&mdev->req_lock,flags);
 
@@ -477,7 +481,8 @@
 	ns.i = (os.i & ~mask.i) | val.i;
 
 	if(cl_wide_st_chg(mdev,os,ns)) {
-		rv = pre_state_checks(mdev,ns);
+		rv = is_valid_state(mdev,ns);
+		if(rv == SS_Success ) rv = is_valid_state_transition(mdev,ns,os);
 		spin_unlock_irqrestore(&mdev->req_lock,flags);
 
 		if( rv < SS_Success ) {
@@ -556,7 +561,7 @@
 		              A##s_to_name(ns.A)); \
 	} })
 
-STATIC int pre_state_checks(drbd_dev* mdev, drbd_state_t ns)
+STATIC int is_valid_state(drbd_dev* mdev, drbd_state_t ns)
 {
 	/* See drbd_state_sw_errors in drbd_strings.c */
 
@@ -604,6 +609,16 @@
 	return rv;
 }
 
+STATIC int is_valid_state_transition(drbd_dev* mdev,drbd_state_t ns,drbd_state_t os)
+{
+	int rv=SS_Success;
+
+	if( (ns.conn == StartingSyncT || ns.conn == StartingSyncS ) &&
+	    os.conn > Connected) rv=SS_ResyncRunning;
+
+	return rv;
+}
+
 int _drbd_set_state(drbd_dev* mdev, drbd_state_t ns,enum chg_state_flags flags)
 {
 	drbd_state_t os;
@@ -715,12 +730,12 @@
 		/*  pre-state-change checks ; only look at ns  */
 		/* See drbd_state_sw_errors in drbd_strings.c */
 
-		rv = pre_state_checks(mdev,ns);
+		rv = is_valid_state(mdev,ns);
 		if(rv < SS_Success) {
 			/* If the old state was illegal as well, then let
 			   this happen...*/
 
-			if( pre_state_checks(mdev,os) == rv ) {
+			if( is_valid_state(mdev,os) == rv ) {
 				ERR("Forcing state change from bad state. "
 				    "Error would be: '%s'\n", 
 				    set_st_err_name(rv));
@@ -728,7 +743,7 @@
 				print_st(mdev,"new",ns);
 				rv = SS_Success;
 			}
-		}
+		} else rv = is_valid_state_transition(mdev,ns,os);
 	}
 
 	if(rv < SS_Success) {

Modified: trunk/drbd/drbd_strings.c
===================================================================
--- trunk/drbd/drbd_strings.c	2006-09-21 13:52:30 UTC (rev 2445)
+++ trunk/drbd/drbd_strings.c	2006-09-22 12:11:59 UTC (rev 2446)
@@ -69,6 +69,7 @@
 	[-SS_SyncingDiskless] = "Refusing to be syncing and diskless",
 	[-SS_ConnectedOutdates] = "Refusing to be Outdated while Connected",
 	[-SS_PrimaryNOP] = "Refusing to be Primary while peer is not outdated",
+	[-SS_ResyncRunning] = "Can not start resync since it is already active",
 	[-SS_CW_FailedByPeer] = "State changed was refused by peer node"
 };
 

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2006-09-21 13:52:30 UTC (rev 2445)
+++ trunk/drbd/linux/drbd.h	2006-09-22 12:11:59 UTC (rev 2446)
@@ -192,7 +192,8 @@
 	SS_SyncingDiskless=-5,
 	SS_ConnectedOutdates=-6,
 	SS_PrimaryNOP=-7,
-	SS_CW_FailedByPeer=-8
+	SS_ResyncRunning=-8,
+	SS_CW_FailedByPeer=-10
 } set_st_err_t;
 
 /* from drbd_strings.c */



More information about the drbd-cvs mailing list