* [PATCH RFC] ipvsadm: support 64-bit stats and rates
@ 2015-01-27 8:47 Julian Anastasov
0 siblings, 0 replies; only message in thread
From: Julian Anastasov @ 2015-01-27 8:47 UTC (permalink / raw)
To: lvs-devel; +Cc: Chris Caputo
Prefer the new netlink attributes IPVS_SVC_ATTR_STATS64 and
IPVS_DEST_ATTR_STATS64 for 64-bit conn/packet/bps/cps/pps stats.
Signed-off-by: Julian Anastasov <ja@ssi.bg>
---
ipvsadm.c | 42 ++++++++++++++---------------
libipvs/ip_vs.h | 28 ++++++++++++++++++-
libipvs/libipvs.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 121 insertions(+), 29 deletions(-)
diff --git a/ipvsadm.c b/ipvsadm.c
index 162d4a2..a33ecfa 100644
--- a/ipvsadm.c
+++ b/ipvsadm.c
@@ -1585,18 +1585,18 @@ print_service_entry(ipvs_service_entry_t *se, unsigned int format)
}
} else if (format & FMT_STATS) {
printf("%-33s", svc_name);
- print_largenum(se->stats.conns, format);
- print_largenum(se->stats.inpkts, format);
- print_largenum(se->stats.outpkts, format);
- print_largenum(se->stats.inbytes, format);
- print_largenum(se->stats.outbytes, format);
+ print_largenum(se->stats64.conns, format);
+ print_largenum(se->stats64.inpkts, format);
+ print_largenum(se->stats64.outpkts, format);
+ print_largenum(se->stats64.inbytes, format);
+ print_largenum(se->stats64.outbytes, format);
} else if (format & FMT_RATE) {
printf("%-33s", svc_name);
- print_largenum(se->stats.cps, format);
- print_largenum(se->stats.inpps, format);
- print_largenum(se->stats.outpps, format);
- print_largenum(se->stats.inbps, format);
- print_largenum(se->stats.outbps, format);
+ print_largenum(se->stats64.cps, format);
+ print_largenum(se->stats64.inpps, format);
+ print_largenum(se->stats64.outpps, format);
+ print_largenum(se->stats64.inbps, format);
+ print_largenum(se->stats64.outbps, format);
} else {
printf("%s %s", svc_name, se->sched_name);
if (se->flags & (IP_VS_SVC_F_SCHED1 |
@@ -1646,19 +1646,19 @@ print_service_entry(ipvs_service_entry_t *se, unsigned int format)
fwd_switch(e->conn_flags), e->weight);
} else if (format & FMT_STATS) {
printf(" -> %-28s", dname);
- print_largenum(e->stats.conns, format);
- print_largenum(e->stats.inpkts, format);
- print_largenum(e->stats.outpkts, format);
- print_largenum(e->stats.inbytes, format);
- print_largenum(e->stats.outbytes, format);
+ print_largenum(e->stats64.conns, format);
+ print_largenum(e->stats64.inpkts, format);
+ print_largenum(e->stats64.outpkts, format);
+ print_largenum(e->stats64.inbytes, format);
+ print_largenum(e->stats64.outbytes, format);
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, format);
- print_largenum(e->stats.outbps, format);
+ printf(" -> %-28s %8llu %8llu %8llu", dname,
+ e->stats64.cps,
+ e->stats64.inpps,
+ e->stats64.outpps);
+ print_largenum(e->stats64.inbps, format);
+ print_largenum(e->stats64.outbps, format);
printf("\n");
} else if (format & FMT_THRESHOLDS) {
printf(" -> %-28s %-10u %-10u %-10u %-10u\n", dname,
diff --git a/libipvs/ip_vs.h b/libipvs/ip_vs.h
index 5a42a0c..1bb2f74 100644
--- a/libipvs/ip_vs.h
+++ b/libipvs/ip_vs.h
@@ -195,6 +195,22 @@ struct ip_vs_stats_user
__u32 outbps; /* current out byte rate */
};
+/*
+ * IPVS statistics object (for user space), 64-bit
+ */
+struct ip_vs_stats64 {
+ __u64 conns; /* connections scheduled */
+ __u64 inpkts; /* incoming packets */
+ __u64 outpkts; /* outgoing packets */
+ __u64 inbytes; /* incoming bytes */
+ __u64 outbytes; /* outgoing bytes */
+
+ __u64 cps; /* current connection rate */
+ __u64 inpps; /* current in packet rate */
+ __u64 outpps; /* current out packet rate */
+ __u64 inbps; /* current in byte rate */
+ __u64 outbps; /* current out byte rate */
+};
/* The argument to IP_VS_SO_GET_INFO */
struct ip_vs_getinfo {
@@ -253,6 +269,8 @@ struct ip_vs_service_entry {
union nf_inet_addr addr;
char pe_name[IP_VS_PENAME_MAXLEN];
+ /* statistics, 64-bit */
+ struct ip_vs_stats64 stats64;
};
struct ip_vs_dest_entry_kern {
@@ -289,6 +307,9 @@ struct ip_vs_dest_entry {
struct ip_vs_stats_user stats;
u_int16_t af;
union nf_inet_addr addr;
+
+ /* statistics, 64-bit */
+ struct ip_vs_stats64 stats64;
};
/* The argument to IP_VS_SO_GET_DESTS */
@@ -444,6 +465,8 @@ enum {
IPVS_SVC_ATTR_PE_NAME, /* name of scheduler */
+ IPVS_SVC_ATTR_STATS64, /* nested attribute for service stats */
+
__IPVS_SVC_ATTR_MAX,
};
@@ -473,6 +496,8 @@ enum {
IPVS_DEST_ATTR_ADDR_FAMILY, /* Address family of address */
+ IPVS_DEST_ATTR_STATS64, /* nested attribute for dest stats */
+
__IPVS_DEST_ATTR_MAX,
};
@@ -496,7 +521,8 @@ enum {
/*
* Attributes used to describe service or destination entry statistics
*
- * Used inside nested attributes IPVS_SVC_ATTR_STATS and IPVS_DEST_ATTR_STATS
+ * Used inside nested attributes IPVS_SVC_ATTR_STATS, IPVS_DEST_ATTR_STATS,
+ * IPVS_SVC_ATTR_STATS64 and IPVS_DEST_ATTR_STATS64.
*/
enum {
IPVS_STATS_ATTR_UNSPEC = 0,
diff --git a/libipvs/libipvs.c b/libipvs/libipvs.c
index 0bfb428..05dd7f6 100644
--- a/libipvs/libipvs.c
+++ b/libipvs/libipvs.c
@@ -150,6 +150,21 @@ int ipvs_init(void)
return 0;
}
+static void copy_stats_from_kern(struct ip_vs_stats64 *d,
+ struct ip_vs_stats_user *s)
+{
+ d->conns = s->conns;
+ d->inpkts = s->inpkts;
+ d->outpkts = s->outpkts;
+ d->inbytes = s->inbytes;
+ d->outbytes = s->outbytes;
+ d->cps = s->cps;
+ d->inpps = s->inpps;
+ d->outpps = s->outpps;
+ d->inbps = s->inbps;
+ d->outbps = s->outbps;
+}
+
#ifdef LIBIPVS_USE_NL
static int ipvs_getinfo_parse_cb(struct nl_msg *msg, void *arg)
{
@@ -545,7 +560,7 @@ nla_put_failure:
}
#ifdef LIBIPVS_USE_NL
-static int ipvs_parse_stats(struct ip_vs_stats_user *stats, struct nlattr *nla)
+static int ipvs_parse_stats(struct ip_vs_stats64 *stats, struct nlattr *nla)
{
struct nlattr *attrs[IPVS_STATS_ATTR_MAX + 1];
@@ -579,6 +594,40 @@ static int ipvs_parse_stats(struct ip_vs_stats_user *stats, struct nlattr *nla)
}
+static int ipvs_parse_stats64(struct ip_vs_stats64 *stats, struct nlattr *nla)
+{
+ struct nlattr *attrs[IPVS_STATS_ATTR_MAX + 1];
+
+ if (nla_parse_nested(attrs, IPVS_STATS_ATTR_MAX, nla,
+ ipvs_stats_policy))
+ return -1;
+
+ if (!(attrs[IPVS_STATS_ATTR_CONNS] &&
+ attrs[IPVS_STATS_ATTR_INPKTS] &&
+ attrs[IPVS_STATS_ATTR_OUTPKTS] &&
+ attrs[IPVS_STATS_ATTR_INBYTES] &&
+ attrs[IPVS_STATS_ATTR_OUTBYTES] &&
+ attrs[IPVS_STATS_ATTR_CPS] &&
+ attrs[IPVS_STATS_ATTR_INPPS] &&
+ attrs[IPVS_STATS_ATTR_OUTPPS] &&
+ attrs[IPVS_STATS_ATTR_INBPS] &&
+ attrs[IPVS_STATS_ATTR_OUTBPS]))
+ return -1;
+
+ stats->conns = nla_get_u64(attrs[IPVS_STATS_ATTR_CONNS]);
+ stats->inpkts = nla_get_u64(attrs[IPVS_STATS_ATTR_INPKTS]);
+ stats->outpkts = nla_get_u64(attrs[IPVS_STATS_ATTR_OUTPKTS]);
+ stats->inbytes = nla_get_u64(attrs[IPVS_STATS_ATTR_INBYTES]);
+ stats->outbytes = nla_get_u64(attrs[IPVS_STATS_ATTR_OUTBYTES]);
+ stats->cps = nla_get_u64(attrs[IPVS_STATS_ATTR_CPS]);
+ stats->inpps = nla_get_u64(attrs[IPVS_STATS_ATTR_INPPS]);
+ stats->outpps = nla_get_u64(attrs[IPVS_STATS_ATTR_OUTPPS]);
+ stats->inbps = nla_get_u64(attrs[IPVS_STATS_ATTR_INBPS]);
+ stats->outbps = nla_get_u64(attrs[IPVS_STATS_ATTR_OUTBPS]);
+
+ return 0;
+}
+
static int ipvs_services_parse_cb(struct nl_msg *msg, void *arg)
{
struct nlmsghdr *nlh = nlmsg_hdr(msg);
@@ -636,9 +685,15 @@ static int ipvs_services_parse_cb(struct nl_msg *msg, void *arg)
nla_memcpy(&flags, svc_attrs[IPVS_SVC_ATTR_FLAGS], sizeof(flags));
get->entrytable[i].flags = flags.flags & flags.mask;
- if (ipvs_parse_stats(&(get->entrytable[i].stats),
- svc_attrs[IPVS_SVC_ATTR_STATS]) != 0)
- return -1;
+ if (svc_attrs[IPVS_SVC_ATTR_STATS64]) {
+ if (ipvs_parse_stats64(&get->entrytable[i].stats64,
+ svc_attrs[IPVS_SVC_ATTR_STATS64]) != 0)
+ return -1;
+ } else if (svc_attrs[IPVS_SVC_ATTR_STATS]) {
+ if (ipvs_parse_stats(&get->entrytable[i].stats64,
+ svc_attrs[IPVS_SVC_ATTR_STATS]) != 0)
+ return -1;
+ }
get->entrytable[i].num_dests = 0;
@@ -702,6 +757,8 @@ struct ip_vs_get_services *ipvs_get_services(void)
sizeof(struct ip_vs_service_entry_kern));
get->entrytable[i].af = AF_INET;
get->entrytable[i].addr.ip = get->entrytable[i].__addr_v4;
+ copy_stats_from_kern(&get->entrytable[i].stats64,
+ &get->entrytable[i].stats);
}
free(getk);
return get;
@@ -796,9 +853,15 @@ static int ipvs_dests_parse_cb(struct nl_msg *msg, void *arg)
else
d->entrytable[i].af = d->af;
- if (ipvs_parse_stats(&(d->entrytable[i].stats),
- dest_attrs[IPVS_DEST_ATTR_STATS]) != 0)
- return -1;
+ if (dest_attrs[IPVS_DEST_ATTR_STATS64]) {
+ if (ipvs_parse_stats(&d->entrytable[i].stats64,
+ dest_attrs[IPVS_DEST_ATTR_STATS64]) != 0)
+ return -1;
+ } else if (dest_attrs[IPVS_DEST_ATTR_STATS]) {
+ if (ipvs_parse_stats(&d->entrytable[i].stats64,
+ dest_attrs[IPVS_DEST_ATTR_STATS]) != 0)
+ return -1;
+ }
i++;
@@ -900,6 +963,8 @@ ipvs_nl_dest_failure:
sizeof(struct ip_vs_dest_entry_kern));
d->entrytable[i].af = AF_INET;
d->entrytable[i].addr.ip = d->entrytable[i].__addr_v4;
+ copy_stats_from_kern(&d->entrytable[i].stats64,
+ &d->entrytable[i].stats);
}
free(dk);
return d;
@@ -1001,6 +1066,7 @@ ipvs_get_service_err2:
svc->af = AF_INET;
svc->addr.ip = svc->__addr_v4;
svc->pe_name[0] = '\0';
+ copy_stats_from_kern(&svc->stats64, &svc->stats);
return svc;
out_err:
free(svc);
--
1.9.3
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2015-01-27 8:47 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-27 8:47 [PATCH RFC] ipvsadm: support 64-bit stats and rates Julian Anastasov
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.