diff options
Diffstat (limited to 'net/ipv4/proc.c')
-rw-r--r-- | net/ipv4/proc.c | 71 |
1 files changed, 59 insertions, 12 deletions
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index d63474c6b400..552169b41b16 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -51,24 +51,54 @@ | |||
51 | */ | 51 | */ |
52 | static int sockstat_seq_show(struct seq_file *seq, void *v) | 52 | static int sockstat_seq_show(struct seq_file *seq, void *v) |
53 | { | 53 | { |
54 | struct net *net = seq->private; | ||
55 | |||
54 | socket_seq_show(seq); | 56 | socket_seq_show(seq); |
55 | seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n", | 57 | seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n", |
56 | sock_prot_inuse_get(&tcp_prot), | 58 | sock_prot_inuse_get(net, &tcp_prot), |
57 | atomic_read(&tcp_orphan_count), | 59 | atomic_read(&tcp_orphan_count), |
58 | tcp_death_row.tw_count, atomic_read(&tcp_sockets_allocated), | 60 | tcp_death_row.tw_count, atomic_read(&tcp_sockets_allocated), |
59 | atomic_read(&tcp_memory_allocated)); | 61 | atomic_read(&tcp_memory_allocated)); |
60 | seq_printf(seq, "UDP: inuse %d mem %d\n", sock_prot_inuse_get(&udp_prot), | 62 | seq_printf(seq, "UDP: inuse %d mem %d\n", |
63 | sock_prot_inuse_get(net, &udp_prot), | ||
61 | atomic_read(&udp_memory_allocated)); | 64 | atomic_read(&udp_memory_allocated)); |
62 | seq_printf(seq, "UDPLITE: inuse %d\n", sock_prot_inuse_get(&udplite_prot)); | 65 | seq_printf(seq, "UDPLITE: inuse %d\n", |
63 | seq_printf(seq, "RAW: inuse %d\n", sock_prot_inuse_get(&raw_prot)); | 66 | sock_prot_inuse_get(net, &udplite_prot)); |
67 | seq_printf(seq, "RAW: inuse %d\n", | ||
68 | sock_prot_inuse_get(net, &raw_prot)); | ||
64 | seq_printf(seq, "FRAG: inuse %d memory %d\n", | 69 | seq_printf(seq, "FRAG: inuse %d memory %d\n", |
65 | ip_frag_nqueues(&init_net), ip_frag_mem(&init_net)); | 70 | ip_frag_nqueues(net), ip_frag_mem(net)); |
66 | return 0; | 71 | return 0; |
67 | } | 72 | } |
68 | 73 | ||
69 | static int sockstat_seq_open(struct inode *inode, struct file *file) | 74 | static int sockstat_seq_open(struct inode *inode, struct file *file) |
70 | { | 75 | { |
71 | return single_open(file, sockstat_seq_show, NULL); | 76 | int err; |
77 | struct net *net; | ||
78 | |||
79 | err = -ENXIO; | ||
80 | net = get_proc_net(inode); | ||
81 | if (net == NULL) | ||
82 | goto err_net; | ||
83 | |||
84 | err = single_open(file, sockstat_seq_show, net); | ||
85 | if (err < 0) | ||
86 | goto err_open; | ||
87 | |||
88 | return 0; | ||
89 | |||
90 | err_open: | ||
91 | put_net(net); | ||
92 | err_net: | ||
93 | return err; | ||
94 | } | ||
95 | |||
96 | static int sockstat_seq_release(struct inode *inode, struct file *file) | ||
97 | { | ||
98 | struct net *net = ((struct seq_file *)file->private_data)->private; | ||
99 | |||
100 | put_net(net); | ||
101 | return single_release(inode, file); | ||
72 | } | 102 | } |
73 | 103 | ||
74 | static const struct file_operations sockstat_seq_fops = { | 104 | static const struct file_operations sockstat_seq_fops = { |
@@ -76,7 +106,7 @@ static const struct file_operations sockstat_seq_fops = { | |||
76 | .open = sockstat_seq_open, | 106 | .open = sockstat_seq_open, |
77 | .read = seq_read, | 107 | .read = seq_read, |
78 | .llseek = seq_lseek, | 108 | .llseek = seq_lseek, |
79 | .release = single_release, | 109 | .release = sockstat_seq_release, |
80 | }; | 110 | }; |
81 | 111 | ||
82 | /* snmp items */ | 112 | /* snmp items */ |
@@ -423,25 +453,42 @@ static const struct file_operations netstat_seq_fops = { | |||
423 | .release = single_release, | 453 | .release = single_release, |
424 | }; | 454 | }; |
425 | 455 | ||
456 | static __net_init int ip_proc_init_net(struct net *net) | ||
457 | { | ||
458 | if (!proc_net_fops_create(net, "sockstat", S_IRUGO, &sockstat_seq_fops)) | ||
459 | return -ENOMEM; | ||
460 | return 0; | ||
461 | } | ||
462 | |||
463 | static __net_exit void ip_proc_exit_net(struct net *net) | ||
464 | { | ||
465 | proc_net_remove(net, "sockstat"); | ||
466 | } | ||
467 | |||
468 | static __net_initdata struct pernet_operations ip_proc_ops = { | ||
469 | .init = ip_proc_init_net, | ||
470 | .exit = ip_proc_exit_net, | ||
471 | }; | ||
472 | |||
426 | int __init ip_misc_proc_init(void) | 473 | int __init ip_misc_proc_init(void) |
427 | { | 474 | { |
428 | int rc = 0; | 475 | int rc = 0; |
429 | 476 | ||
477 | if (register_pernet_subsys(&ip_proc_ops)) | ||
478 | goto out_pernet; | ||
479 | |||
430 | if (!proc_net_fops_create(&init_net, "netstat", S_IRUGO, &netstat_seq_fops)) | 480 | if (!proc_net_fops_create(&init_net, "netstat", S_IRUGO, &netstat_seq_fops)) |
431 | goto out_netstat; | 481 | goto out_netstat; |
432 | 482 | ||
433 | if (!proc_net_fops_create(&init_net, "snmp", S_IRUGO, &snmp_seq_fops)) | 483 | if (!proc_net_fops_create(&init_net, "snmp", S_IRUGO, &snmp_seq_fops)) |
434 | goto out_snmp; | 484 | goto out_snmp; |
435 | |||
436 | if (!proc_net_fops_create(&init_net, "sockstat", S_IRUGO, &sockstat_seq_fops)) | ||
437 | goto out_sockstat; | ||
438 | out: | 485 | out: |
439 | return rc; | 486 | return rc; |
440 | out_sockstat: | ||
441 | proc_net_remove(&init_net, "snmp"); | ||
442 | out_snmp: | 487 | out_snmp: |
443 | proc_net_remove(&init_net, "netstat"); | 488 | proc_net_remove(&init_net, "netstat"); |
444 | out_netstat: | 489 | out_netstat: |
490 | unregister_pernet_subsys(&ip_proc_ops); | ||
491 | out_pernet: | ||
445 | rc = -ENOMEM; | 492 | rc = -ENOMEM; |
446 | goto out; | 493 | goto out; |
447 | } | 494 | } |