[DRBD-cvs] svn commit by lars - r2306 - trunk/user - * drbdadm * added sh-ip command prints the local ip ass

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Fri Jul 28 13:45:53 CEST 2006


Author: lars
Date: 2006-07-28 13:45:47 +0200 (Fri, 28 Jul 2006)
New Revision: 2306

Modified:
   trunk/user/drbdadm.h
   trunk/user/drbdadm_adjust.c
   trunk/user/drbdadm_main.c
   trunk/user/drbdadm_parser.c
   trunk/user/drbdadm_parser.h
   trunk/user/drbdadm_scanner.fl
   trunk/user/drbdmeta.c
   trunk/user/drbdsetup.c
Log:
* drbdadm
  * added sh-ip command
    prints the local ip associated with the given resource
  * just call get_ifi_info once, if needed.
  * strip ip-checking from attach, detach and primary,
    it may be valid to use those commands even if the local ip is
    not currently configured/up
  * make configuration file parsing / verify errors print the
    correct line numbers and text tokens, added a few
    check_uniq()s that got lost, ...
  * make all compile warnings go away (but one about signedness
    from the flex generated drbdadm_scanner.c)


Modified: trunk/user/drbdadm.h
===================================================================
--- trunk/user/drbdadm.h	2006-07-28 10:41:09 UTC (rev 2305)
+++ trunk/user/drbdadm.h	2006-07-28 11:45:47 UTC (rev 2306)
@@ -33,7 +33,7 @@
 #define EXIT_ON_CONFLICT 1
 
 /* for verify_ips(): are not verifyable ips fatal? */
-#define INVALID_IP_IS_INVALID_CONF 0
+#define INVALID_IP_IS_INVALID_CONF 1
 
 enum usage_count_type {
   UC_YES,

Modified: trunk/user/drbdadm_adjust.c
===================================================================
--- trunk/user/drbdadm_adjust.c	2006-07-28 10:41:09 UTC (rev 2305)
+++ trunk/user/drbdadm_adjust.c	2006-07-28 11:45:47 UTC (rev 2306)
@@ -139,7 +139,7 @@
 	return !strcmp(conf->protocol, running->protocol);
 }
 
-static int dev_eq(char* device_name, int g_major, int g_minor)
+static int dev_eq(char* device_name, unsigned int g_major, unsigned int g_minor)
 {
 	struct stat sb;
 	

Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c	2006-07-28 10:41:09 UTC (rev 2305)
+++ trunk/user/drbdadm_main.c	2006-07-28 11:45:47 UTC (rev 2306)
@@ -97,6 +97,7 @@
 static int sh_resources(struct d_resource* ,const char* );
 static int sh_mod_parms(struct d_resource* ,const char* );
 static int sh_dev(struct d_resource* ,const char* );
+static int sh_ip(struct d_resource* ,const char* );
 static int sh_ll_dev(struct d_resource* ,const char* );
 static int sh_md_dev(struct d_resource* ,const char* );
 static int sh_md_idx(struct d_resource* ,const char* );
@@ -115,6 +116,7 @@
 char *config_file = NULL;
 struct d_resource* config = NULL;
 struct d_resource* common = NULL;
+struct ifi_info *my_ifis = NULL;
 int nr_resources;
 int highest_minor;
 int config_valid=1;
@@ -183,13 +185,13 @@
 
 struct adm_cmd cmds[] = {
 /*   name, function,                  show, needs res, verify_ips */
-  { "attach",            adm_attach,    1,1,1 },
-  { "detach",            adm_generic_s, 1,1,1 },
+  { "attach",            adm_attach,    1,1,0 },
+  { "detach",            adm_generic_s, 1,1,0 },
   { "connect",           adm_connect,   1,1,1 },
   { "disconnect",        adm_generic_s, 1,1,0 },
   { "up",                adm_up,        1,1,1 },
   { "down",              adm_generic_s, 1,1,0 },
-  { "primary",           adm_generic_s, 1,1,1 },
+  { "primary",           adm_generic_s, 1,1,0 },
   { "secondary",         adm_generic_s, 1,1,1 },
   { "invalidate",        adm_generic_l, 1,1,1 },
   { "invalidate_remote", adm_generic_l, 1,1,1 },
@@ -217,6 +219,7 @@
   { "sh-ll-dev",         sh_ll_dev,     2,1,0 },
   { "sh-md-dev",         sh_md_dev,     2,1,0 },
   { "sh-md-idx",         sh_md_idx,     2,1,0 },
+  { "sh-ip",             sh_ip,         0,1,0 },
   { "pri-on-incon-degr", adm_khelper,   3,1,0 },
   { "pri-lost-after-sb", adm_khelper,   3,1,0 },
   { "outdate-peer",      adm_khelper,   3,1,0 },
@@ -356,6 +359,13 @@
   return 0;
 }
 
+static int sh_ip(struct d_resource* res,const char* unused __attribute((unused)))
+{
+  printf("%s\n",res->me->address);
+
+  return 0;
+}
+
 static int sh_ll_dev(struct d_resource* res,const char* unused __attribute((unused)))
 {
   printf("%s\n",res->me->disk);
@@ -417,6 +427,7 @@
   }
 }
 
+static void free_ifi_info(struct ifi_info *ifihead);
 static void free_config(struct d_resource* res)
 {
   struct d_resource *f,*t;
@@ -440,6 +451,7 @@
     free_options(common->handlers);
     free(common);
   }
+  if (my_ifis) free_ifi_info(my_ifis);
 }
 
 static void expand_opts(struct d_option* co, struct d_option** opts)
@@ -1278,28 +1290,28 @@
   return ifihead;
 }
 
-void verify_ips(struct d_resource* res)
+int have_ip(const char *ip)
 {
   struct ifi_info *ifi, *ifihead;
-  int family, valid = 0;
+  int family;
   uint32_t addr = 0;
   struct in_addr sin_addr;
-  const char *my_ip;
 
-  my_ip = res->me->address;
-  sin_addr.s_addr = inet_addr(my_ip);
+  sin_addr.s_addr = inet_addr(ip);
 
-  /* does DRBD support inet6? */
+  /* FIXME make DRBD support inet6 */
   family = AF_INET;
+  if (!my_ifis) my_ifis = get_ifi_info(family);
     
-  for (ifihead = ifi = get_ifi_info(family); ifi != NULL; ifi = ifi->ifi_next) {        
+  for (ifihead = ifi = my_ifis; ifi != NULL; ifi = ifi->ifi_next) {
     switch (family) {
     case AF_INET: {
       struct sockaddr_in * sin = (struct sockaddr_in *)ifi->ifi_addr;
       addr = sin->sin_addr.s_addr;
 
-      if (addr == sin_addr.s_addr) /* loop a few times needlessly */
-	valid = 1;
+      if (addr == sin_addr.s_addr) {
+	return 1;
+      }
       break;
     }
     default:
@@ -1307,15 +1319,26 @@
     }
   }
 
-  free_ifi_info(ifihead);
+  return 0;
+}
 
-  if (valid == 0) {
-    fprintf(stderr, "OOPS, the IP address %s isn't configure/up on your system!\n", my_ip);
-#if INVALID_IP_IS_INVALID_CONF
+void verify_ips(struct d_resource *res)
+{
+	if (global_options.disable_ip_verification) return;
+	if (dry_run == 1 || do_verify_ips == 0) return;
+
+	if (! have_ip(res->me->address)) {
+		ENTRY e, *ep;
+		e.key = e.data = ep = NULL;
+		asprintf(&e.key, "%s:%s", res->me->address, res->me->port);
+		ep = hsearch(e, FIND);
+		fprintf(stderr, "%s:%d: in resource %s, on %s:\n\t"
+			"IP %s not found on this host.\n",
+			config_file, (int)(long)ep->data, res->name,
+			res->me->name, res->me->address);
+		if (INVALID_IP_IS_INVALID_CONF)
     config_valid = 0;
-#endif
   }
-  return;
 }
 
 static char* conf_file[] = {

Modified: trunk/user/drbdadm_parser.c
===================================================================
--- trunk/user/drbdadm_parser.c	2006-07-28 10:41:09 UTC (rev 2305)
+++ trunk/user/drbdadm_parser.c	2006-07-28 11:45:47 UTC (rev 2306)
@@ -3,8 +3,9 @@
 
    This file is part of drbd by Philipp Reisner.
 
-   Copyright (C) 2006, Philipp Reisner <philipp.reisner at linbit.com>.
-        Initial author.
+   Copyright (C) 2006, Philipp Reisner <philipp.reisner at linbit.com>
+   Copyright (C) 2006, Lars Ellenberg  <lars.ellenberg at linbit.com>
+   Copyright (C) 2006, LINBIT Information Technologies GmbH
 
    drbd is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -21,6 +22,7 @@
    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
  */
+
 #define _GNU_SOURCE
 
 #include <stdlib.h>
@@ -205,7 +207,7 @@
 	int token; 						\
 	token = yylex(); 					\
 	if(token != TOKEN1)					\
-		pe_expected_got( #TOKEN1, token, yylval.txt); 	\
+		pe_expected_got( #TOKEN1, token);		\
 	token;							\
 })
 
@@ -214,26 +216,37 @@
 	int token; 							\
 	token = yylex(); 						\
 	if(token != TOKEN1 && token != TOKEN2) 				\
-		pe_expected_got( #TOKEN1 "|" # TOKEN2, token, yylval.txt ); \
+		pe_expected_got( #TOKEN1 "|" # TOKEN2, token);		\
 	token;								\
 })
 
-static void pe_expected(const char *exp, char* got_txt)
+static void pe_expected(const char *exp)
 {
-	fprintf(stderr,"Parse error '%s' expected,\n"
-		"but got '%s' at line %d\n",exp,got_txt,line);
-	exit(10);
+	fprintf(stderr,"%s:%u: Parse error: '%s' expected,\n\t"
+		"but got '%s'\n",config_file,line,exp,yytext);
+	exit(E_config_invalid);
 }
 
-static void pe_expected_got(const char *exp, int got, char* got_txt)
+static void pe_expected_got(const char *exp, int got)
 {
-	fprintf(stderr,"Parse error '%s' expected,\n"
-		"but got '%s' (TK %d) at line %d\n",
-		exp,got_txt,got,line);
-	exit(10);
+	static char tmp[2] = "\0";
+	if (exp[0] == '\'' && exp[1] && exp[2] == '\'' && exp[3] == 0) {
+		tmp[0] = exp[1];
+	}
+	fprintf(stderr,"%s:%u: Parse error: '%s' expected,\n\t"
+		"but got '%s' (TK %d)\n",config_file,line,exp,yytext,got);
+	exit(E_config_invalid);
 }
 
 static void parse_global(void) {
+	fline = line;
+	check_uniq("global section","global");
+	if (config) {
+		fprintf(stderr,
+			"%s:%u: You should put the global {} section\n\t"
+			"in front of any resource {} section\n",
+			config_file,line);
+	}
 	EXP('{');
 	while(1) {
 		switch(yylex()) {
@@ -255,14 +268,14 @@
 			case TK_YES: global_options.usage_count=UC_YES; break; 
 			case TK_NO:  global_options.usage_count=UC_NO;  break; 
 			case TK_ASK: global_options.usage_count=UC_ASK; break; 
-			default:     pe_expected("yes | no | ask",yylval.txt);
+			default:     pe_expected("yes | no | ask");
 			}
 			break;
 		case '}':
 			return;
 		default:
 			pe_expected("dialog-refresh | minor-count | "
-				    "disable-ip-verification",yylval.txt);
+				    "disable-ip-verification");
 		}
 		EXP(';');
 	}
@@ -275,6 +288,7 @@
 	enum range_checks rc;
 
 	struct d_option* options = NULL, *ro = NULL;
+	fline = line;
 
 	EXP('{');
 	while(1) {
@@ -291,7 +305,7 @@
 		} else if ( token == '}' ) {
 			return options;
 		} else {
-			pe_expected("an option keyword",yylval.txt);
+			pe_expected("an option keyword");
 		}
 		switch(yylex()) {
 		case TK__IS_DEFAULT:
@@ -301,7 +315,7 @@
 		case ';':
 			break;
 		default:
-			pe_expected("_is_default | ;",yylval.txt);
+			pe_expected("_is_default | ;");
 		}
 	}
 }
