/proc/net parsing optimizations
This commit is contained in:
parent
f26a733bfa
commit
b313b3ec27
|
@ -1545,13 +1545,13 @@ int sigar_cpu_info_list_get(sigar_t *sigar,
|
||||||
return SIGAR_OK;
|
return SIGAR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int hex2int(const char *x)
|
static SIGAR_INLINE unsigned int hex2int(const char *x, int len)
|
||||||
{
|
{
|
||||||
int i, ch;
|
int i;
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
|
|
||||||
for (i=0, j=0; i<8; i++) {
|
for (i=0, j=0; i<len; i++) {
|
||||||
ch = x[i];
|
register int ch = x[i];
|
||||||
j <<= 4;
|
j <<= 4;
|
||||||
if (isdigit(ch)) {
|
if (isdigit(ch)) {
|
||||||
j |= ch - '0';
|
j |= ch - '0';
|
||||||
|
@ -1567,6 +1567,8 @@ static unsigned int hex2int(const char *x)
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define HEX_ENT_LEN 8
|
||||||
|
|
||||||
#ifdef __LP64__
|
#ifdef __LP64__
|
||||||
#define ROUTE_FMT "%16s %128s %128s %X %ld %ld %ld %128s %ld %ld %ld\n"
|
#define ROUTE_FMT "%16s %128s %128s %X %ld %ld %ld %128s %ld %ld %ld\n"
|
||||||
#else
|
#else
|
||||||
|
@ -1611,9 +1613,9 @@ int sigar_net_route_list_get(sigar_t *sigar,
|
||||||
}
|
}
|
||||||
|
|
||||||
route->flags = flags;
|
route->flags = flags;
|
||||||
route->destination = hex2int(net_addr);
|
route->destination = hex2int(net_addr, HEX_ENT_LEN);
|
||||||
route->gateway = hex2int(gate_addr);
|
route->gateway = hex2int(gate_addr, HEX_ENT_LEN);
|
||||||
route->mask = hex2int(mask_addr);
|
route->mask = hex2int(mask_addr, HEX_ENT_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
@ -1683,25 +1685,13 @@ int sigar_net_interface_stat_get(sigar_t *sigar, const char *name,
|
||||||
return found ? SIGAR_OK : ENXIO;
|
return found ? SIGAR_OK : ENXIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define IS_NULL_PTR(ptr) ((ptr == NULL) || (*(ptr) == '\0'))
|
static SIGAR_INLINE int ip_format(char *buffer, int buflen, char *ptr, int len)
|
||||||
#define HEX_ENT_LEN 8
|
|
||||||
|
|
||||||
static SIGAR_INLINE int ip_format(char *buffer, int buflen, char *ptr)
|
|
||||||
{
|
{
|
||||||
int alen;
|
if (len > HEX_ENT_LEN) {
|
||||||
|
|
||||||
if (IS_NULL_PTR(ptr)) {
|
|
||||||
alen = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
alen = strlen(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (alen > HEX_ENT_LEN) {
|
|
||||||
struct in6_addr addr;
|
struct in6_addr addr;
|
||||||
int i;
|
int i;
|
||||||
for (i=0; i<=3; i++, ptr+=8) {
|
for (i=0; i<=3; i++, ptr+=HEX_ENT_LEN) {
|
||||||
addr.s6_addr32[i] = hex2int(ptr);
|
addr.s6_addr32[i] = hex2int(ptr, HEX_ENT_LEN);
|
||||||
}
|
}
|
||||||
if (!inet_ntop(AF_INET6, &addr, buffer, buflen)) {
|
if (!inet_ntop(AF_INET6, &addr, buffer, buflen)) {
|
||||||
return errno;
|
return errno;
|
||||||
|
@ -1709,7 +1699,7 @@ static SIGAR_INLINE int ip_format(char *buffer, int buflen, char *ptr)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
addr.s_addr = (alen == HEX_ENT_LEN) ? hex2int(ptr) : 0;
|
addr.s_addr = (len == HEX_ENT_LEN) ? hex2int(ptr, HEX_ENT_LEN) : 0;
|
||||||
if (!inet_ntop(AF_INET, &addr, buffer, buflen)) {
|
if (!inet_ntop(AF_INET, &addr, buffer, buflen)) {
|
||||||
return errno;
|
return errno;
|
||||||
}
|
}
|
||||||
|
@ -1747,12 +1737,18 @@ static int proc_net_walker(sigar_net_connection_walker_t *walker,
|
||||||
return SIGAR_OK; /* continue loop */
|
return SIGAR_OK; /* continue loop */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SKIP_WHILE(p, c) while (*p == c) p++
|
||||||
|
#define SKIP_PAST(p, c) \
|
||||||
|
while(*p && (*p != c)) p++; \
|
||||||
|
SKIP_WHILE(p, c)
|
||||||
|
|
||||||
static int proc_net_read(sigar_net_connection_walker_t *walker,
|
static int proc_net_read(sigar_net_connection_walker_t *walker,
|
||||||
const char *fname,
|
const char *fname,
|
||||||
int type)
|
int type)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char buffer[8192], *ptr;
|
char buffer[8192];
|
||||||
|
char *ptr;
|
||||||
int flags = walker->flags;
|
int flags = walker->flags;
|
||||||
|
|
||||||
if (!(fp = fopen(fname, "r"))) {
|
if (!(fp = fopen(fname, "r"))) {
|
||||||
|
@ -1763,56 +1759,37 @@ static int proc_net_read(sigar_net_connection_walker_t *walker,
|
||||||
|
|
||||||
while ((ptr = fgets(buffer, sizeof(buffer), fp))) {
|
while ((ptr = fgets(buffer, sizeof(buffer), fp))) {
|
||||||
sigar_net_connection_t conn;
|
sigar_net_connection_t conn;
|
||||||
char *port = NULL;
|
|
||||||
char *laddr, *raddr;
|
char *laddr, *raddr;
|
||||||
|
int laddr_len=0, raddr_len=0;
|
||||||
int status, more;
|
int status, more;
|
||||||
|
|
||||||
SIGAR_SKIP_SPACE(ptr);
|
/* skip leading space */
|
||||||
if (IS_NULL_PTR(ptr)) {
|
SKIP_WHILE(ptr, ' ');
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr = sigar_skip_token(ptr); /* skip number */
|
/* skip "%d: " */
|
||||||
while (isspace(*ptr)) {
|
SKIP_PAST(ptr, ' ');
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
if (IS_NULL_PTR(ptr)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(port = strchr(ptr, ':'))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*port = '\0';
|
|
||||||
++port;
|
|
||||||
|
|
||||||
conn.local_port = (strtoul(port, &port, 16) & 0xffff);
|
|
||||||
laddr = ptr;
|
laddr = ptr;
|
||||||
|
while (*ptr && (*ptr != ':')) {
|
||||||
ptr = port;
|
laddr_len++;
|
||||||
while (isspace(*ptr)) {
|
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
if (IS_NULL_PTR(ptr)) {
|
SKIP_WHILE(ptr, ':');
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(port = strchr(ptr, ':'))) {
|
conn.local_port = (strtoul(ptr, &ptr, 16) & 0xffff);
|
||||||
continue;
|
|
||||||
}
|
SKIP_WHILE(ptr, ' ');
|
||||||
*port = '\0';
|
|
||||||
++port;
|
|
||||||
|
|
||||||
conn.remote_port = (strtoul(port, &port, 16) & 0xffff);
|
|
||||||
raddr = ptr;
|
raddr = ptr;
|
||||||
|
while (*ptr && (*ptr != ':')) {
|
||||||
ptr = port;
|
raddr_len++;
|
||||||
while (isspace(*ptr)) {
|
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
if (IS_NULL_PTR(ptr)) {
|
SKIP_WHILE(ptr, ':');
|
||||||
continue;
|
|
||||||
}
|
conn.remote_port = (strtoul(ptr, &ptr, 16) & 0xffff);
|
||||||
|
|
||||||
|
SKIP_WHILE(ptr, ' ');
|
||||||
|
|
||||||
if (!((conn.remote_port && (flags & SIGAR_NETCONN_CLIENT)) ||
|
if (!((conn.remote_port && (flags & SIGAR_NETCONN_CLIENT)) ||
|
||||||
(!conn.remote_port && (flags & SIGAR_NETCONN_SERVER))))
|
(!conn.remote_port && (flags & SIGAR_NETCONN_SERVER))))
|
||||||
|
@ -1824,7 +1801,7 @@ static int proc_net_read(sigar_net_connection_walker_t *walker,
|
||||||
|
|
||||||
status = ip_format(conn.local_address,
|
status = ip_format(conn.local_address,
|
||||||
sizeof(conn.local_address),
|
sizeof(conn.local_address),
|
||||||
laddr);
|
laddr, laddr_len);
|
||||||
|
|
||||||
if (status != SIGAR_OK) {
|
if (status != SIGAR_OK) {
|
||||||
return status;
|
return status;
|
||||||
|
@ -1832,46 +1809,30 @@ static int proc_net_read(sigar_net_connection_walker_t *walker,
|
||||||
|
|
||||||
status = ip_format(conn.remote_address,
|
status = ip_format(conn.remote_address,
|
||||||
sizeof(conn.remote_address),
|
sizeof(conn.remote_address),
|
||||||
raddr);
|
raddr, raddr_len);
|
||||||
|
|
||||||
if (status != SIGAR_OK) {
|
if (status != SIGAR_OK) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SIGAR_TCP_* currently matches TCP_* in linux/tcp.h */
|
/* SIGAR_TCP_* currently matches TCP_* in linux/tcp.h */
|
||||||
sscanf(ptr, "%2x", &conn.state);
|
conn.state = hex2int(ptr, 2);
|
||||||
ptr = sigar_skip_token(ptr);
|
ptr += 2;
|
||||||
SIGAR_SKIP_SPACE(ptr);
|
SKIP_WHILE(ptr, ' ');
|
||||||
if (IS_NULL_PTR(ptr)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(ptr) < ((HEX_ENT_LEN*2) + 1)) {
|
conn.send_queue = hex2int(ptr, HEX_ENT_LEN);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
conn.send_queue = hex2int(ptr);
|
|
||||||
ptr += HEX_ENT_LEN+1; /* tx + ':' */;
|
ptr += HEX_ENT_LEN+1; /* tx + ':' */;
|
||||||
|
|
||||||
conn.receive_queue = hex2int(ptr);
|
conn.receive_queue = hex2int(ptr, HEX_ENT_LEN);
|
||||||
ptr += HEX_ENT_LEN;
|
ptr += HEX_ENT_LEN;
|
||||||
|
SKIP_WHILE(ptr, ' ');
|
||||||
|
|
||||||
SIGAR_SKIP_SPACE(ptr);
|
SKIP_PAST(ptr, ' '); /* tr:tm->whem */
|
||||||
if (IS_NULL_PTR(ptr)) {
|
SKIP_PAST(ptr, ' '); /* retrnsmt */
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr = sigar_skip_multiple_token(ptr, 2); /* tr:tm->when retrnsmt */
|
|
||||||
if (IS_NULL_PTR(ptr)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
conn.uid = sigar_strtoul(ptr);
|
conn.uid = sigar_strtoul(ptr);
|
||||||
|
|
||||||
ptr = sigar_skip_token(ptr);
|
SKIP_PAST(ptr, ' '); /* timeout */
|
||||||
if (IS_NULL_PTR(ptr)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
conn.inode = sigar_strtoul(ptr);
|
conn.inode = sigar_strtoul(ptr);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue