From drbd-cvs at lists.linbit.com  Fri Nov  3 12:22:09 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri Nov  3 12:22:10 2006
Subject: [DRBD-cvs] svn commit by phil - r2579 - trunk/user - Removed the
	resending of netlink/connector messages, si
Message-ID: <20061103112209.CA9E62D9EC19@mail.linbit.com>

Author: phil
Date: 2006-11-03 12:22:09 +0100 (Fri, 03 Nov 2006)
New Revision: 2579

Modified:
   trunk/user/drbdsetup.c
Log:
Removed the resending of netlink/connector messages, since it seems that
there is no removal of duplicated messages on the receiving side.


Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2006-10-31 15:49:51 UTC (rev 2578)
+++ trunk/user/drbdsetup.c	2006-11-03 11:22:09 UTC (rev 2579)
@@ -123,8 +123,7 @@
 
 
 // Connector functions
-#define NL_TRIES 5
-#define NL_TIME 5000
+#define NL_TIME 10000
 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 timeout_ms);
@@ -1573,21 +1572,18 @@
 int call_drbd(int sk_nl, struct drbd_tag_list *tl, struct nlmsghdr* nl_hdr, 
 		     int size, int timeout_ms)
 {
-	int i,rr;
+	int rr;
 	prepare_nl_header(tl->nl_header, (char*)tl->tag_list_cpos - 
 			  (char*)tl->nl_header);
 
-	for(i=0;i<NL_TRIES;i++) {
-		rr = send(sk_nl,tl->nl_header,tl->nl_header->nlmsg_len,0);
-		if( rr != (ssize_t)tl->nl_header->nlmsg_len) {
-			perror("send() failed");
-			return -1;
-		}
-
-		rr = receive_reply_cn(sk_nl,tl,nl_hdr,size,timeout_ms/NL_TRIES);
-		if( rr == -2 ) continue; // timeout.
-		return rr;
+	rr = send(sk_nl,tl->nl_header,tl->nl_header->nlmsg_len,0);
+	if( rr != (ssize_t)tl->nl_header->nlmsg_len) {
+		perror("send() failed");
+		return -1;
 	}
+
+	rr = receive_reply_cn(sk_nl,tl,nl_hdr,size,timeout_ms);
+
 	if( rr == -2) {
 		fprintf(stderr,"No response from the DRBD driver!"
 			" Is the module loaded?\n");

From drbd-cvs at lists.linbit.com  Fri Nov  3 15:04:45 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri Nov  3 15:04:47 2006
Subject: [DRBD-cvs] svn commit by phil - r2580 - in trunk: . drbd drbd/linux
	- Implemented item 20 of the ROADMAP ( do not allow to co
Message-ID: <20061103140445.7DF4C2D9EBFC@mail.linbit.com>

Author: phil
Date: 2006-11-03 15:04:43 +0100 (Fri, 03 Nov 2006)
New Revision: 2580

Modified:
   trunk/ROADMAP
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/linux/drbd_config.h
Log:
Implemented item 20 of the ROADMAP ( do not allow to connect in
  case the configs do not match)



Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-11-03 11:22:09 UTC (rev 2579)
+++ trunk/ROADMAP	2006-11-03 14:04:43 UTC (rev 2580)
@@ -567,11 +567,12 @@
    the config is valid, from a viewpoint of the whole cluster.
    E.g.
    protocol				equal
-   cram-hmac-alg			equal
    after-sb-0pri / discard-local/remote	equal / reciprocal
    after-sb-1pri			equal
    after-sb-2pri			equal
-   syncer/group				equal
+   want_lose				reciprocal
+   two_primaries			equal
+  99% DONE
 
 21 Write barriers in the kernel
   In Linux-2.6 write barriers in the block-io layer are represented as

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2006-11-03 11:22:09 UTC (rev 2579)
+++ trunk/drbd/drbd_int.h	2006-11-03 14:04:43 UTC (rev 2580)
@@ -474,6 +474,11 @@
 typedef struct {
 	Drbd_Header head;
 	u32         protocol;
+	u32         after_sb_0p;
+	u32         after_sb_1p;
+	u32         after_sb_2p;
+	u32         want_lose;
+	u32         two_primaries;
 } __attribute((packed)) Drbd_Protocol_Packet;
 
 typedef struct {

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-11-03 11:22:09 UTC (rev 2579)
+++ trunk/drbd/drbd_main.c	2006-11-03 14:04:43 UTC (rev 2580)
@@ -1260,7 +1260,12 @@
 {
 	Drbd_Protocol_Packet p;
 
-	p.protocol = cpu_to_be32(mdev->net_conf->wire_protocol);
+	p.protocol      = cpu_to_be32(mdev->net_conf->wire_protocol);
+	p.after_sb_0p   = cpu_to_be32(mdev->net_conf->after_sb_0p);
+	p.after_sb_1p   = cpu_to_be32(mdev->net_conf->after_sb_1p);
+	p.after_sb_2p   = cpu_to_be32(mdev->net_conf->after_sb_2p);
+	p.want_lose     = cpu_to_be32(mdev->net_conf->want_lose);
+	p.two_primaries = cpu_to_be32(mdev->net_conf->two_primaries);
 
 	return drbd_send_cmd(mdev,USE_DATA_SOCKET,ReportProtocol,
 			     (Drbd_Header*)&p,sizeof(p));

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-11-03 11:22:09 UTC (rev 2579)
+++ trunk/drbd/drbd_receiver.c	2006-11-03 14:04:43 UTC (rev 2580)
@@ -1978,32 +1978,77 @@
 	return rv;
 }
 
+/* returns 1 if invalid */
+STATIC int cmp_after_sb(enum after_sb_handler peer, enum after_sb_handler self)
+{
+	// DiscardRemote - DiscardLocal is valid
+	if( (peer == DiscardRemote && self == DiscardLocal) ||
+	    (self == DiscardRemote && peer == DiscardLocal) ) return 0;
+
+	// any other things with DiscardRemote or DiscardLocal are invalid
+	if( peer == DiscardRemote || peer == DiscardLocal ||
+	    self == DiscardRemote || self == DiscardLocal ) return 1;
+	
+	// everything else is valid if they are equal on both sides.
+	if( peer == self ) return 0;
+
+	// everything es is invalid.
+	return 1;
+}
+
 STATIC int receive_protocol(drbd_dev *mdev, Drbd_Header *h)
 {
 	Drbd_Protocol_Packet *p = (Drbd_Protocol_Packet*)h;
 
+	int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p;
+	int p_want_lose, p_two_primaries;
+
 	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
 	if (drbd_recv(mdev, h->payload, h->length) != h->length)
 		return FALSE;
 
-	if(be32_to_cpu(p->protocol)!=mdev->net_conf->wire_protocol) {
-		int peer_proto = be32_to_cpu(p->protocol);
-		if (DRBD_PROT_A <= peer_proto && peer_proto <= DRBD_PROT_C) {
-			ERR("incompatible communication protocols: "
-			    "me %c, peer %c\n",
-				'A'-1+mdev->net_conf->wire_protocol,
-				'A'-1+peer_proto);
-		} else {
-			ERR("incompatible communication protocols: "
-			    "me %c, peer [%d]\n",
-				'A'-1+mdev->net_conf->wire_protocol,
-				peer_proto);
-		}
-		drbd_force_state(mdev,NS(conn,Disconnecting));
-		return FALSE;
+	p_proto         = be32_to_cpu(p->protocol);
+	p_after_sb_0p   = be32_to_cpu(p->after_sb_0p);
+	p_after_sb_1p   = be32_to_cpu(p->after_sb_1p);
+	p_after_sb_2p   = be32_to_cpu(p->after_sb_2p);
+	p_want_lose     = be32_to_cpu(p->want_lose);
+	p_two_primaries = be32_to_cpu(p->two_primaries);
+
+	if( p_proto != mdev->net_conf->wire_protocol) {
+		ERR("incompatible communication protocols\n");
+		goto disconnect;
 	}
 
+	if( cmp_after_sb(p_after_sb_0p, mdev->net_conf->after_sb_0p) ) {
+		ERR("incompatible after-sb-0pri settings\n");
+		goto disconnect;
+	}
+
+	if( cmp_after_sb(p_after_sb_1p, mdev->net_conf->after_sb_1p) ) {
+		ERR("incompatible after-sb-1pri settings\n");
+		goto disconnect;
+	}
+
+	if( cmp_after_sb(p_after_sb_2p, mdev->net_conf->after_sb_2p) ) {
+		ERR("incompatible after-sb-2pri settings\n");
+		goto disconnect;
+	}
+
+	if( p_want_lose && mdev->net_conf->want_lose ) {
+		ERR("both sides have the 'want_lose' flag set\n");
+		goto disconnect;
+	}
+
+	if( p_two_primaries != mdev->net_conf->two_primaries ) {
+		ERR("incompatible setting of the two-primaries options\n");
+		goto disconnect;
+	}
+
 	return TRUE;
+
+ disconnect:
+	drbd_force_state(mdev,NS(conn,Disconnecting));
+	return FALSE;
 }
 
 STATIC int receive_SyncParam(drbd_dev *mdev,Drbd_Header *h)

Modified: trunk/drbd/linux/drbd_config.h
===================================================================
--- trunk/drbd/linux/drbd_config.h	2006-11-03 11:22:09 UTC (rev 2579)
+++ trunk/drbd/linux/drbd_config.h	2006-11-03 14:04:43 UTC (rev 2580)
@@ -22,9 +22,9 @@
 
 extern const char * drbd_buildtag(void);
 
-#define REL_VERSION "8.0pre5"
+#define REL_VERSION "8.0pre6"
 #define API_VERSION 85
-#define PRO_VERSION 84
+#define PRO_VERSION 85
 
 // undef if you need the workaround in drbd_receiver
 #define HAVE_UML_TO_VIRT 1

From drbd-cvs at lists.linbit.com  Fri Nov  3 15:19:22 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri Nov  3 15:19:23 2006
Subject: [DRBD-cvs] svn commit by simon - r2581 - trunk/drbd - The attached
	patch adds some basic tracing to the netli
Message-ID: <20061103141922.420862D9E3AF@mail.linbit.com>

Author: simon
Date: 2006-11-03 15:19:21 +0100 (Fri, 03 Nov 2006)
New Revision: 2581

Modified:
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_nl.c
Log:
The attached patch adds some basic tracing to the netlink interface
using the new TRACE() mechanism and a new trace type. I'd like to add
more detailed tracing of the packets over time (probably based on
generating code from drbd_nl.h).


Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2006-11-03 14:04:43 UTC (rev 2580)
+++ trunk/drbd/drbd_int.h	2006-11-03 14:19:21 UTC (rev 2581)
@@ -1180,6 +1180,7 @@
 	TraceTypeResync = 0x00000008,
 	TraceTypeEE     = 0x00000010,
 	TraceTypeUnplug = 0x00000020,
+	TraceTypeNl     = 0x00000040,
 };
 
 static inline int

Modified: trunk/drbd/drbd_nl.c
===================================================================
--- trunk/drbd/drbd_nl.c	2006-11-03 14:04:43 UTC (rev 2580)
+++ trunk/drbd/drbd_nl.c	2006-11-03 14:19:21 UTC (rev 2581)
@@ -115,12 +115,52 @@
 	tags = (unsigned short*)((char*)tags + arg->member ## _len);
 #include "linux/drbd_nl.h"
 
-
 extern void drbd_init_set_defaults(drbd_dev *mdev);
 void drbd_bcast_ev_helper(drbd_dev *mdev, char* helper_name);
 void drbd_nl_send_reply(struct cn_msg *, int);
 
+char *nl_packet_name(int packet_type) {
+// Generate packet type strings
+#define PACKET(name, number, fields) \
+	[ P_ ## name ] = # name,
+#define INTEGER Argh!
+#define BIT Argh!
+#define INT64 Argh!
+#define STRING Argh!
 
+	static char *nl_tag_name[P_nl_after_last_packet] = {
+#include "linux/drbd_nl.h"
+	};
+
+	return (packet_type < sizeof(nl_tag_name)/sizeof(nl_tag_name[0])) ?
+	    nl_tag_name[packet_type] : "*Unknown*";
+}
+
+void nl_trace_packet(void *data) {
+	struct cn_msg *req = data;
+	struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req*)req->data;
+
+	printk(KERN_INFO DEVICE_NAME "%d: " 
+	       "Netlink: << %s (%d) - seq: %x, ack: %x, len: %x\n",
+	       nlp->drbd_minor,
+	       nl_packet_name(nlp->packet_type),
+	       nlp->packet_type,
+	       req->seq, req->ack, req->len);
+}
+
+void nl_trace_reply(void *data) {
+	struct cn_msg *req = data;
+	struct drbd_nl_cfg_reply *nlp = (struct drbd_nl_cfg_reply*)req->data;
+
+	printk(KERN_INFO DEVICE_NAME "%d: " 
+	       "Netlink: >> %s (%d) - seq: %x, ack: %x, len: %x\n",
+	       nlp->minor,
+	       nlp->packet_type==P_nl_after_last_packet? 
+	           "Empty-Reply" : nl_packet_name(nlp->packet_type),
+	       nlp->packet_type,
+	       req->seq, req->ack, req->len);
+}
+
 int drbd_khelper(drbd_dev *mdev, char* cmd)
 {
 	char mb[12];
@@ -1508,6 +1548,8 @@
 		goto fail;
 	}
 
+	TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_packet(data););
+
 	if( nlp->packet_type >= P_nl_after_last_packet ) {
 		retcode=UnknownNetLinkPacket;
 		goto fail;
@@ -1535,6 +1577,8 @@
 	cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + rr;
 	cn_reply->flags = 0;
 
+	TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply););
+
 	rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
 	if(rr && rr != -ESRCH) {
 		printk(KERN_INFO DEVICE_NAME " cn_netlink_send()=%d\n",rr);
@@ -1577,6 +1621,8 @@
 	reply->minor = mdev_to_minor(mdev);
 	reply->ret_code = NoError;
 
+	TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply););
+
 	cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
 }
 
@@ -1613,6 +1659,8 @@
 	reply->minor = mdev_to_minor(mdev);
 	reply->ret_code = NoError;
 
+	TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply););
+
 	cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
 }
 
@@ -1670,6 +1718,8 @@
 	reply->minor = ((struct drbd_nl_cfg_req *)req->data)->drbd_minor;
 	reply->ret_code = ret_code;
 
