[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