Hi,
The attached patch contains a diff for the addition of a '-x' or
'--exact' command-line switch to ipvsadm (version 1.19.2.2).
The idea behind the new option is to allow users to specify that large
numbers printed with the '--stats' or '--rate' options are in bytes,
rather than converted into 'human-readable' form (e.g. kilobytes,
megabytes etc.).
Regards,
Guy.
--- ipvsadm.c.original Sat Apr 12 00:02:38 2003
+++ ipvsadm.c Fri May 20 08:53:49 2005
@@ -168,7 +168,8 @@ static const char* cmdnames[] = {
#define OPT_STATS 0x01000
#define OPT_RATE 0x02000
#define OPT_SORT 0x04000
-#define NUMBER_OF_OPT 15
+#define OPT_EXACT 0x08000
+#define NUMBER_OF_OPT 16
static const char* optnames[] = {
"numeric",
@@ -186,6 +187,7 @@ static const char* optnames[] = {
"stats",
"rate",
"sort",
+ "exact",
};
/*
@@ -198,22 +200,22 @@ static const char* optnames[] = {
*/
static const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
{
- /* -n -c svc -s -p -M -r fwd -w -mc -to dmn -st
-rt srt */
-/*INSERT*/ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x',
'x', 'x', 'x'},
-/*ADD*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x'},
-/*EDIT*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x'},
-/*DEL*/ {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x'},
-/*FLUSH*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x'},
-/*LIST*/ {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', '
', ' ', ' '},
-/*ADD-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x',
'x', 'x', 'x'},
-/*DEL-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x'},
-/*EDIT-SRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x',
'x', 'x', 'x'},
-/*TIMEOUT*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x'},
-/*START-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x',
'x', 'x', 'x'},
-/*STOP-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x'},
-/*RESTORE*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x'},
-/*SAVE*/ {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x'},
-/*ZERO*/ {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x'},
+ /* -n -c svc -s -p -M -r fwd -w -mc -to dmn -st
-rt srt -x */
+/*INSERT*/ {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 'x', 'x',
'x', 'x', 'x', 'x'},
+/*ADD*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
+/*EDIT*/ {'x', 'x', '+', ' ', ' ', ' ', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
+/*DEL*/ {'x', 'x', '+', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
+/*FLUSH*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
+/*LIST*/ {' ', '1', '1', 'x', 'x', 'x', 'x', 'x', 'x', 'x', '1', '1', '
', ' ', ' ', ' '},
+/*ADD-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
+/*DEL-SERVER*/{'x', 'x', '+', 'x', 'x', 'x', '+', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
+/*EDIT-SRV*/ {'x', 'x', '+', 'x', 'x', 'x', '+', ' ', ' ', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
+/*TIMEOUT*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
+/*START-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', ' ', 'x', 'x',
'x', 'x', 'x', 'x'},
+/*STOP-D*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
+/*RESTORE*/ {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
+/*SAVE*/ {' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
+/*ZERO*/ {'x', 'x', ' ', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x',
'x', 'x', 'x', 'x'},
};
/* printing format flags */
@@ -266,8 +268,8 @@ static void fail(int err, char *msg, ...
/* various listing functions */
static void list_conn(unsigned int format);
-static void list_service(struct ip_vs_rule_user *ur, unsigned int format);
-static void list_all(unsigned int format);
+static void list_service(struct ip_vs_rule_user *ur, unsigned int format,
unsigned int options);
+static void list_all(unsigned int format, unsigned int options);
static void list_timeout(void);
static void list_daemon(void);
@@ -294,7 +296,7 @@ int main(int argc, char **argv)
/* list the table if there is no other arguement */
if (argc == 1){
- list_all(FMT_NONE);
+ list_all(FMT_NONE, OPT_NONE);
ipvs_close();
return 0;
}
@@ -355,6 +357,7 @@ parse_options(int argc, char **argv, str
{"stats", '\0', POPT_ARG_NONE, NULL, '7'},
{"rate", '\0', POPT_ARG_NONE, NULL, '8'},
{"sort", '\0', POPT_ARG_NONE, NULL, '9'},
+ {"exact", 'x', POPT_ARG_NONE, NULL, 'x'},
{NULL, 0, 0, NULL, 0}
};
@@ -522,6 +525,9 @@ parse_options(int argc, char **argv, str
set_option(options, OPT_SORT);
*format |= FMT_SORT;
break;
+ case 'x':
+ set_option(options, OPT_EXACT);
+ break;
default:
fail(2, "invalid option");
}
@@ -567,7 +573,7 @@ parse_options(int argc, char **argv, str
int *cmd, unsigned int *options, unsigned int *format)
{
int c, parse;
- const char *optstring = "AEDCZSRaedlLhvt:u:f:s:M:p::w:r:gmicn";
+ const char *optstring = "AEDCZSRaedlLhvt:u:f:s:M:p::w:r:gmicnx";
const struct option long_options[] = {
{"add-service", 0, 0, 'A'},
{"edit-service", 0, 0, 'E'},
@@ -605,6 +611,7 @@ parse_options(int argc, char **argv, str
{"rate", 0, 0, '8'},
{"sort", 0, 0, '9'},
{"help", 0, 0, 'h'},
+ {"exact", 0, 0, 'x'},
{0, 0, 0, 0}
};
@@ -794,6 +801,9 @@ parse_options(int argc, char **argv, str
set_option(options, OPT_SORT);
*format |= FMT_SORT;
break;
+ case 'x':
+ set_option(options, OPT_EXACT);
+ break;
default:
fail(2, "invalid option");
}
@@ -859,19 +869,19 @@ static int process_options(int argc, cha
if (options & OPT_CONNECTION)
list_conn(format);
else if (options & OPT_SERVICE)
- list_service(&urule, format);
+ list_service(&urule, format, options);
else if (options & OPT_TIMEOUT)
list_timeout();
else if (options & OPT_DAEMON)
list_daemon();
else
- list_all(format);
+ list_all(format, options);
return 0;
case IP_VS_SO_SET_RESTORE:
return restore_table(argc, argv, reading_stdin);
case IP_VS_SO_SET_SAVE:
format |= FMT_RULE;
- list_all(format);
+ list_all(format, options);
return 0;
}
@@ -1172,6 +1182,8 @@ static void usage_exit(const char *progr
" --daemon output of daemon
information\n"
" --stats output of statistics
information\n"
" --rate output of rate
information\n"
+ " --exact -x show raw numbers rather
than human-readable numbers.\n"
+ " used for --stats and
--rate options only\n"
" --sort sorting output of
service/server entries\n"
" --numeric -n numeric output of
addresses and ports\n",
DEF_SCHED);
@@ -1399,6 +1411,16 @@ static void print_largenum(unsigned long
}
+static void print_exactnum(unsigned long long i)
+{
+ char mytmp[128];
+ int mylen;
+ sprintf(mytmp, "%llu", i);
+ mylen = strlen(mytmp);
+ printf("%*llu", mylen<=8?9:mylen+1, i);
+}
+
+
static void print_title(unsigned int format)
{
if (format & FMT_STATS)
@@ -1418,7 +1440,7 @@ static void print_title(unsigned int for
static void
-print_service(struct ip_vs_service_user *svc, unsigned int format)
+print_service(struct ip_vs_service_user *svc, unsigned int format, unsigned
int options)
{
struct ip_vs_get_dests *d;
char svc_name[64];
@@ -1470,18 +1492,34 @@ print_service(struct ip_vs_service_user
}
} else if (format & FMT_STATS) {
printf("%-33s", svc_name);
- print_largenum(svc->stats.conns);
- print_largenum(svc->stats.inpkts);
- print_largenum(svc->stats.outpkts);
- print_largenum(svc->stats.inbytes);
- print_largenum(svc->stats.outbytes);
+ if (options & OPT_EXACT) {
+ print_exactnum(svc->stats.conns);
+ print_exactnum(svc->stats.inpkts);
+ print_exactnum(svc->stats.outpkts);
+ print_exactnum(svc->stats.inbytes);
+ print_exactnum(svc->stats.outbytes);
+ } else {
+ print_largenum(svc->stats.conns);
+ print_largenum(svc->stats.inpkts);
+ print_largenum(svc->stats.outpkts);
+ print_largenum(svc->stats.inbytes);
+ print_largenum(svc->stats.outbytes);
+ }
} else if (format & FMT_RATE) {
printf("%-33s", svc_name);
- print_largenum(svc->stats.cps);
- print_largenum(svc->stats.inpps);
- print_largenum(svc->stats.outpps);
- print_largenum(svc->stats.inbps);
- print_largenum(svc->stats.outbps);
+ if (options & OPT_EXACT) {
+ print_exactnum(svc->stats.cps);
+ print_exactnum(svc->stats.inpps);
+ print_exactnum(svc->stats.outpps);
+ print_exactnum(svc->stats.inbps);
+ print_exactnum(svc->stats.outbps);
+ } else {
+ print_largenum(svc->stats.cps);
+ print_largenum(svc->stats.inpps);
+ print_largenum(svc->stats.outpps);
+ print_largenum(svc->stats.inbps);
+ print_largenum(svc->stats.outbps);
+ }
} else {
printf("%s %s", svc_name, svc->sched_name);
if (svc->flags & IP_VS_SVC_F_PERSISTENT) {
@@ -1513,19 +1551,32 @@ print_service(struct ip_vs_service_user
fwd_switch(e->flags), e->weight);
} else if (format & FMT_STATS) {
printf(" -> %-28s", dname);
- print_largenum(e->stats.conns);
- print_largenum(e->stats.inpkts);
- print_largenum(e->stats.outpkts);
- print_largenum(e->stats.inbytes);
- print_largenum(e->stats.outbytes);
+ if (options & OPT_EXACT) {
+ print_exactnum(e->stats.conns);
+ print_exactnum(e->stats.inpkts);
+ print_exactnum(e->stats.outpkts);
+ print_exactnum(e->stats.inbytes);
+ print_exactnum(e->stats.outbytes);
+ } else {
+ print_largenum(e->stats.conns);
+ print_largenum(e->stats.inpkts);
+ print_largenum(e->stats.outpkts);
+ print_largenum(e->stats.inbytes);
+ print_largenum(e->stats.outbytes);
+ }
printf("\n");
} else if (format & FMT_RATE) {
printf(" -> %-28s %8u %8u %8u", dname,
e->stats.cps,
e->stats.inpps,
e->stats.outpps);
- print_largenum(e->stats.inbps);
- print_largenum(e->stats.outbps);
+ if (options & OPT_EXACT) {
+ print_exactnum(e->stats.inbps);
+ print_exactnum(e->stats.outbps);
+ } else {
+ print_largenum(e->stats.inbps);
+ print_largenum(e->stats.outbps);
+ }
printf("\n");
} else
printf(" -> %-28s %-7s %-6d %-10u %-10u\n",
@@ -1537,7 +1588,7 @@ print_service(struct ip_vs_service_user
}
-static void list_service(struct ip_vs_rule_user *ur, unsigned int format)
+static void list_service(struct ip_vs_rule_user *ur, unsigned int format,
unsigned int options)
{
struct ip_vs_service_user *svc;
@@ -1548,12 +1599,12 @@ static void list_service(struct ip_vs_ru
}
print_title(format);
- print_service(svc, format);
+ print_service(svc, format, options);
free(svc);
}
-static void list_all(unsigned int format)
+static void list_all(unsigned int format, unsigned int options)
{
struct ip_vs_get_services *get;
int i;
@@ -1573,7 +1624,7 @@ static void list_all(unsigned int format
print_title(format);
for (i=0; i<get->num_services; i++)
- print_service(&get->entrytable[i], format);
+ print_service(&get->entrytable[i], format, options);
free(get);
}
|