@@ -314,6 +328,7 @@
 	while(1) {
 		switch(yylex()) {
 		case TK_DISK:
+			check_uniq("disk statement","%s:%s:disk",res->name,host->name);
 			EXP(TK_STRING);
 			host->disk = yylval.txt;
 			check_uniq("disk", "%s:%s:%s","disk",
@@ -329,10 +344,11 @@
 			case ';':
 				break;
 			default:
-				pe_expected("_major | ;",yylval.txt);
+				pe_expected("_major | ;");
 			}
 			break;
 		case TK_DEVICE:
+			check_uniq("device statement","%s:%s:device",res->name,host->name);
 			EXP(TK_STRING);
 			host->device = yylval.txt;
 			check_uniq("device", "%s:%s:%s","device",
@@ -340,15 +356,18 @@
 			EXP(';');
 			break;
 		case TK_ADDRESS:
+			check_uniq("address statement","%s:%s:address",res->name,host->name);
 			EXP(TK_IPADDR);
 			host->address = yylval.txt;
 			EXP(':');
 			EXP(TK_INTEGER);
 			host->port = yylval.txt;
 			range_check(R_PORT, "port", yylval.txt);
+			check_uniq("IP","%s:%s", host->address,host->port);
 			EXP(';');
 			break;
 		case TK_META_DISK:
+			check_uniq("meta-disk statement","%s:%s:meta-disk",res->name,host->name);
 			EXP(TK_STRING);
 			host->meta_disk = yylval.txt;
 			if(strcmp("internal",yylval.txt)) {
@@ -367,7 +386,7 @@
 				case ';':
 					break;
 				default:
-					pe_expected("_major | ;",yylval.txt);
+					pe_expected("_major | ;");
 				}
 			} else {
 				EXP(';');
@@ -375,6 +394,7 @@
 			check_meta_disk(host);
 			break;
 		case TK_FLEX_META_DISK:
+			check_uniq("meta-disk statement","%s:%s:meta-disk",res->name,host->name);
 			EXP(TK_STRING);
 			host->meta_disk = yylval.txt;
 			host->meta_index = strdup("flexible");
@@ -385,7 +405,7 @@
 			goto break_loop;
 		default:
 			pe_expected("disk | device | address | meta-disk "
-				    "| flex-meta-disk",yylval.txt);
+				    "| flex-meta-disk");
 		}
 	}
  break_loop:
@@ -396,16 +416,55 @@
 	if (!host->meta_disk)	derror(host,res,"meta-disk");
 }
 
+void parse_skip()
+{
+	int level;
+	fline = line;
+
+	switch (yylex()) {
+		case TK_STRING:
+			EXP('{');
+			break;
+		case '{':
+			break;
+		default:
+			pe_expected("[ some_text ] {");
+	}
+
+	level = 1;
+	while(level) {
+		switch(yylex()) {
+		case '{':
+			level++; /* if you really want to,
+				    you can wrap this with a GB size config file :) */
+			break;
+		case '}':
+			level--;
+			break;
+		case 0:
+			fprintf(stderr,"%s:%u: reached eof "
+				"while parsing this skip block.\n",
+				config_file, fline);
+			exit(E_config_invalid);
+		}
+	} while(level);
+}
+
+
 static void parse_host_section(struct d_resource* res)
 {
 	struct d_host_info *host;
 
 	c_section_start = line;
+	fline = line;
 
 	host=calloc(1,sizeof(struct d_host_info));
 	EXP(TK_STRING);
 	host->name = yylval.txt;
+
+	check_uniq("host section", "%s: on %s", res->name, host->name);
 	if(strcmp(host->name, nodeinfo.nodename) == 0) {
+		// if (res->me) die duplicate entry ... done by check_uniq above
 		res->me = host;
 	} else {
 		if (res->peer) {
@@ -444,6 +503,8 @@
 	struct d_resource* res;
 	int token;
 
+	fline = line;
+
 	res=calloc(1,sizeof(struct d_resource));
 	res->name = res_name;
 	res->next = NULL;
@@ -451,6 +512,7 @@
 	while(1) {
 		switch((token=yylex())) {
 		case TK_PROTOCOL:
+			check_uniq("protocol statement","%s: protocol",res->name);
 			EXP(TK_STRING);
 			res->protocol=yylval.txt;
 			EXP(';');
@@ -465,50 +527,39 @@
 			parse_drbdsetup_host_dump(res, 0);
 			break;
 		case TK_DISK:
+			check_uniq("disk section", "%s:disk", res->name);
 			res->disk_options = parse_options(TK_DISK_SWITCH,
 							  TK_DISK_OPTION);
 			break;
 		case TK_NET: 
+			check_uniq("net section", "%s:net", res->name);
 			res->net_options = parse_options(TK_NET_SWITCH,
 							 TK_NET_OPTION);
 			break;
 		case TK_SYNCER:
+			check_uniq("syncer section", "%s:syncer", res->name);
 			res->sync_options = parse_options(TK_SYNCER_SWITCH,
 							  TK_SYNCER_OPTION);
 			break;
 		case TK_STARTUP:
+			check_uniq("startup section", "%s:startup", res->name);
 			res->startup_options=parse_options(TK_STARTUP_SWITCH,
 							   TK_STARTUP_OPTION);
 			break;
 		case TK_HANDLER:
-			res->handlers =  parse_options(0,
-						       TK_HANDLER_OPTION);
+			check_uniq("handlers section", "%s:handlers", res->name);
+			res->handlers =  parse_options(0, TK_HANDLER_OPTION);
 			break;
 		case '}': 
 		case 0:	
 			return res;
 		default:
 			pe_expected_got("protocol | on | disk | net | syncer |"
-					" startup | handler",token,yylval.txt);
+					" startup | handler",token);
 		}
 	}
 }
 
-void parse_skip()
-{
-	int level=0;
-	do {
-		switch(yylex()) {
-		case '{': 
-			level++;
-			break;
-		case '}': 
-			level--;
-			break;
-		}
-	} while(level);
-}
-
 void yyparse(void)
 {
 	common = NULL;
@@ -516,7 +567,9 @@
 
 	while(1) {
 		switch(yylex()) {
-		case TK_GLOBAL: parse_global(); break;
+		case TK_GLOBAL:
+			parse_global();
+			break;
 		case TK_COMMON: 
 			EXP('{');
 			common = parse_resource("common"); 
@@ -529,8 +582,7 @@
 		case TK_SKIP: parse_skip(); break;
 		case 0: return;
 		default:
-			pe_expected("global | common | resource | skip",
-				    yylval.txt);
+			pe_expected("global | common | resource | skip");
 		}
 	}
 }

Modified: trunk/user/drbdadm_parser.h
===================================================================
--- trunk/user/drbdadm_parser.h	2006-07-28 10:41:09 UTC (rev 2305)
+++ trunk/user/drbdadm_parser.h	2006-07-28 11:45:47 UTC (rev 2306)
@@ -101,6 +101,7 @@
 #define YYSTYPE_IS_TRIVIAL 1
 
 extern yystype yylval;
+extern char* yytext;
 
 /* avoid compiler warnings about implicit declaration */
 int yylex(void);

Modified: trunk/user/drbdadm_scanner.fl
===================================================================
--- trunk/user/drbdadm_scanner.fl	2006-07-28 10:41:09 UTC (rev 2305)
+++ trunk/user/drbdadm_scanner.fl	2006-07-28 11:45:47 UTC (rev 2306)
@@ -20,8 +20,6 @@
 #define YY_NO_UNPUT 1
 static void yyunput (int c, register char * yy_bp ) __attribute((unused));
 
-int skip_level=0;
-
 %}
 
 %option noyywrap
@@ -35,12 +33,10 @@
 STRING		[a-zA-Z0-9/._-]{1,80}
 LONG_STRING	[a-zA-Z0-9/._-]{81}
 
-%x in_string id skip
-
 %%
 
 \n			{ line++; 				}
-#[^\n]*			/* ignore comments */
+\#.*			/* ignore comments */
 {WS}			/* ignore whitespaces */
 {OPCHAR}		{ DP; return yytext[0];			}
 on			{ DP; return TK_ON;			}
@@ -101,7 +97,7 @@
 {DQSTRING}		{ unescape(); DP; CP; return TK_STRING;	}
 {STRING}		{ DP; CP; return TK_STRING;		}
 {LONG_STRING}		{ long_string( yylval.txt ); 		}
-[^\n]			{ DP; return TK_ELSE;			}
+.			{ DP; return TK_ELSE;			}
 
 %%
 

Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2006-07-28 10:41:09 UTC (rev 2305)
+++ trunk/user/drbdmeta.c	2006-07-28 11:45:47 UTC (rev 2306)
@@ -1067,9 +1067,9 @@
 	return 0;
 }
 
-int m_strsep_bit(char **s, int *val, int mask)
+int m_strsep_bit(char **s, u32 *val, int mask)
 {
-	int d;
+	u32 d;
 	int rv;
 
 	d = *val & mask ? 1 : 0;

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2006-07-28 10:41:09 UTC (rev 2305)
+++ trunk/user/drbdsetup.c	2006-07-28 11:45:47 UTC (rev 2306)
@@ -1247,7 +1247,7 @@
   return 0;
 }
 
-const char* guess_dev_name(const char* dir,int g_major,int g_minor)
+const char* guess_dev_name(const char* dir,unsigned int g_major,unsigned int g_minor)
 {
   DIR* device_dir;
   struct dirent* dde;



More information about the drbd-cvs mailing list