rxrpc: Add /proc/net/rxrpc/peers to display peer list
Add /proc/net/rxrpc/peers to display the list of peers currently active. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
d275444cc3
Коммит
bc0e7cf433
|
@ -1062,6 +1062,7 @@ void rxrpc_put_peer(struct rxrpc_peer *);
|
|||
*/
|
||||
extern const struct seq_operations rxrpc_call_seq_ops;
|
||||
extern const struct seq_operations rxrpc_connection_seq_ops;
|
||||
extern const struct seq_operations rxrpc_peer_seq_ops;
|
||||
|
||||
/*
|
||||
* recvmsg.c
|
||||
|
|
|
@ -102,6 +102,9 @@ static __net_init int rxrpc_init_net(struct net *net)
|
|||
proc_create_net("conns", 0444, rxnet->proc_net,
|
||||
&rxrpc_connection_seq_ops,
|
||||
sizeof(struct seq_net_private));
|
||||
proc_create_net("peers", 0444, rxnet->proc_net,
|
||||
&rxrpc_peer_seq_ops,
|
||||
sizeof(struct seq_net_private));
|
||||
return 0;
|
||||
|
||||
err_proc:
|
||||
|
|
126
net/rxrpc/proc.c
126
net/rxrpc/proc.c
|
@ -212,3 +212,129 @@ const struct seq_operations rxrpc_connection_seq_ops = {
|
|||
.stop = rxrpc_connection_seq_stop,
|
||||
.show = rxrpc_connection_seq_show,
|
||||
};
|
||||
|
||||
/*
|
||||
* generate a list of extant virtual peers in /proc/net/rxrpc/peers
|
||||
*/
|
||||
static int rxrpc_peer_seq_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct rxrpc_peer *peer;
|
||||
time64_t now;
|
||||
char lbuff[50], rbuff[50];
|
||||
|
||||
if (v == SEQ_START_TOKEN) {
|
||||
seq_puts(seq,
|
||||
"Proto Local "
|
||||
" Remote "
|
||||
" Use CW MTU LastUse RTT Rc\n"
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
peer = list_entry(v, struct rxrpc_peer, hash_link);
|
||||
|
||||
sprintf(lbuff, "%pISpc", &peer->local->srx.transport);
|
||||
|
||||
sprintf(rbuff, "%pISpc", &peer->srx.transport);
|
||||
|
||||
now = ktime_get_seconds();
|
||||
seq_printf(seq,
|
||||
"UDP %-47.47s %-47.47s %3u"
|
||||
" %3u %5u %6llus %12llu %2u\n",
|
||||
lbuff,
|
||||
rbuff,
|
||||
atomic_read(&peer->usage),
|
||||
peer->cong_cwnd,
|
||||
peer->mtu,
|
||||
now - peer->last_tx_at,
|
||||
peer->rtt,
|
||||
peer->rtt_cursor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *rxrpc_peer_seq_start(struct seq_file *seq, loff_t *_pos)
|
||||
__acquires(rcu)
|
||||
{
|
||||
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
|
||||
unsigned int bucket, n;
|
||||
unsigned int shift = 32 - HASH_BITS(rxnet->peer_hash);
|
||||
void *p;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
if (*_pos >= UINT_MAX)
|
||||
return NULL;
|
||||
|
||||
n = *_pos & ((1U << shift) - 1);
|
||||
bucket = *_pos >> shift;
|
||||
for (;;) {
|
||||
if (bucket >= HASH_SIZE(rxnet->peer_hash)) {
|
||||
*_pos = UINT_MAX;
|
||||
return NULL;
|
||||
}
|
||||
if (n == 0) {
|
||||
if (bucket == 0)
|
||||
return SEQ_START_TOKEN;
|
||||
*_pos += 1;
|
||||
n++;
|
||||
}
|
||||
|
||||
p = seq_hlist_start_rcu(&rxnet->peer_hash[bucket], n - 1);
|
||||
if (p)
|
||||
return p;
|
||||
bucket++;
|
||||
n = 1;
|
||||
*_pos = (bucket << shift) | n;
|
||||
}
|
||||
}
|
||||
|
||||
static void *rxrpc_peer_seq_next(struct seq_file *seq, void *v, loff_t *_pos)
|
||||
{
|
||||
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
|
||||
unsigned int bucket, n;
|
||||
unsigned int shift = 32 - HASH_BITS(rxnet->peer_hash);
|
||||
void *p;
|
||||
|
||||
if (*_pos >= UINT_MAX)
|
||||
return NULL;
|
||||
|
||||
bucket = *_pos >> shift;
|
||||
|
||||
p = seq_hlist_next_rcu(v, &rxnet->peer_hash[bucket], _pos);
|
||||
if (p)
|
||||
return p;
|
||||
|
||||
for (;;) {
|
||||
bucket++;
|
||||
n = 1;
|
||||
*_pos = (bucket << shift) | n;
|
||||
|
||||
if (bucket >= HASH_SIZE(rxnet->peer_hash)) {
|
||||
*_pos = UINT_MAX;
|
||||
return NULL;
|
||||
}
|
||||
if (n == 0) {
|
||||
*_pos += 1;
|
||||
n++;
|
||||
}
|
||||
|
||||
p = seq_hlist_start_rcu(&rxnet->peer_hash[bucket], n - 1);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
static void rxrpc_peer_seq_stop(struct seq_file *seq, void *v)
|
||||
__releases(rcu)
|
||||
{
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
|
||||
const struct seq_operations rxrpc_peer_seq_ops = {
|
||||
.start = rxrpc_peer_seq_start,
|
||||
.next = rxrpc_peer_seq_next,
|
||||
.stop = rxrpc_peer_seq_stop,
|
||||
.show = rxrpc_peer_seq_show,
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче