From drbd-cvs at lists.linbit.com  Tue May  2 09:45:45 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May  2 09:45:47 2006
Subject: [DRBD-cvs] svn commit by phil - r2195 - trunk/debian - A fix to the
	debian package stuff. 
Message-ID: <20060502074545.820EA14CC6@mail.linbit.com>

Author: phil
Date: 2006-05-02 09:45:41 +0200 (Tue, 02 May 2006)
New Revision: 2195

Modified:
   trunk/debian/changelog
   trunk/debian/control.modules.in
Log:
A fix to the debian package stuff.


Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog	2006-05-01 20:18:26 UTC (rev 2194)
+++ trunk/debian/changelog	2006-05-02 07:45:41 UTC (rev 2195)
@@ -1,4 +1,4 @@
-drbd (8.0pre3-0) unstable; urgency=low
+drbd8 (8.0pre3-0) unstable; urgency=low
 
   * New major release.
 

Modified: trunk/debian/control.modules.in
===================================================================
--- trunk/debian/control.modules.in	2006-05-01 20:18:26 UTC (rev 2194)
+++ trunk/debian/control.modules.in	2006-05-02 07:45:41 UTC (rev 2195)
@@ -1,4 +1,4 @@
-Source: drbd
+Source: drbd8
 Section: misc
 Priority: extra
 Maintainer: David Krovich <dkrovich@csee.wvu.edu>

From drbd-cvs at lists.linbit.com  Tue May  2 17:52:14 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May  2 17:52:15 2006
Subject: [DRBD-cvs] svn commit by phil - r2196 - trunk/user - Fixed a few
	minor issues with v07 meta-data. 
Message-ID: <20060502155214.4762514CC6@mail.linbit.com>

Author: phil
Date: 2006-05-02 17:52:11 +0200 (Tue, 02 May 2006)
New Revision: 2196

Modified:
   trunk/user/drbdmeta.c
Log:
Fixed a few minor issues with v07 meta-data.


Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2006-05-02 07:45:41 UTC (rev 2195)
+++ trunk/user/drbdmeta.c	2006-05-02 15:52:11 UTC (rev 2196)
@@ -421,6 +421,7 @@
 	cpu->al_offset = be32_to_cpu(disk->al_offset.be);
 	cpu->al_nr_extents = be32_to_cpu(disk->al_nr_extents.be);
 	cpu->bm_offset = be32_to_cpu(disk->bm_offset.be);
+	cpu->bm_bytes_per_bit = 4096;
 }
 
 void md_cpu_to_disk_07(struct md_on_disk_07 *disk, struct md_cpu *cpu)
@@ -904,7 +905,9 @@
 	cfg->bm_offset = cfg->md_offset + cfg->md.bm_offset * 512;
 
 	// For the case that someone modified la_sect by hand..
-	if(cfg->md.la_sect*512 > cfg->md_offset) {
+	if( (cfg->md_index == DRBD_MD_INDEX_INTERNAL ||
+	     cfg->md_index == DRBD_MD_INDEX_FLEX_INT ) &&
+	    (cfg->md.la_sect*512 > cfg->md_offset) ) {
 		printf("la-size-sect was too big, fixed.\n");
 		cfg->md.la_sect = cfg->md_offset/512;
 	}
@@ -1701,8 +1704,12 @@
 
 	if (format_version(cfg) >= Drbd_07) {
 		printf("la-size-sect "U64";\n", cfg->md.la_sect);
-		printf("bm-byte-per-bit "U32";\n",cfg->md.bm_bytes_per_bit);
-		printf("device-uuid 0x"X64(016)";\n",cfg->md.device_uuid);
+		if (format_version(cfg) >= Drbd_08) {
+			printf("bm-byte-per-bit "U32";\n",
+			       cfg->md.bm_bytes_per_bit);
+			printf("device-uuid 0x"X64(016)";\n",
+			       cfg->md.device_uuid);
+		}
 		printf("# bm-bytes %u;\n", cfg->bm_bytes);
 		printf("# bits-set %u;\n", cfg->bits_set);
 		if (cfg->on_disk.bm)
@@ -1770,10 +1777,14 @@
 	}
 	EXP(TK_LA_SIZE); EXP(TK_NUM); EXP(';');
 	cfg->md.la_sect = yylval.u64;
-	EXP(TK_BM_BYTE_PER_BIT); EXP(TK_NUM); EXP(';');
-	cfg->md.bm_bytes_per_bit = yylval.u64;
-	EXP(TK_DEVICE_UUID); EXP(TK_U64); EXP(';');
-	cfg->md.device_uuid = yylval.u64;
+	if (format_version(cfg) >= Drbd_08) {
+		EXP(TK_BM_BYTE_PER_BIT); EXP(TK_NUM); EXP(';');
+		cfg->md.bm_bytes_per_bit = yylval.u64;
+		EXP(TK_DEVICE_UUID); EXP(TK_U64); EXP(';');
+		cfg->md.device_uuid = yylval.u64;
+	} else {
+		cfg->md.bm_bytes_per_bit = 4096;
+	}
 	EXP(TK_BM); EXP('{');
 	bm = (le_u64 *)cfg->on_disk.bm;
 	i = 0;

From drbd-cvs at lists.linbit.com  Tue May  2 23:19:32 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May  2 23:19:33 2006
Subject: [DRBD-cvs] svn commit by phil - r2197 - trunk - Two more items on
	DRBD-v8's TODO list. 
Message-ID: <20060502211932.5AE732E5EF@mail.linbit.com>

Author: phil
Date: 2006-05-02 23:19:31 +0200 (Tue, 02 May 2006)
New Revision: 2197

Modified:
   trunk/ROADMAP
Log:
Two more items on DRBD-v8's TODO list.


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-05-02 15:52:11 UTC (rev 2196)
+++ trunk/ROADMAP	2006-05-02 21:19:31 UTC (rev 2197)
@@ -723,10 +723,20 @@
 
    99% DONE
 
-33 Save the minor number and the backing device in the (external) meta
-   data as sanity check.
+33 Make some of the state changes atomic in the whole cluster. So
+   far I identified the following state transitions:
 
+      role <- primary
+      conn <- SyncSource
+      conn <- SyncTarget
+      disk <- Diskless (as long as it happens as administrative command)
+      pdsk <- Outdated (= a 'disconnect' issued on a primary node)
 
+
+34 Improve the initial hand-shake, to identify the sockets (and TCP-
+   links) by an initial message, and not only by the connection timming.
+
+
 plus-banches:
 ----------------------
 

From drbd-cvs at lists.linbit.com  Fri May  5 13:09:30 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri May  5 13:09:32 2006
Subject: [DRBD-cvs] svn commit by phil - r2198 - trunk/user - A variation of
	Ard van Breemen's patch to fix the unini
Message-ID: <20060505110930.B90A82E7C5@mail.linbit.com>

Author: phil
Date: 2006-05-05 13:09:29 +0200 (Fri, 05 May 2006)
New Revision: 2198

Modified:
   trunk/user/drbdadm_usage_cnt.c
Log:
A variation of Ard van Breemen's patch to fix the uninitialized
buffer...


Modified: trunk/user/drbdadm_usage_cnt.c
===================================================================
--- trunk/user/drbdadm_usage_cnt.c	2006-05-02 21:19:31 UTC (rev 2197)
+++ trunk/user/drbdadm_usage_cnt.c	2006-05-05 11:09:29 UTC (rev 2198)
@@ -331,7 +331,8 @@
 	}
 
 	if(!send) return;
-	
+
+	n_comment[0]=0;
 	if (type == UC_ASK ) {
 		printf(
 "\n"
@@ -357,12 +358,9 @@
 			REL_VERSION,ni.node_uuid, ni.version_code);
 		fgets(answer,ANSWER_SIZE,stdin);
 		if(!strcmp(answer,"no\n")) send = 0;
+		url_encode(answer,n_comment);
 	}
 
-
-	n_comment[0]=0;
-	url_encode(answer,n_comment);
-
 	ssprintf(req_buf,"GET http://"HTTP_HOST"/cgi-bin/insert_usage.pl?"
 		 "nu="U64"&nv="U32"%s%s HTTP/1.0\n\n",
 		 ni.node_uuid, ni.version_code,

From drbd-cvs at lists.linbit.com  Wed May 17 17:41:29 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed May 17 17:41:31 2006
Subject: [DRBD-cvs] svn commit by phil - r2199 - trunk - More thought on
	transactional state changes... 
Message-ID: <20060517154129.8890A2D7E9@mail.linbit.com>

Author: phil
Date: 2006-05-17 17:41:28 +0200 (Wed, 17 May 2006)
New Revision: 2199

Modified:
   trunk/ROADMAP
Log:
More thought on transactional state changes...


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-05-05 11:09:29 UTC (rev 2198)
+++ trunk/ROADMAP	2006-05-17 15:41:28 UTC (rev 2199)
@@ -723,8 +723,8 @@
 
    99% DONE
 
-33 Make some of the state changes atomic in the whole cluster. So
-   far I identified the following state transitions:
+33 Serialize state changes like secondary -> primary and 
+   Connected -> SyncSource in the cluster.
 
       role <- primary
       conn <- SyncSource
@@ -732,7 +732,55 @@
       disk <- Diskless (as long as it happens as administrative command)
       pdsk <- Outdated (= a 'disconnect' issued on a primary node)
 
+   * When a state change might sleep ( reuqest_state() ) and it is 
+     to be cluster wide atomic ( pre_state_checks() determines this!).
+	1. Aquire the cluster state change lock (bit & waitqueue) ?
+	2. We send a request_state packet.
 
+   * When a request_state packet is received
+
+	1. * If we are UNIQUE we take the cluster lock (potentially
+	     waiting for it) and try to apply the remote's request
+	     as soon as we have the lock.
+	   * When we are not UNIQUE we try to apply the state change
+	     immediately (without taking the cluster lock).
+	2. We send the ACK / NACK.
+	   ( Do we actually need an ACK/NACK ? 
+ 		* On the not UNIQUE side, we will fail the request as
+		  soon as the offending state request comes in.
+                * On the UNIQUE side we need to positive ACK to 
+		  continue.
+		) I guess for the sake of completeness, we should
+                  have both packets, although currently the need for
+		  the NACK packet is not abvious.
+
+   * When we receive an ACK / NACK we either sucessfully finish or
+     fail the the request_state() call. (Error codes should be passed
+     from the peer.)
+
+   * When the connection failes ( = actually a non-cluster wide state
+     change happens while a cluster wide state change goes on), we
+     need to re-evaluate the pre state change check. In case the
+     pre state change check allows the new state we can procees,
+     otherwise we need to fail the request. 
+
+   * How to do the synchronisation form the receive of the ACK / NACK
+     packet to the termination of the request_state() function ?
+       * wait_queue & bit.
+
+   DATA STRUCTURES:
+	* A CLUSTER_STATE_CHANGE bit == the cluster lock bit.
+	* A CL_ST_CHG_SUCCESS  bit set by the receiver.
+	* A CL_ST_CHG_FAIL     bit set by the receiver.
+	* A wait queue.
+
+   TODOS: 
+    Make sure it is used for getting PRIMARY.
+    Evaluate if it is possible to use it for starting resync. (invalidate)
+    Evaluate it for the other cases...
+
+  50 % Is implemented, needs testing etc...
+
 34 Improve the initial hand-shake, to identify the sockets (and TCP-
    links) by an initial message, and not only by the connection timming.
 

From drbd-cvs at lists.linbit.com  Thu May 18 14:57:20 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu May 18 14:57:22 2006
Subject: [DRBD-cvs] svn commit by phil - r2200 - trunk/user - Fixed another
	stupid bug. 
Message-ID: <20060518125720.96A4816D94@mail.linbit.com>

Author: phil
Date: 2006-05-18 14:57:18 +0200 (Thu, 18 May 2006)
New Revision: 2200

Modified:
   trunk/user/drbdmeta.c
Log:
Fixed another stupid bug.


Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2006-05-17 15:41:28 UTC (rev 2199)
+++ trunk/user/drbdmeta.c	2006-05-18 12:57:18 UTC (rev 2200)
@@ -911,6 +911,10 @@
 		printf("la-size-sect was too big, fixed.\n");
 		cfg->md.la_sect = cfg->md_offset/512;
 	}
+	if(cfg->md.bm_bytes_per_bit == 0 ) {
+		printf("bm-byte-per-bit was 0, fixed. (Set to 4096)\n");
+		cfg->md.bm_bytes_per_bit = 4096;
+	}
 	words = bm_words(cfg->md.la_sect, cfg->md.bm_bytes_per_bit);
 	cfg->bm_bytes = words * sizeof(long);
 

From drbd-cvs at lists.linbit.com  Thu May 18 16:14:24 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu May 18 16:14:26 2006
Subject: [DRBD-cvs] svn commit by rasto - r2201 - in trunk: . tools - added
	files 
Message-ID: <20060518141424.9DA852F039@mail.linbit.com>

Author: rasto
Date: 2006-05-18 16:14:23 +0200 (Thu, 18 May 2006)
New Revision: 2201

Added:
   trunk/tools/
   trunk/tools/README
   trunk/tools/dopd.c
   trunk/tools/dopd.h
   trunk/tools/drbd-peer-outdater.c
Log:
added files


Added: trunk/tools/README
===================================================================
--- trunk/tools/README	2006-05-18 12:57:18 UTC (rev 2200)
+++ trunk/tools/README	2006-05-18 14:14:23 UTC (rev 2201)
@@ -0,0 +1,20 @@
+1) compile
+
+copy this directory into heartbeat tools directory and compile it 
+with heartbeat.
+
+2) prepare drbdmeta
+
+cd /sbin
+chown .haclient drbdmeta
+chmod o-x drbdmeta
+chmod u+s drbdmeta
+
+3) Configure Heartbeat to run the DRBD outdate peer daemon
+
+Add these lines to /etc/ha.d/ha.cf
+---
+respawn hacluster /usr/lib/heartbeat/dopd
+apiauth dopd gid=haclient uid=hacluster
+---
+

