[DRBD-cvs] svn commit by phil - r2395 - in trunk: . drbd drbd/linux user - * Implemented the last two missing options in the netli

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Sun Sep 10 14:02:55 CEST 2006


Author: phil
Date: 2006-09-10 14:02:54 +0200 (Sun, 10 Sep 2006)
New Revision: 2395

Modified:
   trunk/ROADMAP
   trunk/drbd/drbd_nl.c
   trunk/drbd/linux/drbd_nl.h
   trunk/user/drbdsetup.c
Log:
* Implemented the last two missing options in the netlink based
  drbdsetup. --wfc-timeout and --degr-wfc-timeout for the wait-*
  commands
* Fixed a bug in drbdsetup, where it assumed that the enum's of
  handler-names are continous.

I guess drbdsetup(netlink) is not usable.



Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-09-09 23:04:18 UTC (rev 2394)
+++ trunk/ROADMAP	2006-09-10 12:02:54 UTC (rev 2395)
@@ -442,7 +442,7 @@
   Things to do:
   
   * Locking in userspace, to prevent multiple instances of drbdsetup
-  * The timeout options of wait-connect and wait-sync are still missing.
+  * Think about locking in kernel space ( device_mutex? )
 
   80% DONE
 

Modified: trunk/drbd/drbd_nl.c
===================================================================
--- trunk/drbd/drbd_nl.c	2006-09-09 23:04:18 UTC (rev 2394)
+++ trunk/drbd/drbd_nl.c	2006-09-10 12:02:54 UTC (rev 2395)
@@ -1368,6 +1368,24 @@
 	return (int)((char*)tl - (char*)reply->tag_list);
 }
 
+
+STATIC int drbd_nl_get_timeout_flag(drbd_dev *mdev, struct drbd_nl_cfg_req *nlp,
+				    struct drbd_nl_cfg_reply *reply)
+{
+	unsigned short *tl;
+
+	tl = reply->tag_list;
+
+	// This is a hand crafted add tag ;)
+	*tl++ = T_use_degraded;
+	*tl++ = sizeof(char);
+	*((char*)tl) = test_bit(USE_DEGR_WFC_T,&mdev->flags) ? 1 : 0 ;
+	tl=(unsigned short*)((char*)tl + sizeof(char));
+	*tl++ = TT_END;
+
+	return (int)((char*)tl - (char*)reply->tag_list);
+}
+
 STATIC drbd_dev *ensure_mdev(struct drbd_nl_cfg_req *nlp)
 {
 	drbd_dev *mdev;
@@ -1428,6 +1446,9 @@
 				    sizeof(struct get_state_tag_len_struct) },
 	[ P_get_uuids ]		= { &drbd_nl_get_uuids,
 				    sizeof(struct get_uuids_tag_len_struct) },
+	[ P_get_timeout_flag ]	= { &drbd_nl_get_timeout_flag,
+				    sizeof(struct get_timeout_flag_tag_len_struct)},
+
 };
 
 void drbd_connector_callback(void *data)
@@ -1497,7 +1518,7 @@
 	unsigned short *tl = reply->tag_list;
 	static atomic_t seq = ATOMIC_INIT(2); // two.
 
-	WARN("drbd_bcast_state() got called\n");
+	// WARN("drbd_bcast_state() got called\n");
 
 	tl = get_state_to_tags(mdev,(struct get_state*)&mdev->state,tl);
 	*tl++ = TT_END; /* Close the tag list */

Modified: trunk/drbd/linux/drbd_nl.h
===================================================================
--- trunk/drbd/linux/drbd_nl.h	2006-09-09 23:04:18 UTC (rev 2394)
+++ trunk/drbd/linux/drbd_nl.h	2006-09-10 12:02:54 UTC (rev 2395)
@@ -78,6 +78,10 @@
 	INTEGER(  	35,	T_MAY_IGNORE,	uuids_flags)
 )
 
+PACKET(get_timeout_flag,
+	BIT(		36,	T_MAY_IGNORE,	use_degraded)
+)
+
 #undef PACKET
 #undef INTEGER
 #undef INT64

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2006-09-09 23:04:18 UTC (rev 2394)
+++ trunk/user/drbdsetup.c	2006-09-10 12:02:54 UTC (rev 2395)
@@ -45,6 +45,7 @@
 #include <string.h>
 #include <getopt.h>
 #include <stdlib.h>
+#include <sys/time.h>
 #include <time.h>
 
 #include <linux/netlink.h>
@@ -224,7 +225,7 @@
 	DRBD_ ## D ## _DEF } }
 #define EB      conv_bit, show_bit, bit_opt_usage, { } 
 #define ES      conv_string, show_string, string_opt_usage, { } 
-#define CLOSE_OPTIONS  { NULL,0,0,NULL,NULL,NULL, { } }, }} }, },
+#define CLOSE_OPTIONS  { NULL,0,0,NULL,NULL,NULL, { } }
 
 #define F_CONFIG_CMD	generic_config_cmd, config_usage
 #define F_GET_CMD	generic_get_cmd, get_usage
@@ -234,7 +235,7 @@
 	{"primary", P_primary, F_CONFIG_CMD, {{ NULL,
 	 (struct drbd_option[]) {
 		 { "overwrite-data-of-peer",'o',T_overwrite_peer, EB   },
-                 CLOSE_OPTIONS
+                 CLOSE_OPTIONS }} }, },
 
 	{"secondary", P_secondary, F_CONFIG_CMD, {{NULL, NULL}} },
 
@@ -248,7 +249,7 @@
 		 { "size",'d',		T_disk_size,	EN(DISK_SIZE_SECT,'s') },
 		 { "on-io-error",'e',	T_on_io_error,	EH(on_error,ON_IO_ERROR) },
 		 { "fencing",'f',	T_fencing,      EH(fencing_n,FENCING) },
-		 CLOSE_OPTIONS
+		 CLOSE_OPTIONS }} }, },
 
 	{"detach", P_detach, F_CONFIG_CMD, {{NULL, NULL}} },
 
@@ -274,21 +275,21 @@
 		 { "after-sb-1pri",'B',	T_after_sb_1p,EH(asb1p_n,AFTER_SB_1P) },
 		 { "after-sb-2pri",'C',	T_after_sb_2p,EH(asb2p_n,AFTER_SB_2P) },
 		 { "discard-my-data",'D', T_want_lose,     EB },
-		 CLOSE_OPTIONS
+		 CLOSE_OPTIONS }} }, },
 
 	{"disconnect", P_disconnect, F_CONFIG_CMD, {{NULL, NULL}} },
 
 	{"resize", P_resize, F_CONFIG_CMD, {{ NULL,
 	 (struct drbd_option[]) {
 		 { "size",'s',T_resize_size,		EN(DISK_SIZE_SECT,'s') },
-		 CLOSE_OPTIONS
+		 CLOSE_OPTIONS }} }, },
 
 	{"syncer", P_syncer_conf, F_CONFIG_CMD, {{ NULL,
 	 (struct drbd_option[]) {
 		 { "rate",'r',T_rate,			EN(RATE,'k') },
 		 { "after",'a',T_after,			EN(AFTER,1) },
 		 { "al-extents",'e',T_al_extents,	EN(AL_EXTENTS,1) },
-		 CLOSE_OPTIONS
+		 CLOSE_OPTIONS }} }, },
 
 	{"invalidate", P_invalidate, F_CONFIG_CMD, {{ NULL, NULL }} },
 	{"invalidate-remote", P_invalidate_peer, F_CONFIG_CMD, {{NULL, NULL}} },
@@ -307,11 +308,21 @@
 	{"events",          0, F_EVENTS_CMD, { .ep = {
 		(struct option[]) {
 			{ "unfiltered", no_argument, 0, 'u' },
-			{ "all-devices",no_argument, 0, 'd' },
+			{ "all-devices",no_argument, 0, 'a' },
 			{ 0,            0,           0,  0  } },
 		print_state } } },
-	{"wait-connect", 0, F_EVENTS_CMD, {.ep = {NULL,w_connected_state} } },
-	{"wait-sync", 0, F_EVENTS_CMD, {.ep = {NULL,w_synced_state} } },
+	{"wait-connect", 0, F_EVENTS_CMD, {.ep = {
+		(struct option[]) {
+			{ "wfc-timeout",required_argument, 0, 't' },
+			{ "degr-wfc-timeout",required_argument,0,'d'},
+			{ 0,            0,           0,  0  } },
+		w_connected_state} } },
+	{"wait-sync", 0, F_EVENTS_CMD, {.ep = {
+		(struct option[]) {
+			{ "wfc-timeout",required_argument, 0, 't' },
+			{ "degr-wfc-timeout",required_argument,0,'d'},
+			{ 0,            0,           0,  0  } },
+		w_synced_state} } },
 };
 
 #define EM(C) [ C - RetCodeBase ]
@@ -609,18 +620,18 @@
 {
 	const char** handler_names = od->handler_param.handler_names;
 	const int number_of_handlers = od->handler_param.number_of_handlers;
-	int i,nr;
+	int i,nr=-1;
 
 	for(i=0;i<number_of_handlers;i++) {
+		if(handler_names[i]==NULL) continue;
 		if(strcmp(arg,handler_names[i])==0) {
-			nr = i;
-			break;
+			add_tag(tl,od->tag,&nr,sizeof(i));
+			return 0;
 		}
 	}
-
-	add_tag(tl,od->tag,&nr,sizeof(nr));
-
-	return 0;
+	
+	fprintf(stderr, "Handler not known\n");
+	return 20;
 }
 
 int conv_string(struct drbd_option *od, struct drbd_tag_list *tl, char* arg)
@@ -753,7 +764,7 @@
 	add_tag(tl,TT_END,NULL,0); // close the tag list
 
 	if(rv == 0) {
-		// dump_tag_list(tl->tag_list_start);
+		//dump_tag_list(tl->tag_list_start);
 		sk_nl = open_cn();
 		if(sk_nl < 0) return 20;
 
@@ -897,6 +908,18 @@
 	return 0;
 }
 
+char consume_tag_bit(enum drbd_tags tag, unsigned short *tlc)
+{
+	unsigned short *tp;
+	tp = look_for_tag(tlc,tag);
+	if(tp) {
+		*tp++ = TT_REMOVED;
+		tp++;
+		return *(char *)tp;
+	}
+	return 0;
+}
+
 int generic_get_cmd(struct drbd_cmd *cm, int minor, int argc, 
 		    char **argv __attribute((unused)))
 {
@@ -1080,12 +1103,10 @@
 
 int print_state(unsigned int seq, int minor, drbd_state_t ns)
 {
-	/*
-	char stime[20];
-	time_t now;
-	time(&now);
-	strftime(stime,20,"%a %e %T",gmtime(&now));
-	*/
+	/*char stime[20];
+	  time_t now;
+	  time(&now);
+	  strftime(stime,20,"%a %e %T",gmtime(&now)); */
 
 	printf("%u ST %d { cs:%s st:%s/%s ds:%s/%s %c%c%c%c }\n",
 	       seq,
@@ -1127,18 +1148,41 @@
 	struct drbd_tag_list *tl;
 	struct option *lo;
 	unsigned int seq=0;
-	int sk_nl,c,cont=1;
+	int sk_nl,c,cont=1,rr;
 	drbd_state_t state;
 	int unfiltered=0, all_devices=0;
+	int wfc_timeout=0, degr_wfc_timeout=0,timeout_ms;
+	struct pollfd pfd;
+	struct timeval before,after;
 	
 	lo = cm->ep.options;
 
 	while( (c=getopt_long(argc,argv,make_optstring(lo,0),lo,0)) != -1 ) {
-		// This code block is actually only relevant for the "events" 
-		// command. not for wait-connect, or wait-sync.
 		switch(c) {
 		case 'u': unfiltered=1; break;
-		case 'd': all_devices=1; break;
+		case 'a': all_devices=1; break;
+		case 't': 
+			wfc_timeout=m_strtoll(optarg,1);
+			if(DRBD_WFC_TIMEOUT_MIN > wfc_timeout || 
+			   wfc_timeout > DRBD_WFC_TIMEOUT_MAX) {
+				fprintf(stderr, "wfc_timeout => %d"
+					" out of range [%d..%d]\n",
+					wfc_timeout, DRBD_WFC_TIMEOUT_MIN,
+					DRBD_WFC_TIMEOUT_MAX);
+				return 20;
+			}
+			break;
+		case 'd':
+			degr_wfc_timeout=m_strtoll(optarg,1);
+			if(DRBD_DEGR_WFC_TIMEOUT_MIN > degr_wfc_timeout || 
+			   degr_wfc_timeout > DRBD_DEGR_WFC_TIMEOUT_MAX) {
+				fprintf(stderr, "degr_wfc_timeout => %d"
+					" out of range [%d..%d]\n",
+					degr_wfc_timeout, DRBD_DEGR_WFC_TIMEOUT_MIN,
+					DRBD_DEGR_WFC_TIMEOUT_MAX);
+				return 20;
+			}
+			break;
 		}
 	}
 
@@ -1146,15 +1190,37 @@
 		fprintf(stderr,"Ignoring excess arguments\n");
 	}
 
+	tl = create_tag_list(2);
+	add_tag(tl,TT_END,NULL,0); // close the tag list
+
 	sk_nl = open_cn();
 	if(sk_nl < 0) return 20;
 
+	// Find out which timeout value to use.
+	send_tag_list_cn(sk_nl,tl,P_get_timeout_flag,minor,0);
+	receive_cn(sk_nl, (struct nlmsghdr*)buffer, 4096 );
+	cn_reply = (struct cn_msg *)NLMSG_DATA(buffer);
+	reply = (struct drbd_nl_cfg_reply *)cn_reply->data;
+	rr = consume_tag_bit(T_use_degraded,reply->tag_list);
+	timeout_ms= 1000 * (  rr ? degr_wfc_timeout : wfc_timeout) - 1;
+
 	// ask for the current state before waiting for state updates...
-	tl = create_tag_list(2);
-	add_tag(tl,TT_END,NULL,0); // close the tag list
 	send_tag_list_cn(sk_nl,tl,P_get_state,minor,0);
 
 	do {
+		pfd.fd = sk_nl;
+		pfd.events = POLLIN;
+
+		// printf("calling poll(,,%d)\n",timeout_ms);
+		gettimeofday(&before,NULL);
+		rr = poll(&pfd,1,timeout_ms);
+		if(rr == 0) return 5; // timeout expired.
+		gettimeofday(&after,NULL);
+
+		if(timeout_ms > 0 ) {
+			timeout_ms -= ( (after.tv_sec - before.tv_sec) * 1000 +
+					(after.tv_usec - before.tv_usec) / 1000 );
+		}
 		receive_cn(sk_nl, (struct nlmsghdr*)buffer, 4096 );
 
 		cn_reply = (struct cn_msg *)NLMSG_DATA(buffer);



More information about the drbd-cvs mailing list