Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Add "show socket" command written by Hiroki SUENAGA. It prin...



details:   https://anonhg.NetBSD.org/src/rev/63da1fc7aeb7
branches:  trunk
changeset: 320795:63da1fc7aeb7
user:      msaitoh <msaitoh%NetBSD.org@localhost>
date:      Fri Jul 20 08:26:25 2018 +0000

description:
Add "show socket" command written by Hiroki SUENAGA. It prints usage of
system's socket buffers.

diffstat:

 share/man/man4/ddb.4    |   23 +++++-
 sys/ddb/db_command.c    |   18 +++-
 sys/kern/uipc_socket2.c |  199 +++++++++++++++++++++++++++++++++++++++++++++++-
 sys/sys/socketvar.h     |    6 +-
 4 files changed, 239 insertions(+), 7 deletions(-)

diffs (truncated from 357 to 300 lines):

diff -r 38c5563055d2 -r 63da1fc7aeb7 share/man/man4/ddb.4
--- a/share/man/man4/ddb.4      Fri Jul 20 07:12:50 2018 +0000
+++ b/share/man/man4/ddb.4      Fri Jul 20 08:26:25 2018 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: ddb.4,v 1.179 2018/07/17 05:52:07 msaitoh Exp $
+.\"    $NetBSD: ddb.4,v 1.180 2018/07/20 08:26:25 msaitoh 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 July 17, 2018
+.Dd July 20, 2018
 .Dt DDB 4
 .Os
 .Sh NAME
@@ -750,6 +750,25 @@
 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 socket isn'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 use 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
diff -r 38c5563055d2 -r 63da1fc7aeb7 sys/ddb/db_command.c
--- a/sys/ddb/db_command.c      Fri Jul 20 07:12:50 2018 +0000
+++ b/sys/ddb/db_command.c      Fri Jul 20 08:26:25 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: db_command.c,v 1.153 2018/03/19 08:41:21 ozaki-r Exp $ */
+/*     $NetBSD: db_command.c,v 1.154 2018/07/20 08:26:25 msaitoh 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.153 2018/03/19 08:41:21 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_command.c,v 1.154 2018/07/20 08:26:25 msaitoh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_aio.h"
@@ -89,6 +89,7 @@
 #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_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 *);
@@ -257,6 +259,7 @@
            "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,
@@ -1211,6 +1214,17 @@
 #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
diff -r 38c5563055d2 -r 63da1fc7aeb7 sys/kern/uipc_socket2.c
--- a/sys/kern/uipc_socket2.c   Fri Jul 20 07:12:50 2018 +0000
+++ b/sys/kern/uipc_socket2.c   Fri Jul 20 08:26:25 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uipc_socket2.c,v 1.130 2018/06/06 09:46:46 roy Exp $   */
+/*     $NetBSD: uipc_socket2.c,v 1.131 2018/07/20 08:26:25 msaitoh 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.130 2018/06/06 09:46:46 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.131 2018/07/20 08:26:25 msaitoh Exp $");
 
 #ifdef _KERNEL_OPT
+#include "opt_ddb.h"
 #include "opt_mbuftrace.h"
 #include "opt_sb_max.h"
 #endif
@@ -81,6 +82,10 @@
 #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 @@
        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 @@
                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)



Home | Main Index | Thread Index | Old Index