Page MenuHomeFreeBSD

D21460.diff
No OneTemporary

D21460.diff

Index: head/share/man/man4/ddb.4
===================================================================
--- head/share/man/man4/ddb.4
+++ head/share/man/man4/ddb.4
@@ -24,43 +24,9 @@
.\" any improvements or extensions that they make and grant Carnegie Mellon
.\" the rights to redistribute these changes.
.\"
-.\" changed a \# to #, since groff choked on it.
-.\"
-.\" HISTORY
-.\" ddb.4,v
-.\" Revision 1.1 1993/07/15 18:41:02 brezak
-.\" Man page for DDB
-.\"
-.\" Revision 2.6 92/04/08 08:52:57 rpd
-.\" Changes from OSF.
-.\" [92/01/17 14:19:22 jsb]
-.\" Changes for OSF debugger modifications.
-.\" [91/12/12 tak]
-.\"
-.\" Revision 2.5 91/06/25 13:50:22 rpd
-.\" Added some watchpoint explanation.
-.\" [91/06/25 rpd]
-.\"
-.\" Revision 2.4 91/06/17 15:47:31 jsb
-.\" Added documentation for continue/c, match, search, and watchpoints.
-.\" I've not actually explained what a watchpoint is; maybe Rich can
-.\" do that (hint, hint).
-.\" [91/06/17 10:58:08 jsb]
-.\"
-.\" Revision 2.3 91/05/14 17:04:23 mrt
-.\" Correcting copyright
-.\"
-.\" Revision 2.2 91/02/14 14:10:06 mrt
-.\" Changed to new Mach copyright
-.\" [91/02/12 18:10:12 mrt]
-.\"
-.\" Revision 2.2 90/08/30 14:23:15 dbg
-.\" Created.
-.\" [90/08/30 dbg]
-.\"
.\" $FreeBSD$
.\"
-.Dd October 10, 2019
+.Dd October 17, 2019
.Dt DDB 4
.Os
.Sh NAME
@@ -212,7 +178,12 @@
browse through the history buffer, and move the cursor within the
current line.
.Sh COMMANDS
+.Ss COMMON DEBUGGER COMMANDS
.Bl -tag -width indent -compact
+.It Ic help
+Print a short summary of the available commands and command
+abbreviations.
+.Pp
.It Xo
.Ic examine Ns Op Li / Ns Cm AISabcdghilmorsuxz ...
.Oo Ar addr Oc Ns Op , Ns Ar count
@@ -396,6 +367,9 @@
to get the default address of
.Va dot .
.Pp
+.It Ic halt
+Halt the system.
+.Pp
.It Ic watch Oo Ar addr Oc Ns Op , Ns Ar size
Set a watchpoint for a region.
Execution stops when an attempt to modify the region occurs.
@@ -429,6 +403,20 @@
.It Ic dhwatch Oo Ar addr Oc Ns Op , Ns Ar size
Delete specified hardware watchpoint.
.Pp
+.It Ic kill Ar sig pid
+Send signal
+.Ar sig
+to process
+.Ar pid .
+The signal is acted on upon returning from the debugger.
+This command can be used to kill a process causing resource contention
+in the case of a hung system.
+See
+.Xr signal 3
+for a list of signals.
+Note that the arguments are reversed relative to
+.Xr kill 2 .
+.Pp
.It Ic step Ns Oo Li / Ns Cm p Oc Ns Op , Ns Ar count
.It Ic s Ns Oo Li / Ns Cm p Oc Ns Op , Ns Ar count
Single step
@@ -529,6 +517,25 @@
argument limits the search.
.\"
.Pp
+.It Ic reboot Op Ar seconds
+.It Ic reset Op Ar seconds
+Hard reset the system.
+If the optional argument
+.Ar seconds
+is given, the debugger will wait for this long, at most a week,
+before rebooting.
+.Pp
+.It Ic thread Ar addr | tid
+Switch the debugger to the thread with ID
+.Ar tid ,
+if the argument is a decimal number, or address
+.Ar addr ,
+otherwise.
+.El
+.Pp
+.Ss SPECIALIZED HELPER COMMANDS
+.Pp
+.Bl -tag -width indent -compact
.It Xo
.Ic findstack
.Ar addr
@@ -1174,47 +1181,36 @@
Shows information about lock acquisition coming from the
.Xr witness 4
subsystem.
-.\"
+.El
.Pp
+.Ss OFFLINE DEBUGGING COMMANDS
+.Bl -tag -width indent -compact
.It Ic gdb
-Toggles between remote GDB and DDB mode.
+Switches to remote GDB mode.
In remote GDB mode, another machine is required that runs
.Xr gdb 1
using the remote debug feature, with a connection to the serial
console port on the target machine.
-Currently only available on the
-i386
-architecture.
.Pp
-.It Ic halt
-Halt the system.
+.It Ic netdump Fl s Ar server Oo Fl g Ar gateway Oc Fl c Ar client Fl i Ar iface
+Configure
+.Xr netdump 4
+with the provided parameters, and immediately perform a netdump.
.Pp
-.It Ic kill Ar sig pid
-Send signal
-.Ar sig
-to process
-.Ar pid .
-The signal is acted on upon returning from the debugger.
-This command can be used to kill a process causing resource contention
-in the case of a hung system.
-See
-.Xr signal 3
-for a list of signals.
-Note that the arguments are reversed relative to
-.Xr kill 2 .
+There are some known limitations.
+Principally,
+.Xr netdump 4
+only supports IPv4 at this time.
+The address arguments to the
+.Ic netdump
+command must be dotted decimal IPv4 addresses.
+(Hostnames are not supported.)
+At present, the command only works if the machine is in a panic state.
+Finally, the
+.Nm
+.Ic netdump
+command does not provide any way to configure compression or encryption.
.Pp
-.It Ic reboot Op Ar seconds
-.It Ic reset Op Ar seconds
-Hard reset the system.
-If the optional argument
-.Ar seconds
-is given, the debugger will wait for this long, at most a week,
-before rebooting.
-.Pp
-.It Ic help
-Print a short summary of the available commands and command
-abbreviations.
-.Pp
.It Ic capture on
.It Ic capture off
.It Ic capture reset
@@ -1286,13 +1282,6 @@
reports whether a textdump has been scheduled.
.Ic textdump unset
cancels a request to perform a textdump as the next kernel core dump.
-.Pp
-.It Ic thread Ar addr | tid
-Switch the debugger to the thread with ID
-.Ar tid ,
-if the argument is a decimal number, or address
-.Ar addr ,
-otherwise.
.El
.Sh VARIABLES
The debugger accesses registers and variables as
Index: head/share/man/man4/netdump.4
===================================================================
--- head/share/man/man4/netdump.4
+++ head/share/man/man4/netdump.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 5, 2018
+.Dd October 17, 2019
.Dt NETDUMP 4
.Os
.Sh NAME
@@ -46,7 +46,10 @@
.Nm
clients are configured using the
.Xr dumpon 8
-utility.
+utility or the
+.Ic netdump
+command in
+.Xr ddb 4 .
.Pp
.Nm
client messages consist of a fixed-size header followed by a variable-sized
Index: head/sys/net/debugnet.h
===================================================================
--- head/sys/net/debugnet.h
+++ head/sys/net/debugnet.h
@@ -173,6 +173,29 @@
*/
void debugnet_any_ifnet_update(struct ifnet *);
+/*
+ * DDB parsing helper for common debugnet options.
+ *
+ * -s <server> [-g <gateway] -c <localip> -i <interface>
+ *
+ * Order is not significant. Interface is an online interface that supports
+ * debugnet and can route to the debugnet server. The other parameters are all
+ * IP addresses. For now, all parameters are mandatory, except gateway.
+ *
+ * Provides basic '-h' using provided 'cmd' string.
+ *
+ * Returns zero on success, or errno.
+ */
+struct debugnet_ddb_config {
+ struct ifnet *dd_ifp; /* not ref'd */
+ in_addr_t dd_client;
+ in_addr_t dd_server;
+ in_addr_t dd_gateway;
+ bool dd_has_gateway : 1;
+};
+int debugnet_parse_ddb_cmd(const char *cmd,
+ struct debugnet_ddb_config *result);
+
/* Expose sysctl variables for netdump(4) to alias. */
extern int debugnet_npolls;
extern int debugnet_nretries;
Index: head/sys/net/debugnet.c
===================================================================
--- head/sys/net/debugnet.c
+++ head/sys/net/debugnet.c
@@ -31,6 +31,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_ddb.h"
#include "opt_inet.h"
#include <sys/param.h>
@@ -40,6 +41,11 @@
#include <sys/socket.h>
#include <sys/sysctl.h>
+#ifdef DDB
+#include <ddb/ddb.h>
+#include <ddb/db_lex.h>
+#endif
+
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -654,3 +660,223 @@
dn_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
}
SYSINIT(dn_evh_init, SI_SUB_EVENTHANDLER + 1, SI_ORDER_ANY, dn_evh_init, NULL);
+
+/*
+ * DDB parsing helpers for debugnet(4) consumers.
+ */
+#ifdef DDB
+struct my_inet_opt {
+ bool has_opt;
+ const char *printname;
+ in_addr_t *result;
+};
+
+static int
+dn_parse_optarg_ipv4(struct my_inet_opt *opt)
+{
+ in_addr_t tmp;
+ unsigned octet;
+ int t;
+
+ tmp = 0;
+ for (octet = 0; octet < 4; octet++) {
+ t = db_read_token_flags(DRT_WSPACE | DRT_DECIMAL);
+ if (t != tNUMBER) {
+ db_printf("%s:%s: octet %u expected number; found %d\n",
+ __func__, opt->printname, octet, t);
+ return (EINVAL);
+ }
+ /*
+ * db_lex lexes '-' distinctly from the number itself, but
+ * let's document that invariant.
+ */
+ MPASS(db_tok_number >= 0);
+
+ if (db_tok_number > UINT8_MAX) {
+ db_printf("%s:%s: octet %u out of range: %jd\n", __func__,
+ opt->printname, octet, (intmax_t)db_tok_number);
+ return (EDOM);
+ }
+
+ /* Constructed host-endian and converted to network later. */
+ tmp = (tmp << 8) | db_tok_number;
+
+ if (octet < 3) {
+ t = db_read_token_flags(DRT_WSPACE);
+ if (t != tDOT) {
+ db_printf("%s:%s: octet %u expected '.'; found"
+ " %d\n", __func__, opt->printname, octet,
+ t);
+ return (EINVAL);
+ }
+ }
+ }
+
+ *opt->result = htonl(tmp);
+ opt->has_opt = true;
+ return (0);
+}
+
+int
+debugnet_parse_ddb_cmd(const char *cmd, struct debugnet_ddb_config *result)
+{
+ struct ifnet *ifp;
+ int t, error;
+ bool want_ifp;
+ char ch;
+
+ struct my_inet_opt opt_client = {
+ .printname = "client",
+ .result = &result->dd_client,
+ },
+ opt_server = {
+ .printname = "server",
+ .result = &result->dd_server,
+ },
+ opt_gateway = {
+ .printname = "gateway",
+ .result = &result->dd_gateway,
+ },
+ *cur_inet_opt;
+
+ ifp = NULL;
+ memset(result, 0, sizeof(*result));
+
+ /*
+ * command [space] [-] [opt] [[space] [optarg]] ...
+ *
+ * db_command has already lexed 'command' for us.
+ */
+ t = db_read_token_flags(DRT_WSPACE);
+ if (t == tWSPACE)
+ t = db_read_token_flags(DRT_WSPACE);
+
+ while (t != tEOL) {
+ if (t != tMINUS) {
+ db_printf("%s: Bad syntax; expected '-', got %d\n",
+ cmd, t);
+ goto usage;
+ }
+
+ t = db_read_token_flags(DRT_WSPACE);
+ if (t != tIDENT) {
+ db_printf("%s: Bad syntax; expected tIDENT, got %d\n",
+ cmd, t);
+ goto usage;
+ }
+
+ if (strlen(db_tok_string) > 1) {
+ db_printf("%s: Bad syntax; expected single option "
+ "flag, got '%s'\n", cmd, db_tok_string);
+ goto usage;
+ }
+
+ want_ifp = false;
+ cur_inet_opt = NULL;
+ switch ((ch = db_tok_string[0])) {
+ default:
+ DNETDEBUG("Unexpected: '%c'\n", ch);
+ /* FALLTHROUGH */
+ case 'h':
+ goto usage;
+ case 'c':
+ cur_inet_opt = &opt_client;
+ break;
+ case 'g':
+ cur_inet_opt = &opt_gateway;
+ break;
+ case 's':
+ cur_inet_opt = &opt_server;
+ break;
+ case 'i':
+ want_ifp = true;
+ break;
+ }
+
+ t = db_read_token_flags(DRT_WSPACE);
+ if (t != tWSPACE) {
+ db_printf("%s: Bad syntax; expected space after "
+ "flag %c, got %d\n", cmd, ch, t);
+ goto usage;
+ }
+
+ if (want_ifp) {
+ t = db_read_token_flags(DRT_WSPACE);
+ if (t != tIDENT) {
+ db_printf("%s: Expected interface but got %d\n",
+ cmd, t);
+ goto usage;
+ }
+
+ CURVNET_SET(vnet0);
+ /*
+ * We *don't* take a ref here because the only current
+ * consumer, db_netdump_cmd, does not need it. It
+ * (somewhat redundantly) extracts the if_name(),
+ * re-lookups the ifp, and takes its own reference.
+ */
+ ifp = ifunit(db_tok_string);
+ CURVNET_RESTORE();
+ if (ifp == NULL) {
+ db_printf("Could not locate interface %s\n",
+ db_tok_string);
+ goto cleanup;
+ }
+ } else {
+ MPASS(cur_inet_opt != NULL);
+ /* Assume IPv4 for now. */
+ error = dn_parse_optarg_ipv4(cur_inet_opt);
+ if (error != 0)
+ goto cleanup;
+ }
+
+ /* Skip (mandatory) whitespace after option, if not EOL. */
+ t = db_read_token_flags(DRT_WSPACE);
+ if (t == tEOL)
+ break;
+ if (t != tWSPACE) {
+ db_printf("%s: Bad syntax; expected space after "
+ "flag %c option; got %d\n", cmd, ch, t);
+ goto usage;
+ }
+ t = db_read_token_flags(DRT_WSPACE);
+ }
+
+ /* Currently, all three are required. */
+ if (!opt_client.has_opt || !opt_server.has_opt || ifp == NULL) {
+ db_printf("%s needs all of client, server, and interface "
+ "specified.\n", cmd);
+ goto usage;
+ }
+
+ result->dd_has_gateway = opt_gateway.has_opt;
+
+ /* Iface validation stolen from netdump_configure. */
+ if (!DEBUGNET_SUPPORTED_NIC(ifp)) {
+ db_printf("%s: interface '%s' does not support debugnet\n",
+ cmd, if_name(ifp));
+ error = ENODEV;
+ goto cleanup;
+ }
+ if ((if_getflags(ifp) & IFF_UP) == 0) {
+ db_printf("%s: interface '%s' link is down\n", cmd,
+ if_name(ifp));
+ error = ENXIO;
+ goto cleanup;
+ }
+
+ result->dd_ifp = ifp;
+
+ /* We parsed the full line to tEOL already, or bailed with an error. */
+ return (0);
+
+usage:
+ db_printf("Usage: %s -s <server> [-g <gateway>] -c <localip> "
+ "-i <interface>\n", cmd);
+ error = EINVAL;
+ /* FALLTHROUGH */
+cleanup:
+ db_skip_to_eol();
+ return (error);
+}
+#endif /* DDB */
Index: head/sys/netinet/netdump/netdump_client.c
===================================================================
--- head/sys/netinet/netdump/netdump_client.c
+++ head/sys/netinet/netdump/netdump_client.c
@@ -34,6 +34,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_ddb.h"
+
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/disk.h>
@@ -52,6 +54,11 @@
#include <sys/syslog.h>
#include <sys/systm.h>
+#ifdef DDB
+#include <ddb/ddb.h>
+#include <ddb/db_lex.h>
+#endif
+
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -387,15 +394,24 @@
NETDUMP_WUNLOCK();
}
+/*
+ * td of NULL is a sentinel value that indicates a kernel caller (ddb(4) or
+ * modload-based tunable parameters).
+ */
static int
netdump_configure(struct diocskerneldump_arg *conf, struct thread *td)
{
struct ifnet *ifp;
+ struct vnet *vnet;
NETDUMP_ASSERT_WLOCKED();
- CURVNET_SET(TD_TO_VNET(td));
- if (!IS_DEFAULT_VNET(curvnet)) {
+ if (td != NULL)
+ vnet = TD_TO_VNET(td);
+ else
+ vnet = vnet0;
+ CURVNET_SET(vnet);
+ if (td != NULL && !IS_DEFAULT_VNET(curvnet)) {
CURVNET_RESTORE();
return (EINVAL);
}
@@ -699,7 +715,7 @@
/* Ignore errors; we print a message to the console. */
NETDUMP_WLOCK();
- (void)netdump_configure(&conf, curthread);
+ (void)netdump_configure(&conf, NULL);
NETDUMP_WUNLOCK();
}
break;
@@ -729,3 +745,72 @@
MODULE_VERSION(netdump, 1);
DECLARE_MODULE(netdump, netdump_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
+
+#ifdef DDB
+/*
+ * Usage: netdump -s <server> [-g <gateway] -c <localip> -i <interface>
+ *
+ * Order is not significant.
+ *
+ * Currently, this command does not support configuring encryption or
+ * compression.
+ */
+DB_FUNC(netdump, db_netdump_cmd, db_cmd_table, CS_OWN, NULL)
+{
+ static struct diocskerneldump_arg conf;
+ static char blockbuf[NETDUMP_DATASIZE];
+ static union {
+ struct dumperinfo di;
+ /* For valid di_devname. */
+ char di_buf[sizeof(struct dumperinfo) + 1];
+ } u;
+
+ struct debugnet_ddb_config params;
+ int error;
+
+ error = debugnet_parse_ddb_cmd("netdump", &params);
+ if (error != 0) {
+ db_printf("Error configuring netdump: %d\n", error);
+ return;
+ }
+
+ /* Translate to a netdump dumper config. */
+ memset(&conf, 0, sizeof(conf));
+ strlcpy(conf.kda_iface, if_name(params.dd_ifp), sizeof(conf.kda_iface));
+
+ conf.kda_af = AF_INET;
+ conf.kda_server.in4 = (struct in_addr) { params.dd_server };
+ conf.kda_client.in4 = (struct in_addr) { params.dd_client };
+ if (params.dd_has_gateway)
+ conf.kda_gateway.in4 = (struct in_addr) { params.dd_gateway };
+ else
+ conf.kda_gateway.in4 = (struct in_addr) { INADDR_ANY };
+
+ /* Set the global netdump config to these options. */
+ error = netdump_configure(&conf, NULL);
+ if (error != 0) {
+ db_printf("Error enabling netdump: %d\n", error);
+ return;
+ }
+
+ /* Fake the generic dump configuration list entry to avoid malloc. */
+ memset(&u.di_buf, 0, sizeof(u.di_buf));
+ u.di.dumper_start = netdump_start;
+ u.di.dumper_hdr = netdump_write_headers;
+ u.di.dumper = netdump_dumper;
+ u.di.priv = NULL;
+ u.di.blocksize = NETDUMP_DATASIZE;
+ u.di.maxiosize = MAXDUMPPGS * PAGE_SIZE;
+ u.di.mediaoffset = 0;
+ u.di.mediasize = 0;
+ u.di.blockbuf = blockbuf;
+
+ dumper_ddb_insert(&u.di);
+
+ error = doadump(false);
+
+ dumper_ddb_remove(&u.di);
+ if (error != 0)
+ db_printf("Cannot dump: %d\n", error);
+}
+#endif /* DDB */

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 16, 6:44 AM (13 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16670366
Default Alt Text
D21460.diff (15 KB)

Event Timeline