+	TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply););
+
 	rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL);
 	if(rr && rr != -ESRCH) {
 		printk(KERN_INFO DEVICE_NAME " cn_netlink_send()=%d\n",rr);

From drbd-cvs at lists.linbit.com  Fri Nov  3 15:19:50 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri Nov  3 15:19:51 2006
Subject: [DRBD-cvs] svn commit by phil - r2582 - trunk - Preparing the pre6
	release. 
Message-ID: <20061103141950.830F22D9E3AF@mail.linbit.com>

Author: phil
Date: 2006-11-03 15:19:50 +0100 (Fri, 03 Nov 2006)
New Revision: 2582

Modified:
   trunk/ChangeLog
Log:
Preparing the pre6 release.


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2006-11-03 14:19:21 UTC (rev 2581)
+++ trunk/ChangeLog	2006-11-03 14:19:50 UTC (rev 2582)
@@ -4,6 +4,15 @@
  Cumulative changes since last tarball.
  For even more detail, use "svn log" and "svn diff".
 
+8.0pre6 (api:85/proto:85)
+--------
+ * All panic() calls where removed from DRBD.
+ * IO errors while accessing the backing storage device are now handled
+   correct.
+ * Conflict detection for two primaries is in place and tested.
+ * More tracing stuff
+ * Lots of bugs found and fixed
+
 8.0pre5 (api:84/proto:83)
 --------
  * The request code was completely rewritten.

From drbd-cvs at lists.linbit.com  Fri Nov  3 15:22:27 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri Nov  3 15:22:28 2006
Subject: [DRBD-cvs] svn commit by phil - r2583 - in trunk: . debian - more
	preparation... 
Message-ID: <20061103142227.5EC2A2D9E3AF@mail.linbit.com>

Author: phil
Date: 2006-11-03 15:22:26 +0100 (Fri, 03 Nov 2006)
New Revision: 2583

Modified:
   trunk/debian/changelog
   trunk/drbd.spec.in
Log:
more preparation...


Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog	2006-11-03 14:19:50 UTC (rev 2582)
+++ trunk/debian/changelog	2006-11-03 14:22:26 UTC (rev 2583)
@@ -1,3 +1,9 @@
+drbd8 (8.0pre6-0) unstable; urgency=low
+
+  * New upstream release.
+
+ -- Philipp Reisner <phil@linbit.com>  Mon, 31 Jul 2006 12:04:41 +0200
+
 drbd8 (8.0pre4-0) unstable; urgency=low
 
   * New upstream release.

Modified: trunk/drbd.spec.in
===================================================================
--- trunk/drbd.spec.in	2006-11-03 14:19:50 UTC (rev 2582)
+++ trunk/drbd.spec.in	2006-11-03 14:22:26 UTC (rev 2583)
@@ -192,6 +192,15 @@
 
 %changelog
 
+* Fri Nov  3 2006 15:20:54 +0200 Philipp Reisner <phil@linbit.com>
+- drbd (8.0pre5-1)
+ * All panic() calls where removed from DRBD.
+ * IO errors while accessing the backing storage device are now handled
+   correct.
+ * Conflict detection for two primaries is in place and tested.
+ * More tracing stuff
+ * Lots of bugs found and fixed
+
 * Sun Oct 31 2006 22:03:54 +0200 Philipp Reisner <phil@linbit.com>
 - drbd (8.0pre5-1)
  * The request code was completely rewritten.

From drbd-cvs at lists.linbit.com  Fri Nov  3 15:29:55 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri Nov  3 15:29:56 2006
Subject: [DRBD-cvs] svn commit by phil - r2584 - trunk/debian - Fixed the
	date... 
Message-ID: <20061103142955.D0F7A2D9EBFC@mail.linbit.com>

Author: phil
Date: 2006-11-03 15:29:55 +0100 (Fri, 03 Nov 2006)
New Revision: 2584

Modified:
   trunk/debian/changelog
Log:
Fixed the date...


Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog	2006-11-03 14:22:26 UTC (rev 2583)
+++ trunk/debian/changelog	2006-11-03 14:29:55 UTC (rev 2584)
@@ -2,7 +2,7 @@
 
   * New upstream release.
 
- -- Philipp Reisner <phil@linbit.com>  Mon, 31 Jul 2006 12:04:41 +0200
+ -- Philipp Reisner <phil@linbit.com>  Fri, 3 Nov 2006 15:20:54 +0200
 
 drbd8 (8.0pre4-0) unstable; urgency=low
 

From drbd-cvs at lists.linbit.com  Fri Nov  3 15:30:54 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri Nov  3 15:30:55 2006
Subject: [DRBD-cvs] svn commit by phil - r2585 - trunk - foo 
Message-ID: <20061103143054.8F34D2D9EBFC@mail.linbit.com>

Author: phil
Date: 2006-11-03 15:30:50 +0100 (Fri, 03 Nov 2006)
New Revision: 2585

Modified:
   trunk/drbd.spec.in
Log:
foo


Modified: trunk/drbd.spec.in
===================================================================
--- trunk/drbd.spec.in	2006-11-03 14:29:55 UTC (rev 2584)
+++ trunk/drbd.spec.in	2006-11-03 14:30:50 UTC (rev 2585)
@@ -193,7 +193,7 @@
 %changelog
 
 * Fri Nov  3 2006 15:20:54 +0200 Philipp Reisner <phil@linbit.com>
-- drbd (8.0pre5-1)
+- drbd (8.0pre6-1)
  * All panic() calls where removed from DRBD.
  * IO errors while accessing the backing storage device are now handled
    correct.

From drbd-cvs at lists.linbit.com  Fri Nov  3 15:35:42 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri Nov  3 15:35:43 2006
Subject: [DRBD-cvs] svn commit by phil - r2586 - tags - Tagging pre6 
Message-ID: <20061103143542.716E22D9EBFC@mail.linbit.com>

Author: phil
Date: 2006-11-03 15:35:41 +0100 (Fri, 03 Nov 2006)
New Revision: 2586

Added:
   tags/drbd-8.0pre6/
Log:
Tagging pre6


Copied: tags/drbd-8.0pre6 (from rev 2585, trunk)

From drbd-cvs at lists.linbit.com  Fri Nov  3 20:24:04 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri Nov  3 20:24:05 2006
Subject: [DRBD-cvs] svn commit by phil - r2587 - trunk/user - Small
	improvement to the way drbdsetup print its usage.
Message-ID: <20061103192404.C351D2D9EBFC@mail.linbit.com>

Author: phil
Date: 2006-11-03 20:24:03 +0100 (Fri, 03 Nov 2006)
New Revision: 2587

Modified:
   trunk/user/drbdsetup.c
Log:
Small improvement to the way drbdsetup print its usage.


Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2006-11-03 14:35:41 UTC (rev 2586)
+++ trunk/user/drbdsetup.c	2006-11-03 19:24:03 UTC (rev 2587)
@@ -1308,16 +1308,20 @@
 int handler_opt_usage(struct drbd_option *option, char* str, int strlen)
 {
 	const char** handlers;
-	int i, chars=0;
+	int i, chars=0,first=1;
 
-	chars += snprintf(str,strlen," [{--%s|-%c}",
+	chars += snprintf(str,strlen," [{--%s|-%c} {",
 			  option->name, option->short_name);
 	handlers = option->handler_param.handler_names;
 	for(i=0;i<option->handler_param.number_of_handlers;i++) {
-		if(handlers[i]) chars += snprintf(str+chars,strlen,
-						  " %s",handlers[i]);
+		if(handlers[i]) {
+			if(!first) chars += snprintf(str+chars,strlen,"|");
+			first=0;
+			chars += snprintf(str+chars,strlen,
+					  "%s",handlers[i]);
+		}
 	}
-	chars += snprintf(str+chars,strlen,"]");
+	chars += snprintf(str+chars,strlen,"}]");
 	return chars;
 }
 

From drbd-cvs at lists.linbit.com  Sat Nov  4 12:13:59 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Sat Nov  4 12:14:00 2006
Subject: [DRBD-cvs] svn commit by phil - r2589 - trunk - Two now items to
	the roadmap, we must not forget to kee
Message-ID: <20061104111359.A45D72D9E3B5@mail.linbit.com>

Author: phil
Date: 2006-11-04 12:13:58 +0100 (Sat, 04 Nov 2006)
New Revision: 2589

Modified:
   trunk/ROADMAP
Log:
Two now items to the roadmap, we must not forget to keep those in
mind before goint drbd-8.0-final.


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-11-03 20:58:58 UTC (rev 2588)
+++ trunk/ROADMAP	2006-11-04 11:13:58 UTC (rev 2589)
@@ -842,6 +842,12 @@
 
 40 Do something with FLUSHBUFS ioctl.
 
+41 Fix DRBD's behaviour in case of a cluster crash when both nodes
+   are in primary state.
+
+42 Forward port the abilitiy to resume the TL after IO was frozen,
+   in case the connection is reestablished again.
+
 Maybe:
 
 *  Switch to protocol C in case we are running without a local 

From drbd-cvs at lists.linbit.com  Mon Nov  6 12:12:33 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon Nov  6 12:12:35 2006
Subject: [DRBD-cvs] svn commit by phil - r2590 - in trunk/drbd: . linux - *
	DRBD could not cope with failed READA requests from t
Message-ID: <20061106111233.75AAE2D9CFB1@mail.linbit.com>

Author: phil
Date: 2006-11-06 12:12:31 +0100 (Mon, 06 Nov 2006)
New Revision: 2590

Modified:
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/drbd_req.c
   trunk/drbd/drbd_req.h
   trunk/drbd/drbd_worker.c
   trunk/drbd/linux/drbd_config.h
Log:
* DRBD could not cope with failed READA requests from the backing
  device. Fixed that.
* Added the possibility to simulate the failure of READA requests.
* Added an error parameter _req_mod() and _req_may_be_done() to pass
  errnos through.


Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2006-11-04 11:13:58 UTC (rev 2589)
+++ trunk/drbd/drbd_int.h	2006-11-06 11:12:31 UTC (rev 2590)
@@ -200,6 +200,7 @@
     DRBD_FAULT_RS_RD,
     DRBD_FAULT_DT_WR,
     DRBD_FAULT_DT_RD,
+    DRBD_FAULT_DT_RA,  // READA = Read ahead
 
     DRBD_FAULT_MAX,
 };

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-11-04 11:13:58 UTC (rev 2589)
+++ trunk/drbd/drbd_main.c	2006-11-06 11:12:31 UTC (rev 2590)
@@ -230,7 +230,7 @@
 	 * master_bio's could already been completed.  */
 	list_for_each_safe(le, tle, &b->requests) {
 		r = list_entry(le, struct drbd_request,tl_requests);
-		_req_mod(r, barrier_acked);
+		_req_mod(r, barrier_acked, 0);
 	}
 	list_del(&b->requests);
 	/* There could be requests on the list waiting for completion
@@ -273,7 +273,7 @@
 
 		list_for_each_safe(le, tle, &b->requests) {
 			r = list_entry(le, struct drbd_request,tl_requests);
-			_req_mod(r, connection_lost_while_pending);
+			_req_mod(r, connection_lost_while_pending, 0);
 		}
 		tmp = b->next;
 
@@ -2844,6 +2844,7 @@
 		"Resync read",
 		"Data write",
 		"Data read",
+		"Data read ahead",
 	};
 
 	return (type < DRBD_FAULT_MAX)? _faults[type] : "**Unknown**";

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-11-04 11:13:58 UTC (rev 2589)
+++ trunk/drbd/drbd_receiver.c	2006-11-06 11:12:31 UTC (rev 2590)
@@ -1108,7 +1108,7 @@
 	 * still no race with drbd_fail_pending_reads */
 	ok = recv_dless_read(mdev,req,sector,data_size);
 
-	if (ok) req_mod(req, data_received);
+	if (ok) req_mod(req, data_received, 0);
 	/* else: nothing. handled from drbd_disconnect...
 	 * I don't think we may complete this just yet
 	 * in case we are "on-disconnect: freeze" */
@@ -2583,7 +2583,7 @@
 		req = list_entry(le, drbd_request_t, w.list);
 		list_del(le);
 
-		_req_mod(req, connection_lost_while_pending);
+		_req_mod(req, connection_lost_while_pending, 0);
 	}
 	spin_unlock_irq(&mdev->req_lock);
 }
@@ -3096,18 +3096,18 @@
 			switch (be16_to_cpu(h->command)) {
 			case WriteAck:
 				D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
-				_req_mod(req,write_acked_by_peer);
+				_req_mod(req,write_acked_by_peer,0);
 				break;
 			case RecvAck:
 				D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_A);
-				_req_mod(req,recv_acked_by_peer);
+				_req_mod(req,recv_acked_by_peer,0);
 				break;
 			case DiscardAck:
 				D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
 				ALERT("Got DiscardAck packet %llus +%u!"
 				      " DRBD is not a random data generator!\n",
 				      (unsigned long long)req->sector, req->size);
-				_req_mod(req, conflict_discarded_by_peer);
+				_req_mod(req, conflict_discarded_by_peer, 0);
 				break;
 			default:
 				D_ASSERT(0);
@@ -3168,7 +3168,7 @@
 	ERR("Got NegDReply; Sector %llus, len %u; Fail original request.\n",
 	    (unsigned long long)sector,be32_to_cpu(p->blksize));
 
-	_req_mod(req, neg_acked);
+	_req_mod(req, neg_acked, 0);
 	spin_unlock_irq(&mdev->req_lock);
 
 // warning LGE "ugly and wrong"

Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c	2006-11-04 11:13:58 UTC (rev 2589)
+++ trunk/drbd/drbd_req.c	2006-11-06 11:12:31 UTC (rev 2590)
@@ -103,7 +103,7 @@
 #define print_req_mod(T,W)
 #endif
 
-void _req_may_be_done(drbd_request_t *req)
+void _req_may_be_done(drbd_request_t *req, int error)
 {
 	const unsigned long s = req->rq_state;
 	drbd_dev *mdev = req->mdev;
@@ -207,7 +207,8 @@
 		 * then again, if it is a READ, it is not in the TL at all.
 		 * is it still leagal to complete a READ during freeze? */
 		dump_bio(mdev,req->master_bio,1);
-		bio_endio(req->master_bio, req->master_bio->bi_size, ok ? 0 : -EIO);
+		bio_endio(req->master_bio, req->master_bio->bi_size, 
+			  ok ? 0 : ( error ? error : -EIO ) );
 		req->master_bio = NULL;
 		dec_ap_bio(mdev);
 	} else {
@@ -389,11 +390,15 @@
  * Though I think it is likely that we break this again into many
  * static inline void _req_mod_ ## what (req) ...
  */
-void _req_mod(drbd_request_t *req, drbd_req_event_t what)
+void _req_mod(drbd_request_t *req, drbd_req_event_t what, int error)
 {
 	drbd_dev *mdev = req->mdev;
 	MUST_HOLD(&mdev->req_lock);
 
+	if (error && ( bio_rw(req->master_bio) != READA ) ) {
+		ERR("got an _req_mod() errno of %d\n",error);
+	}
+
 	print_req_mod(req,what);
 
 	switch(what) {
@@ -437,7 +442,7 @@
 		req->rq_state |= (RQ_LOCAL_COMPLETED|RQ_LOCAL_OK);
 		req->rq_state &= ~RQ_LOCAL_PENDING;
 
-		_req_may_be_done(req);
+		_req_may_be_done(req,error);
 		break;
 
 	case write_completed_with_error:
@@ -452,20 +457,24 @@
 		/* and now: check how to handle local io error.
 		 * FIXME see comment below in read_completed_with_error */
 		__drbd_chk_io_error(mdev,FALSE);
-		_req_may_be_done(req);
+		_req_may_be_done(req,error);
 		break;
 
 	case read_completed_with_error:
-		drbd_set_out_of_sync(mdev,req->sector,req->size);
+		if (bio_rw(req->master_bio) != READA) {
+			drbd_set_out_of_sync(mdev,req->sector,req->size);
+		}
 		req->rq_state |= RQ_LOCAL_COMPLETED;
 		req->rq_state &= ~RQ_LOCAL_PENDING;
 
 		bio_put(req->private_bio);
 		req->private_bio = NULL;
 		dec_local(mdev);
-		if (bio_rw(req->master_bio) == READA)
+		if (bio_rw(req->master_bio) == READA) {
 			/* it is legal to fail READA */
+			_req_may_be_done(req,error);
 			break;
+		}
 		/* else */
 		ALERT("Local READ failed sec=%llus size=%u\n",
 		      (unsigned long long)req->sector, req->size);
@@ -558,7 +567,7 @@
 		req->rq_state &= ~RQ_NET_QUEUED;
 		/* if we did it right, tl_clear should be scheduled only after this,
 		 * so this should not be necessary! */
-		_req_may_be_done(req);
+		_req_may_be_done(req,error);
 		break;
 
 	case handed_over_to_network:
@@ -589,7 +598,7 @@
 		 * "completed_ok" events came in, once we return from
 		 * _drbd_send_zc_bio (drbd_send_dblock), we have to check
 		 * whether it is done already, and end it.  */
-		_req_may_be_done(req);
+		_req_may_be_done(req,error);
 		break;
 
 	case connection_lost_while_pending:
@@ -602,7 +611,7 @@
 		 * it will be canceled soon.
 		 * FIXME we should change the code so this can not happen. */
 		if (!(req->rq_state & RQ_NET_QUEUED))
-			_req_may_be_done(req);
+			_req_may_be_done(req,error);
 		break;
 
 	case conflict_discarded_by_peer:
@@ -621,7 +630,7 @@
 		dec_ap_pending(mdev);
 		req->rq_state &= ~RQ_NET_PENDING;
 		if (req->rq_state & RQ_NET_SENT)
-			_req_may_be_done(req);
+			_req_may_be_done(req,error);
 		/* else: done by handed_over_to_network */
 		break;
 
@@ -632,7 +641,7 @@
 		/* FIXME THINK! is it DONE now, or is it not? */
 		req->rq_state |= RQ_NET_DONE;
 		if (req->rq_state & RQ_NET_SENT)
-			_req_may_be_done(req);
+			_req_may_be_done(req,error);
 		/* else: done by handed_over_to_network */
 		break;
 
@@ -664,7 +673,7 @@
 		}
 		D_ASSERT(req->rq_state & RQ_NET_SENT);
 		req->rq_state |= RQ_NET_DONE;
-		_req_may_be_done(req);
+		_req_may_be_done(req,error);
 		break;
 
 	case data_received:
@@ -675,7 +684,7 @@
 		/* can it happen that we receive the DataReply
 		 * before the send DataRequest function returns? */
 		if (req->rq_state & RQ_NET_SENT)
-			_req_may_be_done(req);
+			_req_may_be_done(req,error);
 		/* else: done by handed_over_to_network */
 		break;
 	};
@@ -924,8 +933,8 @@
 
 	/* mark them early for readability.
 	 * this just sets some state flags. */
-	if (remote) _req_mod(req, to_be_send);
-	if (local)  _req_mod(req, to_be_submitted);
+	if (remote) _req_mod(req, to_be_send, 0);
+	if (local)  _req_mod(req, to_be_submitted, 0);
 
 	/* check this request on the colison detection hash tables.
 	 * if we have a conflict, just complete it here.
@@ -961,8 +970,8 @@
 		 * or READ, and no local disk,
 		 * or READ, but not in sync.
 		 */
-		if (rw == WRITE) _req_mod(req,queue_for_net_write);
-		else		 _req_mod(req,queue_for_net_read);
+		if (rw == WRITE) _req_mod(req,queue_for_net_write, 0);
+		else		 _req_mod(req,queue_for_net_read, 0);
 	}
 	spin_unlock_irq(&mdev->req_lock);
 	if (b) kfree(b); /* if someone else has beaten us to it... */
@@ -972,7 +981,9 @@
 		 * was not detached below us? */
 		req->private_bio->bi_bdev = mdev->bc->backing_bdev;
 
-		if (FAULT_ACTIVE(rw==WRITE? DRBD_FAULT_DT_WR : DRBD_FAULT_DT_RD))
+		if (FAULT_ACTIVE(rw==WRITE ? DRBD_FAULT_DT_WR : 
+				 ( rw==READ ? DRBD_FAULT_DT_RD : 
+				   DRBD_FAULT_DT_RA ) ))
 			bio_endio(req->private_bio, req->private_bio->bi_size, -EIO);
 		else
 			generic_make_request(req->private_bio);

Modified: trunk/drbd/drbd_req.h
===================================================================
--- trunk/drbd/drbd_req.h	2006-11-04 11:13:58 UTC (rev 2589)
+++ trunk/drbd/drbd_req.h	2006-11-06 11:12:31 UTC (rev 2590)
@@ -291,15 +291,15 @@
 
 /* aparently too large to be inlined...
  * moved to drbd_req.c */
-extern void _req_may_be_done(drbd_request_t *req);
-extern void _req_mod(drbd_request_t *req, drbd_req_event_t what);
+extern void _req_may_be_done(drbd_request_t *req, int error);
+extern void _req_mod(drbd_request_t *req, drbd_req_event_t what, int error);
 
 /* If you need it irqsave, do it your self! */
-static inline void req_mod(drbd_request_t *req, drbd_req_event_t what)
+static inline void req_mod(drbd_request_t *req, drbd_req_event_t what, int error)
 {
 	drbd_dev *mdev = req->mdev;
 	spin_lock_irq(&mdev->req_lock);
-	_req_mod(req,what);
+	_req_mod(req,what,error);
 	spin_unlock_irq(&mdev->req_lock);
 }
 #endif

Modified: trunk/drbd/drbd_worker.c
===================================================================
--- trunk/drbd/drbd_worker.c	2006-11-04 11:13:58 UTC (rev 2589)
+++ trunk/drbd/drbd_worker.c	2006-11-06 11:12:31 UTC (rev 2590)
@@ -165,8 +165,6 @@
 	// see above
 	if (bio->bi_size) return 1;
 
-	if(error) DUMPI(error);
-
 	/* to avoid recursion in _req_mod */
 	what = error
 	       ? (bio_data_dir(bio) == WRITE)
@@ -174,7 +172,7 @@
 	         : read_completed_with_error
 	       : completed_ok;
 	spin_lock_irqsave(&mdev->req_lock,flags);
-	_req_mod(req, what);
+	_req_mod(req, what, error);
 	spin_unlock_irqrestore(&mdev->req_lock,flags);
 	return 0;
 }
@@ -211,7 +209,7 @@
 	if ( cancel ||
 	     mdev->state.conn < Connected ||
 	     mdev->state.pdsk <= Inconsistent ) {
-		_req_mod(req, send_canceled); /* FIXME freeze? ... */
+		_req_mod(req, send_canceled, 0); /* FIXME freeze? ... */
 		spin_unlock_irq(&mdev->req_lock);
 		drbd_khelper(mdev,"pri-on-incon-degr"); /* FIXME REALLY? */
 		ALERT("WE ARE LOST. Local IO failure, no peer.\n");
@@ -607,12 +605,12 @@
 	int ok;
 
 	if (unlikely(cancel)) {
-		req_mod(req, send_canceled);
+		req_mod(req, send_canceled, 0);
 		return 1;
 	}
 
 	ok = drbd_send_dblock(mdev,req);
-	req_mod(req,ok ? handed_over_to_network : send_failed);
+	req_mod(req,ok ? handed_over_to_network : send_failed, 0);
 
 	return ok;
 }
@@ -626,7 +624,7 @@
 	int ok;
 
 	if (unlikely(cancel)) {
-		req_mod(req, send_canceled);
+		req_mod(req, send_canceled, 0);
 		return 1;
 	}
 
@@ -634,7 +632,7 @@
 				(unsigned long)req);
 
 	if(ok) {
-		req_mod(req, handed_over_to_network);
+		req_mod(req, handed_over_to_network, 0);
 	} else {
 		/* ?? we set Timeout or BrokenPipe in drbd_send() */
 		if (mdev->state.conn >= Connected) 

Modified: trunk/drbd/linux/drbd_config.h
===================================================================
--- trunk/drbd/linux/drbd_config.h	2006-11-04 11:13:58 UTC (rev 2589)
+++ trunk/drbd/linux/drbd_config.h	2006-11-06 11:12:31 UTC (rev 2590)
@@ -50,7 +50,7 @@
 // #define DRBD_DISABLE_SENDPAGE
 
 // Enable fault insertion code
-//#define DRBD_ENABLE_FAULTS
+#define DRBD_ENABLE_FAULTS
 
 // RedHat's 2.6.9 kernels have the gfp_t type. Mainline has this feature
 // since 2.6.16. If you build for RedHat enable the line below.

From drbd-cvs at lists.linbit.com  Wed Nov 15 09:44:33 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed Nov 15 09:44:35 2006
Subject: [DRBD-cvs] svn commit by phil - r2591 - branches/drbd-0.7/benchmark
	- Added the missing error checks on fflush() and fdatasyn
Message-ID: <20061115084433.C04172D9D67E@mail.linbit.com>

Author: phil
Date: 2006-11-15 09:44:33 +0100 (Wed, 15 Nov 2006)
New Revision: 2591

Modified:
   branches/drbd-0.7/benchmark/io-latency-test.c
Log:
Added the missing error checks on fflush() and fdatasync(). Both
can trigger in case the filesystem gets remounted read-only because
of an error.


Modified: branches/drbd-0.7/benchmark/io-latency-test.c
===================================================================
--- branches/drbd-0.7/benchmark/io-latency-test.c	2006-11-06 11:12:31 UTC (rev 2590)
+++ branches/drbd-0.7/benchmark/io-latency-test.c	2006-11-15 08:44:33 UTC (rev 2591)
@@ -11,7 +11,7 @@
    the Free Software Foundation; either version 2, or (at your option)
    any later version.
 
-   dm is distributed in the hope that it will be useful,
+   io-latency-test is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
@@ -83,7 +83,8 @@
 		case IO_RUNNING:
 			if(current_record_nr == last_record_nr) {
 				printf("IO got frozen. Last completely "
-				       "written record: %lu\n",
+				       "written record: %lu"
+				       "                        \n",
 				       last_record_nr);
 				io_state = IO_BLOCKED;
 			} else {
@@ -211,9 +212,14 @@
 			write_duration_us/1000,
 			(write_duration_us%1000)/10);
 		
-		fflush(record_f); // flush it from glibc to the kernel.
-		fdatasync(fileno(record_f)); // from buffer cache to disk.
-
+		if(fflush(record_f)) { // flush it from glibc to the kernel.
+			perror("fflush:");
+			return 10;
+		}
+		if(fdatasync(fileno(record_f))) { // from buffer cache to disk.
+			perror("fdatasync:");
+			return 10;
+		}
 		// eventually wait for full record_time
 		gettimeofday(&then_tv, NULL);
 		write_duration_us =

From drbd-cvs at lists.linbit.com  Wed Nov 15 15:12:39 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed Nov 15 15:12:40 2006
Subject: [DRBD-cvs] svn commit by phil - r2592 - in trunk/drbd: . linux - A
	bit of work on the handling of IO errors on the secon
Message-ID: <20061115141239.63BAE2D9EB2A@mail.linbit.com>

Author: phil
Date: 2006-11-15 15:12:37 +0100 (Wed, 15 Nov 2006)
New Revision: 2592

Modified:
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_nl.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/drbd_strings.c
   trunk/drbd/linux/drbd.h
Log:
A bit of work on the handling of IO errors on the secondary node.



Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-11-15 08:44:33 UTC (rev 2591)
+++ trunk/drbd/drbd_main.c	2006-11-15 14:12:37 UTC (rev 2592)
@@ -585,6 +585,9 @@
 	if( ns.conn == Disconnecting && os.conn == StandAlone) 
 		rv=SS_AlreadyStandAlone;
 
+	if( ns.disk == Outdated && os.disk == Diskless) 
+		rv=SS_CanNotOutdateDL;
+
 	return rv;
 }
 

Modified: trunk/drbd/drbd_nl.c
===================================================================
--- trunk/drbd/drbd_nl.c	2006-11-15 08:44:33 UTC (rev 2591)
+++ trunk/drbd/drbd_nl.c	2006-11-15 14:12:37 UTC (rev 2592)
@@ -1163,8 +1163,14 @@
 						      pdsk,Outdated));
 	} else if (retcode == SS_CW_FailedByPeer) {
 		// The peer probabely wants to see us outdated.
-		retcode = drbd_request_state(mdev,NS2(conn,Disconnecting,
-						      disk,Outdated));
+		retcode = _drbd_request_state(mdev,NS2(conn,Disconnecting,
+						       disk,Outdated),0);
+		if( retcode == SS_CanNotOutdateDL ) {
+			// We are diskless and our peer wants to outdate us.
+			// So, simply go away, and let the peer try to
+			// outdate us with its 'outdate-peer' handler later.
+			retcode = drbd_request_state(mdev,NS(conn,StandAlone));
+		}
 	}
 
 	if( retcode < SS_Success ) goto fail;

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-11-15 08:44:33 UTC (rev 2591)
+++ trunk/drbd/drbd_receiver.c	2006-11-15 14:12:37 UTC (rev 2592)
@@ -316,7 +316,7 @@
 
 	bio_put(bio);
 
