Sat Nov 7 17:34:33 2015 UTC ()
check for errors and recover instead of core-dumping.


(christos)
diff -r1.35 -r1.36 src/lib/libc/rpc/svc.c
diff -r1.23 -r1.24 src/lib/libc/rpc/svc_run.c
diff -r1.31 -r1.32 src/lib/libc/rpc/svc_vc.c

cvs diff -r1.35 -r1.36 src/lib/libc/rpc/svc.c (expand / switch to unified diff)

--- src/lib/libc/rpc/svc.c 2015/11/06 19:34:13 1.35
+++ src/lib/libc/rpc/svc.c 2015/11/07 17:34:33 1.36
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: svc.c,v 1.35 2015/11/06 19:34:13 christos Exp $ */ 1/* $NetBSD: svc.c,v 1.36 2015/11/07 17:34:33 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2010, Oracle America, Inc. 4 * Copyright (c) 2010, Oracle America, Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are 7 * modification, are permitted provided that the following conditions are
8 * met: 8 * met:
9 * 9 *
10 * * Redistributions of source code must retain the above copyright 10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above 12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following 13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials 14 * disclaimer in the documentation and/or other materials
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35#if defined(LIBC_SCCS) && !defined(lint)  35#if defined(LIBC_SCCS) && !defined(lint)
36#if 0 36#if 0
37static char *sccsid = "@(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro"; 37static char *sccsid = "@(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";
38static char *sccsid = "@(#)svc.c 2.4 88/08/11 4.0 RPCSRC"; 38static char *sccsid = "@(#)svc.c 2.4 88/08/11 4.0 RPCSRC";
39#else 39#else
40__RCSID("$NetBSD: svc.c,v 1.35 2015/11/06 19:34:13 christos Exp $"); 40__RCSID("$NetBSD: svc.c,v 1.36 2015/11/07 17:34:33 christos Exp $");
41#endif 41#endif
42#endif 42#endif
43 43
44/* 44/*
45 * svc.c, Server-side remote procedure call interface. 45 * svc.c, Server-side remote procedure call interface.
46 * 46 *
47 * There are two sets of procedures here. The xprt routines are 47 * There are two sets of procedures here. The xprt routines are
48 * for handling transport handles. The svc routines handle the 48 * for handling transport handles. The svc routines handle the
49 * list of service routines. 49 * list of service routines.
50 * 50 *
51 * Copyright (C) 1984, Sun Microsystems, Inc. 51 * Copyright (C) 1984, Sun Microsystems, Inc.
52 */ 52 */
53 53
@@ -169,27 +169,28 @@ xprt_register(SVCXPRT *xprt) @@ -169,27 +169,28 @@ xprt_register(SVCXPRT *xprt)
169{ 169{
170 int sock; 170 int sock;
171 171
172 _DIAGASSERT(xprt != NULL); 172 _DIAGASSERT(xprt != NULL);
173 173
174 rwlock_wrlock(&svc_fd_lock); 174 rwlock_wrlock(&svc_fd_lock);
175 sock = xprt->xp_fd; 175 sock = xprt->xp_fd;
176 176
177 if (!xprt_alloc(sock)) 177 if (!xprt_alloc(sock))
178 goto out; 178 goto out;
179 179
180 __svc_xports[sock] = xprt; 180 __svc_xports[sock] = xprt;
181 if (sock != -1) { 181 if (sock != -1) {
182 svc_fdset_set(sock); 182 if (svc_fdset_set(sock) == -1)
 183 return FALSE;
183 } 184 }
184 rwlock_unlock(&svc_fd_lock); 185 rwlock_unlock(&svc_fd_lock);
185 return (TRUE); 186 return (TRUE);
186 187
187out: 188out:
188 rwlock_unlock(&svc_fd_lock); 189 rwlock_unlock(&svc_fd_lock);
189 return (FALSE); 190 return (FALSE);
190} 191}
191 192
192void 193void
193xprt_unregister(SVCXPRT *xprt) 194xprt_unregister(SVCXPRT *xprt)
194{ 195{
195 __xprt_do_unregister(xprt, TRUE); 196 __xprt_do_unregister(xprt, TRUE);
@@ -212,27 +213,27 @@ __xprt_do_unregister(SVCXPRT *xprt, bool @@ -212,27 +213,27 @@ __xprt_do_unregister(SVCXPRT *xprt, bool
212 _DIAGASSERT(xprt != NULL); 213 _DIAGASSERT(xprt != NULL);
213 214
214 if (dolock) 215 if (dolock)
215 rwlock_wrlock(&svc_fd_lock); 216 rwlock_wrlock(&svc_fd_lock);
216 217
217 sock = xprt->xp_fd; 218 sock = xprt->xp_fd;
218 if (sock >= __svc_maxxports || __svc_xports[sock] != xprt) 219 if (sock >= __svc_maxxports || __svc_xports[sock] != xprt)
219 goto out; 220 goto out;
220 221
221 __svc_xports[sock] = NULL; 222 __svc_xports[sock] = NULL;
222 if (sock == -1) 223 if (sock == -1)
223 goto out; 224 goto out;
224 fdmax = svc_fdset_getmax(); 225 fdmax = svc_fdset_getmax();
225 if (sock < *fdmax) 226 if (fdmax == NULL || sock < *fdmax)
226 goto clr; 227 goto clr;
227 228
228 for ((*fdmax)--; *fdmax >= 0; (*fdmax)--) 229 for ((*fdmax)--; *fdmax >= 0; (*fdmax)--)
229 if (__svc_xports[*fdmax]) 230 if (__svc_xports[*fdmax])
230 break; 231 break;
231clr: 232clr:
232 svc_fdset_clr(sock); 233 svc_fdset_clr(sock);
233out: 234out:
234 if (dolock) 235 if (dolock)
235 rwlock_unlock(&svc_fd_lock); 236 rwlock_unlock(&svc_fd_lock);
236} 237}
237 238
238/* 239/*
@@ -624,26 +625,28 @@ svcerr_progvers(SVCXPRT *xprt, rpcvers_t @@ -624,26 +625,28 @@ svcerr_progvers(SVCXPRT *xprt, rpcvers_t
624 * However, this function does not know the structure of the cooked 625 * However, this function does not know the structure of the cooked
625 * credentials, so it make the following assumptions:  626 * credentials, so it make the following assumptions:
626 * a) the structure is contiguous (no pointers), and 627 * a) the structure is contiguous (no pointers), and
627 * b) the cred structure size does not exceed RQCRED_SIZE bytes.  628 * b) the cred structure size does not exceed RQCRED_SIZE bytes.
628 * In all events, all three parameters are freed upon exit from this routine. 629 * In all events, all three parameters are freed upon exit from this routine.
629 * The storage is trivially management on the call stack in user land, but 630 * The storage is trivially management on the call stack in user land, but
630 * is mallocated in kernel land. 631 * is mallocated in kernel land.
631 */ 632 */
632 633
633void 634void
634svc_getreq(int rdfds) 635svc_getreq(int rdfds)
635{ 636{
636 fd_set *readfds = svc_fdset_copy(NULL); 637 fd_set *readfds = svc_fdset_copy(NULL);
 638 if (readfds == NULL)
 639 return;
637 640
638 readfds->fds_bits[0] = (unsigned int)rdfds; 641 readfds->fds_bits[0] = (unsigned int)rdfds;
639 svc_getreqset(readfds); 642 svc_getreqset(readfds);
640 free(readfds); 643 free(readfds);
641} 644}
642 645
643void 646void
644svc_getreqset2(fd_set *readfds, int maxsize) 647svc_getreqset2(fd_set *readfds, int maxsize)
645{ 648{
646 uint32_t mask, *maskp; 649 uint32_t mask, *maskp;
647 int sock, bit, fd; 650 int sock, bit, fd;
648 651
649 _DIAGASSERT(readfds != NULL); 652 _DIAGASSERT(readfds != NULL);
@@ -761,27 +764,27 @@ svc_getreq_poll(struct pollfd *pfdp, int @@ -761,27 +764,27 @@ svc_getreq_poll(struct pollfd *pfdp, int
761 _DIAGASSERT(pfdp != NULL); 764 _DIAGASSERT(pfdp != NULL);
762 765
763 for (i = fds_found = 0; fds_found < pollretval; i++) { 766 for (i = fds_found = 0; fds_found < pollretval; i++) {
764 struct pollfd *p = &pfdp[i]; 767 struct pollfd *p = &pfdp[i];
765 768
766 if (p->revents) { 769 if (p->revents) {
767 /* fd has input waiting */ 770 /* fd has input waiting */
768 fds_found++; 771 fds_found++;
769 /* 772 /*
770 * We assume that this function is only called 773 * We assume that this function is only called
771 * via someone select()ing from svc_fdset or 774 * via someone select()ing from svc_fdset or
772 * pollts()ing from svc_pollset[]. Thus it's safe 775 * pollts()ing from svc_pollset[]. Thus it's safe
773 * to handle the POLLNVAL event by simply turning 776 * to handle the POLLNVAL event by simply turning
774 * the corresponding bit off in svc_fdset. The 777 * the corresponding bit off in the fdset. The
775 * svc_pollset[] array is derived from svc_fdset 778 * svc_pollset[] array is derived from svc_fdset
776 * and so will also be updated eventually. 779 * and so will also be updated eventually.
777 * 780 *
778 * XXX Should we do an xprt_unregister() instead? 781 * XXX Should we do an xprt_unregister() instead?
779 */ 782 */
780 if (p->revents & POLLNVAL) { 783 if (p->revents & POLLNVAL) {
781 rwlock_wrlock(&svc_fd_lock); 784 rwlock_wrlock(&svc_fd_lock);
782 svc_fdset_clr(p->fd); 785 svc_fdset_clr(p->fd);
783 rwlock_unlock(&svc_fd_lock); 786 rwlock_unlock(&svc_fd_lock);
784 } else 787 } else
785 svc_getreq_common(p->fd); 788 svc_getreq_common(p->fd);
786 } 789 }
787 } 790 }

cvs diff -r1.23 -r1.24 src/lib/libc/rpc/svc_run.c (expand / switch to unified diff)

--- src/lib/libc/rpc/svc_run.c 2015/11/06 19:34:13 1.23
+++ src/lib/libc/rpc/svc_run.c 2015/11/07 17:34:33 1.24
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: svc_run.c,v 1.23 2015/11/06 19:34:13 christos Exp $ */ 1/* $NetBSD: svc_run.c,v 1.24 2015/11/07 17:34:33 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2010, Oracle America, Inc. 4 * Copyright (c) 2010, Oracle America, Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are 7 * modification, are permitted provided that the following conditions are
8 * met: 8 * met:
9 * 9 *
10 * * Redistributions of source code must retain the above copyright 10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above 12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following 13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials 14 * disclaimer in the documentation and/or other materials
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35#if defined(LIBC_SCCS) && !defined(lint) 35#if defined(LIBC_SCCS) && !defined(lint)
36#if 0 36#if 0
37static char *sccsid = "@(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro"; 37static char *sccsid = "@(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";
38static char *sccsid = "@(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC"; 38static char *sccsid = "@(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC";
39#else 39#else
40__RCSID("$NetBSD: svc_run.c,v 1.23 2015/11/06 19:34:13 christos Exp $"); 40__RCSID("$NetBSD: svc_run.c,v 1.24 2015/11/07 17:34:33 christos Exp $");
41#endif 41#endif
42#endif 42#endif
43 43
44/* 44/*
45 * This is the rpc server side idle loop 45 * This is the rpc server side idle loop
46 * Wait for input, call server program. 46 * Wait for input, call server program.
47 */ 47 */
48#include "namespace.h" 48#include "namespace.h"
49#include "reentrant.h" 49#include "reentrant.h"
50#include <err.h> 50#include <err.h>
51#include <errno.h> 51#include <errno.h>
52#include <stdio.h> 52#include <stdio.h>
53#include <stdlib.h> 53#include <stdlib.h>
@@ -59,69 +59,75 @@ __RCSID("$NetBSD: svc_run.c,v 1.23 2015/ @@ -59,69 +59,75 @@ __RCSID("$NetBSD: svc_run.c,v 1.23 2015/
59#include "svc_fdset.h" 59#include "svc_fdset.h"
60#include "rpc_internal.h" 60#include "rpc_internal.h"
61 61
62#ifdef __weak_alias 62#ifdef __weak_alias
63__weak_alias(svc_run,_svc_run) 63__weak_alias(svc_run,_svc_run)
64__weak_alias(svc_exit,_svc_exit) 64__weak_alias(svc_exit,_svc_exit)
65#endif 65#endif
66 66
67void 67void
68svc_run(void) 68svc_run(void)
69{ 69{
70 fd_set *readfds, *cleanfds; 70 fd_set *readfds, *cleanfds;
71 struct timeval timeout; 71 struct timeval timeout;
72 int maxfd, fdsize; 72 int *maxfd, fdsize;
73#ifndef RUMP_RPC  73#ifndef RUMP_RPC
74 int probs = 0; 74 int probs = 0;
75#endif 75#endif
76#ifdef _REENTRANT 76#ifdef _REENTRANT
77 extern rwlock_t svc_fd_lock; 77 extern rwlock_t svc_fd_lock;
78#endif 78#endif
79 79
80 readfds = NULL; 80 readfds = NULL;
81 cleanfds = NULL; 81 cleanfds = NULL;
82 fdsize = 0; 82 fdsize = 0;
83 timeout.tv_sec = 30; 83 timeout.tv_sec = 30;
84 timeout.tv_usec = 0; 84 timeout.tv_usec = 0;
85 85
86 for (;;) { 86 for (;;) {
87 rwlock_rdlock(&svc_fd_lock); 87 rwlock_rdlock(&svc_fd_lock);
88 if (fdsize != svc_fdset_getsize(0)) { 88 if (fdsize != svc_fdset_getsize(0)) {
89 fdsize = svc_fdset_getsize(0); 89 fdsize = svc_fdset_getsize(0);
90 free(readfds); 90 free(readfds);
91 readfds = svc_fdset_copy(svc_fdset_get()); 91 readfds = svc_fdset_copy(svc_fdset_get());
92 free(cleanfds); 92 free(cleanfds);
93 cleanfds = svc_fdset_copy(svc_fdset_get()); 93 cleanfds = svc_fdset_copy(svc_fdset_get());
94 } 94 }
95 maxfd = *svc_fdset_getmax(); 95 maxfd = svc_fdset_getmax();
 96 if (maxfd == NULL) {
 97 warn("can't get maxfd");
 98 continue;
 99 }
96 rwlock_unlock(&svc_fd_lock); 100 rwlock_unlock(&svc_fd_lock);
97 switch (select(maxfd + 1, readfds, NULL, NULL, &timeout)) { 101 switch (select(*maxfd + 1, readfds, NULL, NULL, &timeout)) {
98 case -1: 102 case -1:
99#ifndef RUMP_RPC  103#ifndef RUMP_RPC
100 if ((errno == EINTR || errno == EBADF) && probs < 100) { 104 if ((errno == EINTR || errno == EBADF) && probs < 100) {
101 probs++; 105 probs++;
102 continue; 106 continue;
103 } 107 }
104#endif 108#endif
105 if (errno == EINTR) { 109 if (errno == EINTR) {
106 continue; 110 continue;
107 } 111 }
108 warn("%s: select failed", __func__); 112 warn("%s: select failed", __func__);
109 goto out; 113 goto out;
110 case 0: 114 case 0:
111 __svc_clean_idle(cleanfds, 30, FALSE); 115 if (cleanfds)
 116 __svc_clean_idle(cleanfds, 30, FALSE);
112 continue; 117 continue;
113 default: 118 default:
114 svc_getreqset2(readfds, fdsize); 119 if (readfds)
 120 svc_getreqset2(readfds, fdsize);
115#ifndef RUMP_RPC 121#ifndef RUMP_RPC
116 probs = 0; 122 probs = 0;
117#endif 123#endif
118 } 124 }
119 } 125 }
120out: 126out:
121 free(readfds); 127 free(readfds);
122 free(cleanfds); 128 free(cleanfds);
123} 129}
124 130
125/* 131/*
126 * This function causes svc_run() to exit by telling it that it has no 132 * This function causes svc_run() to exit by telling it that it has no
127 * more work to do. 133 * more work to do.

cvs diff -r1.31 -r1.32 src/lib/libc/rpc/svc_vc.c (expand / switch to unified diff)

--- src/lib/libc/rpc/svc_vc.c 2015/11/06 19:34:13 1.31
+++ src/lib/libc/rpc/svc_vc.c 2015/11/07 17:34:33 1.32
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: svc_vc.c,v 1.31 2015/11/06 19:34:13 christos Exp $ */ 1/* $NetBSD: svc_vc.c,v 1.32 2015/11/07 17:34:33 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2010, Oracle America, Inc. 4 * Copyright (c) 2010, Oracle America, Inc.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are 7 * modification, are permitted provided that the following conditions are
8 * met: 8 * met:
9 * 9 *
10 * * Redistributions of source code must retain the above copyright 10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above 12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following 13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials 14 * disclaimer in the documentation and/or other materials
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35#if defined(LIBC_SCCS) && !defined(lint) 35#if defined(LIBC_SCCS) && !defined(lint)
36#if 0 36#if 0
37static char *sccsid = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro"; 37static char *sccsid = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";
38static char *sccsid = "@(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC"; 38static char *sccsid = "@(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC";
39#else 39#else
40__RCSID("$NetBSD: svc_vc.c,v 1.31 2015/11/06 19:34:13 christos Exp $"); 40__RCSID("$NetBSD: svc_vc.c,v 1.32 2015/11/07 17:34:33 christos Exp $");
41#endif 41#endif
42#endif 42#endif
43 43
44/* 44/*
45 * svc_vc.c, Server side for Connection Oriented based RPC.  45 * svc_vc.c, Server side for Connection Oriented based RPC.
46 * 46 *
47 * Actually implements two flavors of transporter - 47 * Actually implements two flavors of transporter -
48 * a tcp rendezvouser (a listner and connection establisher) 48 * a tcp rendezvouser (a listner and connection establisher)
49 * and a record/tcp stream. 49 * and a record/tcp stream.
50 */ 50 */
51 51
52#include "namespace.h" 52#include "namespace.h"
53#include "reentrant.h" 53#include "reentrant.h"
@@ -319,27 +319,29 @@ rendezvous_request(SVCXPRT *xprt, struct @@ -319,27 +319,29 @@ rendezvous_request(SVCXPRT *xprt, struct
319 r = (struct cf_rendezvous *)xprt->xp_p1; 319 r = (struct cf_rendezvous *)xprt->xp_p1;
320again: 320again:
321 len = sizeof addr; 321 len = sizeof addr;
322 if ((sock = accept(xprt->xp_fd, (struct sockaddr *)(void *)&addr, 322 if ((sock = accept(xprt->xp_fd, (struct sockaddr *)(void *)&addr,
323 &len)) < 0) { 323 &len)) < 0) {
324 if (errno == EINTR) 324 if (errno == EINTR)
325 goto again; 325 goto again;
326 /* 326 /*
327 * Clean out the most idle file descriptor when we're 327 * Clean out the most idle file descriptor when we're
328 * running out. 328 * running out.
329 */ 329 */
330 if (errno == EMFILE || errno == ENFILE) { 330 if (errno == EMFILE || errno == ENFILE) {
331 fd_set *cleanfds = svc_fdset_copy(svc_fdset_get()); 331 fd_set *cleanfds = svc_fdset_copy(svc_fdset_get());
332 int rv = __svc_clean_idle(cleanfds, 0, FALSE); 332 int rv = 0;
 333 if (cleanfds)
 334 rv = __svc_clean_idle(cleanfds, 0, FALSE);
333 free(cleanfds); 335 free(cleanfds);
334 if (rv) 336 if (rv)
335 goto again; 337 goto again;
336 } 338 }
337 return FALSE; 339 return FALSE;
338 } 340 }
339 /* 341 /*
340 * make a new transporter (re-uses xprt) 342 * make a new transporter (re-uses xprt)
341 */ 343 */
342 newxprt = makefd_xprt(sock, r->sendsize, r->recvsize); 344 newxprt = makefd_xprt(sock, r->sendsize, r->recvsize);
343 if (newxprt == NULL) 345 if (newxprt == NULL)
344 goto out; 346 goto out;
345 newxprt->xp_rtaddr.buf = mem_alloc(len); 347 newxprt->xp_rtaddr.buf = mem_alloc(len);
@@ -751,39 +753,46 @@ svc_vc_rendezvous_ops(SVCXPRT *xprt) @@ -751,39 +753,46 @@ svc_vc_rendezvous_ops(SVCXPRT *xprt)
751 xprt->xp_ops = &ops; 753 xprt->xp_ops = &ops;
752 xprt->xp_ops2 = &ops2; 754 xprt->xp_ops2 = &ops2;
753 mutex_unlock(&ops_lock); 755 mutex_unlock(&ops_lock);
754} 756}
755 757
756/* 758/*
757 * Destroy xprts that have not have had any activity in 'timeout' seconds. 759 * Destroy xprts that have not have had any activity in 'timeout' seconds.
758 * If 'cleanblock' is true, blocking connections (the default) are also 760 * If 'cleanblock' is true, blocking connections (the default) are also
759 * cleaned. If timeout is 0, the least active connection is picked. 761 * cleaned. If timeout is 0, the least active connection is picked.
760 */ 762 */
761bool_t 763bool_t
762__svc_clean_idle(fd_set *fds, int timeout, bool_t cleanblock) 764__svc_clean_idle(fd_set *fds, int timeout, bool_t cleanblock)
763{ 765{
764 int i, ncleaned, fdmax; 766 int i, ncleaned, *fdmax;
765 SVCXPRT *xprt, *least_active; 767 SVCXPRT *xprt, *least_active;
766 struct timeval tv, tdiff, tmax; 768 struct timeval tv, tdiff, tmax;
767 struct cf_conn *cd; 769 struct cf_conn *cd;
768 770
769 gettimeofday(&tv, NULL); 771 gettimeofday(&tv, NULL);
770 tmax.tv_sec = tmax.tv_usec = 0; 772 tmax.tv_sec = tmax.tv_usec = 0;
771 least_active = NULL; 773 least_active = NULL;
772 rwlock_wrlock(&svc_fd_lock); 774 rwlock_wrlock(&svc_fd_lock);
773 fdmax = *svc_fdset_getmax(); 775 fdmax = svc_fdset_getmax();
774 for (i = ncleaned = 0; i <= fdmax; i++) { 776 if (fdmax == NULL)
775 if (!svc_fdset_isset(i)) 777 return FALSE;
 778 for (i = ncleaned = 0; i <= *fdmax; i++) {
 779 switch (svc_fdset_isset(i)) {
 780 case 0:
 781 case -1:
776 continue; 782 continue;
 783 default:
 784 break;
 785 }
777 786
778 xprt = __svc_xports[i]; 787 xprt = __svc_xports[i];
779 if (xprt == NULL || xprt->xp_ops == NULL || 788 if (xprt == NULL || xprt->xp_ops == NULL ||
780 xprt->xp_ops->xp_recv != svc_vc_recv) 789 xprt->xp_ops->xp_recv != svc_vc_recv)
781 continue; 790 continue;
782 791
783 cd = (struct cf_conn *)xprt->xp_p1; 792 cd = (struct cf_conn *)xprt->xp_p1;
784 if (!cleanblock && !cd->nonblock) 793 if (!cleanblock && !cd->nonblock)
785 continue; 794 continue;
786 795
787 if (timeout == 0) { 796 if (timeout == 0) {
788 timersub(&tv, &cd->last_recv_time, &tdiff); 797 timersub(&tv, &cd->last_recv_time, &tdiff);
789 if (timercmp(&tdiff, &tmax, >)) { 798 if (timercmp(&tdiff, &tmax, >)) {