Added: trunk/tools/dopd.c
===================================================================
--- trunk/tools/dopd.c	2006-05-18 12:57:18 UTC (rev 2200)
+++ trunk/tools/dopd.c	2006-05-18 14:14:23 UTC (rev 2201)
@@ -0,0 +1,557 @@
+/* $Id$ */
+/* drbd outdate peer daemon
+ * Copyright (C) 2006 LINBIT <http://www.linbit.com/>
+ * Written by Rasto Levrinc <rasto@linbit.at>
+ *
+ * based on ipfail.c and attrd.c
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This software 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.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <portability.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <libgen.h>
+#include <heartbeat.h>
+#include <ha_msg.h>
+#include <hb_api.h>
+#include <clplumbing/cl_signal.h>
+#include <clplumbing/GSource.h>
+#include <clplumbing/Gmain_timeout.h>
+#include <clplumbing/coredumps.h>
+#include <dopd.h>
+#include <clplumbing/cl_misc.h>
+
+#include <crm/crm.h>
+#include <crm/common/ipc.h>
+
+
+const char *node_name;	   /* The node we are connected to            */
+char other_node[SYS_NMLN]; /* The remote node in the pair             */
+int node_stable;           /* Other node stable?                      */
+int need_standby;          /* Are we waiting for stability?           */
+int quitnow = 0;           /* Allows a signal to break us out of loop */
+GMainLoop *mainloop;       /* Reference to the mainloop for events    */
+ll_cluster_t *dopd_cluster_conn;
+
+/* only one client can be connected at a time */
+
+typedef struct dopd_client_s
+{
+	char  *id;
+
+	IPC_Channel *channel;
+	GCHSource   *source;
+} dopd_client_t;
+
+IPC_Channel *CURR_CLIENT_CHANNEL = NULL;
+
+/* send_message_to_other_node()
+ * send message with drbd resource to other node.
+ */
+static gboolean
+send_message_to_other_node(const char *drbd_resource)
+{
+	ll_cluster_t *hb = dopd_cluster_conn;
+        HA_Message *msg = NULL;
+
+        crm_info("sending start_outdate message to the other node %s -> %s",
+		  node_name, other_node);
+
+        msg = ha_msg_new(3);
+        ha_msg_add(msg, F_TYPE, "start_outdate");
+        ha_msg_add(msg, F_ORIG, node_name);
+        ha_msg_add(msg, F_DOPD_RES, drbd_resource);
+
+	crm_debug("sending [start_outdate res: %s] to other node", 
+		  drbd_resource);
+        hb->llc_ops->sendnodemsg(hb, msg, other_node);
+	ha_msg_del(msg);
+
+        return TRUE;
+}
+
+/* msg_start_outdate()
+ * got start_outdate message with resource from other node. Execute drbd
+ * outdate command, convert return code and send message to other node
+ * with return code.
+ *
+ * Conversion of return codes:
+ *     0 => 4
+ *     5 => 3
+ *    17 => 6
+ * other => 5
+ */
+void
+msg_start_outdate(struct ha_msg *msg, void *private)
+{
+	ll_cluster_t *hb = (ll_cluster_t *)private;
+	int rc = 5;
+	int command_ret;
+
+	char rc_string[4];
+        HA_Message *msg2 = NULL;
+	const char *drbd_resource = ha_msg_value(msg, F_DOPD_RES);
+	char *command;
+
+	/* execute outdate command */
+        crm_malloc0(command, strlen(OUTDATE_COMMAND) + 1 + strlen(drbd_resource) + 1);
+	strcpy(command, OUTDATE_COMMAND);
+	strcat(command, " ");
+	strcat(command, drbd_resource);
+	crm_debug("command: %s", command);
+	command_ret = system(command) >> 8;
+
+	/* convert return code */
+	crm_free(command);
+	if (command_ret == 0)
+		rc = 4;
+	else if (command_ret == 5)
+		rc = 3;
+	else if (command_ret == 17)
+		rc = 6;
+	else
+		crm_info("unknown exit code from "OUTDATE_COMMAND": %i",
+				command_ret);
+
+	crm_debug("msg_start_outdate: %s, command rc: %i, rc: %i", 
+			 ha_msg_value(msg, F_ORIG), command_ret, rc);
+	sprintf(rc_string, "%i", rc);
+
+	/* send return code to oder node */
+	msg2 = ha_msg_new(3);
+	ha_msg_add(msg2, F_TYPE, "outdate_rc");
+	ha_msg_add(msg2, F_DOPD_VALUE, rc_string);
+	ha_msg_add(msg2, F_ORIG, node_name);
+
+	hb->llc_ops->sendnodemsg(hb, msg2, other_node);
+	ha_msg_del(msg2);
+}
+
+/* msg_outdate_rc()
+ * got outdate_rc message with return code from other node. Send the 
+ * return code to the outdater client.
+ */
+void
+msg_outdate_rc(struct ha_msg *msg_in, void *private)
+{
+        HA_Message *msg_out = NULL;
+	const char *rc_string = ha_msg_value(msg_in, F_DOPD_VALUE);
+
+	if (CURR_CLIENT_CHANNEL == NULL)
+		return;
+	crm_debug("msg_outdate_rc: %s", rc_string);
+	msg_out = ha_msg_new(3);
+	ha_msg_add(msg_out, F_TYPE, "outdater_rc");
+	ha_msg_add(msg_out, F_ORIG, node_name);
+	ha_msg_add(msg_out, F_DOPD_VALUE, rc_string);
+
+	if (send_ipc_message(CURR_CLIENT_CHANNEL, msg_out) == FALSE) {
+		crm_err("Could not send message to the client");
+	}
+	CURR_CLIENT_CHANNEL = NULL;
+}
+
+/* outdater_callback()
+ * got message from outdater client with drbd resource, it will be sent
+ * to the other node.
+ */
+static gboolean
+outdater_callback(IPC_Channel *client, gpointer user_data)
+{
+	int lpc = 0;
+	HA_Message *msg = NULL;
+	const char *drbd_resource = NULL;
+	dopd_client_t *curr_client = (dopd_client_t*)user_data;
+	gboolean stay_connected = TRUE;
+
+	crm_debug("invoked: %s", curr_client->id);
+
+	/* allow one connection from outdater at a time */
+	if (CURR_CLIENT_CHANNEL != NULL &&
+	    CURR_CLIENT_CHANNEL != curr_client->channel) {
+		crm_debug("one client already connected");
+		return FALSE;
+	}
+	CURR_CLIENT_CHANNEL = curr_client->channel;
+
+	while (IPC_ISRCONN(client)) {
+		if(client->ops->is_message_pending(client) == 0) {
+			break;
+		}
+
+                msg = msgfromIPC_noauth(client);
+                if (msg == NULL) {
+                        crm_debug("%s: no message this time",
+				  curr_client->id);
+                        continue;
+		}
+
+		lpc++;
+
+		crm_debug("Processing msg from %s", curr_client->id);
+		crm_debug("Got message from (%s). (%s)",
+				ha_msg_value(msg, F_ORIG),
+				ha_msg_value(msg, F_OUTDATER_RES));
+
+		drbd_resource = ha_msg_value(msg, F_OUTDATER_RES);
+		send_message_to_other_node(drbd_resource);
+
+		crm_msg_del(msg);
+		msg = NULL;
+
+		if(client->ch_status != IPC_CONNECT) {
+			break;
+		}
+	}
+	crm_debug("Processed %d messages", lpc);
+	if (client->ch_status != IPC_CONNECT) {
+		stay_connected = FALSE;
+	}
+	return stay_connected;
+}
+
+
+/* outdater_ipc_connection_destroy()
+ * clean client struct
+ */
+static void
+outdater_ipc_connection_destroy(gpointer user_data)
+{
+	dopd_client_t *client = (dopd_client_t*)user_data;
+
+	if (client == NULL)
+		return;
+
+	if (client->source != NULL) {
+		crm_debug("Deleting %s (%p) from mainloop",
+				client->id, client->source);
+		G_main_del_IPC_Channel(client->source);
+		client->source = NULL;
+	}
+	crm_free(client->id);
+	if (client->channel == CURR_CLIENT_CHANNEL) {
+		crm_debug("connection from client closed");
+		CURR_CLIENT_CHANNEL = NULL;
+	}
+	crm_free(client);
+	return;
+}
+
+/* outdater_client_connect()
+ * outdater is connected set outdater_callback.
+ */
+static gboolean
+outdater_client_connect(IPC_Channel *channel, gpointer user_data)
+{
+        dopd_client_t *new_client = NULL;
+        crm_debug("Connecting channel");
+        if(channel == NULL) {
+                crm_err("Channel was NULL");
+                return FALSE;
+
+        } else if(channel->ch_status != IPC_CONNECT) {
+                crm_err("Channel was disconnected");
+                return FALSE;
+        }
+
+        crm_malloc0(new_client, sizeof(dopd_client_t));
+        new_client->channel = channel;
+        crm_malloc0(new_client->id, 10);
+        strcpy(new_client->id, "outdater");
+
+        new_client->source = G_main_add_IPC_Channel(
+                G_PRIORITY_DEFAULT, channel, FALSE, outdater_callback,
+                new_client, outdater_ipc_connection_destroy);
+
+        crm_debug("Client %s (%p) connected",
+			  new_client->id,
+			  new_client->source);
+
+        return TRUE;
+}
+
+static void
+outdater_client_destroy(gpointer user_data)
+{
+	crm_info("ipc server destroy");
+}
+
+int
+is_stable(ll_cluster_t *hb)
+{
+	const char *resources = hb->llc_ops->get_resources(hb);
+	if (!resources)
+		/* Heartbeat is not providing resource management */
+	        return -1;
+
+	if (!strcmp(resources, "transition"))
+		return 0;
+
+	return 1;
+}
+
+/* node_walk()
+ * get name of other node and set other_node string
+ */
+void
+node_walk(ll_cluster_t *hb)
+{
+	const char *node;
+
+	crm_debug("Starting node walk");
+	if (hb->llc_ops->init_nodewalk(hb) != HA_OK) {
+		crm_err("Cannot start node walk");
+		crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+		exit(9);
+	}
+	while((node = hb->llc_ops->nextnode(hb)) != NULL) {
+		crm_debug("Cluster node: %s: status: %s", node,
+				hb->llc_ops->node_status(hb, node));
+
+		/* Look for our partner */
+		if (!strcmp("normal", hb->llc_ops->node_type(hb, node))
+		    && strcmp(node, node_name)) {
+			strcpy(other_node, node);
+			crm_debug("[They are %s]", other_node);
+		}
+	}
+	if (hb->llc_ops->end_nodewalk(hb) != HA_OK) {
+		crm_err("Cannot end node walk");
+		crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+		exit(12);
+	}
+}
+
+/* set_callbacks()
+ * set callbacks for communication between two nodes
+ */
+void
+set_callbacks(ll_cluster_t *hb)
+{
+	/* Add each of the callbacks we use with the API */
+	if (hb->llc_ops->set_msg_callback(hb, "start_outdate",
+					  msg_start_outdate, hb) != HA_OK) {
+		crm_err("Cannot set msg_start_outdate callback");
+		crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+		exit(2);
+	}
+
+	if (hb->llc_ops->set_msg_callback(hb, "outdate_rc",
+					  msg_outdate_rc, hb) != HA_OK) {
+		crm_err("Cannot set msg_outdate_rc callback");
+		crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+		exit(2);
+	}
+}
+
+void
+set_signals(ll_cluster_t *hb)
+{
+	/* Setup the various signals */
+
+	CL_SIGINTERRUPT(SIGINT, 1);
+	CL_SIGNAL(SIGINT, gotsig);
+	CL_SIGINTERRUPT(SIGTERM, 1);
+	CL_SIGNAL(SIGTERM, gotsig);
+
+	crm_debug("Setting message signal");
+	if (hb->llc_ops->setmsgsignal(hb, 0) != HA_OK) {
+		crm_err("Cannot set message signal");
+		crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+		exit(13);
+	}
+}
+
+void
+gotsig(int nsig)
+{
+	(void)nsig;
+	quitnow = 1;
+}
+
+/* Used to handle the API in the gmainloop */
+gboolean
+dopd_dispatch(IPC_Channel* ipc, gpointer user_data)
+{
+	struct ha_msg *reply;
+	ll_cluster_t *hb = user_data;
+
+	reply = hb->llc_ops->readmsg(hb, 0);
+
+	if (reply != NULL) {
+		ha_msg_del(reply); reply=NULL;
+		return TRUE;
+	}
+	return TRUE;
+}
+
+void
+dopd_dispatch_destroy(gpointer user_data)
+{
+	return;
+}
+
+gboolean
+dopd_timeout_dispatch(gpointer user_data)
+{
+	ll_cluster_t *hb = user_data;
+
+	if (quitnow) {
+		g_main_quit(mainloop);
+		return FALSE;
+	}
+
+	if (hb->llc_ops->msgready(hb)) {
+		return dopd_dispatch(NULL, user_data);
+	}
+	return TRUE;
+}
+
+/* Sign in to the API */
+void
+open_api(ll_cluster_t *hb)
+{
+	crm_debug("Signing in with heartbeat");
+	if (hb->llc_ops->signon(hb, "dopd")!= HA_OK) {
+		crm_err("Cannot sign on with heartbeat");
+		crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+		exit(1);
+	}
+}
+
+/* Log off of the API and clean up */
+void
+close_api(ll_cluster_t *hb)
+{
+	if (hb->llc_ops->signoff(hb, FALSE) != HA_OK) {
+		crm_err("Cannot sign off from heartbeat.");
+		crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+		exit(14);
+	}
+	if (hb->llc_ops->delete(hb) != HA_OK) {
+		crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+		crm_err("Cannot delete API object.");
+		exit(15);
+	}
+}
+
+int
+main(int argc, char **argv)
+{
+	unsigned fmask;
+	ll_cluster_t *hb;
+	char pid[10];
+	char *bname, *parameter;
+	IPC_Channel *apiIPC;
+
+	/* Get the name of the binary for logging purposes */
+	bname = ha_strdup(argv[0]);
+	crm_log_init(bname);
+
+	hb = ll_cluster_new("heartbeat");
+	dopd_cluster_conn = hb;
+
+	memset(other_node, 0, sizeof(other_node));
+	need_standby = 0;
+
+	memset(pid, 0, sizeof(pid));
+	snprintf(pid, sizeof(pid), "%ld", (long)getpid());
+	crm_debug("PID=%s", pid);
+
+	open_api(hb);
+
+	node_stable = is_stable(hb);
+	if (node_stable == -1) {
+		crm_err("No managed resources");
+		exit(100);
+	}
+
+	/* Obtain our local node name */
+	node_name = hb->llc_ops->get_mynodeid(hb);
+	if (node_name == NULL) {
+		crm_err("Cannot get my nodeid");
+		crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+		exit(19);
+	}
+	crm_debug("[We are %s]", node_name);
+
+	/* See if we should drop cores somewhere odd... */
+	parameter = hb->llc_ops->get_parameter(hb, KEY_COREROOTDIR);
+	if (parameter) {
+		cl_set_corerootdir(parameter);
+		cl_cdtocoredir();
+	}
+	cl_cdtocoredir();
+
+
+	set_callbacks(hb);
+
+	fmask = LLC_FILTER_DEFAULT;
+
+	crm_debug("Setting message filter mode");
+	if (hb->llc_ops->setfmode(hb, fmask) != HA_OK) {
+		crm_err("Cannot set filter mode");
+		crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+		exit(8);
+	}
+
+	node_walk(hb);
+
+	set_signals(hb);
+
+	crm_debug("Waiting for messages...");
+	errno = 0;
+
+	mainloop = g_main_new(TRUE);
+
+        apiIPC = hb->llc_ops->ipcchan(hb);
+
+	/* Watch the API IPC for input */
+        G_main_add_IPC_Channel(G_PRIORITY_HIGH, apiIPC, FALSE,
+                               dopd_dispatch, (gpointer)hb,
+                               dopd_dispatch_destroy);
+
+	Gmain_timeout_add_full(G_PRIORITY_DEFAULT, 1000,
+	                        dopd_timeout_dispatch, (gpointer)hb,
+	                        dopd_dispatch_destroy);
+	int rc = init_server_ipc_comms(
+			ha_strdup(T_OUTDATER),
+			outdater_client_connect,
+			outdater_client_destroy);
+	if (rc != 0)
+		crm_err("Could not start IPC server");
+
+	g_main_run(mainloop);
+	g_main_destroy(mainloop);
+
+	if (!quitnow && errno != EAGAIN && errno != EINTR) {
+		crm_err("read_hb_msg returned NULL");
+		crm_err("REASON: %s", hb->llc_ops->errmsg(hb));
+	}
+
+	close_api(hb);
+
+	return 0;
+}

Added: trunk/tools/dopd.h
===================================================================
--- trunk/tools/dopd.h	2006-05-18 12:57:18 UTC (rev 2200)
+++ trunk/tools/dopd.h	2006-05-18 14:14:23 UTC (rev 2201)
@@ -0,0 +1,43 @@
+/* $Id$ */
+/* drbd outdate peer daemon
+ * Copyright (C) 2006 LINBIT <http://www.linbit.com/>
+ *
+ * Written by Rasto Levrinc <rasto@linbit.at>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This software 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.
+ * 
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#define T_OUTDATER		"outdater"
+#define F_OUTDATER_RES		"outdater_res"
+#define F_DOPD_VALUE            "dop_value"
+#define F_DOPD_RES              "dop_res"
+
+#define OUTDATE_COMMAND		"/sbin/drbdadm outdate"
+
+
+/* Prototypes */
+void node_walk(ll_cluster_t *);
+void set_signals(ll_cluster_t *);
+void gotsig(int);
+void set_callbacks(ll_cluster_t *);
+void open_api(ll_cluster_t *);
+void close_api(ll_cluster_t *);
+gboolean dopd_dispatch(IPC_Channel *, gpointer);
+void dopd_dispatch_destroy(gpointer);
+gboolean dopd_timeout_dispatch(gpointer);
+int is_stable(ll_cluster_t *);
+void msg_start_outdate(struct ha_msg *, void *);
+void msg_outdate_rc(struct ha_msg *, void *);

Added: trunk/tools/drbd-peer-outdater.c
===================================================================
--- trunk/tools/drbd-peer-outdater.c	2006-05-18 12:57:18 UTC (rev 2200)
+++ trunk/tools/drbd-peer-outdater.c	2006-05-18 14:14:23 UTC (rev 2201)
@@ -0,0 +1,230 @@
+/* $Id$ */
+/* drbd-peer-outdater
+ * Copyright (C) 2006 LINBIT <http://www.linbit.com/>
+ *
+ * Written by Rasto Levrinc <rasto@linbit.at>
+ *
+ * based on attrd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This software 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.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <portability.h>
+
+#include <sys/param.h>
+
+#include <crm/crm.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <stdlib.h>
+#include <crm/common/ipc.h>
+#include <clplumbing/lsb_exitcodes.h>
+#include <clplumbing/Gmain_timeout.h>
+#include <dopd.h>
+
+#define OPTARGS      "hVt:r:"
+
+typedef struct dop_client_s
+{
+	int timeout;
+	GMainLoop *mainloop;
+	int rc;
+} dop_client_t;
+
+const char *crm_system_name = "drbd-peer-outdater";
+
+static void usage(const char* cmd, int exit_status);
+
+static void
+dop_exit(dop_client_t *client)
+{
+	int rc;
+
+	if (client == NULL)
+		exit(5);
+	rc = client->rc;
+
+	crm_free(client);
+	exit(rc);
+}
+
+static gboolean
+outdate_callback(IPC_Channel * server, gpointer user_data)
+{
+	dop_client_t *client = (dop_client_t *)user_data;
+	HA_Message *msg = NULL;
+	const char *rc_string;
+	char *ep;
+	int rc;
+
+	msg = msgfromIPC_noauth(server);
+	if (!msg) {
+		fprintf(stderr, "no message from server or other "
+				"instance is running\n");
+		if (client->mainloop != NULL &&
+		    g_main_is_running(client->mainloop))
+			g_main_quit(client->mainloop);
+		return FALSE;
+	}
+	crm_debug_2("message: %s, %s\n",
+			ha_msg_value(msg, F_TYPE),
+			ha_msg_value(msg, F_ORIG)
+			);
+	rc_string = ha_msg_value(msg, F_DOPD_VALUE);
+
+	errno = 0;
+	rc = strtol(rc_string, &ep, 10);
+	if (errno != 0 || *ep != EOS) {
+		fprintf(stderr, "unknown message: %s from server", rc_string);
+		ha_msg_del(msg);
+		if (client->mainloop != NULL &&
+		    g_main_is_running(client->mainloop))
+			g_main_quit(client->mainloop);
+		return FALSE;
+	}
+
+	ha_msg_del(msg);
+
+	if (client->mainloop != NULL && g_main_is_running(client->mainloop)) {
+		client->rc = rc;
+		g_main_quit(client->mainloop);
+	} else
+		dop_exit(client);
+
+	return TRUE;
+}
+
+static void
+outdater_dispatch_destroy(gpointer user_data)
+{
+	return;
+}
+
+static gboolean
+outdater_timeout_dispatch(gpointer user_data)
+{
+	dop_client_t *client = (dop_client_t *)user_data;
+	fprintf(stderr, "error: could not connect to dopd after %i seconds"
+			": timeout reached\n", client->timeout);
+	if (client->mainloop != NULL && g_main_is_running(client->mainloop))
+		g_main_quit(client->mainloop);
+	return FALSE;
+}
+
+int
+main(int argc, char ** argv)
+{
+	HA_Message *update = NULL;
+	IPC_Channel *ipc_server = NULL;
+	int argerr = 0;
+	int flag;
+	char *drbd_resource = NULL;
+	char drbd_resource_default[] = "r0";
+	int timeout = 60; // timeout in seconds
+
+	dop_client_t *new_client = NULL;
+	GCHSource *src = NULL;
+
+	crm_log_init(crm_system_name);
+
+	crm_debug_3("Begining option processing");
+	while ((flag = getopt(argc, argv, OPTARGS)) != EOF) {
+		switch(flag) {
+			case 'V':
+				alter_debug(DEBUG_INC);
+				break;
+			case 'h':		/* Help message */
+				usage(crm_system_name, LSB_EXIT_OK);
+				break;
+			case 't':		/* Help message */
+				timeout = atoi(optarg);
+				break;
+			case 'r':		/* Help message */
+				drbd_resource = crm_strdup(optarg);
+				break;
+			default:
+				++argerr;
+				break;
+		}
+	}
+
+	crm_debug_3("Option processing complete");
+
+	/* the caller drbdadm sets DRBD_RESOURCE env variable, use it if
+	 * -r option was not specified, or use default value */
+	if ((drbd_resource == NULL) && !(drbd_resource = getenv("DRBD_RESOURCE"))) {
+		drbd_resource = drbd_resource_default;
+	}
+
+	if (optind > argc) {
+		++argerr;
+	}
+
+	if (argerr) {
+		usage(crm_system_name, LSB_EXIT_GENERIC);
+	}
+
+	crm_debug_2("drbd resource: %s\n", drbd_resource);
+
+	crm_malloc0(new_client, sizeof(dop_client_t));
+	new_client->timeout = timeout;
+	new_client->mainloop = g_main_new(FALSE);
+	new_client->rc = 5;
+
+	/* Connect to the IPC server */
+	src = init_client_ipc_comms(T_OUTDATER, outdate_callback,
+			      (gpointer)new_client, &ipc_server);
+
+	if (ipc_server == NULL) {
+		fprintf(stderr, "Could not connect to "T_OUTDATER" channel\n");
+		dop_exit(new_client); // unreachable
+	}
+
+	/* send message with drbd resource to dopd */
+	update = ha_msg_new(3);
+	ha_msg_add(update, F_TYPE, T_OUTDATER);
+	ha_msg_add(update, F_ORIG, crm_system_name);
+	ha_msg_add(update, F_OUTDATER_RES, drbd_resource);
+
+	if (send_ipc_message(ipc_server, update) == FALSE) {
+		fprintf(stderr, "Could not send message\n");
+		dop_exit(new_client);
+	}
+
+	Gmain_timeout_add_full(G_PRIORITY_DEFAULT, new_client->timeout * 1000,
+	                       outdater_timeout_dispatch, (gpointer)new_client,
+			       outdater_dispatch_destroy);
+
+	g_main_run(new_client->mainloop);
+	dop_exit(new_client);
+	return 5;
+}
+
+static void
+usage(const char* cmd, int exit_status)
+{
+	FILE* stream;
+
+	stream = exit_status ? stderr : stdout;
+	fprintf(stream, "usage: %s [-tr]\n", cmd);
+	fprintf(stream, "\t-t <int>\ttimeout in seconds\n");
+	fprintf(stream, "\t-r <string>\tdrbd resource, default is r0\n");
+	fflush(stream);
+
+	exit(exit_status);
+}
+

From drbd-cvs at lists.linbit.com  Thu May 18 17:07:05 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu May 18 17:07:07 2006
Subject: [DRBD-cvs] svn commit by phil - r2202 - trunk/user - Some stuff to
	make the drbd-peer-outdater work. 
Message-ID: <20060518150705.AB0E12F03D@mail.linbit.com>

Author: phil
Date: 2006-05-18 17:07:04 +0200 (Thu, 18 May 2006)
New Revision: 2202

Modified:
   trunk/user/Makefile
   trunk/user/drbdadm_usage_cnt.c
Log:
Some stuff to make the drbd-peer-outdater work.


Modified: trunk/user/Makefile
===================================================================
--- trunk/user/Makefile	2006-05-18 14:14:23 UTC (rev 2201)
+++ trunk/user/Makefile	2006-05-18 15:07:04 UTC (rev 2202)
@@ -57,9 +57,15 @@
 
 install:
 	install -d $(PREFIX)/sbin/
-	install -m 755 drbdsetup $(PREFIX)/sbin/
-	install -m 755 drbdmeta $(PREFIX)/sbin/
-	install -m 755 drbdadm $(PREFIX)/sbin/
+	if getent group haclient > /dev/null 2> /dev/null ; then	\
+		install -g haclient -m 4750 drbdsetup $(PREFIX)/sbin/ ;	\
+		install -g haclient -m 4750 drbdmeta $(PREFIX)/sbin/ ;	\
+		install -m 755 drbdadm $(PREFIX)/sbin/ ;		\
+	else								\
+		install -m 755 drbdsetup $(PREFIX)/sbin/ ;		\
+		install -m 755 drbdmeta $(PREFIX)/sbin/ ;		\
+		install -m 755 drbdadm $(PREFIX)/sbin/ ; 		\
+	fi
 
 uninstall:
 	rm -f $(PREFIX)/sbin/drbdsetup

Modified: trunk/user/drbdadm_usage_cnt.c
===================================================================
--- trunk/user/drbdadm_usage_cnt.c	2006-05-18 14:14:23 UTC (rev 2201)
+++ trunk/user/drbdadm_usage_cnt.c	2006-05-18 15:07:04 UTC (rev 2202)
@@ -314,6 +314,7 @@
 	char n_comment[ANSWER_SIZE*3];
 
 	if( type == UC_NO ) return;
+	if( getuid() != 0 ) return;
 
 	current = current_svn_revision();
 

From drbd-cvs at lists.linbit.com  Thu May 18 17:07:10 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu May 18 17:07:12 2006
Subject: [DRBD-cvs] svn commit by rasto - r2203 - in trunk: scripts tools -
	Documentation update 
Message-ID: <20060518150710.B3A4B2F03F@mail.linbit.com>

Author: rasto
Date: 2006-05-18 17:07:08 +0200 (Thu, 18 May 2006)
New Revision: 2203

Modified:
   trunk/scripts/drbd.conf
   trunk/tools/README
Log:
Documentation update


Modified: trunk/scripts/drbd.conf
===================================================================
--- trunk/scripts/drbd.conf	2006-05-18 15:07:04 UTC (rev 2202)
+++ trunk/scripts/drbd.conf	2006-05-18 15:07:08 UTC (rev 2203)
@@ -147,7 +147,11 @@
     # communication possibilities of our cluster manager.
     # The provided script uses ssh, and is for demonstration/development
     # purposis.
-    outdate-peer "/usr/lib/drbd/outdate-peer.sh on amd 192.168.22.11 192.168.23.11 on alf 192.168.22.12 192.168.23.12";
+    # outdate-peer "/usr/lib/drbd/outdate-peer.sh on amd 192.168.22.11 192.168.23.11 on alf 192.168.22.12 192.168.23.12";
+    #  
+    # Update: Now there is a solution that relies on heartbeat's 
+    # communication layers. You should really use this.
+    outdate-peer "/usr/sbin/drbd-peer-outdater";   
   }
 
   startup {

Modified: trunk/tools/README
===================================================================
--- trunk/tools/README	2006-05-18 15:07:04 UTC (rev 2202)
+++ trunk/tools/README	2006-05-18 15:07:08 UTC (rev 2203)
@@ -10,6 +10,10 @@
 chmod o-x drbdmeta
 chmod u+s drbdmeta
 
+chown .haclient drbdsetup
+chmod o-x drbdsetup
+chmod u+s drbdsetup
+
 3) Configure Heartbeat to run the DRBD outdate peer daemon
 
 Add these lines to /etc/ha.d/ha.cf

From drbd-cvs at lists.linbit.com  Mon May 22 13:27:58 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May 22 13:27:59 2006
Subject: [DRBD-cvs] svn commit by phil - r2204 - trunk/user - Christopher
	Boumenot's patch that removes some calls to
Message-ID: <20060522112758.571BD2F026@mail.linbit.com>

Author: phil
Date: 2006-05-22 13:27:56 +0200 (Mon, 22 May 2006)
New Revision: 2204

Modified:
   trunk/user/drbdadm.h
   trunk/user/drbdadm_main.c
Log:
Christopher Boumenot's patch that removes some calls to external
programs to verify user supplied IP addresses.


