[sheepdog] [PATCH 4/6] use sd_getopt instead of getopt_long

morita.kazutaka at gmail.com morita.kazutaka at gmail.com
Mon Nov 5 11:52:01 CET 2012


From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 collie/cluster.c          |   28 +++---
 collie/collie.c           |   30 +++---
 collie/collie.h           |    2 +-
 collie/debug.c            |    2 +-
 collie/vdi.c              |   32 +++----
 include/option.h          |    1 -
 sheep/cluster.h           |    9 +-
 sheep/cluster/accord.c    |   12 ++-
 sheep/cluster/corosync.c  |    2 +-
 sheep/cluster/local.c     |    8 +-
 sheep/cluster/zookeeper.c |   12 ++-
 sheep/sheep.c             |  223 +++++++++++++++++----------------------------
 sheep/sheep_priv.h        |    2 +-
 13 files changed, 152 insertions(+), 211 deletions(-)

diff --git a/collie/cluster.c b/collie/cluster.c
index 8e97a8e..24e5063 100644
--- a/collie/cluster.c
+++ b/collie/cluster.c
@@ -429,40 +429,36 @@ static struct subcommand cluster_cmd[] = {
 	{NULL,},
 };
 
-static int cluster_parser(int ch, char *opt)
+static int cluster_parser(struct sd_option *opt)
 {
-	int copies;
-	char *p;
-
-	switch (ch) {
+	switch (opt->ch) {
 	case 'b':
 		pstrcpy(cluster_cmd_data.name, sizeof(cluster_cmd_data.name),
-			opt);
+			opt->arg.str);
 		break;
 	case 'c':
-		copies = strtol(opt, &p, 10);
-		if (opt == p || copies < 1) {
+		if (!sd_opt_is_valid_number(&opt->arg, 1, INT64_MAX)) {
 			fprintf(stderr, "There must be at least one copy of data\n");
 			exit(EXIT_FAILURE);
-		} else if (copies > SD_MAX_COPIES) {
+		} else if (!sd_opt_is_valid_number(&opt->arg, 1, SD_MAX_COPIES)) {
 			fprintf(stderr, "Redundancy may not exceed %d copies\n",
 				SD_MAX_COPIES);
 			exit(EXIT_FAILURE);
 		}
-		cluster_cmd_data.copies = copies;
+		cluster_cmd_data.copies = opt->arg.num;
 		break;
 	case 'm':
-		if (strcmp(opt, "safe") == 0) {
+		if (strcmp(opt->arg.str, "safe") == 0) {
 			cluster_cmd_data.nohalt = false;
 			cluster_cmd_data.quorum = false;
-		} else if (strcmp(opt, "quorum") == 0) {
+		} else if (strcmp(opt->arg.str, "quorum") == 0) {
 			cluster_cmd_data.nohalt = false;
 			cluster_cmd_data.quorum = true;
-		} else if (strcmp(opt, "unsafe") == 0) {
+		} else if (strcmp(opt->arg.str, "unsafe") == 0) {
 			cluster_cmd_data.nohalt = true;
 			cluster_cmd_data.quorum = false;
 		} else {
-			fprintf(stderr, "Unknown mode '%s'\n", opt);
+			fprintf(stderr, "Unknown mode '%s'\n", opt->arg.str);
 			exit(EXIT_FAILURE);
 		}
 		break;
@@ -470,11 +466,11 @@ static int cluster_parser(int ch, char *opt)
 		cluster_cmd_data.force = true;
 		break;
 	case 'R':
-		cluster_cmd_data.epoch = strtol(opt, &p, 10);
-		if (opt == p) {
+		if (!sd_opt_is_number(&opt->arg)) {
 			fprintf(stderr, "The epoch must be an integer\n");
 			exit(EXIT_FAILURE);
 		}
+		cluster_cmd_data.epoch = opt->arg.num;
 		if (cluster_cmd_data.epoch < 1) {
 			fprintf(stderr, "The epoch must be greater than 0\n");
 			exit(EXIT_FAILURE);
diff --git a/collie/collie.c b/collie/collie.c
index 7b8e95f..5724a80 100644
--- a/collie/collie.c
+++ b/collie/collie.c
@@ -107,7 +107,7 @@ out:
 	return ret;
 }
 
-static int (*command_parser)(int, char *);
+static int (*command_parser)(struct sd_option *);
 static int (*command_fn)(int, char **);
 static const char *command_opts;
 static const char *command_arg;
@@ -302,7 +302,7 @@ void subcommand_usage(char *cmd, char *subcmd, int status)
 	exit(status);
 }
 
-static const struct sd_option *build_sd_options(const char *opts)
+static struct sd_option *build_sd_options(const char *opts)
 {
 	static struct sd_option sd_opts[256], *p;
 	int i, len = strlen(opts);
@@ -317,13 +317,10 @@ static const struct sd_option *build_sd_options(const char *opts)
 
 int main(int argc, char **argv)
 {
-	int ch, longindex, ret;
+	int ret;
 	unsigned long flags;
-	struct option *long_options;
 	const struct command *commands;
-	const char *short_options;
-	char *p;
-	const struct sd_option *sd_opts;
+	struct sd_option *sd_opts, *opt;
 
 	init_commands(&commands);
 
@@ -335,22 +332,18 @@ int main(int argc, char **argv)
 	optind = 3;
 
 	sd_opts = build_sd_options(command_opts);
-	long_options = build_long_options(sd_opts);
-	short_options = build_short_options(sd_opts);
+	while ((opt = sd_getopt(argc, argv, sd_opts)) != NULL) {
 
-	while ((ch = getopt_long(argc, argv, short_options, long_options,
-				&longindex)) >= 0) {
-
-		switch (ch) {
+		switch (opt->ch) {
 		case 'a':
-			sdhost = optarg;
+			sdhost = opt->arg.str;
 			break;
 		case 'p':
-			sdport = strtol(optarg, &p, 10);
-			if (optarg == p || sdport < 1 || sdport > UINT16_MAX) {
-				fprintf(stderr, "Invalid port number '%s'\n", optarg);
+			if (!sd_opt_is_valid_number(&opt->arg, 1, UINT16_MAX)) {
+				fprintf(stderr, "Invalid port number '%s'\n", opt->arg.str);
 				exit(EXIT_USAGE);
 			}
+			sdport = opt->arg.num;
 			break;
 		case 'r':
 			raw_output = true;
@@ -359,11 +352,12 @@ int main(int argc, char **argv)
 			subcommand_usage(argv[1], argv[2], EXIT_SUCCESS);
 			break;
 		case '?':
+		case '\0':
 			usage(commands, EXIT_USAGE);
 			break;
 		default:
 			if (command_parser)
-				command_parser(ch, optarg);
+				command_parser(opt);
 			else
 				usage(commands, EXIT_USAGE);
 			break;
diff --git a/collie/collie.h b/collie/collie.h
index 1b00e68..078d1ed 100644
--- a/collie/collie.h
+++ b/collie/collie.h
@@ -33,7 +33,7 @@
 struct command {
 	const char *name;
 	struct subcommand *sub;
-	int (*parser)(int, char *);
+	int (*parser)(struct sd_option *);
 };
 
 struct subcommand {
diff --git a/collie/debug.c b/collie/debug.c
index 11d5934..1de1ec5 100644
--- a/collie/debug.c
+++ b/collie/debug.c
@@ -190,7 +190,7 @@ static int trace_cat(int argc, char **argv)
 	return EXIT_SUCCESS;
 }
 
-static int debug_parser(int ch, char *opt)
+static int debug_parser(struct sd_option *opt)
 {
 	return 0;
 }
diff --git a/collie/vdi.c b/collie/vdi.c
index e8e3b2e..c4839df 100644
--- a/collie/vdi.c
+++ b/collie/vdi.c
@@ -1897,28 +1897,26 @@ static struct subcommand vdi_cmd[] = {
 	{NULL,},
 };
 
-static int vdi_parser(int ch, char *opt)
+static int vdi_parser(struct sd_option *opt)
 {
-	char *p;
-	int nr_copies;
-
-	switch (ch) {
+	switch (opt->ch) {
 	case 'P':
 		vdi_cmd_data.prealloc = true;
 		break;
 	case 'i':
-		vdi_cmd_data.index = strtol(opt, &p, 10);
-		if (opt == p) {
-			fprintf(stderr, "The index must be an integer\n");
+		if (!sd_opt_is_valid_number(&opt->arg, 0, MAX_DATA_OBJS)) {
+			fprintf(stderr, "The index is invalid, %s\n", opt->arg.str);
 			exit(EXIT_FAILURE);
 		}
+		vdi_cmd_data.index = opt->arg.num;
 		break;
 	case 's':
-		vdi_cmd_data.snapshot_id = strtol(opt, &p, 10);
-		if (opt == p) {
+		if (sd_opt_is_number(&opt->arg))
+			vdi_cmd_data.snapshot_id = opt->arg.num;
+		else {
 			vdi_cmd_data.snapshot_id = 0;
 			pstrcpy(vdi_cmd_data.snapshot_tag,
-				sizeof(vdi_cmd_data.snapshot_tag), opt);
+				sizeof(vdi_cmd_data.snapshot_tag), opt->arg.str);
 		}
 		break;
 	case 'x':
@@ -1931,20 +1929,20 @@ static int vdi_parser(int ch, char *opt)
 		vdi_cmd_data.writeback = true;
 		break;
 	case 'c':
-		nr_copies = strtol(opt, &p, 10);
-		if (opt == p || nr_copies < 0 || nr_copies > SD_MAX_COPIES) {
+		if (!sd_opt_is_valid_number(&opt->arg, 0, SD_MAX_COPIES)) {
 			fprintf(stderr, "Invalid copies number, must be "
 				"an integer between 0 and %d\n", SD_MAX_COPIES);
 			exit(EXIT_FAILURE);
 		}
-		vdi_cmd_data.nr_copies = nr_copies;
+		vdi_cmd_data.nr_copies = opt->arg.num;
 		break;
 	case 'F':
-		vdi_cmd_data.from_snapshot_id = strtol(opt, &p, 10);
-		if (opt == p) {
+		if (sd_opt_is_number(&opt->arg))
+			vdi_cmd_data.from_snapshot_id = opt->arg.num;
+		else {
 			vdi_cmd_data.from_snapshot_id = 0;
 			pstrcpy(vdi_cmd_data.from_snapshot_tag,
-				sizeof(vdi_cmd_data.from_snapshot_tag), opt);
+				sizeof(vdi_cmd_data.from_snapshot_tag), opt->arg.str);
 		}
 		break;
 	}
diff --git a/include/option.h b/include/option.h
index ccc5158..5fdca82 100644
--- a/include/option.h
+++ b/include/option.h
@@ -12,7 +12,6 @@
 #define __SD_OPTION_H__
 
 #include <stdbool.h>
-#include <getopt.h>
 #include <stdint.h>
 
 /*
diff --git a/sheep/cluster.h b/sheep/cluster.h
index 2679c19..1016d9e 100644
--- a/sheep/cluster.h
+++ b/sheep/cluster.h
@@ -22,6 +22,7 @@
 #include "sheepdog_proto.h"
 #include "sheep.h"
 #include "logger.h"
+#include "option.h"
 
 /* maximum payload size sent in ->notify and ->unblock */
 #define SD_MAX_EVENT_BUF_SIZE (64 * 1024)
@@ -44,7 +45,7 @@ struct cluster_driver {
 	 *
 	 * Returns zero on success, -1 on error.
 	 */
-	int (*init)(const char *option);
+	int (*init)(struct sd_opt_param *option);
 
 	/*
 	 * Get a node ID for this sheep.
@@ -129,13 +130,9 @@ static void __attribute__((constructor)) regist_ ## driver(void) {	\
 static inline struct cluster_driver *find_cdrv(const char *name)
 {
 	struct cluster_driver *cdrv;
-	int len;
 
 	FOR_EACH_CLUSTER_DRIVER(cdrv) {
-		len = strlen(cdrv->name);
-
-		if (strncmp(cdrv->name, name, len) == 0 &&
-		    (name[len] == ':' || name[len] == '\0'))
+		if (strcmp(cdrv->name, name) == 0)
 			return cdrv;
 	}
 
diff --git a/sheep/cluster/accord.c b/sheep/cluster/accord.c
index be0cf83..af4190b 100644
--- a/sheep/cluster/accord.c
+++ b/sheep/cluster/accord.c
@@ -521,21 +521,25 @@ out:
 	pthread_mutex_unlock(&queue_lock);
 }
 
-static int accord_init(const char *option)
+static int accord_init(struct sd_opt_param *option)
 {
 	int ret;
+	struct sd_opt_value *opt_val;
+	const char *server;
 
-	if (!option) {
+	opt_val = sd_opt_param_get(option, "accord", "server");
+	if (!opt_val) {
 		eprintf("specify one of the accord servers.\n");
 		eprintf("e.g. sheep /store -c accord:127.0.0.1\n");
 		return -1;
 	}
+	server = opt_val->str;
 
 	pthread_mutex_lock(&start_lock);
 
-	ahandle = acrd_init(option, 9090, acrd_join_fn, acrd_leave_fn, NULL);
+	ahandle = acrd_init(server, 9090, acrd_join_fn, acrd_leave_fn, NULL);
 	if (!ahandle) {
-		eprintf("failed to connect to accrd server %s\n", option);
+		eprintf("failed to connect to accrd server %s\n", server);
 		return -1;
 	}
 
diff --git a/sheep/cluster/corosync.c b/sheep/cluster/corosync.c
index a607bae..0088e0d 100644
--- a/sheep/cluster/corosync.c
+++ b/sheep/cluster/corosync.c
@@ -756,7 +756,7 @@ out:
 	exit(1);
 }
 
-static int corosync_init(const char *option)
+static int corosync_init(struct sd_opt_param *option)
 {
 	int ret, retry_cnt = 0;
 	uint32_t nodeid;
diff --git a/sheep/cluster/local.c b/sheep/cluster/local.c
index 20ce325..79a29ab 100644
--- a/sheep/cluster/local.c
+++ b/sheep/cluster/local.c
@@ -523,17 +523,19 @@ static int local_get_local_addr(uint8_t *myaddr)
 	return 0;
 }
 
-static int local_init(const char *option)
+static int local_init(struct sd_opt_param *option)
 {
 	sigset_t mask;
 	int ret;
+	struct sd_opt_value *opt_val;
 	static struct timer t = {
 		.callback = check_pids,
 		.data = &t,
 	};
 
-	if (option)
-		shmfile = option;
+	opt_val = sd_opt_param_get(option, "local", "shmfile");
+	if (opt_val && opt_val->str)
+		shmfile = opt_val->str;
 
 	shm_queue_init();
 
diff --git a/sheep/cluster/zookeeper.c b/sheep/cluster/zookeeper.c
index 91ea608..826ef74 100644
--- a/sheep/cluster/zookeeper.c
+++ b/sheep/cluster/zookeeper.c
@@ -792,22 +792,26 @@ out:
 	return;
 }
 
-static int zk_init(const char *option)
+static int zk_init(struct sd_opt_param *option)
 {
 	int ret;
+	struct sd_opt_value *opt_val;
+	char *servers;
 
-	if (!option) {
+	opt_val = sd_opt_param_get(option, "zookeeper", "server");
+	if (!opt_val) {
 		eprintf("specify comma separated host:port pairs, "
 			"each corresponding to a zk server.\n");
 		eprintf("e.g. sheep /store -c zookeeper:127.0.0.1:"
 			"3000,127.0.0.1:3001,127.0.0.1:3002\n");
 		return -1;
 	}
+	servers = opt_val->str;
 
-	zhandle = zookeeper_init(option, watcher, SESSION_TIMEOUT, NULL, NULL,
+	zhandle = zookeeper_init(servers, watcher, SESSION_TIMEOUT, NULL, NULL,
 				 0);
 	if (!zhandle) {
-		eprintf("failed to connect to zk server %s\n", option);
+		eprintf("failed to connect to zk server %s\n", servers);
 		return -1;
 	}
 	dprintf("request session timeout:%dms, "
diff --git a/sheep/sheep.c b/sheep/sheep.c
index 576bc5a..b86b815 100644
--- a/sheep/sheep.c
+++ b/sheep/sheep.c
@@ -39,9 +39,27 @@
 LIST_HEAD(cluster_drivers);
 static const char program_name[] = "sheep";
 
+static struct sd_opt_param cluster_options[] = {
+	{"local", "shmfile", "<filename>",
+	 "specify a file to be used for shared memory"},
+	{"zookeeper", "server", "<host[:port]>[,...]",
+	 "specify ZooKeeper servers with comma separated host:port pairs"},
+	{"accord", "server", "<server>",
+	 "specify one of Accord servers"},
+	{NULL, NULL, NULL, NULL},
+};
+
+static struct sd_opt_param write_cache_options[] = {
+	{"object", "size", "<size>",
+	 "specify a cache size for object cache"},
+	{"object", "directio", "<on|off>",
+	 "avoid using gateway page cache"},
+	{NULL, NULL, NULL, NULL},
+};
+
 static struct sd_option sheep_options[] = {
 	{'b', "bindaddr", true, NULL, "specify IP address of interface to listen on"},
-	{'c', "cluster", true, NULL, "specify the cluster driver"},
+	{'c', "cluster", true, cluster_options, "specify the cluster driver"},
 	{'d', "debug", false, NULL, "include debug messages in the log"},
 	{'f', "foreground", false, NULL, "make the program run in the foreground"},
 	{'g', "gateway", false, NULL, "make the progam run as a gateway mode"},
@@ -51,9 +69,9 @@ static struct sd_option sheep_options[] = {
 	{'o', "stdout", false, NULL, "log to stdout instead of shared logger"},
 	{'p', "port", true, NULL, "specify the TCP port on which to listen"},
 	{'P', "pidfile", true, NULL, "create a pid file"},
-	{'s', "disk-space", true, NULL, "specify the free disk space in megabytes"},
+	{'s', "disk-space", true, NULL, "specify the free disk space"},
 	{'u', "upgrade", false, NULL, "upgrade to the latest data layout"},
-	{'w', "write-cache", true, NULL, "specify the cache type"},
+	{'w', "write-cache", true, write_cache_options, "specify the cache type"},
 	{'y', "myaddr", true, NULL, "specify the address advertised to other sheep"},
 	{'z', "zone", true, NULL, "specify the zone id"},
 	{ 0, NULL, false, NULL, NULL },
@@ -172,101 +190,52 @@ static int init_signal(void)
 static struct cluster_info __sys;
 struct cluster_info *sys = &__sys;
 
-static void parse_arg(char *arg, const char *delim, void (*fn)(char *))
-{
-	char *savep, *s;
-
-	s = strtok_r(arg, delim, &savep);
-	do {
-		fn(s);
-	} while ((s = strtok_r(NULL, delim, &savep)));
-}
-
-static void object_cache_size_set(char *s)
-{
-	const char *header = "size=";
-	int len = strlen(header);
-	char *size, *p;
-	uint64_t cache_size;
-	const uint32_t max_cache_size = UINT32_MAX;
-
-	assert(!strncmp(s, header, len));
-
-	size = s + len;
-	cache_size = strtoull(size, &p, 10);
-	if (size == p || max_cache_size < cache_size)
-		goto err;
-
-	sys->object_cache_size = cache_size;
-	return;
-
-err:
-	fprintf(stderr, "Invalid object cache option '%s': "
-		"size must be an integer between 1 and %"PRIu32" inclusive\n",
-		s, max_cache_size);
-	exit(1);
-}
-
-static void object_cache_directio_set(char *s)
+static int object_cache_set(struct sd_opt_param *params)
 {
-	assert(!strcmp(s, "directio"));
-	sys->object_cache_directio = true;
-}
-
-static void _object_cache_set(char *s)
-{
-	int i;
-	static bool first = true;
-
-	struct object_cache_arg {
-		const char *name;
-		void (*set)(char *);
-	};
-
-	struct object_cache_arg object_cache_args[] = {
-		{ "size=", object_cache_size_set },
-		{ "directio", object_cache_directio_set },
-		{ NULL, NULL },
-	};
-
-	if (first) {
-		assert(!strcmp(s, "object"));
-		first = false;
-		return;
-	}
+	const struct sd_opt_value *opt_val;
 
-	for (i = 0; object_cache_args[i].name; i++) {
-		const char *n = object_cache_args[i].name;
+	sys->enabled_cache_type |= CACHE_TYPE_OBJECT;
 
-		if (!strncmp(s, n, strlen(n))) {
-			object_cache_args[i].set(s);
-			return;
+	opt_val = sd_opt_param_get(params, "object", "directio");
+	if (opt_val) {
+		if (!sd_opt_is_bool(opt_val)) {
+			fprintf(stderr, "set directio with on or off\n");
+			return -1;
 		}
+		sys->object_cache_directio = opt_val->boolean;
 	}
 
-	fprintf(stderr, "invalid object cache arg: %s\n", s);
-	exit(1);
-}
+	opt_val = sd_opt_param_get(params, "object", "size");
+	if (!opt_val) {
+		fprintf(stderr, "object cache size is not set\n");
+		return -1;
+	} else if (!sd_opt_is_size(opt_val)) {
+		fprintf(stderr, "invalid cache size, %s\n",
+			opt_val->str);
+		return -1;
+	} else if (opt_val->size < SD_DATA_OBJ_SIZE) {
+		fprintf(stderr, "Cache size %s is too small\n",
+			opt_val->str);
+		return -1;
+	}
+	sys->object_cache_size = opt_val->size / 1024 / 1024;
 
-static void object_cache_set(char *s)
-{
-	sys->enabled_cache_type |= CACHE_TYPE_OBJECT;
-	parse_arg(s, ":", _object_cache_set);
+	return 0;
 }
 
-static void disk_cache_set(char *s)
+static int disk_cache_set(struct sd_opt_param *params)
 {
-	assert(!strcmp(s, "disk"));
 	sys->enabled_cache_type |= CACHE_TYPE_DISK;
+	return 0;
 }
 
-static void do_cache_type(char *s)
+static int init_cache_type(struct sd_option *opt)
 {
 	int i;
 
 	struct cache_type {
 		const char *name;
-		void (*set)(char *);
+		int (*set)(struct sd_opt_param *);
 	};
 	struct cache_type cache_types[] = {
 		{ "object", object_cache_set },
@@ -277,31 +246,16 @@ static void do_cache_type(char *s)
 	for (i = 0; cache_types[i].name; i++) {
 		const char *n = cache_types[i].name;
 
-		if (!strncmp(s, n, strlen(n))) {
-			cache_types[i].set(s);
-			return;
-		}
+		if (!strncmp(opt->arg.str, n, strlen(n)))
+			return cache_types[i].set(opt->params);
 	}
+	fprintf(stderr, "invalid cache type: %s\n", opt->arg.str);
 
-	fprintf(stderr, "invalid cache type: %s\n", s);
-	exit(1);
-}
-
-static void init_cache_type(char *arg)
-{
-	sys->object_cache_size = 0;
-
-	parse_arg(arg, ",", do_cache_type);
-
-	if (is_object_cache_enabled() && sys->object_cache_size == 0) {
-		fprintf(stderr, "object cache size is not set\n");
-		exit(1);
-	}
+	return -1;
 }
 
 int main(int argc, char **argv)
 {
-	int ch, longindex;
 	int ret, port = SD_LISTEN_PORT;
 	const char *dir = DEFAULT_OBJECT_DIR;
 	bool is_daemon = true;
@@ -309,57 +263,51 @@ int main(int argc, char **argv)
 	int log_level = SDOG_INFO;
 	char path[PATH_MAX];
 	int64_t zone = -1;
-	int64_t free_space = 0;
 	int nr_vnodes = SD_DEFAULT_VNODES;
 	bool explicit_addr = false;
 	int af;
-	char *p;
 	struct cluster_driver *cdrv;
 	char *pid_file = NULL;
 	char *bindaddr = NULL;
 	unsigned char buf[sizeof(struct in6_addr)];
 	int ipv4 = 0;
 	int ipv6 = 0;
-	struct option *long_options;
-	const char *short_options;
+	struct sd_option *opt;
 
 	signal(SIGPIPE, SIG_IGN);
 
-	long_options = build_long_options(sheep_options);
-	short_options = build_short_options(sheep_options);
-	while ((ch = getopt_long(argc, argv, short_options, long_options,
-				 &longindex)) >= 0) {
-		switch (ch) {
+	while ((opt = sd_getopt(argc, argv, sheep_options)) != NULL) {
+		switch (opt->ch) {
 		case 'p':
-			port = strtol(optarg, &p, 10);
-			if (optarg == p || port < 1 || port > UINT16_MAX) {
+			if (!sd_opt_is_valid_number(&opt->arg, 1, UINT16_MAX)) {
 				fprintf(stderr, "Invalid port number '%s'\n",
-					optarg);
+					opt->arg.str);
 				exit(1);
 			}
+			port = opt->arg.num;
 			break;
 		case 'P':
-			pid_file = optarg;
+			pid_file = opt->arg.str;
 			break;
 		case 'f':
 			is_daemon = false;
 			break;
 		case 'l':
-			log_level = strtol(optarg, &p, 10);
-			if (optarg == p || log_level < SDOG_EMERG ||
-			    log_level > SDOG_DEBUG) {
+			if (!sd_opt_is_valid_number(&opt->arg, SDOG_EMERG,
+						    SDOG_DEBUG)) {
 				fprintf(stderr, "Invalid log level '%s'\n",
-					optarg);
+					opt->arg.str);
 				sdlog_help();
 				exit(1);
 			}
+			log_level = opt->arg.num;
 			break;
 		case 'y':
-			af = strstr(optarg, ":") ? AF_INET6 : AF_INET;
-			if (!str_to_addr(af, optarg, sys->this_node.nid.addr)) {
+			af = strstr(opt->arg.str, ":") ? AF_INET6 : AF_INET;
+			if (!str_to_addr(af, opt->arg.str, sys->this_node.nid.addr)) {
 				fprintf(stderr,
 					"Invalid address: '%s'\n",
-					optarg);
+					opt->arg.str);
 				sdlog_help();
 				exit(1);
 			}
@@ -377,33 +325,31 @@ int main(int argc, char **argv)
 			to_stdout = true;
 			break;
 		case 'z':
-			zone = strtol(optarg, &p, 10);
-			if (optarg == p || zone < 0 || UINT32_MAX < zone) {
+			if (!sd_opt_is_valid_number(&opt->arg, 0, UINT32_MAX)) {
 				fprintf(stderr, "Invalid zone id '%s': "
 					"must be an integer between 0 and %u\n",
-					optarg, UINT32_MAX);
+					opt->arg.str, UINT32_MAX);
 				exit(1);
 			}
+			zone = opt->arg.num;
 			sys->this_node.zone = zone;
 			break;
 		case 's':
-			free_space = strtoll(optarg, &p, 10);
-			if (optarg == p || free_space <= 0 ||
-			    UINT64_MAX < free_space) {
-				fprintf(stderr, "Invalid free space size '%s': "
-					"must be an integer between 0 and "
-					"%"PRIu64"\n", optarg, UINT64_MAX);
+			if (!sd_opt_is_size(&opt->arg)) {
+				fprintf(stderr, "Invalid free space size, %s\n",
+					opt->arg.str);
 				exit(1);
 			}
-			sys->disk_space = free_space * 1024 * 1024;
+			sys->disk_space = opt->arg.size;
 			break;
 		case 'u':
 			sys->upgrade = true;
 			break;
 		case 'c':
-			sys->cdrv = find_cdrv(optarg);
+			sys->cdrv = find_cdrv(opt->arg.str);
 			if (!sys->cdrv) {
-				fprintf(stderr, "Invalid cluster driver '%s'\n", optarg);
+				fprintf(stderr, "Invalid cluster driver '%s'\n",
+					opt->arg.str);
 				fprintf(stderr, "Supported drivers:");
 				FOR_EACH_CLUSTER_DRIVER(cdrv) {
 					fprintf(stderr, " %s", cdrv->name);
@@ -412,23 +358,24 @@ int main(int argc, char **argv)
 				exit(1);
 			}
 
-			sys->cdrv_option = get_cdrv_option(sys->cdrv, optarg);
+			sys->cdrv_option = opt->params;
 			break;
 		case 'w':
-			init_cache_type(optarg);
+			if (init_cache_type(opt) < 0)
+				exit(1);
 			break;
 		case 'j':
 			sys->use_journal = true;
 			break;
 		case 'b':
 			/* validate provided address using inet_pton */
-			ipv4 = inet_pton(AF_INET, optarg, buf);
-			ipv6 = inet_pton(AF_INET6, optarg, buf);
+			ipv4 = inet_pton(AF_INET, opt->arg.str, buf);
+			ipv6 = inet_pton(AF_INET6, opt->arg.str, buf);
 			if (ipv4 || ipv6) {
-				bindaddr = optarg;
+				bindaddr = opt->arg.str;
 			} else {
-				fprintf(stderr,
-					"Invalid bind address '%s'\n", optarg);
+				fprintf(stderr, "Invalid bind address '%s'\n",
+					opt->arg.str);
 				exit(1);
 			}
 			break;
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index 9bec91e..4bfcd3c 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -63,7 +63,7 @@ struct request {
 
 struct cluster_info {
 	struct cluster_driver *cdrv;
-	const char *cdrv_option;
+	struct sd_opt_param *cdrv_option;
 
 	/* set after finishing the JOIN procedure */
 	bool join_finished;
-- 
1.7.9.5




More information about the sheepdog mailing list