Date: Tue, 12 Apr 2011 17:02:40 +0000 (UTC) From: Attilio Rao <attilio@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r220572 - in projects/sv/sys: kern netinet sys Message-ID: <201104121702.p3CH2eH6030495@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: attilio Date: Tue Apr 12 17:02:40 2011 New Revision: 220572 URL: http://svn.freebsd.org/changeset/base/220572 Log: - Integrate netdump better in the shutdown code: * Invoke netdump handler directly from doadump(). * Remove checks replication and export of typically static variables - Remove module handler for netdump and provide a SYSINIT() wrap for netdump_config() - Revert some change for de-staticizing dumppcb and dumptid Tested by: pluknet Modified: projects/sv/sys/kern/kern_shutdown.c projects/sv/sys/netinet/netdump.h projects/sv/sys/netinet/netdump_client.c projects/sv/sys/sys/conf.h Modified: projects/sv/sys/kern/kern_shutdown.c ============================================================================== --- projects/sv/sys/kern/kern_shutdown.c Tue Apr 12 16:52:05 2011 (r220571) +++ projects/sv/sys/kern/kern_shutdown.c Tue Apr 12 17:02:40 2011 (r220572) @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include "opt_ddb.h" #include "opt_kdb.h" +#include "opt_netdump.h" #include "opt_panic.h" #include "opt_show_busybufs.h" #include "opt_sched.h" @@ -80,6 +81,15 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_pager.h> #include <vm/swap_pager.h> +#ifdef NETDUMP_CLIENT +#include <sys/socket.h> + +#include <net/if.h> +#include <net/if_var.h> + +#include <netinet/netdump.h> +#endif + #include <sys/signalvar.h> #ifndef PANIC_REBOOT_WAIT_TIME @@ -130,8 +140,8 @@ int rebooting; /* system is rebooting static struct dumperinfo dumper; /* our selected dumper */ /* Context information for dump-debuggers. */ -struct pcb dumppcb; /* Registers. */ -lwpid_t dumptid; /* Thread ID. */ +static struct pcb dumppcb; /* Registers. */ +static lwpid_t dumptid; /* Thread ID. */ static void poweroff_wait(void *, int); static void shutdown_halt(void *junk, int howto); @@ -233,19 +243,38 @@ static void doadump(void) { + savectx(&dumppcb); + dumptid = curthread->td_tid; + dumping++; + +#ifdef NETDUMP_CLIENT + /* + * If netdump finished successfully just return, otherwise give + * traditional disk dumping a chance. + * + * Avoid a POLA breakage by skipping netdump when calling it from + * within KDB. That may change in the future. + */ +#ifdef KDB + if (kdb_why == KDB_WHY_UNSET) +#endif + if (netdumpsys() == 0) { + dumping--; + return; + } +#endif + /* * Sometimes people have to call this from the kernel debugger. * (if 'panic' can not dump) * Give them a clue as to why they can't dump. */ if (dumper.dumper == NULL) { + dumping--; printf("Cannot dump. Device not defined or unavailable.\n"); return; } - savectx(&dumppcb); - dumptid = curthread->td_tid; - dumping++; #ifdef DDB if (textdump_pending) textdump_dumpsys(&dumper); Modified: projects/sv/sys/netinet/netdump.h ============================================================================== --- projects/sv/sys/netinet/netdump.h Tue Apr 12 16:52:05 2011 (r220571) +++ projects/sv/sys/netinet/netdump.h Tue Apr 12 17:02:40 2011 (r220572) @@ -70,6 +70,8 @@ struct netdump_methods { ndumplock_handler_t *ne_enable_intr; }; +int netdumpsys(void); + #endif #endif /* !_NETINET_NETDUMP_H_ */ Modified: projects/sv/sys/netinet/netdump_client.c ============================================================================== --- projects/sv/sys/netinet/netdump_client.c Tue Apr 12 16:52:05 2011 (r220571) +++ projects/sv/sys/netinet/netdump_client.c Tue Apr 12 17:02:40 2011 (r220572) @@ -24,10 +24,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + /* * netdump_client.c - * FreeBSD kernel module supporting netdump network dumps. - * netdump_server must be running to accept client dumps. + * FreeBSD subsystem supporting netdump network dumps. + * A dedicated server must be running to accept client dumps. * XXX: This should be split into machdep and non-machdep parts * */ @@ -98,19 +99,17 @@ __FBSDID("$FreeBSD$"); static void nd_handle_arp(struct mbuf **mb); static void nd_handle_ip(struct mbuf **mb); static int netdump_arp_server(void); -static void netdump_config_defaults(void); +static void netdump_config_defaults(void *dummy __unused); static int netdump_dumper(void *priv __unused, void *virtual, vm_offset_t physical __unused, off_t offset, size_t length); static int netdump_ether_output(struct mbuf *m, struct ifnet *ifp, struct ether_addr dst, u_short etype); static void netdump_mbuf_nop(void *ptr __unused, void *opt_args __unused); -static int netdump_modevent(module_t mod, int type, void *unused); static void netdump_network_poll(void); static void netdump_pkt_in(struct ifnet *ifp, struct mbuf *m); static int netdump_send(uint32_t type, off_t offset, unsigned char *data, uint32_t datalen); static int netdump_send_arp(void); -static void netdump_trigger(void *arg, int howto); static int netdump_udp_output(struct mbuf *m); static int sysctl_handle_ifxname(SYSCTL_HANDLER_ARGS); @@ -118,7 +117,6 @@ static int sysctl_handle_inaddr(SYSCTL_ /* Must be at least as big as the chunks dumpsys() gives us. */ static unsigned char buf[MAXDUMPPGS * PAGE_SIZE]; -static eventhandler_tag nd_tag; static uint64_t rcvd_acks; static uint32_t nd_seqno = 1; static int dump_failed, have_server_mac; @@ -1034,24 +1032,23 @@ netdump_dumper(void *priv __unused, void } /* - * Handler going into shutdown_pre_sync hook. - * Overrides a standard disk dumping activity. + * Dumper routine, specular to dumpsys(). * * Parameters: - * arg unused - * howto boot flags (only dump if RB_DUMP set) + * void * * Returns: - * void + * int see errno.h, 0 for success */ -static void -netdump_trigger(void *arg, int howto) +int +netdumpsys() { struct dumperinfo dumper; void (*old_if_input)(struct ifnet *, struct mbuf *); - int found, must_lock, nd_gw_unset; + int error, found, must_lock, nd_gw_unset; old_if_input = NULL; + error = 0; found = 0; nd_gw_unset = 0; must_lock = 1; @@ -1061,9 +1058,8 @@ netdump_trigger(void *arg, int howto) #endif /* Check if the dumping is allowed to continue. */ - if ((howto & (RB_HALT | RB_DUMP)) != RB_DUMP || nd_enable == 0 || - cold != 0 || dumping != 0) - return; + if (nd_enable == 0) + return (EINVAL); /* Lookup the right if device to be used in the dump. */ if (must_lock != 0) @@ -1079,35 +1075,22 @@ netdump_trigger(void *arg, int howto) if (must_lock != 0) IFNET_RUNLOCK_NOSLEEP(); if (found == 0) { - printf("netdump_trigger: Can't netdump: no valid NIC given\n"); - return; + printf("netdumpsys: Can't netdump: no valid NIC given\n"); + return (EINVAL); } MPASS(nd_ifp != NULL); if (nd_server.s_addr == INADDR_ANY) { - printf("netdump_trigger: Can't netdump; no server IP given\n"); - return; + printf("netdumpsys: Can't netdump; no server IP given\n"); + return (EINVAL); } if (nd_client.s_addr == INADDR_ANY) { - printf("netdump_trigger: Can't netdump; no client IP given\n"); - return; + printf("netdumpsys: Can't netdump; no client IP given\n"); + return (EINVAL); } /* - * netdump is invoked as a pre-sync handler instead of as - * a real dumpdev dump routine (that is because shutdown handlers - * run as post-sync handlers, earlier than dumping routines - * taking place, and thus network and devices may not be further - * available). - * Make sure, artificially, the dump context is set so a debugger - * can find the stack trace. - */ - savectx(&dumppcb); - dumptid = curthread->td_tid; - dumping++; - - /* * nd_server_port could have switched after the first ack the * first time it gets called. Adjust it accordingly. */ @@ -1127,10 +1110,12 @@ netdump_trigger(void *arg, int howto) printf("netdump in progress. searching for server.. "); if (netdump_arp_server()) { printf("Failed to locate server MAC address\n"); + error = EINVAL; goto trig_abort; } if (netdump_send(NETDUMP_HERALD, 0, NULL, 0) != 0) { printf("Failed to contact netdump server\n"); + error = EINVAL; goto trig_abort; } printf("dumping to %s (%6D)\n", inet_ntoa(nd_server), nd_gw_mac.octet, @@ -1146,15 +1131,15 @@ netdump_trigger(void *arg, int howto) dumpsys(&dumper); if (dump_failed != 0) { printf("Failed to dump the actual raw datas\n"); + error = EINVAL; goto trig_abort; } if (netdump_send(NETDUMP_FINISHED, 0, NULL, 0) != 0) { printf("Failed to close the transaction\n"); + error = EINVAL; goto trig_abort; } printf("\nnetdump finished.\n"); - printf("cancelling normal dump\n"); - set_dumper(NULL); trig_abort: if (nd_gw_unset != 0) nd_gw.s_addr = INADDR_ANY; @@ -1162,7 +1147,7 @@ trig_abort: nd_ifp->if_input = old_if_input; if ((nd_ifp->if_capenable & IFCAP_POLLING) == 0 && must_lock != 0) nd_ifp->if_ndumpfuncs->ne_enable_intr(nd_ifp); - dumping--; + return (error); } /*- @@ -1170,18 +1155,18 @@ trig_abort: */ /* - * Called upon module load. Initializes the sysctl variables to sane defaults + * Called upon system init. Initializes the sysctl variables to sane defaults * (locates the first available NIC and uses the first IPv4 IP on that card as * the client IP). Leaves the server IP unconfigured. * * Parameters: - * void + * void *, unused * * Returns: * void */ static void -netdump_config_defaults() +netdump_config_defaults(void *dummy __unused) { struct ifnet *ifp; int found; @@ -1212,51 +1197,12 @@ netdump_config_defaults() nd_ifp = ifp; } } - -static int -netdump_modevent(module_t mod, int type, void *unused) -{ -#ifdef NETDUMP_CLIENT_DEBUG - char buf[INET_ADDRSTRLEN]; -#endif - - switch (type) { - case MOD_LOAD: - netdump_config_defaults(); - nd_tag = EVENTHANDLER_REGISTER(shutdown_pre_sync, - netdump_trigger, NULL, SHUTDOWN_PRI_FIRST); - -#ifdef NETDUMP_CLIENT_DEBUG - if (nd_ifp == NULL) { - printf("netdump: Warning: No default interface found."); - printf("Manual configuration required.\n"); - } else { - inet_ntoa_r(nd_client, buf); - printf("netdump: Using interface %s; client IP %s\n", - nd_ifp->if_xname, buf); - } -#endif - printf("netdump initialized\n"); - break; - case MOD_UNLOAD: - if (nd_tag != NULL) { - EVENTHANDLER_DEREGISTER(shutdown_pre_sync, nd_tag); - nd_tag = NULL; - } - printf("netdump unloaded\n"); - break; - default: - break; - } - return (0); -} -static moduledata_t netdump_mod = {"netdump", netdump_modevent, 0}; -DECLARE_MODULE(netdump, netdump_mod, SI_SUB_PROTO_END, SI_ORDER_ANY); +SYSINIT(netdump, SI_SUB_KLD, SI_ORDER_ANY, netdump_config_defaults, NULL); #ifdef DDB DB_COMMAND(netdump, ddb_force_netdump) { - netdump_trigger(NULL, RB_DUMP); + netdumpsys(); } #endif Modified: projects/sv/sys/sys/conf.h ============================================================================== --- projects/sv/sys/sys/conf.h Tue Apr 12 16:52:05 2011 (r220571) +++ projects/sv/sys/sys/conf.h Tue Apr 12 17:02:40 2011 (r220572) @@ -330,10 +330,7 @@ struct dumperinfo { int set_dumper(struct dumperinfo *); int dump_write(struct dumperinfo *, void *, vm_offset_t, off_t, size_t); void dumpsys(struct dumperinfo *); - -extern int dumping; -extern struct pcb dumppcb; -extern lwpid_t dumptid; +extern int dumping; /* system is dumping */ #endif /* _KERNEL */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104121702.p3CH2eH6030495>