[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");