[DRBD-cvs] r1459 - in trunk: drbd drbd/linux user

drbd-user@lists.linbit.com drbd-user@lists.linbit.com
Tue, 27 Jul 2004 18:58:10 +0200 (CEST)


Author: phil
Date: 2004-07-27 18:58:09 +0200 (Tue, 27 Jul 2004)
New Revision: 1459

Modified:
   trunk/drbd/drbd_fs.c
   trunk/drbd/drbd_int.h
   trunk/drbd/linux/drbd.h
   trunk/drbd/linux/drbd_config.h
   trunk/user/drbdadm_main.c
   trunk/user/drbdsetup.c
Log:
* Increment the human-count if someone types in "yes" at the
  user's dialog.
* Make sure the timeout-count is increased if the timeout 
  expires at the user's dialog.


Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c	2004-07-27 09:01:05 UTC (rev 1458)
+++ trunk/drbd/drbd_fs.c	2004-07-27 16:58:09 UTC (rev 1459)
@@ -714,15 +714,6 @@
 				return -EIO;
 			}
 		}
-#if 0
-		else if (mdev->cstate >= Connected) {
-			/* do NOT increase the Human count if we are connected,
-			 * and there is no reason for it.  I'm not yet sure
-			 * wether this is what I mean, though...
-			 */
-			newstate &= ~(Human|DontBlameDrbd);
-		}
-#endif
 	}
 
 	drbd_sync_me(mdev);
@@ -774,6 +765,16 @@
 		mdev->this_bdev->bd_disk = mdev->vdisk;
 )
 
+		if(test_bit(ON_PRI_INC_HUMAN,&mdev->flags)) { 
+			newstate |= Human;
+			clear_bit(ON_PRI_INC_HUMAN,&mdev->flags);
+		}
+
+		if(test_bit(ON_PRI_INC_TIMEOUTEX,&mdev->flags)) {
+			newstate |= TimeoutExpired;
+			clear_bit(ON_PRI_INC_TIMEOUTEX,&mdev->flags);
+		}
+
 		if(newstate & Human) {
 			drbd_md_inc(mdev,HumanCnt);
 		} else if(newstate & TimeoutExpired ) {
@@ -996,6 +997,20 @@
 		}
 		break;
 
+	case DRBD_IOCTL_SET_STATE_FLAGS:
+		if (arg & ~(Human|TimeoutExpired) ) {
+			err = -EINVAL;
+		} else {
+			clear_bit(ON_PRI_INC_HUMAN,&mdev->flags);
+			clear_bit(ON_PRI_INC_TIMEOUTEX,&mdev->flags);
+
+			if (arg & Human ) 
+				set_bit(ON_PRI_INC_HUMAN,&mdev->flags);
+			if (arg & TimeoutExpired )
+				set_bit(ON_PRI_INC_TIMEOUTEX,&mdev->flags);
+		}
+		break;
+
 	case DRBD_IOCTL_SET_DISK_CONFIG:
 		err = drbd_ioctl_set_disk(mdev,(struct ioctl_disk_config*)arg);
 		break;

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2004-07-27 09:01:05 UTC (rev 1458)
+++ trunk/drbd/drbd_int.h	2004-07-27 16:58:09 UTC (rev 1459)
@@ -670,6 +670,8 @@
 	WRITER_PRESENT,		// somebody opened us with write intent
 	STOP_SYNC_TIMER,	// tell timer to cancel itself
 	DO_NOT_INC_CONCNT,	// well, don't ...
+	ON_PRI_INC_HUMAN,       // When we become primary increase human-count
+	ON_PRI_INC_TIMEOUTEX,   // When " - "  increase timeout-count
 	UNPLUG_QUEUED,		// only relevant with kernel 2.4
 	UNPLUG_REMOTE,		// whether sending a "UnplugRemote" makes sense
 	DISKLESS,		// no local disk

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2004-07-27 09:01:05 UTC (rev 1458)
+++ trunk/drbd/linux/drbd.h	2004-07-27 16:58:09 UTC (rev 1459)
@@ -223,6 +223,8 @@
 #define DRBD_IOCTL_WAIT_CONNECT     _IOR( DRBD_IOCTL_LETTER, 0x11, struct ioctl_wait )
 #define DRBD_IOCTL_WAIT_SYNC        _IOR( DRBD_IOCTL_LETTER, 0x12, struct ioctl_wait )
 #define DRBD_IOCTL_UNCONFIG_DISK    _IO ( DRBD_IOCTL_LETTER, 0x13 )
