[PATCH v8 1/2] ipvsadm: convert options to unsigned long long

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



To allow up to 64 options to be specified.
Add calculated logarithm constants for existing options.
Remove opt2name function to avoid recalculation.

Signed-off-by: Jacky Hu <hengqing.hu@xxxxxxxxx>
---
 ipvsadm.c | 117 ++++++++++++++++++++++++++++++++----------------------
 1 file changed, 69 insertions(+), 48 deletions(-)

diff --git a/ipvsadm.c b/ipvsadm.c
index 0cb2b68..3cca20e 100644
--- a/ipvsadm.c
+++ b/ipvsadm.c
@@ -189,6 +189,35 @@ static const char* cmdnames[] = {
 #define OPT_SYNC_MAXLEN	0x08000000
 #define NUMBER_OF_OPT		28
 
+#define OPTC_NUMERIC		0
+#define OPTC_CONNECTION		1
+#define OPTC_SERVICE		2
+#define OPTC_SCHEDULER		3
+#define OPTC_PERSISTENT		4
+#define OPTC_NETMASK		5
+#define OPTC_SERVER		6
+#define OPTC_FORWARD		7
+#define OPTC_WEIGHT		8
+#define OPTC_UTHRESHOLD		9
+#define OPTC_LTHRESHOLD		10
+#define OPTC_MCAST		11
+#define OPTC_TIMEOUT		12
+#define OPTC_DAEMON		13
+#define OPTC_STATS		14
+#define OPTC_RATE		15
+#define OPTC_THRESHOLDS		16
+#define OPTC_PERSISTENTCONN	17
+#define OPTC_NOSORT		18
+#define OPTC_SYNCID		19
+#define OPTC_EXACT		20
+#define OPTC_ONEPACKET		21
+#define OPTC_PERSISTENCE_ENGINE	22
+#define OPTC_SCHED_FLAGS	23
+#define OPTC_MCAST_GROUP	24
+#define OPTC_MCAST_PORT		25
+#define OPTC_MCAST_TTL		26
+#define OPTC_SYNC_MAXLEN	27
+
 static const char* optnames[] = {
 	"numeric",
 	"connection",
@@ -320,9 +349,9 @@ static unsigned int parse_fwmark(char *buf);
 static unsigned int parse_sched_flags(const char *sched, char *optarg);
 
 /* check the options based on the commands_v_options table */
-static void generic_opt_check(int command, int options);
+static void generic_opt_check(int command, unsigned long long options);
 static void set_command(int *cmd, const int newcmd);
-static void set_option(unsigned int *options, unsigned int option);
+static void set_option(unsigned long long *options, int optc);
 
 static void tryhelp_exit(const char *program, const int exit_status);
 static void usage_exit(const char *program, const int exit_status);
@@ -416,7 +445,7 @@ static char *protocol_name(int proto)
 
 static int
 parse_options(int argc, char **argv, struct ipvs_command_entry *ce,
-	      unsigned int *options, unsigned int *format)
+	      unsigned long long *options, unsigned int *format)
 {
 	int c, parse;
 	poptContext context;
@@ -575,7 +604,7 @@ parse_options(int argc, char **argv, struct ipvs_command_entry *ce,
 		case 't':
 		case 'u':
 		case TAG_SCTP_SERVICE:
-			set_option(options, OPT_SERVICE);
+			set_option(options, OPTC_SERVICE);
 			ce->svc.protocol = option_to_protocol(c);
 			parse = parse_service(optarg, &ce->svc);
 			if (!(parse & SERVICE_ADDR))
@@ -583,7 +612,7 @@ parse_options(int argc, char **argv, struct ipvs_command_entry *ce,
 				     "address[:port] specified");
 			break;
 		case 'f':
-			set_option(options, OPT_SERVICE);
+			set_option(options, OPTC_SERVICE);
 			/*
 			 * Set protocol to a sane values, even
 			 * though it is not used
@@ -593,18 +622,18 @@ parse_options(int argc, char **argv, struct ipvs_command_entry *ce,
 			ce->svc.fwmark = parse_fwmark(optarg);
 			break;
 		case 's':
-			set_option(options, OPT_SCHEDULER);
+			set_option(options, OPTC_SCHEDULER);
 			strncpy(ce->svc.sched_name,
 				optarg, IP_VS_SCHEDNAME_MAXLEN - 1);
 			break;
 		case 'p':
-			set_option(options, OPT_PERSISTENT);
+			set_option(options, OPTC_PERSISTENT);
 			ce->svc.flags |= IP_VS_SVC_F_PERSISTENT;
 			ce->svc.timeout =
 				parse_timeout(optarg, 1, MAX_TIMEOUT);
 			break;
 		case 'M':
-			set_option(options, OPT_NETMASK);
+			set_option(options, OPTC_NETMASK);
 			if (ce->svc.af != AF_INET6) {
 				parse = parse_netmask(optarg, &ce->svc.netmask);
 				if (parse != 1)
@@ -617,7 +646,7 @@ parse_options(int argc, char **argv, struct ipvs_command_entry *ce,
 			}
 			break;
 		case 'r':
-			set_option(options, OPT_SERVER);
+			set_option(options, OPTC_SERVER);
 			ipvs_service_t t_dest = ce->svc;
 			parse = parse_service(optarg, &t_dest);
 			ce->dest.af = t_dest.af;
@@ -631,84 +660,84 @@ parse_options(int argc, char **argv, struct ipvs_command_entry *ce,
 				ce->dest.port = ce->svc.port;
 			break;
 		case 'i':
-			set_option(options, OPT_FORWARD);
+			set_option(options, OPTC_FORWARD);
 			ce->dest.conn_flags = IP_VS_CONN_F_TUNNEL;
 			break;
 		case 'g':
-			set_option(options, OPT_FORWARD);
+			set_option(options, OPTC_FORWARD);
 			ce->dest.conn_flags = IP_VS_CONN_F_DROUTE;
 			break;
 		case 'm':
-			set_option(options, OPT_FORWARD);
+			set_option(options, OPTC_FORWARD);
 			ce->dest.conn_flags = IP_VS_CONN_F_MASQ;
 			break;
 		case 'w':
-			set_option(options, OPT_WEIGHT);
+			set_option(options, OPTC_WEIGHT);
 			if ((ce->dest.weight =
 			     string_to_number(optarg, 0, 65535)) == -1)
 				fail(2, "illegal weight specified");
 			break;
 		case 'x':
-			set_option(options, OPT_UTHRESHOLD);
+			set_option(options, OPTC_UTHRESHOLD);
 			if ((ce->dest.u_threshold =
 			     string_to_number(optarg, 0, INT_MAX)) == -1)
 				fail(2, "illegal u_threshold specified");
 			break;
 		case 'y':
-			set_option(options, OPT_LTHRESHOLD);
+			set_option(options, OPTC_LTHRESHOLD);
 			if ((ce->dest.l_threshold =
 			     string_to_number(optarg, 0, INT_MAX)) == -1)
 				fail(2, "illegal l_threshold specified");
 			break;
 		case 'c':
-			set_option(options, OPT_CONNECTION);
+			set_option(options, OPTC_CONNECTION);
 			break;
 		case 'n':
-			set_option(options, OPT_NUMERIC);
+			set_option(options, OPTC_NUMERIC);
 			*format |= FMT_NUMERIC;
 			break;
 		case TAG_MCAST_INTERFACE:
-			set_option(options, OPT_MCAST);
+			set_option(options, OPTC_MCAST);
 			strncpy(ce->daemon.mcast_ifn,
 				optarg, IP_VS_IFNAME_MAXLEN - 1);
 			break;
 		case 'I':
-			set_option(options, OPT_SYNCID);
+			set_option(options, OPTC_SYNCID);
 			if ((ce->daemon.syncid =
 			     string_to_number(optarg, 0, 255)) == -1)
 				fail(2, "illegal syncid specified");
 			break;
 		case TAG_TIMEOUT:
-			set_option(options, OPT_TIMEOUT);
+			set_option(options, OPTC_TIMEOUT);
 			break;
 		case TAG_DAEMON:
-			set_option(options, OPT_DAEMON);
+			set_option(options, OPTC_DAEMON);
 			break;
 		case TAG_STATS:
-			set_option(options, OPT_STATS);
+			set_option(options, OPTC_STATS);
 			*format |= FMT_STATS;
 			break;
 		case TAG_RATE:
-			set_option(options, OPT_RATE);
+			set_option(options, OPTC_RATE);
 			*format |= FMT_RATE;
 			break;
 		case TAG_THRESHOLDS:
-			set_option(options, OPT_THRESHOLDS);
+			set_option(options, OPTC_THRESHOLDS);
 			*format |= FMT_THRESHOLDS;
 			break;
 		case TAG_PERSISTENTCONN:
-			set_option(options, OPT_PERSISTENTCONN);
+			set_option(options, OPTC_PERSISTENTCONN);
 			*format |= FMT_PERSISTENTCONN;
 			break;
 		case TAG_NO_SORT:
-			set_option(options, OPT_NOSORT	);
+			set_option(options, OPTC_NOSORT);
 			*format |= FMT_NOSORT;
 			break;
 		case TAG_SORT:
 			/* Sort is the default, this is a no-op for compatibility */
 			break;
 		case 'X':
-			set_option(options, OPT_EXACT);
+			set_option(options, OPTC_EXACT);
 			*format |= FMT_EXACT;
 			break;
 		case '6':
@@ -720,20 +749,20 @@ parse_options(int argc, char **argv, struct ipvs_command_entry *ce,
 			}
 			break;
 		case 'o':
-			set_option(options, OPT_ONEPACKET);
+			set_option(options, OPTC_ONEPACKET);
 			ce->svc.flags |= IP_VS_SVC_F_ONEPACKET;
 			break;
 		case TAG_PERSISTENCE_ENGINE:
-			set_option(options, OPT_PERSISTENCE_ENGINE);
+			set_option(options, OPTC_PERSISTENCE_ENGINE);
 			strncpy(ce->svc.pe_name, optarg, IP_VS_PENAME_MAXLEN);
 			break;
 		case 'b':
-			set_option(options, OPT_SCHED_FLAGS);
+			set_option(options, OPTC_SCHED_FLAGS);
 			snprintf(sched_flags_arg, sizeof(sched_flags_arg),
 				"%s", optarg);
 			break;
 		case TAG_MCAST_GROUP:
-			set_option(options, OPT_MCAST_GROUP);
+			set_option(options, OPTC_MCAST_GROUP);
 			if (strchr(optarg, ':')) {
 				if (inet_pton(AF_INET6, optarg,
 					      &ce->daemon.mcast_group) <= 0 ||
@@ -753,21 +782,21 @@ parse_options(int argc, char **argv, struct ipvs_command_entry *ce,
 			}
 			break;
 		case TAG_MCAST_PORT:
-			set_option(options, OPT_MCAST_PORT);
+			set_option(options, OPTC_MCAST_PORT);
 			parse = string_to_number(optarg, 1, 65535);
 			if (parse == -1)
 				fail(2, "illegal mcast-port specified");
 			ce->daemon.mcast_port = parse;
 			break;
 		case TAG_MCAST_TTL:
-			set_option(options, OPT_MCAST_TTL);
+			set_option(options, OPTC_MCAST_TTL);
 			parse = string_to_number(optarg, 1, 255);
 			if (parse == -1)
 				fail(2, "illegal mcast-ttl specified");
 			ce->daemon.mcast_ttl = parse;
 			break;
 		case TAG_SYNC_MAXLEN:
-			set_option(options, OPT_SYNC_MAXLEN);
+			set_option(options, OPTC_SYNC_MAXLEN);
 			parse = string_to_number(optarg, 1, 65535 - 20 - 8);
 			if (parse == -1)
 				fail(2, "illegal sync-maxlen specified");
@@ -845,7 +874,7 @@ static int restore_table(int argc, char **argv, int reading_stdin)
 static int process_options(int argc, char **argv, int reading_stdin)
 {
 	struct ipvs_command_entry ce;
-	unsigned int options = OPT_NONE;
+	unsigned long long options = OPT_NONE;
 	unsigned int format = FMT_NONE;
 	int result = 0;
 
@@ -1164,7 +1193,7 @@ static unsigned int parse_sched_flags(const char *sched, char *optarg)
 }
 
 static void
-generic_opt_check(int command, int options)
+generic_opt_check(int command, unsigned long long options)
 {
 	int i, j;
 	int last = 0, count = 0;
@@ -1173,7 +1202,7 @@ generic_opt_check(int command, int options)
 	i = command - CMD_NONE -1;
 
 	for (j = 0; j < NUMBER_OF_OPT; j++) {
-		if (!(options & (1<<j))) {
+		if (!(options & (1ULL << j))) {
 			if (commands_v_options[i][j] == '+')
 				fail(2, "You need to supply the '%s' "
 				     "option for the '%s' command",
@@ -1197,15 +1226,6 @@ generic_opt_check(int command, int options)
 	}
 }
 
-static inline const char *
-opt2name(int option)
-{
-	const char **ptr;
-	for (ptr = optnames; option > 1; option >>= 1, ptr++);
-
-	return *ptr;
-}
-
 static void
 set_command(int *cmd, const int newcmd)
 {
@@ -1215,10 +1235,11 @@ set_command(int *cmd, const int newcmd)
 }
 
 static void
-set_option(unsigned int *options, unsigned int option)
+set_option(unsigned long long *options, int optc)
 {
+	unsigned long long option = 1ULL << optc;
 	if (*options & option)
-		fail(2, "multiple '%s' options specified", opt2name(option));
+		fail(2, "multiple '%s' options specified", optnames[optc]);
 	*options |= option;
 }
 
-- 
2.21.0




[Index of Archives]     [Linux Filesystem Devel]     [Linux NFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]     [X.Org]

  Powered by Linux