[DRBD-cvs] r1649 - in trunk: drbd scripts user
svn at svn.drbd.org
svn at svn.drbd.org
Mon Nov 22 23:35:11 CET 2004
Author: phil
Date: 2004-11-22 23:35:08 +0100 (Mon, 22 Nov 2004)
New Revision: 1649
Modified:
trunk/drbd/drbd_receiver.c
trunk/scripts/drbd.conf
trunk/user/drbdadm.h
trunk/user/drbdadm_main.c
trunk/user/drbdadm_parser.y
trunk/user/drbdadm_scanner.fl
trunk/user/drbdsetup.c
Log:
Implemented the concept of handlers. These handlers are scripts
that are run on demand of the DRBD kernel module.
Currently the config file knows of the following handlers:
* pri-on-incon-degr
* pri-sees-sec-with-higher-gc
* on-disconnect
[more might come]
Code in drbdadm tested slightly, code on the side of the module
is missing or untested.
Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c 2004-11-22 14:31:35 UTC (rev 1648)
+++ trunk/drbd/drbd_receiver.c 2004-11-22 22:35:08 UTC (rev 1649)
@@ -1624,6 +1624,23 @@
}
}
+void drbd_khelper(drbd_dev *mdev, char* cmd)
+{
+ int ret;
+ char mb[12];
+ char *argv[] = {"/sbin/drbdadm", cmd, mb, NULL };
+ static char *envp[] = { "HOME=/",
+ "TERM=linux",
+ "PATH=/sbin:/usr/sbin:/bin:/usr/bin",
+ NULL };
+
+ snprintf(mb,12,"minor-%d",(int)(mdev-drbd_conf));
+ ret = call_usermodehelper("/sbin/drbdadm",argv,envp,0);
+ if(ret) {
+ ERR("call_usermodhelper failed with %d",ret);
+ }
+}
+
STATIC void drbd_disconnect(drbd_dev *mdev)
{
D_ASSERT(mdev->state.s.conn < Connected);
@@ -1736,6 +1753,8 @@
}
clear_bit(DO_NOT_INC_CONCNT,&mdev->flags);
+ drbd_khelper(mdev,"on-disconnect");
+
INFO("Connection lost.\n");
}
Modified: trunk/scripts/drbd.conf
===================================================================
--- trunk/scripts/drbd.conf 2004-11-22 14:31:35 UTC (rev 1648)
+++ trunk/scripts/drbd.conf 2004-11-22 22:35:08 UTC (rev 1649)
@@ -118,10 +118,20 @@
#
protocol C;
- # what should be done in case the cluster starts up in
- # degraded mode, but knows it has inconsistent data.
- incon-degr-cmd "echo '!DRBD! pri on incon-degr' | wall ; sleep 60 ; halt -f";
+ handlers {
+ # what should be done in case the node is primary, degraded
+ # (=no connection) and has inconsistent data.
+ pri-on-incon-degr "halt -f";
+ # If suddenly the peer presents a higher generation count
+ # than we have, and we are primary.
+ pri-sees-sec-with-higher-gc "halt -f";
+
+ # Commands to run in case we loose connection. Use this script in
+ # in conjunction with the on-disconnect=suspend_io configuration.
+ # on-disconnect "/usr/lib/drbd/outdate-peer.sh";
+ }
+
startup {
# Wait for connection timeout.
# The init script blocks the boot process until the resources
@@ -248,7 +258,6 @@
#
resource "r1" {
protocol C;
- incon-degr-cmd "echo '!DRBD! pri on incon-degr' | wall ; sleep 60 ; halt -f";
startup {
wfc-timeout 0; ## Infinite!
degr-wfc-timeout 120; ## 2 minutes.
@@ -285,7 +294,6 @@
resource r2 {
protocol C;
- incon-degr-cmd "echo '!DRBD! pri on incon-degr' | wall ; sleep 60 ; halt -f";
startup { wfc-timeout 0; degr-wfc-timeout 120; }
disk { on-io-error detach; }
@@ -304,7 +312,7 @@
resource r3 {
protocol C;
- incon-degr-cmd "echo '!DRBD! pri on incon-degr' | wall ; sleep 60 ; halt -f";
+
startup { wfc-timeout 0; degr-wfc-timeout 120; }
disk { on-io-error detach; }
syncer {
Modified: trunk/user/drbdadm.h
===================================================================
--- trunk/user/drbdadm.h 2004-11-22 14:31:35 UTC (rev 1648)
+++ trunk/user/drbdadm.h 2004-11-22 22:35:08 UTC (rev 1649)
@@ -58,13 +58,13 @@
{
char* name;
char* protocol;
- char* ind_cmd;
struct d_host_info* me;
struct d_host_info* peer;
struct d_option* net_options;
struct d_option* disk_options;
struct d_option* sync_options;
struct d_option* startup_options;
+ struct d_option* handlers;
struct d_resource* next;
};
Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c 2004-11-22 14:31:35 UTC (rev 1648)
+++ trunk/user/drbdadm_main.c 2004-11-22 22:35:08 UTC (rev 1649)
@@ -77,7 +77,6 @@
int adm_generic_l(struct d_resource* ,char* );
int adm_resize(struct d_resource* ,char* );
int adm_syncer(struct d_resource* ,char* );
-static int adm_primary(struct d_resource* ,char* );
static int adm_up(struct d_resource* ,char* );
extern int adm_adjust(struct d_resource* ,char* );
static int adm_dump(struct d_resource* ,char* );
@@ -90,6 +89,7 @@
static int sh_md_dev(struct d_resource* ,char* );
static int sh_md_idx(struct d_resource* ,char* );
static int admm_generic(struct d_resource* ,char* );
+static int adm_khelper(struct d_resource* ,char* );
char ss_buffer[255];
struct utsname nodeinfo;
@@ -122,7 +122,7 @@
{ "disconnect", adm_generic_s,"disconnect" ,1,1 },
{ "up", adm_up, 0 ,1,1 },
{ "down", adm_generic_s,"down" ,1,1 },
- { "primary", adm_primary, 0 ,1,1 },
+ { "primary", adm_generic_s,"primary" ,1,1 },
{ "secondary", adm_generic_s,"secondary" ,1,1 },
{ "invalidate", adm_generic_l,"invalidate" ,1,1 },
{ "invalidate_remote", adm_generic_l,"invalidate_remote",1,1 },
@@ -139,6 +139,9 @@
{ "get-gc", admm_generic, "get-gc" ,1,1 },
{ "dump-md", admm_generic, "dump-md" ,1,1 },
{ "set-gc", admm_generic, "set-gc" ,0,1 },
+ { "pri-on-incon-degr", adm_khelper, "pri-on-incon-degr",0,1},
+ { "pri-sees-sec-with-higher-gc", adm_khelper, "pri-sees-sec-with-higher-gc",0,1},
+ { "on-disconnect", adm_khelper, "on-disconnect" ,0,1},
{ "wait_con_int", adm_wait_ci, 0 ,1,0 },
{ "sh-resources", sh_resources,0 ,0,0 },
{ "sh-mod-parms", sh_mod_parms,0 ,0,0 },
@@ -181,7 +184,7 @@
printI("%s {\n",name); ++indent;
while(opts) {
- if(opts->value) printA(opts->name,opts->value);
+ if(opts->value) printA(opts->name,esc(opts->value));
else printI(BFMT,opts->name);
opts=opts->next;
}
@@ -226,14 +229,13 @@
{
printI("resource %s {\n",esc(res->name)); ++indent;
printA("protocol",res->protocol);
- if(res->ind_cmd)
- printA("incon-degr-cmd",esc(res->ind_cmd));
dump_host_info(res->me);
dump_host_info(res->peer);
dump_options("net",res->net_options);
dump_options("disk",res->disk_options);
dump_options("syncer",res->sync_options);
dump_options("startup",res->startup_options);
+ dump_options("handlers",res->handlers);
--indent; printf("}\n\n");
return 0;
@@ -324,13 +326,13 @@
for_each_resource(f,t,res) {
free(f->name);
free(f->protocol);
- free(f->ind_cmd);
free_host_info(f->me);
free_host_info(f->peer);
free_options(f->net_options);
free_options(f->disk_options);
free_options(f->sync_options);
free_options(f->startup_options);
+ free_options(f->handlers);
free(f);
}
}
@@ -554,17 +556,18 @@
return adm_generic(res,cmd,SLEEPS_LONG);
}
-int adm_primary(struct d_resource* res,char* unused)
+static char* get_opt_val(struct d_option*,char*,char*);
+
+static int adm_khelper(struct d_resource* res ,char* cmd)
{
- int rv;
- char *argv[] = { "/bin/bash", "-c", res->ind_cmd , NULL };
+ char *sh_cmd;
+ char *argv[] = { "/bin/bash", "-c", NULL , NULL };
- rv = adm_generic_s(res,"primary");
-
- if(rv==21) {
- rv = m_system(argv,SLEEPS_VERY_LONG);
+ if( (sh_cmd = get_opt_val(res->handlers,cmd,NULL)) ) {
+ argv[2]=sh_cmd;
+ m_system(argv,SLEEPS_VERY_LONG);
}
- return rv;
+ return 0;
}
int adm_connect(struct d_resource* res,char* unused)
@@ -649,7 +652,27 @@
return rv;
}
+struct d_resource* res_by_minor(const char *id)
+{
+ struct d_resource *res,*t;
+ struct stat sb;
+ int mm;
+ if(strncmp(id,"minor-",6)) return NULL;
+
+ mm = m_strtoll(id+6,1);
+
+ for_each_resource(res,t,config) {
+ if(stat(res->me->device,&sb)) {
+ perror("stat");
+ }
+ if( mm == minor(sb.st_rdev)) {
+ return res;
+ }
+ }
+ return NULL;
+}
+
/* 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)
@@ -1218,6 +1241,7 @@
for_each_resource(res,tmp,config) {
if(!strcmp(argv[i],res->name)) goto found;
}
+ if( (res=res_by_minor(argv[i])) ) goto found;
fprintf(stderr,"'%s' not defined in your config.\n",argv[i]);
exit(E_usage);
found:
Modified: trunk/user/drbdadm_parser.y
===================================================================
--- trunk/user/drbdadm_parser.y 2004-11-22 14:31:35 UTC (rev 1648)
+++ trunk/user/drbdadm_parser.y 2004-11-22 22:35:08 UTC (rev 1649)
@@ -238,7 +238,7 @@
%token TK_GLOBAL TK_RESOURCE
%token TK_ON TK_NET TK_DISK_S TK_SYNCER TK_STARTUP
%token TK_DISABLE_IO_HINTS
-%token TK_PROTOCOL TK_INCON_DEGR_CMD
+%token TK_PROTOCOL TK_HANDLERS
%token TK_ADDRESS TK_DISK TK_DEVICE TK_META_DISK
%token <txt> TK_MINOR_COUNT TK_INTEGER TK_STRING
%token <txt> TK_ON_IO_ERROR TK_SIZE
@@ -248,12 +248,14 @@
%token <txt> TK_WFC_TIMEOUT TK_DEGR_WFC_TIMEOUT
%token <txt> TK_KO_COUNT TK_ON_DISCONNECT TK_DIALOG_REFRESH
%token <txt> TK_ALLOW_TWO_PRIMARIES
+%token <txt> TK_PRI_ON_INCON_DEGR TK_PRI_SEES_SEC_WITH_HIGHER_GC
%type <txt> hostname resource_name
%type <d_option> disk_stmts disk_stmt
%type <d_option> net_stmts net_stmt
%type <d_option> sync_stmts sync_stmt
%type <d_option> startup_stmts startup_stmt
+%type <d_option> handler_stmts handler_stmt
%type <d_resource> resources resource
%%
@@ -306,7 +308,6 @@
;
res_stmt: TK_PROTOCOL TK_STRING { c_res->protocol=$2; }
- | TK_INCON_DEGR_CMD TK_STRING { c_res->ind_cmd=$2; }
;
section: TK_DISK_S disk_stmts
@@ -318,6 +319,8 @@
| TK_STARTUP startup_stmts
{ CHKS("startup"); c_res->startup_options=$2; }
| TK_ON hostname host_stmts { host_sec($2); }
+ | TK_HANDLERS handler_stmts
+ { CHKS("handlers"); c_res->handlers=$2; }
;
hostname: TK_STRING
@@ -419,3 +422,13 @@
| TK_DEGR_WFC_TIMEOUT TK_INTEGER
{ range_check(R_DEGR_WFC_TIMEOUT,$1,$2);$$=new_opt($1,$2); }
;
+
+handler_stmts: /* empty */ { $$ = 0; }
+ | handler_stmts handler_stmt { $$=APPEND($1,$2); }
+ ;
+
+handler_stmt: TK_PRI_ON_INCON_DEGR TK_STRING { $$=new_opt($1,$2); }
+ | TK_PRI_SEES_SEC_WITH_HIGHER_GC TK_STRING
+ { $$=new_opt($1,$2); }
+ | TK_ON_DISCONNECT TK_STRING { $$=new_opt($1,$2); }
+ ;
Modified: trunk/user/drbdadm_scanner.fl
===================================================================
--- trunk/user/drbdadm_scanner.fl 2004-11-22 14:31:35 UTC (rev 1648)
+++ trunk/user/drbdadm_scanner.fl 2004-11-22 22:35:08 UTC (rev 1649)
@@ -47,7 +47,7 @@
%option stack
%x RESOURCE GLOBAL
-%x STARTUP DISK NET SYNCER HOST
+%x STARTUP DISK NET SYNCER HOST HANDLERS
%x SEMICOLON ASSIGN NUM NUM_U NAME STRING PROTO IO_ERROR ON_DISCONNECT
%x IP_AND_PORT PORT META_DISK META_IDX
%x LS LBRACE IGNORE_SECTION
@@ -90,7 +90,7 @@
{NDELIM} expect_error("one of 'global|resource'");
}
-<RESOURCE,GLOBAL,IGNORE_SECTION,STARTUP,DISK,NET,SYNCER,HOST>{
+<RESOURCE,GLOBAL,IGNORE_SECTION,STARTUP,DISK,NET,SYNCER,HOST,HANDLERS>{
{IGNORE} update_lcnt();
\} yy_pop_state();
}
@@ -209,13 +209,14 @@
syncer section(SYNCER); return TK_SYNCER;
disk section(DISK); return TK_DISK_S;
net section(NET); return TK_NET;
+ handlers section(HANDLERS); return TK_HANDLERS;
protocol do_assign(PROTO); CP; return TK_PROTOCOL;
- incon-degr-cmd do_assign(STRING); CP; return TK_INCON_DEGR_CMD;
{NDELIM} {
expect_error(
"one of 'protocol|incon-degr-cmd|"
- "startup|disk|net|syncer|on <HOSTNAME>'");
+ "startup|disk|net|syncer|on <HOSTNAME>'|"
+ "handlers");
}
}
@@ -272,6 +273,18 @@
{NDELIM} expect_error("one of 'address|device|disk|meta-disk'");
}
+<HANDLERS>{
+ pri-on-incon-degr do_assign(STRING); CP; return TK_PRI_ON_INCON_DEGR;
+ pri-sees-sec-with-higher-gc do_assign(STRING); CP; return TK_PRI_SEES_SEC_WITH_HIGHER_GC;
+ on-disconnect do_assign(STRING); CP; return TK_ON_DISCONNECT;
+ {NDELIM} {
+ expect_error(
+ "one of 'pri-on-incon-degr|"
+ "pri-sees-sec-with-higher-gc|"
+ "on-disconnect");
+ }
+}
+
<*>{
\{ syntax_error("unexpected opening brace.");
\n syntax_error("unexpected end of line, maybe missing ';' ? ");
Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c 2004-11-22 14:31:35 UTC (rev 1648)
+++ trunk/user/drbdsetup.c 2004-11-22 22:35:08 UTC (rev 1649)
@@ -700,7 +700,6 @@
break;
case EIO:
fprintf(stderr,"Local replica is inconsistent (--do-what-I-say ?)\n");
- return 21;
}
return 20;
}
More information about the drbd-cvs
mailing list