+#define DRBD_IOCTL_SET_STATE_FLAGS  _IOW( DRBD_IOCTL_LETTER, 0x14, Drbd_State )
 
+
 #endif
 

Modified: trunk/drbd/linux/drbd_config.h
===================================================================
--- trunk/drbd/linux/drbd_config.h	2004-07-27 09:01:05 UTC (rev 1458)
+++ trunk/drbd/linux/drbd_config.h	2004-07-27 16:58:09 UTC (rev 1459)
@@ -23,7 +23,7 @@
 extern const char * drbd_buildtag(void);
 
 #define REL_VERSION "0.7.0"
-#define API_VERSION 74
+#define API_VERSION 75
 #define PRO_VERSION 74
 
 //#define DBG_ALL_SYMBOLS // no static functs, improves quality of OOPS traces

Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c	2004-07-27 09:01:05 UTC (rev 1458)
+++ trunk/user/drbdadm_main.c	2004-07-27 16:58:09 UTC (rev 1459)
@@ -564,11 +564,27 @@
   return adm_syncer(res,unused);
 }
 
+static int on_primary(struct d_resource* res ,char* flag)
+{
+  char* argv[20];
+  int argc=0;
+
+  argc=0;
+  argv[argc++]=drbdsetup;
+  argv[argc++]=res->me->device;
+  argv[argc++]="on_primary";
+  argv[argc++]=flag;
+  argv[argc++]=0;
+
+  return m_system(0,argv);
+}
+
+
 static int adm_wait_c(struct d_resource* res ,char* unused)
 {
   char* argv[20];
   struct d_option* opt;
-  int argc=0;
+  int argc=0,rv;
 
   argv[argc++]=drbdsetup;
   argv[argc++]=res->me->device;
@@ -577,19 +593,28 @@
   make_options(opt);
   argv[argc++]=0;
 
-  return m_system(SF_MaySleep,argv);
+  rv = m_system(SF_MaySleep,argv);
+  
+  if(rv == 5) { // Timer expired
+    rv = on_primary(res,"--inc-timeout-expired");
+  }
+
+  return rv;
 }
 
 
+/* In case a child exited, or exits, its return code is stored as
+   negative number in the pids[i] array */
 static int childs_running(pid_t* pids,int opts)
 {
   int i=0,wr,rv=0,status;
 
   for(i=0;i<nr_resources;i++) {
-    if(pids[i]==0) continue;
+    if(pids[i]<=0) continue;
     wr = waitpid(pids[i], &status, opts);
     if( wr == -1) {            // Wait error.
       if (errno == ECHILD) {
+	printf("No exit code for %d\n",pids[i]);
 	pids[i] = 0;           // Child exited before ?
 	continue;
       }
@@ -597,7 +622,11 @@
       exit(E_exec_error);
     }
     if( wr == 0 ) rv = 1;      // Child still running.
-    if( wr > 0 )  pids[i] = 0; // Child exited.
+    if( wr > 0 ) {
+      pids[i] = 0;
+      if( WIFEXITED(status) ) pids[i] = -WEXITSTATUS(status);
+      if( WIFSIGNALED(status) ) pids[i] = -1000;
+    }
   }
   return rv;
 }
@@ -607,7 +636,7 @@
   int i;
 
   for(i=0;i<nr_resources;i++) {
-    if(pids[i]==0) continue;
+    if(pids[i]<=0) continue;
     kill(pids[i],SIGINT);
   }
 }
@@ -676,6 +705,26 @@
   // do nothing. But interrupt systemcalls :)
 }
 
