From drbd-cvs at lists.linbit.com  Thu Feb  2 18:43:40 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu Feb  2 18:43:41 2006
Subject: [DRBD-cvs] svn commit by phil - r2058 - trunk/user - Fixed the dump
	/ restore for v07 meta-data in drbdmeta 
Message-ID: <20060202174340.7965B1628F@mail.linbit.com>

Author: phil
Date: 2006-02-02 18:43:39 +0100 (Thu, 02 Feb 2006)
New Revision: 2058

Modified:
   trunk/user/drbdmeta.c
Log:
Fixed the dump / restore for v07 meta-data in drbdmeta



Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2006-01-31 14:54:35 UTC (rev 2057)
+++ trunk/user/drbdmeta.c	2006-02-02 17:43:39 UTC (rev 2058)
@@ -1644,7 +1644,7 @@
 	if (format_version(cfg) < Drbd_08) {
 		printf("gc {\n   ");
 		for (i = 0; i < GEN_CNT_SIZE; i++) {
-			printf(" 0x%X;", cfg->md.gc[i]);
+			printf(" %d;", cfg->md.gc[i]);
 		}
 	} else { // >= 08
 		printf("uuid {\n   ");
@@ -1707,7 +1707,7 @@
 	if (format_version(cfg) < Drbd_08) {
 		EXP(TK_GC); EXP('{');
 		for (i = 0; i < GEN_CNT_SIZE; i++) {
-			EXP(TK_U64); EXP(';');
+			EXP(TK_NUM); EXP(';');
 			cfg->md.gc[i] = yylval.u64;
 		}
 		EXP('}');

From drbd-cvs at lists.linbit.com  Sun Feb  5 21:51:51 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Sun Feb  5 21:51:52 2006
Subject: [DRBD-cvs] svn commit by phil - r2059 - in trunk: . scripts user -
	Worked on item 28 of the ROADMAP. 50% done. 
Message-ID: <20060205205151.70F8A16384@mail.linbit.com>

Author: phil
Date: 2006-02-05 21:51:49 +0100 (Sun, 05 Feb 2006)
New Revision: 2059

Added:
   trunk/user/drbdadm_usage_cnt.c
Modified:
   trunk/ROADMAP
   trunk/scripts/drbd.conf
   trunk/user/Makefile
   trunk/user/drbd_endian.h
   trunk/user/drbdadm.h
   trunk/user/drbdadm_main.c
   trunk/user/drbdadm_parser.c
   trunk/user/drbdadm_parser.h
   trunk/user/drbdadm_scanner.fl
Log:
Worked on item 28 of the ROADMAP. 50% done.


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-02-02 17:43:39 UTC (rev 2058)
+++ trunk/ROADMAP	2006-02-05 20:51:49 UTC (rev 2059)
@@ -667,6 +667,9 @@
    set gets generated, the 'call home' is initiated. The user might
    of course opt out of this.
 
+   50% DONE [ Counting of resources is missing, counting of DRBD releases
+              is alrady implemented. ]
+
 29 Make drbdadm to have 'hidden-commands' command to also show
    the hidden sub-commands in the ussage.
 

Modified: trunk/scripts/drbd.conf
===================================================================
--- trunk/scripts/drbd.conf	2006-02-02 17:43:39 UTC (rev 2058)
+++ trunk/scripts/drbd.conf	2006-02-05 20:51:49 UTC (rev 2059)
@@ -84,6 +84,11 @@
 
     # You might disable one of drbdadm's sanity check.
     # disable-ip-verification;
+
+    # Participate in DRBD's online usage counter at http://usage.drbd.org
+    # possilbe options: ask, yes, no. Default is ask. In case you do not
+    # know, leave it at ask, and follow the on screen instructions later.
+    # usage-count ask;
 # }
 
 

Modified: trunk/user/Makefile
===================================================================
--- trunk/user/Makefile	2006-02-02 17:43:39 UTC (rev 2058)
+++ trunk/user/Makefile	2006-02-05 20:51:49 UTC (rev 2059)
@@ -21,7 +21,8 @@
 CC = gcc
 
 drbdadm-obj = drbdadm_scanner.o drbdadm_parser.o drbdadm_main.o \
-	      drbdadm_adjust.o drbdtool_common.o ../drbd/drbd_buildtag.o
+	      drbdadm_adjust.o drbdtool_common.o drbdadm_usage_cnt.o \
+	      ../drbd/drbd_buildtag.o
 
 drbdsetup-obj = drbdsetup.o drbdtool_common.o ../drbd/drbd_buildtag.o \
 	        ../drbd/drbd_strings.o
@@ -73,3 +74,4 @@
 drbdsetup.o:       drbdtool_common.h           drbd_limits.h
 drbdsetup.o: ../drbd/linux/drbd.h ../drbd/linux/drbd_config.h
 drbdmeta.o:        drbdtool_common.h drbd_endian.h 
+drbdadm_usage_cnt.o: drbdadm.h drbd_endian.h

Modified: trunk/user/drbd_endian.h
===================================================================
--- trunk/user/drbd_endian.h	2006-02-02 17:43:39 UTC (rev 2058)
+++ trunk/user/drbd_endian.h	2006-02-05 20:51:49 UTC (rev 2059)
@@ -166,12 +166,12 @@
  */
 
 #if BITS_PER_LONG == 32
-# define X32 "%lX"
+# define X32 "%X"
 //# define X64 "%llX"
 # define X64(a) "%"#a"llX"
-# define D32 "%ld"
+# define D32 "%d"
 # define D64 "%lld"
-# define U32 "%lu"
+# define U32 "%u"
 # define U64 "%llu"
 #elif BITS_PER_LONG == 64
 # define X32 "%X"

Modified: trunk/user/drbdadm.h
===================================================================
--- trunk/user/drbdadm.h	2006-02-02 17:43:39 UTC (rev 2058)
+++ trunk/user/drbdadm.h	2006-02-05 20:51:49 UTC (rev 2059)
@@ -33,13 +33,19 @@
 /* for verify_ips(): are not verifyable ips fatal? */
 #define INVALID_IP_IS_INVALID_CONF 0
 
-
+enum usage_count_type {
+  UC_YES,
+  UC_NO,
+  UC_ASK,
+};
+  
 struct d_globals
 {
   int disable_io_hints;
   int disable_ip_verification;
   int minor_count;
   int dialog_refresh;
+  enum usage_count_type usage_count;
 };
 
 struct d_host_info
@@ -87,8 +93,8 @@
 extern void schedule_dcmd( int (* function)(struct d_resource*,const char* ),
 			   struct d_resource* res,
 			   int order);
+extern void uc_node(enum usage_count_type type);
 
-
 extern char* config_file;
 extern int config_valid;
 extern struct d_resource* config;

Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c	2006-02-02 17:43:39 UTC (rev 2058)
+++ trunk/user/drbdadm_main.c	2006-02-05 20:51:49 UTC (rev 2059)
@@ -106,7 +106,7 @@
 struct utsname nodeinfo;
 int line=1;
 int fline, c_resource_start;
-struct d_globals global_options = { 0, 0, 0, 1 };
+struct d_globals global_options = { 0, 0, 0, 1, UC_ASK };
 char *config_file = NULL;
 struct d_resource* config = NULL;
 struct d_resource* common = NULL;
@@ -1530,6 +1530,8 @@
     find_drbdcmd(&drbdmeta,(char *[]){"./drbdmeta", "/sbin/drbdmeta", 0 });
   }
 
+  uc_node(global_options.usage_count);
+
   if(cmd->res_name_required)
     {
       int is_dump = (cmd->function == adm_dump);

Modified: trunk/user/drbdadm_parser.c
===================================================================
--- trunk/user/drbdadm_parser.c	2006-02-02 17:43:39 UTC (rev 2058)
+++ trunk/user/drbdadm_parser.c	2006-02-05 20:51:49 UTC (rev 2059)
@@ -205,6 +205,7 @@
 	token = yylex(); 				\
 	if(token != TOKEN1)				\
 		pe_expected_got( #TOKEN1, token ); 	\
+	token;						\
 })
 
 #define EXP2(TOKEN1,TOKEN2)					\
@@ -213,6 +214,7 @@
 	token = yylex(); 					\
 	if(token != TOKEN1 && token != TOKEN2) 			\
 		pe_expected_got( #TOKEN1 "|" # TOKEN2, token );	\
+	token;							\
 })
 
 static void pe_expected(const char *exp)
@@ -245,6 +247,14 @@
 			range_check(R_DIALOG_REFRESH,"dialog-refresh",yylval.txt);
 			global_options.dialog_refresh=atoi(yylval.txt);
 			break;
+		case TK_USAGE_COUNT:
+			switch(yylex()) {
+			case TK_YES: global_options.usage_count=UC_YES; break; 
+			case TK_NO:  global_options.usage_count=UC_NO;  break; 
+			case TK_ASK: global_options.usage_count=UC_ASK; break; 
+			default:     pe_expected("yes | no | ask");
+			}
+			break;
 		case '}':
 			return;
 		default:

Modified: trunk/user/drbdadm_parser.h
===================================================================
--- trunk/user/drbdadm_parser.h	2006-02-02 17:43:39 UTC (rev 2058)
+++ trunk/user/drbdadm_parser.h	2006-02-05 20:51:49 UTC (rev 2059)
@@ -79,7 +79,11 @@
 	TK_SYNCER_OPTION,
 	TK_STARTUP_SWITCH,
 	TK_STARTUP_OPTION,