-	BUG_ON(!hlist_unhashed(&e->colision));
+	D_ASSERT(hlist_unhashed(&e->colision));
 
 	mempool_free(e, drbd_ee_mempool);
 }
@@ -422,6 +422,7 @@
 		   is_syncer_block_id(e->block_id)) {
 			++n;
 		}
+		if(!hlist_unhashed(&e->colision)) hlist_del_init(&e->colision);
 		drbd_free_ee(mdev,e);
 	}
 
@@ -1305,7 +1306,8 @@
 		if (DRBD_ratelimit(5*HZ,5))
 			ERR("Can not write mirrored data block to local disk.\n");
 		drbd_send_ack_dp(mdev,NegAck,p);
-		return TRUE;
+		mdev->epoch_size++; // spin lock ?
+		return drbd_drain_block(mdev,data_size);
 	}
 
 	sector = be64_to_cpu(p->sector);
@@ -2315,7 +2317,8 @@
 	peer_state.i = be32_to_cpu(p->state);
 
 	if (mdev->p_uuid && mdev->state.conn <= Connected && 
-	    inc_local_if_state(mdev,Negotiating) ) {
+	    inc_local_if_state(mdev,Negotiating) && 
+	    peer_state.disk >= Negotiating) {
 		nconn=drbd_sync_handshake(mdev,peer_state.role,peer_state.disk);
 		dec_local(mdev);
 
@@ -3127,16 +3130,14 @@
 STATIC int got_NegAck(drbd_dev *mdev, Drbd_Header* h)
 {
 	Drbd_BlockAck_Packet *p = (Drbd_BlockAck_Packet*)h;
+	sector_t sector = be64_to_cpu(p->sector);
+	drbd_request_t *req;
 
 	if (DRBD_ratelimit(5*HZ,5))
 		WARN("Got NegAck packet. Peer is in troubles?\n");
 
 	update_peer_seq(mdev,be32_to_cpu(p->seq_num));
 
-	/* do nothing here.
-	 * we expect to get a "report param" on the data socket soon,
-	 * and will do the cleanup then and there.
-	 */
 	if(is_syncer_block_id(p->block_id)) {
 		sector_t sector = be64_to_cpu(p->sector);
 		int size = be32_to_cpu(p->blksize);
@@ -3144,6 +3145,16 @@
 		dec_rs_pending(mdev);
 
 		drbd_rs_failed_io(mdev, sector, size);
+	} else {
+		req = _ack_id_to_req(mdev, p->block_id, sector);
+
+		if (unlikely(!req)) {
+			spin_unlock_irq(&mdev->req_lock);
+			ERR("Got a corrupt block_id/sector pair(2).\n");
+			return FALSE;
+		}
+
+		req_mod(req, neg_acked, 0);
 	}
 
 	return TRUE;

Modified: trunk/drbd/drbd_strings.c
===================================================================
--- trunk/drbd/drbd_strings.c	2006-11-15 08:44:33 UTC (rev 2591)
+++ trunk/drbd/drbd_strings.c	2006-11-15 14:12:37 UTC (rev 2592)
@@ -73,7 +73,8 @@
 	[-SS_PrimaryNOP] = "Refusing to be Primary while peer is not outdated",
 	[-SS_ResyncRunning] = "Can not start resync since it is already active",
 	[-SS_AlreadyStandAlone] = "Can not disconnect a StandAlone device",
-	[-SS_CW_FailedByPeer] = "State changed was refused by peer node"
+	[-SS_CW_FailedByPeer] = "State changed was refused by peer node",
+	[-SS_CanNotOutdateDL] = "Can not outdate a diskless device"
 };
 
 const char* conns_to_name(drbd_conns_t s) {

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2006-11-15 08:44:33 UTC (rev 2591)
+++ trunk/drbd/linux/drbd.h	2006-11-15 14:12:37 UTC (rev 2592)
@@ -201,7 +201,8 @@
 	SS_PrimaryNOP=-7,
 	SS_ResyncRunning=-8,
 	SS_AlreadyStandAlone=-9,
-	SS_CW_FailedByPeer=-10
+	SS_CW_FailedByPeer=-10,
+	SS_CanNotOutdateDL=-11
 } set_st_err_t;
 
 /* from drbd_strings.c */

From drbd-cvs at lists.linbit.com  Wed Nov 15 16:26:22 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed Nov 15 16:26:23 2006
Subject: [DRBD-cvs] svn commit by phil - r2593 - trunk/drbd - One more fix
	to the 'handle IO errors on secondary code
Message-ID: <20061115152622.39D142D9EB2A@mail.linbit.com>

Author: phil
Date: 2006-11-15 16:26:21 +0100 (Wed, 15 Nov 2006)
New Revision: 2593

Modified:
   trunk/drbd/drbd_actlog.c
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_receiver.c
Log:
One more fix to the 'handle IO errors on secondary code':
   * We need to update the sequence number also, if we 
     are going to send a NegAck.

Added tracing code to drbd_al_begin_io() and drbd_al_complete_io().


Modified: trunk/drbd/drbd_actlog.c
===================================================================
--- trunk/drbd/drbd_actlog.c	2006-11-15 14:12:37 UTC (rev 2592)
+++ trunk/drbd/drbd_actlog.c	2006-11-15 15:26:21 UTC (rev 2593)
@@ -224,6 +224,12 @@
 	struct update_al_work al_work;
 
 	D_ASSERT(atomic_read(&mdev->local_cnt)>0);
+
+	MTRACE(TraceTypeALExts,TraceLvlMetrics,
+	       INFO("al_begin_io( sec=%llus (al_enr=%u) (rs_enr=%d) )\n",
+		    sector, enr, (int)BM_SECT_TO_EXT(sector));
+	       );
+
 	wait_event(mdev->al_wait, (al_ext = _al_get(mdev,enr)) );
 
 	if (al_ext->lc_number != enr) {
@@ -267,6 +273,11 @@
 	struct lc_element *extent;
 	unsigned long flags;
 
+	MTRACE(TraceTypeALExts,TraceLvlMetrics,
+	       INFO("al_complete_io( sec=%llus (al_enr=%u) (rs_enr=%d) )\n",
+		    sector, enr, (int)BM_SECT_TO_EXT(sector));
+	       );
+
 	spin_lock_irqsave(&mdev->al_lock,flags);
 
 	extent = lc_find(mdev->act_log,enr);
@@ -914,8 +925,8 @@
 	int i, sig;
 
 	MTRACE(TraceTypeResync, TraceLvlAll,
-	       INFO("drbd_rs_begin_io: sector=%llus\n",
-		    (unsigned long long)sector);
+	       INFO("drbd_rs_begin_io: sector=%llus (rs_end=%d)\n",
+		    (unsigned long long)sector,enr);
 	    );
 
 	sig = wait_event_interruptible( mdev->al_wait,
@@ -1075,8 +1086,8 @@
 	unsigned long flags;
 
 	MTRACE(TraceTypeResync, TraceLvlAll,
-	       INFO("drbd_rs_complete_io: sector=%llus\n",
-		    (long long)sector);
+	       INFO("drbd_rs_complete_io: sector=%llus (rs_enr=%d)\n",
+		    (long long)sector, enr);
 	    );
 
 	spin_lock_irqsave(&mdev->al_lock,flags);

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2006-11-15 14:12:37 UTC (rev 2592)
+++ trunk/drbd/drbd_int.h	2006-11-15 15:26:21 UTC (rev 2593)
@@ -1182,6 +1182,7 @@
 	TraceTypeEE     = 0x00000010,
 	TraceTypeUnplug = 0x00000020,
 	TraceTypeNl     = 0x00000040,
+	TraceTypeALExts = 0x00000080,
 };
 
 static inline int

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-11-15 14:12:37 UTC (rev 2592)
+++ trunk/drbd/drbd_receiver.c	2006-11-15 15:26:21 UTC (rev 2593)
@@ -1305,6 +1305,11 @@
 		 * or in drbd_endio_write_sec. */
 		if (DRBD_ratelimit(5*HZ,5))
 			ERR("Can not write mirrored data block to local disk.\n");
+		spin_lock(&mdev->peer_seq_lock);
+		if (mdev->peer_seq+1 == be32_to_cpu(p->seq_num))
+			mdev->peer_seq++;
+		spin_unlock(&mdev->peer_seq_lock);
+
 		drbd_send_ack_dp(mdev,NegAck,p);
 		mdev->epoch_size++; // spin lock ?
 		return drbd_drain_block(mdev,data_size);

From drbd-cvs at lists.linbit.com  Wed Nov 15 17:44:20 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed Nov 15 17:44:21 2006
Subject: [DRBD-cvs] svn commit by phil - r2594 - trunk/drbd - This seems to
	be the last patch of the 'handle IO failu
Message-ID: <20061115164420.8C34A2D9EB2A@mail.linbit.com>

Author: phil
Date: 2006-11-15 17:44:19 +0100 (Wed, 15 Nov 2006)
New Revision: 2594

Modified:
   trunk/drbd/drbd_receiver.c
Log:
This seems to be the last patch of the 
 'handle IO failures on the secondary node right' 
patch.


Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-11-15 15:26:21 UTC (rev 2593)
+++ trunk/drbd/drbd_receiver.c	2006-11-15 16:44:19 UTC (rev 2594)
@@ -3216,12 +3216,6 @@
 {
 	Drbd_BarrierAck_Packet *p = (Drbd_BarrierAck_Packet*)h;
 
-	smp_rmb();
-	/* FIXME
-	 * and who is going to clear those request objects
-	 * from this epoch object in protocol != C ?? */
-	if(unlikely(mdev->state.pdsk <= Diskless)) return TRUE;
-
 	tl_release(mdev,p->barrier,be32_to_cpu(p->set_size));
 	dec_ap_pending(mdev);
 

From drbd-cvs at lists.linbit.com  Wed Nov 15 18:19:31 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed Nov 15 18:19:32 2006
Subject: [DRBD-cvs] svn commit by phil - r2595 - trunk/drbd - Fixed one more
	problem with the 'handle IO failures on 
Message-ID: <20061115171932.18F572D9EB2A@mail.linbit.com>

Author: phil
Date: 2006-11-15 18:19:31 +0100 (Wed, 15 Nov 2006)
New Revision: 2595

Modified:
   trunk/drbd/drbd_receiver.c
Log:
Fixed one more problem with the
  'handle IO failures on the secondary node right'
code.


Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-11-15 16:44:19 UTC (rev 2594)
+++ trunk/drbd/drbd_receiver.c	2006-11-15 17:19:31 UTC (rev 2595)
@@ -3067,65 +3067,40 @@
 
 	update_peer_seq(mdev,be32_to_cpu(p->seq_num));
 
-	smp_rmb();
-	/* FIXME smp_rmb() is probably not good enough.
-	 * we have to make sure that, no matter what,
-	 * we do not set something "in sync" when
-	 * the peer has no disk (anymore)
-	 * I think this has to be looked at under the req_lock.
-	 * since we need to grab that anyways, lets do that.
-	 */
-	if(likely(mdev->state.pdsk >= Inconsistent )) {
-		/*
-		 * If one of a few IO requests on the peer failed (got_NegAck),
-		 * but some subsequent requests completed sucessfull
-		 * afterwards, verification of the block_id below would fail,
-		 * since we killed everything out of the transferlog when we
-		 * got the news hat IO is broken on the peer.
-		 *
-		 * FIXME
-		 * could this be handled better?
-		 * do we need to look over this again for freeze-io?
-		 */
+	if( is_syncer_block_id(p->block_id)) {
+		drbd_set_in_sync(mdev,sector,blksize);
+		set_bit(SYNC_STARTED,&mdev->flags);
+		dec_rs_pending(mdev);
+	} else {
+		spin_lock_irq(&mdev->req_lock);
+		req = _ack_id_to_req(mdev, p->block_id, sector);
 
-		if( is_syncer_block_id(p->block_id)) {
-			drbd_set_in_sync(mdev,sector,blksize);
-			set_bit(SYNC_STARTED,&mdev->flags);
-		} else {
-			spin_lock_irq(&mdev->req_lock);
-			req = _ack_id_to_req(mdev, p->block_id, sector);
-
-			if (unlikely(!req)) {
-				spin_unlock_irq(&mdev->req_lock);
-				ERR("Got a corrupt block_id/sector pair(2).\n");
-				return FALSE;
-			}
-
-			switch (be16_to_cpu(h->command)) {
-			case WriteAck:
-				D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
-				_req_mod(req,write_acked_by_peer,0);
-				break;
-			case RecvAck:
-				D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_A);
-				_req_mod(req,recv_acked_by_peer,0);
-				break;
-			case DiscardAck:
-				D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
-				ALERT("Got DiscardAck packet %llus +%u!"
-				      " DRBD is not a random data generator!\n",
-				      (unsigned long long)req->sector, req->size);
-				_req_mod(req, conflict_discarded_by_peer, 0);
-				break;
-			default:
-				D_ASSERT(0);
-			}
+		if (unlikely(!req)) {
 			spin_unlock_irq(&mdev->req_lock);
+			ERR("Got a corrupt block_id/sector pair(2).\n");
+			return FALSE;
 		}
-	}
 
-	if(is_syncer_block_id(p->block_id)) {
-		dec_rs_pending(mdev);
+		switch (be16_to_cpu(h->command)) {
+		case WriteAck:
+			D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
+			_req_mod(req,write_acked_by_peer,0);
+			break;
+		case RecvAck:
+			D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_A);
+			_req_mod(req,recv_acked_by_peer,0);
+			break;
+		case DiscardAck:
+			D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C);
+			ALERT("Got DiscardAck packet %llus +%u!"
+			      " DRBD is not a random data generator!\n",
+			      (unsigned long long)req->sector, req->size);
+			_req_mod(req, conflict_discarded_by_peer, 0);
+			break;
+		default:
+			D_ASSERT(0);
+		}
+		spin_unlock_irq(&mdev->req_lock);
 	}
 	/* dec_ap_pending is handled within _req_mod */
 

From drbd-cvs at lists.linbit.com  Wed Nov 15 20:19:19 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed Nov 15 20:19:21 2006
Subject: [DRBD-cvs] svn commit by phil - r2596 - in trunk: . drbd - Allow a
	live attach on a primary node. Since we have th
Message-ID: <20061115191919.8244F2D9EB2A@mail.linbit.com>

Author: phil
Date: 2006-11-15 20:19:18 +0100 (Wed, 15 Nov 2006)
New Revision: 2596

Modified:
   trunk/Makefile
   trunk/drbd/drbd_receiver.c
Log:
Allow a live attach on a primary node. Since we have the "negotiating"
dstate, which will change from negotiating directly to inconsistent
we can do this nowadays.


Modified: trunk/Makefile
===================================================================
--- trunk/Makefile	2006-11-15 17:19:31 UTC (rev 2595)
+++ trunk/Makefile	2006-11-15 19:19:18 UTC (rev 2596)
@@ -93,7 +93,7 @@
 	then \
 	   echo "You need to update ChangeLog"; \
 	   up2date=false; fi ; \
-	if ! grep "^drbd ($$dver_re-" >/dev/null 2>&1 debian/changelog; \
+	if ! grep "^drbd8 ($$dver_re-" >/dev/null 2>&1 debian/changelog; \
 	then \
 	   echo -e "\n\n\tdebian/changelog needs some update\n"; \
 	   : do not fail the build because of outdated debian/changelog ; fi ; \

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-11-15 17:19:31 UTC (rev 2595)
+++ trunk/drbd/drbd_receiver.c	2006-11-15 19:19:18 UTC (rev 2596)
@@ -1941,13 +1941,10 @@
 		drbd_force_state(mdev,NS(conn,Disconnecting));
 		return conn_mask;
 	}
-	if (hg < 0 && 
-	    mdev->state.role == Primary && mydisk >= Consistent ) {
-		ERR("I shall become SyncTarget, but I am primary!\n");
-		drbd_force_state(mdev,NS(conn,Disconnecting));
-		return conn_mask;
-	}
 
+	/* The check "I shall become SyncTarget, but I am primary"
+	   got removed since, we now do live attachs on primary nodes! */
+
 	if (abs(hg) >= 2) {
 		drbd_md_set_flag(mdev,MDF_FullSync);
 		drbd_md_sync(mdev);

From drbd-cvs at lists.linbit.com  Thu Nov 16 11:33:25 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu Nov 16 11:33:27 2006
Subject: [DRBD-cvs] svn commit by lars - r2597 - trunk/user - implemented
	wipe-md command 
Message-ID: <20061116103326.173AA2DF653A@mail.linbit.com>

Author: lars
Date: 2006-11-16 11:33:25 +0100 (Thu, 16 Nov 2006)
New Revision: 2597

Modified:
   trunk/user/drbdmeta.c
Log:
implemented wipe-md command

Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2006-11-15 19:19:18 UTC (rev 2596)
+++ trunk/user/drbdmeta.c	2006-11-16 10:33:25 UTC (rev 2597)
@@ -25,6 +25,8 @@
 /* have the <sys/....h> first, otherwise you get e.g. "redefined" types from
  * sys/types.h and other weird stuff */
 
+#define DONT_INITIALIZE_BITMAP
+
 #define _GNU_SOURCE
 #define __USE_LARGEFILE64
 
@@ -769,6 +771,7 @@
 int meta_dump_md(struct format *cfg, char **argv, int argc);
 int meta_restore_md(struct format *cfg, char **argv, int argc);
 int meta_create_md(struct format *cfg, char **argv, int argc);
+int meta_wipe_md(struct format *cfg, char **argv, int argc);
 int meta_outdate(struct format *cfg, char **argv, int argc);
 int meta_set_gi(struct format *cfg, char **argv, int argc);
 int meta_read_dev_uuid(struct format *cfg, char **argv, int argc);
@@ -781,6 +784,7 @@
 	{"dump-md", 0, meta_dump_md, 1},
 	{"restore-md", "file", meta_restore_md, 1},
 	{"create-md", 0, meta_create_md, 1},
+	{"wipe-md", 0, meta_wipe_md, 1},
 	{"outdate", 0, meta_outdate, 1},
 	{"dstate", 0, meta_dstate, 1},
 	{"read-dev-uuid", "VAL",  meta_read_dev_uuid,  0},
@@ -1341,7 +1345,7 @@
 	/* THINK
 	 * do we really need to initialize the bitmap? */
 #ifdef DONT_INITIALIZE_BITMAP
-	fprintf(stderr,"NOT initialized bitmap (%u KB)\n", (bm_bytes>>10));
+	fprintf(stderr,"NOT initialized bitmap (%u KB)\n", (cfg->bm_mmaped_length>>10));
 #else
 	{
 		const size_t bm_bytes = cfg->bm_mmaped_length;
@@ -2151,6 +2155,31 @@
 	return err;
 }
 
+int meta_wipe_md(struct format *cfg, char **argv __attribute((unused)), int argc)
+{
+	int virgin, err;
+	if (argc > 0) {
+		fprintf(stderr, "Ignoring additional arguments\n");
+	}
+
+	virgin = cfg->ops->open(cfg);
+	if (virgin) {
+		fprintf(stderr,"There apears to be no drbd meta data to wipe out?\n");
+		return 0;
+	}
+
+	printf("Wiping meta data...\n");
+	MEMSET(cfg->on_disk.md, 0, 4096);
+
+	err = cfg->ops->close(cfg);
+	if (err)
+		fprintf(stderr, "operation failed\n");
+	else
+		printf("DRBD meta data block successfully wiped out.\n");
+
+	return err;
+}
+
 int meta_outdate(struct format *cfg, char **argv __attribute((unused)), int argc)
 {
 	int err;

From drbd-cvs at lists.linbit.com  Thu Nov 16 11:34:43 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu Nov 16 11:34:44 2006
Subject: [DRBD-cvs] svn commit by lars - r2598 - trunk - improve error
	messages for check_changelogs_up2date tar
Message-ID: <20061116103443.81C632DEACD6@mail.linbit.com>

Author: lars
Date: 2006-11-16 11:34:43 +0100 (Thu, 16 Nov 2006)
New Revision: 2598

Modified:
   trunk/Makefile
Log:
improve error messages for check_changelogs_up2date target

Modified: trunk/Makefile
===================================================================
--- trunk/Makefile	2006-11-16 10:33:25 UTC (rev 2597)
+++ trunk/Makefile	2006-11-16 10:34:43 UTC (rev 2598)
@@ -46,13 +46,19 @@
 LN_S = ln -s
 RPMBUILD=rpmbuild
 
-all:
-	@ set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i ; done
-	@ echo -e "\n\tBuild successful."
+all: tools module
 
+module: 
+	@if [ -z "$(KVER)" ]; then \
+		echo "Could not determine uts_release" ; \
+		false ; \
+	fi
+	@ $(MAKE) -C drbd
+	@ echo -e "\n\tModule build was successful."
+
 tools:
 	@ set -e; for i in $(patsubst drbd,,$(SUBDIRS)); do $(MAKE) -C $$i ; done
-	@ echo -e "\n\tBuild successful."
+	@ echo -e "\n\tUserland tools build was successful."
 
 doc:
 	$(MAKE) -C documentation doc
@@ -87,15 +93,15 @@
 	                     -e '/^\*.* \['"$$dver_re"'-/p' < drbd.spec.in) ; \
 	if test -z "$$in_changelog" ; \
 	then \
-	   echo "You need to update the %changelog in drbd.spec.in"; \
+	   echo -e "\n\t%changelog in drbd.spec.in needs update"; \
 	   up2date=false; fi; \
 	if ! grep "^$$dver_re\>" >/dev/null 2>&1 ChangeLog; \
 	then \
-	   echo "You need to update ChangeLog"; \
+	   echo -e "\n\tChangeLog needs update"; \
 	   up2date=false; fi ; \
 	if ! grep "^drbd8 ($$dver_re-" >/dev/null 2>&1 debian/changelog; \
 	then \
-	   echo -e "\n\n\tdebian/changelog needs some update\n"; \
+	   echo -e "\n\tdebian/changelog needs update [ignored]\n"; \
 	   : do not fail the build because of outdated debian/changelog ; fi ; \
 	$$up2date
 
@@ -160,9 +166,6 @@
 
 KDIR := $(shell echo /lib/modules/`uname -r`/build)
 KVER := $(shell KDIR=$(KDIR) O=$(O) scripts/get_uts_release.sh)
-ifeq ($(KVER),)
-$(error "could not determine uts_release")
-endif
 
 kernel-patch: drbd/drbd_buildtag.c
 	set -o errexit; \

From drbd-cvs at lists.linbit.com  Thu Nov 16 11:41:21 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu Nov 16 11:41:23 2006
Subject: [DRBD-cvs] svn commit by lars - r2599 - in trunk/drbd: . linux -
	include drbd_config.h, so connector.h knows about KERNE
Message-ID: <20061116104121.B29D22DEACD6@mail.linbit.com>

Author: lars
Date: 2006-11-16 11:41:20 +0100 (Thu, 16 Nov 2006)
New Revision: 2599

Modified:
   trunk/drbd/connector.c
   trunk/drbd/linux/connector.h
Log:
include drbd_config.h, so connector.h knows about KERNEL_HAS_GFP_T
recognize whether "our" in-drbd-tree connector.c is built against
the in-kernel-tree connector.h, and error out in that case.
they are most likely incompatible.


Modified: trunk/drbd/connector.c
===================================================================
--- trunk/drbd/connector.c	2006-11-16 10:34:43 UTC (rev 2598)
+++ trunk/drbd/connector.c	2006-11-16 10:41:20 UTC (rev 2599)
@@ -29,6 +29,11 @@
 #include <linux/moduleparam.h>
 #include <linux/connector.h>
 
+#ifndef DRBD_CONNECTOR_BACKPORT_HEADER
+#error "drbd backported connector.c compiled against kernel connector.h will not work"
+#error "enable CONFIG_CONNECTOR in your kernel and try again"
+#endif
+
 #include <net/sock.h>
 
 #ifdef NETLINK_ROUTE6

Modified: trunk/drbd/linux/connector.h
===================================================================
--- trunk/drbd/linux/connector.h	2006-11-16 10:34:43 UTC (rev 2598)
+++ trunk/drbd/linux/connector.h	2006-11-16 10:41:20 UTC (rev 2599)
@@ -23,6 +23,7 @@
 
 #ifndef __CONNECTOR_H
 #define __CONNECTOR_H
+#define DRBD_CONNECTOR_BACKPORT_HEADER
 
 #include <asm/types.h>
 
@@ -93,6 +94,7 @@
 };
 
 #ifdef __KERNEL__
+#include <linux/drbd_config.h>
 
 #if defined(NETLINK_ROUTE6) && !defined(KERNEL_HAS_GFP_T)
    /* pre 2.6.16 */

From drbd-cvs at lists.linbit.com  Thu Nov 16 12:47:42 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu Nov 16 12:47:43 2006
Subject: [DRBD-cvs] svn commit by lars - r2600 - trunk/drbd - move the
	EOPNOTSUPP for barriers to before the possible
Message-ID: <20061116114743.0519D2D9E384@mail.linbit.com>

Author: lars
Date: 2006-11-16 12:47:42 +0100 (Thu, 16 Nov 2006)
New Revision: 2600

Modified:
   trunk/drbd/drbd_req.c
Log:
move the EOPNOTSUPP for barriers to before the possible bio_split

Modified: trunk/drbd/drbd_req.c
===================================================================
--- trunk/drbd/drbd_req.c	2006-11-16 10:41:20 UTC (rev 2599)
+++ trunk/drbd/drbd_req.c	2006-11-16 11:47:42 UTC (rev 2600)
@@ -747,12 +747,6 @@
 	drbd_request_t *req;
 	int local, remote;
 
-	/* Currently our BARRIER code is disabled. */
-	if(unlikely(bio_barrier(bio))) {
-		bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
-		return 0;
-	}
-
 	/* allocate outside of all locks; get a "reference count" (ap_bio_cnt)
 	 * to avoid races with the disconnect/reconnect code.  */
 	inc_ap_bio(mdev);
@@ -1057,6 +1051,12 @@
 		return 0;
 	}
 
