svn commit: r217781 - projects/sv/sys/netinet
Attilio Rao
attilio at FreeBSD.org
Mon Jan 24 14:45:17 UTC 2011
Author: attilio
Date: Mon Jan 24 14:45:16 2011
New Revision: 217781
URL: http://svn.freebsd.org/changeset/base/217781
Log:
Perform the dumping ifp lookup differently:
- The string name of the interface is stored in a global array
- On dumping activity the lookup is performed and the ifp pointer is
eventually found and used
That makes the sysclt_nic() unuseful and it can be removed.
Additively, use s/strcmp/strncmp in another place, besides new lookup
point.
That action makes the window for races narrower.
Requested by and discussed with: rwatson
Modified:
projects/sv/sys/netinet/netdump_client.c
Modified: projects/sv/sys/netinet/netdump_client.c
==============================================================================
--- projects/sv/sys/netinet/netdump_client.c Mon Jan 24 14:24:10 2011 (r217780)
+++ projects/sv/sys/netinet/netdump_client.c Mon Jan 24 14:45:16 2011 (r217781)
@@ -115,7 +115,6 @@ static int netdump_udp_output(struct mb
static int sysctl_force_crash(SYSCTL_HANDLER_ARGS);
#endif
static int sysctl_handle_inaddr(SYSCTL_HANDLER_ARGS);
-static int sysctl_nic(SYSCTL_HANDLER_ARGS);
static eventhandler_tag nd_tag = NULL; /* record of our shutdown event */
static uint32_t nd_seqno = 1; /* current sequence number */
@@ -128,6 +127,7 @@ static unsigned char buf[MAXDUMPPGS*PAGE
static struct ether_addr nd_gw_mac;
static int nd_enable = 0; /* if we should perform a network dump */
+static char nd_ifp_str[IFNAMSIZ]; /* String rappresenting the interface */
static struct in_addr nd_server = {INADDR_ANY}; /* server address */
static struct in_addr nd_client = {INADDR_ANY}; /* client (our) address */
static struct in_addr nd_gw = {INADDR_ANY}; /* gw, if set */
@@ -194,66 +194,6 @@ sysctl_handle_inaddr(SYSCTL_HANDLER_ARGS
return (error);
}
-/*
- * [sysctl_nic]
- *
- * sysctl handler to deal with converting a string sysctl to/from an interface
- *
- * Parameters:
- * SYSCTL_HANDLER_ARGS
- * - arg1 is a pointer to the struct ifnet to the interface
- * - arg2 is the maximum string length (IFNAMSIZ)
- *
- * Returns:
- * int see errno.h, 0 for success
- */
-static int
-sysctl_nic(SYSCTL_HANDLER_ARGS)
-{
- struct ifnet *ifp;
- char buf[arg2+1];
- int error;
- int len;
- int invalid;
-
- invalid = 0;
- if (*(struct ifnet **)arg1) {
- error = SYSCTL_OUT(req,
- (*(struct ifnet **)arg1)->if_xname,
- strlen((*(struct ifnet **)arg1)->if_xname));
- } else
- invalid = 1;
-
- if (error || !req->newptr)
- return error;
-
- len = req->newlen - req->newidx;
- if (len >= arg2) {
- error = EINVAL;
- } else {
- if (invalid != 0)
- ifp = NULL;
- else {
- error = SYSCTL_IN(req, buf, len);
- buf[len]='\0';
- if (error)
- return error;
- IFNET_RLOCK_NOSLEEP();
- if ((ifp = TAILQ_FIRST(&V_ifnet)) != NULL) do {
- if (!strcmp(ifp->if_xname, buf)) break;
- } while ((ifp = TAILQ_NEXT(ifp, if_link)) != NULL);
- IFNET_RUNLOCK_NOSLEEP();
-
- if (!ifp) return ENODEV;
- if (!netdump_supported_nic(ifp)) return EINVAL;
- }
-
- (*(struct ifnet **)arg1) = ifp;
- }
-
- return error;
-}
-
#ifdef NETDUMP_CLIENT_DEBUG
static int
sysctl_force_crash(SYSCTL_HANDLER_ARGS)
@@ -296,8 +236,8 @@ SYSCTL_PROC(_net_dump, OID_AUTO, client,
0, sysctl_handle_inaddr, "A", "dump client");
SYSCTL_PROC(_net_dump, OID_AUTO, gateway, CTLTYPE_STRING|CTLFLAG_RW, &nd_gw,
0, sysctl_handle_inaddr, "A", "dump default gateway");
-SYSCTL_PROC(_net_dump, OID_AUTO, nic, CTLTYPE_STRING|CTLFLAG_RW, &nd_ifp,
- IFNAMSIZ, sysctl_nic, "A", "NIC to dump on");
+SYSCTL_STRING(_net_dump, OID_AUTO, nic, CTLFLAG_RW, nd_ifp_str,
+ sizeof(nd_ifp_str), "dumping interface string");
SYSCTL_INT(_net_dump, OID_AUTO, polls, CTLTYPE_INT|CTLFLAG_RW, &nd_polls, 0,
"times to poll NIC per retry");
SYSCTL_INT(_net_dump, OID_AUTO, retries, CTLTYPE_INT|CTLFLAG_RW, &nd_retries, 0,
@@ -415,6 +355,8 @@ netdump_udp_output(struct mbuf *m)
struct udpiphdr *ui;
struct ip *ip;
+ MPASS(nd_ifp != NULL);
+
M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
if (m == 0) {
printf("netdump_udp_output: Out of mbufs\n");
@@ -476,6 +418,8 @@ netdump_send_arp()
struct arphdr *ah;
struct ether_addr bcast;
+ MPASS(nd_ifp != NULL);
+
/* Fill-up a broadcast address. */
memset(&bcast, 0xFF, ETHER_ADDR_LEN);
MGETHDR(m, M_DONTWAIT, MT_DATA);
@@ -567,6 +511,8 @@ netdump_send(uint32_t type, off_t offset
rcvd_acks = 0;
+ MPASS(nd_ifp != NULL);
+
retransmit:
/* We might get chunks too big to fit in packets. Yuck. */
for (i=sent_so_far=0; sent_so_far < datalen || (i==0 && datalen==0);
@@ -1051,6 +997,8 @@ static void
netdump_network_poll()
{
+ MPASS(nd_ifp != NULL);
+
#if defined(KDB) && !defined(KDB_UNATTENDED)
if (panicstr != NULL)
nd_ifp->if_ndumpfuncs->ne_poll_unlocked(nd_ifp,
@@ -1135,15 +1083,34 @@ netdump_trigger(void *arg, int howto)
{
struct dumperinfo dumper;
void (*old_if_input)(struct ifnet *, struct mbuf *)=NULL;
+ int found;
if ((howto&(RB_HALT|RB_DUMP))!=RB_DUMP || !nd_enable || cold ||
dumping)
return;
- if (!nd_ifp) {
- printf("netdump_trigger: Can't netdump: no NIC given\n");
+ found = 0;
+#if defined(KDB) && !defined(KDB_UNATTENDED)
+ if (panicstr == NULL)
+#endif
+ IFNET_RLOCK_NOSLEEP();
+ TAILQ_FOREACH(nd_ifp, &V_ifnet, if_link) {
+ if (!strncmp(nd_ifp->if_xname, nd_ifp_str,
+ strlen(nd_ifp->if_xname))) {
+ found = 1;
+ break;
+ }
+ }
+#if defined(KDB) && !defined(KDB_UNATTENDED)
+ if (panicstr == NULL)
+#endif
+ IFNET_RUNLOCK_NOSLEEP();
+
+ if (found == 0) {
+ printf("netdump_trigger: Can't netdump: no valid NIC given\n");
return;
}
+ MPASS(nd_ifp != NULL);
if (nd_server.s_addr == INADDR_ANY) {
printf("netdump_trigger: Can't netdump; no server IP given\n");
@@ -1274,7 +1241,8 @@ netdump_config_defaults()
found = 0;
IFNET_RLOCK_NOSLEEP();
TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
- if (!strcmp(ifp->if_xname, nd_nic_tun)) {
+ if (!strncmp(ifp->if_xname, nd_nic_tun,
+ strlen(ifp->if_xname))) {
found = 1;
break;
}
More information about the svn-src-projects
mailing list