-	TK_HANDLER_OPTION
+	TK_HANDLER_OPTION,
+	TK_USAGE_COUNT,
+	TK_ASK,
+	TK_YES,
+	TK_NO
 };
 
 typedef struct YYSTYPE {

Modified: trunk/user/drbdadm_scanner.fl
===================================================================
--- trunk/user/drbdadm_scanner.fl	2006-02-02 17:43:39 UTC (rev 2058)
+++ trunk/user/drbdadm_scanner.fl	2006-02-05 20:51:49 UTC (rev 2059)
@@ -44,7 +44,10 @@
 {WS}			/* ignore whitespaces */
 {OPCHAR}		{ DP; return yytext[0];			}
 on			{ DP; return TK_ON;			}
+no			{ DP; return TK_NO;			}
 net			{ DP; return TK_NET;			}
+yes			{ DP; return TK_YES;			}
+ask			{ DP; return TK_ASK;			}
 skip			{ DP; return TK_SKIP;			}
 disk			{ DP; return TK_DISK;			}
 syncer			{ DP; return TK_SYNCER;			}
@@ -62,6 +65,7 @@
 resource		{ DP; return TK_RESOURCE;		}
 meta-disk		{ DP; return TK_META_DISK;		}
 flexible-meta-disk	{ DP; return TK_FLEX_META_DISK;		}
+usage-count 		{ DP; return TK_USAGE_COUNT;		}
 size			{ DP; CP; RC(DISK_SIZE); return TK_DISK_OPTION;	}
 on-io-error		{ DP; CP; return TK_DISK_OPTION;	}
 split-brain-fix		{ DP; CP; return TK_DISK_SWITCH;	}

Added: trunk/user/drbdadm_usage_cnt.c
===================================================================
--- trunk/user/drbdadm_usage_cnt.c	2006-02-02 17:43:39 UTC (rev 2058)
+++ trunk/user/drbdadm_usage_cnt.c	2006-02-05 20:51:49 UTC (rev 2059)
@@ -0,0 +1,315 @@
+/*
+   drbdadm_usage_cnt.c
+
+   This file is part of drbd by Philipp Reisner.
+
+   Copyright (C) 2006, Philipp Reisner <philipp.reisner@linbit.com>.
+        Initial author.
+
+   Copyright (C) 2006, 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)
+   any later version.
+
+   drbd 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 drbd; see the file COPYING.  If not, write to
+   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#include "drbdadm.h"
+#include "drbd_endian.h"
+#include "linux/drbd.h"		/* only use DRBD_MAGIC from here! */
+
+#define HTTP_PORT 80
+#define HTTP_HOST "usage.drbd.org"
+#define HTTP_ADDR "212.69.162.23"
+#define NODE_ID_FILE "/var/lib/drbd/node_id"
+
+struct node_info {
+	u64	node_uuid;
+	u32	version_code;
+};
+
+struct node_info_od {
+	u32 magic;
+	struct node_info ni;
+} __attribute((packed));
+
+/* FIX: mark plus versions, mark production vs beta releases.
+        read the version string from the /proc file, so we
+	look at the version of the module and not at the version
+	of the drbdadm executable.
+ */
+static unsigned int numeric_version_code(char* text)
+{
+	unsigned int nc;
+	char buffer[5], *c, *b;
+	unsigned m = 1000000;
+
+	nc = 0;
+	c = text;
+
+	while(*c) {
+		while(!isdigit(*c)) c++;
+		b = buffer;
+		while(isdigit(*c)) *b++=*c++;
+		*b=0;
+
+		nc = nc + atoi( buffer ) * m;
+		m=m/1000;
+	}
+
+	return nc;
+}
+
+static void get_random_bytes(void* buffer, int len)
+{
+	int fd;
+
+	fd = open("/dev/random",O_RDONLY);
+	if( fd == -1) {
+		perror("Open of /dev/random failed");
+		exit(20);
+	}
+	if(read(fd,buffer,len) != len) {
+		fprintf(stderr,"Reading from /dev/random failed\n");
+		exit(20);
+	}
+	close(fd);	
+}
+
+static void write_node_id(struct node_info *ni)
+{
+	int fd;
+	struct node_info_od on_disk;
+
+	fd = open(NODE_ID_FILE,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
+	if( fd == -1) {
+		perror("Creation of "NODE_ID_FILE" failed.");
+		exit(20);
+	}
+
+	on_disk.magic           = cpu_to_be32(DRBD_MAGIC);
+	on_disk.ni.node_uuid    = cpu_to_be64(ni->node_uuid);
+	on_disk.ni.version_code = cpu_to_be32(ni->version_code);
+
+	if( write(fd,&on_disk, sizeof(on_disk)) != sizeof(on_disk)) {
+		perror("Write to "NODE_ID_FILE" failed.");
+		exit(20);
+	}
+
+	close(fd);
+}
+
+
+static int read_node_id(struct node_info *ni)
+{
+	int fd;
+	struct node_info_od on_disk;
+
+	fd = open(NODE_ID_FILE,O_RDONLY);
+	if( fd == -1) {
+		return 0;
+	}
+	
+	if( read(fd,&on_disk, sizeof(on_disk)) != sizeof(on_disk)) {
+		close(fd);
+		return 0;
+	}
+
+	if ( be32_to_cpu(on_disk.magic) != DRBD_MAGIC ) return 0;
+
+	ni->node_uuid    = be64_to_cpu(on_disk.ni.node_uuid);
+	ni->version_code = be32_to_cpu(on_disk.ni.version_code);
+
+	close(fd);
+	return 1;
+}
+
+/**
+ * insert_usage_with_socket:
+ * 
+ * Return codes:
+ *
+ * 0 - success
+ * 1 - failed to create socket
+ * 2 - unknown server
+ * 3 - cannot connect to server
+ * 5 - other error
+ */
+static int make_get_request(char *req_buf) {
+	struct sockaddr_in server;
+	struct hostent *host_info;
+	unsigned long addr;
+	int sock;
+	char *http_host = HTTP_HOST;
+	int buf_len = 1024;
+	char buffer[buf_len];
+	FILE *sockfd;
+	int writeit;
+	sock = socket( PF_INET, SOCK_STREAM, 0);
+	if (sock < 0) {
+		return 1;
+	}
+	memset (&server, 0, sizeof(server));
+
+	/* convert host name to ip */
+	host_info = gethostbyname(http_host);
+	if (host_info == NULL) {
+		/* unknown host, try with ip */
+		if ((addr = inet_addr( HTTP_ADDR )) != INADDR_NONE)
+			memcpy((char *)&server.sin_addr, &addr, sizeof(addr));
+		else {
+			close(sock);
+			return 2;
+		}
+	} else {
+		memcpy((char *)&server.sin_addr, host_info->h_addr,
+			host_info->h_length);
+	}
+
+	server.sin_family = AF_INET;
+	server.sin_port = htons(HTTP_PORT);
+
+	if (connect(sock, (struct sockaddr*)&server, sizeof(server))<0) {
+		/* cannot connect to server */
+		close(sock);
+		return 3;
+	}
+
+	if ((sockfd = fdopen(sock, "r+")) == NULL) {
+		close(sock);
+		return 5;
+	}
+
+	if (fputs(req_buf, sockfd) == EOF) {
+		fclose(sockfd);
+		close(sock);
+		return 5;
+	}
+
+	writeit = 0;
+	while (fgets(buffer, buf_len, sockfd) != NULL) {
+		/* ignore http headers */
+		if (writeit == 0) {
+			if (buffer[0] == '\r' || buffer[0] == '\n')
+				writeit = 1;
+		} else {
+			printf("%s", buffer);
+		}
+	}
+	fclose(sockfd);
+	close(sock);
+	return 0;
+}
+
+static int insert_resource(u64 node_uuid, u64 res_uuid, u64 res_size) {
+	char *req_buf;
+        ssprintf( req_buf, "GET http://"HTTP_HOST"/cgi-bin/insert_usage.pl?"
+		  "nu="U64"&ru="U64"&rs="U64" HTTP/1.0\n\n",
+		  node_uuid, res_uuid, res_size);
+	return make_get_request(req_buf);
+}
+
+/* Ensure that the node is counted on http://usage.drbd.org
+ */
+void uc_node(enum usage_count_type type)
+{
+	struct node_info ni;
+	char *req_buf;
+	u32 current;
+	int send = 0;
+	int update = 0;
+	char answer[10];
+
+	if( type == UC_NO ) return;
+
+	current = numeric_version_code(REL_VERSION);
+
+	if( ! read_node_id(&ni) ) {
+		get_random_bytes(&ni.node_uuid,sizeof(ni.node_uuid));
+		ni.version_code = current;
+		send = 1;
+	} else {
+		// read_node_id() was successull
+		if (ni.version_code != current) {
+			ni.version_code = current;
+			update = 1;
+			send = 1;
+		}
+	}
+
+	if(!send) return;
+	
+	if (type == UC_ASK ) {
+		printf(
+"\n"
+"\t\t--== This is %s of DRBD ==--\n"
+"Please take part in the global DRBD usage count at http://"HTTP_HOST".\n\n"
+"The conter works completely anonymous. A random number gets created on\n"
+"you machine, and that randomer number (as identifier for this machine) and\n"
+"DRBD's version number are sent to "HTTP_HOST".\n\n"
+"The benifits for you are:\n"
+" * As a respose to your data, the server ("HTTP_HOST") will tell you\n"
+"   how many users before your have installed this version (%s).\n"
+" * With a high counter the DRBD developers have a high motivation to\n"
+"   continue development of the software.\n\n"
+"The following string will be send to the server:\n"
+"http://"HTTP_HOST"/cgi-bin/insert_usage.pl?nu="U64"&nv="U32"\n\n"
+"In case you want to participate but know that this machines is firewalled\n"
+"simply issue the query string with your favourite web browser or wget\n\n"
+"You can control all this by setting 'usage-count' in the globals section\n"
+"of your drbd.conf\n\n"
+"Just press [enter] or enter 'no'[enter] to opt out: ",
+			update ? "an update" : "a new installation",
+			REL_VERSION,ni.node_uuid, ni.version_code);
+		fgets(answer,9,stdin);
+		if(!strcmp(answer,"no")) send = 0;
+	}
+
+        ssprintf(req_buf,"GET http://"HTTP_HOST"/cgi-bin/insert_usage.pl?"
+		 "nu="U64"&nv="U32" HTTP/1.0\n\n",
+		 ni.node_uuid, ni.version_code);
+
+	if (send) {
+		write_node_id(&ni);
+
+		printf(
+"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
+"  --==  Thank you for participating in the global usage survey  ==--\n"
+"The server's response is:\n\n");
+		make_get_request(req_buf);
+		printf(
+"\n"
+"In the future drbdadm will only contact "HTTP_HOST" when you update\n"
+"DRBD or when you use 'drbdadm create-md'. Of course it will continue\n"
+"to ask you for confirmation as long as 'usage-count' is at its default\n"
+"value of 'ask'.\n\n"
+"Just press [enter] to continue: ");
+		fgets(answer,9,stdin);
+	}
+}

From drbd-cvs at lists.linbit.com  Tue Feb  7 22:19:26 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue Feb  7 22:19:27 2006
Subject: [DRBD-cvs] svn commit by phil - r2060 - trunk/user - * The
	is_attached() function of drbdmeta was not workin
Message-ID: <20060207211926.8E5DB163F2@mail.linbit.com>

Author: phil
Date: 2006-02-07 22:19:25 +0100 (Tue, 07 Feb 2006)
New Revision: 2060

Modified:
   trunk/user/drbdadm_scanner.fl
   trunk/user/drbdadm_usage_cnt.c
   trunk/user/drbdmeta.c
   trunk/user/drbdtool_common.c
   trunk/user/drbdtool_common.h
Log:
* The is_attached() function of drbdmeta was not working right. FIXED.
* drbdadm will create /var/lib/drbd when it is needed for storing
  /var/lib/drbd/node_id .
* Two keywords were missing from drbdadm_scanner.fl (cram-hmac-alg and
  shared-secret)


Modified: trunk/user/drbdadm_scanner.fl
===================================================================
--- trunk/user/drbdadm_scanner.fl	2006-02-05 20:51:49 UTC (rev 2059)
+++ trunk/user/drbdadm_scanner.fl	2006-02-07 21:19:25 UTC (rev 2060)
@@ -75,6 +75,8 @@
 max-buffers		{ DP; CP; RC(MAX_BUFFERS); return TK_NET_OPTION;}
 sndbuf-size		{ DP; CP; RC(SNDBUF_SIZE); return TK_NET_OPTION;}
 connect-int		{ DP; CP; RC(CONNECT_INT); return TK_NET_OPTION;}
+cram-hmac-alg		{ DP; CP; return TK_NET_OPTION;		}
+shared-secret		{ DP; CP; return TK_NET_OPTION;		}
 max-epoch-size		{ DP; CP; RC(MAX_EPOCH_SIZE); return TK_NET_OPTION;}
 after-sb-[012]pri	{ DP; CP; return TK_NET_OPTION;		}
 allow-two-primaries	{ DP; CP; return TK_NET_SWITCH;		}

Modified: trunk/user/drbdadm_usage_cnt.c
===================================================================
--- trunk/user/drbdadm_usage_cnt.c	2006-02-05 20:51:49 UTC (rev 2059)
+++ trunk/user/drbdadm_usage_cnt.c	2006-02-07 21:19:25 UTC (rev 2060)
@@ -47,7 +47,8 @@
 #define HTTP_PORT 80
 #define HTTP_HOST "usage.drbd.org"
 #define HTTP_ADDR "212.69.162.23"
-#define NODE_ID_FILE "/var/lib/drbd/node_id"
+#define DRBD_LIB_DIR "/var/lib/drbd"
+#define NODE_ID_FILE DRBD_LIB_DIR"/node_id"
 
 struct node_info {
 	u64	node_uuid;
@@ -108,6 +109,11 @@
 	struct node_info_od on_disk;
 
 	fd = open(NODE_ID_FILE,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
+	if( fd == -1 && errno == ENOENT) {
+		mkdir(DRBD_LIB_DIR,S_IRWXU);
+		fd = open(NODE_ID_FILE,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR);
+	}
+
 	if( fd == -1) {
 		perror("Creation of "NODE_ID_FILE" failed.");
 		exit(20);

Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2006-02-05 20:51:49 UTC (rev 2059)
+++ trunk/user/drbdmeta.c	2006-02-07 21:19:25 UTC (rev 2060)
@@ -2222,19 +2222,20 @@
 int is_attached(int minor)
 {
 	FILE *pr;
-	char line[120], cs[40],st[40],ds[40];
-	int m,rv=0;
+	char token[40];
+	int rv=1;
+	long m,cm=-1;
+	char *p;
 
 	pr = fopen("/proc/drbd","r");
-	if(!pr) return rv;
+	if(!pr) return 0;
 
-	while(fgets(line,120,pr)) {
-		if(sscanf(line,"%2d: %s %s %s",&m,cs,st,ds)) {
-			if( m == minor ) {
-				rv = strcmp(cs,"Unconfigured");
-				if(rv) rv = strncmp(ds,"ds:Diskless/",11);
-				break;
-			}
+	while(fget_token(token,40,pr) != EOF) {
+		m=strtol(token,&p,10);
+		if(*p==':' && p-token == (long)strlen(token)-1 ) cm=m;
+		if( cm == minor ) {
+			if(!strcmp(token,"cs:Unconfigured")) rv = 0;
+			if(!strncmp(token,"ds:Diskless",11)) rv = 0;
 		}
 	}
 	fclose(pr);

Modified: trunk/user/drbdtool_common.c
===================================================================
--- trunk/user/drbdtool_common.c	2006-02-05 20:51:49 UTC (rev 2059)
+++ trunk/user/drbdtool_common.c	2006-02-07 21:19:25 UTC (rev 2060)
@@ -356,3 +356,23 @@
 "         -<  Node was in the progress of setting all bits in the bitmap  >--+\n"
 "\n");
 }
+
+int fget_token(char *s, int size, FILE* stream)
+{
+	int c;
+	char* sp = s;
+
+	do { // eat white spaces in front.
+		c = getc(stream);
+		if( c == EOF) return EOF;
+	} while (!isgraph(c));
+
+	do { // read the first word into s
+		*sp++ = c;
+		c = getc(stream);
+		if ( c == EOF) break;
+	} while (isgraph(c) && --size);
+
+	*sp=0;
+	return 1;
+}

Modified: trunk/user/drbdtool_common.h
===================================================================
--- trunk/user/drbdtool_common.h	2006-02-05 20:51:49 UTC (rev 2059)
+++ trunk/user/drbdtool_common.h	2006-02-07 21:19:25 UTC (rev 2060)
@@ -35,5 +35,6 @@
 extern void dt_pretty_print_gc(const __u32* gen_cnt);
 extern void dt_print_uuids(const __u64* uuid, unsigned int flags);
 extern void dt_pretty_print_uuids(const __u64* uuid, unsigned int flags);
+extern int fget_token(char *s, int size, FILE* stream);
 
 #endif

From drbd-cvs at lists.linbit.com  Wed Feb  8 16:00:44 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed Feb  8 16:00:45 2006
Subject: [DRBD-cvs] svn commit by phil - r2061 - trunk/user - Small patch,
	big difference!
Message-ID: <20060208150044.5A45516434@mail.linbit.com>

drbdmeta could not access 
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Author: phil
Date: 2006-02-08 16:00:42 +0100 (Wed, 08 Feb 2006)
New Revision: 2061

Modified:
   trunk/user/drbdmeta.c
Log:
Small patch, big difference!
drbdmeta could not access internal meta-data on devices bigger
than 2G, since it used mmap() instead of mmap64() .


Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2006-02-07 21:19:25 UTC (rev 2060)
+++ trunk/user/drbdmeta.c	2006-02-08 15:00:42 UTC (rev 2061)
@@ -337,7 +337,7 @@
 }
 
 void *my_mmap(const char* func, const unsigned int line, const char* what,
-	size_t length, int prot , int flags, int fd, off_t offset)
+	size_t length, int prot , int flags, int fd, __off64_t offset)
 {
     void *p;
     u64 have = bdev_size(fd);
@@ -353,7 +353,7 @@
 	    (unsigned long long)length, (unsigned long long)offset);
     */
     length = PAGE_ALIGN(length) + ((offset & ~PAGE_MASK) ? PAGE_SIZE : 0);
-    p = mmap(NULL, length, prot, flags, fd, offset & PAGE_MASK);
+    p = mmap64(NULL, length, prot, flags, fd, offset & PAGE_MASK);
     // fprintf(stderr,"mmap %s: %p %lu @%lu\n",what, p,(unsigned long)length, (unsigned long) (offset & PAGE_MASK));
     if (p == MAP_FAILED) {
 	PERROR("%s:%u: mmap(%s) failed", func, line, what);

From drbd-cvs at lists.linbit.com  Wed Feb  8 18:40:24 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed Feb  8 18:40:26 2006
Subject: [DRBD-cvs] svn commit by phil - r2062 - trunk/user - GC based meta
	data (v06 and v07) does not have the MDF_
Message-ID: <20060208174024.D1FC91642F@mail.linbit.com>

Author: phil
Date: 2006-02-08 18:40:23 +0100 (Wed, 08 Feb 2006)
New Revision: 2062

Modified:
   trunk/user/drbdmeta.c
   trunk/user/drbdtool_common.c
Log:
GC based meta data (v06 and v07) does not have the MDF_WasUpToDate flag!
Removed this nonsense!


Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2006-02-08 15:00:42 UTC (rev 2061)
+++ trunk/user/drbdmeta.c	2006-02-08 17:40:23 UTC (rev 2062)
@@ -389,33 +389,17 @@
 void md_disk_06_to_cpu(struct md_cpu *cpu, const struct md_on_disk_06 *disk)
 {
 	int i;
-	u32 flags;
 
 	MEMSET(cpu, 0, sizeof(*cpu));
 	for (i = 0; i < GEN_CNT_SIZE; i++)
 		cpu->gc[i] = be32_to_cpu(disk->gc[i].be);
 	cpu->magic = be32_to_cpu(disk->magic.be);
-
-	/* 06 does not have the UpToDate flag, set it according to
-	   the Consistent Flag */
-	flags = cpu->gc[Flags];
-	if( flags & MDF_Consistent) flags = flags | MDF_WasUpToDate;
-	cpu->gc[Flags]=flags;
 }
 
 void md_cpu_to_disk_06(struct md_on_disk_06 *disk, struct md_cpu *cpu)
 {
 	int i;
-	u32 flags;
 
-	/* clear Consistent flag if UpToDate is not set*/
-	flags = cpu->gc[Flags];
-	if(!((flags & MDF_Consistent) && (flags & MDF_WasUpToDate))) {
-		flags &= ~MDF_Consistent;
-	}
-	flags &= ~MDF_WasUpToDate;
-	cpu->gc[Flags]=flags;
-
 	for (i = 0; i < GEN_CNT_SIZE; i++)
 		disk->gc[i].be = cpu_to_be32(cpu->gc[i]);
 	disk->magic.be = cpu_to_be32(cpu->magic);
@@ -448,7 +432,6 @@
 void md_disk_07_to_cpu(struct md_cpu *cpu, const struct md_on_disk_07 *disk)
 {
 	int i;
-	u32 flags;
 
 	MEMSET(cpu, 0, sizeof(*cpu));
 	cpu->la_sect = be64_to_cpu(disk->la_kb.be) << 1;
@@ -459,27 +442,12 @@
 	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);
-
-	/* 07 does not have the UpToDate flag, set it according to
-	   the Consistent Flag */
-	flags = cpu->gc[Flags];
-	if( flags & MDF_Consistent) flags = flags | MDF_WasUpToDate;
-	cpu->gc[Flags]=flags;
 }
 
 void md_cpu_to_disk_07(struct md_on_disk_07 *disk, struct md_cpu *cpu)
 {
 	int i;
-	u32 flags;
 
-	/* clear Consistent flag if UpToDate is not set*/
-	flags = cpu->gc[Flags];
-	if(!((flags & MDF_Consistent) && (flags & MDF_WasUpToDate))) {
-		flags &= ~MDF_Consistent;
-	}
-	flags &= ~MDF_WasUpToDate;
-	cpu->gc[Flags]=flags;
-
 	disk->la_kb.be = cpu_to_be64(cpu->la_sect >> 1);
 	for (i = 0; i < GEN_CNT_SIZE; i++)
 		disk->gc[i].be = cpu_to_be32(cpu->gc[i]);
@@ -1070,7 +1038,6 @@
 
 	do {
 		if (!m_strsep_bit(str, &md->gc[Flags], MDF_Consistent)) break;
-		if (!m_strsep_bit(str, &md->gc[Flags], MDF_WasUpToDate)) break;
 		if (!m_strsep_u32(str, &md->gc[HumanCnt])) break;
 		if (!m_strsep_u32(str, &md->gc[TimeoutCnt])) break;
 		if (!m_strsep_u32(str, &md->gc[ConnectedCnt])) break;
@@ -1100,15 +1067,11 @@
 	} while (0);
 }
 
-int m_outdate_gc(struct md_cpu *md)
+int m_outdate_gc(struct md_cpu *md __attribute((unused)))
 {
-	if ( !(md->gc[Flags] & MDF_Consistent) ) {
-		return 5;
-	}
+	fprintf(stderr, "Can not outdate GC based meta data!\n");
 
-	md->gc[Flags] &= ~MDF_WasUpToDate;
-
-	return 0;
+	return 5;
 }
 
 int m_outdate_uuid(struct md_cpu *md)

Modified: trunk/user/drbdtool_common.c
===================================================================
--- trunk/user/drbdtool_common.c	2006-02-08 15:00:42 UTC (rev 2061)
+++ trunk/user/drbdtool_common.c	2006-02-08 17:40:23 UTC (rev 2062)
@@ -282,9 +282,8 @@
 
 void dt_print_gc(const __u32* gen_cnt)
 {
-	printf("%d:%d:%d:%d:%d:%d:%d:%d:%d\n",
+	printf("%d:%d:%d:%d:%d:%d:%d:%d\n",
 	       gen_cnt[Flags] & MDF_Consistent ? 1 : 0,
-	       gen_cnt[Flags] & MDF_WasUpToDate ? 1 : 0,
 	       gen_cnt[HumanCnt],
 	       gen_cnt[TimeoutCnt],
 	       gen_cnt[ConnectedCnt],
@@ -297,20 +296,18 @@
 void dt_pretty_print_gc(const __u32* gen_cnt)
 {
 	printf("\n"
-	       "                                              WantFullSync |\n"
-	       "                                        ConnectedInd |     |\n"
-	       "                                     lastState |     |     |\n"
-	       "                            ArbitraryCnt |     |     |     |\n"
-	       "                      ConnectedCnt |     |     |     |     |\n"
-	       "                  TimeoutCnt |     |     |     |     |     |\n"
-	       "              HumanCnt |     |     |     |     |     |     |\n"
-	       "     WasUpToDate |     |     |     |     |     |     |     |\n"
-	       "Consistent |     |     |     |     |     |     |     |     |\n"
-	       "   --------+-----+-----+-----+-----+-----+-----+-----+-----+\n"
-	       "       %3s | %3s | %3d | %3d | %3d | %3d | %3s | %3s | %3s  \n"
+	       "                                        WantFullSync |\n"
+	       "                                  ConnectedInd |     |\n"
+	       "                               lastState |     |     |\n"
+	       "                      ArbitraryCnt |     |     |     |\n"
+	       "                ConnectedCnt |     |     |     |     |\n"
+	       "            TimeoutCnt |     |     |     |     |     |\n"
+	       "        HumanCnt |     |     |     |     |     |     |\n"
+	       "Consistent |     |     |     |     |     |     |     |\n"
+	       "   --------+-----+-----+-----+-----+-----+-----+-----+\n"
+	       "       %3s | %3d | %3d | %3d | %3d | %3s | %3s | %3s  \n"
 	       "\n",
 	       gen_cnt[Flags] & MDF_Consistent ? "1/c" : "0/i",
-	       gen_cnt[Flags] & MDF_WasUpToDate ? "1/y" : "0/n",
 	       gen_cnt[HumanCnt],
 	       gen_cnt[TimeoutCnt],
 	       gen_cnt[ConnectedCnt],

From drbd-cvs at lists.linbit.com  Thu Feb  9 12:26:22 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu Feb  9 12:26:23 2006
Subject: [DRBD-cvs] svn commit by phil - r2063 - branches/drbd-0.7/drbd -
	There was a bug related to the degr-wcf-timeout config 
Message-ID: <20060209112622.2B27A1644E@mail.linbit.com>

Author: phil
Date: 2006-02-09 12:26:18 +0100 (Thu, 09 Feb 2006)
New Revision: 2063

Modified:
   branches/drbd-0.7/drbd/drbd_fs.c
   branches/drbd-0.7/drbd/drbd_int.h
   branches/drbd-0.7/drbd/drbd_receiver.c
Log:
There was a bug related to the degr-wcf-timeout config option, it was
no longer used in recent DRBD releases.
Over the time the a drbd_md_write() got inserted into the execution
path between the drbd_md_read() and the drbd_get_wait_time().
Fixed that.



Modified: branches/drbd-0.7/drbd/drbd_fs.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_fs.c	2006-02-08 17:40:23 UTC (rev 2062)
+++ branches/drbd-0.7/drbd/drbd_fs.c	2006-02-09 11:26:18 UTC (rev 2063)
@@ -485,6 +485,27 @@
 
 /* FIXME if (md_gc_valid < 0) META DATA IO NOT POSSIBLE! */
 
+	/* If I am currently not Primary,
+	 * but meta data primary indicator is set,
+	 * I just now recover from a hard crash,
+	 * and have been Primary before that crash.
+	 *
+	 * Now, if I had no connection before that crash
+	 * (have been degraded Primary), chances are that
+	 * I won't find my peer now either.
+	 *
+	 * In that case, and _only_ in that case,
+	 * we use the degr-wfc-timeout instead of the default,
+	 * so we can automatically recover from a crash of a
+	 * degraded but active "cluster" after a certain timeout.
+	 */
+	clear_bit(USE_DEGR_WFC_T,&mdev->flags);
+	if ( mdev->state != Primary &&
+	     drbd_md_test_flag(mdev,MDF_PrimaryInd) &&
+	    !drbd_md_test_flag(mdev,MDF_ConnectedInd) ) {
+		set_bit(USE_DEGR_WFC_T,&mdev->flags);
+	}
+
 	drbd_bm_lock(mdev); // racy...
 	if (drbd_determin_dev_size(mdev) < 0) {
 		/* could not allocate bitmap.
@@ -894,23 +915,8 @@
 	if(copy_from_user(&p,arg,sizeof(p))) {
 		return -EFAULT;
 	}
-	/* If I am currently not Primary,
-	 * but meta data primary indicator is set,
-	 * I just now recover from a hard crash,
-	 * and have been Primary before that crash.
-	 *
-	 * Now, if I had no connection before that crash
-	 * (have been degraded Primary), chances are that
-	 * I won't find my peer now either.
-	 *
-	 * In that case, and _only_ in that case,
-	 * we use the degr-wfc-timeout instead of the default,
-	 * so we can automatically recover from a crash of a
-	 * degraded but active "cluster" after a certain timeout.
-	 */
-	if ( mdev->state != Primary &&
-	     drbd_md_test_flag(mdev,MDF_PrimaryInd) &&
-	    !drbd_md_test_flag(mdev,MDF_ConnectedInd) ) {
+
+	if ( test_bit(USE_DEGR_WFC_T,&mdev->flags) ) {
 		time=p.degr_wfc_timeout;
 		if (time) WARN("using degr_wfc_timeout=%ld seconds\n", time);
 	} else {

Modified: branches/drbd-0.7/drbd/drbd_int.h
===================================================================
--- branches/drbd-0.7/drbd/drbd_int.h	2006-02-08 17:40:23 UTC (rev 2062)
+++ branches/drbd-0.7/drbd/drbd_int.h	2006-02-09 11:26:18 UTC (rev 2063)
@@ -697,6 +697,7 @@
 	SENT_DISK_FAILURE,	// sending it once is enough
 	MD_DIRTY,		// current gen counts and flags not yet on disk
 	SYNC_STARTED,		// Needed to agree on the exact point in time..
+	USE_DEGR_WFC_T,		// Use degr-wfc-timeout instad of wfc-timeout.
 };
 
 struct drbd_bitmap; // opaque for Drbd_Conf

Modified: branches/drbd-0.7/drbd/drbd_receiver.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_receiver.c	2006-02-08 17:40:23 UTC (rev 2062)
+++ branches/drbd-0.7/drbd/drbd_receiver.c	2006-02-09 11:26:18 UTC (rev 2063)
@@ -788,6 +788,7 @@
 	drbd_thread_start(&mdev->asender);
 
 	drbd_send_param(mdev,0);
+	clear_bit(USE_DEGR_WFC_T,&mdev->flags);
 
 	return 1;
 }

From drbd-cvs at lists.linbit.com  Thu Feb  9 13:40:52 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu Feb  9 13:40:54 2006
Subject: [DRBD-cvs] svn commit by phil - r2064 - branches/drbd-0.7/drbd - It
	is no longer possible that a consistent device shrin
Message-ID: <20060209124052.59DE31644E@mail.linbit.com>

Author: phil
Date: 2006-02-09 13:40:48 +0100 (Thu, 09 Feb 2006)
New Revision: 2064

Modified:
   branches/drbd-0.7/drbd/drbd_fs.c
   branches/drbd-0.7/drbd/drbd_int.h
   branches/drbd-0.7/drbd/drbd_receiver.c
Log:
It is no longer possible that a consistent device shrinks due to
successfull connection to the peer or due to successfull attach.



Modified: branches/drbd-0.7/drbd/drbd_fs.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_fs.c	2006-02-09 11:26:18 UTC (rev 2063)
+++ branches/drbd-0.7/drbd/drbd_fs.c	2006-02-09 12:40:48 UTC (rev 2064)
@@ -68,19 +68,70 @@
 }
 #endif
 
-STATIC int do_determin_dev_size(struct Drbd_Conf* mdev);
+char* ppsize(char* buf, size_t size) 
+{
+	// Needs 9 bytes at max.
+	static char units[] = { 'K','M','G','T' };
+	int base = 0;
+	while (size >= 10000 ) {
+		size = size >> 10;
+		base++;
+	}
+	sprintf(buf,"%ld %cB",(long)size,units[base]);
+
+	return buf;
+}
+
+/* Returns -ENOMEM if we could not allocate the bitmap
+ *
+ * currently *_size is in KB.
+ *
+ * FIXME
+ * since this is done by drbd receiver as well as from drbdsetup,
+ * this actually needs proper locking!
+ * drbd_bm_resize already protects itself with a mutex.
+ * but again, this is a state change, and thus should be serialized with other
+ * state changes on a more general level already.
+ */
 int drbd_determin_dev_size(struct Drbd_Conf* mdev)
 {
 	sector_t pmdss; // previous meta data start sector
 	sector_t la_size;
+	sector_t size;
+	char ppb[10];
+
 	int md_moved, la_size_changed;
-	int rv;
+	int rv=0;
 
 	wait_event(mdev->al_wait, lc_try_lock(mdev->act_log));
 	pmdss = drbd_md_ss(mdev);
 	la_size = mdev->la_size;
 
-	rv = do_determin_dev_size(mdev);
+	size = drbd_new_dev_size(mdev);
+
+	if( (drbd_get_capacity(mdev->this_bdev)>>1) != size ) {
+		int err;
+		err = drbd_bm_resize(mdev,size<<1); // wants sectors
+		if (unlikely(err)) {
+			/* currently there is only one error: ENOMEM! */
+			size = drbd_bm_capacity(mdev)>>1;
+			if (size == 0) {
+				ERR("OUT OF MEMORY! Could not allocate bitmap! Set device size => 0\n");
+			} else {
+				/* FIXME this is problematic,
+				 * if we in fact are smaller now! */
+				ERR("BM resizing failed. "
+				    "Leaving size unchanged at size = %lu KB\n", 
+				    (unsigned long)size);
+			}
+			rv = err;
+		}
+		// racy, see comments above.
+		drbd_set_my_capacity(mdev,size<<1);
+		mdev->la_size = size;
+		INFO("size = %s (%lu KB)\n",ppsize(ppb,size),
+		     (unsigned long)size);
+	}
 	if (rv < 0) goto out;
 
 	la_size_changed = (la_size != mdev->la_size);
@@ -103,46 +154,16 @@
 	return rv;
 }
 
-char* ppsize(char* buf, size_t size) 
-{
-	// Needs 9 bytes at max.
-	static char units[] = { 'K','M','G','T' };
-	int base = 0;
-	while (size >= 10000 ) {
-		size = size >> 10;
-		base++;
-	}
-	sprintf(buf,"%ld %cB",(long)size,units[base]);
-
-	return buf;
-}
-
-
-/* Returns 1 if there is a disk-less node, 0 if both nodes have a disk.
- * -ENOMEM if we could not allocate the bitmap
- */
 /*
- * THINK do we want the size to be KB or sectors ?
- * note, *_capacity operates in 512 byte sectors!!
- *
  * currently *_size is in KB.
- *
- * FIXME
- * since this is done by drbd receiver as well as from drbdsetup,
- * this actually needs proper locking!
- * drbd_bm_resize already protects itself with a mutex.
- * but again, this is a state change, and thus should be serialized with other
- * state changes on a more general level already.
  */
-STATIC int do_determin_dev_size(struct Drbd_Conf* mdev)
+sector_t drbd_new_dev_size(struct Drbd_Conf* mdev)
 {
 	sector_t p_size = mdev->p_size;  // partner's disk size.
 	sector_t la_size = mdev->la_size; // last agreed size.
 	sector_t m_size; // my size
 	sector_t u_size = mdev->lo_usize; // size requested by user.
 	sector_t size=0;
-	int rv;
-	char ppb[10];
 
 	m_size = drbd_get_capacity(mdev->backing_bdev)>>1;
 
@@ -152,10 +173,8 @@
 	}
 
 	if(p_size && m_size) {
-		rv=0;
 		size=min_t(sector_t,p_size,m_size);
 	} else {
-		rv=1;
 		if(la_size) {
 			size=la_size;
 			if(m_size && m_size < size) size=m_size;
@@ -179,31 +198,7 @@
 		}
 	}
 
-	if( (drbd_get_capacity(mdev->this_bdev)>>1) != size ) {
-		int err;
-		err = drbd_bm_resize(mdev,size<<1); // wants sectors
-		if (unlikely(err)) {
-			/* currently there is only one error: ENOMEM! */
-			size = drbd_bm_capacity(mdev)>>1;
-			if (size == 0) {
-				ERR("OUT OF MEMORY! Could not allocate bitmap! Set device size => 0\n");
-			} else {
-				/* FIXME this is problematic,
-				 * if we in fact are smaller now! */
-				ERR("BM resizing failed. "
-				    "Leaving size unchanged at size = %lu KB\n", 
-				    (unsigned long)size);
-			}
-			rv = err;
-		}
-		// racy, see comments above.
-		drbd_set_my_capacity(mdev,size<<1);
-		mdev->la_size = size;
-		INFO("size = %s (%lu KB)\n",ppsize(ppb,size),
-		     (unsigned long)size);
-	}
-
-	return rv;
+	return size;
 }
 
 /* checks that the al lru is of requested size, and if neccessary tries to
@@ -507,6 +502,21 @@
 	}
 
 	drbd_bm_lock(mdev); // racy...
+
+	if(drbd_md_test_flag(mdev,MDF_Consistent) &&
+	   drbd_new_dev_size(mdev) < mdev->la_size ) {
+		D_ASSERT(mdev->cstate == Unconfigured);
+		D_ASSERT(mput == 1);
+		/* Do not attach a too small disk.*/
+		drbd_bm_unlock(mdev);
+		ERR("Lower device smaller than last agreed size!\n");
+		drbd_free_ll_dev(mdev);
+		set_cstate(mdev,Unconfigured);
+		retcode = LDDeviceTooSmall;
+		module_put(THIS_MODULE);
+		if (put_user(retcode, &arg->ret_code)) return -EFAULT;
+		return -EINVAL;
+	}
 	if (drbd_determin_dev_size(mdev) < 0) {
 		/* could not allocate bitmap.
 		 * try to undo ... */

Modified: branches/drbd-0.7/drbd/drbd_int.h
===================================================================
--- branches/drbd-0.7/drbd/drbd_int.h	2006-02-09 11:26:18 UTC (rev 2063)
+++ branches/drbd-0.7/drbd/drbd_int.h	2006-02-09 12:40:48 UTC (rev 2064)
@@ -1044,6 +1044,7 @@
 // drbd_fs.c
 extern char* ppsize(char* buf, size_t size);
 extern int drbd_determin_dev_size(drbd_dev*);
+extern sector_t drbd_new_dev_size(struct Drbd_Conf*);
 extern int drbd_set_state(drbd_dev *mdev,Drbd_State newstate);
 extern int drbd_ioctl(struct inode *inode, struct file *file,
 		      unsigned int cmd, unsigned long arg);
@@ -1145,6 +1146,14 @@
 
 #include "drbd_compat_wrappers.h"
 
+static inline int drbd_disk_less_node_present(struct Drbd_Conf* mdev)
+{
+	sector_t p_size = mdev->p_size;
+	sector_t m_size = drbd_get_capacity(mdev->backing_bdev);
+
+	return ! ( p_size && m_size ) ;
+}
+
 static inline void
 drbd_flush_signals(struct task_struct *t)
 {

Modified: branches/drbd-0.7/drbd/drbd_receiver.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_receiver.c	2006-02-09 11:26:18 UTC (rev 2063)
+++ branches/drbd-0.7/drbd/drbd_receiver.c	2006-02-09 12:40:48 UTC (rev 2064)
@@ -1379,7 +1379,7 @@
 	Drbd_Parameter_Packet *p = (Drbd_Parameter_Packet*)h;
 	int consider_sync;
 	int oo_state,i;
-	sector_t p_size, p_usize;
+	sector_t p_size, p_usize, my_usize;
 
 	if (h->length != (sizeof(*p)-sizeof(*h))) {
 		ERR("Incompatible packet size of Parameter packet!\n");
@@ -1472,22 +1472,28 @@
 		 * just do what the peer suggests */
 	}
 #undef min_not_zero
-	if( mdev->lo_usize != p_usize ) {
+
+	my_usize = mdev->lo_usize;
+
+	if( mdev->lo_usize > p_usize ) {
 		mdev->lo_usize = p_usize;
 		INFO("Peer sets u_size to %lu KB\n",
 		     (unsigned long)mdev->lo_usize);
 	}
 
+	if( drbd_new_dev_size(mdev) <
+	    (drbd_get_capacity(mdev->this_bdev)>>1) &&
+	    mdev->gen_cnt[Flags] & MDF_Consistent ) {
+		ERR("The peer's disk size is too small!\n");
+		set_cstate(mdev,StandAlone);
+		drbd_thread_stop_nowait(&mdev->receiver);
+		mdev->lo_usize = my_usize;
+		return FALSE;
+	}
 
-/*lge:
- * FIXME
- * please get the order of tests (re)settings for consider_sync
- * right, and comment them!
- */
-
 	consider_sync = (mdev->cstate == WFReportParams);
-	if(drbd_determin_dev_size(mdev)) consider_sync=0;
-
+	drbd_determin_dev_size(mdev);
+	if(drbd_disk_less_node_present(mdev)) consider_sync=0;
 	if(test_bit(DISKLESS, &mdev->flags)) consider_sync=0;
 
 	drbd_bm_unlock(mdev); // }

From drbd-cvs at lists.linbit.com  Fri Feb 10 13:24:57 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri Feb 10 13:24:58 2006
Subject: [DRBD-cvs] svn commit by phil - r2065 - branches/drbd-0.7/drbd -
	When connecting a diskless node to a node with a disk, 
Message-ID: <20060210122457.4CF3016470@mail.linbit.com>

Author: phil
Date: 2006-02-10 13:24:56 +0100 (Fri, 10 Feb 2006)
New Revision: 2065

Modified:
   branches/drbd-0.7/drbd/drbd_fs.c
Log:
When connecting a diskless node to a node with a disk, the diskless
node eventually tried to write its bitmap to disk. Fixed that.


Modified: branches/drbd-0.7/drbd/drbd_fs.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_fs.c	2006-02-09 12:40:48 UTC (rev 2064)
+++ branches/drbd-0.7/drbd/drbd_fs.c	2006-02-10 12:24:56 UTC (rev 2065)
@@ -143,10 +143,13 @@
 	}
 
 	if ( la_size_changed || md_moved ) {
-		drbd_al_shrink(mdev); // All extents inactive.
-		drbd_bm_write(mdev);  // write bitmap
-		// Write mdev->la_size to [possibly new position on] disk.
-		drbd_md_write(mdev);
+		if( inc_local_md_only(mdev)) {
+			drbd_al_shrink(mdev); // All extents inactive.
+			drbd_bm_write(mdev);  // write bitmap
+			// Write mdev->la_size to on disk.
+			drbd_md_write(mdev);
+			dec_local(mdev);
+		}
 	}
   out:
 	lc_unlock(mdev->act_log);

From drbd-cvs at lists.linbit.com  Mon Feb 13 15:55:18 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon Feb 13 15:55:19 2006
Subject: [DRBD-cvs] svn commit by phil - r2066 - in branches/drbd-0.7: .
	debian drbd/linux - Preparing the 0.7.16 release. 
Message-ID: <20060213145518.8E4D916550@mail.linbit.com>

Author: phil
Date: 2006-02-13 15:55:17 +0100 (Mon, 13 Feb 2006)
New Revision: 2066

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 the 0.7.16 release.


Modified: branches/drbd-0.7/ChangeLog
===================================================================
--- branches/drbd-0.7/ChangeLog	2006-02-10 12:24:56 UTC (rev 2065)
+++ branches/drbd-0.7/ChangeLog	2006-02-13 14:55:17 UTC (rev 2066)
@@ -4,6 +4,20 @@
  Cumulative changes since last tarball.
  For even more detail, use "svn log" and "svn diff".
 
+0.7.16 (api:77/proto:74)
+-----
+ * DRBD no longer shrinks an consistent device if it gets connected to
+   an smaller peer or attached to a smaller disk.
+ * There was a bug related to the degr-wcf-timeout config option, it was
+   never used in recent DRBD releases. Fixed.
+ * Made DRBD work with Neil Brown's patch, that serializes recusive
+   ralls to generic_make_request(). FC4 included that patch in its
+   later kernels.
+ * Minor fixes to drbdadm
+ * Compiles now also with Linux-2.6.16-rc1
+ * Updates to documentation and example config file to make it more
+   clear that we talk about byte/second and not bit/second.
+
 0.7.15 (api:77/proto:74)
 -----
  * Fixed a bug in the GC code that could cause a resync attempt

Modified: branches/drbd-0.7/debian/changelog
===================================================================
--- branches/drbd-0.7/debian/changelog	2006-02-10 12:24:56 UTC (rev 2065)
+++ branches/drbd-0.7/debian/changelog	2006-02-13 14:55:17 UTC (rev 2066)
@@ -1,3 +1,9 @@
+drbd (0.7.16-0) unstable; urgency=low
+
+  * New upstream release
+
+ -- Philipp Reisner <phil@linbit.com>  Mon, 13 Feb 2006 15:52:00 +0200
+
 drbd (0.7.15-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-02-10 12:24:56 UTC (rev 2065)
+++ branches/drbd-0.7/drbd/linux/drbd_config.h	2006-02-13 14:55:17 UTC (rev 2066)
@@ -22,7 +22,7 @@
 
 extern const char * drbd_buildtag(void);
 
-#define REL_VERSION "0.7.15"
+#define REL_VERSION "0.7.16"
 #define API_VERSION 77
 #define PRO_VERSION 74
 

Modified: branches/drbd-0.7/drbd.spec.in
===================================================================
--- branches/drbd-0.7/drbd.spec.in	2006-02-10 12:24:56 UTC (rev 2065)
+++ branches/drbd-0.7/drbd.spec.in	2006-02-13 14:55:17 UTC (rev 2066)
@@ -190,6 +190,20 @@
 /sbin/depmod -a -F /boot/System.map-%{kernelversion} %{kernelversion} >/dev/null 2>&1 || true
 
 %changelog
+* Mon Feb 13 2006 15:52:00 +0200 Philipp Reisner <phil@linbit.com>
+- drbd (0.7.16-1)
+ * DRBD no longer shrinks an consistent device if it gets connected to
+   an smaller peer or attached to a smaller disk.
+ * There was a bug related to the degr-wcf-timeout config option, it was
+   never used in recent DRBD releases. Fixed.
+ * Made DRBD work with Neil Brown's patch, that serializes recusive
+   ralls to generic_make_request(). FC4 included that patch in its
+   later kernels.
+ * Minor fixes to drbdadm
+ * Compiles now also with Linux-2.6.16-rc1
+ * Updates to documentation and example config file to make it more
+   clear that we talk about byte/second and not bit/second.
+
 * Mon Dec 19 2005 14:44:00 +0200 Philipp Reisner <phil@linbit.com>
 - drbd (0.7.15-1)
  * Fixed a bug in the GC code that could cause a resync attempt

From drbd-cvs at lists.linbit.com  Mon Feb 13 15:55:48 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Mon Feb 13 15:55:49 2006
Subject: [DRBD-cvs] svn commit by phil - r2067 - tags - 1st try to tag
	0.7.16 
Message-ID: <20060213145548.4940A16550@mail.linbit.com>

Author: phil
Date: 2006-02-13 15:55:47 +0100 (Mon, 13 Feb 2006)
New Revision: 2067

Added:
   tags/drbd-0.7.16/
Log:
1st try to tag 0.7.16


Copied: tags/drbd-0.7.16 (from rev 2066, branches/drbd-0.7)

From drbd-cvs at lists.linbit.com  Wed Feb 22 18:26:02 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed Feb 22 18:26:04 2006
Subject: [DRBD-cvs] svn commit by phil - r2076 - in trunk: . user - Fixed
	the way we determin our own revision number 
Message-ID: <20060222172602.78B31163E1@mail.linbit.com>

Author: phil
Date: 2006-02-22 18:26:01 +0100 (Wed, 22 Feb 2006)
New Revision: 2076

Modified:
   trunk/ROADMAP
   trunk/user/drbdadm_usage_cnt.c
   trunk/user/drbdtool_common.c
   trunk/user/drbdtool_common.h
Log:
Fixed the way we determin our own revision number


Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-02-14 09:53:49 UTC (rev 2075)
+++ trunk/ROADMAP	2006-02-22 17:26:01 UTC (rev 2076)
@@ -684,7 +684,14 @@
 31 Resizing several GB results in ko-count timeouts, maybe since the
    secondary node does the enlargement of the bitmap in the receiver (?)
 
+32 drbdmeta: with internal meta-data v07 and v08 meta-data super blocks
+   are in different places. -> It is possible to have v07 AND v08 meta
+   data on one device. 
+   => drbdmeta should make sure that it overwrites the other location
+      in case it create a meta-data block.
 
+33? Online verification.
+
 plus-banches:
 ----------------------
 

Modified: trunk/user/drbdadm_usage_cnt.c
===================================================================
--- trunk/user/drbdadm_usage_cnt.c	2006-02-14 09:53:49 UTC (rev 2075)
+++ trunk/user/drbdadm_usage_cnt.c	2006-02-22 17:26:01 UTC (rev 2076)
@@ -41,6 +41,7 @@
 #include <netdb.h>
 
 #include "drbdadm.h"
+#include "drbdtool_common.h"
 #include "drbd_endian.h"
 #include "linux/drbd.h"		/* only use DRBD_MAGIC from here! */
 
@@ -60,31 +61,73 @@
 	struct node_info ni;
 } __attribute((packed));
 
-/* FIX: mark plus versions, mark production vs beta releases.
-        read the version string from the /proc file, so we
-	look at the version of the module and not at the version
-	of the drbdadm executable.
+/* For our purpose (finding the revision) SLURP_SIZE is always enough.
  */
-static unsigned int numeric_version_code(char* text)
+static char* slurp_proc_drbd()
 {
-	unsigned int nc;
-	char buffer[5], *c, *b;
-	unsigned m = 1000000;
+	const int SLURP_SIZE = 4096;
+	char* buffer;
+	int rr, fd;
 
-	nc = 0;
-	c = text;
+	fd = open("/proc/drbd",O_RDONLY);
+	if( fd == -1) return 0;
+	
+	buffer = malloc(SLURP_SIZE);
+	if(!buffer) return 0;
 
-	while(*c) {
-		while(!isdigit(*c)) c++;
-		b = buffer;
-		while(isdigit(*c)) *b++=*c++;
-		*b=0;
+	rr = read(fd, buffer, SLURP_SIZE-1);
+	if( rr == -1) {
+		free(buffer);
+		return 0;
+	}
+	
+	buffer[rr]=0;
+	close(fd);
 
-		nc = nc + atoi( buffer ) * m;
-		m=m/1000;
+	return buffer;
+}
+
+static unsigned int extract_svn_revision(char* text)
+{
+	char token[40];
+	unsigned int svn_rev = 0;
+	int plus=0;
+	enum { begin,f_svn,f_rev } ex=begin;
+
+	while(sget_token(token,40,&text) != EOF) {
+		switch(ex) {
+		case begin: 
+			if(!strcmp(token,"plus")) plus = 1;
+			if(!strcmp(token,"SVN"))  ex = f_svn;
+			break;
+		case f_svn:
+			if(!strcmp(token,"Revision:"))  ex = f_rev;
+			break;
+		case f_rev:
+			svn_rev = atol(token); 
+			goto out;
+		}
 	}
+ out:
+	svn_rev = svn_rev * 10;
+	if( svn_rev && plus ) svn_rev += 1;
+	return svn_rev;
+}
 
-	return nc;
+static unsigned int current_svn_revision()
+{
+	char* version_txt;
+	unsigned int svn_rev;
+
+	version_txt = slurp_proc_drbd();
+	if(version_txt) {
+		svn_rev = extract_svn_revision(version_txt);
+		free(version_txt);
+	} else {
+		svn_rev = extract_svn_revision(drbd_buildtag());
+	}
+
+	return svn_rev;
 }
 
 static void get_random_bytes(void* buffer, int len)
@@ -254,7 +297,7 @@
 
 	if( type == UC_NO ) return;
 
-	current = numeric_version_code(REL_VERSION);
+	current = current_svn_revision();
 
 	if( ! read_node_id(&ni) ) {
 		get_random_bytes(&ni.node_uuid,sizeof(ni.node_uuid));
@@ -319,3 +362,4 @@
 		fgets(answer,9,stdin);
 	}
 }
+

Modified: trunk/user/drbdtool_common.c
===================================================================
--- trunk/user/drbdtool_common.c	2006-02-14 09:53:49 UTC (rev 2075)
+++ trunk/user/drbdtool_common.c	2006-02-22 17:26:01 UTC (rev 2076)
@@ -373,3 +373,23 @@
 	*sp=0;
 	return 1;
 }
+
+int sget_token(char *s, int size, char** text)
+{
+	int c;
+	char* sp = s;
+
+	do { // eat white spaces in front.
+		c = *(*text)++;
+		if( c == 0) return EOF;
+	} while (!isgraph(c));
+
+	do { // read the first word into s
+		*sp++ = c;
+		c = *(*text)++;
+		if ( c == 0) break;
+	} while (isgraph(c) && --size);
+
+	*sp=0;
+	return 1;
+}

Modified: trunk/user/drbdtool_common.h
===================================================================
--- trunk/user/drbdtool_common.h	2006-02-14 09:53:49 UTC (rev 2075)
+++ trunk/user/drbdtool_common.h	2006-02-22 17:26:01 UTC (rev 2076)
@@ -36,5 +36,6 @@
 extern void dt_print_uuids(const __u64* uuid, unsigned int flags);
 extern void dt_pretty_print_uuids(const __u64* uuid, unsigned int flags);
 extern int fget_token(char *s, int size, FILE* stream);
+extern int sget_token(char *s, int size, char** text);
 
 #endif

From drbd-cvs at lists.linbit.com  Wed Feb 22 23:09:37 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Wed Feb 22 23:09:39 2006
Subject: [DRBD-cvs] svn commit by phil - r2077 - trunk/user - Now a node
	comment can be stored at usage.drbd.org as w
Message-ID: <20060222220937.6F219163E1@mail.linbit.com>

Author: phil
Date: 2006-02-22 23:09:36 +0100 (Wed, 22 Feb 2006)
New Revision: 2077

Modified:
   trunk/user/drbdadm_usage_cnt.c
   trunk/user/drbdtool_common.c
   trunk/user/drbdtool_common.h
Log:
Now a node comment can be stored at usage.drbd.org as well.


Modified: trunk/user/drbdadm_usage_cnt.c
===================================================================
--- trunk/user/drbdadm_usage_cnt.c	2006-02-22 17:26:01 UTC (rev 2076)
+++ trunk/user/drbdadm_usage_cnt.c	2006-02-22 22:09:36 UTC (rev 2077)
@@ -87,7 +87,7 @@
 	return buffer;
 }
 
-static unsigned int extract_svn_revision(char* text)
+static unsigned int extract_svn_revision(const char* text)
 {
 	char token[40];
 	unsigned int svn_rev = 0;
@@ -284,8 +284,33 @@
 	return make_get_request(req_buf);
 }
 
+static void url_encode(char* in, char* out)
+{
+	char *h = "0123456789abcdef";
+	char c;
+
+	while( (c = *in++) != 0 ) {
+		if( c == '\n' ) break;
+		if( ( 'a' <= c && c <= 'z' )
+		    || ( 'A' <= c && c <= 'Z' )
+		    || ( '0' <= c && c <= '9' )
+		    || c == '-' || c == '_' || c == '.' )
+			*out++ = c;
+		else if( c == ' ' )
+			*out++ = '+';
+		else {
+			*out++ = '%';
+			*out++ = h[c >> 4];
+			*out++ = h[c & 0x0f];
+		}
+	}
+	*out = 0;
+}
+
 /* Ensure that the node is counted on http://usage.drbd.org
  */
+#define ANSWER_SIZE 80
+
 void uc_node(enum usage_count_type type)
 {
 	struct node_info ni;
@@ -293,7 +318,8 @@
 	u32 current;
 	int send = 0;
 	int update = 0;
-	char answer[10];
+	char answer[ANSWER_SIZE];
+	char n_comment[ANSWER_SIZE*3];
 
 	if( type == UC_NO ) return;
 
@@ -324,7 +350,7 @@
 "DRBD's version number are sent to "HTTP_HOST".\n\n"
 "The benifits for you are:\n"
 " * As a respose to your data, the server ("HTTP_HOST") will tell you\n"
-"   how many users before your have installed this version (%s).\n"
+"   how many users before you have installed this version (%s).\n"
 " * With a high counter the DRBD developers have a high motivation to\n"
 "   continue development of the software.\n\n"
 "The following string will be send to the server:\n"
@@ -333,17 +359,22 @@
 "simply issue the query string with your favourite web browser or wget\n\n"
 "You can control all this by setting 'usage-count' in the globals section\n"
 "of your drbd.conf\n\n"
-"Just press [enter] or enter 'no'[enter] to opt out: ",
+"Just press [return], 'no' to opt out or give an optional node comment: ",
 			update ? "an update" : "a new installation",
 			REL_VERSION,ni.node_uuid, ni.version_code);
-		fgets(answer,9,stdin);
+		fgets(answer,ANSWER_SIZE,stdin);
 		if(!strcmp(answer,"no")) send = 0;
 	}
 
-        ssprintf(req_buf,"GET http://"HTTP_HOST"/cgi-bin/insert_usage.pl?"
-		 "nu="U64"&nv="U32" HTTP/1.0\n\n",
-		 ni.node_uuid, ni.version_code);
 
+	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,
+		 n_comment[0] ? "&nc=" : "", n_comment);
+
 	if (send) {
 		write_node_id(&ni);
 

Modified: trunk/user/drbdtool_common.c
===================================================================
--- trunk/user/drbdtool_common.c	2006-02-22 17:26:01 UTC (rev 2076)
+++ trunk/user/drbdtool_common.c	2006-02-22 22:09:36 UTC (rev 2077)
@@ -374,7 +374,7 @@
 	return 1;
 }
 
-int sget_token(char *s, int size, char** text)
+int sget_token(char *s, int size, const char** text)
 {
 	int c;
 	char* sp = s;

Modified: trunk/user/drbdtool_common.h
===================================================================
--- trunk/user/drbdtool_common.h	2006-02-22 17:26:01 UTC (rev 2076)
+++ trunk/user/drbdtool_common.h	2006-02-22 22:09:36 UTC (rev 2077)
@@ -36,6 +36,6 @@
 extern void dt_print_uuids(const __u64* uuid, unsigned int flags);
 extern void dt_pretty_print_uuids(const __u64* uuid, unsigned int flags);
 extern int fget_token(char *s, int size, FILE* stream);
-extern int sget_token(char *s, int size, char** text);
+extern int sget_token(char *s, int size, const char** text);
 
 #endif

From drbd-cvs at lists.linbit.com  Thu Feb 23 18:46:30 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Thu Feb 23 18:46:32 2006
Subject: [DRBD-cvs] svn commit by phil - r2078 - in trunk: drbd user -
	Finaly implemented the usage counting of resources. 
Message-ID: <20060223174630.69506163E1@mail.linbit.com>

Author: phil
Date: 2006-02-23 18:46:28 +0100 (Thu, 23 Feb 2006)
New Revision: 2078

Modified:
   trunk/drbd/drbd_main.c
   trunk/user/drbdadm.h
   trunk/user/drbdadm_main.c
   trunk/user/drbdadm_usage_cnt.c
   trunk/user/drbdmeta.c
   trunk/user/drbdtool_common.c
   trunk/user/drbdtool_common.h
Log:
Finaly implemented the usage counting of resources. 


Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-02-22 22:09:36 UTC (rev 2077)
+++ trunk/drbd/drbd_main.c	2006-02-23 17:46:28 UTC (rev 2078)
@@ -2401,6 +2401,7 @@
 struct meta_data_on_disk {
 	u64 la_size;           // last agreed size.
 	u64 uuid[UUID_SIZE];   // UUIDs.
+	u64 device_uuid;
 	u32 flags;             // MDF
 	u32 magic;
 	u32 md_size_sect;

Modified: trunk/user/drbdadm.h
===================================================================
--- trunk/user/drbdadm.h	2006-02-22 22:09:36 UTC (rev 2077)
+++ trunk/user/drbdadm.h	2006-02-23 17:46:28 UTC (rev 2078)
@@ -85,6 +85,7 @@
 extern int adm_connect(struct d_resource* ,const char* );
 extern int adm_resize(struct d_resource* ,const char* );
 extern int adm_syncer(struct d_resource* ,const char* );
+extern int admm_generic(struct d_resource* ,const char* );
 extern int m_system(char**,int );
 extern struct d_option* find_opt(struct d_option*,char*);
 extern void validate_resource(struct d_resource *);
@@ -93,7 +94,9 @@
 extern void schedule_dcmd( int (* function)(struct d_resource*,const char* ),
 			   struct d_resource* res,
 			   int order);
+
 extern void uc_node(enum usage_count_type type);
+extern int adm_create_md(struct d_resource* res ,const char* cmd);
 
 extern char* config_file;
 extern int config_valid;
@@ -107,7 +110,10 @@
 extern char ss_buffer[255];
 extern struct utsname nodeinfo;
 
+extern char* setup_opts[10];
+extern int soi;
 
+
 /* ssprintf() places the result of the printf in the current stack
    frame and sets ptr to the resulting string. If the current stack
    frame is destroyed (=function returns), the allocated memory is

Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c	2006-02-22 22:09:36 UTC (rev 2077)
+++ trunk/user/drbdadm_main.c	2006-02-23 17:46:28 UTC (rev 2078)
@@ -97,7 +97,7 @@
 static int sh_ll_dev(struct d_resource* ,const char* );
 static int sh_md_dev(struct d_resource* ,const char* );
 static int sh_md_idx(struct d_resource* ,const char* );
-static int admm_generic(struct d_resource* ,const char* );
+       int admm_generic(struct d_resource* ,const char* );
 static int adm_khelper(struct d_resource* ,const char* );
 static int adm_generic_b(struct d_resource* ,const char* );
 static int hidden_cmds(struct d_resource* ,const char* );
@@ -198,7 +198,7 @@
   { "state",             adm_generic_s, 1,1,0 },
   { "cstate",            adm_generic_s, 1,1,1 },
   { "dump",              adm_dump,      1,1,1 },
-  { "create-md",         admm_generic,  1,1,0 },
+  { "create-md",         adm_create_md, 1,1,0 },
   { "show-gi",           adm_generic_b, 1,1,0 },
   { "get-gi",            adm_generic_b, 1,1,0 },
   { "dump-md",           admm_generic,  1,1,0 },
@@ -628,7 +628,7 @@
   return m_system(argv,SLEEPS_SHORT);
 }
 
-static int admm_generic(struct d_resource* res ,const char* cmd)
+int admm_generic(struct d_resource* res ,const char* cmd)
 {
   char* argv[20];
   int argc=0,i;

Modified: trunk/user/drbdadm_usage_cnt.c
===================================================================
--- trunk/user/drbdadm_usage_cnt.c	2006-02-22 22:09:36 UTC (rev 2077)
+++ trunk/user/drbdadm_usage_cnt.c	2006-02-23 17:46:28 UTC (rev 2078)
@@ -276,14 +276,6 @@
 	return 0;
 }
 
-static int insert_resource(u64 node_uuid, u64 res_uuid, u64 res_size) {
-	char *req_buf;
-        ssprintf( req_buf, "GET http://"HTTP_HOST"/cgi-bin/insert_usage.pl?"
-		  "nu="U64"&ru="U64"&rs="U64" HTTP/1.0\n\n",
-		  node_uuid, res_uuid, res_size);
-	return make_get_request(req_buf);
-}
-
 static void url_encode(char* in, char* out)
 {
 	char *h = "0123456789abcdef";
@@ -394,3 +386,106 @@
 	}
 }
 
+/* For our purpose (finding the revision) SLURP_SIZE is always enough.
+ */
+char* run_adm_function( int (* function)(struct d_resource*,const char* ), 
+			struct d_resource* res ,const char* cmd)
+{
+	const int SLURP_SIZE = 4096;
+	int rr,pipes[2];
+	char* buffer;
+	pid_t pid;
+
+	buffer = malloc(SLURP_SIZE);
+	if(!buffer) return 0;
+
+	if(pipe(pipes)) return 0;
+
+	pid = fork();
+	if(pid == -1) {
+		fprintf(stderr,"Can not fork\n");
+		exit(E_exec_error);
+	}
+	if(pid == 0) {
+		// child
+		close(pipes[0]); // close reading end
+		dup2(pipes[1],1); // 1 = stdout
+		close(pipes[1]);
+		exit(function(res,cmd));
+	}
+	close(pipes[1]); // close writing end
+
+	rr = read(pipes[0], buffer, SLURP_SIZE-1);
+	if( rr == -1) {
+		free(buffer);
+		// FIXME cleanup
+		return 0;
+	}
+	buffer[rr]=0;
+	close(pipes[0]);
+	
+	waitpid(pid,0,0);
+
+	return buffer;
+}
+
+int adm_create_md(struct d_resource* res ,const char* cmd)
+{
+	char answer[ANSWER_SIZE];
+	struct node_info ni;
+	u64 device_uuid=0;
+	u64 device_size=0;
+	char *req_buf;
+	int send=0;
+	char *tb;
+	int rv,fd;
+
+	tb = run_adm_function(admm_generic, res, "read-dev-uuid");
+	device_uuid = strto_u64(tb,NULL,16);
+	free(tb);
+
+	rv = admm_generic(res, cmd); // cmd is "create-md".
+
+	if(!device_uuid) {
+		get_random_bytes(&device_uuid, sizeof(u64));
+	}
+
+	fd = open(res->me->disk,O_RDONLY);
+	if( fd != -1) {
+		device_size = bdev_size(fd);
+		close(fd);
+	}
+
+	if( read_node_id(&ni) && device_size ) {
+		if( global_options.usage_count == UC_YES ) send = 1;
+		if( global_options.usage_count == UC_ASK ) {
+			printf(
+"\n"
+"\t\t--== Creating metadata ==--\n"
+"As with nodes we count the total number of devices mirrored by DRBD at\n"
+"at http://"HTTP_HOST".\n\n"
+"The conter works completely anonymous. A random number gets created for\n"
+"this device, and that randomer number and the devices size will be sent.\n\n"
+"http://"HTTP_HOST"/cgi-bin/insert_usage.pl?nu="U64"&ru="U64"&rs="U64"\n\n"
+"Enter 'no' to opt out, or just press [return] to continue:",
+				ni.node_uuid,device_uuid,device_size
+				);
+		fgets(answer,ANSWER_SIZE,stdin);
+		if(strcmp(answer,"no")) send = 1;
+		}
+	}
+
+	if (send) {
+		ssprintf(req_buf,"GET http://"HTTP_HOST"/cgi-bin/insert_usage.pl?"
+			 "nu="U64"&ru="U64"&rs="U64" HTTP/1.0\n\n",
+			 ni.node_uuid, device_uuid, device_size);
+		make_get_request(req_buf);
+	}
+
+	ssprintf( setup_opts[0], X64(016), device_uuid);
+	soi=1;
+	admm_generic(res, "write-dev-uuid");
+
+	return rv;
+}
+

Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2006-02-22 22:09:36 UTC (rev 2077)
+++ trunk/user/drbdmeta.c	2006-02-23 17:46:28 UTC (rev 2078)
@@ -40,8 +40,8 @@
 #include <unistd.h>
 #include <fcntl.h>
 
-#include <linux/fs.h>           /* for BLKGETSIZE64 */
 #include <linux/drbd.h>		/* only use DRBD_MAGIC from here! */
+#include <linux/fs.h>           /* for BLKFLSBUF */
 
 #include "drbd_endian.h"
 #include "drbdtool_common.h"
@@ -233,6 +233,7 @@
 	/* Since DRBD 0.8 we have uuid instead of gc */
 	u64 uuid[UUID_SIZE];
 	u32 flags;
+	u64 device_uuid;
 };
 
 /*
@@ -311,31 +312,6 @@
 	int (*outdate_gi) (struct md_cpu *md);
 };
 
-u64 bdev_size(int fd)
-{
-	u64 size64;		/* size in byte. */
-	long size;		/* size in sectors. */
-	int err;
-
-	err = ioctl(fd, BLKGETSIZE64, &size64);
-	if (err) {
-		if (errno == EINVAL) {
-			printf("INFO: falling back to BLKGETSIZE\n");
-			err = ioctl(fd, BLKGETSIZE, &size);
-			if (err) {
-				perror("ioctl(,BLKGETSIZE,) failed");
-				exit(20);
-			}
-			size64 = (u64)512 *size;
-		} else {
-			perror("ioctl(,BLKGETSIZE64,) failed");
-			exit(20);
-		}
-	}
-
-	return size64;
-}
-
 void *my_mmap(const char* func, const unsigned int line, const char* what,
 	size_t length, int prot , int flags, int fd, __off64_t offset)
 {
@@ -547,13 +523,15 @@
 struct __attribute__ ((packed)) md_on_disk_08 {
 	be_u64 la_sect;		/* last agreed size. */
 	be_u64 uuid[UUID_SIZE];   // UUIDs.
+	be_u64 device_uuid;
 	be_u32 flags;
 	be_u32 magic;
 	be_u32 md_size_sect;
 	be_s32 al_offset;	/* signed sector offset to this block */
 	be_u32 al_nr_extents;	/* important for restoring the AL */
 	be_s32 bm_offset;	/* signed sector offset to the bitmap, from here */
-	char reserved[8 * 512 - (8*(UUID_SIZE+1)+4*6)];
+	
+	char reserved[8 * 512 - (8*(UUID_SIZE+2)+4*6)];
 };
 
 void md_disk_08_to_cpu(struct md_cpu *cpu, const struct md_on_disk_08 *disk)
@@ -564,6 +542,7 @@
 	cpu->la_sect = be64_to_cpu(disk->la_sect.be);
 	for ( i=Current ; i<UUID_SIZE ; i++ )
 		cpu->uuid[i] = be64_to_cpu(disk->uuid[i].be);
+	cpu->device_uuid = be64_to_cpu(disk->device_uuid.be);
 	cpu->flags = be32_to_cpu(disk->flags.be);
 	cpu->magic = be32_to_cpu(disk->magic.be);
 	cpu->md_size_sect = be32_to_cpu(disk->md_size_sect.be);
@@ -579,6 +558,7 @@
 	for ( i=Current ; i<UUID_SIZE ; i++ ) {
 		disk->uuid[i].be = cpu_to_be64(cpu->uuid[i]);
 	}
+	disk->device_uuid.be = cpu_to_be64(cpu->device_uuid);
 	disk->flags.be = cpu_to_be32(cpu->flags);
 	disk->magic.be = cpu_to_be32(cpu->magic);
 	disk->md_size_sect.be = cpu_to_be32(cpu->md_size_sect);
@@ -771,7 +751,10 @@
 int meta_create_md(struct format *cfg, char **argv, int argc);
 int meta_outdate(struct format *cfg, char **argv, int argc);
 int meta_set_gi(struct format *cfg, char **argv, int argc);
+int meta_read_dev_uuid(struct format *cfg, char **argv, int argc);
+int meta_write_dev_uuid(struct format *cfg, char **argv, int argc);
 
+
 struct meta_cmd cmds[] = {
 	{"get-gi", 0, meta_get_gi, 1},
 	{"show-gi", 0, meta_show_gi, 1},
@@ -782,6 +765,8 @@
 	 * implicit convert from v07 to v08 by create-md
 	 * see comments there */
 	{"outdate", 0, meta_outdate, 1},
+	{"read-dev-uuid", "VAL",  meta_read_dev_uuid,  0},
+	{"write-dev-uuid", "VAL", meta_write_dev_uuid, 0},
 	{"set-gi", ":::VAL:VAL:...", meta_set_gi, 0},
 };
 
@@ -2126,6 +2111,45 @@
 }
 #endif
 
+int meta_read_dev_uuid(struct format *cfg, char **argv __attribute((unused)), int argc)
+{
+	if (argc > 0) {
+		fprintf(stderr, "Ignoring additional arguments\n");
+	}
+
+	if (cfg->ops->open(cfg))
+		return -1;
+
+	printf(X64(016)"\n",cfg->md.device_uuid);
+
+	return cfg->ops->close(cfg);	
+}
+
+int meta_write_dev_uuid(struct format *cfg, char **argv, int argc)
+{
+	int err;
+
+	if (argc > 1) {
+		fprintf(stderr, "Ignoring additional arguments\n");
+	}
+	if (argc < 1) {
+		fprintf(stderr, "Required Argument missing\n");
+		exit(10);
+	}
+
+	if (cfg->ops->open(cfg))
+		return -1;
+
+	cfg->md.device_uuid = strto_u64(argv[0],NULL,16);
+
+	err = cfg->ops->md_cpu_to_disk(cfg);
+	err = cfg->ops->close(cfg) || err;
+	if (err)
+		fprintf(stderr, "update failed\n");
+
+	return err;
+}
+
 char *progname = NULL;
 void print_usage_and_exit()
 {

Modified: trunk/user/drbdtool_common.c
===================================================================
--- trunk/user/drbdtool_common.c	2006-02-22 22:09:36 UTC (rev 2077)
+++ trunk/user/drbdtool_common.c	2006-02-23 17:46:28 UTC (rev 2078)
@@ -13,8 +13,8 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include <linux/drbd.h>
+#include <linux/fs.h>           /* for BLKGETSIZE64 */
 
-#include "drbd_endian.h"
 #include "drbdtool_common.h"
 
 char* ppsize(char* buf, size_t size) 
@@ -393,3 +393,28 @@
 	*sp=0;
 	return 1;
 }
+
+u64 bdev_size(int fd)
+{
+	u64 size64;		/* size in byte. */
+	long size;		/* size in sectors. */
+	int err;
+
+	err = ioctl(fd, BLKGETSIZE64, &size64);
+	if (err) {
+		if (errno == EINVAL) {
+			printf("INFO: falling back to BLKGETSIZE\n");
+			err = ioctl(fd, BLKGETSIZE, &size);
+			if (err) {
+				perror("ioctl(,BLKGETSIZE,) failed");
+				exit(20);
+			}
+			size64 = (u64)512 *size;
+		} else {
+			perror("ioctl(,BLKGETSIZE64,) failed");
+			exit(20);
+		}
+	}
+
+	return size64;
+}

Modified: trunk/user/drbdtool_common.h
===================================================================
--- trunk/user/drbdtool_common.h	2006-02-22 22:09:36 UTC (rev 2077)
+++ trunk/user/drbdtool_common.h	2006-02-23 17:46:28 UTC (rev 2078)
@@ -2,6 +2,7 @@
 #define DRBDTOOL_COMMON_H
 
 #include <asm/types.h>
+#include "drbd_endian.h"
 
 #define ARRY_SIZE(A) (sizeof(A)/sizeof(A[0]))
 
@@ -37,5 +38,5 @@
 extern void dt_pretty_print_uuids(const __u64* uuid, unsigned int flags);
 extern int fget_token(char *s, int size, FILE* stream);
 extern int sget_token(char *s, int size, const char** text);
-
+extern u64 bdev_size(int fd);
 #endif

From drbd-cvs at lists.linbit.com  Fri Feb 24 12:43:11 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri Feb 24 12:43:12 2006
Subject: [DRBD-cvs] svn commit by phil - r2079 - in trunk: . drbd user -
	Propagated most of the changes from the 07 branch to th
Message-ID: <20060224114311.B174F163E1@mail.linbit.com>

Author: phil
Date: 2006-02-24 12:43:09 +0100 (Fri, 24 Feb 2006)
New Revision: 2079

Modified:
   trunk/
   trunk/drbd/drbd_actlog.c
   trunk/drbd/drbd_fs.c
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_receiver.c
   trunk/user/drbdadm_main.c
   trunk/user/drbdadm_usage_cnt.c
Log:
Propagated most of the changes from the 07 branch to the trunk.



Property changes on: trunk
___________________________________________________________________
Name: propagate:at
   - 2040
   + 2068

Modified: trunk/drbd/drbd_actlog.c
===================================================================
--- trunk/drbd/drbd_actlog.c	2006-02-23 17:46:28 UTC (rev 2078)
+++ trunk/drbd/drbd_actlog.c	2006-02-24 11:43:09 UTC (rev 2079)
@@ -162,8 +162,15 @@
 	unsigned int enr;
 };
 
-STATIC void drbd_al_write_transaction(struct Drbd_Conf *,struct lc_element *,
-				      unsigned int );
+struct update_al_work {
+	struct drbd_work w;
+	struct lc_element * al_ext;
+	struct completion event;
+	unsigned int enr;
+};
+
+STATIC int w_al_write_transaction(struct Drbd_Conf *, struct drbd_work *, int);
+
 static inline
 struct lc_element* _al_get(struct Drbd_Conf *mdev, unsigned int enr)
 {
@@ -200,6 +207,7 @@
 {
 	unsigned int enr = (sector >> (AL_EXTENT_SIZE_B-9));
 	struct lc_element *al_ext;
+	struct update_al_work al_work;
 
 	D_ASSERT(atomic_read(&mdev->local_cnt)>0);
 	wait_event(mdev->al_wait, (al_ext = _al_get(mdev,enr)) );
@@ -213,7 +221,19 @@
 		if(mdev->state.conn < Connected && evicted != LC_FREE ) {
 			drbd_bm_write_sect(mdev, evicted/AL_EXT_PER_BM_SECT );
 		}
-		drbd_al_write_transaction(mdev,al_ext,enr);
+
+		/* drbd_al_write_transaction(mdev,al_ext,enr);
+		   generic_make_request() are serialized on the 
+		   current->bio_tail list now. Therefore we have
+		   to deligate writing something to AL to the
+		   worker thread. */
+		init_completion(&al_work.event);
+		al_work.al_ext = al_ext;
+		al_work.enr = enr;
+		al_work.w.cb = w_al_write_transaction;
+		drbd_queue_work_front(mdev,&mdev->data.work,&al_work.w);
+		wait_for_completion(&al_work.event);
+		
 		mdev->al_writ_cnt++;
 
 		/*
@@ -250,9 +270,8 @@
 	spin_unlock_irqrestore(&mdev->al_lock,flags);
 }
 
-STATIC void
-drbd_al_write_transaction(struct Drbd_Conf *mdev,struct lc_element *updated,
-			  unsigned int new_enr)
+STATIC int
+w_al_write_transaction(struct Drbd_Conf *mdev, struct drbd_work *w, int unused)
 {
 	int i,n,mx;
 	unsigned int extent_nr;
@@ -260,6 +279,9 @@
 	sector_t sector;
 	u32 xor_sum=0;
 
+	struct lc_element *updated = ((struct update_al_work*)w)->al_ext;
+	unsigned int new_enr = ((struct update_al_work*)w)->enr;
+
 	down(&mdev->md_io_mutex); // protects md_io_buffer, al_tr_cycle, ...
 	buffer = (struct al_transaction*)page_address(mdev->md_io_page);
 
@@ -311,6 +333,10 @@
 	mdev->al_tr_number++;
 
 	up(&mdev->md_io_mutex);
+
+	complete(&((struct update_al_work*)w)->event);
+
+	return 1;
 }
 
 STATIC int drbd_al_read_tr(struct Drbd_Conf *mdev,

Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c	2006-02-23 17:46:28 UTC (rev 2078)
+++ trunk/drbd/drbd_fs.c	2006-02-24 11:43:09 UTC (rev 2079)
@@ -120,10 +120,13 @@
 	}
 
 	if ( la_size_changed || md_moved ) {
-		drbd_al_shrink(mdev); // All extents inactive.
-		drbd_bm_write(mdev);  // write bitmap
-		// Write mdev->bc->md.la_size_sect to [possibly new position on] disk.
-		drbd_md_mark_dirty(mdev);
+		if( inc_local_md_only(mdev)) {
+			drbd_al_shrink(mdev); // All extents inactive.
+			drbd_bm_write(mdev);  // write bitmap
+			// Write mdev->la_size to on disk.
+			drbd_md_mark_dirty(mdev);
+			dec_local(mdev);
+		}
 	}
   out:
 	lc_unlock(mdev->act_log);
@@ -472,6 +475,27 @@
 	 * drbd_set_recv_tcq(mdev,drbd_queue_order_type(mdev)==QUEUE_ORDERED_TAG);
 	 */
 
+	/* If I am currently not Primary,
+	 * but meta data primary indicator is set,
+	 * I just now recover from a hard crash,
+	 * and have been Primary before that crash.
+	 *
+	 * Now, if I had no connection before that crash
+	 * (have been degraded Primary), chances are that
+	 * I won't find my peer now either.
+	 *
+	 * In that case, and _only_ in that case,
+	 * we use the degr-wfc-timeout instead of the default,
+	 * so we can automatically recover from a crash of a
+	 * degraded but active "cluster" after a certain timeout.
+	 */
+	clear_bit(USE_DEGR_WFC_T,&mdev->flags);
+	if ( mdev->state != Primary &&
+	     drbd_md_test_flag(mdev,MDF_PrimaryInd) &&
+	    !drbd_md_test_flag(mdev,MDF_ConnectedInd) ) {
+		set_bit(USE_DEGR_WFC_T,&mdev->flags);
+	}
+
 	drbd_bm_lock(mdev); // racy...
 	drbd_determin_dev_size(mdev);
 
@@ -919,24 +943,7 @@
 	if(copy_from_user(&p,arg,sizeof(p))) {
 		return -EFAULT;
 	}
-
-	/* If I am currently not Primary,
-	 * but meta data primary indicator is set,
-	 * I just now recover from a hard crash,
-	 * and have been Primary before that crash.
-	 *
-	 * Now, if I had no connection before that crash
-	 * (have been degraded Primary), chances are that
-	 * I won't find my peer now either.
-	 *
-	 * In that case, and _only_ in that case,
-	 * we use the degr-wfc-timeout instead of the default,
-	 * so we can automatically recover from a crash of a
-	 * degraded but active "cluster" after a certain timeout.
-	 */
-	if ( mdev->state.role != Primary &&
-	     drbd_md_test_flag(mdev,MDF_PrimaryInd) &&
-	    !drbd_md_test_flag(mdev,MDF_ConnectedInd) ) {
+	if ( test_bit(USE_DEGR_WFC_T,&mdev->flags) ) {
 		time=p.degr_wfc_timeout;
 		if (time) WARN("using degr_wfc_timeout=%ld seconds\n", time);
 	} else {

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2006-02-23 17:46:28 UTC (rev 2078)
+++ trunk/drbd/drbd_int.h	2006-02-24 11:43:09 UTC (rev 2079)
@@ -637,6 +637,7 @@
 	SYNC_STARTED,		// Needed to agree on the exact point in time..
 	UNIQUE,                 // Set on one node, cleared on the peer!
 	SPLIT_BRAIN_FIX,        // Set if split-brain-fix is configured
+	USE_DEGR_WFC_T		// Use degr-wfc-timeout instead of wfc-timeout.
 };
 
 struct drbd_bitmap; // opaque for Drbd_Conf

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-02-23 17:46:28 UTC (rev 2078)
+++ trunk/drbd/drbd_receiver.c	2006-02-24 11:43:09 UTC (rev 2079)
@@ -38,6 +38,7 @@
 #include <linux/version.h>
 #include <linux/fs.h>
 #include <linux/file.h>
+#include <linux/in.h>
 #include <linux/mm.h>
 #include <linux/drbd_config.h>
 #include <linux/mm_inline.h>
@@ -731,6 +732,7 @@
 	drbd_send_sizes(mdev);
 	drbd_send_uuids(mdev);
 	drbd_send_state(mdev);
+	clear_bit(USE_DEGR_WFC_T,&mdev->flags);
 
 	return 1;
 }

Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c	2006-02-23 17:46:28 UTC (rev 2078)
+++ trunk/user/drbdadm_main.c	2006-02-24 11:43:09 UTC (rev 2079)
@@ -323,8 +323,11 @@
 static int sh_resources(struct d_resource* ignored __attribute((unused)),const char* unused __attribute((unused)))
 {
   struct d_resource *res,*t;
+  int first=1;
+
   for_each_resource(res,t,config) {
-    printf(res==config?"%s":" %s",esc(res->name));
+    printf(first?"%s":" %s",esc(res->name));
+    first=0;
   }
   printf("\n");
 

Modified: trunk/user/drbdadm_usage_cnt.c
===================================================================
--- trunk/user/drbdadm_usage_cnt.c	2006-02-23 17:46:28 UTC (rev 2078)
+++ trunk/user/drbdadm_usage_cnt.c	2006-02-24 11:43:09 UTC (rev 2079)
@@ -464,7 +464,7 @@
 "\t\t--== Creating metadata ==--\n"
 "As with nodes we count the total number of devices mirrored by DRBD at\n"
 "at http://"HTTP_HOST".\n\n"
-"The conter works completely anonymous. A random number gets created for\n"
+"The counter works completely anonymous. A random number gets created for\n"
 "this device, and that randomer number and the devices size will be sent.\n\n"
 "http://"HTTP_HOST"/cgi-bin/insert_usage.pl?nu="U64"&ru="U64"&rs="U64"\n\n"
 "Enter 'no' to opt out, or just press [return] to continue:",

From drbd-cvs at lists.linbit.com  Fri Feb 24 15:20:21 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri Feb 24 15:20:22 2006
Subject: [DRBD-cvs] svn commit by phil - r2080 - in trunk/drbd: . linux -
	Forward ported the patch that prevents shrinking of con
Message-ID: <20060224142021.3EE1D163E1@mail.linbit.com>

Author: phil
Date: 2006-02-24 15:20:19 +0100 (Fri, 24 Feb 2006)
New Revision: 2080

Modified:
   trunk/drbd/drbd_fs.c
   trunk/drbd/drbd_int.h
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/linux/drbd.h
Log:
Forward ported the patch that prevents shrinking of consistent devices.


Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c	2006-02-24 11:43:09 UTC (rev 2079)
+++ trunk/drbd/drbd_fs.c	2006-02-24 14:20:19 UTC (rev 2080)
@@ -87,15 +87,32 @@
 		break;
 	}
 }
+
+char* ppsize(char* buf, size_t size)
+{
+	// Needs 9 bytes at max.
+	static char units[] = { 'K','M','G','T','P','E' };
+	int base = 0;
+	while (size >= 10000 ) {
+		size = size >> 10;
+		base++;
+	}
+	sprintf(buf,"%ld %cB",(long)size,units[base]);
+
+	return buf;
+}
+
 /* You should call drbd_md_sync() after calling this.
  */
-STATIC int do_determin_dev_size(struct Drbd_Conf* mdev);
 int drbd_determin_dev_size(struct Drbd_Conf* mdev)
 {
 	sector_t prev_first_sect, prev_size; // previous meta location
 	sector_t la_size;
+	sector_t size;
+	char ppb[10];
+
 	int md_moved, la_size_changed;
-	int rv;
+	int rv=0;
 
 	wait_event(mdev->al_wait, lc_try_lock(mdev->act_log));
 
@@ -105,7 +122,32 @@
 
 	// TODO: should only be some assert here, not (re)init...
 	drbd_md_set_sector_offsets(mdev,mdev->bc);
-	rv = do_determin_dev_size(mdev);
+
+	size = drbd_new_dev_size(mdev,mdev->bc);
+
+	if( drbd_get_capacity(mdev->this_bdev) != size ) {
+		int err;
+		err = drbd_bm_resize(mdev,size);
+		if (unlikely(err)) {
+			/* currently there is only one error: ENOMEM! */
+			size = drbd_bm_capacity(mdev)>>1;
+			if (size == 0) {
+				ERR("OUT OF MEMORY! Could not allocate bitmap! Set device size => 0\n");
+			} else {
+				/* FIXME this is problematic,
+				 * if we in fact are smaller now! */
+				ERR("BM resizing failed. "
+				    "Leaving size unchanged at size = %lu KB\n",
+				    (unsigned long)size);
+			}
+			rv = err;
+		}
+		// racy, see comments above.
+		drbd_set_my_capacity(mdev,size);
+		mdev->bc->md.la_size_sect = size;
+		INFO("size = %s (%lu KB)\n",ppsize(ppb,size>>1),
+		     (unsigned long)size>>1);
+	}
 	if (rv < 0) goto out;
 
 	la_size_changed = (la_size != mdev->bc->md.la_size_sect);
@@ -120,7 +162,7 @@
 	}
 
 	if ( la_size_changed || md_moved ) {
-		if( inc_local_md_only(mdev)) {
+		if( inc_md_only(mdev,Attaching) ) {
 			drbd_al_shrink(mdev); // All extents inactive.
 			drbd_bm_write(mdev);  // write bitmap
 			// Write mdev->la_size to on disk.
@@ -134,52 +176,20 @@
 	return rv;
 }
 
-char* ppsize(char* buf, size_t size)
+sector_t 
+drbd_new_dev_size(struct Drbd_Conf* mdev, struct drbd_backing_dev *bdev)
 {
-	// Needs 9 bytes at max.
-	static char units[] = { 'K','M','G','T','P','E' };
-	int base = 0;
-	while (size >= 10000 ) {
-		size = size >> 10;
-		base++;
-	}
-	sprintf(buf,"%ld %cB",(long)size,units[base]);
-
-	return buf;
-}
-
-
-/* Returns 1 if there is a disk-less node, 0 if both nodes have a disk.
- * -ENOMEM if we could not allocate the bitmap
- */
-/*
- * *_size is in sectors.
- *
- * FIXME
- * since this is done by drbd receiver as well as from drbdsetup,
- * this actually needs proper locking!
- * drbd_bm_resize already protects itself with a mutex.
- * but again, this is a state change, and thus should be serialized with other
- * state changes on a more general level already.
- */
-STATIC int do_determin_dev_size(struct Drbd_Conf* mdev)
-{
 	sector_t p_size = mdev->p_size;   // partner's disk size.
-	sector_t la_size = mdev->bc->md.la_size_sect; // last agreed size.
+	sector_t la_size = bdev->md.la_size_sect; // last agreed size.
 	sector_t m_size; // my size
-	sector_t u_size = mdev->bc->u_size; // size requested by user.
+	sector_t u_size = bdev->u_size; // size requested by user.
 	sector_t size=0;
-	int rv;
-	char ppb[10];
 
-	m_size = drbd_get_max_capacity(mdev);
-	INFO("msize = %llu\n", (unsigned long long) m_size);
+	m_size = drbd_get_max_capacity(bdev);
 
 	if(p_size && m_size) {
-		rv=0;
 		size=min_t(sector_t,p_size,m_size);
 	} else {
-		rv=1;
 		if(la_size) {
 			size=la_size;
 			if(m_size && m_size < size) size=m_size;
@@ -203,31 +213,7 @@
 		}
 	}
 
-	if( drbd_get_capacity(mdev->this_bdev) != size ) {
-		int err;
-		err = drbd_bm_resize(mdev,size);
-		if (unlikely(err)) {
-			/* currently there is only one error: ENOMEM! */
-			size = drbd_bm_capacity(mdev)>>1;
-			if (size == 0) {
-				ERR("OUT OF MEMORY! Could not allocate bitmap! Set device size => 0\n");
-			} else {
-				/* FIXME this is problematic,
-				 * if we in fact are smaller now! */
-				ERR("BM resizing failed. "
-				    "Leaving size unchanged at size = %lu KB\n",
-				    (unsigned long)size);
-			}
-			rv = err;
-		}
-		// racy, see comments above.
-		drbd_set_my_capacity(mdev,size);
-		mdev->bc->md.la_size_sect = size;
-		INFO("size = %s (%lu KB)\n",ppsize(ppb,size>>1),
-		     (unsigned long)size>>1);
-	}
-
-	return rv;
+	return size;
 }
 
 /** 
@@ -456,6 +442,13 @@
 		goto release_bdev3_fail_ioctl;
 	}
 
+	// Prevent shrinking of consistent devices !
+	if(drbd_md_test_flag(nbc,MDF_Consistent) &&
+	   drbd_new_dev_size(mdev,nbc) < nbc->md.la_size_sect) {
+		retcode = LDDeviceTooSmall;
+		goto release_bdev3_fail_ioctl;
+	}
+
 	// Point of no return reached.
 
 	D_ASSERT(mdev->bc == NULL);
@@ -490,16 +483,16 @@
 	 * degraded but active "cluster" after a certain timeout.
 	 */
 	clear_bit(USE_DEGR_WFC_T,&mdev->flags);
-	if ( mdev->state != Primary &&
-	     drbd_md_test_flag(mdev,MDF_PrimaryInd) &&
-	    !drbd_md_test_flag(mdev,MDF_ConnectedInd) ) {
+	if ( mdev->state.role != Primary &&
+	     drbd_md_test_flag(mdev->bc,MDF_PrimaryInd) &&
+	    !drbd_md_test_flag(mdev->bc,MDF_ConnectedInd) ) {
 		set_bit(USE_DEGR_WFC_T,&mdev->flags);
 	}
 
 	drbd_bm_lock(mdev); // racy...
 	drbd_determin_dev_size(mdev);
 
-	if (drbd_md_test_flag(mdev,MDF_FullSync)) {
+	if (drbd_md_test_flag(mdev->bc,MDF_FullSync)) {
 		INFO("Assuming that all blocks are out of sync (aka FullSync)\n");
 		drbd_bm_set_all(mdev);
 		drbd_bm_write(mdev);
@@ -510,7 +503,7 @@
 	}
 
 	drbd_al_read_log(mdev);
-	if (drbd_md_test_flag(mdev,MDF_PrimaryInd)) {
+	if (drbd_md_test_flag(mdev->bc,MDF_PrimaryInd)) {
 		drbd_al_apply_to_bm(mdev);
 		drbd_al_to_on_disk_bm(mdev);
 	}
@@ -530,8 +523,8 @@
 		   If MDF_WasUpToDate is not set go into Outdated disk state, 
 		   otherwise into Consistent state.
 		*/
-		if(drbd_md_test_flag(mdev,MDF_Consistent)) {
-			if(drbd_md_test_flag(mdev,MDF_WasUpToDate)) {
+		if(drbd_md_test_flag(mdev->bc,MDF_Consistent)) {
+			if(drbd_md_test_flag(mdev->bc,MDF_WasUpToDate)) {
 				nds = Consistent;
 			} else {
 				nds = Outdated;

Modified: trunk/drbd/drbd_int.h
===================================================================
--- trunk/drbd/drbd_int.h	2006-02-24 11:43:09 UTC (rev 2079)
+++ trunk/drbd/drbd_int.h	2006-02-24 14:20:19 UTC (rev 2080)
@@ -874,7 +874,7 @@
 extern void drbd_uuid_set_bm(drbd_dev *mdev, u64 val);
 extern void drbd_md_set_flag(drbd_dev *mdev, int flags);
 extern void drbd_md_clear_flag(drbd_dev *mdev, int flags);
-extern int drbd_md_test_flag(drbd_dev *mdev, int flag);
+extern int drbd_md_test_flag(struct drbd_backing_dev *, int);
 extern void drbd_md_mark_dirty(drbd_dev *mdev);
 
 /* Meta data layout
@@ -1068,6 +1068,7 @@
 
 // drbd_fs.c
 extern char* ppsize(char* buf, size_t size);
+extern sector_t drbd_new_dev_size(struct Drbd_Conf*, struct drbd_backing_dev*);
 extern int drbd_determin_dev_size(drbd_dev*);
 extern void drbd_setup_queue_param(drbd_dev *mdev, unsigned int);
 extern int drbd_set_role(drbd_dev *mdev, int *arg);
@@ -1275,17 +1276,17 @@
 }
 
 /* returns the capacity we announce to out peer */
-static inline sector_t drbd_get_max_capacity(drbd_dev *mdev)
+static inline sector_t drbd_get_max_capacity(struct drbd_backing_dev *bdev)
 {
-	switch (mdev->bc->md_index) {
+	switch (bdev->md_index) {
 	case DRBD_MD_INDEX_INTERNAL:
 	case DRBD_MD_INDEX_FLEX_INT:
-		return drbd_get_capacity(mdev->bc->backing_bdev)
-			? drbd_md_first_sector(mdev->bc)
+		return drbd_get_capacity(bdev->backing_bdev)
+			? drbd_md_first_sector(bdev)
 			: 0;
 	case DRBD_MD_INDEX_FLEX_EXT:
 	default:
-		return drbd_get_capacity(mdev->bc->backing_bdev);
+		return drbd_get_capacity(bdev->backing_bdev);
 	}
 }
 

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2006-02-24 11:43:09 UTC (rev 2079)
+++ trunk/drbd/drbd_main.c	2006-02-24 14:20:19 UTC (rev 2080)
@@ -504,8 +504,8 @@
 	ok = drbd_send_state(mdev);
 	WARN("Notified peer that my disk is broken.\n");
 
-	D_ASSERT(drbd_md_test_flag(mdev,MDF_FullSync));
-	D_ASSERT(!drbd_md_test_flag(mdev,MDF_Consistent));
+	D_ASSERT(drbd_md_test_flag(mdev->bc,MDF_FullSync));
+	D_ASSERT(!drbd_md_test_flag(mdev->bc,MDF_Consistent));
 	drbd_md_sync(mdev);
 
 	if ( wait_event_interruptible_timeout(mdev->cstate_wait,
@@ -1109,7 +1109,7 @@
 
 	if(inc_md_only(mdev,Attaching)) {
 		D_ASSERT(mdev->bc->backing_bdev);
-		d_size = drbd_get_max_capacity(mdev);
+		d_size = drbd_get_max_capacity(mdev->bc);
 		p.u_size = cpu_to_be64(mdev->bc->u_size);
 		dec_local(mdev);
 	} else d_size = 0;
@@ -1160,7 +1160,7 @@
 	p  = vmalloc(PAGE_SIZE); // sleeps. cannot fail.
 	buffer = (unsigned long*)p->payload;
 
-	if (drbd_md_test_flag(mdev,MDF_FullSync)) {
+	if (drbd_md_test_flag(mdev->bc,MDF_FullSync)) {
 		drbd_bm_set_all(mdev);
 		drbd_bm_write(mdev);
 		if (unlikely(mdev->state.disk <= Failed )) {
@@ -2630,10 +2630,9 @@
 		mdev->bc->md.flags &= ~flag;
 	}
 }
-int drbd_md_test_flag(drbd_dev *mdev, int flag)
+int drbd_md_test_flag(struct drbd_backing_dev *bdev, int flag)
 {
-	MUST_HOLD(mdev->req_lock);
-	return ((mdev->bc->md.flags & flag) != 0);
+	return ((bdev->md.flags & flag) != 0);
 }
 
 STATIC void md_sync_timer_fn(unsigned long data)

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-02-24 11:43:09 UTC (rev 2079)
+++ trunk/drbd/drbd_receiver.c	2006-02-24 14:20:19 UTC (rev 2080)
@@ -1717,7 +1717,7 @@
 	}
 
 	if (hg > 0) { // become sync source.
-		D_ASSERT(drbd_md_test_flag(mdev,MDF_Consistent));
+		D_ASSERT(drbd_md_test_flag(mdev->bc,MDF_Consistent));
 		rv = WFBitMapS;
 	} else if (hg < 0) { // become sync target
 		drbd_md_clear_flag(mdev,MDF_Consistent);
@@ -1831,7 +1831,7 @@
 {
 	Drbd_Sizes_Packet *p = (Drbd_Sizes_Packet*)h;
 	unsigned int max_seg_s;
-	sector_t p_size, p_usize;
+	sector_t p_size, p_usize, my_usize;
 	drbd_conns_t nconn;
 
 	ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE;
@@ -1861,11 +1861,25 @@
 			p_usize = min_not_zero(mdev->bc->u_size, p_usize);
 		}
 
+		my_usize = mdev->bc->u_size;
+
 		if( mdev->bc->u_size != p_usize ) {
 			mdev->bc->u_size = p_usize;
 			INFO("Peer sets u_size to %lu KB\n",
 			     (unsigned long)mdev->bc->u_size);
 		}
+
+		// Never shrink a device with usable data.
+		if(drbd_new_dev_size(mdev,mdev->bc) < 
+		   drbd_get_capacity(mdev->this_bdev) &&
+		   mdev->state.disk >= Outdated ) {
+			dec_local(mdev);
+			ERR("The peer's disk size is too small!\n");
+			drbd_force_state(mdev,NS(conn,StandAlone));
+			drbd_thread_stop_nowait(&mdev->receiver);
+			mdev->bc->u_size = my_usize;
+			return FALSE;
+		}
 		dec_local(mdev);
 	}
 #undef min_not_zero

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2006-02-24 11:43:09 UTC (rev 2079)
+++ trunk/drbd/linux/drbd.h	2006-02-24 14:20:19 UTC (rev 2080)
@@ -232,7 +232,7 @@
 	Attaching,      /* In the process of reading the meta-data */
 	Inconsistent,
 	Outdated,
-	DUnknown,
+	DUnknown,       /* Only used for the peer, never for myself */
 	Consistent,     /* Might be Outdated, might be UpToDate ... */
 	UpToDate,
 	disk_mask=15

From drbd-cvs at lists.linbit.com  Fri Feb 24 16:34:16 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Fri Feb 24 16:34:17 2006
Subject: [DRBD-cvs] svn commit by phil - r2081 - in trunk: drbd user - *
	Made the output of the user tools a bit prettier.
Message-ID: <20060224153416.E860916768@mail.linbit.com>

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

Author: phil
Date: 2006-02-24 16:34:15 +0100 (Fri, 24 Feb 2006)
New Revision: 2081

Modified:
   trunk/drbd/drbd_receiver.c
   trunk/user/drbdadm.h
   trunk/user/drbdadm_main.c
   trunk/user/drbdadm_usage_cnt.c
   trunk/user/drbdmeta.c
Log:
* Made the output of the user tools a bit prettier.
* Removed some old cruft from drbd_receiver.c


Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2006-02-24 14:20:19 UTC (rev 2080)
+++ trunk/drbd/drbd_receiver.c	2006-02-24 15:34:15 UTC (rev 2081)
@@ -1372,14 +1372,6 @@
 	sector = be64_to_cpu(p->sector);
 	size   = be32_to_cpu(p->blksize);
 
-	/*
-	 * handled by NegDReply below ...
-	ERR_IF (test_bit(DISKLESS,&mdev->flags)) {
-		return FALSE;
-	ERR_IF ( (mdev->gen_cnt[Flags] & MDF_Consistent) == 0 )
-		return FALSE;
-	*/
-
 	if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) {
 		ERR("%s:%d: sector: %lu, size: %d\n", __FILE__, __LINE__,
 				(unsigned long)sector,size);
@@ -1717,10 +1709,8 @@
 	}
 
 	if (hg > 0) { // become sync source.
-		D_ASSERT(drbd_md_test_flag(mdev->bc,MDF_Consistent));
 		rv = WFBitMapS;
 	} else if (hg < 0) { // become sync target
-		drbd_md_clear_flag(mdev,MDF_Consistent);
 		drbd_uuid_set(mdev,Current,mdev->p_uuid[Bitmap]);
 		rv = WFBitMapT;
 	} else {

Modified: trunk/user/drbdadm.h
===================================================================
--- trunk/user/drbdadm.h	2006-02-24 14:20:19 UTC (rev 2080)
+++ trunk/user/drbdadm.h	2006-02-24 15:34:15 UTC (rev 2081)
@@ -85,7 +85,7 @@
 extern int adm_connect(struct d_resource* ,const char* );
 extern int adm_resize(struct d_resource* ,const char* );
 extern int adm_syncer(struct d_resource* ,const char* );
-extern int admm_generic(struct d_resource* ,const char* );
+extern int _admm_generic(struct d_resource* ,const char*, int flags);
 extern int m_system(char**,int );
 extern struct d_option* find_opt(struct d_option*,char*);
 extern void validate_resource(struct d_resource *);

Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c	2006-02-24 14:20:19 UTC (rev 2080)
+++ trunk/user/drbdadm_main.c	2006-02-24 15:34:15 UTC (rev 2081)
@@ -97,7 +97,7 @@
 static int sh_ll_dev(struct d_resource* ,const char* );
 static int sh_md_dev(struct d_resource* ,const char* );
 static int sh_md_idx(struct d_resource* ,const char* );
-       int admm_generic(struct d_resource* ,const char* );
+static int admm_generic(struct d_resource* ,const char* );
 static int adm_khelper(struct d_resource* ,const char* );
 static int adm_generic_b(struct d_resource* ,const char* );
 static int hidden_cmds(struct d_resource* ,const char* );
@@ -631,7 +631,7 @@
   return m_system(argv,SLEEPS_SHORT);
 }
 
-int admm_generic(struct d_resource* res ,const char* cmd)
+int _admm_generic(struct d_resource* res ,const char* cmd, int flags)
 {
   char* argv[20];
   int argc=0,i;
@@ -660,9 +660,14 @@
 
   argv[argc++]=0;
 
-  return m_system(argv,SLEEPS_VERY_LONG);
+  return m_system(argv,flags);
 }
 
+static int admm_generic(struct d_resource* res ,const char* cmd)
+{
+  return _admm_generic(res, cmd, SLEEPS_VERY_LONG);
+}
+
 static int adm_generic(struct d_resource* res,const char* cmd,int flags)
 {
   char* argv[20];

Modified: trunk/user/drbdadm_usage_cnt.c
===================================================================
--- trunk/user/drbdadm_usage_cnt.c	2006-02-24 14:20:19 UTC (rev 2080)
+++ trunk/user/drbdadm_usage_cnt.c	2006-02-24 15:34:15 UTC (rev 2081)
@@ -345,13 +345,14 @@
 "   how many users before you have installed this version (%s).\n"
 " * With a high counter the DRBD developers have a high motivation to\n"
 "   continue development of the software.\n\n"
-"The following string will be send to the server:\n"
 "http://"HTTP_HOST"/cgi-bin/insert_usage.pl?nu="U64"&nv="U32"\n\n"
 "In case you want to participate but know that this machines is firewalled\n"
-"simply issue the query string with your favourite web browser or wget\n\n"
-"You can control all this by setting 'usage-count' in the globals section\n"
-"of your drbd.conf\n\n"
-"Just press [return], 'no' to opt out or give an optional node comment: ",
+"simply issue the query string with your favourite web browser or wget.\n"
+"You can control all this by setting 'usage-count' in your drbd.conf.\n\n"
+"* You may enter a free form comment about your machine, that gets\n"
+"  used on "HTTP_HOST" instead of the big random number.\n"
+"* Enter 'no' to opt out.\n"
+"* To count this node without comment, just press [RETURN]\n",
 			update ? "an update" : "a new installation",
 			REL_VERSION,ni.node_uuid, ni.version_code);
 		fgets(answer,ANSWER_SIZE,stdin);
@@ -388,8 +389,7 @@
 
 /* For our purpose (finding the revision) SLURP_SIZE is always enough.
  */
-char* run_adm_function( int (* function)(struct d_resource*,const char* ), 
-			struct d_resource* res ,const char* cmd)
+char* run_admm_generic(struct d_resource* res ,const char* cmd)
 {
 	const int SLURP_SIZE = 4096;
 	int rr,pipes[2];
@@ -411,7 +411,9 @@
 		close(pipes[0]); // close reading end
 		dup2(pipes[1],1); // 1 = stdout
 		close(pipes[1]);
-		exit(function(res,cmd));
+		exit(_admm_generic(res,cmd,
+				   SLEEPS_VERY_LONG|SUPRESS_STDERR|
+				   DONT_REPORT_FAILED));
 	}
 	close(pipes[1]); // close writing end
 
@@ -440,11 +442,11 @@
 	char *tb;
 	int rv,fd;
 
-	tb = run_adm_function(admm_generic, res, "read-dev-uuid");
+	tb = run_admm_generic(res, "read-dev-uuid");
 	device_uuid = strto_u64(tb,NULL,16);
 	free(tb);
 
-	rv = admm_generic(res, cmd); // cmd is "create-md".
+	rv = _admm_generic(res, cmd, SLEEPS_VERY_LONG); // cmd is "create-md".
 
 	if(!device_uuid) {
 		get_random_bytes(&device_uuid, sizeof(u64));
@@ -484,7 +486,7 @@
 
 	ssprintf( setup_opts[0], X64(016), device_uuid);
 	soi=1;
-	admm_generic(res, "write-dev-uuid");
+	_admm_generic(res, "write-dev-uuid", SLEEPS_VERY_LONG);
 
 	return rv;
 }

Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2006-02-24 14:20:19 UTC (rev 2080)
+++ trunk/user/drbdmeta.c	2006-02-24 15:34:15 UTC (rev 2081)
@@ -867,7 +867,7 @@
 	}
 
 	(void) cfg->ops->md_get_byte_offset(cfg);
-	fprintf(stderr,"offset: "U64"\n", cfg->md_offset);
+	// fprintf(stderr,"offset: "U64"\n", cfg->md_offset);
 
 	cfg->md_mmaped_length = size;
 	cfg->on_disk.md =
@@ -1239,11 +1239,11 @@
 	cfg->al_offset = cfg->md_offset + cfg->md.al_offset * 512;
 	cfg->bm_offset = cfg->md_offset + cfg->md.bm_offset * 512;
 
-	fprintf(stderr,"md_offset: "U64"\n", cfg->md_offset);
-	fprintf(stderr,"al_offset: "U64" (%d)\n", cfg->al_offset, cfg->md.al_offset);
-	fprintf(stderr,"bm_offset: "U64" (%d)\n", cfg->bm_offset, cfg->md.bm_offset);
-	fprintf(stderr,"md_size_sect: %lu\n", (unsigned long)cfg->md.md_size_sect);
-	fprintf(stderr,"bm_mmaped_length: %lu\n", (unsigned long)cfg->bm_mmaped_length);
+	//fprintf(stderr,"md_offset: "U64"\n", cfg->md_offset);
+	//fprintf(stderr,"al_offset: "U64" (%d)\n", cfg->al_offset, cfg->md.al_offset);
+	//fprintf(stderr,"bm_offset: "U64" (%d)\n", cfg->bm_offset, cfg->md.bm_offset);
+	//fprintf(stderr,"md_size_sect: %lu\n", (unsigned long)cfg->md.md_size_sect);
+	//fprintf(stderr,"bm_mmaped_length: %lu\n", (unsigned long)cfg->bm_mmaped_length);
 
 	cfg->al_mmaped_length = MD_AL_MAX_SECT_07 * 512;
 	cfg->on_disk.al =
@@ -1255,7 +1255,7 @@
 		 MAP_SHARED, cfg->md_fd, cfg->bm_offset);
 
 	/* do you want to initilize al to something more usefull? */
-	fprintf(stderr,"initialising activity log\n");
+	printf("initialising activity log\n");
 	MEMSET(cfg->on_disk.al, 0x00, MD_AL_MAX_SECT_07*512);
 	/* THINK
 	 * do we really need to initialize the bitmap? */
@@ -1280,10 +1280,10 @@
 			}
 		}
 #else
-		fprintf(stderr,"initialising bitmap (%u KB)\n", (bm_bytes>>10));
+		printf("initialising bitmap (%u KB)\n", (bm_bytes>>10));
 		MEMSET((void*)cfg->on_disk.bm, 0xff, bm_bytes);
 #endif
-		fprintf(stderr,"\r100%%\n");
+		//fprintf(stderr,"\r100%%\n");
 	}
 #endif
 	return 0;
@@ -2002,7 +2002,7 @@
 	MEMSET(&cfg->md, 0, sizeof(cfg->md));
 	err = cfg->ops->md_initialize(cfg);
 	err = err || cfg->ops->md_cpu_to_disk(cfg); // <- short circuit
-	fprintf(stderr,"munmap... fsync...\n");
+	//fprintf(stderr,"munmap... fsync...\n");
 	err = cfg->ops->close(cfg)          || err; // <- close always
 	if (err)
 		fprintf(stderr, "operation failed\n");

From drbd-cvs at lists.linbit.com  Sun Feb 26 12:56:58 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Sun Feb 26 12:56:59 2006
Subject: [DRBD-cvs] svn commit by lars - r2082 - branches/drbd-0.7/drbd -
	cosmetics
Message-ID: <20060226115658.5E7D31676E@mail.linbit.com>

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

Author: lars
Date: 2006-02-26 12:56:57 +0100 (Sun, 26 Feb 2006)
New Revision: 2082

Modified:
   branches/drbd-0.7/drbd/drbd_actlog.c
Log:
cosmetics

Modified: branches/drbd-0.7/drbd/drbd_actlog.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_actlog.c	2006-02-24 15:34:15 UTC (rev 2081)
+++ branches/drbd-0.7/drbd/drbd_actlog.c	2006-02-26 11:56:57 UTC (rev 2082)
@@ -143,9 +143,9 @@
 	}
 
 #if DUMP_MD >= 3
-	INFO("%s [%d]:%s(,%ld,%s)\n",
+	INFO("%s [%d]:%s(,%llu,%s)\n",
 	     current->comm, current->pid, __func__,
-	     sector, rw ? "WRITE" : "READ");
+	     (unsigned long long)sector, rw ? "WRITE" : "READ");
 #endif
 
 	if (sector < drbd_md_ss(mdev)  ||
@@ -540,7 +540,7 @@
 	wake_up(&mdev->al_wait);
 
 	INFO("Marked additional %s as out-of-sync based on AL.\n",
-	     ppsize(ppb,add >> 1));
+	     ppsize(ppb,Bit2KB(add)));
 }
 
 static inline int _try_lc_del(struct Drbd_Conf *mdev,struct lc_element *al_ext)

From drbd-cvs at lists.linbit.com  Tue Feb 28 11:55:55 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue Feb 28 11:55:56 2006
Subject: [DRBD-cvs] svn commit by phil - r2083 - branches/drbd-0.7/drbd -
	Got a very detailed bug report, description and patch f
Message-ID: <20060228105555.3EDC9166F0@mail.linbit.com>

Author: phil
Date: 2006-02-28 11:55:54 +0100 (Tue, 28 Feb 2006)
New Revision: 2083

Modified:
   branches/drbd-0.7/drbd/drbd_actlog.c
   branches/drbd-0.7/drbd/drbd_fs.c
Log:
Got a very detailed bug report, description and patch from Luo Jinhua.

* The AL was not applied in case the user selected a non standard AL
  size after a primary crash. Fixed.
* When reading the AL, the last change AL-entry might not become 
  restored correctly. Fixed.


Modified: branches/drbd-0.7/drbd/drbd_actlog.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_actlog.c	2006-02-26 11:56:57 UTC (rev 2082)
+++ branches/drbd-0.7/drbd/drbd_actlog.c	2006-02-28 10:55:54 UTC (rev 2083)
@@ -453,7 +453,12 @@
 		trn=be32_to_cpu(buffer->tr_number);
 
 		spin_lock_irq(&mdev->al_lock);
-		for(j=0;j<AL_EXTENTS_PT+1;j++) {
+
+		/* This loop runs backwards because in the cyclic 
+		   elements there might be an old version of the
+		   updated element (in slot 0). So the element in slot 0
+		   can overwrite old versions. */
+		for(j=AL_EXTENTS_PT;j>=0;j--) {
 			pos = be32_to_cpu(buffer->updates[j].pos);
 			extent_nr = be32_to_cpu(buffer->updates[j].extent);
 

Modified: branches/drbd-0.7/drbd/drbd_fs.c
===================================================================
--- branches/drbd-0.7/drbd/drbd_fs.c	2006-02-26 11:56:57 UTC (rev 2082)
+++ branches/drbd-0.7/drbd/drbd_fs.c	2006-02-28 10:55:54 UTC (rev 2083)
@@ -263,7 +263,7 @@
 			struct ioctl_disk_config * arg)
 {
 	NOT_IN_26(int err;) // unused in 26 ?? cannot believe it ...
-	int i, md_gc_valid, minor, mput=0;
+	int i, md_gc_valid, minor, mput=0, apply_al;
 	enum ret_codes retcode;
 	struct disk_config new_conf;
 	struct file *filp = 0;
@@ -520,6 +520,13 @@
 		if (put_user(retcode, &arg->ret_code)) return -EFAULT;
 		return -EINVAL;
 	}
+
+	apply_al = drbd_md_test_flag(mdev,MDF_PrimaryInd);
+	/* All tests on MDF_PrimaryInd and MDF_ConnectedInd must happen before 
+	   this point, because determin_dev_size() might call drbd_md_write(), 
+	   which in turn modifies these flags. Exceptions are where, we want
+	   to test the current state (drbd_md_compare(), drbd_send_param()). */
+
 	if (drbd_determin_dev_size(mdev) < 0) {
 		/* could not allocate bitmap.
 		 * try to undo ... */
@@ -561,7 +568,7 @@
 
 	if (md_gc_valid > 0) {
 		drbd_al_read_log(mdev);
-		if (drbd_md_test_flag(mdev,MDF_PrimaryInd)) {
+		if (apply_al) {
 			drbd_al_apply_to_bm(mdev);
 			drbd_al_to_on_disk_bm(mdev);
 		}

From drbd-cvs at lists.linbit.com  Tue Feb 28 12:20:17 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue Feb 28 12:20:18 2006
Subject: [DRBD-cvs] svn commit by phil - r2084 - in trunk: . drbd -
	Propagated the latest bug-fixes from the 07 branch. 
Message-ID: <20060228112017.37A7B166F0@mail.linbit.com>

Author: phil
Date: 2006-02-28 12:20:15 +0100 (Tue, 28 Feb 2006)
New Revision: 2084

Modified:
   trunk/
   trunk/drbd/drbd_actlog.c
   trunk/drbd/drbd_fs.c
Log:
Propagated the latest bug-fixes from the 07 branch.



Property changes on: trunk
___________________________________________________________________
Name: propagate:at
   - 2068
   + 2083

Modified: trunk/drbd/drbd_actlog.c
===================================================================
--- trunk/drbd/drbd_actlog.c	2006-02-28 10:55:54 UTC (rev 2083)
+++ trunk/drbd/drbd_actlog.c	2006-02-28 11:20:15 UTC (rev 2084)
@@ -115,9 +115,9 @@
 	}
 
 #if DUMP_MD >= 3
-	INFO("%s [%d]:%s(,%ld,%s)\n",
+	INFO("%s [%d]:%s(,%llu,%s)\n",
 	     current->comm, current->pid, __func__,
-	     sector, rw ? "WRITE" : "READ");
+	     (unsigned long long)sector, rw ? "WRITE" : "READ");
 #endif
 
 	if (sector < drbd_md_first_sector(bdev)  || sector > drbd_md_last_sector(bdev)) {
@@ -424,7 +424,12 @@
 		trn=be32_to_cpu(buffer->tr_number);
 
 		spin_lock_irq(&mdev->al_lock);
-		for(j=0;j<AL_EXTENTS_PT+1;j++) {
+
+		/* This loop runs backwards because in the cyclic 
+		   elements there might be an old version of the
+		   updated element (in slot 0). So the element in slot 0
+		   can overwrite old versions. */
+		for(j=AL_EXTENTS_PT;j>=0;j--) {
 			pos = be32_to_cpu(buffer->updates[j].pos);
 			extent_nr = be32_to_cpu(buffer->updates[j].extent);
 
@@ -511,7 +516,7 @@
 	wake_up(&mdev->al_wait);
 
 	INFO("Marked additional %s as out-of-sync based on AL.\n",
-	     ppsize(ppb,add >> 1));
+	     ppsize(ppb,Bit2KB(add)));
 }
 
 static inline int _try_lc_del(struct Drbd_Conf *mdev,struct lc_element *al_ext)

Modified: trunk/drbd/drbd_fs.c
===================================================================
--- trunk/drbd/drbd_fs.c	2006-02-28 10:55:54 UTC (rev 2083)
+++ trunk/drbd/drbd_fs.c	2006-02-28 11:20:15 UTC (rev 2084)
@@ -532,7 +532,11 @@
 		} else {
 			nds = Inconsistent;
 		}
-		
+
+		/* All tests on MDF_PrimaryInd, MDF_ConnectedInd, 
+		   MDF_Consistent and MDF_WasUpToDate must happen before 
+		   this point, because drbd_request_state() modifies these
+		   flags. */
 		if(drbd_request_state(mdev,NS(disk,nds)) >= SS_Success ) {
 			drbd_thread_start(&mdev->worker);
 		}

From drbd-cvs at lists.linbit.com  Tue Feb 28 15:15:22 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue Feb 28 15:15:23 2006
Subject: [DRBD-cvs] svn commit by lars - r2085 - branches/drbd-0.7/drbd -
	missing macro (); non-critical fix, but you never know 
Message-ID: <20060228141522.6C130166F0@mail.linbit.com>

Author: lars
Date: 2006-02-28 15:15:19 +0100 (Tue, 28 Feb 2006)
New Revision: 2085

Modified:
   branches/drbd-0.7/drbd/drbd_int.h
Log:
missing macro (); non-critical fix, but you never know when and how we next use that constant

Modified: branches/drbd-0.7/drbd/drbd_int.h
===================================================================
--- branches/drbd-0.7/drbd/drbd_int.h	2006-02-28 11:20:15 UTC (rev 2084)
+++ branches/drbd-0.7/drbd/drbd_int.h	2006-02-28 14:15:19 UTC (rev 2085)
@@ -896,7 +896,7 @@
 #define MD_HARDSECT      (1<<MD_HARDSECT_B)
 
 // activity log
-#define AL_EXTENTS_PT    (MD_HARDSECT-12)/8-1 // 61 ; Extents per 512B sector
+#define AL_EXTENTS_PT    ((MD_HARDSECT-12)/8-1) // 61 ; Extents per 512B sector
 #define AL_EXTENT_SIZE_B 22      // One extent represents 4M Storage
 #define AL_EXTENT_SIZE (1<<AL_EXTENT_SIZE_B)
 

From drbd-cvs at lists.linbit.com  Tue Feb 28 19:14:51 2006
From: drbd-cvs at lists.linbit.com (drbd-cvs@lists.linbit.com)
Date: Tue Feb 28 19:14:53 2006
Subject: [DRBD-cvs] svn commit by phil - r2086 - in trunk: . user -
	Implemented the 'dstate' command to ease the heartbeat-
Message-ID: <20060228181451.EEE3415EEC@mail.linbit.com>

Author: phil
Date: 2006-02-28 19:14:50 +0100 (Tue, 28 Feb 2006)
New Revision: 2086

Modified:
   trunk/ROADMAP
   trunk/user/drbdadm_main.c
   trunk/user/drbdmeta.c
   trunk/user/drbdsetup.c
Log:
Implemented the 'dstate' command to ease the heartbeat-2 
glue code.



Modified: trunk/ROADMAP
===================================================================
--- trunk/ROADMAP	2006-02-28 14:15:19 UTC (rev 2085)
+++ trunk/ROADMAP	2006-02-28 18:14:50 UTC (rev 2086)
@@ -655,6 +655,8 @@
 26 Implement a kind of "dstate" command to make integration with 
    Heartbeat-2.0's master/slave-support possible.
 
+   99% DONE
+
 27 Remove all explicit drbd_md_write() calls, and create a mechanism,
    that always keeps the on disk-metadata up-to-date implicit. 
    Calling drbd_md_write() explicit is too errorprone.
@@ -667,8 +669,7 @@
    set gets generated, the 'call home' is initiated. The user might
    of course opt out of this.
 
-   50% DONE [ Counting of resources is missing, counting of DRBD releases
-              is alrady implemented. ]
+   99% DONE
 
 29 Make drbdadm to have 'hidden-commands' command to also show
    the hidden sub-commands in the ussage.

Modified: trunk/user/drbdadm_main.c
===================================================================
--- trunk/user/drbdadm_main.c	2006-02-28 14:15:19 UTC (rev 2085)
+++ trunk/user/drbdadm_main.c	2006-02-28 18:14:50 UTC (rev 2086)
@@ -197,6 +197,7 @@
   { "wait_connect",      adm_wait_c,    1,1,1 },
   { "state",             adm_generic_s, 1,1,0 },
   { "cstate",            adm_generic_s, 1,1,1 },
+  { "dstate",            adm_generic_b, 1,1,1 },
   { "dump",              adm_dump,      1,1,1 },
   { "create-md",         adm_create_md, 1,1,0 },
   { "show-gi",           adm_generic_b, 1,1,0 },

Modified: trunk/user/drbdmeta.c
===================================================================
--- trunk/user/drbdmeta.c	2006-02-28 14:15:19 UTC (rev 2085)
+++ trunk/user/drbdmeta.c	2006-02-28 18:14:50 UTC (rev 2086)
@@ -753,8 +753,8 @@
 int meta_set_gi(struct format *cfg, char **argv, int argc);
 int meta_read_dev_uuid(struct format *cfg, char **argv, int argc);
 int meta_write_dev_uuid(struct format *cfg, char **argv, int argc);
+int meta_dstate(struct format *cfg, char **argv, int argc);
 
-
 struct meta_cmd cmds[] = {
 	{"get-gi", 0, meta_get_gi, 1},
 	{"show-gi", 0, meta_show_gi, 1},
@@ -765,6 +765,7 @@
 	 * implicit convert from v07 to v08 by create-md
 	 * see comments there */
 	{"outdate", 0, meta_outdate, 1},
+	{"dstate", 0, meta_dstate, 1},
 	{"read-dev-uuid", "VAL",  meta_read_dev_uuid,  0},
 	{"write-dev-uuid", "VAL", meta_write_dev_uuid, 0},
 	{"set-gi", ":::VAL:VAL:...", meta_set_gi, 0},
@@ -893,9 +894,9 @@
 	cfg->bm_offset = cfg->md_offset + cfg->md.bm_offset * 512;
 	cfg->bm_mmaped_length = (u64)(cfg->md.md_size_sect - MD_BM_OFFSET_07)*512;
 
-	fprintf(stderr,"al_offset: "U64" (%d)\n", cfg->al_offset, cfg->md.al_offset);
-	fprintf(stderr,"bm_offset: "U64" (%d)\n", cfg->bm_offset, cfg->md.bm_offset);
-	fprintf(stderr,"bm_mmaped_length: %lu\n",(unsigned long)cfg->bm_mmaped_length);
+	//fprintf(stderr,"al_offset: "U64" (%d)\n", cfg->al_offset, cfg->md.al_offset);
+	//fprintf(stderr,"bm_offset: "U64" (%d)\n", cfg->bm_offset, cfg->md.bm_offset);
+	//fprintf(stderr,"bm_mmaped_length: %lu\n",(unsigned long)cfg->bm_mmaped_length);
 
 	cfg->al_mmaped_length = MD_AL_MAX_SECT_07 * 512;
 	cfg->on_disk.al =
@@ -1538,6 +1539,28 @@
 	return cfg->ops->close(cfg);
 }
 
+int meta_dstate(struct format *cfg, char **argv __attribute((unused)), int argc)
+{
+	if (argc > 0) {
+		fprintf(stderr, "Ignoring additional arguments\n");
+	}
+
+	if (cfg->ops->open(cfg))
+		return -1;
+
+	if(cfg->md.flags & MDF_Consistent) {
+		if(cfg->md.flags & MDF_WasUpToDate) {
+			printf("Consistent/DUnknown\n");
+		} else {
+			printf("Outdated/DUnknown\n");
+		}
+	} else {
+		printf("Inconsistent/DUnknown\n");
+	}
+
+	return cfg->ops->close(cfg);
+}
+
 int meta_set_gi(struct format *cfg, char **argv, int argc)
 {
 	struct md_cpu tmp;

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2006-02-28 14:15:19 UTC (rev 2085)
+++ trunk/user/drbdsetup.c	2006-02-28 18:14:50 UTC (rev 2086)
@@ -122,6 +122,7 @@
 int cmd_detach(int drbd_fd,char** argv,int argc,struct option *options);
 int cmd_state(int drbd_fd,char** argv,int argc,struct option *options);
 int cmd_cstate(int drbd_fd,char** argv,int argc,struct option *options);
+int cmd_dstate(int drbd_fd,char** argv,int argc,struct option *options);
 int cmd_show_gi(int drbd_fd,char** argv,int argc,struct option *options);
 int cmd_get_gi(int drbd_fd,char** argv,int argc,struct option *options);
 
@@ -188,6 +189,7 @@
   {"disconnect", cmd_disconnect,     0, 0, },
   {"state", cmd_state,               0, 0, },
   {"cstate", cmd_cstate,             0, 0, },
+  {"dstate", cmd_dstate,             0, 0, },
   {"show-gi", cmd_show_gi,           0, 0, },
   {"get-gi", cmd_get_gi,             0, 0, },
   {"show", cmd_show,                 0, 0, },
@@ -1390,8 +1392,8 @@
 
   if( cn.state.conn == StandAlone && cn.state.disk == Diskless)
     {
-      printf("Not configured\n");
-      return 0;
+      fprintf(stderr,"Not configured\n");
+      return 10;
     }
 
   printf("%s/%s\n",roles_to_name(cn.state.role),
@@ -1414,8 +1416,8 @@
 
   if( cn.state.conn == StandAlone && cn.state.disk == Diskless)
     {
-      printf("Not configured\n");
-      return 0;
+      fprintf(stderr,"Not configured\n");
+      return 10;
     }
 
   printf("%s\n",conns_to_name(cn.state.conn));
@@ -1423,6 +1425,29 @@
   return 0;
 }
 
+int cmd_dstate(int drbd_fd,char** argv __attribute((unused)),int argc __attribute((unused)),struct option *options __attribute((unused)))
+{
+  struct ioctl_get_config cn;
+  int err;
+
+  err=ioctl(drbd_fd,DRBD_IOCTL_GET_CONFIG,&cn);
+  if(err)
+    {
+      PERROR("ioctl(,GET_CONFIG,) failed");
+      return 20;
+    }
+
+  if( cn.state.conn == StandAlone && cn.state.disk == Diskless)
+    {
+      fprintf(stderr,"Not configured\n");
+      return 10;
+    }
+
+  printf("%s/%s\n",disks_to_name(cn.state.disk),disks_to_name(cn.state.pdsk));
+
+  return 0;
+}
+
 int cmd_get_gi(int drbd_fd,char** argv __attribute((unused)),int argc __attribute((unused)),struct option *options __attribute((unused)))
 {
   struct ioctl_get_uuids cn;