+	/* Currently our BARRIER code is disabled. */
+	if(unlikely(bio_barrier(bio))) {
+		bio_endio(bio, bio->bi_size, -EOPNOTSUPP);
+		return 0;
+	}
+
 	/*
 	 * what we "blindly" assume:
 	 */

From drbd-cvs at lists.linbit.com  Sat Nov 18 11:46:57 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Sat Nov 18 11:46:58 2006
Subject: [DRBD-cvs] svn commit by phil - r2601 - in trunk: . drbd drbd/linux
	user - Implemented a new after-slit-brain-0pri policy: "discar
Message-ID: <20061118104657.72B2F2DBBA6C@mail.linbit.com>

Author: phil
Date: 2006-11-18 11:46:55 +0100 (Sat, 18 Nov 2006)
New Revision: 2601

Modified:
   trunk/ROADMAP
   trunk/drbd/drbd_receiver.c
   trunk/drbd/linux/drbd.h
   trunk/user/drbdsetup.c
Log:
Implemented a new after-slit-brain-0pri policy:
       "discard-zero-changes"
                      Auto sync from the node that modified
                      blocks during the split brain situation, but only
		      if the target not did not touched a single block.
                      If both nodes touched their data, this policy 
		      falls back to disconnect.

And a new after-sb-1pri & 2pri policy
     "violently-as0p" Alsways take the decission of the "after-sb-0pri"
                      algorithm. Even if that causes case an erratic change
		      of the primarie's view of the data.
	              This is only usefull if you use an 1node FS (i.e.
		      not OCFS2 or GFS) with the allow-two-primaries
		      flag, _AND_ you really know what you are doing.
		      This is DANGEROUS and MAY CRASH YOUR MACHINE if you
		      have a FS mounted on the primary node.

To allow Simon and Ernest to run DRBD in this setup:

When running Primary/Primary if the Heartbeat connection goes down when
we recover we always split brain.  Simon had an idea which I have
implemented. He is on vacation  so this may not reflect his exact idea.

Essentially with this change, we do not create a new current UUID on the
node unless I/O is seen. This prevent Split-Brain mitigation when both
nodes are primary but only one node is originating I/O and never the
other.  He is only stand-by in that case.



Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-11-16 11:47:42 UTC (rev 2600)
+++ trunk/ROADMAP	2006-11-18 10:46:55 UTC (rev 2601)
@@ -44,6 +44,15 @@
      "discard-older-primary"
                       Auto sync from the node that became primary 
                       as second during the split brain situation.
+                      If discard-younger-primary and discard-older-primary
+		      can not find a decissions, they fall back to
+                      discard-least-changes.
+     "discard-zero-changes"
+                      Auto sync from the node that modified
+                      blocks during the split brain situation, but only
+		      if the target not did not touched a single block.
+                      If both nodes touched their data, this policy 
+		      falls back to disconnect.
      "discard-least-changes"
                       Auto sync from the node that touched more
                       blocks during the split brain situation.
@@ -56,6 +65,14 @@
      "consensus"  ... discard the version of the secondary if the outcome
                       of the "after-sb-0pri" algorithm would also destroy 
                       the current secondary's data. Otherwise disconnect.
+     "violently-as0p" Alsways take the decission of the "after-sb-0pri"
+                      algorithm. Even if that causes case an erratic change
+		      of the primarie's view of the data.
+	              This is only usefull if you use an 1node FS (i.e.
+		      not OCFS2 or GFS) with the allow-two-primaries
+		      flag, _AND_ you really know what you are doing.
+		      This is DANGEROUS and MAY CRASH YOUR MACHINE if you
+		      have a FS mounted on the primary node.
      "discard-secondary"     
                       discard the version of the secondary.
      "call-pri-lost-after-sb"    
@@ -70,6 +87,14 @@
   In case both nodes are primary you control DRBD's strategy by
   the "after-sb-2pri" option.
      "disconnect" ... Go to StandAlone mode on both sides.
+     "violently-as0p" Alsways take the decission of the "after-sb-0pri"
+                      algorithm. Even if that causes case an erratic change
+		      of the primarie's view of the data.
+	              This is only usefull if you use an 1node FS (i.e.
+		      not OCFS2 or GFS) with the allow-two-primaries
+		      flag, _AND_ you really know what you are doing.
+		      This is DANGEROUS and MAY CRASH YOUR MACHINE if you
+		      have a FS mounted on the primary node.
      "call-pri-lost-after-sb"
 	              Honor the outcome of the "after-sb-0pri" algorithm
                       and calls the "pri-lost-after-sb" program on the

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-11-16 11:47:42 UTC (rev 2600)
+++ trunk/drbd/drbd_receiver.c	2006-11-18 10:46:55 UTC (rev 2601)
@@ -1667,6 +1667,9 @@
 	self = mdev->bc->md.uuid[Bitmap] & 1;
 	peer = mdev->p_uuid[Bitmap] & 1;
 
+	ch_peer = mdev->p_uuid[UUID_SIZE];
+	ch_self = drbd_bm_total_weight(mdev);
+
 	switch ( mdev->net_conf->after_sb_0p ) {
 	case Consensus:
 	case DiscardSecondary:
@@ -1685,22 +1688,21 @@
 		/* Else fall through to one of the other strategies... */
 		WARN("Discard younger/older primary did not found a decision\n"
 		     "Using discard-least-changes instead\n");
+	case DiscardZeroChg:
+		if( ch_peer == 0 && ch_self == 0) {
+			rv=test_bit(DISCARD_CONCURRENT,&mdev->flags) ? -1 : 1;
+			break;
+		} else {
+			if ( ch_peer == 0 ) { rv =  1; break; }
+			if ( ch_self == 0 ) { rv = -1; break; }
+		}
+		if( mdev->net_conf->after_sb_0p == DiscardZeroChg ) break;
 	case DiscardLeastChg:
-		ch_peer = mdev->p_uuid[UUID_SIZE];
-		ch_self = drbd_bm_total_weight(mdev);
 		if      ( ch_self < ch_peer ) rv = -1;
 		else if ( ch_self > ch_peer ) rv =  1;
 		else /* ( ch_self == ch_peer ) */ {
-			// Well, then use the order of the IP addresses...
-			ch_self = (unsigned long)
-				(((struct sockaddr_in *)mdev->net_conf->my_addr)
-				 ->sin_addr.s_addr);
-			ch_peer = (unsigned long)
-				(((struct sockaddr_in *)mdev->net_conf->peer_addr)
-				 ->sin_addr.s_addr);
-			if      ( ch_self < ch_peer ) rv = -1;
-			else if ( ch_self > ch_peer ) rv =  1;
-			else ERR("Everything equal!?!\n");
+			// Well, then use something else.
+			rv=test_bit(DISCARD_CONCURRENT,&mdev->flags) ? -1 : 1;
 		}
 		break;
 	case DiscardLocal:
@@ -1735,6 +1737,9 @@
 		if( hg == -1 && mdev->state.role==Secondary) rv=hg;
 		if( hg == 1  && mdev->state.role==Primary)   rv=hg;
 		break;
+	case ViolentlyAS0Pri:
+		rv = drbd_asb_recover_0p(mdev);
+		break;
 	case DiscardSecondary:
 		return mdev->state.role==Primary ? 1 : -1;
 	case CallHelper:
@@ -1749,6 +1754,7 @@
 			}
 		} else rv = hg;
 	}
+
 	return rv;
 }
 
@@ -1769,6 +1775,9 @@
 	case DiscardSecondary:
 		ERR("Configuration error.\n");
 		break;
+	case ViolentlyAS0Pri:
+		rv = drbd_asb_recover_0p(mdev);
+		break;
 	case Disconnect:
 		break;
 	case CallHelper:
@@ -1783,6 +1792,7 @@
 			}
 		} else rv = hg;
 	}
+
 	return rv;
 }
 

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2006-11-16 11:47:42 UTC (rev 2600)
+++ trunk/drbd/linux/drbd.h	2006-11-18 10:46:55 UTC (rev 2601)
@@ -55,12 +55,14 @@
 	Disconnect,
 	DiscardYoungerPri,
 	DiscardOlderPri,
+	DiscardZeroChg,
 	DiscardLeastChg,
 	DiscardLocal,
 	DiscardRemote,
 	Consensus,
 	DiscardSecondary,
-	CallHelper
+	CallHelper,
+	ViolentlyAS0Pri
 };
 
 /* KEEP the order, do not delete or insert!

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2006-11-16 11:47:42 UTC (rev 2600)
+++ trunk/user/drbdsetup.c	2006-11-18 10:46:55 UTC (rev 2601)
@@ -197,6 +197,7 @@
         [Disconnect]        = "disconnect",
 	[DiscardYoungerPri] = "discard-younger-primary",
 	[DiscardOlderPri]   = "discard-older-primary",
+	[DiscardZeroChg]    = "discard-zero-changes",
 	[DiscardLeastChg]   = "discard-least-changes",
 	[DiscardLocal]      = "discard-local",
 	[DiscardRemote]     = "discard-remote"
@@ -205,12 +206,14 @@
 const char *asb1p_n[] = {
 	[Disconnect]        = "disconnect",
 	[Consensus]         = "consensus",
+	[ViolentlyAS0Pri]   = "violently-as0p",
 	[DiscardSecondary]  = "discard-secondary",
 	[CallHelper]        = "call-pri-lost-after-sb"
 };
 
 const char *asb2p_n[] = {
 	[Disconnect]        = "disconnect",
+	[ViolentlyAS0Pri]   = "violently-as0p",
 	[CallHelper]        = "call-pri-lost-after-sb"
 };
 

From drbd-cvs at lists.linbit.com  Sun Nov 19 13:54:52 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Sun Nov 19 13:54:54 2006
Subject: [DRBD-cvs] svn commit by phil - r2602 - in trunk: . drbd drbd/linux
	scripts user - Did item 41 of the ROADMAP. Right resync after
	a cluste
Message-ID: <20061119125452.86D9B2DF6547@mail.linbit.com>

Author: phil
Date: 2006-11-19 13:54:50 +0100 (Sun, 19 Nov 2006)
New Revision: 2602

Modified:
   trunk/ROADMAP
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/linux/drbd.h
   trunk/drbd/linux/drbd_limits.h
   trunk/drbd/linux/drbd_nl.h
   trunk/scripts/drbd.conf
   trunk/user/drbdadm_scanner.fl
   trunk/user/drbdsetup.c
Log:
Did item 41 of the ROADMAP.
 Right resync after a cluster crash or common power failure.


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-11-18 10:46:55 UTC (rev 2601)
+++ trunk/ROADMAP	2006-11-19 12:54:50 UTC (rev 2602)
@@ -65,7 +65,7 @@
      "consensus"  ... discard the version of the secondary if the outcome
                       of the "after-sb-0pri" algorithm would also destroy 
                       the current secondary's data. Otherwise disconnect.
-     "violently-as0p" Alsways take the decission of the "after-sb-0pri"
+     "violently-as0p" Always take the decission of the "after-sb-0pri"
                       algorithm. Even if that causes case an erratic change
 		      of the primarie's view of the data.
 	              This is only usefull if you use an 1node FS (i.e.
@@ -87,7 +87,7 @@
   In case both nodes are primary you control DRBD's strategy by
   the "after-sb-2pri" option.
      "disconnect" ... Go to StandAlone mode on both sides.
-     "violently-as0p" Alsways take the decission of the "after-sb-0pri"
+     "violently-as0p" Always take the decission of the "after-sb-0pri"
                       algorithm. Even if that causes case an erratic change
 		      of the primarie's view of the data.
 	              This is only usefull if you use an 1node FS (i.e.
@@ -521,7 +521,11 @@
   1.  C=JC   C=JC   No Sync
   2.  C=JC   C!=JC  I am SyncTarget setting BM
   3. C!=JC   C=JC   I am SyncSource setting BM
-  4.   C   =   C    No Sync
+  4.   C   =   C    Common power [off|failure](Examine the roles at crash time)
+  4.1  sec   sec    Common power off, no sync.
+  4.2  pri   sec    Common power failure, I am SyncSource using BM
+  4.3  sec   pri    Common power failure, I am SyncTarget using BM
+  4.4  pri   pri    Common power failure, resync in arbitrary direction.
   5.   C   =   B    I am SyncTarget using BM
   6.   C   = H1|H2  I am SyncTarget setting BM
   7.   B   =   C    I am SyncSource using BM
@@ -867,9 +871,30 @@
 
 40 Do something with FLUSHBUFS ioctl.
 
-41 Fix DRBD's behaviour in case of a cluster crash when both nodes
-   are in primary state.
+41 Fix DRBD's behaviour in case of a common power failuer and when 
+   both nodes were in primary role.
 
+   See the the Algorithm of Item 16, section 4 to 4.4 .
+
+   Further we need to have the resync rolces conflict  "rr-conflict" 
+   strategy option with the following values:
+
+   The available options are:
+     "disconnect" ... No automatic resynchronisation, simply disconnect.
+     "violently" .... Sync to the primary node is allowed, violating the 
+	              assumption that data on a block device is stable
+		      for one of the nodes. DANGEROUS, DO NOT USE.
+     "call-pri-lost"
+                      Call this helper program on one of the machines.
+                      This program is expected to halt or reboot the
+                      machine.
+
+   An exception of course is a primary disk-less node that gets a disk
+   attached. Such a nodes becomes sync target, but since it does not
+   show a violently data change, this state transition is always allowed.
+
+   99% DONE
+
 42 Forward port the abilitiy to resume the TL after IO was frozen,
    in case the connection is reestablished again.
 

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2006-11-18 10:46:55 UTC (rev 2601)
+++ trunk/drbd/drbd_int.h	2006-11-19 12:54:50 UTC (rev 2602)
@@ -684,7 +684,9 @@
 	CLUSTER_ST_CHANGE,      // Cluster wide state change going on...
 	CL_ST_CHG_SUCCESS,
 	CL_ST_CHG_FAIL,
-	CRASHED_PRIMARY,	// This node was a crashed primary
+	CRASHED_PRIMARY,	// This node was a crashed primary. Gets
+	                        // cleared when the state.conn  goes into 
+	                        // Connected state.
 	WRITE_BM_AFTER_RESYNC	// A kmalloc() during resync failed
 };
 

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-11-18 10:46:55 UTC (rev 2601)
+++ trunk/drbd/drbd_main.c	2006-11-19 12:54:50 UTC (rev 2602)
@@ -834,8 +834,7 @@
 	enum fencing_policy fp;
 	u32 mdf;
 
-	if ( (os.role != Primary && ns.role == Primary)    ||
-	     (os.conn != Connected && ns.conn == Connected) ) {
+	if ( (os.conn != Connected && ns.conn == Connected) ) {
 		clear_bit(CRASHED_PRIMARY, &mdev->flags);
 	}
 
@@ -1278,6 +1277,7 @@
 {
 	Drbd_GenCnt_Packet p;
 	int i;
+	u64 uuid_flags = 0;
 
 	if(!inc_local_if_state(mdev,Negotiating)) return 1; // ok.
 
@@ -1289,7 +1289,9 @@
 	}
 
 	p.uuid[UUID_SIZE] = cpu_to_be64(drbd_bm_total_weight(mdev));
-	p.uuid[UUID_FLAGS] = cpu_to_be64(mdev->net_conf->want_lose);
+	uuid_flags |= mdev->net_conf->want_lose ? 1 : 0;
+	uuid_flags |= test_bit(CRASHED_PRIMARY, &mdev->flags) ? 2 : 0;
+	p.uuid[UUID_FLAGS] = cpu_to_be64(uuid_flags);
 
 	dec_local(mdev);
 

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-11-18 10:46:55 UTC (rev 2601)
+++ trunk/drbd/drbd_receiver.c	2006-11-19 12:54:50 UTC (rev 2602)
@@ -1737,7 +1737,7 @@
 		if( hg == -1 && mdev->state.role==Secondary) rv=hg;
 		if( hg == 1  && mdev->state.role==Primary)   rv=hg;
 		break;
-	case ViolentlyAS0Pri:
+	case Violently:
 		rv = drbd_asb_recover_0p(mdev);
 		break;
 	case DiscardSecondary:
@@ -1775,7 +1775,7 @@
 	case DiscardSecondary:
 		ERR("Configuration error.\n");
 		break;
-	case ViolentlyAS0Pri:
+	case Violently:
 		rv = drbd_asb_recover_0p(mdev);
 		break;
 	case Disconnect:
@@ -1833,8 +1833,23 @@
 	if (self != UUID_JUST_CREATED &&
 	    peer == UUID_JUST_CREATED) return 2;
 
-	if (self == peer) return 0;
+	if (self == peer) { // Common power [off|failure]
+		int rct; // roles at crash time
 
+		rct = (test_bit(CRASHED_PRIMARY, &mdev->flags) ? 1 : 0) +
+			( mdev->p_uuid[UUID_FLAGS] & 2 );
+		// lowest bit is set when we were primary
+		// next bit (weight 2) is set when peer was primary
+
+		switch(rct) {
+		case 0: /* !self_pri && !peer_pri */ return 0;
+		case 1: /*  self_pri && !peer_pri */ return 1;
+		case 2: /* !self_pri &&  peer_pri */ return -1;
+		case 3: /*  self_pri &&  peer_pri */ 
+			return test_bit(DISCARD_CONCURRENT,&mdev->flags) ? -1 : 1;
+		}
+	}
+
 	peer = mdev->p_uuid[Bitmap] & ~((u64)1);
 	if (self == peer) return -1;
 
@@ -1925,9 +1940,9 @@
 		}
 	}
 	
-	if (hg == 0) {
+	if (abs(hg) < 100) {
 		// This is needed in case someone does an invalidate on an
-		// disconnected node.
+		// disconnected node. This has priority.
 		if(mydisk==Inconsistent && peer_disk>Inconsistent) hg=-1;
 		if(mydisk>Inconsistent && peer_disk==Inconsistent) hg= 1;
 	}
@@ -1952,8 +1967,21 @@
 		return conn_mask;
 	}
 
-	/* The check "I shall become SyncTarget, but I am primary"
-	   got removed since, we now do live attachs on primary nodes! */
+	if (hg < 0 && // by intention we do not use mydisk here.
+	    mdev->state.role == Primary && mdev->state.disk >= Consistent ) {
+		switch(mdev->net_conf->rr_conflict) {
+		case CallHelper:
+			drbd_khelper(mdev,"pri-lost");
+			// fall through
+		case Disconnect:
+			ERR("I shall become SyncTarget, but I am primary!\n");
+			drbd_force_state(mdev,NS(conn,Disconnecting));
+			return conn_mask;
+		case Violently:
+			WARN("Becoming SyncTarget, violating the stable-data"
+			     "assumption\n");
+		}
+	}
 
 	if (abs(hg) >= 2) {
 		drbd_md_set_flag(mdev,MDF_FullSync);
@@ -1976,17 +2004,9 @@
 		rv = WFBitMapT;
 	} else {
 		rv = Connected;
-		drbd_bm_lock(mdev);   // {
 		if(drbd_bm_total_weight(mdev)) {
-			/* FIXME for two-primaries this is wrong and may lead
-			 * to diverging data sets! */
-			INFO("No resync -> clearing bit map.\n");
-			drbd_bm_clear_all(mdev);
-			drbd_uuid_set_bm(mdev,0UL);
-			if (unlikely(drbd_bm_write(mdev) < 0))
-				return conn_mask;
+			INFO("No resync, but bits in bitmap!\n");
 		}
-		drbd_bm_unlock(mdev); // }
 	}
 
 	return rv;

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2006-11-18 10:46:55 UTC (rev 2601)
+++ trunk/drbd/linux/drbd.h	2006-11-19 12:54:50 UTC (rev 2602)
@@ -62,7 +62,7 @@
 	Consensus,
 	DiscardSecondary,
 	CallHelper,
-	ViolentlyAS0Pri
+	Violently
 };
 
 /* KEEP the order, do not delete or insert!

Modified: trunk/drbd/linux/drbd_limits.h
===================================================================
--- trunk/drbd/linux/drbd_limits.h	2006-11-18 10:46:55 UTC (rev 2601)
+++ trunk/drbd/linux/drbd_limits.h	2006-11-19 12:54:50 UTC (rev 2602)
@@ -113,6 +113,7 @@
 #define DRBD_AFTER_SB_0P_DEF Disconnect
 #define DRBD_AFTER_SB_1P_DEF Disconnect
 #define DRBD_AFTER_SB_2P_DEF Disconnect
+#define DRBD_RR_CONFLICT_DEF Disconnect
 
 #undef RANGE
 #endif

Modified: trunk/drbd/linux/drbd_nl.h
===================================================================
--- trunk/drbd/linux/drbd_nl.h	2006-11-18 10:46:55 UTC (rev 2601)
+++ trunk/drbd/linux/drbd_nl.h	2006-11-19 12:54:50 UTC (rev 2602)
@@ -46,6 +46,7 @@
 	INTEGER(	24,	T_MAY_IGNORE,	after_sb_0p)
 	INTEGER(	25,	T_MAY_IGNORE,	after_sb_1p)
 	INTEGER(	26,	T_MAY_IGNORE,	after_sb_2p)
+	INTEGER(	39,	T_MAY_IGNORE,	rr_conflict)
 	BIT(		27,	T_MAY_IGNORE,	want_lose)
 	BIT(		28,	T_MAY_IGNORE,	two_primaries)
 )

Modified: trunk/scripts/drbd.conf
===================================================================
--- trunk/scripts/drbd.conf	2006-11-18 10:46:55 UTC (rev 2601)
+++ trunk/scripts/drbd.conf	2006-11-19 12:54:50 UTC (rev 2602)
@@ -299,6 +299,14 @@
     #    "consensus"  ... discard the version of the secondary if the outcome
     #                     of the "after-sb-0pri" algorithm would also destroy 
     #                     the current secondary's data. Otherwise disconnect.
+    #    "violently-as0p" Always take the decission of the "after-sb-0pri"
+    #                     algorithm. Even if that causes case an erratic change
+    #		          of the primarie's view of the data.
+    #                     This is only usefull if you use an 1node FS (i.e.
+    #		          not OCFS2 or GFS) with the allow-two-primaries
+    #		          flag, _AND_ you really know what you are doing.
+    #		          This is DANGEROUS and MAY CRASH YOUR MACHINE if you
+    #		          have a FS mounted on the primary node.
     #    "discard-secondary"     
     #                     discard the version of the secondary.
     #    "panic-primary"  Always honour the outcome of the "after-sb-0pri"
@@ -311,10 +319,22 @@
     # In case both nodes are primary you control DRBD's strategy by
     # the "after-sb-2pri" option.
     #    "disconnect" ... Go to StandAlone mode on both sides.
+    #    "violently-as0p" Always take the decission of the "after-sb-0pri".
     #    "panic"      ... Honor the outcome of the "after-sb-0pri" algorithm
     #                     and panic the other node.
     after-sb-2pri disconnect;
 
+    # To solve the cases when the outcome of the resync descissions is 
+    # incompatible to the current role asignment in the cluster.
+    #    "disconnect" ... No automatic resynchronisation, simply disconnect.
+    #    "violently" .... Sync to the primary node is allowed, violating the 
+    #	                  assumption that data on a block device is stable
+    #		          for one of the nodes. DANGEROUS, DO NOT USE.
+    #    "call-pri-lost"  Call the "pri-lost" helper program on one of the 
+    #	                  machines. This program is expected to reboot the
+    #                     machine. (I.e. make it secondary.)
+    rr-conflict disconnect;
+
     # DRBD-0.7's behaviour is equivalent to 
     #   after-sb-0pri discard-younger-primary;
     #   after-sb-1pri consensus;

Modified: trunk/user/drbdadm_scanner.fl
===================================================================
--- trunk/user/drbdadm_scanner.fl	2006-11-18 10:46:55 UTC (rev 2601)
+++ trunk/user/drbdadm_scanner.fl	2006-11-19 12:54:50 UTC (rev 2602)
@@ -78,7 +78,8 @@
 cram-hmac-alg		{ DP; CP; return TK_NET_OPTION;		}
 shared-secret		{ DP; CP; return TK_NET_OPTION;		}
 max-epoch-size		{ DP; CP; RC(MAX_EPOCH_SIZE); return TK_NET_OPTION;}
-after-sb-[012]pri	{ DP; CP; return TK_NET_OPTION;		}
+after-sb-[012]pri	{ DP; CP; return TK_NET_OPTION;		} 
+rr-conflict 		{ DP; CP; return TK_NET_OPTION;		} 
 unplug-watermark	{ DP; CP; return TK_NET_OPTION;         }
 allow-two-primaries	{ DP; CP; return TK_NET_SWITCH;		}
 rate			{ DP; CP; RC(RATE); return TK_SYNCER_OPTION;	}
@@ -88,6 +89,7 @@
 degr-wfc-timeout	{ DP; CP; RC(DEGR_WFC_TIMEOUT); return TK_STARTUP_OPTION;}
 pri-on-incon-degr	{ DP; CP; return TK_HANDLER_OPTION;	}
 pri-lost-after-sb	{ DP; CP; return TK_HANDLER_OPTION;	}
+pri-lost	        { DP; CP; return TK_HANDLER_OPTION;     }
 outdate-peer		{ DP; CP; return TK_HANDLER_OPTION;	}
 local-io-error		{ DP; CP; return TK_HANDLER_OPTION;     }
 {IPV4ADDR}		{ DP; CP; return TK_IPADDR;		}

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2006-11-18 10:46:55 UTC (rev 2601)
+++ trunk/user/drbdsetup.c	2006-11-19 12:54:50 UTC (rev 2602)
@@ -206,17 +206,23 @@
 const char *asb1p_n[] = {
 	[Disconnect]        = "disconnect",
 	[Consensus]         = "consensus",
-	[ViolentlyAS0Pri]   = "violently-as0p",
+	[Violently]         = "violently-as0p",
 	[DiscardSecondary]  = "discard-secondary",
 	[CallHelper]        = "call-pri-lost-after-sb"
 };
 
 const char *asb2p_n[] = {
 	[Disconnect]        = "disconnect",
-	[ViolentlyAS0Pri]   = "violently-as0p",
+	[Violently]         = "violently-as0p",
 	[CallHelper]        = "call-pri-lost-after-sb"
 };
 
+const char *rrcf_n[] = {
+	[Disconnect]        = "disconnect",
+	[Violently]         = "violently",
+	[CallHelper]        = "call-pri-lost"
+};
+
 struct option wait_cmds_options[] = {
 	{ "wfc-timeout",required_argument, 0, 't' },
 	{ "degr-wfc-timeout",required_argument,0,'d'},
@@ -283,6 +289,7 @@
 		 { "after-sb-0pri",'A',	T_after_sb_0p,EH(asb0p_n,AFTER_SB_0P) },
 		 { "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) },
+		 { "rr-conflict",'R',	T_rr_conflict,EH(rrcf_n,RR_CONFLICT) },
 		 { "discard-my-data",'D', T_want_lose,     EB },
 		 CLOSE_OPTIONS }} }, },
 

From drbd-cvs at lists.linbit.com  Mon Nov 20 22:16:26 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon Nov 20 22:16:28 2006
Subject: [DRBD-cvs] svn commit by phil - r2603 - in trunk: drbd drbd/linux
	scripts user - Splitted the generic timeout and the ping
	timeout. This
Message-ID: <20061120211626.3CFD72DEACDA@mail.linbit.com>

Author: phil
Date: 2006-11-20 22:16:22 +0100 (Mon, 20 Nov 2006)
New Revision: 2603

Modified:
   trunk/drbd/drbd_nl.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/linux/drbd_limits.h
   trunk/drbd/linux/drbd_nl.h
   trunk/scripts/drbd.conf
   trunk/user/drbdadm_scanner.fl
   trunk/user/drbdsetup.c
Log:
Splitted the generic timeout and the ping timeout. This allows
us to support sub-second failover times!

 When we are asked to become primary we need to check if the
 peer is still alive. Since the asender-thread is a real-time
 task, this works really fast.



Modified: trunk/drbd/drbd_nl.c
===================================================================
--- trunk/drbd/drbd_nl.c	2006-11-19 12:54:50 UTC (rev 2602)
+++ trunk/drbd/drbd_nl.c	2006-11-20 21:16:22 UTC (rev 2603)
@@ -353,6 +353,7 @@
 			   struct drbd_nl_cfg_reply *reply)
 {
 	struct primary primary_args;
+	int rv;
 
 	memset(&primary_args, 0, sizeof(struct primary));
 	if(!primary_from_tags(mdev,nlp->tag_list,&primary_args)) {
@@ -360,8 +361,15 @@
 		return 0;
 	}
 
-	reply->ret_code = drbd_set_role(mdev, Primary, primary_args.overwrite_peer);
-
+	request_ping(mdev); // Detect a dead peer ASAP
+	rv = drbd_set_role(mdev, Primary, primary_args.overwrite_peer);
+	if( rv == SS_TwoPrimaries ) { 
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout((mdev->net_conf->ping_timeo+1)*HZ/10);
+		rv = drbd_set_role(mdev, Primary, primary_args.overwrite_peer);
+	}
+	
+	reply->ret_code = rv;
 	return 0;
 }
 
@@ -1006,6 +1014,8 @@
 		new_conf->want_lose       = 0;
 		new_conf->two_primaries   = 0;
 		new_conf->wire_protocol   = DRBD_PROT_C;
+		new_conf->ping_timeo      = DRBD_PING_TIMEO_DEF;
+		new_conf->rr_conflict     = DRBD_RR_CONFLICT_DEF;
 	}
 
 	if (!net_conf_from_tags(mdev,nlp->tag_list,new_conf)) {

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-11-19 12:54:50 UTC (rev 2602)
+++ trunk/drbd/drbd_receiver.c	2006-11-20 21:16:22 UTC (rev 2603)
@@ -769,7 +769,7 @@
 	sock->sk->sk_sndbuf = mdev->net_conf->sndbuf_size;
 	sock->sk->sk_rcvbuf = mdev->net_conf->sndbuf_size;
 	/* NOT YET ...
-	 * sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/20;
+	 * sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10;
 	 * sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
 	 * first set it to the HandShake timeout, wich is hardcoded for now: */
 	sock->sk->sk_sndtimeo =
@@ -779,7 +779,7 @@
 	msock->sk->sk_priority=TC_PRIO_INTERACTIVE;
 	tcp_sk(sock->sk)->nonagle = 1;
 	msock->sk->sk_sndbuf = 2*32767;
-	msock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/20;
+	msock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10;
 	msock->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ;
 
 	mdev->data.socket = sock;
@@ -799,7 +799,7 @@
 		}
 	}
 
-	sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/20;
+	sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10;
 	sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT;
 
 	atomic_set(&mdev->packet_seq,0);
@@ -3262,10 +3262,8 @@
 	while (get_t_state(thi) == Running) {
 		if (test_and_clear_bit(SEND_PING, &mdev->flags)) {
 			ERR_IF(!drbd_send_ping(mdev)) goto err;
-			// half ack timeout only,
-			// since sendmsg waited the other half already
 			mdev->meta.socket->sk->sk_rcvtimeo =
-				mdev->net_conf->timeout*HZ/20;
+				mdev->net_conf->ping_timeo*HZ/10;
 		}
 
 		while(1) {
@@ -3305,7 +3303,7 @@
 			goto err;
 		} else if (rv == -EAGAIN) {
 			if( mdev->meta.socket->sk->sk_rcvtimeo ==
-			    mdev->net_conf->timeout*HZ/20) {
+			    mdev->net_conf->ping_timeo*HZ/10 ) {
 				ERR("PingAck did not arrive in time.\n");
 				goto err;
 			}

Modified: trunk/drbd/linux/drbd_limits.h
===================================================================
--- trunk/drbd/linux/drbd_limits.h	2006-11-19 12:54:50 UTC (rev 2602)
+++ trunk/drbd/linux/drbd_limits.h	2006-11-20 21:16:22 UTC (rev 2603)
@@ -54,6 +54,11 @@
 #define DRBD_PING_INT_MAX 120
 #define DRBD_PING_INT_DEF 10
 
+ /* timeout for the ping packets.*/
+#define DRBD_PING_TIMEO_MIN  1
+#define DRBD_PING_TIMEO_MAX  100
+#define DRBD_PING_TIMEO_DEF  5
+
   /* max number of write requests between write barriers */
 #define DRBD_MAX_EPOCH_SIZE_MIN 1
 #define DRBD_MAX_EPOCH_SIZE_MAX 20000

Modified: trunk/drbd/linux/drbd_nl.h
===================================================================
--- trunk/drbd/linux/drbd_nl.h	2006-11-19 12:54:50 UTC (rev 2602)
+++ trunk/drbd/linux/drbd_nl.h	2006-11-20 21:16:22 UTC (rev 2603)
@@ -47,6 +47,7 @@
 	INTEGER(	25,	T_MAY_IGNORE,	after_sb_1p)
 	INTEGER(	26,	T_MAY_IGNORE,	after_sb_2p)
 	INTEGER(	39,	T_MAY_IGNORE,	rr_conflict)
+	INTEGER(	40,	T_MAY_IGNORE,	ping_timeo)
 	BIT(		27,	T_MAY_IGNORE,	want_lose)
 	BIT(		28,	T_MAY_IGNORE,	two_primaries)
 )

Modified: trunk/scripts/drbd.conf
===================================================================
--- trunk/scripts/drbd.conf	2006-11-19 12:54:50 UTC (rev 2602)
+++ trunk/scripts/drbd.conf	2006-11-20 21:16:22 UTC (rev 2603)
@@ -224,6 +224,7 @@
     # timeout       60;    #  6 seconds  (unit = 0.1 seconds)
     # connect-int   10;    # 10 seconds  (unit = 1 second)
     # ping-int      10;    # 10 seconds  (unit = 1 second)
+    # ping-timeout   5;    # 500 ms (unit = 0.1 seconds)
 
     # Maximal number of requests (4K) to be allocated by DRBD.
     # The minimum is hardcoded to 32 (=128 kByte).

Modified: trunk/user/drbdadm_scanner.fl
===================================================================
--- trunk/user/drbdadm_scanner.fl	2006-11-19 12:54:50 UTC (rev 2602)
+++ trunk/user/drbdadm_scanner.fl	2006-11-20 21:16:22 UTC (rev 2603)
@@ -80,6 +80,7 @@
 max-epoch-size		{ DP; CP; RC(MAX_EPOCH_SIZE); return TK_NET_OPTION;}
 after-sb-[012]pri	{ DP; CP; return TK_NET_OPTION;		} 
 rr-conflict 		{ DP; CP; return TK_NET_OPTION;		} 
+ping-timeout 		{ DP; CP; return TK_NET_OPTION;		} 
 unplug-watermark	{ DP; CP; return TK_NET_OPTION;         }
 allow-two-primaries	{ DP; CP; return TK_NET_SWITCH;		}
 rate			{ DP; CP; RC(RATE); return TK_SYNCER_OPTION;	}

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2006-11-19 12:54:50 UTC (rev 2602)
+++ trunk/user/drbdsetup.c	2006-11-20 21:16:22 UTC (rev 2603)
@@ -290,6 +290,7 @@
 		 { "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) },
 		 { "rr-conflict",'R',	T_rr_conflict,EH(rrcf_n,RR_CONFLICT) },
+		 { "ping-timeout",'p',  T_ping_timeo,	   EN(PING_TIMEO,1) },
 		 { "discard-my-data",'D', T_want_lose,     EB },
 		 CLOSE_OPTIONS }} }, },
 

From drbd-cvs at lists.linbit.com  Tue Nov 21 18:29:50 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue Nov 21 18:29:50 2006
Subject: [DRBD-cvs] svn commit by phil - r2604 - in trunk: . drbd - Made the
	sub-second takeover code less verbose. (Untest
Message-ID: <20061121172950.32E952D9D461@mail.linbit.com>

Author: phil
Date: 2006-11-21 18:29:49 +0100 (Tue, 21 Nov 2006)
New Revision: 2604

Modified:
   trunk/ROADMAP
   trunk/drbd/drbd_nl.c
Log:
Made the sub-second takeover code less verbose.
(Untested, will test later.)


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-11-20 21:16:22 UTC (rev 2603)
+++ trunk/ROADMAP	2006-11-21 17:29:49 UTC (rev 2604)
@@ -898,6 +898,8 @@
 42 Forward port the abilitiy to resume the TL after IO was frozen,
    in case the connection is reestablished again.
 
+43 Fix indexed meta-data.
+
 Maybe:
 
 *  Switch to protocol C in case we are running without a local 

Modified: trunk/drbd/drbd_nl.c
===================================================================
--- trunk/drbd/drbd_nl.c	2006-11-20 21:16:22 UTC (rev 2603)
+++ trunk/drbd/drbd_nl.c	2006-11-21 17:29:49 UTC (rev 2604)
@@ -243,7 +243,7 @@
 		mdev->this_bdev->bd_contains = mdev->this_bdev;
 	}
 
-	if ( new_role & Secondary ) {
+	if ( new_role == Secondary ) {
 		/* If I got here, I am Primary. I claim me for myself. If that
 		 * does not succeed, someone other has claimed me, so I cannot
 		 * become Secondary. */
@@ -253,8 +253,12 @@
 			bd_release(mdev->this_bdev);
 	}
 
+	if ( new_role == Primary ) {
+		request_ping(mdev); // Detect a dead peer ASAP
+	}
+
 	mask.i = 0; mask.role = role_mask;
-	val.i  = 0; val.role  = new_role & role_mask;
+	val.i  = 0; val.role  = new_role;
 
 	while (try++ < 3) {
 		r = _drbd_request_state(mdev,mask,val,0);
@@ -280,7 +284,13 @@
 
 			continue;
 		}
-
+		if( r == SS_TwoPrimaries ) {
+			// Maybe the peer is detected as dead very soon...
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout((mdev->net_conf->ping_timeo+1)*HZ/10);
+			if(try == 1) try++; // only a single retry in this case.
+			continue;
+		}
 		if ( r < SS_Success ) {
 			r = drbd_request_state(mdev,mask,val); // Be verbose.
 			if( r < SS_Success ) goto fail;
@@ -305,7 +315,7 @@
 	 * but that means someone is misusing DRBD...
 	 * */
 
-	if (new_role & Secondary) {
+	if (new_role == Secondary) {
 		set_disk_ro(mdev->vdisk, TRUE );
 	} else {
 		if(inc_net(mdev)) {
@@ -324,7 +334,7 @@
 		}
 	}
 
-	if((new_role & Secondary) && inc_local(mdev) ) {
+	if((new_role == Secondary) && inc_local(mdev) ) {
 		drbd_al_to_on_disk_bm(mdev);
 		dec_local(mdev);
 	}
@@ -340,7 +350,7 @@
 	return r;
 
  fail:
-	if ( new_role & Secondary ) {
+	if ( new_role == Secondary ) {
 		D_ASSERT(mdev->this_bdev->bd_holder == drbd_sec_holder);
 		bd_release(mdev->this_bdev);
 	}
@@ -353,7 +363,6 @@
 			   struct drbd_nl_cfg_reply *reply)
 {
 	struct primary primary_args;
-	int rv;
 
 	memset(&primary_args, 0, sizeof(struct primary));
 	if(!primary_from_tags(mdev,nlp->tag_list,&primary_args)) {
@@ -361,15 +370,8 @@
 		return 0;
 	}
 
-	request_ping(mdev); // Detect a dead peer ASAP
-	rv = drbd_set_role(mdev, Primary, primary_args.overwrite_peer);
-	if( rv == SS_TwoPrimaries ) { 
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout((mdev->net_conf->ping_timeo+1)*HZ/10);
-		rv = drbd_set_role(mdev, Primary, primary_args.overwrite_peer);
-	}
-	
-	reply->ret_code = rv;
+	reply->ret_code = drbd_set_role(mdev, Primary, primary_args.overwrite_peer);
+
 	return 0;
 }
 

From drbd-cvs at lists.linbit.com  Wed Nov 29 10:20:08 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed Nov 29 10:20:09 2006
Subject: [DRBD-cvs] svn commit by rasto - r2605 - trunk/tools - removed
	warning in dopd.c, fixed email address and fixe
Message-ID: <20061129092008.E33042CFED29@mail.linbit.com>

Author: rasto
Date: 2006-11-29 10:20:06 +0100 (Wed, 29 Nov 2006)
New Revision: 2605

Modified:
   trunk/tools/dopd.c
   trunk/tools/drbd-peer-outdater.c
Log:
removed warning in dopd.c, fixed email address and fixed typos in the help text


Modified: trunk/tools/dopd.c
===================================================================
--- trunk/tools/dopd.c	2006-11-21 17:29:49 UTC (rev 2604)
+++ trunk/tools/dopd.c	2006-11-29 09:20:06 UTC (rev 2605)
@@ -1,7 +1,7 @@
 /* $Id$ */
 /* drbd outdate peer daemon
  * Copyright (C) 2006 LINBIT <http://www.linbit.com/>
- * Written by Rasto Levrinc <rasto@linbit.at>
+ * Written by Rasto Levrinc <rasto@linbit.com>
  *
  * based on ipfail.c and attrd.c
  *
@@ -465,6 +465,7 @@
 	char pid[10];
 	char *bname, *parameter;
 	IPC_Channel *apiIPC;
+	int rc;
 
 	/* Get the name of the binary for logging purposes */
 	bname = ha_strdup(argv[0]);
@@ -536,7 +537,7 @@
 	Gmain_timeout_add_full(G_PRIORITY_DEFAULT, 1000,
 	                        dopd_timeout_dispatch, (gpointer)hb,
 	                        dopd_dispatch_destroy);
-	int rc = init_server_ipc_comms(
+	rc = init_server_ipc_comms(
 			ha_strdup(T_OUTDATER),
 			outdater_client_connect,
 			outdater_client_destroy);

Modified: trunk/tools/drbd-peer-outdater.c
===================================================================
--- trunk/tools/drbd-peer-outdater.c	2006-11-21 17:29:49 UTC (rev 2604)
+++ trunk/tools/drbd-peer-outdater.c	2006-11-29 09:20:06 UTC (rev 2605)
@@ -2,7 +2,7 @@
 /* drbd-peer-outdater
  * Copyright (C) 2006 LINBIT <http://www.linbit.com/>
  *
- * Written by Rasto Levrinc <rasto@linbit.at>
+ * Written by Rasto Levrinc <rasto@linbit.com>
  *
  * based on attrd
  *
@@ -224,10 +224,10 @@
 	fprintf(stream, "\t-t <int>\ttimeout in seconds; default: %d\n",
 			DEFAULT_TIMEOUT);
 	fprintf(stream, "\t-r <string>\tdrbd resource\n\n"
-		"The drbd resource has to be specified,\n"
+		"The drbd resource has to be specified \n"
 		"either on the commandline using the -r option,\n"
-		"or unsing the $DRBD_RESOURCE environment variable,\n"
-		"which will be ignored, if the -r option is used.\n");
+		"or using the $DRBD_RESOURCE environment variable.\n"
+		"$DRBD_RESOURCE will be ignored, if the -r option is used.\n");
 	fflush(stream);
 
 	exit(exit_status);

From drbd-cvs at lists.linbit.com  Thu Nov 30 16:00:24 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu Nov 30 16:00:26 2006
Subject: [DRBD-cvs] svn commit by phil - r2606 - in trunk: . scripts user -
	We are trying to get the dopd/drbd-peer-outdater stuff 
Message-ID: <20061130150024.A9E8A2CFF552@mail.linbit.com>

Author: phil
Date: 2006-11-30 16:00:22 +0100 (Thu, 30 Nov 2006)
New Revision: 2606

Modified:
   trunk/ROADMAP
   trunk/scripts/outdate-peer.sh
   trunk/user/drbdadm_main.c
Log:
We are trying to get the dopd/drbd-peer-outdater stuff commited
to heartbeat's revision control system. They want to support multiple
node, therefor we need to pass this informatipn (DRBD_PEER) on.


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-11-29 09:20:06 UTC (rev 2605)
+++ trunk/ROADMAP	2006-11-30 15:00:22 UTC (rev 2606)
@@ -226,6 +226,10 @@
   * We need to store the fact that the peer is outdated/inconsistent
     in the meta-data. To allow an stand allone primary to be rebooted.
 
+  * The outdate-peer program gets two environment variables:
+    DRBD_RESOURCE the name of the DRBD-resource and DRBD_PEER
+    the host name of the peer.
+
   99% DONE
 
 8 New command drbdmeta
@@ -900,6 +904,8 @@
 
 43 Fix indexed meta-data.
 
+44 Callbacks to userspace should run asynchronous.
+
 Maybe:
 
 *  Switch to protocol C in case we are running without a local 

Modified: trunk/scripts/outdate-peer.sh
===================================================================
--- trunk/scripts/outdate-peer.sh	2006-11-29 09:20:06 UTC (rev 2605)
+++ trunk/scripts/outdate-peer.sh	2006-11-30 15:00:22 UTC (rev 2606)
@@ -39,7 +39,7 @@
 #
 
 #
-# The caller (drbdadm) sets DRBD_RESOURCE for us.
+# The caller (drbdadm) sets DRBD_RESOURCE and DRBD_PEER for us.
 #
 
 TIMEOUT=6

Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c	2006-11-29 09:20:06 UTC (rev 2605)
+++ trunk/user/drbdadm_main.c	2006-11-30 15:00:22 UTC (rev 2606)
@@ -762,6 +762,7 @@
   char *argv[] = { "/bin/sh", "-c", NULL , NULL };
 
   setenv("DRBD_RESOURCE",res->name,1);
+  setenv("DRBD_PEER",res->peer->name,1);
 
   if( (sh_cmd = get_opt_val(res->handlers,cmd,NULL)) ) {
     argv[2]=sh_cmd;

