[DRBD-cvs] svn commit by phil - r2434 - trunk/user - * Missing userland parts of the last commit. * Made the

drbd-cvs at lists.linbit.com drbd-cvs at lists.linbit.com
Wed Sep 20 12:20:52 CEST 2006


Author: phil
Date: 2006-09-20 12:20:51 +0200 (Wed, 20 Sep 2006)
New Revision: 2434

Modified:
   trunk/user/drbdadm_scanner.fl
   trunk/user/drbdadm_usage_cnt.c
   trunk/user/drbdsetup.c
   trunk/user/drbdtool_common.c
   trunk/user/drbdtool_common.h
Log:
* Missing userland parts of the last commit.
* Made the consume_tag_*() functions sane.
* Implemented correct handling of seq & ack members of the cn_msg
  packets.

The visible bug this fixes was:

 When doint 'drbdadm up r0', the attach and the connect processes
 overlapped. Altough this allowed to fix quite some bugs in the
 kernel code, it was actually a bug in drbdsetup. drbdsetup interpreted
 the state-change-broadcast as the answer to a config cmd. This
 is fixed now.
 


Modified: trunk/user/drbdadm_scanner.fl
===================================================================
--- trunk/user/drbdadm_scanner.fl	2006-09-20 08:35:23 UTC (rev 2433)
+++ trunk/user/drbdadm_scanner.fl	2006-09-20 10:20:51 UTC (rev 2434)
@@ -68,6 +68,7 @@
 size			{ DP; CP; RC(DISK_SIZE); return TK_DISK_OPTION;	}
 on-io-error		{ DP; CP; return TK_DISK_OPTION;	}
 fencing			{ DP; CP; return TK_DISK_OPTION;	}
+use-bmbv		{ DP; CP; return TK_DISK_SWITCH;		}
 timeout			{ DP; CP; RC(TIMEOUT); return TK_NET_OPTION;	}
 ko-count		{ DP; CP; RC(KO_COUNT); return TK_NET_OPTION;	}
 ping-int		{ DP; CP; RC(PING_INT); return TK_NET_OPTION;	}

Modified: trunk/user/drbdadm_usage_cnt.c
===================================================================
--- trunk/user/drbdadm_usage_cnt.c	2006-09-20 08:35:23 UTC (rev 2433)
+++ trunk/user/drbdadm_usage_cnt.c	2006-09-20 10:20:51 UTC (rev 2434)
@@ -130,22 +130,6 @@
 	return svn_rev;
 }
 
-static void get_random_bytes(void* buffer, int len)
-{
-	int fd;
-
-	fd = open("/dev/random",O_RDONLY);
-	if( fd == -1) {
-		perror("Open of /dev/random failed");
-		exit(20);
-	}
-	if(read(fd,buffer,len) != len) {
-		fprintf(stderr,"Reading from /dev/random failed\n");
-		exit(20);
-	}
-	close(fd);	
-}
-
 static void write_node_id(struct node_info *ni)
 {
 	int fd;

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2006-09-20 08:35:23 UTC (rev 2433)
+++ trunk/user/drbdsetup.c	2006-09-20 10:20:51 UTC (rev 2434)
@@ -128,8 +128,9 @@
 // Connector functions
 int open_cn();
 int send_cn(int sk_nl, struct nlmsghdr* nl_hdr, int size);
+int receive_cn(int sk_nl, struct nlmsghdr* nl_hdr, int size);
 int send_tag_list_cn(int, struct drbd_tag_list *, const int, int, int);
-int receive_cn(int sk_nl, struct nlmsghdr* nl_hdr, int size);
+int receive_reply_cn(int, struct drbd_tag_list *, struct nlmsghdr*,int);
 void close_cn(int sk_nl);
 
 // other functions
@@ -255,6 +256,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) },
+		 { "use-bmbv",'b',	T_use_bmbv,     EB },
 		 CLOSE_OPTIONS }} }, },
 
 	{"detach", P_detach, F_CONFIG_CMD, {{NULL, NULL}} },
@@ -368,7 +370,6 @@
 	EM(FailedToClaimMyself) = "FailedToClaimMyself",
 };
 
-const char empty_string[] = "";
 char* cmdname = 0;
 
 int dump_tag_list(unsigned short *tlc)
@@ -767,8 +768,7 @@
 		if(sk_nl < 0) return 20;
 
 		send_tag_list_cn(sk_nl,tl,cm->packet_id,minor,flags);
-
-		receive_cn(sk_nl, (struct nlmsghdr*)buffer, RCV_SIZE );
+		receive_reply_cn(sk_nl, tl, (struct nlmsghdr*)buffer, RCV_SIZE );
 		close_cn(sk_nl);
 		reply = (struct drbd_nl_cfg_reply *)
 			((struct cn_msg *)NLMSG_DATA(buffer))->data;
@@ -870,50 +870,57 @@
 }
 
 
-const char* consume_tag_blob(enum drbd_tags tag, unsigned short *tlc, 
-			     unsigned int* len)
+int consume_tag_blob(enum drbd_tags tag, unsigned short *tlc, 
+		     char** val, unsigned int* len)
 {
 	unsigned short *tp;
 	tp = look_for_tag(tlc,tag);
 	if(tp) {
 		*tp++ = TT_REMOVED;
 		*len = *tp++;
-		return (char*)tp;
+		*val = (char*)tp;
+		return 1;
 	}
-	return NULL;
+	return 0;
 }
 
-const char* consume_tag_string(enum drbd_tags tag, unsigned short *tlc)
+int consume_tag_string(enum drbd_tags tag, unsigned short *tlc, char** val)
 {
 	unsigned short *tp;
 	tp = look_for_tag(tlc,tag);
 	if(tp) {
 		*tp++ = TT_REMOVED;
-		if( *tp++ > 0) return (char*)tp;
+		if( *tp++ > 0 )
+			*val = (char*)tp;
+		else 
+			*val = "";
+		return 1;
 	}
-	return empty_string;
+	return 0;
 }
 
-int consume_tag_int(enum drbd_tags tag, unsigned short *tlc)
+int consume_tag_int(enum drbd_tags tag, unsigned short *tlc, int* val)
 {
 	unsigned short *tp;
 	tp = look_for_tag(tlc,tag);
 	if(tp) {
 		*tp++ = TT_REMOVED;
 		tp++;
-		return *(int *)tp;
+		*val = *(int *)tp;
+		return 1;
 	}
 	return 0;
 }
 
-char consume_tag_bit(enum drbd_tags tag, unsigned short *tlc)
+int consume_tag_bit(enum drbd_tags tag, unsigned short *tlc, int* val)
 {
 	unsigned short *tp;
 	tp = look_for_tag(tlc,tag);
 	if(tp) {
 		*tp++ = TT_REMOVED;
 		tp++;
-		return *(char *)tp;
+		*val = (int)(*(char *)tp);
+		return 1;
 	}
 	return 0;
 }
@@ -937,8 +944,8 @@
 	if(sk_nl < 0) return 20;
 
 	send_tag_list_cn(sk_nl,tl,cm->packet_id,minor,0);
+	receive_reply_cn(sk_nl,tl, (struct nlmsghdr*)buffer, 4096 );
 
-	receive_cn(sk_nl, (struct nlmsghdr*)buffer, 4096 );
 	close_cn(sk_nl);
 	reply = (struct drbd_nl_cfg_reply *)
 		((struct cn_msg *)NLMSG_DATA(buffer))->data;
@@ -956,7 +963,7 @@
 int show_scmd(struct drbd_cmd *cm, int minor, unsigned short *rtl)
 {
 	int idx;
-	const char* str;
+	char* str;
 	struct sockaddr_in *addr;
 
 	// find all commands that have options and print those...
@@ -966,30 +973,26 @@
 	}
 
 	// start of spagethi code...
-	idx = consume_tag_int(T_wire_protocol,rtl);
-	if(idx) printf("protocol %c;\n",'A'+idx-1);
-	str = consume_tag_string(T_backing_dev,rtl);
-	if(str != empty_string) {
+	if(consume_tag_int(T_wire_protocol,rtl,&idx))
+		printf("protocol %c;\n",'A'+idx-1);
+	if(consume_tag_string(T_backing_dev,rtl,&str)) {
 		printf("_this_host {\n");
 		printf("\tdevice\t\t\t\"/dev/drbd%d\";\n",minor);
 		printf("\tdisk\t\t\t\"%s\";\n",str);
-		idx=consume_tag_int(T_meta_dev_idx,rtl);
+		consume_tag_int(T_meta_dev_idx,rtl,&idx);
+		consume_tag_string(T_meta_dev,rtl,&str);
 		switch(idx) {
 		case DRBD_MD_INDEX_INTERNAL:
 		case DRBD_MD_INDEX_FLEX_INT:
 			printf("\tmeta-disk\t\tinternal;\n");
-			consume_tag_string(T_meta_dev,rtl);
 			break;
 		case DRBD_MD_INDEX_FLEX_EXT:
-			printf("\tflexible-meta-disk\t\"%s\";\n",
-			       consume_tag_string(T_meta_dev,rtl));
+			printf("\tflexible-meta-disk\t\"%s\";\n",str);
 			break;
 		default:
-			printf("\tmeta-disk\t\t\"%s\" [ %d ];\n",
-			       consume_tag_string(T_meta_dev,rtl),idx);
+			printf("\tmeta-disk\t\t\"%s\" [ %d ];\n",str,idx);
 		}
-		str = consume_tag_string(T_my_addr,rtl);
-		if(str != empty_string ) {
+		if(consume_tag_string(T_my_addr,rtl,&str)) {
 			addr = (struct sockaddr_in *)str;
 			printf("\taddress\t\t\t%s:%d;\n",
 			       inet_ntoa(addr->sin_addr),
@@ -998,8 +1001,7 @@
 		printf("}\n");
 	}
 
-	str = consume_tag_string(T_peer_addr,rtl);
-	if(str != empty_string) {
+	if(consume_tag_string(T_peer_addr,rtl,&str)) {
 		printf("_remote_host {\n");
 		addr = (struct sockaddr_in *)str;
 		printf("\taddress\t\t\t%s:%d;\n",
@@ -1016,7 +1018,7 @@
 	       unsigned short *rtl)
 {
 	drbd_state_t state;
-	state = (drbd_state_t)(unsigned int)consume_tag_int(T_state_i,rtl);
+	consume_tag_int(T_state_i,rtl,(int*)&state.i);
 	printf("%s\n",roles_to_name(state.role));
 	return 0;
 }
@@ -1026,7 +1028,7 @@
 		unsigned short *rtl)
 {
 	drbd_state_t state;
-	state = (drbd_state_t)(unsigned int)consume_tag_int(T_state_i,rtl);
+	consume_tag_int(T_state_i,rtl,(int*)&state.i);
 	printf("%s\n",conns_to_name(state.conn));
 	return 0;
 }
@@ -1036,7 +1038,7 @@
 		unsigned short *rtl)
 {
 	drbd_state_t state;
-	state = (drbd_state_t)(unsigned int)consume_tag_int(T_state_i,rtl);
+	consume_tag_int(T_state_i,rtl,(int*)&state.i);
 	printf("%s\n",disks_to_name(state.disk));
 	return 0;
 }
@@ -1047,15 +1049,14 @@
 {
 	__u64 *uuids;
 	int flags;
-	unsigned int len = 4711;
+	unsigned int len;
 
-	uuids = (__u64 *)consume_tag_blob(T_uuids,rtl,&len);
-	if(len == 4711) {
+	if(!consume_tag_blob(T_uuids,rtl,(char **) &uuids,&len)) {
 		fprintf(stderr,"Reply payload did not carry an uuid-tag,\n"
 			"Probabely the device has no disk!\n");
 		return 1;
 	}
-	flags = consume_tag_int(T_uuids_flags,rtl);
+	consume_tag_int(T_uuids_flags,rtl,&flags);
 	if( len == UUID_SIZE * sizeof(__u64)) {
 		if(!strcmp(cm->cmd,"show-gi")) {
 			dt_pretty_print_uuids(uuids,flags);
@@ -1199,10 +1200,10 @@
 
 	// 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 );
+	receive_reply_cn(sk_nl,tl, (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);
+	consume_tag_bit(T_use_degraded,reply->tag_list,&rr);
 	timeout_ms= 1000 * (  rr ? degr_wfc_timeout : wfc_timeout) - 1;
 
 	// ask for the current state before waiting for state updates...
@@ -1232,8 +1233,14 @@
 		if(!unfiltered && cn_reply->seq <= seq) continue;
 		seq = cn_reply->seq;
 
-		state.i = consume_tag_int(T_state_i,reply->tag_list);
-		
+		if(!consume_tag_int(T_state_i,reply->tag_list,(int*)&state.i)) {
+			if( all_devices || minor == reply->minor ) {
+				printf("%u ?? %d <other message>\n",cn_reply->seq,
+				       reply->minor);
+			}
+			continue;
+		}
+
 		if(dump_tag_list(reply->tag_list)) {
 			printf("# Found unknown tags, you should update your\n"
 			       "# userland tools\n");
@@ -1422,6 +1429,7 @@
 
 int send_cn(int sk_nl, struct nlmsghdr* nl_hdr, int size)
 {
+	static __u32 cn_seq = 1;
 	struct cn_msg *cn_hdr;
 	cn_hdr = (struct cn_msg *)NLMSG_DATA(nl_hdr);
 	int rr;
@@ -1434,8 +1442,8 @@
 	nl_hdr->nlmsg_pid = getpid();
 	/* fill the connector header */
 	cn_hdr->id.idx = CN_IDX_DRBD;
-	cn_hdr->seq = 1;
-	cn_hdr->ack = 0;
+	cn_hdr->seq = cn_seq++;
+	get_random_bytes(&cn_hdr->ack,sizeof(cn_hdr->ack));
 	cn_hdr->len = size - sizeof(struct nlmsghdr) - sizeof(struct cn_msg);
 
 	rr = send(sk_nl,nl_hdr,nl_hdr->nlmsg_len,0);
@@ -1459,6 +1467,31 @@
 	return rr;
 }
 
+int receive_reply_cn(int sk_nl, struct drbd_tag_list *tl, struct nlmsghdr* nl_hdr, 
+		     int size)
+{
+	struct cn_msg *request_cn_hdr;
+	struct cn_msg *reply_cn_hdr;
+	int rr;
+
+	request_cn_hdr = (struct cn_msg *)NLMSG_DATA(tl->nl_header);
+	reply_cn_hdr = (struct cn_msg *)NLMSG_DATA(nl_hdr);
+
+	while(1) {
+		rr = receive_cn(sk_nl,nl_hdr,size);
+		if( rr < 0 ) return -1;
+		if(reply_cn_hdr->seq == request_cn_hdr->seq &&
+		   reply_cn_hdr->ack == request_cn_hdr->ack+1 ) return rr;
+		/* printf("INFO: got other message \n"
+		   "got seq: %d ; ack %d \n"
+		   "exp seq: %d ; ack %d \n", 
+		   reply_cn_hdr->seq,reply_cn_hdr->ack,
+		   request_cn_hdr->seq,request_cn_hdr->ack); */
+	}
+
+	return rr;
+}
+
 int send_tag_list_cn(int sk_nl, struct drbd_tag_list *tl, const int packet_id, int minor, int flags)
 {
 	tl->cn_header->id.val = CN_VAL_DRBD;

Modified: trunk/user/drbdtool_common.c
===================================================================
--- trunk/user/drbdtool_common.c	2006-09-20 08:35:23 UTC (rev 2433)
+++ trunk/user/drbdtool_common.c	2006-09-20 10:20:51 UTC (rev 2434)
@@ -428,3 +428,19 @@
 
 	return size64;
 }
+
+void get_random_bytes(void* buffer, int len)
+{
+	int fd;
+
+	fd = open("/dev/urandom",O_RDONLY);
+	if( fd == -1) {
+		perror("Open of /dev/urandom failed");
+		exit(20);
+	}
+	if(read(fd,buffer,len) != len) {
+		fprintf(stderr,"Reading from /dev/urandom failed\n");
+		exit(20);
+	}
+	close(fd);	
+}

Modified: trunk/user/drbdtool_common.h
===================================================================
--- trunk/user/drbdtool_common.h	2006-09-20 08:35:23 UTC (rev 2433)
+++ trunk/user/drbdtool_common.h	2006-09-20 10:20:51 UTC (rev 2434)
@@ -39,4 +39,5 @@
 extern int fget_token(char *s, int size, FILE* stream);
 extern int sget_token(char *s, int size, const char** text);
 extern u64 bdev_size(int fd);
+extern void get_random_bytes(void* buffer, int len);
 #endif



More information about the drbd-cvs mailing list