Modified: trunk/user/drbdadm.h
===================================================================
--- trunk/user/drbdadm.h	2006-05-18 15:07:08 UTC (rev 2203)
+++ trunk/user/drbdadm.h	2006-05-22 11:27:56 UTC (rev 2204)
@@ -4,6 +4,8 @@
 #include <linux/drbd_config.h>
 #include <sys/utsname.h>
 #include <sys/types.h>
+#include <net/if.h>
+#include <stdint.h>
 
 #define E_syntax	  2
 #define E_usage		  3
@@ -48,6 +50,19 @@
   enum usage_count_type usage_count;
 };
 
+#define IFI_HADDR 8
+#define IFI_ALIAS 1
+
+struct ifi_info {
+  char ifi_name[IFNAMSIZ];      /* interface name, nul terminated */
+  uint8_t ifi_haddr[IFI_HADDR]; /* hardware address */
+  uint16_t ifi_hlen;            /* bytes in hardware address, 0, 6, 8 */
+  short ifi_flags;              /* IFF_xxx constants from <net/if.h> */
+  short ifi_myflags;            /* our own IFI_xxx flags */
+  struct sockaddr *ifi_addr;    /* primary address */
+  struct ifi_info *ifi_next;    /* next ifi_info structure */
+};
+
 struct d_host_info
 {
   char* name;

Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c	2006-05-18 15:07:08 UTC (rev 2203)
+++ trunk/user/drbdadm_main.c	2006-05-22 11:27:56 UTC (rev 2204)
@@ -37,6 +37,10 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
@@ -103,6 +107,8 @@
 static int adm_generic_b(struct d_resource* ,const char* );
 static int hidden_cmds(struct d_resource* ,const char* );
 
+static struct ifi_info* get_ifi_info(int family);
+
 char ss_buffer[255];
 struct utsname nodeinfo;
 int line=1;
@@ -1153,87 +1159,162 @@
   exit(E_usage);
 }
 
-/* if not verifyable, prints a message to stderr,
- * and sets config_valid = 0 if INVALID_IP_IS_INVALID_CONF is defined */
-#define INVALID_IP_IS_INVALID_CONF 0
-void verify_ips(struct d_resource* res)
+static void free_ifi_info(struct ifi_info *ifihead)
 {
-  char *my_ip = NULL;
-  char *his_ip = NULL;
-  char *argv[] = { "/bin/bash", "-c", NULL, "drbdadm:verify_ips", NULL };
-  int ex;
+  struct ifi_info *ifi, *ifinext;
+  for (ifi = ifihead; ifi != NULL; ifi = ifinext) {
+    if (ifi->ifi_addr != NULL)
+      free(ifi->ifi_addr);
+    ifinext = ifi->ifi_next;
+    free(ifi);
+  }
+}
 
-  if (global_options.disable_ip_verification) return;
-  if (dry_run == 1 || do_verify_ips == 0) return;
+static struct ifi_info* get_ifi_info(int family)
+{
+  struct ifi_info *ifi, *ifihead, **ifipnext;
+  int sockfd, len, lastlen, flags, myflags;
+  char *ptr, *buf, lastname[IFNAMSIZ], *cptr;
+  struct ifconf ifc;
+  struct ifreq *ifr, ifrcopy;
+  struct sockaddr_in *sinptr;
+    
+  sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+  if (sockfd < 0) {
+    fprintf(stderr, "sockfd < 0\n");
+    return NULL;
+  }
 
-  if (!(res && res->me   && res->me->address
-	    && res->peer && res->peer->address)) {
-    fprintf(stderr, "OOPS, no resource info in verify_ips!\n");
-    exit(E_config_invalid);
+  lastlen = 0;
+  len = 100 * sizeof(struct ifreq); /* initial guess */
+    
+  for (;;) {
+    buf = malloc(len);
+    if (!buf)
+      return NULL;
+    ifc.ifc_len = len;
+    ifc.ifc_buf = buf;
+        
+    if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
+      if (errno != EINVAL || lastlen != 0)
+	return NULL;
+    } else {
+      if (ifc.ifc_len == lastlen)
+	break; /* success, len has not changed */
+      lastlen = ifc.ifc_len;
+    }
+    len += 10 * sizeof(struct ifreq); /* increment */
+    free(buf);
   }
-  my_ip  = res->me->address;
-  his_ip = res->peer->address;
 
-  ex = asprintf(&argv[2],
-	"IP=%s; IP=${IP//./\\\\.};"
-	"LANG=; PATH=/sbin/:$PATH;"
-	"if   type -p ip       ; then"
-	"  ip addr show | grep -qE 'inet '$IP'[ /]';"
-	"elif type -p ifconfig ; then"
-	"  ifconfig | grep -qE ' inet addr:'$IP' ';"
-	"else"
-	"  echo >&2 $0: 'neither ip nor ifconfig found!';"
-	"fi >/dev/null",
-	my_ip);
-  if (ex < 0) { perror("asprintf"); exit(E_thinko); }
-  ex = m_system(argv,SLEEPS_SHORT|DONT_REPORT_FAILED);
-  free(argv[2]); argv[2] = NULL;
+  ifihead = NULL;
+  ifipnext = &ifihead;
+  lastname[0] = 0;
 
-  if (ex != 0) {
-    ENTRY e, *ep;
-    e.key = e.data = ep = NULL;
-    asprintf(&e.key,"%s:%s",my_ip,res->me->port);
-    ep = hsearch(e, FIND);
-    fprintf(stderr, "%s:%d: in resource %s, on %s:\n\t"
-		    "IP %s not found on this host.\n",
-	    config_file,(int)(long)ep->data,res->name, res->me->name,my_ip);
-    if (INVALID_IP_IS_INVALID_CONF)
-	    config_valid = 0;
-    free(e.key);
-    return;
+  for (ptr = buf; ptr < buf + ifc.ifc_len; ) {
+    ifr = (struct ifreq*) ptr;
+
+    switch (ifr->ifr_addr.sa_family) {
+      /*         case AF_INET6: len = sizeof(struct sockaddr_in6); break; */
+    case AF_INET:
+    default:
+      len = sizeof(struct sockaddr);
+      break;
+    }
+        
+    ptr += sizeof(ifr->ifr_name) + len; /* for next one in buffer */
+        
+    if (ifr->ifr_addr.sa_family != family)
+      continue; /* ignore if not desired address family */
+        
+    myflags = 0;
+    if ((cptr = strchr(ifr->ifr_name, ':')) != NULL)
+      *cptr = 0; /* replace colon with null */
+
+    if (strncmp(lastname, ifr->ifr_name, IFNAMSIZ) == 0)
+      myflags = IFI_ALIAS;
+
+    memcpy(lastname, ifr->ifr_name, IFNAMSIZ);
+
+    ifrcopy = *ifr;
+    if (ioctl(sockfd, SIOCGIFFLAGS, &ifrcopy) < 0)
+      return NULL;
+
+    flags = ifrcopy.ifr_flags;
+    if ((flags & IFF_UP) == 0)
+      continue; /* ignore if the interface is not up */
+
+    ifi = calloc(1, sizeof(struct ifi_info));
+    if (!ifi)
+      return NULL;
+        
+    *ifipnext = ifi; /* prev points to this new one */
+    ifipnext = &ifi->ifi_next; /* pointer to next one goes here */
+
+    ifi->ifi_flags = flags; /* IFI_xxx values */
+    ifi->ifi_myflags = myflags; /* IFI_xxx values */
+    memcpy(ifi->ifi_name, ifr->ifr_name, IFNAMSIZ);
+    ifi->ifi_name[IFNAMSIZ - 1] = '\0';
+
+    switch(ifr->ifr_addr.sa_family) {
+      /*         case AF_INET6: return NULL; */
+    case AF_INET:
+      sinptr = (struct sockaddr_in *)&ifr->ifr_addr;
+      if (ifi->ifi_addr == NULL) {
+	ifi->ifi_addr = calloc(1, sizeof(struct sockaddr));
+	if (!ifi->ifi_addr)
+	  return NULL;
+
+	memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr));
+      }
+      /* IFF_BROADCAST and IFF_POINTTOPOINT are ignored */
+    default:
+      break;
+    }
   }
 
-#if 1
-/* seems to not work as expected with aliases.
- * maybe drop it completely and trust the admin.
- */
-  ex = asprintf(&argv[2],
-	"IP=%s; IPQ=${IP//./\\\\.};"
-	"peerIP=%s; peerIPQ=${peerIP//./\\\\.};"
-	"LANG=; PATH=/sbin/:$PATH;"
-	"if type -p ip ; then "
-	"  ip -o route get to $peerIP from $IP 2>/dev/null |"
-	"    grep -qE ^$peerIPQ' from '$IPQ' ';"
-	/* "else"
-	 * "  echo >&2 $0: 'cannot check route to peer';" */
-	"fi >/dev/null",
-	my_ip,his_ip);
-  if (ex < 0) { perror("asprintf"); exit(E_thinko); }
-  ex = m_system(argv,SLEEPS_SHORT);
-  free(argv[2]); argv[2] = NULL;
-  if (ex != 0) {
-    ENTRY e, *ep;
-    e.key = e.data = ep = NULL;
-    asprintf(&e.key,"%s:%s",his_ip,res->peer->port);
-    ep = hsearch(e, FIND);
-    fprintf(stderr, "%s:%d: in resource %s:\n\tNo route from me (%s) to peer (%s).\n",
-	    config_file,(int)(long)ep->data,res->name, my_ip, his_ip);
-    if (INVALID_IP_IS_INVALID_CONF)
-	    config_valid = 0;
-    return;
+  free(buf);
+  close(sockfd);
+
+  return ifihead;
+}
+
+void verify_ips(struct d_resource* res)
+{
+  struct ifi_info *ifi, *ifihead;
+  int family, valid = 0;
+  uint32_t addr = 0;
+  struct in_addr sin_addr;
+  const char *my_ip;
+
+  my_ip = res->me->address;
+
+  /* does DRBD support inet6? */
+  family = AF_INET;
+    
+  for (ifihead = ifi = get_ifi_info(family); ifi != NULL; ifi = ifi->ifi_next) {        
+    switch (family) {
+    case AF_INET: {
+      struct sockaddr_in * sin = (struct sockaddr_in *)ifi->ifi_addr;
+      addr = sin->sin_addr.s_addr;
+
+      if (addr == sin_addr.s_addr) /* loop a few times needlessly */
+	valid = 1;
+      break;
+    }
+    default:
+      break;
+    }
   }
+
+  free_ifi_info(ifihead);
+
+  if (valid == 0) {
+    fprintf(stderr, "OOPS, the IP address %s isn't configure/up on your system!\n", my_ip);
+#ifdef INVALID_IP_IS_INVALID_CONF
+    config_valid = 0;
 #endif
-
+  }
   return;
 }
 

From drbd-cvs at lists.linbit.com  Mon May 22 17:10:55 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May 22 17:11:02 2006
Subject: [DRBD-cvs] svn commit by phil - r2205 - in trunk: . drbd drbd/linux
	- Implemented "cluster wide state changes". For now that 
Message-ID: <20060522151055.B03422E411@mail.linbit.com>

Author: phil
Date: 2006-05-22 17:10:53 +0200 (Mon, 22 May 2006)
New Revision: 2205

Modified:
   trunk/ROADMAP
   trunk/drbd/drbd_fs.c
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/drbd_strings.c
   trunk/drbd/linux/drbd.h
Log:
Implemented "cluster wide state changes". For now that method
is only used for becoming primary. (Should also be used for
the "invalidate" command).
Seems to work so far.


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-05-22 11:27:56 UTC (rev 2204)
+++ trunk/ROADMAP	2006-05-22 15:10:53 UTC (rev 2205)
@@ -775,11 +775,11 @@
 	* A wait queue.
 
    TODOS: 
-    Make sure it is used for getting PRIMARY.
     Evaluate if it is possible to use it for starting resync. (invalidate)
     Evaluate it for the other cases...
 
-  50 % Is implemented, needs testing etc...
+  60 % Is implemented. Changing the role to primary already uses this 
+       mechanism. Seems to work.
 
 34 Improve the initial hand-shake, to identify the sockets (and TCP-
    links) by an initial message, and not only by the connection timming.

Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c	2006-05-22 11:27:56 UTC (rev 2204)
+++ trunk/drbd/drbd_fs.c	2006-05-22 15:10:53 UTC (rev 2205)
@@ -851,8 +851,8 @@
 int drbd_set_role(drbd_dev *mdev, int* arg)
 {
 	drbd_role_t newstate = *arg;
-	int rv,r,forced = 0;
-	drbd_state_t os,ns,rs;
+	int rv,r,forced = 0, try=0;
+	drbd_state_t mask, val;
 	drbd_disks_t nps;
 
 	D_ASSERT(semaphore_is_locked(&mdev->device_mutex));
@@ -875,42 +875,42 @@
 			bd_release(mdev->this_bdev);
 	}
 
-	nps = disk_mask;
- retry:
-	spin_lock_irq(&mdev->req_lock);
-	os = mdev->state;
-	rs.i = os.i;
-	rs.role = newstate & role_mask;
-	if(nps != disk_mask) rs.pdsk = nps;
-	r = _drbd_set_state(mdev, rs, 0);
+	mask.i = 0; mask.role = role_mask;
+	val.i  = 0; val.role  = newstate & role_mask;
 
-	if ( r == SS_NoConsistnetDisk ) {
-		if ( newstate & DontBlameDrbd && mdev->state.disk<UpToDate) {
-			rs.disk = UpToDate;
+	while (try++ < 3) {
+		r = _drbd_request_state(mdev,mask,val,0);
+		if( r == SS_NoConsistnetDisk && (newstate & DontBlameDrbd) && 
+		    mdev->state.disk < UpToDate) {
+			mask.disk = disk_mask;
+			val.disk  = UpToDate;
 			forced = 1;
-			r = _drbd_set_state(mdev, rs, 0);
+			continue;
 		}
-	}
+		if ( r == SS_NothingToDo ) { rv = 0; goto fail; }
+		if ( r == SS_PrimaryNOP ) {
+			nps = drbd_try_outdate_peer(mdev);
 
-	ns = mdev->state;
-	spin_unlock_irq(&mdev->req_lock);
+			if ( newstate & DontBlameDrbd && nps > Outdated ) {
+				WARN("Forced into split brain situation!\n");
+				nps = Outdated;
+			}
 
-	if ( r == SS_NothingToDo ) { rv = 0; goto fail; }
-	if ( r == SS_PrimaryNOP && nps == disk_mask ) {
-		nps = drbd_try_outdate_peer(mdev);
-		if ( newstate & DontBlameDrbd && nps > Outdated ) {
-			WARN("Forced into split brain situation!\n");
-			nps = Outdated;
+			mask.pdsk = disk_mask;
+			val.pdsk  = nps;
+
+			continue;
 		}
-		goto retry;
+
+		if ( r < SS_Success ) {
+			r = drbd_request_state(mdev,mask,val); // Be verbose.
+			if( r < SS_Success ) {
+				rv = -EIO;
+				goto fail;
+			}
+		}
+		break;
 	}
-	if ( r < SS_Success ) {
-		print_st_err(mdev,os,rs,r);
-		*arg = r;
-		rv = -EIO;
-		goto fail;
-	}
-	after_state_ch(mdev,os,ns);
 
 	if(forced) WARN("Forced to conisder local data as UpToDate!\n");
 

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2006-05-22 11:27:56 UTC (rev 2204)
+++ trunk/drbd/drbd_int.h	2006-05-22 15:10:53 UTC (rev 2205)
@@ -315,6 +315,7 @@
 	AuthResponse,
 	OutdateRequest,
 	OutdatedReply,
+	StateChgRequest,
 
 	Ping,         // These are sent on the meta socket...
 	PingAck,
@@ -325,6 +326,7 @@
 	NegRSDReply,  // Local disk is broken...
 	BarrierAck,
 	DiscardNote,
+	StateChgReply,
 
 	MAX_CMD,
 	MayIgnore = 0x100, // Flag only to test if (cmd > MayIgnore) ...
@@ -370,6 +372,8 @@
 		[NegRSDReply]      = "NegRSDReply",
 		[BarrierAck]       = "BarrierAck",
 		[DiscardNote]      = "DiscardNote",
+		[StateChgRequest]  = "StateChgRequest",
+		[StateChgReply]    = "StateChgReply"
 	};
 
 	if (cmd == HandShake) return "HandShake";
@@ -515,6 +519,17 @@
 } __attribute((packed)) Drbd_State_Packet;
 
 typedef struct {
+	Drbd_Header head;
+	u32         mask;
+	u32         val;
+} __attribute((packed)) Drbd_Req_State_Packet;
+
+typedef struct {
+	Drbd_Header head;
+	u32         retcode;
+} __attribute((packed)) Drbd_RqS_Reply_Packet;
+
+typedef struct {
 	u64       size;
 	u32       state;
 	u32       blksize;
@@ -649,7 +664,10 @@
 	MD_DIRTY,		// current gen counts and flags not yet on disk
 	SYNC_STARTED,		// Needed to agree on the exact point in time..
 	UNIQUE,                 // Set on one node, cleared on the peer!
-	USE_DEGR_WFC_T		// Use degr-wfc-timeout instead of wfc-timeout.
+	USE_DEGR_WFC_T,		// Use degr-wfc-timeout instead of wfc-timeout.
+	CLUSTER_ST_CHANGE,      // Cluster wide state change going on...
+	CL_ST_CHG_SUCCESS,
+	CL_ST_CHG_FAIL
 };
 
 struct drbd_bitmap; // opaque for Drbd_Conf
@@ -831,6 +849,11 @@
 	ScheduleAfter   = 4,
 };
 
+extern int drbd_change_state(drbd_dev* mdev, enum chg_state_flags f,
+			     drbd_state_t mask, drbd_state_t val);
+extern void drbd_force_state(drbd_dev*, drbd_state_t, drbd_state_t);
+extern int _drbd_request_state(drbd_dev*, drbd_state_t, drbd_state_t, 
+			       enum chg_state_flags);
 extern int _drbd_set_state(drbd_dev*, drbd_state_t, enum chg_state_flags );
 extern void print_st_err(drbd_dev*, drbd_state_t, drbd_state_t, int );
 extern void after_state_ch(drbd_dev* mdev, drbd_state_t os, drbd_state_t ns);
@@ -874,6 +897,7 @@
 extern int drbd_send_bitmap(drbd_dev *mdev);
 extern int _drbd_send_bitmap(drbd_dev *mdev);
 extern int drbd_send_discard(drbd_dev *mdev, drbd_request_t *req);
+extern int drbd_send_sr_reply(drbd_dev *mdev, int retcode);
 extern void drbd_free_bc(struct drbd_backing_dev* bc);
 extern int drbd_io_error(drbd_dev* mdev);
 extern void drbd_mdev_cleanup(drbd_dev *mdev);
@@ -1187,34 +1211,22 @@
                 ({drbd_state_t ns; ns.i = mdev->state.i; ns.T1 = (S1); \
                 ns.T2 = (S2); ns.T3 = (S3); ns;})
 
-static inline int drbd_change_state(drbd_dev* mdev, enum chg_state_flags f,
-				    drbd_state_t mask, drbd_state_t val)
+static inline void drbd_state_lock(drbd_dev *mdev)
 {
-	unsigned long flags;
-	drbd_state_t os,ns;
-	int rv;
-
-	spin_lock_irqsave(&mdev->req_lock,flags);
-	os = mdev->state;
-	ns.i = (os.i & ~mask.i) | val.i;
-	rv = _drbd_set_state(mdev, ns, f);
-	ns = mdev->state;
-	spin_unlock_irqrestore(&mdev->req_lock,flags);
-	after_state_ch(mdev,os,ns);
-
-	return rv;
+	wait_event(mdev->cstate_wait,
+		   !test_and_set_bit(CLUSTER_ST_CHANGE,&mdev->flags));
 }
 
-static inline void drbd_force_state(drbd_dev* mdev,
-				    drbd_state_t mask, drbd_state_t val)
+static inline void drbd_state_unlock(drbd_dev *mdev)
 {
-	drbd_change_state(mdev,ChgStateHard,mask,val);
+	clear_bit(CLUSTER_ST_CHANGE,&mdev->flags);
+	wake_up(&mdev->cstate_wait);
 }
 
-static inline int drbd_request_state(drbd_dev* mdev,
-				    drbd_state_t mask, drbd_state_t val)
+static inline int drbd_request_state(drbd_dev* mdev, drbd_state_t mask,
+				     drbd_state_t val)
 {
-	return drbd_change_state(mdev,ChgStateVerbose,mask,val);
+	return _drbd_request_state(mdev, mask, val, ChgStateVerbose);
 }
 
 static inline void drbd_req_free(drbd_request_t *req)

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-05-22 11:27:56 UTC (rev 2204)
+++ trunk/drbd/drbd_main.c	2006-05-22 15:10:53 UTC (rev 2205)
@@ -527,6 +527,104 @@
 	return ok;
 }
 
