ss: Unify unix stats output from netlink and proc
Refactored to use one func for output unix stats info from both /proc and netlink. Signed-off-by: Vadim Kochan <vadim4j@gmail.com>
This commit is contained in:
parent
decbb4378c
commit
bf4ceee6ae
101
misc/ss.c
101
misc/ss.c
|
|
@ -25,6 +25,7 @@
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "rt_names.h"
|
#include "rt_names.h"
|
||||||
|
|
@ -2234,6 +2235,7 @@ struct unixstat
|
||||||
struct unixstat *next;
|
struct unixstat *next;
|
||||||
int ino;
|
int ino;
|
||||||
int peer;
|
int peer;
|
||||||
|
char *peer_name;
|
||||||
int rq;
|
int rq;
|
||||||
int wq;
|
int wq;
|
||||||
int state;
|
int state;
|
||||||
|
|
@ -2279,7 +2281,18 @@ static const char *unix_netid_name(int type)
|
||||||
return netid;
|
return netid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unix_list_print(struct unixstat *list, struct filter *f)
|
static bool unix_type_skip(struct unixstat *s, struct filter *f)
|
||||||
|
{
|
||||||
|
if (s->type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB)))
|
||||||
|
return true;
|
||||||
|
if (s->type == SOCK_DGRAM && !(f->dbs&(1<<UNIX_DG_DB)))
|
||||||
|
return true;
|
||||||
|
if (s->type == SOCK_SEQPACKET && !(f->dbs&(1<<UNIX_SQ_DB)))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unix_stats_print(struct unixstat *list, struct filter *f)
|
||||||
{
|
{
|
||||||
struct unixstat *s;
|
struct unixstat *s;
|
||||||
char *peer;
|
char *peer;
|
||||||
|
|
@ -2287,15 +2300,14 @@ static void unix_list_print(struct unixstat *list, struct filter *f)
|
||||||
for (s = list; s; s = s->next) {
|
for (s = list; s; s = s->next) {
|
||||||
if (!(f->states & (1<<s->state)))
|
if (!(f->states & (1<<s->state)))
|
||||||
continue;
|
continue;
|
||||||
if (s->type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB)))
|
if (unix_type_skip(s, f))
|
||||||
continue;
|
|
||||||
if (s->type == SOCK_DGRAM && !(f->dbs&(1<<UNIX_DG_DB)))
|
|
||||||
continue;
|
|
||||||
if (s->type == SOCK_SEQPACKET && !(f->dbs&(1<<UNIX_SQ_DB)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
peer = "*";
|
peer = "*";
|
||||||
if (s->peer) {
|
if (s->peer_name)
|
||||||
|
peer = s->peer_name;
|
||||||
|
|
||||||
|
if (s->peer && !s->peer_name) {
|
||||||
struct unixstat *p;
|
struct unixstat *p;
|
||||||
for (p = list; p; p = p->next) {
|
for (p = list; p; p = p->next) {
|
||||||
if (s->peer == p->ino)
|
if (s->peer == p->ino)
|
||||||
|
|
@ -2356,36 +2368,23 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
|
||||||
struct unix_diag_msg *r = NLMSG_DATA(nlh);
|
struct unix_diag_msg *r = NLMSG_DATA(nlh);
|
||||||
struct rtattr *tb[UNIX_DIAG_MAX+1];
|
struct rtattr *tb[UNIX_DIAG_MAX+1];
|
||||||
char name[128];
|
char name[128];
|
||||||
int peer_ino;
|
struct unixstat stat = { .name = "*" , .peer_name = "*" };
|
||||||
__u32 rqlen, wqlen;
|
|
||||||
|
|
||||||
parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr*)(r+1),
|
parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr*)(r+1),
|
||||||
nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
|
nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*r)));
|
||||||
|
|
||||||
if (r->udiag_type == SOCK_STREAM && !(f->dbs&(1<<UNIX_ST_DB)))
|
stat.type = r->udiag_type;
|
||||||
return 0;
|
stat.state = r->udiag_state;
|
||||||
if (r->udiag_type == SOCK_DGRAM && !(f->dbs&(1<<UNIX_DG_DB)))
|
stat.ino = r->udiag_ino;
|
||||||
return 0;
|
|
||||||
if (r->udiag_type == SOCK_SEQPACKET && !(f->dbs&(1<<UNIX_SQ_DB)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (netid_width)
|
if (unix_type_skip(&stat, f))
|
||||||
printf("%-*s ", netid_width,
|
return 0;
|
||||||
unix_netid_name(r->udiag_type));
|
|
||||||
if (state_width)
|
|
||||||
printf("%-*s ", state_width, sstate_name[r->udiag_state]);
|
|
||||||
|
|
||||||
if (tb[UNIX_DIAG_RQLEN]) {
|
if (tb[UNIX_DIAG_RQLEN]) {
|
||||||
struct unix_diag_rqlen *rql = RTA_DATA(tb[UNIX_DIAG_RQLEN]);
|
struct unix_diag_rqlen *rql = RTA_DATA(tb[UNIX_DIAG_RQLEN]);
|
||||||
rqlen = rql->udiag_rqueue;
|
stat.rq = rql->udiag_rqueue;
|
||||||
wqlen = rql->udiag_wqueue;
|
stat.wq = rql->udiag_wqueue;
|
||||||
} else {
|
|
||||||
rqlen = 0;
|
|
||||||
wqlen = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%-6u %-6u ", rqlen, wqlen);
|
|
||||||
|
|
||||||
if (tb[UNIX_DIAG_NAME]) {
|
if (tb[UNIX_DIAG_NAME]) {
|
||||||
int len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]);
|
int len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]);
|
||||||
|
|
||||||
|
|
@ -2393,41 +2392,17 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
|
||||||
name[len] = '\0';
|
name[len] = '\0';
|
||||||
if (name[0] == '\0')
|
if (name[0] == '\0')
|
||||||
name[0] = '@';
|
name[0] = '@';
|
||||||
} else
|
stat.name = &name[0];
|
||||||
sprintf(name, "*");
|
|
||||||
|
|
||||||
if (tb[UNIX_DIAG_PEER])
|
|
||||||
peer_ino = rta_getattr_u32(tb[UNIX_DIAG_PEER]);
|
|
||||||
else
|
|
||||||
peer_ino = 0;
|
|
||||||
|
|
||||||
printf("%*s %-*d %*s %-*d",
|
|
||||||
addr_width, name,
|
|
||||||
serv_width, r->udiag_ino,
|
|
||||||
addr_width, "*", /* FIXME */
|
|
||||||
serv_width, peer_ino);
|
|
||||||
|
|
||||||
char *buf = NULL;
|
|
||||||
|
|
||||||
if (show_proc_ctx || show_sock_ctx) {
|
|
||||||
if (find_entry(r->udiag_ino, &buf,
|
|
||||||
(show_proc_ctx & show_sock_ctx) ?
|
|
||||||
PROC_SOCK_CTX : PROC_CTX) > 0) {
|
|
||||||
printf(" users:(%s)", buf);
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
} else if (show_users) {
|
|
||||||
if (find_entry(r->udiag_ino, &buf, USERS) > 0) {
|
|
||||||
printf(" users:(%s)", buf);
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (tb[UNIX_DIAG_PEER])
|
||||||
|
stat.peer = rta_getattr_u32(tb[UNIX_DIAG_PEER]);
|
||||||
|
|
||||||
|
unix_stats_print(&stat, f);
|
||||||
|
|
||||||
if (show_mem) {
|
if (show_mem) {
|
||||||
printf("\n\t");
|
printf("\t");
|
||||||
print_skmeminfo(tb, UNIX_DIAG_MEMINFO);
|
print_skmeminfo(tb, UNIX_DIAG_MEMINFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (show_details) {
|
if (show_details) {
|
||||||
if (tb[UNIX_DIAG_SHUTDOWN]) {
|
if (tb[UNIX_DIAG_SHUTDOWN]) {
|
||||||
unsigned char mask;
|
unsigned char mask;
|
||||||
|
|
@ -2435,9 +2410,8 @@ static int unix_show_sock(const struct sockaddr_nl *addr, struct nlmsghdr *nlh,
|
||||||
printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
|
printf(" %c-%c", mask & 1 ? '-' : '<', mask & 2 ? '-' : '>');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (show_mem || show_details)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2505,6 +2479,7 @@ static int unix_show(struct filter *f)
|
||||||
if (!(u = malloc(sizeof(*u))))
|
if (!(u = malloc(sizeof(*u))))
|
||||||
break;
|
break;
|
||||||
u->name = NULL;
|
u->name = NULL;
|
||||||
|
u->peer_name = NULL;
|
||||||
|
|
||||||
if (sscanf(buf, "%x: %x %x %x %x %x %d %s",
|
if (sscanf(buf, "%x: %x %x %x %x %x %d %s",
|
||||||
&u->peer, &u->rq, &u->wq, &flags, &u->type,
|
&u->peer, &u->rq, &u->wq, &flags, &u->type,
|
||||||
|
|
@ -2544,7 +2519,7 @@ static int unix_show(struct filter *f)
|
||||||
strcpy(u->name, name);
|
strcpy(u->name, name);
|
||||||
}
|
}
|
||||||
if (++cnt > MAX_UNIX_REMEMBER) {
|
if (++cnt > MAX_UNIX_REMEMBER) {
|
||||||
unix_list_print(list, f);
|
unix_stats_print(list, f);
|
||||||
unix_list_free(list);
|
unix_list_free(list);
|
||||||
list = NULL;
|
list = NULL;
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
|
|
@ -2552,7 +2527,7 @@ static int unix_show(struct filter *f)
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
if (list) {
|
if (list) {
|
||||||
unix_list_print(list, f);
|
unix_stats_print(list, f);
|
||||||
unix_list_free(list);
|
unix_list_free(list);
|
||||||
list = NULL;
|
list = NULL;
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue