[DRBD-cvs] r1617 - in trunk: . documentation drbd drbd/linux scripts testing user

svn at svn.drbd.org svn at svn.drbd.org
Thu Oct 28 22:06:24 CEST 2004


Author: phil
Date: 2004-10-28 22:06:21 +0200 (Thu, 28 Oct 2004)
New Revision: 1617

Added:
   trunk/drbd/drbd_sizeof_sanity_check.c
   trunk/user/drbd_limits.h
Modified:
   trunk/
   trunk/documentation/drbd.conf.sgml
   trunk/drbd/Makefile-2.6
   trunk/drbd/drbd_main.c
   trunk/drbd/drbd_receiver.c
   trunk/drbd/linux/drbd.h
   trunk/drbd/linux/drbd_config.h
   trunk/scripts/drbd.conf
   trunk/testing/ioctl_structs_sizes.c
   trunk/user/Makefile
   trunk/user/drbdadm_parser.y
   trunk/user/drbdadm_scanner.fl
   trunk/user/drbdsetup.c
Log:
svnp run. Investigated 1607 to 1617

r1609 by lars on 2004-10-21 01:50:56 +0200 (Thu, 21 Oct 2004) 
  Changed paths:
     M /branches/drbd-0.7/documentation/drbd.conf.sgml
     M /branches/drbd-0.7/scripts/drbd.conf
     M /branches/drbd-0.7/user/drbdadm_parser.y
  
  added range_check to drbdadm_parser.y,
   now helmut can add rangechecks where neccessary

r1610 by phil on 2004-10-21 12:09:14 +0200 (Thu, 21 Oct 2004) 
  Changed paths:
     M /branches/drbd-0.7/drbd/linux/drbd.h
     M /branches/drbd-0.7/drbd/linux/drbd_config.h
  
  Arranged ioctl structs to be friendly aligned on 64 architectures.
  Breaks ioctl() binary API compatibility.
  

r1611 by lars on 2004-10-24 13:20:13 +0200 (Sun, 24 Oct 2004) 
  Changed paths:
     M /branches/drbd-0.7/drbd/drbd_receiver.c
  
  * wake_up_interruptible did not wake up threads in wait_even(cstate)
  * down_interruptible in drbd_send_handshake, just in case some drbdsetup kills us

r1612 by lars on 2004-10-25 16:52:38 +0200 (Mon, 25 Oct 2004) 
  Changed paths:
     M /branches/drbd-0.7/drbd/Makefile-2.4
     M /branches/drbd-0.7/drbd/Makefile-2.6
     M /branches/drbd-0.7/drbd/drbd_main.c
     A /branches/drbd-0.7/drbd/drbd_sizeof_sanity_check.c
     M /branches/drbd-0.7/drbd/linux/drbd.h
  
  oh the wonders of kernel build.
  added drbd_sizeof_sanity_check.c
  which is compiled with -Wpadded -Werror
  removed the __attribute__((packed)) from the ioctl structs again,
  to avoid forcing misaligned longs for example.

r1613 by lars on 2004-10-25 23:02:21 +0200 (Mon, 25 Oct 2004) 
  Changed paths:
     M /branches/drbd-0.7/testing/ioctl_structs_sizes.c
     M /branches/drbd-0.7/user/Makefile
     A /branches/drbd-0.7/user/drbd_limits.h
     M /branches/drbd-0.7/user/drbdadm_parser.y
     M /branches/drbd-0.7/user/drbdadm_scanner.fl
     M /branches/drbd-0.7/user/drbdsetup.c
  
  added decent range checks for almost all configurable values
  for drbdsetup as well as drbdadm

r1615 by phil on 2004-10-28 21:36:59 +0200 (Thu, 28 Oct 2004) 
  Changed paths:
     M /branches/drbd-0.7/drbd/linux/drbd.h
     M /branches/drbd-0.7/testing/ioctl_structs_sizes.c
  
  Make it work again in an 32-bit userland / 64-bit kernel environment.
  



Property changes on: trunk
___________________________________________________________________
Name: propagate:at
   - 1607
   + 1617

Modified: trunk/documentation/drbd.conf.sgml
===================================================================
--- trunk/documentation/drbd.conf.sgml	2004-10-28 19:41:23 UTC (rev 1616)
+++ trunk/documentation/drbd.conf.sgml	2004-10-28 20:06:21 UTC (rev 1617)
@@ -37,14 +37,16 @@
     device    /dev/drbd1;
     disk      /dev/hda7;
     address   10.1.1.31:7789;
+    meta-disk  internal;
   }
 
   on thost2 {
     device    /dev/drbd1;
     disk      /dev/hda7;
     address   10.1.1.32:7789;
+    meta-disk  internal;
   }
-}	
+}
 </programlisting>
 </example>
  In this example there is a single DRBD resource (called drbd0) which uses
@@ -524,7 +526,7 @@
 </refsect1>
 <refsect1>
 <title>Version</title>
-<simpara>This document is correct for version 0.7-pre7 of the DRBD distribution.
+<simpara>This document is correct for version 0.7.5 of the DRBD distribution.
 </simpara>
 </refsect1>
 <refsect1>