+static int check_exit_codes(pid_t* pids)
+{
+  struct d_resource *res,*t;
+  int i=0,rv=0;
+
+  for_each_resource(res,t,config) {
+    if (pids[i] == -5) {
+      rv |= on_primary(res,"--inc-timeout-expired");
+      pids[i]=0;
+    }
+    if (pids[i] == -1000) {
+      rv |= on_primary(res,"--inc-human");
+      pids[i]=0;
+    }
+    if (pids[i] == -20) rv = 20;
+    i++;
+  }
+  return rv;
+}
+
 static int adm_wait_ci(struct d_resource* ignored ,char* unused)
 {
   struct d_resource *res,*t;
@@ -711,6 +760,7 @@
 
   start = time(0);
   rr = gets_timeout(pids,0,0,3*1000); // no string, but timeout of 3 seconds.
+  check_exit_codes(pids);
 
   if(rr == 0) {
     printf("***************************************************************\n"
@@ -729,10 +779,13 @@
       printf("\e[s\e[31G[%4d]:\e[u",(int)(time(0)-start)); // Redraw sec.
       fflush(stdout);
       rr = gets_timeout(pids,answer,40,wtime*1000);
+      check_exit_codes(pids);
+
       if(rr==1) {
 	if(!strcmp(answer,"yes\n")) {
 	  kill_childs(pids);
 	  childs_running(pids,0);
+	  check_exit_codes(pids);
 	  rr = -1;
 	} else {
 	  printf(" To abort waiting enter 'yes' [ -- ]:");
@@ -1106,7 +1159,7 @@
   }
 
   if(drbdsetup == NULL) {
-    find_drbdsetup((char *[]){"/sbin/drbdsetup", "./drbdsetup", 0 });
+    find_drbdsetup((char *[]){"./drbdsetup", "/sbin/drbdsetup", 0 });
   }
 
   if(cmd->res_name_required)

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2004-07-27 09:01:05 UTC (rev 1458)
+++ trunk/user/drbdsetup.c	2004-07-27 16:58:09 UTC (rev 1459)
@@ -99,6 +99,7 @@
 
 int cmd_primary(int drbd_fd,char** argv,int argc,struct option *options);
 int cmd_secondary(int drbd_fd,char** argv,int argc,struct option *options);
+int cmd_on_primary(int drbd_fd,char** argv,int argc,struct option *options);
 int cmd_wait_sync(int drbd_fd,char** argv,int argc,struct option *options);
 int cmd_wait_connect(int drbd_fd,char** argv,int argc,struct option *options);
 int cmd_invalidate(int drbd_fd,char** argv,int argc,struct option *options);
@@ -121,6 +122,11 @@
      { "timeout-expired",no_argument,   0, 't' },
      { 0,            0,                 0, 0   } } },
   {"secondary", cmd_secondary,       0, 0, },
+  {"on_primary", cmd_on_primary,           0,
+   (struct option[]) {
+     { "inc-human",      no_argument,    0, 'h' },
+     { "inc-timeout-expired",no_argument,0, 't' },
+     { 0,            0,                 0, 0   } } },
   {"wait_sync", cmd_wait_sync,       0,
    (struct option[]) {
      { "time",       required_argument, 0, 't' },
@@ -775,6 +781,48 @@
   return set_state(drbd_fd,Secondary);
 }
 
+int cmd_on_primary(int drbd_fd,char** argv,int argc,struct option *options)
+{
+  int err;
+  Drbd_State flags=0;
+
+  if(argc > 0)
+    {
+      while(1)
+	{
+	  int c;
+
+	  PRINT_ARGV;
+
+	  c = getopt_long(argc,argv,make_optstring(options),options,0);
+	  if(c == -1) break;
+	  switch(c)
+	    {
+	    case 'h':
+	      flags |= Human;
+	      break;
+	    case 't':
+	      flags |= TimeoutExpired;
+	      break;
+	    case 1:	// non option argument. see getopt_long(3)
+	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",basename,optarg);
+	    case '?':
+	      return 20;
+	    }
+	}
+    }
+
+  err=ioctl(drbd_fd,DRBD_IOCTL_SET_STATE_FLAGS,flags);
+  if(err)
+    {
+      PERROR("ioctl(,SET_STATE_FLAGS,) failed");
+      exit(20);
+    }
+
+  return 0;
+}
+
+
 int wait_on(int drbd_fd,char** argv,int argc,int wfct,int dwfct, int req,
 	    struct option *options)
 {
@@ -809,6 +857,7 @@
 	}
     }
   err=ioctl(drbd_fd,req,&p);
+  if(errno == ETIME) exit(5);
   if(err)
     {
       PERROR("ioctl(,WAIT_*,) failed");