[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