Modified: trunk/drbd/Makefile-2.6
===================================================================
--- trunk/drbd/Makefile-2.6	2004-10-28 19:41:23 UTC (rev 1616)
+++ trunk/drbd/Makefile-2.6	2004-10-28 20:06:21 UTC (rev 1617)
@@ -1,4 +1,7 @@
-drbd-objs  := drbd_buildtag.o drbd_bitmap.o drbd_fs.o drbd_proc.o \
-	      drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o \
-	      lru_cache.o drbd_main.o
+CFLAGS_drbd_sizeof_sanity_check.o = -Wpadded -Werror
+
+drbd-objs  :=	drbd_sizeof_sanity_check.o \
+		drbd_buildtag.o drbd_bitmap.o drbd_fs.o drbd_proc.o \
+		drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o \
+		lru_cache.o drbd_main.o
 obj-$(CONFIG_BLK_DEV_DRBD)     += drbd.o

Modified: trunk/drbd/drbd_main.c
===================================================================
--- trunk/drbd/drbd_main.c	2004-10-28 19:41:23 UTC (rev 1616)
+++ trunk/drbd/drbd_main.c	2004-10-28 20:06:21 UTC (rev 1617)
@@ -1569,6 +1569,7 @@
 	printk(KERN_INFO DEVICE_NAME": module cleanup done.\n");
 }
 
+int sizeof_drbd_structs_sanity_check(void);
 int __init drbd_init(void)
 {
 	int i,err;
@@ -1607,6 +1608,9 @@
 		       ": never change the size or layout of the HandShake packet.\n");
 		return -EINVAL;
 	}
+	if (sizeof_drbd_structs_sanity_check()) {
+		return -EINVAL;
+	}
 
 	if (use_nbd_major) {
 		major_nr = NBD_MAJOR;

Modified: trunk/drbd/drbd_receiver.c
===================================================================
--- trunk/drbd/drbd_receiver.c	2004-10-28 19:41:23 UTC (rev 1616)
+++ trunk/drbd/drbd_receiver.c	2004-10-28 20:06:21 UTC (rev 1617)
@@ -1786,7 +1786,7 @@
 		atomic_set(&mdev->ap_pending_cnt,0);
 	}
 
-	wake_up_interruptible(&mdev->cstate_wait);
+	wake_up(&mdev->cstate_wait);
 
 	if ( mdev->state == Primary &&
 	    ( test_bit(DISKLESS,&mdev->flags)
@@ -1833,7 +1833,10 @@
 	Drbd_HandShake_Packet *p = &mdev->data.sbuf.HandShake;
 	int ok;
 
-	down(&mdev->data.mutex);
+	if (down_interruptible(&mdev->data.mutex)) {
+		ERR("interrupted during initial handshake\n");
+		return 0; /* interrupted. not ok. */
+	}
 	memset(p,0,sizeof(*p));
 	p->protocol_version = cpu_to_be32(PRO_VERSION);
 	ok = _drbd_send_cmd( mdev, mdev->data.socket, HandShake,

Copied: trunk/drbd/drbd_sizeof_sanity_check.c (from rev 1612, branches/drbd-0.7/drbd/drbd_sizeof_sanity_check.c)

Modified: trunk/drbd/linux/drbd.h
===================================================================
--- trunk/drbd/linux/drbd.h	2004-10-28 19:41:23 UTC (rev 1616)
+++ trunk/drbd/linux/drbd.h	2004-10-28 20:06:21 UTC (rev 1617)
@@ -45,6 +45,12 @@
 #define INOUT
 #endif
 
+/* 
+   - Never forget to place bigger members before the smaller ones, 
+     to avoid unaligned placement of members on 64 bit architectures. 
+   - Never forget to add explicit _pad members to make sizeof(struct)
+     divisible by 8.
+*/
 
 #define MAX_SOCK_ADDR	128	/* 108 for Unix domain -
 				   16 for IP, 16 for IPX,
@@ -62,9 +68,9 @@
 };
 
 
-struct __attribute__((packed)) disk_config {
+struct disk_config {
+	IN __u64    disk_size;
 	IN int      lower_device;
-	IN __u64    disk_size;
 	IN enum io_error_handler on_io_error;
 	IN int      meta_device;
 	IN int      meta_index;
@@ -76,10 +82,10 @@
 	FreezeIO
 };
 
-struct __attribute__((packed)) net_config {
+struct net_config {
 	IN char     my_addr[MAX_SOCK_ADDR];
+	IN char     other_addr[MAX_SOCK_ADDR];
 	IN int      my_addr_len;
-	IN char     other_addr[MAX_SOCK_ADDR];
 	IN int      other_addr_len;
 	IN int      timeout;          // deci seconds
 	IN int      wire_protocol;
@@ -90,14 +96,16 @@
 	IN int      sndbuf_size;  /* socket send buffer size */
 	IN unsigned int ko_count;
 	IN enum disconnect_handler on_disconnect;
+	const int   _pad;
 };
 
-struct __attribute__((packed)) syncer_config {
+struct syncer_config {
 	int      rate; /* KB/sec */
 	int      use_csums;   /* use checksum based syncing*/
 	int      skip;
 	int      group;
 	int      al_extents;
+	const int _pad;
 };
 
 /* KEEP the order, do not delete or insert!
@@ -122,25 +130,29 @@
 	LDDeviceTooLarge,
 };
 
-struct __attribute__((packed)) ioctl_disk_config {
+struct ioctl_disk_config {
 	struct disk_config    config;
 	OUT enum ret_codes    ret_code;
+	const int             _pad;
 };
 
-struct __attribute__((packed)) ioctl_net_config {
+struct ioctl_net_config {
 	struct net_config     config;
 	OUT enum ret_codes    ret_code;
+	const int             _pad;
 };
 
-struct __attribute__((packed)) ioctl_syncer_config {
+struct ioctl_syncer_config {
 	struct syncer_config  config;
 	OUT enum ret_codes    ret_code;
+	const int             _pad;
 };
 
-struct __attribute__((packed)) ioctl_wait {
+struct ioctl_wait {
 	IN int wfc_timeout;
 	IN int degr_wfc_timeout;
 	OUT int ret_code;
+	int      _pad;
 };
 
 #define DRBD_PROT_A   1
@@ -189,21 +201,22 @@
 # define BDEVNAME_SIZE 32
 #endif
 
-struct __attribute__((packed)) ioctl_get_config {
+struct ioctl_get_config {
+	OUT __u64             disk_size_user;
+	OUT char              lower_device_name[BDEVNAME_SIZE];
+	OUT char              meta_device_name[BDEVNAME_SIZE];
 	struct net_config     nconf;
 	struct syncer_config  sconf;
 	OUT int               lower_device_major;
 	OUT int               lower_device_minor;
-	OUT __u64             disk_size_user;
 	OUT enum io_error_handler on_io_error;
 	OUT int               meta_device_major;
 	OUT int               meta_device_minor;
 	OUT int               meta_index;
-	OUT char              lower_device_name[BDEVNAME_SIZE];
-	OUT char              meta_device_name[BDEVNAME_SIZE];
 	OUT Drbd_CState       cstate;
 	OUT Drbd_State        state;
 	OUT Drbd_State        peer_state;
+	int                   _pad;
 };
 
 #define DRBD_MAGIC 0x83740267

Modified: trunk/drbd/linux/drbd_config.h
===================================================================
--- trunk/drbd/linux/drbd_config.h	2004-10-28 19:41:23 UTC (rev 1616)
+++ trunk/drbd/linux/drbd_config.h	2004-10-28 20:06:21 UTC (rev 1617)
@@ -23,7 +23,7 @@
 extern const char * drbd_buildtag(void);
 
 #define REL_VERSION "0.8-pre1"
-#define API_VERSION 76
+#define API_VERSION 77
 #define PRO_VERSION 74
 
 //#define DBG_ALL_SYMBOLS // no static functs, improves quality of OOPS traces

Modified: trunk/scripts/drbd.conf
===================================================================
--- trunk/scripts/drbd.conf	2004-10-28 19:41:23 UTC (rev 1616)
+++ trunk/scripts/drbd.conf	2004-10-28 20:06:21 UTC (rev 1617)
@@ -125,8 +125,10 @@
   startup {
     # Wait for connection timeout. 
     # The init script blocks the boot process until the resources
-    # are connected. 
+    # are connected. This is so when the cluster manager starts later,
+    # it does not see a resource with internal split-brain.
     # In case you want to limit the wait time, do it here.
+    # Default is 0, which means unlimited. Unit is seconds.
     #
     # wfc-timeout  0;
 

Modified: trunk/testing/ioctl_structs_sizes.c
===================================================================
--- trunk/testing/ioctl_structs_sizes.c	2004-10-28 19:41:23 UTC (rev 1616)
+++ trunk/testing/ioctl_structs_sizes.c	2004-10-28 20:06:21 UTC (rev 1617)
@@ -1,11 +1,11 @@
 #include <stdio.h>
 #include <linux/drbd.h>
 
-#define SZO(x)  (int) sizeof(x);\
-({ printf("sizeof(" #x ") = %d\n", (int)sizeof(x)); })
-                
+#define SZO(x) \
+({ int _i = sizeof(x); printf("sizeof(" #x ") = %d\n", _i); \
+ if( _i % 8 ) printf(" WARN sizeof(" #x ") %% 8 != 0\n"); _i; })
 
-#define DRBD_07_SUM 1140
+#define DRBD_07_SUM 1184
 
 int main()
 {
@@ -24,5 +24,5 @@
 
 	printf(sum == DRBD_07_SUM ? "OKAY\n" : "FAILED\n" );
 
-	return 0;
+	return sum != DRBD_07_SUM; /* if not equal, exit code is non-zero */
 }

Modified: trunk/user/Makefile
===================================================================
--- trunk/user/Makefile	2004-10-28 19:41:23 UTC (rev 1616)
+++ trunk/user/Makefile	2004-10-28 20:06:21 UTC (rev 1617)
@@ -70,4 +70,5 @@
 ###dependencies
 drbdadm_adjust.o: drbdadm.h drbdadm_adjust.c
 drbdadm_main.o: drbdadm.h drbdadm_main.c ../drbd/linux/drbd_config.h
-drbdsetup.o: ../drbd/linux/drbd.h ../drbd/linux/drbd_config.h
+drbdsetup.o: ../drbd/linux/drbd.h ../drbd/linux/drbd_config.h drbd_limits.h
+drbdadm_parser.o: drbd_limits.h

Copied: trunk/user/drbd_limits.h (from rev 1613, branches/drbd-0.7/user/drbd_limits.h)

Modified: trunk/user/drbdadm_parser.y
===================================================================
--- trunk/user/drbdadm_parser.y	2004-10-28 19:41:23 UTC (rev 1616)
+++ trunk/user/drbdadm_parser.y	2004-10-28 20:06:21 UTC (rev 1617)
@@ -5,6 +5,7 @@
 #include <string.h>
 
 #include "drbdadm.h"
+#include "drbd_limits.h"
 
 extern void yyerror(char* text);
 extern int  yylex(void);
@@ -27,6 +28,205 @@
 static char* c_hostname;
 static int   c_section_start, n_hosts;
 
+unsigned long long
+m_strtoll(const char *s, char def_unit)
+{
+  unsigned long long r;
+  char unit = 0;
+  char dummy = 0;
+  int shift, c;
+
+  /*
+   * paranoia
+   */
+  switch (def_unit)
+    {
+    default:
+      fprintf(stderr, "%s:%d: unexpected default unit\n", __FILE__, __LINE__);
+      exit(E_thinko);
+    case 0:
+    case 1:
+    case '1':
+      shift = 0;
+      break;
+
+    case 'K':
+    case 'k':
+      shift = -10;
+      break;
+
+      /*
+         case 'M':
+         case 'm':
+         case 'G':
+         case 'g':
+       */
+    }
+
+  /* catched by the scanner already */
+  if (!s || !*s)
+    {
+      fprintf(stderr, "missing number argument\n");
+      exit(E_thinko);
+    }
+
+  c = sscanf(s, "%llu%c%c", &r, &unit, &dummy);
+
+  /* catched by the scanner already */
+  if (c != 1 && c != 2)
+    {
+      fprintf(stderr, "%s:%d: '%s' is not a valid number; %c %c\n",
+	      config_file, fline, s, unit, dummy);
+      exit(20);
+    }
+
+  switch (unit)
+    {
+    case 0:
+      return r;
+    case 'K':
+    case 'k':
+      shift += 10;
+      break;
+    case 'M':
+    case 'm':
+      shift += 20;
+      break;
+    case 'G':
+    case 'g':
+      shift += 30;
+      break;
+    default:
+      fprintf(stderr, "%s is not a valid number\n", s);
+      exit(20);
+    }
+  if (r > (~0ULL >> shift))
+    {
+      fprintf(stderr, "%s: out of range\n", s);
+      exit(20);
+    }
+  return r << shift;
+}
+
+void
+m_strtoll_range(const char *s, char def_unit,
+		const char *name,
+		unsigned long long min, unsigned long long max)
+{
+  unsigned long long r = m_strtoll(s, def_unit);
+  char unit[] = { def_unit > '1' ? def_unit : 0, 0 };
+  if (min > r || r > max)
+    {
+      fprintf(stderr,
+	      "%s:%d: %s %s => %llu%s out of range [%llu..%llu]%s.\n",
+	      config_file, fline, name, s, r, unit, min, max, unit);
+      exit(E_config_invalid);
+    }
+  if (DEBUG_RANGE_CHECK)
+    {
+      fprintf(stderr,
+	      "%s:%d: %s %s => %llu%s in range [%llu..%llu]%s.\n",
+	      config_file, fline, name, s, r, unit, min, max, unit);
+    }
+}
+
+enum range_checks
+{
+  R_MINOR_COUNT,
+  R_DIALOG_REFRESH,
+  R_DISK_SIZE,
+  R_TIMEOUT,
+  R_CONNECT_INT,
+  R_PING_INT,
+  R_MAX_BUFFERS,
+  R_MAX_EPOCH_SIZE,
+  R_SNDBUF_SIZE,
+  R_KO_COUNT,
+  R_RATE,
+  R_GROUP,
+  R_AL_EXTENTS,
+  R_PORT,
+  R_META_IDX,
+  R_WFC_TIMEOUT,
+  R_DEGR_WFC_TIMEOUT,
+};
+
+void
+range_check(const enum range_checks what, const char *name, const char *value)
+{
+  switch (what)
+    {
+    default:
+      fprintf(stderr, "%s:%d: unknown range for %s => %s\n",
+	      config_file, fline, name, value);
+      break;
+    case R_MINOR_COUNT:
+      m_strtoll_range(value, 1, name,
+		      DRBD_MINOR_COUNT_MIN, DRBD_MINOR_COUNT_MAX);
+      break;
+    case R_DIALOG_REFRESH:
+      m_strtoll_range(value, 1, name,
+		      DRBD_DIALOG_REFRESH_MIN, DRBD_DIALOG_REFRESH_MAX);
+      break;
+    case R_DISK_SIZE:
+      m_strtoll_range(value, 'K', name,
+		      DRBD_DISK_SIZE_SECT_MIN >> 1,
+		      DRBD_DISK_SIZE_SECT_MAX >> 1);
+      break;
+    case R_TIMEOUT:
+      m_strtoll_range(value, 1, name, DRBD_TIMEOUT_MIN, DRBD_TIMEOUT_MAX);
+      break;
+    case R_CONNECT_INT:
+      m_strtoll_range(value, 1, name, DRBD_CONNECT_INT_MIN,
+		      DRBD_CONNECT_INT_MAX);
+      break;
+    case R_PING_INT:
+      m_strtoll_range(value, 1, name, DRBD_PING_INT_MIN, DRBD_PING_INT_MAX);
+      break;
+    case R_MAX_BUFFERS:
+      m_strtoll_range(value, 1, name, DRBD_MAX_BUFFERS_MIN,
+		      DRBD_MAX_BUFFERS_MAX);
+      break;
+    case R_MAX_EPOCH_SIZE:
+      m_strtoll_range(value, 1, name, DRBD_MAX_EPOCH_SIZE_MIN,
+		      DRBD_MAX_EPOCH_SIZE_MAX);
+      break;
+    case R_SNDBUF_SIZE:
+      m_strtoll_range(value, 1, name, DRBD_SNDBUF_SIZE_MIN,
+		      DRBD_SNDBUF_SIZE_MAX);
+      break;
+    case R_KO_COUNT:
+      m_strtoll_range(value, 1, name, DRBD_KO_COUNT_MIN, DRBD_KO_COUNT_MAX);
+      break;
+    case R_RATE:
+      m_strtoll_range(value, 'K', name, DRBD_RATE_MIN, DRBD_RATE_MAX);
+      break;
+    case R_GROUP:
+      m_strtoll_range(value, 1, name, DRBD_GROUP_MIN, DRBD_GROUP_MAX);
+      break;
+    case R_AL_EXTENTS:
+      m_strtoll_range(value, 1, name, DRBD_AL_EXTENTS_MIN,
+		      DRBD_AL_EXTENTS_MAX);
+      break;
+    case R_PORT:
+      m_strtoll_range(value, 1, name, DRBD_PORT_MIN, DRBD_PORT_MAX);
+      break;
+      /* FIXME not yet implemented!
+         case R_META_IDX:
+         m_strtoll_range(value, 1, name, DRBD_META_IDX_MIN, DRBD_META_IDX_MAX);
+         break;
+       */
+    case R_WFC_TIMEOUT:
+      m_strtoll_range(value, 1, name, DRBD_WFC_TIMEOUT_MIN,
+		      DRBD_WFC_TIMEOUT_MAX);
+      break;
+    case R_DEGR_WFC_TIMEOUT:
+      m_strtoll_range(value, 1, name, DRBD_DEGR_WFC_TIMEOUT_MIN,
+		      DRBD_DEGR_WFC_TIMEOUT_MAX);
+      break;
+    }
+}
+
 static struct d_option* new_opt(char* name,char* value)
 {
   struct d_option* cn = malloc(sizeof(struct d_option));
@@ -116,10 +316,10 @@
 
 %token TK_GLOBAL TK_RESOURCE
 %token TK_ON TK_NET TK_DISK_S TK_SYNCER TK_STARTUP
-%token TK_MINOR_COUNT TK_DISABLE_IO_HINTS
+%token TK_DISABLE_IO_HINTS
 %token TK_PROTOCOL TK_INCON_DEGR_CMD
 %token TK_ADDRESS TK_DISK TK_DEVICE TK_META_DISK
-%token <txt> TK_INTEGER TK_STRING
+%token <txt> TK_MINOR_COUNT TK_INTEGER TK_STRING
 %token <txt> TK_ON_IO_ERROR TK_SIZE
 %token <txt> TK_TIMEOUT TK_CONNECT_INT TK_PING_INT TK_MAX_BUFFERS TK_IPADDR
 %token <txt> TK_MAX_EPOCH_SIZE TK_SNDBUF_SIZE
@@ -149,9 +349,15 @@
 glob_stmt:	  TK_DISABLE_IO_HINTS
 			{ global_options.disable_io_hints=1;   }
 		| TK_MINOR_COUNT TK_INTEGER
-			{ global_options.minor_count=atoi($2); }
-		| TK_DIALOG_REFRESH TK_INTEGER   
-                        { global_options.dialog_refresh=atoi($2); }
+		{
+			range_check(R_MINOR_COUNT,$1,$2);
+			global_options.minor_count=atoi($2);
+		}
+		| TK_DIALOG_REFRESH TK_INTEGER
+                {
+			range_check(R_DIALOG_REFRESH,$1,$2);
+			global_options.dialog_refresh=atoi($2);
+		}
 		;
 
 resources:	  /* empty */	     { $$ = 0; }
@@ -217,21 +423,29 @@
 		;
 
 disk_stmt:	  TK_ON_IO_ERROR TK_STRING { $$=new_opt($1,$2); }
-		| TK_SIZE TK_INTEGER       { $$=new_opt($1,$2); }
+		| TK_SIZE TK_INTEGER
+		{ $$=new_opt($1,$2); range_check(R_DISK_SIZE,$1,$2); }
 		;
 
 net_stmts:	  /* empty */	           { $$ = 0; }
 		| net_stmts net_stmt       { $$=APPEND($1,$2); }
 		;
 
-net_stmt:	  TK_TIMEOUT	    TK_INTEGER { $$=new_opt($1,$2); }
-		| TK_CONNECT_INT    TK_INTEGER { $$=new_opt($1,$2); }
-		| TK_PING_INT	    TK_INTEGER { $$=new_opt($1,$2); }
-		| TK_MAX_BUFFERS    TK_INTEGER { $$=new_opt($1,$2); }
-		| TK_MAX_EPOCH_SIZE TK_INTEGER { $$=new_opt($1,$2); }
-		| TK_SNDBUF_SIZE    TK_INTEGER { $$=new_opt($1,$2); }
-		| TK_KO_COUNT       TK_INTEGER { $$=new_opt($1,$2); }
-		| TK_ON_DISCONNECT  TK_STRING  { $$=new_opt($1,$2); }
+net_stmt:	  TK_TIMEOUT	    TK_INTEGER
+		{ range_check(R_TIMEOUT,$1,$2);		$$=new_opt($1,$2); }
+		| TK_CONNECT_INT    TK_INTEGER
+		{ range_check(R_CONNECT_INT,$1,$2);	$$=new_opt($1,$2); }
+		| TK_PING_INT	    TK_INTEGER
+		{ range_check(R_PING_INT,$1,$2);	$$=new_opt($1,$2); }
+		| TK_MAX_BUFFERS    TK_INTEGER
+		{ range_check(R_MAX_BUFFERS,$1,$2);	$$=new_opt($1,$2); }
+		| TK_MAX_EPOCH_SIZE TK_INTEGER
+		{ range_check(R_MAX_EPOCH_SIZE,$1,$2);	$$=new_opt($1,$2); }
+		| TK_SNDBUF_SIZE    TK_INTEGER
+		{ range_check(R_SNDBUF_SIZE,$1,$2);	$$=new_opt($1,$2); }
+		| TK_KO_COUNT       TK_INTEGER
+		{ range_check(R_KO_COUNT,$1,$2);	$$=new_opt($1,$2); }
+		| TK_ON_DISCONNECT  TK_STRING	{	$$=new_opt($1,$2); }
 		;
 
 sync_stmts:	  /* empty */	           { $$ = 0; }
@@ -240,9 +454,12 @@
 
 sync_stmt:	  TK_SKIP_SYNC		   { $$=new_opt($1,0);  }
 		| TK_USE_CSUMS		   { $$=new_opt($1,0);  }
-		| TK_RATE	TK_INTEGER { $$=new_opt($1,$2); }
+		| TK_RATE	TK_INTEGER
+		{ range_check(R_RATE,$1,$2); $$=new_opt($1,$2); }
 		| TK_SYNC_GROUP TK_INTEGER { $$=new_opt($1,$2); }
+		{ range_check(R_GROUP,$1,$2); $$=new_opt($1,$2); }
 		| TK_AL_EXTENTS TK_INTEGER { $$=new_opt($1,$2); }
+		{ range_check(R_AL_EXTENTS,$1,$2); $$=new_opt($1,$2); }
 		;
 
 host_stmts:	  /* empty */ { c_host=calloc(1,sizeof(struct d_host_info)); }
@@ -258,7 +475,10 @@
 
 
 ip_and_port:	  TK_IPADDR TK_INTEGER
-		{ c_host->address=$1; c_host->port = $2; }
+		{
+			range_check(R_PORT, "port", $2);
+			c_host->address=$1; c_host->port = $2;
+		}
 		;
 
 meta_disk_and_index:
@@ -271,6 +491,8 @@
 		| startup_stmts startup_stmt   { $$=APPEND($1,$2); }
 		;
 
-startup_stmt:	  TK_WFC_TIMEOUT      TK_INTEGER   { $$=new_opt($1,$2); }
-		| TK_DEGR_WFC_TIMEOUT TK_INTEGER   { $$=new_opt($1,$2); }
+startup_stmt:	  TK_WFC_TIMEOUT      TK_INTEGER
+		{ range_check(R_WFC_TIMEOUT,$1,$2);	$$=new_opt($1,$2); }
+		| TK_DEGR_WFC_TIMEOUT TK_INTEGER
+		{ range_check(R_DEGR_WFC_TIMEOUT,$1,$2);$$=new_opt($1,$2); }
 		;

Modified: trunk/user/drbdadm_scanner.fl
===================================================================
--- trunk/user/drbdadm_scanner.fl	2004-10-28 19:41:23 UTC (rev 1616)
+++ trunk/user/drbdadm_scanner.fl	2004-10-28 20:06:21 UTC (rev 1617)
@@ -57,8 +57,9 @@
 COMMENT			  \#[^\n]*
 WSC			  ({WS}|{COMMENT}\n)+
 ASSIGN			  {LS}
-NUM			  [0-9]+
-NUM_U			  [0-9]+[kmgKMG]? 
+OUT_OF_RANGE_NUM	  [0-9]{10,}[kmgKMG]? 
+NUM			  [0-9]{1,9}
+NUM_U			  [0-9]{1,9}[kmgKMG]? 
 NAME			  [/_.A-Za-z0-9-]+
 STRING			  ({NAME}|\"([^\"\\\n]*|\\.)*\")+
 USTRING			  \"([^\"\\\n]*|\\.)*
@@ -113,6 +114,13 @@
   {NDELIM}		expect_error("whitespace");
 }
 
+<NUM,NUM_U>{
+  {OUT_OF_RANGE_NUM}	{
+			  PRINTF("%s: number exeeds limit of 9 digits\n", yytext);
+			  exit(E_syntax);
+			}
+}
+
 <NUM>{
   {NUM}			yy_pop_state(); CP; return TK_INTEGER;
   {NDELIM}		expect_error("integer"); yy_pop_state();
@@ -189,7 +197,7 @@
 }
 
 <GLOBAL>{
-  minor[-_]count	do_assign(NUM); return TK_MINOR_COUNT;
+  minor[-_]count	do_assign(NUM); CP; return TK_MINOR_COUNT;
   disable[-_]io[-_]hints yy_push_state(SEMICOLON); return TK_DISABLE_IO_HINTS;
   dialog-refresh        do_assign(NUM); CP; return TK_DIALOG_REFRESH;
   {NDELIM}		expect_error("'minor-count|disable-io-hints|dialog-refresh'");

Modified: trunk/user/drbdsetup.c
===================================================================
--- trunk/user/drbdsetup.c	2004-10-28 19:41:23 UTC (rev 1616)
+++ trunk/user/drbdsetup.c	2004-10-28 20:06:21 UTC (rev 1617)
@@ -48,6 +48,7 @@
 #include <dirent.h>
 #include <mntent.h>
 #include "drbdtool_common.h"
+#include "drbd_limits.h"
 
 /* Default values */
 #define DEF_NET_TIMEOUT             60      //  6 seconds
@@ -203,6 +204,108 @@
   return retval;
 }
 
+<<<<<<< .working
+=======
+unsigned long long
+m_strtoll(const char *s, char def_unit)
+{
+  unsigned long long r;
+  char unit = 0;
+  char dummy = 0;
+  int shift, c;
+
+  /*
+   * paranoia
+   */
+  switch (def_unit)
+    {
+    default:
+      fprintf(stderr, "%s:%d: unexpected default unit\n", __FILE__, __LINE__);
+      exit(100);
+    case 0:
+    case 1:
+    case '1':
+      shift = 0;
+      break;
+
+    case 'K':
+    case 'k':
+      shift = -10;
+      break;
+
+      /*
+         case 'M':
+         case 'm':
+         case 'G':
+         case 'g':
+       */
+    }
+
+  if (!s || !*s)
+    {
+      fprintf(stderr, "missing number argument\n");
+      exit(100);
+    }
+
+  c = sscanf(s, "%llu%c%c", &r, &unit, &dummy);
+
+  if (c != 1 && c != 2)
+    {
+      fprintf(stderr, "%s is not a valid number\n", s);
+      exit(20);
+    }
+
+  switch (unit)
+    {
+    case 0:
+      return r;
+    case 'K':
+    case 'k':
+      shift += 10;
+      break;
+    case 'M':
+    case 'm':
+      shift += 20;
+      break;
+    case 'G':
+    case 'g':
+      shift += 30;
+      break;
+    default:
+      fprintf(stderr, "%s is not a valid number\n", s);
+      exit(20);
+    }
+  if (r > (~0ULL >> shift))
+    {
+      fprintf(stderr, "%s: out of range\n", s);
+      exit(20);
+    }
+  return r << shift;
+}
+
+>>>>>>> .merge-right.r1613
+/* NOTE all values are _unsigned_ */
+unsigned long long
+m_strtoll_range(const char *s, const char def_unit, const char *name,
+		const unsigned long long min, const unsigned long long max)
+{
+  unsigned long long r = m_strtoll(s, def_unit);
+  char unit[] = { def_unit > '1' ? def_unit : 0, 0 };
+  if (min > r || r > max)
+    {
+      fprintf(stderr, "%s %s => %llu%s out of range [%llu..%llu]%s\n",
+	      name, s, r, unit, min, max, unit);
+      exit(20);
+    }
+  if (DEBUG_RANGE_CHECK)
+    {
+      fprintf(stderr,
+	      "OK: %s %s => %llu%s in range [%llu..%llu]%s.\n",
+	      name, s, r, unit, min, max, unit);
+    }
+  return r;
+}
+
 const char* addr_part(const char* s)
 {
   static char buffer[200];
@@ -224,7 +327,7 @@
 
   b=strchr(s,':');
   if(b)
-      return m_strtol(b+1,1);
+      return m_strtoll_range(b+1,1, "port", DRBD_PORT_MIN, DRBD_PORT_MAX);
 
   return 7788;
 }
@@ -311,7 +414,7 @@
   int i;
 
   printf("\nUSAGE: %s device command arguments options\n\n"
-	 "Device is usually /dev/nbX or /dev/drbd/X.\n"
+	 "Device is usually /dev/drbdX or /dev/drbd/X.\n"
          "Commands, arguments and options are:\n",basename);
 
 
@@ -383,7 +486,9 @@
       switch(c)
 	{
 	case 'd':
-	  cn->config.disk_size = m_strtol(optarg,1024);
+	  cn->config.disk_size = m_strtoll_range(optarg,'K', "disk-size",
+			      DRBD_DISK_SIZE_SECT_MIN>>1,
+			      DRBD_DISK_SIZE_SECT_MAX>>1 );
 	  break;
 	case 'e':
 	  for(i=0;i<ARRY_SIZE(eh_names);i++) {
@@ -431,25 +536,33 @@
       switch(c)
 	{
 	case 't':
-	  cn->config.timeout = m_strtol(optarg,1);
+	  cn->config.timeout = m_strtoll_range(optarg,1, "timeout",
+			  DRBD_TIMEOUT_MIN, DRBD_TIMEOUT_MAX);
 	  break;
 	case 'e':
-	  cn->config.max_epoch_size = m_strtol(optarg,1);
+	  cn->config.max_epoch_size = m_strtoll_range(optarg,1,
+			  "max-epoch-size",
+			  DRBD_MAX_EPOCH_SIZE_MIN, DRBD_MAX_EPOCH_SIZE_MAX);
 	  break;
 	case 'b':
-	  cn->config.max_buffers = m_strtol(optarg,1);
+	  cn->config.max_buffers = m_strtoll_range(optarg,1, "max-buffers",
+			  DRBD_MAX_BUFFERS_MIN, DRBD_MAX_BUFFERS_MIN);
 	  break;
 	case 'c':
-	  cn->config.try_connect_int = m_strtol(optarg,1);
+	  cn->config.try_connect_int = m_strtoll_range(optarg,1, "connect-int",
+			  DRBD_CONNECT_INT_MIN, DRBD_CONNECT_INT_MAX);
 	  break;
 	case 'i':
-	  cn->config.ping_int = m_strtol(optarg,1);
+	  cn->config.ping_int = m_strtoll_range(optarg,1, "ping-int",
+			  DRBD_PING_INT_MIN, DRBD_PING_INT_MAX);
 	  break;
 	case 'S':
-	  cn->config.sndbuf_size = m_strtol(optarg,1);
+	  cn->config.sndbuf_size = m_strtoll_range(optarg,1, "sndbuf-size",
+			  DRBD_SNDBUF_SIZE_MIN, DRBD_SNDBUF_SIZE_MAX);
 	  break;
        case 'k':
-          cn->config.ko_count = m_strtol(optarg,1);
+          cn->config.ko_count = m_strtoll_range(optarg,1, "ko-count",
+			  DRBD_KO_COUNT_MIN, DRBD_KO_COUNT_MAX);
           break;
 	case 'd':
 	  for(i=0;i<ARRY_SIZE(dh_names);i++) {
@@ -783,10 +896,14 @@
 	  switch(c)
 	    {
 	    case 't':
-	      p.wfc_timeout = m_strtol(optarg,1);
+	      p.wfc_timeout = m_strtoll_range(optarg,1, "wfc-timeout",
+			      DRBD_WFC_TIMEOUT_MIN, DRBD_WFC_TIMEOUT_MAX);
 	      break;
 	    case 'd':
-	      p.degr_wfc_timeout = m_strtol(optarg,1);
+	      p.degr_wfc_timeout = m_strtoll_range(optarg,1,
+			      "degr-wfc-timeout",
+			      DRBD_DEGR_WFC_TIMEOUT_MIN,
+			      DRBD_DEGR_WFC_TIMEOUT_MAX);
 	      break;
 	    case 1:	// non option argument. see getopt_long(3)
 	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",basename,optarg);
@@ -858,13 +975,16 @@
 	      cn.config.skip=1;
 	      break;
 	    case 'r':
-	      cn.config.rate=m_strtol(optarg,1024);
+	      cn.config.rate=m_strtoll_range(optarg,'K', "rate",
+			      DRBD_RATE_MIN, DRBD_RATE_MAX);
 	      break;
 	    case 'g':
-	      cn.config.group=m_strtol(optarg,1);
+	      cn.config.group=m_strtoll_range(optarg,1, "group",
+			      DRBD_GROUP_MIN, DRBD_GROUP_MAX);
 	      break;
 	    case 'e':
-	      cn.config.al_extents=m_strtol(optarg,1);
+	      cn.config.al_extents=m_strtoll_range(optarg,1, "al-extents",
+			      DRBD_AL_EXTENTS_MIN, DRBD_AL_EXTENTS_MAX);
 	      break;
 	    case 1:	// non option argument. see getopt_long(3)
 	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",basename,optarg);
@@ -991,12 +1111,12 @@
   retval=scan_disk_options(argv,argc,&cn,options);
   if(retval) return retval;
 
-  mi = m_strtol(argv[5],1);
+  mi = m_strtoll(argv[5],1);
   if( mi < -1 ) {
     fprintf(stderr,"meta_index may not be smaller than -1.\n");
-    return 20;    
+    return 20;
   }
-  //TODO check that mi*128M is not bigger than meta device!
+  //FIXME check that mi*128M is not bigger than meta device!
   cn.config.meta_index = mi;
 
   return do_disk_conf(drbd_fd,argv[3],argv[4],&cn);
@@ -1019,7 +1139,9 @@
 	  switch(c)
 	    {
 	    case 'd':
-	      u_size=m_strtol(optarg,1024);
+	      u_size=m_strtoll_range(optarg,'K', "disk-size",
+			      DRBD_DISK_SIZE_SECT_MIN>>1,
+			      DRBD_DISK_SIZE_SECT_MAX>>1 );
 	      break;
 	    case 1:	// non option argument. see getopt_long(3)
 	      fprintf(stderr,"%s: Unexpected nonoption argument '%s'\n",basename,optarg);
@@ -1281,7 +1403,9 @@
   else
       basename = argv[0];
 
-  if (argc > 1 && !strcmp(argv[1],"help")) help = 1;
+  /* == '-' catches -h, --help, and similar */
+  if (argc > 1 && (!strcmp(argv[1],"help") || argv[1][0] == '-'))
+	  help = 1;
   if (argc < 3) print_usage(argc==1 ? 0 : " Insufficient arguments");
 
   chdir("/");



More information about the drbd-cvs mailing list