Module Name: src
Committed By: martin
Date: Tue Jul 31 17:01:20 UTC 2018
Modified Files:
src/share/man/man4 [netbsd-8]: ddb.4
src/sys/ddb [netbsd-8]: db_command.c
src/sys/kern [netbsd-8]: uipc_socket2.c
src/sys/sys [netbsd-8]: socketvar.h
Log Message:
Pull up following revision(s) (requested by msaitoh in ticket #954):
sys/sys/socketvar.h: revision 1.157
share/man/man4/ddb.4: revision 1.180
share/man/man4/ddb.4: revision 1.181
sys/kern/uipc_socket2.c: revision 1.131
sys/ddb/db_command.c: revision 1.154
Add "show socket" command written by Hiroki SUENAGA. It prints usage of
system's socket buffers.
Improve wording.
To generate a diff of this commit:
cvs rdiff -u -r1.166.6.1 -r1.166.6.2 src/share/man/man4/ddb.4
cvs rdiff -u -r1.148.8.1 -r1.148.8.2 src/sys/ddb/db_command.c
cvs rdiff -u -r1.124.8.2 -r1.124.8.3 src/sys/kern/uipc_socket2.c
cvs rdiff -u -r1.144.6.3 -r1.144.6.4 src/sys/sys/socketvar.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/share/man/man4/ddb.4
diff -u src/share/man/man4/ddb.4:1.166.6.1 src/share/man/man4/ddb.4:1.166.6.2
--- src/share/man/man4/ddb.4:1.166.6.1 Mon Apr 2 09:07:52 2018
+++ src/share/man/man4/ddb.4 Tue Jul 31 17:01:20 2018
@@ -1,4 +1,4 @@
-.\" $NetBSD: ddb.4,v 1.166.6.1 2018/04/02 09:07:52 martin Exp $
+.\" $NetBSD: ddb.4,v 1.166.6.2 2018/07/31 17:01:20 martin Exp $
.\"
.\" Copyright (c) 1997 - 2009 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -56,7 +56,7 @@
.\" any improvements or extensions that they make and grant Carnegie Mellon
.\" the rights to redistribute these changes.
.\"
-.Dd March 19, 2018
+.Dd July 31, 2018
.Dt DDB 4
.Os
.Sh NAME
@@ -750,6 +750,25 @@ of LWPs will be shown.
If the run queue has LWPs, but the sched_whichqs bit is not set for that
queue, the queue index will be prefixed with a
.Sq \&! .
+.It Ic show socket Ns Oo Cm /ampv Oc
+Print usage of system's socket buffers.
+By default, empty sockets aren't printed.
+.Bl -tag -width 4n -compact
+.It Cm /a
+Print all processes which use the socket.
+.It Cm /m
+Print mbuf chain in the socket buffer.
+.It Cm /p
+By default, a process which uses the socket is printed (only one socket).
+If
+.Cm /p
+is specified, the process isn't printed.
+.It Cm /v
+Verbose mode.
+If
+.Cm /v
+is specified, all sockets are printed.
+.El
.It Ic show uvmexp
Print a selection of UVM counters and statistics.
.It Ic show kernhist Oo Ar addr Oc
Index: src/sys/ddb/db_command.c
diff -u src/sys/ddb/db_command.c:1.148.8.1 src/sys/ddb/db_command.c:1.148.8.2
--- src/sys/ddb/db_command.c:1.148.8.1 Mon Apr 2 09:07:52 2018
+++ src/sys/ddb/db_command.c Tue Jul 31 17:01:20 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: db_command.c,v 1.148.8.1 2018/04/02 09:07:52 martin Exp $ */
+/* $NetBSD: db_command.c,v 1.148.8.2 2018/07/31 17:01:20 martin Exp $ */
/*
* Copyright (c) 1996, 1997, 1998, 1999, 2002, 2009 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_command.c,v 1.148.8.1 2018/04/02 09:07:52 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_command.c,v 1.148.8.2 2018/07/31 17:01:20 martin Exp $");
#ifdef _KERNEL_OPT
#include "opt_aio.h"
@@ -89,6 +89,7 @@ __KERNEL_RCSID(0, "$NetBSD: db_command.c
#include <sys/buf.h>
#include <sys/module.h>
#include <sys/kernhist.h>
+#include <sys/socketvar.h>
/*include queue macros*/
#include <sys/queue.h>
@@ -203,6 +204,7 @@ static void db_show_all_pages(db_expr_t,
static void db_pool_print_cmd(db_expr_t, bool, db_expr_t, const char *);
static void db_reboot_cmd(db_expr_t, bool, db_expr_t, const char *);
static void db_sifting_cmd(db_expr_t, bool, db_expr_t, const char *);
+static void db_socket_print_cmd(db_expr_t, bool, db_expr_t, const char *);
static void db_stack_trace_cmd(db_expr_t, bool, db_expr_t, const char *);
static void db_sync_cmd(db_expr_t, bool, db_expr_t, const char *);
static void db_whatis_cmd(db_expr_t, bool, db_expr_t, const char *);
@@ -256,6 +258,7 @@ static const struct db_command db_show_c
"Print statistics of locks", NULL, NULL) },
{ DDB_ADD_CMD("map", db_map_print_cmd, 0,
"Print the vm_map at address.", "[/f] address",NULL) },
+ { DDB_ADD_CMD("socket", db_socket_print_cmd, 0,NULL,NULL,NULL) },
{ DDB_ADD_CMD("module", db_show_module_cmd, 0,
"Print kernel modules", NULL, NULL) },
{ DDB_ADD_CMD("mount", db_mount_print_cmd, 0,
@@ -1210,6 +1213,17 @@ db_uvmexp_print_cmd(db_expr_t addr, bool
#endif
}
+/*ARGSUSED */
+static void
+db_socket_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
+ const char *modif)
+{
+
+#ifdef _KERNEL /* XXX CRASH(8) */
+ socket_print(modif, db_printf);
+#endif
+}
+
#ifdef KERNHIST
/*ARGSUSED*/
static void
Index: src/sys/kern/uipc_socket2.c
diff -u src/sys/kern/uipc_socket2.c:1.124.8.2 src/sys/kern/uipc_socket2.c:1.124.8.3
--- src/sys/kern/uipc_socket2.c:1.124.8.2 Sat Jun 9 15:16:30 2018
+++ src/sys/kern/uipc_socket2.c Tue Jul 31 17:01:20 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: uipc_socket2.c,v 1.124.8.2 2018/06/09 15:16:30 martin Exp $ */
+/* $NetBSD: uipc_socket2.c,v 1.124.8.3 2018/07/31 17:01:20 martin Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,9 +58,10 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.124.8.2 2018/06/09 15:16:30 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.124.8.3 2018/07/31 17:01:20 martin Exp $");
#ifdef _KERNEL_OPT
+#include "opt_ddb.h"
#include "opt_mbuftrace.h"
#include "opt_sb_max.h"
#endif
@@ -81,6 +82,10 @@ __KERNEL_RCSID(0, "$NetBSD: uipc_socket2
#include <sys/pool.h>
#include <sys/uidinfo.h>
+#ifdef DDB
+#include <sys/filedesc.h>
+#endif
+
/*
* Primitive routines for operating on sockets and socket buffers.
*
@@ -687,6 +692,7 @@ sbreserve(struct sockbuf *sb, u_long cc,
sb->sb_mbmax = min(cc * 2, sb_max);
if (sb->sb_lowat > sb->sb_hiwat)
sb->sb_lowat = sb->sb_hiwat;
+
return (1);
}
@@ -1541,3 +1547,192 @@ sowait(struct socket *so, bool catch_p,
solockretry(so, lock);
return error;
}
+
+#ifdef DDB
+
+/*
+ * Currently, sofindproc() is used only from DDB. It could be used from others
+ * by using db_mutex_enter()
+ */
+
+static inline int
+db_mutex_enter(kmutex_t *mtx)
+{
+ extern int db_active;
+ int rv;
+
+ if (!db_active) {
+ mutex_enter(mtx);
+ rv = 1;
+ } else
+ rv = mutex_tryenter(mtx);
+
+ return rv;
+}
+
+int
+sofindproc(struct socket *so, int all, void (*pr)(const char *, ...))
+{
+ proc_t *p;
+ filedesc_t *fdp;
+ fdtab_t *dt;
+ fdfile_t *ff;
+ file_t *fp = NULL;
+ int found = 0;
+ int i, t;
+
+ if (so == NULL)
+ return 0;
+
+ t = db_mutex_enter(proc_lock);
+ if (!t) {
+ pr("could not acquire proc_lock mutex\n");
+ return 0;
+ }
+ PROCLIST_FOREACH(p, &allproc) {
+ if (p->p_stat == SIDL)
+ continue;
+ fdp = p->p_fd;
+ t = db_mutex_enter(&fdp->fd_lock);
+ if (!t) {
+ pr("could not acquire fd_lock mutex\n");
+ continue;
+ }
+ dt = fdp->fd_dt;
+ for (i = 0; i < dt->dt_nfiles; i++) {
+ ff = dt->dt_ff[i];
+ if (ff == NULL)
+ continue;
+
+ fp = ff->ff_file;
+ if (fp == NULL)
+ continue;
+
+ t = db_mutex_enter(&fp->f_lock);
+ if (!t) {
+ pr("could not acquire f_lock mutex\n");
+ continue;
+ }
+ if ((struct socket *)fp->f_data != so) {
+ mutex_exit(&fp->f_lock);
+ continue;
+ }
+ found++;
+ if (pr)
+ pr("socket %p: owner %s(pid=%d)\n",
+ so, p->p_comm, p->p_pid);
+ mutex_exit(&fp->f_lock);
+ if (all == 0)
+ break;
+ }
+ mutex_exit(&fdp->fd_lock);
+ if (all == 0 && found != 0)
+ break;
+ }
+ mutex_exit(proc_lock);
+
+ return found;
+}
+
+void
+socket_print(const char *modif, void (*pr)(const char *, ...))
+{
+ file_t *fp;
+ struct socket *so;
+ struct sockbuf *sb_snd, *sb_rcv;
+ struct mbuf *m_rec, *m;
+ bool opt_v = false;
+ bool opt_m = false;
+ bool opt_a = false;
+ bool opt_p = false;
+ int nrecs, nmbufs;
+ char ch;
+ const char *family;
+
+ while ( (ch = *(modif++)) != '\0') {
+ switch (ch) {
+ case 'v':
+ opt_v = true;
+ break;
+ case 'm':
+ opt_m = true;
+ break;
+ case 'a':
+ opt_a = true;
+ break;
+ case 'p':
+ opt_p = true;
+ break;
+ }
+ }
+ if (opt_v == false && pr)
+ (pr)("Ignore empty sockets. use /v to print all.\n");
+ if (opt_p == true && pr)
+ (pr)("Don't search owner process.\n");
+
+ LIST_FOREACH(fp, &filehead, f_list) {
+ if (fp->f_type != DTYPE_SOCKET)
+ continue;
+ so = (struct socket *)fp->f_data;
+ if (so == NULL)
+ continue;
+
+ if (so->so_proto->pr_domain->dom_family == AF_INET)
+ family = "INET";
+#ifdef INET6
+ else if (so->so_proto->pr_domain->dom_family == AF_INET6)
+ family = "INET6";
+#endif
+ else if (so->so_proto->pr_domain->dom_family == pseudo_AF_KEY)
+ family = "KEY";
+ else if (so->so_proto->pr_domain->dom_family == AF_ROUTE)
+ family = "ROUTE";
+ else
+ continue;
+
+ sb_snd = &so->so_snd;
+ sb_rcv = &so->so_rcv;
+
+ if (opt_v != true &&
+ sb_snd->sb_cc == 0 && sb_rcv->sb_cc == 0)
+ continue;
+
+ pr("---SOCKET %p: type %s\n", so, family);
+ if (opt_p != true)
+ sofindproc(so, opt_a == true ? 1 : 0, pr);
+ pr("Send Buffer Bytes: %d [bytes]\n", sb_snd->sb_cc);
+ pr("Send Buffer mbufs:\n");
+ m_rec = m = sb_snd->sb_mb;
+ nrecs = 0;
+ nmbufs = 0;
+ while (m_rec) {
+ nrecs++;
+ if (opt_m == true)
+ pr(" mbuf chain %p\n", m_rec);
+ while (m) {
+ nmbufs++;
+ m = m->m_next;
+ }
+ m_rec = m = m_rec->m_nextpkt;
+ }
+ pr(" Total %d records, %d mbufs.\n", nrecs, nmbufs);
+
+ pr("Recv Buffer Usage: %d [bytes]\n", sb_rcv->sb_cc);
+ pr("Recv Buffer mbufs:\n");
+ m_rec = m = sb_rcv->sb_mb;
+ nrecs = 0;
+ nmbufs = 0;
+ while (m_rec) {
+ nrecs++;
+ if (opt_m == true)
+ pr(" mbuf chain %p\n", m_rec);
+ while (m) {
+ nmbufs++;
+ m = m->m_next;
+ }
+ m_rec = m = m_rec->m_nextpkt;
+ }
+ pr(" Total %d records, %d mbufs.\n", nrecs, nmbufs);
+ }
+}
+#endif /* DDB */
Index: src/sys/sys/socketvar.h
diff -u src/sys/sys/socketvar.h:1.144.6.3 src/sys/sys/socketvar.h:1.144.6.4
--- src/sys/sys/socketvar.h:1.144.6.3 Sat Jun 9 15:16:30 2018
+++ src/sys/sys/socketvar.h Tue Jul 31 17:01:20 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: socketvar.h,v 1.144.6.3 2018/06/09 15:16:30 martin Exp $ */
+/* $NetBSD: socketvar.h,v 1.144.6.4 2018/07/31 17:01:20 martin Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -572,6 +572,10 @@ SYSCTL_DECL(_net_inet_accf);
#endif
void accept_filter_init(void);
#endif
+#ifdef DDB
+int sofindproc(struct socket *so, int all, void (*pr)(const char *, ...));
+void socket_print(const char *modif, void (*pr)(const char *, ...));
+#endif
#endif /* _KERNEL */