+/** 
+ * cl_wide_st_chg:
+ * Returns TRUE if this state change should be preformed as a cluster wide
+ * transaction. 
+ */ 
+STATIC int cl_wide_st_chg(drbd_dev* mdev, drbd_state_t os, drbd_state_t ns)
+{
+	return ( ns.conn >= Connected &&
+		 ( ( os.role != Primary && ns.role == Primary ) ||
+		   // ( os.conn != SyncSource && ns.role == SyncSource ) ||
+		   // ( os.conn != SyncTarget && ns.role == SyncTarget ) ||
+		   // ( os.disk != Diskless && ns.role == Diskless ) ||
+		   // ( os.conn != TearDown && ns.conn == TearDown ) ||
+		   0
+		   ) );
+}
+
+int drbd_change_state(drbd_dev* mdev, enum chg_state_flags f,
+		      drbd_state_t mask, drbd_state_t val)
+{
+	unsigned long flags;
+	drbd_state_t os,ns;
+	int rv;
+
+	spin_lock_irqsave(&mdev->req_lock,flags);
+	os = mdev->state;
+	ns.i = (os.i & ~mask.i) | val.i;
+	rv = _drbd_set_state(mdev, ns, f);
+	ns = mdev->state;
+	spin_unlock_irqrestore(&mdev->req_lock,flags);
+	after_state_ch(mdev,os,ns);
+
+	return rv;
+}
+
+void drbd_force_state(drbd_dev* mdev, drbd_state_t mask, drbd_state_t val)
+{
+	drbd_change_state(mdev,ChgStateHard,mask,val);
+}
+
+static inline enum { REQS_SUCCESS=1, REQS_FAIL=2, REQS_NO_NEED=3 } 
+_req_st_cond(drbd_dev* mdev,drbd_state_t mask, drbd_state_t val)
+{
+	drbd_state_t os,ns;
+
+	if(test_and_clear_bit(CL_ST_CHG_SUCCESS,&mdev->flags)) return REQS_SUCCESS;
+	if(test_and_clear_bit(CL_ST_CHG_FAIL,&mdev->flags)) return REQS_FAIL;
+
+	os = mdev->state;
+	ns.i = (os.i & ~mask.i) | val.i;
+
+	if(!cl_wide_st_chg(mdev,os,ns)) return REQS_NO_NEED;
+
+	return 0;
+}
+
+STATIC int drbd_send_state_req(drbd_dev *, drbd_state_t, drbd_state_t);
+
+int _drbd_request_state(drbd_dev* mdev, drbd_state_t mask, drbd_state_t val,
+		       enum chg_state_flags f)
+{
+	unsigned long flags;
+	drbd_state_t os,ns;
+	int rv;
+
+	spin_lock_irqsave(&mdev->req_lock,flags);
+	os = mdev->state;
+	ns.i = (os.i & ~mask.i) | val.i;
+
+	if(cl_wide_st_chg(mdev,os,ns)) {
+		// TODO do the pre checks here as well ;
+		spin_unlock_irqrestore(&mdev->req_lock,flags);
+
+		drbd_state_lock(mdev);
+		drbd_send_state_req(mdev,mask,val);
+
+		wait_event(mdev->cstate_wait,(rv=_req_st_cond(mdev,mask,val)));
+
+		if(rv == REQS_FAIL) {
+			drbd_state_unlock(mdev);
+			return SS_FailedByPeer; // Nearly dead code ;)
+		}
+		spin_lock_irqsave(&mdev->req_lock,flags);
+		os = mdev->state;
+		ns.i = (os.i & ~mask.i) | val.i;
+		drbd_state_unlock(mdev);
+	}
+
+	rv = _drbd_set_state(mdev, ns, f);
+	ns = mdev->state;
+	spin_unlock_irqrestore(&mdev->req_lock,flags);
+
+	if (rv == SS_Success) after_state_ch(mdev,os,ns);
+
+	return rv;
+}
+
+
 static void print_st(drbd_dev* mdev, char *name, drbd_state_t ns)
 {
 	ERR(" %s = { cs:%s st:%s/%s ds:%s/%s %c%c%c%c }\n",
@@ -615,7 +713,6 @@
 	return rv;
 }
 
-
 int _drbd_set_state(drbd_dev* mdev, drbd_state_t ns,enum chg_state_flags flags)
 {
 	drbd_state_t os;
@@ -1225,6 +1322,28 @@
 			     (Drbd_Header*)&p,sizeof(p));
 }
 
+STATIC int drbd_send_state_req(drbd_dev *mdev, drbd_state_t mask, drbd_state_t val)
+{
+	Drbd_Req_State_Packet p;
+
+	p.mask    = cpu_to_be32(mask.i);
+	p.val     = cpu_to_be32(val.i);
+
+	return drbd_send_cmd(mdev,mdev->data.socket,StateChgRequest,
+			     (Drbd_Header*)&p,sizeof(p));
+}
+
+int drbd_send_sr_reply(drbd_dev *mdev, int retcode)
+{
+	Drbd_RqS_Reply_Packet p;
+
+	p.retcode    = cpu_to_be32(retcode);
+
+	return drbd_send_cmd(mdev,mdev->meta.socket,StateChgReply,
+			     (Drbd_Header*)&p,sizeof(p));
+}
+
+
 /* See the comment at receive_bitmap() */
 int _drbd_send_bitmap(drbd_dev *mdev)
 {

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-05-22 11:27:56 UTC (rev 2204)
+++ trunk/drbd/drbd_receiver.c	2006-05-22 15:10:53 UTC (rev 2205)
@@ -1831,8 +1831,9 @@
 /* warn if the arguments differ by more than 12.5% */
 static void warn_if_differ_considerably(drbd_dev *mdev, const char *s, sector_t a, sector_t b)
 {
+	sector_t d;
 	if (a == 0 || b == 0) return;
-	sector_t d = (a > b) ? (a - b) : (b - a);
+	d = (a > b) ? (a - b) : (b - a);
 	if ( d > (a>>3) || d > (b>>3)) {
 		WARN("Considerable difference in %s: %llu vs. %llu\n", s,
 		     (unsigned long long)a, (unsigned long long)b);
@@ -1961,7 +1962,67 @@
 	return TRUE;
 }
 
+/** 
+ * convert_state:
+ * Switches the view of the state.
+ */ 
+STATIC drbd_state_t convert_state(drbd_state_t ps)
+{
+	drbd_state_t ms;
 
+	static drbd_conns_t c_tab[] = {
+		[Connected] = Connected,
+		[SkippedSyncS] = SkippedSyncT,
+		[SkippedSyncT] = SkippedSyncS,
+		[WFBitMapS] = WFBitMapT,
+		[WFBitMapT] = WFBitMapS,
+		[WFSyncUUID] = SyncSource,
+		[SyncSource] = SyncTarget,
+		[SyncTarget] = WFSyncUUID,
+		[PausedSyncS] = PausedSyncT,
+		[PausedSyncT] = PausedSyncS,
+		[conn_mask]   = conn_mask,
+	};
+
+	ms.i = ps.i;
+
+	ms.conn = c_tab[ps.conn];
+	ms.peer = ps.role;
+	ms.role = ps.peer;
+	ms.pdsk = ps.disk;
+	ms.disk = ps.pdsk;
+	ms.peer_isp = ( ps.aftr_isp | ps.user_isp );
+
+	return ms;
+}
+
+STATIC int receive_req_state(drbd_dev *mdev, Drbd_Header *h)
+{
+	Drbd_Req_State_Packet *p = (Drbd_Req_State_Packet*)h;
+	drbd_state_t mask,val;
+	int rv;
+
+	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
+	if (drbd_recv(mdev, h->payload, h->length) != h->length)
+		return FALSE;
+
+	mask.i = be32_to_cpu(p->mask);
+	val.i = be32_to_cpu(p->val);
+
+	if (test_bit(UNIQUE,&mdev->flags)) drbd_state_lock(mdev);
+
+	mask = convert_state(mask);
+	val = convert_state(val);
+
+	rv = drbd_change_state(mdev,ChgStateVerbose,mask,val);
+
+	if (test_bit(UNIQUE,&mdev->flags)) drbd_state_unlock(mdev);
+
+	drbd_send_sr_reply(mdev,rv);
+
+	return TRUE;
+}
+
 STATIC int receive_state(drbd_dev *mdev, Drbd_Header *h)
 {
 	Drbd_State_Packet *p = (Drbd_State_Packet*)h;
@@ -2269,6 +2330,7 @@
 	[ReportUUIDs]      = receive_uuids,
 	[ReportSizes]      = receive_sizes,
 	[ReportState]      = receive_state,
+	[StateChgRequest]  = receive_req_state,
 	[ReportSyncUUID]   = receive_sync_uuid,
 	[PauseResync]      = receive_pause_resync,
 	[ResumeResync]     = receive_resume_resync,
@@ -2751,6 +2813,24 @@
 
 /* ********* acknowledge sender ******** */
 
+STATIC int got_RqSReply(drbd_dev *mdev, Drbd_Header* h)
+{
+	Drbd_RqS_Reply_Packet *p = (Drbd_RqS_Reply_Packet*)h;
+
+	int retcode = be32_to_cpu(p->retcode);
+
+	if(retcode >= SS_Success) {
+		set_bit(CL_ST_CHG_SUCCESS,&mdev->flags);
+	} else {
+		set_bit(CL_ST_CHG_FAIL,&mdev->flags);
+		ERR("Requested state change failed by peer: %s\n",
+		    set_st_err_name(retcode));
+	}
+	wake_up(&mdev->cstate_wait);
+
+	return TRUE;
+}
+
 STATIC int got_Ping(drbd_dev *mdev, Drbd_Header* h)
 {
 	return drbd_send_ping_ack(mdev);
@@ -2940,6 +3020,7 @@
 		[NegRSDReply]={sizeof(Drbd_BlockAck_Packet),  got_NegRSDReply},
 		[BarrierAck]={ sizeof(Drbd_BarrierAck_Packet),got_BarrierAck },
 		[DiscardNote]={sizeof(Drbd_Discard_Packet),   got_Discard },
+		[StateChgReply]={sizeof(Drbd_RqS_Reply_Packet),got_RqSReply },
 	};
 
 	sprintf(current->comm, "drbd%d_asender", (int)(mdev-drbd_conf));

Modified: trunk/drbd/drbd_strings.c
===================================================================
--- trunk/drbd/drbd_strings.c	2006-05-22 11:27:56 UTC (rev 2204)
+++ trunk/drbd/drbd_strings.c	2006-05-22 15:10:53 UTC (rev 2205)
@@ -68,6 +68,7 @@
 	[-SS_SyncingDiskless] = "Refusing to be syncing and diskless",
 	[-SS_ConnectedOutdates] = "Refusing to be Outdated while Connected",
 	[-SS_PrimaryNOP] = "Refusing to be Primary while peer is not outdated",
+	[-SS_FailedByPeer] = "State changed was refused by peer node"
 };
 
 const char* conns_to_name(drbd_conns_t s) {

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2006-05-22 11:27:56 UTC (rev 2204)
+++ trunk/drbd/linux/drbd.h	2006-05-22 15:10:53 UTC (rev 2205)
@@ -217,7 +217,7 @@
 	NetworkFailure,
 	WFConnection,
 	WFReportParams, // we have a socket
-	TearDown, 
+	TearDown,
 	Connected,      // we have introduced each other
 	SkippedSyncS,   // we should have synced, but user said no
 	SkippedSyncT,
@@ -268,7 +268,8 @@
 	SS_BothInconsistent=-4,
 	SS_SyncingDiskless=-5,
 	SS_ConnectedOutdates=-6,
-	SS_PrimaryNOP=-7
+	SS_PrimaryNOP=-7,
+	SS_FailedByPeer=-8
 } set_st_err_t;
 
 /* from drbd_strings.c */

From drbd-cvs at lists.linbit.com  Mon May 22 20:58:47 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May 22 20:58:48 2006
Subject: [DRBD-cvs] svn commit by phil - r2206 - in trunk/drbd: . linux -
	Improved a few details: *) Made sure a state request fa
Message-ID: <20060522185847.4B7372E411@mail.linbit.com>

Author: phil
Date: 2006-05-22 20:58:45 +0200 (Mon, 22 May 2006)
New Revision: 2206

Modified:
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_strings.c
   trunk/drbd/linux/drbd.h
Log:
Improved a few details:
 *) Made sure a state request fails if it is even local not desirable.
 *) Made sure it failes if it becomes impossible during waiting for
    the peers answer.


Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-05-22 15:10:53 UTC (rev 2205)
+++ trunk/drbd/drbd_main.c	2006-05-22 18:58:45 UTC (rev 2206)
@@ -530,7 +530,7 @@
 /** 
  * cl_wide_st_chg:
  * Returns TRUE if this state change should be preformed as a cluster wide
- * transaction. 
+ * transaction. Of courese it returns 0 as soon as the connection is lost.
  */ 
 STATIC int cl_wide_st_chg(drbd_dev* mdev, drbd_state_t os, drbd_state_t ns)
 {
@@ -567,24 +567,41 @@
 	drbd_change_state(mdev,ChgStateHard,mask,val);
 }
 
-static inline enum { REQS_SUCCESS=1, REQS_FAIL=2, REQS_NO_NEED=3 } 
-_req_st_cond(drbd_dev* mdev,drbd_state_t mask, drbd_state_t val)
+STATIC int pre_state_checks(drbd_dev* mdev, drbd_state_t ns);
+STATIC int drbd_send_state_req(drbd_dev *, drbd_state_t, drbd_state_t);
+
+set_st_err_t _req_st_cond(drbd_dev* mdev,drbd_state_t mask, drbd_state_t val)
 {
 	drbd_state_t os,ns;
+	unsigned long flags;
+	int rv;
 
-	if(test_and_clear_bit(CL_ST_CHG_SUCCESS,&mdev->flags)) return REQS_SUCCESS;
-	if(test_and_clear_bit(CL_ST_CHG_FAIL,&mdev->flags)) return REQS_FAIL;
+	if(test_and_clear_bit(CL_ST_CHG_SUCCESS,&mdev->flags)) 
+		return SS_CW_Success;
 
+	if(test_and_clear_bit(CL_ST_CHG_FAIL,&mdev->flags)) 
+		return SS_CW_FailedByPeer;
+
+	rv=0;
+	spin_lock_irqsave(&mdev->req_lock,flags);
 	os = mdev->state;
 	ns.i = (os.i & ~mask.i) | val.i;
+	if( !cl_wide_st_chg(mdev,os,ns) ) rv = SS_CW_NoNeed;
+	if( !rv ) {
+		rv = pre_state_checks(mdev,ns);
+		if(rv==SS_Success) rv = 0; // cont waiting, otherwise fail.
+	}
+	spin_unlock_irqrestore(&mdev->req_lock,flags);
 
-	if(!cl_wide_st_chg(mdev,os,ns)) return REQS_NO_NEED;
-
-	return 0;
+	return rv;
 }
 
-STATIC int drbd_send_state_req(drbd_dev *, drbd_state_t, drbd_state_t);
-
+/** 
+ * _drbd_request_state:
+ * This function is the most gracefull way to change state. For some state
+ * transition this function even does a cluster wide transaction.
+ * It has a cousin named drbd_request_state(), which is always verbose.
+ */ 
 int _drbd_request_state(drbd_dev* mdev, drbd_state_t mask, drbd_state_t val,
 		       enum chg_state_flags f)
 {
@@ -597,17 +614,24 @@
 	ns.i = (os.i & ~mask.i) | val.i;
 
 	if(cl_wide_st_chg(mdev,os,ns)) {
-		// TODO do the pre checks here as well ;
+		rv = pre_state_checks(mdev,ns);
 		spin_unlock_irqrestore(&mdev->req_lock,flags);
 
+		if( rv < SS_Success ) {
+			if( f & ChgStateVerbose ) print_st_err(mdev,os,ns,rv);
+			return rv;
+		}
+
 		drbd_state_lock(mdev);
 		drbd_send_state_req(mdev,mask,val);
 
 		wait_event(mdev->cstate_wait,(rv=_req_st_cond(mdev,mask,val)));
 
-		if(rv == REQS_FAIL) {
+		if( rv < SS_Success ) {
+			// nearly dead code.
 			drbd_state_unlock(mdev);
-			return SS_FailedByPeer; // Nearly dead code ;)
+			if( f & ChgStateVerbose ) print_st_err(mdev,os,ns,rv);
+			return rv;
 		}
 		spin_lock_irqsave(&mdev->req_lock,flags);
 		os = mdev->state;

Modified: trunk/drbd/drbd_strings.c
===================================================================
--- trunk/drbd/drbd_strings.c	2006-05-22 15:10:53 UTC (rev 2205)
+++ trunk/drbd/drbd_strings.c	2006-05-22 18:58:45 UTC (rev 2206)
@@ -68,7 +68,7 @@
 	[-SS_SyncingDiskless] = "Refusing to be syncing and diskless",
 	[-SS_ConnectedOutdates] = "Refusing to be Outdated while Connected",
 	[-SS_PrimaryNOP] = "Refusing to be Primary while peer is not outdated",
-	[-SS_FailedByPeer] = "State changed was refused by peer node"
+	[-SS_CW_FailedByPeer] = "State changed was refused by peer node"
 };
 
 const char* conns_to_name(drbd_conns_t s) {
@@ -88,7 +88,7 @@
 }
 
 const char* set_st_err_name(set_st_err_t err) {
-	return err < SS_PrimaryNOP ? "TOO_SMALL" :
+	return err < SS_CW_FailedByPeer ? "TOO_SMALL" :
 	       err > SS_TowPrimaries ? "TOO_LARGE"
 		        : drbd_state_sw_errors[-err];
 }

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2006-05-22 15:10:53 UTC (rev 2205)
+++ trunk/drbd/linux/drbd.h	2006-05-22 18:58:45 UTC (rev 2206)
@@ -260,16 +260,18 @@
 } drbd_state_t;
 
 typedef enum {
+	SS_CW_NoNeed=4,
+	SS_CW_Success=3,
 	SS_NothingToDo=2,
 	SS_Success=1,
-	SS_UnknownError=0,
+	SS_UnknownError=0, // Used to sleep longer in _drbd_request_state
 	SS_TowPrimaries=-1,
 	SS_NoConsistnetDisk=-2,
 	SS_BothInconsistent=-4,
 	SS_SyncingDiskless=-5,
 	SS_ConnectedOutdates=-6,
 	SS_PrimaryNOP=-7,
-	SS_FailedByPeer=-8
+	SS_CW_FailedByPeer=-8
 } set_st_err_t;
 
 /* from drbd_strings.c */

From drbd-cvs at lists.linbit.com  Mon May 22 22:02:46 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon May 22 22:02:48 2006
Subject: [DRBD-cvs] svn commit by phil - r2207 - trunk - Documented the idea
	how to synchronise the start of res
Message-ID: <20060522200246.B9B562E411@mail.linbit.com>

Author: phil
Date: 2006-05-22 22:02:45 +0200 (Mon, 22 May 2006)
New Revision: 2207

Modified:
   trunk/ROADMAP
Log:
Documented the idea how to synchronise the start of resync.


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-05-22 18:58:45 UTC (rev 2206)
+++ trunk/ROADMAP	2006-05-22 20:02:45 UTC (rev 2207)
@@ -727,11 +727,14 @@
    Connected -> SyncSource in the cluster.
 
       role <- primary
-      conn <- SyncSource
-      conn <- SyncTarget
+      disk <- inconsistent (conn <- SyncTarget) **
+      pdsk <- inconsistent (conn <- SyncSource)
       disk <- Diskless (as long as it happens as administrative command)
       pdsk <- Outdated (= a 'disconnect' issued on a primary node)
 
+   ** It is more feasable to make the change on disk/pdsk cluster
+      wide atomic than working with the connection state.
+
    * When a state change might sleep ( reuqest_state() ) and it is 
      to be cluster wide atomic ( pre_state_checks() determines this!).
 	1. Aquire the cluster state change lock (bit & waitqueue) ?

From drbd-cvs at lists.linbit.com  Tue May 23 11:14:02 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May 23 11:14:04 2006
Subject: [DRBD-cvs] svn commit by lars - r2208 - trunk/tools - minor polish
Message-ID: <20060523091402.C39282F0B9@mail.linbit.com>

Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Author: lars
Date: 2006-05-23 11:14:01 +0200 (Tue, 23 May 2006)
New Revision: 2208

Modified:
   trunk/tools/README
   trunk/tools/drbd-peer-outdater.c
Log:
minor polish

Modified: trunk/tools/README
===================================================================
--- trunk/tools/README	2006-05-22 20:02:45 UTC (rev 2207)
+++ trunk/tools/README	2006-05-23 09:14:01 UTC (rev 2208)
@@ -6,11 +6,11 @@
 2) prepare drbdmeta
 
 cd /sbin
-chown .haclient drbdmeta
+chgrp haclient drbdmeta
 chmod o-x drbdmeta
 chmod u+s drbdmeta
 
-chown .haclient drbdsetup
+chgrp haclient drbdsetup
 chmod o-x drbdsetup
 chmod u+s drbdsetup
 

Modified: trunk/tools/drbd-peer-outdater.c
===================================================================
--- trunk/tools/drbd-peer-outdater.c	2006-05-22 20:02:45 UTC (rev 2207)
+++ trunk/tools/drbd-peer-outdater.c	2006-05-23 09:14:01 UTC (rev 2208)
@@ -150,10 +150,10 @@
 			case 'h':		/* Help message */
 				usage(crm_system_name, LSB_EXIT_OK);
 				break;
-			case 't':		/* Help message */
+			case 't':
 				timeout = atoi(optarg);
 				break;
-			case 'r':		/* Help message */
+			case 'r':
 				drbd_resource = crm_strdup(optarg);
 				break;
 			default:

From drbd-cvs at lists.linbit.com  Tue May 23 12:26:19 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May 23 12:26:21 2006
Subject: [DRBD-cvs] svn commit by lars - r2209 - trunk/tools - notes about
	how to configure drbd to actually use dopd
Message-ID: <20060523102619.8013A2F0B9@mail.linbit.com>

Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Author: lars
Date: 2006-05-23 12:26:18 +0200 (Tue, 23 May 2006)
New Revision: 2209

Modified:
   trunk/tools/README
Log:
notes about how to configure drbd to actually use dopd

Modified: trunk/tools/README
===================================================================
--- trunk/tools/README	2006-05-23 09:14:01 UTC (rev 2208)
+++ trunk/tools/README	2006-05-23 10:26:18 UTC (rev 2209)
@@ -22,3 +22,22 @@
 apiauth dopd gid=haclient uid=hacluster
 ---
 
+4) Configure DRBD to use this facility
+   
+   resource rX {
+     ...
+     handlers {
+       ...
+       outdate-peer "/usr/sbin/drbd-peer-outdater";   
+     }
+     disk {
+       ...
+       fencing resource-only;
+       # or
+       # fencing resource-and-stonith;
+       # in case you configure heartbeat to use stonith
+     }
+     ...
+   }
+
+

From drbd-cvs at lists.linbit.com  Wed May 24 10:59:26 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed May 24 10:59:28 2006
Subject: [DRBD-cvs] svn commit by phil - r2210 - branches/drbd-0.7/drbd -
	Improves the read performance in a corner case from 70M
Message-ID: <20060524085926.E743A2E7B8@mail.linbit.com>

Author: phil
Date: 2006-05-24 10:59:25 +0200 (Wed, 24 May 2006)
New Revision: 2210

Modified:
   branches/drbd-0.7/drbd/drbd_fs.c
Log:
Improves the read performance in a corner case from 70MB/sec to
320MB/sec (cciss driver). Of course only if the reading from 
the backing device itself has such an huge performance.


Modified: branches/drbd-0.7/drbd/drbd_fs.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_fs.c	2006-05-23 10:26:18 UTC (rev 2209)
+++ branches/drbd-0.7/drbd/drbd_fs.c	2006-05-24 08:59:25 UTC (rev 2210)
@@ -469,6 +469,13 @@
 	q->hardsect_size     = max((unsigned short)512,b->hardsect_size);
 	q->seg_boundary_mask = PAGE_SIZE-1;
 	D_ASSERT(q->hardsect_size <= PAGE_SIZE); // or we are really screwed ;-)
+
+	if( q->backing_dev_info.ra_pages != b->backing_dev_info.ra_pages) {
+		INFO("Adjusting our ra_pages to backing device's (%lu)\n",
+		     b->backing_dev_info.ra_pages);
+		q->backing_dev_info.ra_pages = b->backing_dev_info.ra_pages;
+	}
+
 })
 #undef min_not_zero
 

From drbd-cvs at lists.linbit.com  Wed May 24 11:00:27 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed May 24 11:00:28 2006
Subject: [DRBD-cvs] svn commit by phil - r2211 - branches/drbd-0.7/drbd -
	latest version of the patch 
Message-ID: <20060524090027.EF7ED2F0E8@mail.linbit.com>

Author: phil
Date: 2006-05-24 11:00:26 +0200 (Wed, 24 May 2006)
New Revision: 2211

Modified:
   branches/drbd-0.7/drbd/drbd_fs.c
Log:
latest version of the patch 


Modified: branches/drbd-0.7/drbd/drbd_fs.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_fs.c	2006-05-24 08:59:25 UTC (rev 2210)
+++ branches/drbd-0.7/drbd/drbd_fs.c	2006-05-24 09:00:26 UTC (rev 2211)
@@ -471,7 +471,8 @@
 	D_ASSERT(q->hardsect_size <= PAGE_SIZE); // or we are really screwed ;-)
 
 	if( q->backing_dev_info.ra_pages != b->backing_dev_info.ra_pages) {
-		INFO("Adjusting our ra_pages to backing device's (%lu)\n",
+		INFO("Adjusting my ra_pages to backing device's (%lu -> %lu)\n",
+		     q->backing_dev_info.ra_pages,
 		     b->backing_dev_info.ra_pages);
 		q->backing_dev_info.ra_pages = b->backing_dev_info.ra_pages;
 	}

From drbd-cvs at lists.linbit.com  Wed May 24 14:03:37 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed May 24 14:03:39 2006
Subject: [DRBD-cvs] svn commit by phil - r2212 - in branches/drbd-0.7: .
	debian drbd/linux - Preparing 0.7.19 
Message-ID: <20060524120337.5336D2F0E8@mail.linbit.com>

Author: phil
Date: 2006-05-24 14:03:35 +0200 (Wed, 24 May 2006)
New Revision: 2212

Modified:
   branches/drbd-0.7/ChangeLog
   branches/drbd-0.7/debian/changelog
   branches/drbd-0.7/drbd.spec.in
   branches/drbd-0.7/drbd/linux/drbd_config.h
Log:
Preparing 0.7.19


Modified: branches/drbd-0.7/ChangeLog
===================================================================
--- branches/drbd-0.7/ChangeLog	2006-05-24 09:00:26 UTC (rev 2211)
+++ branches/drbd-0.7/ChangeLog	2006-05-24 12:03:35 UTC (rev 2212)
@@ -1,9 +1,20 @@
 Latest:
 ------
- ChangeLog last updated: r2085 2006-03-06
+ ChangeLog last updated: r2211 2006-05-24
  Cumulative changes since last tarball.
  For even more detail, use "svn log" and "svn diff".
 
+0.7.19 (api:78/proto:74)
+-----
+ * Fixed a bug where lc_del() left a list poison in an LRU chache's
+   hash table. The only way to trigger this bug was:
+   up (>>200M), primary, mkfs, resize to 200M, down, up
+ * DRBD now propagates the backing storage's read ahead properties
+   to upper layers. With devices that read very fast, this is 
+   important.
+ * GFP_KERNEL was changed to GFP_NOIO in a few places, to make it
+   more save against deadlocks in the memory subsystem.
+
 0.7.18 (api:78/proto:74)
 -----
  * Under high memory pressure it was possible to hit a deadlock 

Modified: branches/drbd-0.7/debian/changelog
===================================================================
--- branches/drbd-0.7/debian/changelog	2006-05-24 09:00:26 UTC (rev 2211)
+++ branches/drbd-0.7/debian/changelog	2006-05-24 12:03:35 UTC (rev 2212)
@@ -1,3 +1,9 @@
+drbd (0.7.19-0) unstable; urgency=low
+
+  * New upstream release
+
+ -- Philipp Reisner <phil@linbit.com>  Mon, 24 May 2006 14:03:07 +0200
+
 drbd (0.7.18-0) unstable; urgency=low
 
   * New upstream release

Modified: branches/drbd-0.7/drbd/linux/drbd_config.h
===================================================================
--- branches/drbd-0.7/drbd/linux/drbd_config.h	2006-05-24 09:00:26 UTC (rev 2211)
+++ branches/drbd-0.7/drbd/linux/drbd_config.h	2006-05-24 12:03:35 UTC (rev 2212)
@@ -22,7 +22,7 @@
 
 extern const char * drbd_buildtag(void);
 
-#define REL_VERSION "0.7.18"
+#define REL_VERSION "0.7.19"
 #define API_VERSION 78
 #define PRO_VERSION 74
 

Modified: branches/drbd-0.7/drbd.spec.in
===================================================================
--- branches/drbd-0.7/drbd.spec.in	2006-05-24 09:00:26 UTC (rev 2211)
+++ branches/drbd-0.7/drbd.spec.in	2006-05-24 12:03:35 UTC (rev 2212)
@@ -190,6 +190,17 @@
 /sbin/depmod -a -F /boot/System.map-%{kernelversion} %{kernelversion} >/dev/null 2>&1 || true
 
 %changelog
+* Mon May 24 2006 14:03:07 +0200 Philipp Reisner <phil@linbit.com>
+- drbd (0.7.19-1)
+ * Fixed a bug where lc_del() left a list poison in an LRU chache's
+   hash table. The only way to trigger this bug was:
+   up (>>200M), primary, mkfs, resize to 200M, down, up
+ * DRBD now propagates the backing storage's read ahead properties
+   to upper layers. With devices that read very fast, this is 
+   important.
+ * GFP_KERNEL was changed to GFP_NOIO in a few places, to make it
+   more save against deadlocks in the memory subsystem.
+
 * Mon Apr 26 2006 14:10:07 +0200 Philipp Reisner <phil@linbit.com>
 - drbd (0.7.18-1)
  * Under high memory pressure it was possible to hit a deadlock 

From drbd-cvs at lists.linbit.com  Wed May 24 14:05:17 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed May 24 14:05:18 2006
Subject: [DRBD-cvs] svn commit by phil - r2213 - tags - Tagging 0.7.19 
Message-ID: <20060524120517.BDB2A2F0E8@mail.linbit.com>

Author: phil
Date: 2006-05-24 14:05:16 +0200 (Wed, 24 May 2006)
New Revision: 2213

Added:
   tags/drbd-0.7.19/
Log:
Tagging 0.7.19


Copied: tags/drbd-0.7.19 (from rev 2212, branches/drbd-0.7)

From drbd-cvs at lists.linbit.com  Wed May 24 20:42:54 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed May 24 20:43:03 2006
Subject: [DRBD-cvs] svn commit by phil - r2214 - in trunk: scripts user -
	Fixed two small issues: * Do not crash in the the devic
Message-ID: <20060524184254.3AE972D7E9@mail.linbit.com>

Author: phil
Date: 2006-05-24 20:42:52 +0200 (Wed, 24 May 2006)
New Revision: 2214

Modified:
   trunk/scripts/drbd.conf
   trunk/user/drbdadm_adjust.c
   trunk/user/drbdadm_main.c
Log:
Fixed two small issues:
 * Do not crash in the the device is not configured at all.
 * Verify that the resource specified with the after directive exists at all.


Modified: trunk/scripts/drbd.conf
===================================================================
--- trunk/scripts/drbd.conf	2006-05-24 12:05:16 UTC (rev 2213)
+++ trunk/scripts/drbd.conf	2006-05-24 18:42:52 UTC (rev 2214)
@@ -65,7 +65,7 @@
 # At most ONE global section is allowed.
 # It must precede any resource section.
 #
-# global {
+global {
     # use this if you want to define more resources later
     # without reloading the module.
     # by default we load the module with exactly as many devices
@@ -89,7 +89,7 @@
     # possilbe options: ask, yes, no. Default is ask. In case you do not
     # know, set it to ask, and follow the on screen instructions later.
     usage-count yes;
-# }
+}
 
 
 #

Modified: trunk/user/drbdadm_adjust.c
===================================================================
--- trunk/user/drbdadm_adjust.c	2006-05-24 12:05:16 UTC (rev 2213)
+++ trunk/user/drbdadm_adjust.c	2006-05-24 18:42:52 UTC (rev 2214)
@@ -195,8 +195,10 @@
 	convert_after_option(res);
 
 	do_attach  = !opts_equal(res->disk_options, running->disk_options);
-	do_attach |= strcmp(res->me->device, running->me->device);
-	do_attach |= !disk_equal(res->me, running->me);
+	if(running->me) {
+		do_attach |= strcmp(res->me->device, running->me->device);
+		do_attach |= !disk_equal(res->me, running->me);
+	} else  do_attach |= 1;
 
 	do_connect  = !opts_equal(res->net_options, running->net_options);
 	do_connect |= !addr_equal(res,running);

Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c	2006-05-24 12:05:16 UTC (rev 2213)
+++ trunk/user/drbdadm_main.c	2006-05-24 18:42:52 UTC (rev 2214)
@@ -473,6 +473,7 @@
     expand_opts(common->sync_options,    &res->sync_options);
     expand_opts(common->startup_options, &res->startup_options);
     expand_opts(common->handlers,        &res->handlers);
+    validate_resource(res);
   }
 }
 
@@ -747,6 +748,8 @@
 {
   struct d_option* opt;
 
+  if (res==NULL) return;
+
   if ( (opt = find_opt(res->net_options, "after-sb-0pri")) ) {
     if(!strncmp(opt->value,"discard-node-",13)) {
       if(!strcmp(nodeinfo.nodename,opt->value+13)) {
@@ -795,6 +798,8 @@
 {
   struct d_option* opt;
 
+  if (res==NULL) return;
+
   if ( (opt = find_opt(res->sync_options, "after")) ) {
     char *ptr;
     ssprintf(ptr,"%d",dt_minor_of_dev(res_by_name(opt->value)->me->device));
@@ -1374,6 +1379,8 @@
 
 void validate_resource(struct d_resource * res)
 {
+  struct d_option* opt;
+
   if (!res->protocol) {
     fprintf(stderr,
 	    "%s:%d: in resource %s:\n\tprotocol definition missing.\n",
@@ -1395,6 +1402,13 @@
 	    config_file, c_resource_start, res->name);
     config_valid = 0;
   }
+  if ( (opt = find_opt(res->sync_options, "after")) ) {
+    if (res_by_name(opt->value) == NULL) {
+      fprintf(stderr,"In resource %s:\n\tresource '%s' mentioned in "
+	      "'after' option is not known.\n",res->name,opt->value);
+      config_valid=0;
+    }
+  }
   if (res->me && res->peer) {
     verify_ips(res);
   }

From drbd-cvs at lists.linbit.com  Wed May 24 21:04:02 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed May 24 21:04:03 2006
Subject: [DRBD-cvs] svn commit by phil - r2215 - trunk/user - A last small
	fix to make drbdadm adjust work with exter
Message-ID: <20060524190402.B299E2D7E9@mail.linbit.com>

Author: phil
Date: 2006-05-24 21:04:01 +0200 (Wed, 24 May 2006)
New Revision: 2215

Modified:
   trunk/user/drbdadm_parser.c
   trunk/user/drbdadm_parser.h
Log:
A last small fix to make drbdadm adjust work with external meta data.


Modified: trunk/user/drbdadm_parser.c
===================================================================
--- trunk/user/drbdadm_parser.c	2006-05-24 18:42:52 UTC (rev 2214)
+++ trunk/user/drbdadm_parser.c	2006-05-24 19:04:01 UTC (rev 2215)
@@ -354,8 +354,6 @@
 				EXP(TK_INTEGER);
 				host->meta_index = yylval.txt;
 				EXP(']');
-				EXP(';');
-			} else {
 				switch(yylex()) {
 				case TK__MAJOR:
 					EXP(TK_INTEGER);
@@ -369,6 +367,8 @@
 				default:
 					pe_expected("_major | ;");
 				}
+			} else {
+				EXP(';');
 			}
 			check_meta_disk(host);
 			break;

Modified: trunk/user/drbdadm_parser.h
===================================================================
--- trunk/user/drbdadm_parser.h	2006-05-24 18:42:52 UTC (rev 2214)
+++ trunk/user/drbdadm_parser.h	2006-05-24 19:04:01 UTC (rev 2215)
@@ -80,7 +80,7 @@
 	TK_STARTUP_SWITCH,
 	TK_STARTUP_OPTION,
 	TK_HANDLER_OPTION,
-	TK_USAGE_COUNT,
+	TK_USAGE_COUNT,  // 290
 	TK_ASK,
 	TK_YES,
 	TK_NO,

From drbd-cvs at lists.linbit.com  Fri May 26 15:20:52 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri May 26 15:20:53 2006
Subject: [DRBD-cvs] svn commit by phil - r2216 - in branches/drbd-0.7:
	documentation drbd drbd/linux scripts user - Added a new run
	time configuration parameter (bdev-tres
Message-ID: <20060526132052.9E61E2E411@mail.linbit.com>

Author: phil
Date: 2006-05-26 15:20:48 +0200 (Fri, 26 May 2006)
New Revision: 2216

Modified:
   branches/drbd-0.7/documentation/drbdsetup.sgml
   branches/drbd-0.7/drbd/drbd_receiver.c
   branches/drbd-0.7/drbd/drbd_sizeof_sanity_check.c
   branches/drbd-0.7/drbd/linux/drbd.h
   branches/drbd-0.7/drbd/linux/drbd_config.h
   branches/drbd-0.7/scripts/drbd.conf
   branches/drbd-0.7/user/drbd_limits.h
   branches/drbd-0.7/user/drbdadm_adjust.c
   branches/drbd-0.7/user/drbdadm_parser.y
   branches/drbd-0.7/user/drbdadm_scanner.fl
   branches/drbd-0.7/user/drbdsetup.c
Log:
Added a new run time configuration parameter (bdev-treshold) to 
be able to tune for special controllers. In this case HP's cciss.


Modified: branches/drbd-0.7/documentation/drbdsetup.sgml
===================================================================
--- branches/drbd-0.7/documentation/drbdsetup.sgml	2006-05-24 19:04:01 UTC (rev 2215)
+++ branches/drbd-0.7/documentation/drbdsetup.sgml	2006-05-26 13:20:48 UTC (rev 2216)
@@ -313,6 +313,21 @@
 	  </listitem>
 	</varlistentry>
 	<varlistentry>
+	  <term><option>-l</option>,
+	  <option>--bdev-treshold <replaceable>val</replaceable></option></term>
+	  <listitem>
+	    <para>
+	      When the number of pending write requests on the standby
+	      (secondary) nodes goes over bdev-treshold we trigger
+	      the request processing of out backing storage device.
+	      Some storage controllers deliver better performance with small
+	      values, other delivers beste performance when it is set to
+	      the same value as max-buffers. Minimum 16, default 128, maximum
+	      131072.
+	    </para>
+	  </listitem>
+	</varlistentry>
+	<varlistentry>
 	  <term><option>-d</option>,
 	  <option>--on-disconnect <replaceable>discon_handler</replaceable></option></term>
 	  <listitem>

Modified: branches/drbd-0.7/drbd/drbd_receiver.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_receiver.c	2006-05-24 19:04:01 UTC (rev 2215)
+++ branches/drbd-0.7/drbd/drbd_receiver.c	2006-05-26 13:20:48 UTC (rev 2216)
@@ -301,7 +301,8 @@
 
 	MUST_HOLD(&mdev->ee_lock);
 
-	if(mdev->ee_vacant == EE_MININUM / 2) {
+	if(mdev->ee_vacant == EE_MININUM / 2 && 
+	   (mdev->conf.bdev_treshold != mdev->conf.max_buffers) ) {
 		spin_unlock_irq(&mdev->ee_lock);
 		drbd_kick_lo(mdev);
 		spin_lock_irq(&mdev->ee_lock);
@@ -903,11 +904,8 @@
 	/* kick lower level device, if we have more than (arbitrary number)
 	 * reference counts on it, which typically are locally submitted io
 	 * requests.  don't use unacked_cnt, so we speed up proto A and B, too.
-	 *
-	 * XXX maybe: make that arbitrary number configurable.
-	 * for now, I choose 1/16 of max-epoch-size.
 	 */
-	if (atomic_read(&mdev->local_cnt) >= (mdev->conf.max_epoch_size>>4) ) {
+	if (atomic_read(&mdev->local_cnt) >= mdev->conf.bdev_treshold ) {
 		drbd_kick_lo(mdev);
 	}
 	mdev->writ_cnt+=data_size>>9;

Modified: branches/drbd-0.7/drbd/drbd_sizeof_sanity_check.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_sizeof_sanity_check.c	2006-05-24 19:04:01 UTC (rev 2215)
+++ branches/drbd-0.7/drbd/drbd_sizeof_sanity_check.c	2006-05-26 13:20:48 UTC (rev 2216)
@@ -12,13 +12,13 @@
 {
 	int err = 0, s = 0;
 	SZO(struct disk_config,		 24)
-	SZO(struct net_config,		304)
+	SZO(struct net_config,		308)
 	SZO(struct syncer_config,	 24)
 	SZO(struct ioctl_disk_config,	 32)
-	SZO(struct ioctl_net_config,	312)
+	SZO(struct ioctl_net_config,	316)
 	SZO(struct ioctl_syncer_config,	 32)
 	SZO(struct ioctl_wait,		 16)
-	SZO(struct ioctl_get_config,	440)
+	SZO(struct ioctl_get_config,	444)
 	if (err) printk("<3>ioctls won't work, aborting\n");
 	return err;
 }

Modified: branches/drbd-0.7/drbd/linux/drbd.h
===================================================================
--- branches/drbd-0.7/drbd/linux/drbd.h	2006-05-24 19:04:01 UTC (rev 2215)
+++ branches/drbd-0.7/drbd/linux/drbd.h	2006-05-26 13:20:48 UTC (rev 2216)
@@ -93,6 +93,7 @@
 	IN int      ping_int;         /* seconds */
 	IN int      max_epoch_size;
 	IN int      max_buffers;
+	IN int      bdev_treshold;
 	IN int      sndbuf_size;  /* socket send buffer size */
 	IN unsigned int ko_count;
 	IN enum disconnect_handler on_disconnect;

Modified: branches/drbd-0.7/drbd/linux/drbd_config.h
===================================================================
--- branches/drbd-0.7/drbd/linux/drbd_config.h	2006-05-24 19:04:01 UTC (rev 2215)
+++ branches/drbd-0.7/drbd/linux/drbd_config.h	2006-05-26 13:20:48 UTC (rev 2216)
@@ -23,7 +23,7 @@
 extern const char * drbd_buildtag(void);
 
 #define REL_VERSION "0.7.19"
-#define API_VERSION 78
+#define API_VERSION 79
 #define PRO_VERSION 74
 
 //#define DBG_ALL_SYMBOLS // no static functs, improves quality of OOPS traces

Modified: branches/drbd-0.7/scripts/drbd.conf
===================================================================
--- branches/drbd-0.7/scripts/drbd.conf	2006-05-24 19:04:01 UTC (rev 2215)
+++ branches/drbd-0.7/scripts/drbd.conf	2006-05-26 13:20:48 UTC (rev 2216)
@@ -172,6 +172,18 @@
     #
     # max-buffers     2048;
 
+    # When the number of outstanding requests on a standby (secondary)
+    # node goes over bdev-reshold we start to kick the backing device
+    # to start its request processing. This is an advanced tuning
+    # parameter to get more performance out of capable storage controlers.
+    # Some controlers likes to be kicked often, other controlers 
+    # deliver better performance when the are kicked less frequently.
+    # Set it to the value of max-buffers to get the least possible
+    # number of run_task_queue_disk() calls.
+    #
+    # bdev-treshold   128;
+
+
     # The highest number of data blocks between two write barriers. 
     # If you set this < 10 you might decrease your performance.
     # max-epoch-size  2048;

Modified: branches/drbd-0.7/user/drbd_limits.h
===================================================================
--- branches/drbd-0.7/user/drbd_limits.h	2006-05-24 19:04:01 UTC (rev 2215)
+++ branches/drbd-0.7/user/drbd_limits.h	2006-05-26 13:20:48 UTC (rev 2216)
@@ -52,6 +52,9 @@
   /* @4k PageSize -> 128kB - 512MB */
   RANGE(MAX_BUFFERS, 32, 131072);
 
+  /* @4k PageSize -> 64kB - 512MB */
+  RANGE(BDEV_TRESHOLD, 16, 131072);
+
   /* 0 is disabled.
    * 200 should be more than enough even for very short timeouts */
   RANGE(KO_COUNT,0, 200);

Modified: branches/drbd-0.7/user/drbdadm_adjust.c
===================================================================
--- branches/drbd-0.7/user/drbdadm_adjust.c	2006-05-24 19:04:01 UTC (rev 2215)
+++ branches/drbd-0.7/user/drbdadm_adjust.c	2006-05-26 13:20:48 UTC (rev 2216)
@@ -337,6 +337,7 @@
     do_connect |= check_opt_d(in,"ping-int",1,"sec",res->net_options);
     do_connect |= check_opt_d(in,"max-epoch-size",1,"",res->net_options);
     do_connect |= check_opt_d(in,"max-buffers",1,"",res->net_options);
+    do_connect |= check_opt_d(in,"bdev-treshold",1,"",res->net_options);
     do_connect |= check_opt_d(in,"sndbuf-size",1,"",res->net_options);
     do_connect |= check_opt_d(in,"ko-count",1,"",res->net_options);
     do_connect |= check_opt_s(in,"on-disconnect",res->net_options);

Modified: branches/drbd-0.7/user/drbdadm_parser.y
===================================================================
--- branches/drbd-0.7/user/drbdadm_parser.y	2006-05-24 19:04:01 UTC (rev 2215)
+++ branches/drbd-0.7/user/drbdadm_parser.y	2006-05-26 13:20:48 UTC (rev 2216)
@@ -144,6 +144,7 @@
   R_CONNECT_INT,
   R_PING_INT,
   R_MAX_BUFFERS,
+  R_BDEV_TRESHOLD,
   R_MAX_EPOCH_SIZE,
   R_SNDBUF_SIZE,
   R_KO_COUNT,
@@ -192,6 +193,10 @@
       m_strtoll_range(value, 1, name, DRBD_MAX_BUFFERS_MIN,
 		      DRBD_MAX_BUFFERS_MAX);
       break;
+    case R_BDEV_TRESHOLD:
+      m_strtoll_range(value, 1, name, DRBD_BDEV_TRESHOLD_MIN,
+		      DRBD_BDEV_TRESHOLD_MAX);
+      break;
     case R_MAX_EPOCH_SIZE:
       m_strtoll_range(value, 1, name, DRBD_MAX_EPOCH_SIZE_MIN,
 		      DRBD_MAX_EPOCH_SIZE_MAX);
@@ -328,7 +333,7 @@
 %token <txt> TK_MINOR_COUNT TK_INTEGER TK_STRING
 %token <txt> TK_ON_IO_ERROR TK_SIZE
 %token <txt> TK_TIMEOUT TK_CONNECT_INT TK_PING_INT TK_MAX_BUFFERS TK_IPADDR
-%token <txt> TK_MAX_EPOCH_SIZE TK_SNDBUF_SIZE
+%token <txt> TK_BDEV_TRESHOLD TK_MAX_EPOCH_SIZE TK_SNDBUF_SIZE
 %token <txt> TK_SKIP_SYNC TK_USE_CSUMS TK_RATE TK_SYNC_GROUP TK_AL_EXTENTS
 %token <txt> TK_WFC_TIMEOUT TK_DEGR_WFC_TIMEOUT
 %token <txt> TK_KO_COUNT TK_ON_DISCONNECT TK_DIALOG_REFRESH
@@ -452,6 +457,8 @@
 		{ range_check(R_PING_INT,$1,$2);	$$=new_opt($1,$2); }
 		| TK_MAX_BUFFERS    TK_INTEGER
 		{ range_check(R_MAX_BUFFERS,$1,$2);	$$=new_opt($1,$2); }
+		| TK_BDEV_TRESHOLD    TK_INTEGER
+		{ range_check(R_BDEV_TRESHOLD,$1,$2);	$$=new_opt($1,$2); }
 		| TK_MAX_EPOCH_SIZE TK_INTEGER
 		{ range_check(R_MAX_EPOCH_SIZE,$1,$2);	$$=new_opt($1,$2); }
 		| TK_SNDBUF_SIZE    TK_INTEGER

Modified: branches/drbd-0.7/user/drbdadm_scanner.fl
===================================================================
--- branches/drbd-0.7/user/drbdadm_scanner.fl	2006-05-24 19:04:01 UTC (rev 2215)
+++ branches/drbd-0.7/user/drbdadm_scanner.fl	2006-05-26 13:20:48 UTC (rev 2216)
@@ -258,10 +258,11 @@
   ping-int		do_assign(NUM);   CP; return TK_PING_INT;
   connect-int		do_assign(NUM);   CP; return TK_CONNECT_INT;
   max-buffers		do_assign(NUM);   CP; return TK_MAX_BUFFERS;
+  bdev-treshold		do_assign(NUM);   CP; return TK_BDEV_TRESHOLD;
   max-epoch-size	do_assign(NUM);   CP; return TK_MAX_EPOCH_SIZE;
   ko-count		do_assign(NUM);   CP; return TK_KO_COUNT;
   on-disconnect 	do_assign(ON_DISCONNECT); CP; return TK_ON_DISCONNECT;
-  {NDELIM}		expect_error("one of 'sndbuf-size|timeout|ping-int|connect-int|max-buffers|max-epoch-size|ko-count|on-disconnect'");
+  {NDELIM}		expect_error("one of 'sndbuf-size|timeout|ping-int|connect-int|max-buffers|bdev-treshold|max-epoch-size|ko-count|on-disconnect'");
 }
 
 <SYNCER>{

Modified: branches/drbd-0.7/user/drbdsetup.c
===================================================================
--- branches/drbd-0.7/user/drbdsetup.c	2006-05-24 19:04:01 UTC (rev 2215)
+++ branches/drbd-0.7/user/drbdsetup.c	2006-05-26 13:20:48 UTC (rev 2216)
@@ -70,6 +70,7 @@
 #define DEF_ON_IO_ERROR         PassOn
 #define DEF_KO_COUNT                 0
 #define DEF_ON_DISCONNECT       Reconnect
+#define DEF_BDEV_TRESHOLD       (DEF_MAX_BUFFERS/16)
 
 #if 0
 # define ioctl(X...) (fprintf(stderr,"ioctl(%s)\n",#X),0);
@@ -157,6 +158,7 @@
      { "timeout",    required_argument, 0, 't' },
      { "max-epoch-size", required_argument, 0, 'e' },
      { "max-buffers",required_argument, 0, 'b' },
+     { "bdev-treshold",required_argument, 0, 'l' },
      { "connect-int",required_argument, 0, 'c' },
      { "ping-int",   required_argument, 0, 'i' },
      { "sndbuf-size",required_argument, 0, 'S' },
@@ -562,6 +564,7 @@
   cn->config.sndbuf_size = DEF_SNDBUF_SIZE ;
   cn->config.on_disconnect = DEF_ON_DISCONNECT;
   cn->config.ko_count = DEF_KO_COUNT;
+  cn->config.bdev_treshold = DEF_BDEV_TRESHOLD;
 
   if(argc==0) return 0;
 
@@ -588,6 +591,10 @@
 	  cn->config.max_buffers = m_strtoll_range(optarg,1, "max-buffers",
 			  DRBD_MAX_BUFFERS_MIN, DRBD_MAX_BUFFERS_MAX);
 	  break;
+	case 'l':
+	  cn->config.bdev_treshold = m_strtoll_range(optarg,1, "bdev-treshold",
+			  DRBD_BDEV_TRESHOLD_MIN, DRBD_BDEV_TRESHOLD_MAX);
+	  break;
 	case 'c':
 	  cn->config.try_connect_int = m_strtoll_range(optarg,1, "connect-int",
 			  DRBD_CONNECT_INT_MIN, DRBD_CONNECT_INT_MAX);
@@ -1345,6 +1352,7 @@
   SHOW_I("ping-int","sec", cn.nconf.ping_int, DEF_NET_PING_I);
   SHOW_I("max-epoch-size","", cn.nconf.max_epoch_size, DEF_MAX_EPOCH_SIZE);
   SHOW_I("max-buffers","", cn.nconf.max_buffers, DEF_MAX_BUFFERS);
+  SHOW_I("bdev-threshold","", cn.nconf.bdev_treshold, DEF_BDEV_TRESHOLD);
   SHOW_I("sndbuf-size","", cn.nconf.sndbuf_size, DEF_SNDBUF_SIZE);
   SHOW_I("ko-count","", cn.nconf.ko_count, DEF_KO_COUNT);
   if( cn.nconf.on_disconnect != DEF_ON_DISCONNECT) {

From drbd-cvs at lists.linbit.com  Fri May 26 17:24:00 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri May 26 17:24:01 2006
Subject: [DRBD-cvs] svn commit by lars - r2222 - in branches/drbd-0.7: .
	documentation drbd scripts user - * Corrected some spelling
	errors in the recent document
Message-ID: <20060526152400.3FC3C2E411@mail.linbit.com>

Author: lars
Date: 2006-05-26 17:23:55 +0200 (Fri, 26 May 2006)
New Revision: 2222

Modified:
   branches/drbd-0.7/ChangeLog
   branches/drbd-0.7/documentation/drbd.conf.sgml
   branches/drbd-0.7/documentation/drbd.sgml
   branches/drbd-0.7/documentation/drbdadm.sgml
   branches/drbd-0.7/documentation/drbddisk.sgml
   branches/drbd-0.7/documentation/drbdsetup.sgml
   branches/drbd-0.7/drbd/drbd_actlog.c
   branches/drbd-0.7/drbd/drbd_bitmap.c
   branches/drbd-0.7/drbd/drbd_fs.c
   branches/drbd-0.7/drbd/drbd_int.h
   branches/drbd-0.7/drbd/drbd_main.c
   branches/drbd-0.7/drbd/drbd_proc.c
   branches/drbd-0.7/drbd/drbd_receiver.c
   branches/drbd-0.7/drbd/drbd_req.c
   branches/drbd-0.7/drbd/drbd_worker.c
   branches/drbd-0.7/drbd/lru_cache.c
   branches/drbd-0.7/drbd/lru_cache.h
   branches/drbd-0.7/scripts/drbd.conf
   branches/drbd-0.7/scripts/patch-kernel
   branches/drbd-0.7/user/drbdadm_adjust.c
   branches/drbd-0.7/user/drbdadm_main.c
   branches/drbd-0.7/user/drbdsetup.c
Log:

* Corrected some spelling errors in the recent documentation,
  and added bdev-threshold to drbd.conf.sgml
* removed references to freeze io from the manpages:
  we did not implement it in 0.7.x
* adjusted some copyright comments



Modified: branches/drbd-0.7/ChangeLog
===================================================================
--- branches/drbd-0.7/ChangeLog	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/ChangeLog	2006-05-26 15:23:55 UTC (rev 2222)
@@ -1,6 +1,6 @@
 Latest:
 ------
- ChangeLog last updated: r2211 2006-05-24
+ ChangeLog last updated: $LastChangedRev$ $LastChangedDate$
  Cumulative changes since last tarball.
  For even more detail, use "svn log" and "svn diff".
 


Property changes on: branches/drbd-0.7/ChangeLog
___________________________________________________________________
Name: svn:keywords
   + LastChangedRev LastChangedDate

Modified: branches/drbd-0.7/documentation/drbd.conf.sgml
===================================================================
--- branches/drbd-0.7/documentation/drbd.conf.sgml	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/documentation/drbd.conf.sgml	2006-05-26 15:23:55 UTC (rev 2222)
@@ -175,6 +175,7 @@
     <option>sndbuf-size</option>, <option>timeout</option>,
     <option>connect-int</option>, <option>ping-int</option>,
     <option>max-buffers</option>, <option>max-epoch-size</option>,
+    <option>bdev-treshold</option>,
     <option>ko-count</option>, <option>on-disconnect</option>.
   </para>
   </listitem>
@@ -427,6 +428,21 @@
 </varlistentry>
 
 <varlistentry>
+  <term><option>bdev-treshold <replaceable>number</replaceable></option></term>
+  <listitem>
+    <para>
+      When the number of pending write requests on the standby
+      (secondary) node exceeds the bdev-treshold, we trigger
+      the request processing of our backing storage device.
+      Some storage controllers deliver better performance with small
+      values, other deliver best performance when it is set to
+      the same value as max-buffers. Minimum 16, default 128, maximum
+      131072.
+    </para>
+  </listitem>
+</varlistentry>
+
+<varlistentry>
   <term><option>ko-count <replaceable>count</replaceable></option></term>
   <listitem><para>
   In case the secondary node fails to complete a single write request
@@ -441,17 +457,14 @@
   <term><option>on-disconnect <replaceable>handler</replaceable></option></term>
   <listitem><para>
   When the connection to the peer is lost, DRBD can either
-  go into stand alone mode, try to reconnect to the peer or
-  freeze all further IO requests (think of an NFS hard mount).
-  Valid handler specifiers are <option>stand_alone</option>,
-  <option>reconnect</option> and <option>freeze_io</option>.
+  go into stand alone mode, or try to reconnect to the peer.
+  Valid handler specifiers are <option>stand_alone</option> and
+  <option>reconnect</option>.
   The default handler is <option>reconnect</option>.
   </para>
   <para><option>stand_alone</option>: Do not reconnect, go into
   StandAlone state.</para>
   <para><option>reconnect</option>: Try to reconnect.</para>
-  <para><option>freeze_io</option>: Try to reconnect, but freeze all
-  IO until the connection is established again.</para>
   </listitem>
 </varlistentry>
 
@@ -530,7 +543,7 @@
 </refsect1>
 <refsect1>
 <title>Version</title>
-<simpara>This document is correct for version 0.7.15 of the DRBD distribution.
+<simpara>This document is correct for version 0.7.20 of the DRBD distribution.
 </simpara>
 </refsect1>
 <refsect1>
@@ -547,7 +560,7 @@
 <refsect1>
 <title>Copyright</title>
 <simpara>
-Copyright (c) 2001-2005 Philipp Reisner. This  is  free software; 
+Copyright (c) 2001-2006 Philipp Reisner. This  is  free software; 
 see the source for copying conditions.  There is NO warranty; 
 not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 </simpara>

Modified: branches/drbd-0.7/documentation/drbd.sgml
===================================================================
--- branches/drbd-0.7/documentation/drbd.sgml	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/documentation/drbd.sgml	2006-05-26 15:23:55 UTC (rev 2222)
@@ -53,7 +53,7 @@
 
 <refsect1>
   <title>Version</title>
-  <simpara>This document is correct for version 0.7.15 of the DRBD distribution.
+  <simpara>This document is correct for version 0.7.20 of the DRBD distribution.
   </simpara>
 </refsect1>
 
@@ -74,7 +74,7 @@
 <refsect1>
   <title>Copyright</title>
   <simpara>
-    Copyright (c) 2001-2005 Philipp Reisner. This  is  free software; 
+    Copyright (c) 2001-2006 Philipp Reisner. This  is  free software; 
     see the source for copying conditions.  There is NO warranty; 
     not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   </simpara>

Modified: branches/drbd-0.7/documentation/drbdadm.sgml
===================================================================
--- branches/drbd-0.7/documentation/drbdadm.sgml	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/documentation/drbdadm.sgml	2006-05-26 15:23:55 UTC (rev 2222)
@@ -192,7 +192,7 @@
   <refsect1>
     <title>Version</title>
     <simpara>
-      This document is correct for version 0.7.15 of the DRBD distribution.
+      This document is correct for version 0.7.20 of the DRBD distribution.
     </simpara>
   </refsect1>
 
@@ -209,7 +209,7 @@
   <refsect1>
     <title>Copyright</title>
     <simpara>
-      Copyright (c) 2004-2005 Philipp Reisner. This  is  free software; 
+      Copyright (c) 2004-2006 Philipp Reisner. This  is  free software; 
       see the source for copying conditions.  There is NO warranty; 
       not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     </simpara>

Modified: branches/drbd-0.7/documentation/drbddisk.sgml
===================================================================
--- branches/drbd-0.7/documentation/drbddisk.sgml	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/documentation/drbddisk.sgml	2006-05-26 15:23:55 UTC (rev 2222)
@@ -45,7 +45,7 @@
 
 <refsect1>
 <title>Version</title>
-<simpara>This document is correct for version 0.7.15 of the DRBD distribution.
+<simpara>This document is correct for version 0.7.20 of the DRBD distribution.
 </simpara>
 </refsect1>
 
@@ -66,7 +66,7 @@
 <refsect1>
   <title>Copyright</title>
   <simpara>
-    Copyright (c) 2004-2005 Philipp Reisner. This  is  free software; 
+    Copyright (c) 2004-2006 Philipp Reisner. This  is  free software; 
     see the source for copying conditions.  There is NO warranty; 
     not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   </simpara>

Modified: branches/drbd-0.7/documentation/drbdsetup.sgml
===================================================================
--- branches/drbd-0.7/documentation/drbdsetup.sgml	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/documentation/drbdsetup.sgml	2006-05-26 15:23:55 UTC (rev 2222)
@@ -318,10 +318,10 @@
 	  <listitem>
 	    <para>
 	      When the number of pending write requests on the standby
-	      (secondary) nodes goes over bdev-treshold we trigger
-	      the request processing of out backing storage device.
+	      (secondary) node exceeds the bdev-treshold, we trigger
+	      the request processing of our backing storage device.
 	      Some storage controllers deliver better performance with small
-	      values, other delivers beste performance when it is set to
+	      values, other deliver best performance when it is set to
 	      the same value as max-buffers. Minimum 16, default 128, maximum
 	      131072.
 	    </para>
@@ -333,10 +333,9 @@
 	  <listitem>
 	    <para>
 	      When the connection to the peer is lost, DRBD can either
-	      go into stand alone mode, try to reconnect to the peer or
-	      freeze all further IO requests (think of an NFS hard mount).
-	      The keywords are: <option>stand_alone</option>, 
-	      <option>reconnect</option> and <option>freeze_io</option>.
+	      go into stand alone mode, or try to reconnect to the peer.
+	      The keywords are: <option>stand_alone</option> and
+	      <option>reconnect</option>.
 	      The default handler is <option>reconnect</option>.
 	    </para>
 	  </listitem>
@@ -612,7 +611,7 @@
 
   <refsect1>
     <title>Version</title>
-    <simpara>This document is correct for version 0.7.15 of the DRBD distribution.
+    <simpara>This document is correct for version 0.7.20 of the DRBD distribution.
     </simpara>
   </refsect1>
 
@@ -629,7 +628,7 @@
   <refsect1>
     <title>Copyright</title>
     <simpara>
-      Copyright (c) 2001-2005 Philipp Reisner. This  is  free software; 
+      Copyright (c) 2001-2006 Philipp Reisner. This  is  free software; 
       see the source for copying conditions.  There is NO warranty; 
       not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     </simpara>

Modified: branches/drbd-0.7/drbd/drbd_actlog.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_actlog.c	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/drbd/drbd_actlog.c	2006-05-26 15:23:55 UTC (rev 2222)
@@ -5,9 +5,9 @@
 
    This file is part of drbd by Philipp Reisner.
 
-   Copyright (C) 2003-2004, Philipp Reisner <philipp.reisner@linbit.com>.
-   Copyright (C) 2003-2004, Lars Ellenberg <l.g.e@web.de>.
-        authors.
+   Copyright (C) 2003-2006, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2003-2006, Lars Ellenberg <lars.ellenberg@linbit.com>.
+   Copyright (C) 2003-2006, LINBIT Information Technologies GmbH.
 
    drbd is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by

Modified: branches/drbd-0.7/drbd/drbd_bitmap.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_bitmap.c	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/drbd/drbd_bitmap.c	2006-05-26 15:23:55 UTC (rev 2222)
@@ -5,12 +5,10 @@
 
    This file is part of drbd by Philipp Reisner.
 
-   Copyright (C) 2004, Lars Ellenberg <l.g.e@web.de>.
-	main author.
+   Copyright (C) 2004-2006, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2004-2006, Lars Ellenberg <lars.ellenberg@linbit.com>.
+   Copyright (C) 2004-2006, LINBIT Information Technologies GmbH.
 
-   Copyright (C) 2004, Philipp Reisner <philipp.reisner@linbit.com>.
-	contributions.
-
    drbd is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)

Modified: branches/drbd-0.7/drbd/drbd_fs.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_fs.c	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/drbd/drbd_fs.c	2006-05-26 15:23:55 UTC (rev 2222)
@@ -5,12 +5,10 @@
 
    This file is part of drbd by Philipp Reisner.
 
-   Copyright (C) 1999-2004, Philipp Reisner <philipp.reisner@linbit.com>.
-	main author.
+   Copyright (C) 1999-2006, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2006, Lars Ellenberg <lars.ellenberg@linbit.com>.
+   Copyright (C) 2001-2006, LINBIT Information Technologies GmbH.
 
-   Copyright (C) 2002-2004, Lars Ellenberg <l.g.e@web.de>.
-	main contributor.
-
    Copyright (C) 2000, Fábio Olivé Leite <olive@conectiva.com.br>.
 	Some sanity checks in IOCTL_SET_STATE.
 

Modified: branches/drbd-0.7/drbd/drbd_int.h
===================================================================
--- branches/drbd-0.7/drbd/drbd_int.h	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/drbd/drbd_int.h	2006-05-26 15:23:55 UTC (rev 2222)
@@ -4,12 +4,10 @@
 
   This file is part of drbd by Philipp Reisner.
 
-  Copyright (C) 1999-2004, Philipp Reisner <philipp.reisner@linbit.com>.
-	main author.
+  Copyright (C) 1999-2006, Philipp Reisner <philipp.reisner@linbit.com>.
+  Copyright (C) 2002-2006, Lars Ellenberg <lars.ellenberg@linbit.com>.
+  Copyright (C) 2001-2006, LINBIT Information Technologies GmbH.
 
-  Copyright (C) 2002-2004, Lars Ellenberg <l.g.e@web.de>.
-	main contributor.
-
   drbd is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)

Modified: branches/drbd-0.7/drbd/drbd_main.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_main.c	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/drbd/drbd_main.c	2006-05-26 15:23:55 UTC (rev 2222)
@@ -5,12 +5,10 @@
 
    This file is part of drbd by Philipp Reisner.
 
-   Copyright (C) 1999-2004, Philipp Reisner <philipp.reisner@linbit.com>.
-	main author.
+   Copyright (C) 1999-2006, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2006, Lars Ellenberg <lars.ellenberg@linbit.com>.
+   Copyright (C) 2001-2006, LINBIT Information Technologies GmbH.
 
-   Copyright (C) 2002-2004, Lars Ellenberg <l.g.e@web.de>.
-	main contributor.
-
    Copyright (C) 2000, Marcelo Tosatti <marcelo@conectiva.com.br>.
 	Early 2.3.x work.
 

Modified: branches/drbd-0.7/drbd/drbd_proc.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_proc.c	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/drbd/drbd_proc.c	2006-05-26 15:23:55 UTC (rev 2222)
@@ -5,12 +5,10 @@
 
    This file is part of drbd by Philipp Reisner.
 
-   Copyright (C) 1999-2004, Philipp Reisner <philipp.reisner@linbit.com>.
-	main author.
+   Copyright (C) 1999-2006, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2006, Lars Ellenberg <lars.ellenberg@linbit.com>.
+   Copyright (C) 2001-2006, LINBIT Information Technologies GmbH.
 
-   Copyright (C) 2002-2004, Lars Ellenberg <l.g.e@web.de>.
-	main contributor.
-
    drbd is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)

Modified: branches/drbd-0.7/drbd/drbd_receiver.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_receiver.c	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/drbd/drbd_receiver.c	2006-05-26 15:23:55 UTC (rev 2222)
@@ -5,12 +5,10 @@
 
    This file is part of drbd by Philipp Reisner.
 
-   Copyright (C) 1999-2004, Philipp Reisner <philipp.reisner@linbit.com>.
-	main author.
+   Copyright (C) 1999-2006, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2006, Lars Ellenberg <lars.ellenberg@linbit.com>.
+   Copyright (C) 2001-2006, LINBIT Information Technologies GmbH.
 
-   Copyright (C) 2002-2004, Lars Ellenberg <l.g.e@web.de>.
-	main contributor.
-
    drbd is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)

Modified: branches/drbd-0.7/drbd/drbd_req.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_req.c	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/drbd/drbd_req.c	2006-05-26 15:23:55 UTC (rev 2222)
@@ -5,12 +5,10 @@
 
    This file is part of drbd by Philipp Reisner.
 
-   Copyright (C) 1999-2004, Philipp Reisner <philipp.reisner@linbit.com>.
-	main author.
+   Copyright (C) 1999-2006, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2006, Lars Ellenberg <lars.ellenberg@linbit.com>.
+   Copyright (C) 2001-2006, LINBIT Information Technologies GmbH.
 
-   Copyright (C) 2002-2004, Lars Ellenberg <l.g.e@web.de>.
-	main contributor.
-
    drbd is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)

Modified: branches/drbd-0.7/drbd/drbd_worker.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_worker.c	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/drbd/drbd_worker.c	2006-05-26 15:23:55 UTC (rev 2222)
@@ -5,9 +5,9 @@
 
    This file is part of drbd by Philipp Reisner.
 
-   Copyright (C) 2003-2004, Philipp Reisner <philipp.reisner@linbit.com>.
-   Copyright (C) 2003-2004, Lars Ellenberg <l.g.e@web.de>.
-	authors.
+   Copyright (C) 1999-2006, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2006, Lars Ellenberg <lars.ellenberg@linbit.com>.
+   Copyright (C) 2001-2006, LINBIT Information Technologies GmbH.
 
    drbd is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by

Modified: branches/drbd-0.7/drbd/lru_cache.c
===================================================================
--- branches/drbd-0.7/drbd/lru_cache.c	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/drbd/lru_cache.c	2006-05-26 15:23:55 UTC (rev 2222)
@@ -5,9 +5,9 @@
 
    This file is part of drbd by Philipp Reisner.
 
-   Copyright (C) 2003-2004, Philipp Reisner <philipp.reisner@linbit.com>.
-   Copyright (C) 2003-2004, Lars Ellenberg <l.g.e@web.de>.
-        authors.
+   Copyright (C) 2003-2006, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2003-2006, Lars Ellenberg <lars.ellenberg@linbit.com>.
+   Copyright (C) 2003-2006, LINBIT Information Technologies GmbH.
 
    drbd is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by

Modified: branches/drbd-0.7/drbd/lru_cache.h
===================================================================
--- branches/drbd-0.7/drbd/lru_cache.h	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/drbd/lru_cache.h	2006-05-26 15:23:55 UTC (rev 2222)
@@ -5,8 +5,9 @@
 
    This file is part of drbd by Philipp Reisner.
 
-   Copyright (C) 2003-2004, Philipp Reisner <philipp.reisner@linbit.com>.
-        main author.
+   Copyright (C) 2003-2006, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2003-2006, Lars Ellenberg <lars.ellenberg@linbit.com>.
+   Copyright (C) 2003-2006, LINBIT Information Technologies GmbH.
 
    drbd is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by

Modified: branches/drbd-0.7/scripts/drbd.conf
===================================================================
--- branches/drbd-0.7/scripts/drbd.conf	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/scripts/drbd.conf	2006-05-26 15:23:55 UTC (rev 2222)
@@ -173,13 +173,13 @@
     # max-buffers     2048;
 
     # When the number of outstanding requests on a standby (secondary)
-    # node goes over bdev-reshold we start to kick the backing device
+    # node exceeds bdev-threshold, we start to kick the backing device
     # to start its request processing. This is an advanced tuning
     # parameter to get more performance out of capable storage controlers.
-    # Some controlers likes to be kicked often, other controlers 
-    # deliver better performance when the are kicked less frequently.
+    # Some controlers like to be kicked often, other controlers 
+    # deliver better performance when they are kicked less frequently.
     # Set it to the value of max-buffers to get the least possible
-    # number of run_task_queue_disk() calls.
+    # number of run_task_queue_disk() / q->unplug_fn(q) calls.
     #
     # bdev-treshold   128;
 
@@ -197,6 +197,9 @@
     #  "stand_alone" -> Do not reconnect (AKA StandAlone state)
     #  "freeze_io"   -> Try to reconnect but freeze all IO until
     #                   the connection is established again.
+    #  [ lge: oops. freeze_io is not implemented yet...       ]
+    #  [ at least not in drbd 0.7.x; but nobody wanted to use ]
+    #  [ that anyways, otherwise we had noticed earlier :-)   ]
     # on-disconnect reconnect;
 
   }

Modified: branches/drbd-0.7/scripts/patch-kernel
===================================================================
--- branches/drbd-0.7/scripts/patch-kernel	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/scripts/patch-kernel	2006-05-26 15:23:55 UTC (rev 2222)
@@ -6,6 +6,9 @@
 #
 # Copyright (C) 2003 Kees Cook, OSDL
 # kees@osdl.org, http://developer.osdl.org/kees/
+#
+# Copyright (C) 2003-2006 LINBIT Information Technologies GmbH
+# http://www.linbit.com
 # 
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License

Modified: branches/drbd-0.7/user/drbdadm_adjust.c
===================================================================
--- branches/drbd-0.7/user/drbdadm_adjust.c	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/user/drbdadm_adjust.c	2006-05-26 15:23:55 UTC (rev 2222)
@@ -3,7 +3,7 @@
 
    This file is part of drbd by Philipp Reisner.
 
-   Copyright (C) 2003-2004, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2003-2006, Philipp Reisner <philipp.reisner@linbit.com>.
         Initial author.
 
    drbd is free software; you can redistribute it and/or modify

Modified: branches/drbd-0.7/user/drbdadm_main.c
===================================================================
--- branches/drbd-0.7/user/drbdadm_main.c	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/user/drbdadm_main.c	2006-05-26 15:23:55 UTC (rev 2222)
@@ -3,12 +3,10 @@
 
    This file is part of drbd by Philipp Reisner.
 
-   Copyright (C) 2002-2004, Philipp Reisner <philipp.reisner@linbit.com>.
-        Initial author.
+   Copyright (C) 2002-2006, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2006, Lars Ellenberg <lars.ellenberg@linbit.com>.
+   Copyright (C) 2002-2006, LINBIT Information Technologies GmbH.
 
-   Copyright (C) 2003-2004, Lars Ellenberg <l.g.e@web.de>
-        contributions.
-
    drbd is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)

Modified: branches/drbd-0.7/user/drbdsetup.c
===================================================================
--- branches/drbd-0.7/user/drbdsetup.c	2006-05-26 14:21:51 UTC (rev 2221)
+++ branches/drbd-0.7/user/drbdsetup.c	2006-05-26 15:23:55 UTC (rev 2222)
@@ -3,15 +3,13 @@
 
    This file is part of drbd by Philipp Reisner.
 
-   Copyright (C) 1999-2004, Philipp Reisner <philipp.reisner@linbit.com>.
-        Initial author.
+   Copyright (C) 1999-2006, Philipp Reisner <philipp.reisner@linbit.com>.
+   Copyright (C) 2002-2006, Lars Ellenberg <lars.ellenberg@linbit.com>.
+   Copyright (C) 2001-2006, LINBIT Information Technologies GmbH.
 
    Copyright (C) 2000, Fábio Olivé Leite <olive@conectiva.com.br>.
         Added sanity checks before using the device.
 
-   Copyright (C) 2002-2004, Lars Ellenberg <l.g.e@web.de>
-	main contributor.
-
    drbd is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)

From drbd-cvs at lists.linbit.com  Fri May 26 17:25:17 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri May 26 17:25:19 2006
Subject: [DRBD-cvs] svn commit by lars - r2223 - branches/drbd-0.7 - how can
	keyword substitution work if you don't use the 
Message-ID: <20060526152517.4ED482E411@mail.linbit.com>

Author: lars
Date: 2006-05-26 17:25:16 +0200 (Fri, 26 May 2006)
New Revision: 2223

Modified:
   branches/drbd-0.7/ChangeLog
Log:
how can keyword substitution work if you don't use the right keywords...

Modified: branches/drbd-0.7/ChangeLog
===================================================================
--- branches/drbd-0.7/ChangeLog	2006-05-26 15:23:55 UTC (rev 2222)
+++ branches/drbd-0.7/ChangeLog	2006-05-26 15:25:16 UTC (rev 2223)
@@ -1,6 +1,6 @@
 Latest:
 ------
- ChangeLog last updated: $LastChangedRev$ $LastChangedDate$
+ ChangeLog last updated: $LastChangedRevision$ $LastChangedDate$
  Cumulative changes since last tarball.
  For even more detail, use "svn log" and "svn diff".
 


Property changes on: branches/drbd-0.7/ChangeLog
___________________________________________________________________
Name: svn:keywords
   - LastChangedRev LastChangedDate
   + LastChangedRevision LastChangedDate

From drbd-cvs at lists.linbit.com  Fri May 26 17:26:10 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri May 26 17:26:11 2006
Subject: [DRBD-cvs] svn commit by lars - r2224 - branches/drbd-0.7 - keyword
	substititution again
Message-ID: <20060526152610.194032E411@mail.linbit.com>

Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Author: lars
Date: 2006-05-26 17:26:09 +0200 (Fri, 26 May 2006)
New Revision: 2224

Modified:
   branches/drbd-0.7/ChangeLog
Log:
keyword substititution again

Modified: branches/drbd-0.7/ChangeLog
===================================================================
--- branches/drbd-0.7/ChangeLog	2006-05-26 15:25:16 UTC (rev 2223)
+++ branches/drbd-0.7/ChangeLog	2006-05-26 15:26:09 UTC (rev 2224)
@@ -1,6 +1,8 @@
 Latest:
 ------
- ChangeLog last updated: $LastChangedRevision$ $LastChangedDate$
+ ChangeLog last updated: $LastChangedRevision$
+ $LastChangedDate$
+
  Cumulative changes since last tarball.
  For even more detail, use "svn log" and "svn diff".
 

From drbd-cvs at lists.linbit.com  Tue May 30 23:44:20 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May 30 23:44:23 2006
Subject: [DRBD-cvs] svn commit by lars - r2225 - in branches/drbd-0.7:
	documentation drbd drbd/linux scripts user - oh well.
	treshold != threshold; 
Message-ID: <20060530214420.9C0282F0E0@mail.linbit.com>

btw, can we please name
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Author: lars
Date: 2006-05-30 23:44:18 +0200 (Tue, 30 May 2006)
New Revision: 2225

Modified:
   branches/drbd-0.7/documentation/drbd.conf.sgml
   branches/drbd-0.7/documentation/drbdsetup.sgml
   branches/drbd-0.7/drbd/drbd_receiver.c
   branches/drbd-0.7/drbd/linux/drbd.h
   branches/drbd-0.7/drbd/mempool-2.4.c
   branches/drbd-0.7/scripts/drbd.conf
   branches/drbd-0.7/user/drbd_limits.h
   branches/drbd-0.7/user/drbdadm_adjust.c
   branches/drbd-0.7/user/drbdadm_parser.y
   branches/drbd-0.7/user/drbdadm_scanner.fl
   branches/drbd-0.7/user/drbdsetup.c
Log:
oh well. treshold != threshold;
btw, can we please name this 'unplug-watermark'?
what would probably be a block device threshold...

we also need to implement hysteresis,
so we won't keep kicking every other request,
once we exceed the threshold...



Modified: branches/drbd-0.7/documentation/drbd.conf.sgml
===================================================================
--- branches/drbd-0.7/documentation/drbd.conf.sgml	2006-05-26 15:26:09 UTC (rev 2224)
+++ branches/drbd-0.7/documentation/drbd.conf.sgml	2006-05-30 21:44:18 UTC (rev 2225)
@@ -175,7 +175,7 @@
     <option>sndbuf-size</option>, <option>timeout</option>,
     <option>connect-int</option>, <option>ping-int</option>,
     <option>max-buffers</option>, <option>max-epoch-size</option>,
-    <option>bdev-treshold</option>,
+    <option>bdev-threshold</option>,
     <option>ko-count</option>, <option>on-disconnect</option>.
   </para>
   </listitem>
@@ -428,11 +428,11 @@
 </varlistentry>
 
 <varlistentry>
-  <term><option>bdev-treshold <replaceable>number</replaceable></option></term>
+  <term><option>bdev-threshold <replaceable>number</replaceable></option></term>
   <listitem>
     <para>
       When the number of pending write requests on the standby
-      (secondary) node exceeds the bdev-treshold, we trigger
+      (secondary) node exceeds the bdev-threshold, we trigger
       the request processing of our backing storage device.
       Some storage controllers deliver better performance with small
       values, other deliver best performance when it is set to

Modified: branches/drbd-0.7/documentation/drbdsetup.sgml
===================================================================
--- branches/drbd-0.7/documentation/drbdsetup.sgml	2006-05-26 15:26:09 UTC (rev 2224)
+++ branches/drbd-0.7/documentation/drbdsetup.sgml	2006-05-30 21:44:18 UTC (rev 2225)
@@ -314,11 +314,11 @@
 	</varlistentry>
 	<varlistentry>
 	  <term><option>-l</option>,
-	  <option>--bdev-treshold <replaceable>val</replaceable></option></term>
+	  <option>--bdev-threshold <replaceable>val</replaceable></option></term>
 	  <listitem>
 	    <para>
 	      When the number of pending write requests on the standby
-	      (secondary) node exceeds the bdev-treshold, we trigger
+	      (secondary) node exceeds the bdev-threshold, we trigger
 	      the request processing of our backing storage device.
 	      Some storage controllers deliver better performance with small
 	      values, other deliver best performance when it is set to

Modified: branches/drbd-0.7/drbd/drbd_receiver.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_receiver.c	2006-05-26 15:26:09 UTC (rev 2224)
+++ branches/drbd-0.7/drbd/drbd_receiver.c	2006-05-30 21:44:18 UTC (rev 2225)
@@ -300,7 +300,7 @@
 	MUST_HOLD(&mdev->ee_lock);
 
 	if(mdev->ee_vacant == EE_MININUM / 2 && 
-	   (mdev->conf.bdev_treshold != mdev->conf.max_buffers) ) {
+	   (mdev->conf.bdev_threshold != mdev->conf.max_buffers) ) {
 		spin_unlock_irq(&mdev->ee_lock);
 		drbd_kick_lo(mdev);
 		spin_lock_irq(&mdev->ee_lock);
@@ -903,7 +903,7 @@
 	 * reference counts on it, which typically are locally submitted io
 	 * requests.  don't use unacked_cnt, so we speed up proto A and B, too.
 	 */
-	if (atomic_read(&mdev->local_cnt) >= mdev->conf.bdev_treshold ) {
+	if (atomic_read(&mdev->local_cnt) >= mdev->conf.bdev_threshold ) {
 		drbd_kick_lo(mdev);
 	}
 	mdev->writ_cnt+=data_size>>9;

Modified: branches/drbd-0.7/drbd/linux/drbd.h
===================================================================
--- branches/drbd-0.7/drbd/linux/drbd.h	2006-05-26 15:26:09 UTC (rev 2224)
+++ branches/drbd-0.7/drbd/linux/drbd.h	2006-05-30 21:44:18 UTC (rev 2225)
@@ -93,7 +93,7 @@
 	IN int      ping_int;         /* seconds */
 	IN int      max_epoch_size;
 	IN int      max_buffers;
-	IN int      bdev_treshold;
+	IN int      bdev_threshold;
 	IN int      sndbuf_size;  /* socket send buffer size */
 	IN unsigned int ko_count;
 	IN enum disconnect_handler on_disconnect;

Modified: branches/drbd-0.7/drbd/mempool-2.4.c
===================================================================
--- branches/drbd-0.7/drbd/mempool-2.4.c	2006-05-26 15:26:09 UTC (rev 2224)
+++ branches/drbd-0.7/drbd/mempool-2.4.c	2006-05-30 21:44:18 UTC (rev 2225)
@@ -145,7 +145,7 @@
 	spin_unlock_irqrestore(&pool->lock, flags);
 
 	/*
-	 * We refill the pool up to the new treshold - but we dont
+	 * We refill the pool up to the new threshold - but we dont
 	 * (cannot) guarantee that the refill succeeds.
 	 */
 	while (delta) {

Modified: branches/drbd-0.7/scripts/drbd.conf
===================================================================
--- branches/drbd-0.7/scripts/drbd.conf	2006-05-26 15:26:09 UTC (rev 2224)
+++ branches/drbd-0.7/scripts/drbd.conf	2006-05-30 21:44:18 UTC (rev 2225)
@@ -181,7 +181,7 @@
     # Set it to the value of max-buffers to get the least possible
     # number of run_task_queue_disk() / q->unplug_fn(q) calls.
     #
-    # bdev-treshold   128;
+    # bdev-threshold   128;
 
 
     # The highest number of data blocks between two write barriers. 

Modified: branches/drbd-0.7/user/drbd_limits.h
===================================================================
--- branches/drbd-0.7/user/drbd_limits.h	2006-05-26 15:26:09 UTC (rev 2224)
+++ branches/drbd-0.7/user/drbd_limits.h	2006-05-30 21:44:18 UTC (rev 2225)
@@ -53,7 +53,7 @@
   RANGE(MAX_BUFFERS, 32, 131072);
 
   /* @4k PageSize -> 64kB - 512MB */
-  RANGE(BDEV_TRESHOLD, 16, 131072);
+  RANGE(BDEV_THRESHOLD, 16, 131072);
 
   /* 0 is disabled.
    * 200 should be more than enough even for very short timeouts */

Modified: branches/drbd-0.7/user/drbdadm_adjust.c
===================================================================
--- branches/drbd-0.7/user/drbdadm_adjust.c	2006-05-26 15:26:09 UTC (rev 2224)
+++ branches/drbd-0.7/user/drbdadm_adjust.c	2006-05-30 21:44:18 UTC (rev 2225)
@@ -337,7 +337,7 @@
     do_connect |= check_opt_d(in,"ping-int",1,"sec",res->net_options);
     do_connect |= check_opt_d(in,"max-epoch-size",1,"",res->net_options);
     do_connect |= check_opt_d(in,"max-buffers",1,"",res->net_options);
-    do_connect |= check_opt_d(in,"bdev-treshold",1,"",res->net_options);
+    do_connect |= check_opt_d(in,"bdev-threshold",1,"",res->net_options);
     do_connect |= check_opt_d(in,"sndbuf-size",1,"",res->net_options);
     do_connect |= check_opt_d(in,"ko-count",1,"",res->net_options);
     do_connect |= check_opt_s(in,"on-disconnect",res->net_options);

Modified: branches/drbd-0.7/user/drbdadm_parser.y
===================================================================
--- branches/drbd-0.7/user/drbdadm_parser.y	2006-05-26 15:26:09 UTC (rev 2224)
+++ branches/drbd-0.7/user/drbdadm_parser.y	2006-05-30 21:44:18 UTC (rev 2225)
@@ -144,7 +144,7 @@
   R_CONNECT_INT,
   R_PING_INT,
   R_MAX_BUFFERS,
-  R_BDEV_TRESHOLD,
+  R_BDEV_THRESHOLD,
   R_MAX_EPOCH_SIZE,
   R_SNDBUF_SIZE,
   R_KO_COUNT,
@@ -193,9 +193,9 @@
       m_strtoll_range(value, 1, name, DRBD_MAX_BUFFERS_MIN,
 		      DRBD_MAX_BUFFERS_MAX);
       break;
-    case R_BDEV_TRESHOLD:
-      m_strtoll_range(value, 1, name, DRBD_BDEV_TRESHOLD_MIN,
-		      DRBD_BDEV_TRESHOLD_MAX);
+    case R_BDEV_THRESHOLD:
+      m_strtoll_range(value, 1, name, DRBD_BDEV_THRESHOLD_MIN,
+		      DRBD_BDEV_THRESHOLD_MAX);
       break;
     case R_MAX_EPOCH_SIZE:
       m_strtoll_range(value, 1, name, DRBD_MAX_EPOCH_SIZE_MIN,
@@ -333,7 +333,7 @@
 %token <txt> TK_MINOR_COUNT TK_INTEGER TK_STRING
 %token <txt> TK_ON_IO_ERROR TK_SIZE
 %token <txt> TK_TIMEOUT TK_CONNECT_INT TK_PING_INT TK_MAX_BUFFERS TK_IPADDR
-%token <txt> TK_BDEV_TRESHOLD TK_MAX_EPOCH_SIZE TK_SNDBUF_SIZE
+%token <txt> TK_BDEV_THRESHOLD TK_MAX_EPOCH_SIZE TK_SNDBUF_SIZE
 %token <txt> TK_SKIP_SYNC TK_USE_CSUMS TK_RATE TK_SYNC_GROUP TK_AL_EXTENTS
 %token <txt> TK_WFC_TIMEOUT TK_DEGR_WFC_TIMEOUT
 %token <txt> TK_KO_COUNT TK_ON_DISCONNECT TK_DIALOG_REFRESH
@@ -457,8 +457,8 @@
 		{ range_check(R_PING_INT,$1,$2);	$$=new_opt($1,$2); }
 		| TK_MAX_BUFFERS    TK_INTEGER
 		{ range_check(R_MAX_BUFFERS,$1,$2);	$$=new_opt($1,$2); }
-		| TK_BDEV_TRESHOLD    TK_INTEGER
-		{ range_check(R_BDEV_TRESHOLD,$1,$2);	$$=new_opt($1,$2); }
+		| TK_BDEV_THRESHOLD    TK_INTEGER
+		{ range_check(R_BDEV_THRESHOLD,$1,$2);	$$=new_opt($1,$2); }
 		| TK_MAX_EPOCH_SIZE TK_INTEGER
 		{ range_check(R_MAX_EPOCH_SIZE,$1,$2);	$$=new_opt($1,$2); }
 		| TK_SNDBUF_SIZE    TK_INTEGER

Modified: branches/drbd-0.7/user/drbdadm_scanner.fl
===================================================================
--- branches/drbd-0.7/user/drbdadm_scanner.fl	2006-05-26 15:26:09 UTC (rev 2224)
+++ branches/drbd-0.7/user/drbdadm_scanner.fl	2006-05-30 21:44:18 UTC (rev 2225)
@@ -258,11 +258,11 @@
   ping-int		do_assign(NUM);   CP; return TK_PING_INT;
   connect-int		do_assign(NUM);   CP; return TK_CONNECT_INT;
   max-buffers		do_assign(NUM);   CP; return TK_MAX_BUFFERS;
-  bdev-treshold		do_assign(NUM);   CP; return TK_BDEV_TRESHOLD;
+  bdev-threshold		do_assign(NUM);   CP; return TK_BDEV_THRESHOLD;
   max-epoch-size	do_assign(NUM);   CP; return TK_MAX_EPOCH_SIZE;
   ko-count		do_assign(NUM);   CP; return TK_KO_COUNT;
   on-disconnect 	do_assign(ON_DISCONNECT); CP; return TK_ON_DISCONNECT;
-  {NDELIM}		expect_error("one of 'sndbuf-size|timeout|ping-int|connect-int|max-buffers|bdev-treshold|max-epoch-size|ko-count|on-disconnect'");
+  {NDELIM}		expect_error("one of 'sndbuf-size|timeout|ping-int|connect-int|max-buffers|bdev-threshold|max-epoch-size|ko-count|on-disconnect'");
 }
 
 <SYNCER>{

Modified: branches/drbd-0.7/user/drbdsetup.c
===================================================================
--- branches/drbd-0.7/user/drbdsetup.c	2006-05-26 15:26:09 UTC (rev 2224)
+++ branches/drbd-0.7/user/drbdsetup.c	2006-05-30 21:44:18 UTC (rev 2225)
@@ -68,7 +68,7 @@
 #define DEF_ON_IO_ERROR         PassOn
 #define DEF_KO_COUNT                 0
 #define DEF_ON_DISCONNECT       Reconnect
-#define DEF_BDEV_TRESHOLD       (DEF_MAX_BUFFERS/16)
+#define DEF_BDEV_THRESHOLD       (DEF_MAX_BUFFERS/16)
 
 #if 0
 # define ioctl(X...) (fprintf(stderr,"ioctl(%s)\n",#X),0);
@@ -156,7 +156,7 @@
      { "timeout",    required_argument, 0, 't' },
      { "max-epoch-size", required_argument, 0, 'e' },
      { "max-buffers",required_argument, 0, 'b' },
-     { "bdev-treshold",required_argument, 0, 'l' },
+     { "bdev-threshold",required_argument, 0, 'l' },
      { "connect-int",required_argument, 0, 'c' },
      { "ping-int",   required_argument, 0, 'i' },
      { "sndbuf-size",required_argument, 0, 'S' },
@@ -562,7 +562,7 @@
   cn->config.sndbuf_size = DEF_SNDBUF_SIZE ;
   cn->config.on_disconnect = DEF_ON_DISCONNECT;
   cn->config.ko_count = DEF_KO_COUNT;
-  cn->config.bdev_treshold = DEF_BDEV_TRESHOLD;
+  cn->config.bdev_threshold = DEF_BDEV_THRESHOLD;
 
   if(argc==0) return 0;
 
@@ -590,8 +590,8 @@
 			  DRBD_MAX_BUFFERS_MIN, DRBD_MAX_BUFFERS_MAX);
 	  break;
 	case 'l':
-	  cn->config.bdev_treshold = m_strtoll_range(optarg,1, "bdev-treshold",
-			  DRBD_BDEV_TRESHOLD_MIN, DRBD_BDEV_TRESHOLD_MAX);
+	  cn->config.bdev_threshold = m_strtoll_range(optarg,1, "bdev-threshold",
+			  DRBD_BDEV_THRESHOLD_MIN, DRBD_BDEV_THRESHOLD_MAX);
 	  break;
 	case 'c':
 	  cn->config.try_connect_int = m_strtoll_range(optarg,1, "connect-int",
@@ -1350,7 +1350,7 @@
   SHOW_I("ping-int","sec", cn.nconf.ping_int, DEF_NET_PING_I);
   SHOW_I("max-epoch-size","", cn.nconf.max_epoch_size, DEF_MAX_EPOCH_SIZE);
   SHOW_I("max-buffers","", cn.nconf.max_buffers, DEF_MAX_BUFFERS);
-  SHOW_I("bdev-threshold","", cn.nconf.bdev_treshold, DEF_BDEV_TRESHOLD);
+  SHOW_I("bdev-threshold","", cn.nconf.bdev_threshold, DEF_BDEV_THRESHOLD);
   SHOW_I("sndbuf-size","", cn.nconf.sndbuf_size, DEF_SNDBUF_SIZE);
   SHOW_I("ko-count","", cn.nconf.ko_count, DEF_KO_COUNT);
   if( cn.nconf.on_disconnect != DEF_ON_DISCONNECT) {

From drbd-cvs at lists.linbit.com  Tue May 30 23:47:37 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue May 30 23:47:38 2006
Subject: [DRBD-cvs] svn commit by lars - r2226 - in branches/drbd-0.7: drbd
	scripts user - fix the drbd_get_ee thing.
Message-ID: <20060530214737.1E49D2F0E0@mail.linbit.com>

this is basically a copy fro
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Author: lars
Date: 2006-05-30 23:47:36 +0200 (Tue, 30 May 2006)
New Revision: 2226

Modified:
   branches/drbd-0.7/drbd/drbd_receiver.c
   branches/drbd-0.7/scripts/drbd.conf
   branches/drbd-0.7/user/drbdadm_parser.y
   branches/drbd-0.7/user/drbdadm_scanner.fl
Log:

fix the drbd_get_ee thing.
this is basically a copy from the drbd-plus branch.

this also fixes some whitespace of the previous t(h)reshold patch...



Modified: branches/drbd-0.7/drbd/drbd_receiver.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_receiver.c	2006-05-30 21:44:18 UTC (rev 2225)
+++ branches/drbd-0.7/drbd/drbd_receiver.c	2006-05-30 21:47:36 UTC (rev 2226)
@@ -145,7 +145,6 @@
  _drbd_process_ee()
 
 You must not have the ee_lock:
- _drbd_alloc_ee()
  drbd_alloc_ee()
  drbd_init_ee()
  drbd_release_ee()
@@ -155,89 +154,90 @@
  drbd_wait_ee()
 */
 
-STATIC int _drbd_alloc_ee(drbd_dev *mdev,struct page* page,int mask)
+/*
+ * gfp_mask is only used for the page allocation,
+ * not for the kmem_cache_alloc, which is hardcoded to
+ * basically GFP_NOIO, see below.
+ *
+ * THIS MUST NOT HOLD A LOCK
+ */
+struct Tl_epoch_entry*
+drbd_try_alloc_ee(drbd_dev *mdev, int gfp_mask)
 {
 	struct Tl_epoch_entry* e;
+	struct page *page = alloc_page(gfp_mask);
 
-	/* kmem_cache does not like to mix different memory types.
-	 * so even if we alloc'ed the page from HIGHMEM,
-	 * the ee comes from normal memory.
-	 */
-	e = kmem_cache_alloc(drbd_ee_cache, mask & ~(__GFP_HIGHMEM));
-	if( e == NULL ) return FALSE;
-
-	drbd_ee_init(e,page);
-	spin_lock_irq(&mdev->ee_lock);
-	list_add(&e->w.list,&mdev->free_ee);
-	mdev->ee_vacant++;
-	spin_unlock_irq(&mdev->ee_lock);
-
-	return TRUE;
-}
-
-/* bool */
-STATIC int drbd_alloc_ee(drbd_dev *mdev,int mask)
-{
-	struct page *page;
-
-	page=alloc_page(mask);
-	if(!page) return FALSE;
-
+	if (!page) return NULL;
 	/* if we got the page, we really want the ee, too,
 	 * even for "GFP_TRY".
 	 * we may wait, but better not cause IO,
 	 * we might be in the IO path (of our peer).
+	 *
+	 * kmem_cache does not like to mix different memory types.
+	 * so even if we alloc'ed the page from HIGHMEM,
+	 * the ee comes from normal memory.
 	 */
-	if(!_drbd_alloc_ee(mdev,page,mask | GFP_NOIO)) {
-		__free_page(page);
-		return FALSE;
-	}
+	e = kmem_cache_alloc(drbd_ee_cache, (gfp_mask|GFP_NOIO) & ~(__GFP_HIGHMEM));
 
-	return TRUE;
+	if (e) drbd_ee_init(e,page);
+	else  __free_page(page);
+
+	return e;
 }
 
-STATIC struct page* drbd_free_ee(drbd_dev *mdev, struct list_head *list)
+/*
+ * just free the ee and the associated page.
+ * no accounting here, no list movement, nothing.
+ */
+void drbd_free_ee(drbd_dev *mdev, struct Tl_epoch_entry *e)
 {
-	struct list_head *le;
-	struct Tl_epoch_entry* e;
-	struct page* page;
-
-	MUST_HOLD(&mdev->ee_lock);
-
-	D_ASSERT(!list_empty(list));
-	le = list->next;
-	e = list_entry(le, struct Tl_epoch_entry, w.list);
-	list_del(le);
-
-	page = drbd_bio_get_page(&e->private_bio);
+	struct page *page = drbd_bio_get_page(&e->private_bio);
 ONLY_IN_26(
 	D_ASSERT(page == e->ee_bvec.bv_page);
-	page = e->ee_bvec.bv_page;
+	page = e->ee_bvec.bv_page;		/* just in case */
 )
+	__free_page(page);
 	kmem_cache_free(drbd_ee_cache, e);
-	mdev->ee_vacant--;
-
-	return page;
 }
 
+/* XXX currently only called on module init.
+ * actually we do not need to care about spinlocks.
+ */
 int drbd_init_ee(drbd_dev *mdev)
 {
-	while(mdev->ee_vacant < EE_MININUM ) {
-		if(!drbd_alloc_ee(mdev,GFP_USER)) {
+	LIST_HEAD(tmp);
+	struct Tl_epoch_entry *e;
+	int i;
+
+	for (i = 0; i < EE_MININUM; i++) {
+		e = drbd_try_alloc_ee(mdev,GFP_HIGHUSER);
+		if (!e) {
 			ERR("Failed to allocate %d EEs !\n",EE_MININUM);
-			return 0;
+			break;
 		}
+		list_add(&e->w.list,&tmp);
 	}
-	return 1;
+
+	spin_lock_irq(&mdev->ee_lock);
+	list_splice(&tmp,&mdev->free_ee);
+	mdev->ee_vacant += i;
+	spin_unlock_irq(&mdev->ee_lock);
+
+	return (i == EE_MININUM);
 }
 
 int drbd_release_ee(drbd_dev *mdev,struct list_head* list)
 {
 	int count=0;
+	struct Tl_epoch_entry *e;
+	struct list_head *le, *tmp;
 
 	spin_lock_irq(&mdev->ee_lock);
-	while(!list_empty(list)) {
-		__free_page(drbd_free_ee(mdev,list));
+	list_for_each_safe(le,tmp,list) {
+		list_del(le);
+		e = list_entry(le, struct Tl_epoch_entry, w.list);
+		drbd_free_ee(mdev,e);
+		mdev->ee_vacant--;
 		count++;
 	}
 	spin_unlock_irq(&mdev->ee_lock);
@@ -288,13 +288,16 @@
 #endif
 
 /**
- * drbd_get_ee: Returns an Tl_epoch_entry; might sleep. Fails only if
- * a signal comes in.
+ * drbd_get_ee:
+ * Returns an Tl_epoch_entry; might sleep. Fails only if a signal comes in.
+ *
+ * We do not do this straight forward, because we don't want to consume
+ * too much memory: the upper bound is mdev->conf.max_buffers.
  */
 struct Tl_epoch_entry* drbd_get_ee(drbd_dev *mdev)
 {
 	struct list_head *le;
-	struct Tl_epoch_entry* e;
+	struct Tl_epoch_entry* e = NULL;
 	DEFINE_WAIT(wait);
 
 	MUST_HOLD(&mdev->ee_lock);
@@ -308,49 +311,50 @@
 
 	if(list_empty(&mdev->free_ee)) _drbd_process_ee(mdev,1);
 
-	if(list_empty(&mdev->free_ee)) {
-		for (;;) {
-			prepare_to_wait(&mdev->ee_wait, &wait, 
-					TASK_INTERRUPTIBLE);
-			if(!list_empty(&mdev->free_ee)) break;
+	while (list_empty(&mdev->free_ee)) {
+		if( mdev->conf.max_buffers >
+		    mdev->ee_vacant + mdev->ee_in_use )
+		{
 			spin_unlock_irq(&mdev->ee_lock);
-			if( ( mdev->ee_vacant+mdev->ee_in_use) < 
-			      mdev->conf.max_buffers ) {
-				if(drbd_alloc_ee(mdev,GFP_TRY)) {
-	/* race race race
-	 * (currently harmless for drbd07, since drbd_get_ee is called by
-	 * receiver_thread only. solved with different implementation in
-	 * drbd-plus already.)
-	 */
-					spin_lock_irq(&mdev->ee_lock);
-					break;
-				}
-			}
-			drbd_kick_lo(mdev);
-			schedule();
+			e = drbd_try_alloc_ee(mdev,GFP_TRY);
 			spin_lock_irq(&mdev->ee_lock);
-			finish_wait(&mdev->ee_wait, &wait);
-			if (signal_pending(current)) {
-				WARN("drbd_get_ee interrupted!\n");
-				return 0;
-			}
-			// finish wait is inside, so that we are TASK_RUNNING 
-			// in _drbd_process_ee (which might sleep by itself.)
-			_drbd_process_ee(mdev,1);
+			if (e) goto got_new_ee;
 		}
-		finish_wait(&mdev->ee_wait, &wait); 
+
+		prepare_to_wait(&mdev->ee_wait, &wait, TASK_INTERRUPTIBLE);
+		if (!list_empty(&mdev->free_ee)) break;
+
+		spin_unlock_irq(&mdev->ee_lock);
+
+		drbd_kick_lo(mdev);
+		schedule();
+
+		// finish wait is inside, so that we are TASK_RUNNING
+		// in _drbd_process_ee (which might sleep by itself.)
+		finish_wait(&mdev->ee_wait, &wait);
+
+		spin_lock_irq(&mdev->ee_lock);
+
+		if (signal_pending(current)) {
+			WARN("drbd_get_ee interrupted!\n");
+			return NULL;
+		}
+
+		_drbd_process_ee(mdev,1);
 	}
+	/* no-op when &wait has not been touched */
+	finish_wait(&mdev->ee_wait, &wait);
 
-	/* race race race */
-	le=mdev->free_ee.next;
+	le = mdev->free_ee.next;
 	list_del(le);
 	mdev->ee_vacant--;
-	mdev->ee_in_use++;
 	e=list_entry(le, struct Tl_epoch_entry, w.list);
 ONLY_IN_26(
 	D_ASSERT(e->private_bio.bi_idx == 0);
 	drbd_ee_init(e,e->ee_bvec.bv_page); // reinitialize
 )
+  got_new_ee:
+	mdev->ee_in_use++;
 	e->block_id = !ID_VACANT;
 	SET_MAGIC(e);
 	return e;
@@ -358,27 +362,30 @@
 
 void drbd_put_ee(drbd_dev *mdev,struct Tl_epoch_entry *e)
 {
-	struct page* page;
-
 	MUST_HOLD(&mdev->ee_lock);
 
 	D_ASSERT(page_count(drbd_bio_get_page(&e->private_bio)) == 1);
 
 	mdev->ee_in_use--;
-	mdev->ee_vacant++;
 	e->block_id = ID_VACANT;
 	INVALIDATE_MAGIC(e);
-	list_add_tail(&e->w.list,&mdev->free_ee);
 
-	if((mdev->ee_vacant * 2 > mdev->ee_in_use ) &&
-	   ( mdev->ee_vacant + mdev->ee_in_use > EE_MININUM) ) {
-		// FIXME cleanup: never returns NULL anymore
-		page=drbd_free_ee(mdev,&mdev->free_ee);
-		if( page ) __free_page(page);
+	if ( (mdev->ee_vacant * 2 > mdev->ee_in_use) &&
+	     (mdev->ee_vacant + mdev->ee_in_use > EE_MININUM) ) {
+		drbd_free_ee(mdev,e);
+	} else {
+		list_add_tail(&e->w.list,&mdev->free_ee);
+		mdev->ee_vacant++;
 	}
-	if(mdev->ee_in_use == 0) {
-		while( mdev->ee_vacant > EE_MININUM ) {
-			__free_page(drbd_free_ee(mdev,&mdev->free_ee));
+	if (mdev->ee_in_use == 0) {
+		struct Tl_epoch_entry *e;
+		struct list_head *le, *tmp;
+		list_for_each_safe(le,tmp,&mdev->free_ee) {
+			if (mdev->ee_vacant <= EE_MININUM) break;
+			list_del(le);
+			e = list_entry(le, struct Tl_epoch_entry, w.list);
+			drbd_free_ee(mdev,e);
+			mdev->ee_vacant--;
 		}
 	}
 
@@ -1225,7 +1232,9 @@
 		if (!drbd_rs_begin_io(mdev,sector)) {
 			// we have been interrupted, probably connection lost!
 			D_ASSERT(signal_pending(current));
+			spin_lock_irq(&mdev->ee_lock);
 			drbd_put_ee(mdev,e);
+			spin_unlock_irq(&mdev->ee_lock);
 			return 0;
 		}
 		break;

Modified: branches/drbd-0.7/scripts/drbd.conf
===================================================================
--- branches/drbd-0.7/scripts/drbd.conf	2006-05-30 21:44:18 UTC (rev 2225)
+++ branches/drbd-0.7/scripts/drbd.conf	2006-05-30 21:47:36 UTC (rev 2226)
@@ -97,9 +97,9 @@
   # C: write IO is reported as completed, if we know it has
   #    reached _both_ local and remote DISK.
   #    * for critical transactional data.
+  #    * for most cases.
   # B: write IO is reported as completed, if it has reached
   #    local DISK and remote buffer cache.
-  #    * for most cases.
   # A: write IO is reported as completed, if it has reached
   #    local DISK and local tcp send buffer. (see also sndbuf-size)
   #    * for high latency networks

Modified: branches/drbd-0.7/user/drbdadm_parser.y
===================================================================
--- branches/drbd-0.7/user/drbdadm_parser.y	2006-05-30 21:44:18 UTC (rev 2225)
+++ branches/drbd-0.7/user/drbdadm_parser.y	2006-05-30 21:47:36 UTC (rev 2226)
@@ -457,7 +457,7 @@
 		{ range_check(R_PING_INT,$1,$2);	$$=new_opt($1,$2); }
 		| TK_MAX_BUFFERS    TK_INTEGER
 		{ range_check(R_MAX_BUFFERS,$1,$2);	$$=new_opt($1,$2); }
-		| TK_BDEV_THRESHOLD    TK_INTEGER
+		| TK_BDEV_THRESHOLD TK_INTEGER
 		{ range_check(R_BDEV_THRESHOLD,$1,$2);	$$=new_opt($1,$2); }
 		| TK_MAX_EPOCH_SIZE TK_INTEGER
 		{ range_check(R_MAX_EPOCH_SIZE,$1,$2);	$$=new_opt($1,$2); }

Modified: branches/drbd-0.7/user/drbdadm_scanner.fl
===================================================================
--- branches/drbd-0.7/user/drbdadm_scanner.fl	2006-05-30 21:44:18 UTC (rev 2225)
+++ branches/drbd-0.7/user/drbdadm_scanner.fl	2006-05-30 21:47:36 UTC (rev 2226)
@@ -258,7 +258,7 @@
   ping-int		do_assign(NUM);   CP; return TK_PING_INT;
   connect-int		do_assign(NUM);   CP; return TK_CONNECT_INT;
   max-buffers		do_assign(NUM);   CP; return TK_MAX_BUFFERS;
-  bdev-threshold		do_assign(NUM);   CP; return TK_BDEV_THRESHOLD;
+  bdev-threshold	do_assign(NUM);   CP; return TK_BDEV_THRESHOLD;
   max-epoch-size	do_assign(NUM);   CP; return TK_MAX_EPOCH_SIZE;
   ko-count		do_assign(NUM);   CP; return TK_KO_COUNT;
   on-disconnect 	do_assign(ON_DISCONNECT); CP; return TK_ON_DISCONNECT;

