Mercurial > illumos > illumos-gate
changeset 10377:596c39d50e2a
6752302 in.mpathd needs non-blocking ICMP probe sockets
author | George Shepherd <George.Shepherd@Sun.COM> |
---|---|
date | Tue, 25 Aug 2009 08:25:56 -0700 |
parents | 803e1af65252 |
children | bca9668e9ba5 |
files | usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_probe.c usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_tables.c |
diffstat | 2 files changed, 46 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_probe.c Tue Aug 25 09:49:46 2009 +0800 +++ b/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_probe.c Tue Aug 25 08:25:56 2009 -0700 @@ -1,4 +1,3 @@ - /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. @@ -221,7 +220,8 @@ struct sockaddr_storage targ; /* target address */ uint_t targaddrlen; /* targed address length */ int pr_ndx; /* probe index in pii->pii_probes[] */ - boolean_t sent = _B_TRUE; + boolean_t sent = _B_FALSE; + int rval; if (debug & D_TARGET) { logdebug("probe(%s %s %d %lld)\n", AF_STR(pii->pii_af), @@ -297,10 +297,19 @@ */ sent_hrtime = gethrtime(); (void) gettimeofday(&sent_tv, NULL); - if (sendto(pii->pii_probe_sock, &probe_pkt, sizeof (probe_pkt), 0, - (struct sockaddr *)&targ, targaddrlen) != sizeof (probe_pkt)) { + rval = sendto(pii->pii_probe_sock, &probe_pkt, sizeof (probe_pkt), 0, + (struct sockaddr *)&targ, targaddrlen); + /* + * If the send would block, this may either be transient or a hang in a + * lower layer. We pretend the probe was actually sent, the daemon will + * not see a reply to the probe and will fail the interface if normal + * failure detection criteria are met. + */ + if (rval == sizeof (probe_pkt) || + (rval == -1 && errno == EWOULDBLOCK)) { + sent = _B_TRUE; + } else { logperror_pii(pii, "probe: probe sendto"); - sent = _B_FALSE; } /*
--- a/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_tables.c Tue Aug 25 09:49:46 2009 +0800 +++ b/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_tables.c Tue Aug 25 08:25:56 2009 -0700 @@ -863,6 +863,7 @@ int off = 0; int on = 1; struct sockaddr_in6 testaddr; + int flags; /* * Open a raw socket with ICMPv6 protocol. @@ -881,6 +882,21 @@ return (_B_FALSE); } + /* + * Probes must not block in case of lower layer issues. + */ + if ((flags = fcntl(pii->pii_probe_sock, F_GETFL, 0)) == -1) { + logperror_pii(pii, "phyint_inst_v6_sockinit: fcntl" + " F_GETFL"); + return (_B_FALSE); + } + if (fcntl(pii->pii_probe_sock, F_SETFL, + flags | O_NONBLOCK) == -1) { + logperror_pii(pii, "phyint_inst_v6_sockinit: fcntl" + " F_SETFL O_NONBLOCK"); + return (_B_FALSE); + } + bzero(&testaddr, sizeof (testaddr)); testaddr.sin6_family = AF_INET6; testaddr.sin6_port = 0; @@ -971,6 +987,7 @@ int ttl = 1; char char_ttl = 1; int on = 1; + int flags; /* * Open a raw socket with ICMPv4 protocol. @@ -988,6 +1005,21 @@ return (_B_FALSE); } + /* + * Probes must not block in case of lower layer issues. + */ + if ((flags = fcntl(pii->pii_probe_sock, F_GETFL, 0)) == -1) { + logperror_pii(pii, "phyint_inst_v4_sockinit: fcntl" + " F_GETFL"); + return (_B_FALSE); + } + if (fcntl(pii->pii_probe_sock, F_SETFL, + flags | O_NONBLOCK) == -1) { + logperror_pii(pii, "phyint_inst_v4_sockinit: fcntl" + " F_SETFL O_NONBLOCK"); + return (_B_FALSE); + } + bzero(&testaddr, sizeof (testaddr)); testaddr.sin_family = AF_INET; testaddr.sin_port = 0;