--- old/usr/src/cmd/fs.d/nfs/etc/nfs.dfl Wed Jun 17 00:15:41 2009 +++ new/usr/src/cmd/fs.d/nfs/etc/nfs.dfl Wed Jun 17 00:15:40 2009 @@ -1,14 +1,12 @@ -# ident "%Z%%M% %I% %E% SMI" # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -101,3 +99,17 @@ # the domain to append to outbound attribute strings, and that it is to # use 'domain' to compare against inbound attribute strings. #NFSMAPID_DOMAIN=domain + +# Specifies TCP send and receive buffer size of NFS server connections. +# +# To override the default values and force NFS connections to use system-wide +# default TCP send and receive buffer size, set the corresponding option to 0. +# +# Default is 1048576 bytes, which is the current maximum allowable buffer size +# limited by system-wide 'tcp_max_buf' configuration variable. To set the buffer +# size beyond the current maximum allowable value, increase 'tcp_max_buf' to +# a value greater than, or equal to, the desired value for NFS_SERVER_SNDBUFSZ +# and NFS_SERVER_RCVBUFSZ. +# +#NFS_SERVER_SNDBUFSZ=1048576 +#NFS_SERVER_RCVBUFSZ=1048576 --- old/usr/src/cmd/fs.d/nfs/lib/nfs_tbind.h Wed Jun 17 00:15:42 2009 +++ new/usr/src/cmd/fs.d/nfs/lib/nfs_tbind.h Wed Jun 17 00:15:41 2009 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,8 +30,6 @@ #ifndef _NFS_TBIND_H #define _NFS_TBIND_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include @@ -73,11 +71,17 @@ */ extern int nfslib_transport_open(struct netconfig *); extern int nfslib_bindit(struct netconfig *, struct netbuf **, - struct nd_hostserv *, int); + struct nd_hostserv *, int, int sndbufsz, int rcvbufsz); extern void nfslib_log_tli_error(char *, int, struct netconfig *); +extern int do_all_setbuf(struct protob *, + int (*)(int, struct netbuf, struct netconfig *), + int use_pmap, int sndbufsz, int rcvbufsz); extern int do_all(struct protob *, int (*)(int, struct netbuf, struct netconfig *), int use_pmap); +extern void do_one_setbuf(char *, char *, struct protob *, + int (*)(int, struct netbuf, struct netconfig *), + int use_pmap, int sndbufsz, int rcvbufsz); extern void do_one(char *, char *, struct protob *, int (*)(int, struct netbuf, struct netconfig *), int use_pmap); --- old/usr/src/cmd/fs.d/nfs/lib/nfs_tbind.c Wed Jun 17 00:15:42 2009 +++ new/usr/src/cmd/fs.d/nfs/lib/nfs_tbind.c Wed Jun 17 00:15:42 2009 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -27,8 +27,6 @@ * nfs_tbind.c, common part for nfsd and lockd. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #define PORTMAP #include @@ -103,9 +101,9 @@ static void add_to_poll_list(int, struct netconfig *); static char *serv_name_to_port_name(char *); static int bind_to_proto(char *, char *, struct netbuf **, - struct netconfig **); + struct netconfig **, int, int); static int bind_to_provider(char *, char *, struct netbuf **, - struct netconfig **); + struct netconfig **, int, int); static void conn_close_oldest(void); static boolean_t conn_get(int, struct netconfig *, struct conn_ind **); static void cots_listen_event(int, int); @@ -121,6 +119,7 @@ static int num_conns; /* Current number of connections */ int (*Mysvc4)(int, struct netbuf *, struct netconfig *, int, struct netbuf *); +static int setopt(int fd, int level, int name, int value); extern bool_t __pmap_set(const rpcprog_t program, const rpcvers_t version, const struct netconfig *nconf, const struct netbuf *address); @@ -240,9 +239,28 @@ return (0); } +static int +nfslib_set_sockbuf(int fd, int which, int val) +{ + if ((which != SO_RCVBUF) && (which != SO_SNDBUF)) + return (-1); + + syslog(LOG_DEBUG, "Set %s option to %d", + ((which == SO_RCVBUF) ? "SO_RCVBUF" : "SO_SNDBUF"), val); + + if (setopt(fd, SOL_SOCKET, which, val) < 0) { + syslog(LOG_ERR, "couldn't set %s to %d - t_errno = %d", + ((which == SO_RCVBUF) ? "SO_RCVBUF" : "SO_SNDBUF"), + val, t_errno); + syslog(LOG_ERR, "Check and increase system-wide tcp_max_buf"); + return (-1); + } + return (0); +} + int nfslib_bindit(struct netconfig *nconf, struct netbuf **addr, - struct nd_hostserv *hs, int backlog) + struct nd_hostserv *hs, int backlog, int sndbufsz, int rcvbufsz) { int fd; struct t_bind *ntb; @@ -402,6 +420,11 @@ "couldn't set NODELAY option for proto %s: t_errno = %d, %m", nconf->nc_proto, t_errno); } + + if (sndbufsz > 0) + (void) nfslib_set_sockbuf(fd, SO_SNDBUF, sndbufsz); + if (rcvbufsz > 0) + (void) nfslib_set_sockbuf(fd, SO_RCVBUF, rcvbufsz); } return (fd); @@ -477,11 +500,13 @@ } /* - * Called to set up service over a particular transport. + * Called to set up service over a particular transport also + * set send and receive buffer size for transport connection. */ void -do_one(char *provider, NETSELDECL(proto), struct protob *protobp0, - int (*svc)(int, struct netbuf, struct netconfig *), int use_pmap) +do_one_setbuf(char *provider, NETSELDECL(proto), struct protob *protobp0, + int (*svc)(int, struct netbuf, struct netconfig *), int use_pmap, + int sndbufsz, int rcvbufsz) { register int sock; struct protob *protobp; @@ -494,10 +519,10 @@ if (provider) sock = bind_to_provider(provider, protobp0->serv, &retaddr, - &retnconf); + &retnconf, sndbufsz, rcvbufsz); else sock = bind_to_proto(proto, protobp0->serv, &retaddr, - &retnconf); + &retnconf, sndbufsz, rcvbufsz); if (sock == -1) { (void) syslog(LOG_ERR, @@ -582,13 +607,16 @@ */ add_to_poll_list(sock, retnconf); } + /* - * Set up the NFS service over all the available transports. + * Set up the NFS service over all the available transports and + * also set send and receive buffer size for transport connection. * Returns -1 for failure, 0 for success. */ int -do_all(struct protob *protobp, - int (*svc)(int, struct netbuf, struct netconfig *), int use_pmap) +do_all_setbuf(struct protob *protobp, + int (*svc)(int, struct netbuf, struct netconfig *), int use_pmap, + int sndbufsz, int rcvbufsz) { struct netconfig *nconf; NCONF_HANDLE *nc; @@ -605,8 +633,8 @@ OK_TPI_TYPE(nconf) && (protobp->program != NFS4_CALLBACK || strncasecmp(nconf->nc_proto, NC_UDP, l) != 0)) - do_one(nconf->nc_device, nconf->nc_proto, - protobp, svc, use_pmap); + do_one_setbuf(nconf->nc_device, nconf->nc_proto, + protobp, svc, use_pmap, sndbufsz, rcvbufsz); } (void) endnetconfig(nc); return (0); @@ -613,6 +641,27 @@ } /* + * Called to set up service over a particular transport. + */ +void +do_one(char *provider, NETSELDECL(proto), struct protob *protobp0, + int (*svc)(int, struct netbuf, struct netconfig *), int use_pmap) +{ + do_one_setbuf(provider, proto, protobp0, svc, use_pmap, 0, 0); +} + +/* + * Set up the NFS service over all the available transports. + * Returns -1 for failure, 0 for success. + */ +int +do_all(struct protob *protobp, + int (*svc)(int, struct netbuf, struct netconfig *), int use_pmap) +{ + return (do_all_setbuf(protobp, svc, use_pmap, 0, 0)); +} + +/* * poll on the open transport descriptors for events and errors. */ void @@ -1577,7 +1626,7 @@ static int bind_to_provider(char *provider, char *serv, struct netbuf **addr, - struct netconfig **retnconf) + struct netconfig **retnconf, int sndbufsz, int rcvbufsz) { struct netconfig *nconf; NCONF_HANDLE *nc; @@ -1595,7 +1644,7 @@ strcmp(nconf->nc_device, provider) == 0) { *retnconf = nconf; return (nfslib_bindit(nconf, addr, &hs, - listen_backlog)); + listen_backlog, sndbufsz, rcvbufsz)); } } (void) endnetconfig(nc); @@ -1607,7 +1656,7 @@ static int bind_to_proto(NETSELDECL(proto), char *serv, struct netbuf **addr, - struct netconfig **retnconf) + struct netconfig **retnconf, int sndbufsz, int rcvbufsz) { struct netconfig *nconf; NCONF_HANDLE *nc = NULL; @@ -1624,7 +1673,7 @@ if (OK_TPI_TYPE(nconf) && NETSELEQ(nconf->nc_proto, proto)) { *retnconf = nconf; return (nfslib_bindit(nconf, addr, &hs, - listen_backlog)); + listen_backlog, sndbufsz, rcvbufsz)); } } (void) endnetconfig(nc); --- old/usr/src/cmd/fs.d/nfs/nfs4cbd/nfs4cbd.c Wed Jun 17 00:15:43 2009 +++ new/usr/src/cmd/fs.d/nfs/nfs4cbd/nfs4cbd.c Wed Jun 17 00:15:43 2009 @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -31,8 +31,6 @@ * under license from the Regents of the University of California. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * This module provides the user level support for the NFSv4 * callback program. It is modeled after nfsd. When a nfsv4 @@ -129,7 +127,7 @@ if (pi == -1) { (void) syslog(LOG_ERR, - "Could not start NFS4_CALLBACK service"); + "Could not start NFS4_CALLBACK service"); exit(1); } @@ -140,7 +138,7 @@ if (__init_daemon_priv(PU_RESETGROUPS|PU_CLEARLIMITSET, DAEMON_UID, DAEMON_GID, PRIV_SYS_NFS, (char *)NULL) == -1) { (void) fprintf(stderr, "%s must be run with sufficient" - " privileges\n", argv[0]); + " privileges\n", argv[0]); exit(1); } /* Basic privileges we don't need, remove from E/P. */ @@ -240,7 +238,7 @@ if (ua == NULL) { #ifdef DEBUG fprintf(stderr, "taddr2uaddr failed for netid %s\n", - nconf->nc_netid); + nconf->nc_netid); #endif return (NULL); } @@ -261,7 +259,7 @@ if (ua2 == NULL) { #ifdef DEBUG fprintf(stderr, "taddr2uaddr failed for netid %s.\n", - nconf->nc_netid); + nconf->nc_netid); #endif return (NULL); } @@ -296,8 +294,8 @@ if (ua == NULL) { syslog(LOG_NOTICE, "nfsv4 cannot determine local hostname " - "binding for transport %s - delegations will not be " - "available on this transport\n", nconf->nc_netid); + "binding for transport %s - delegations will not be " + "available on this transport\n", nconf->nc_netid); return (0); } @@ -304,10 +302,10 @@ #ifdef DEBUG if (cmd & NFS4_KRPC_START) fprintf(stderr, "nfs4cbd: starting callback rpc on %s %s\n", - nconf->nc_netid, ua); + nconf->nc_netid, ua); else fprintf(stderr, "nfs4cbd: listening on %s %s\n", - nconf->nc_netid, ua); + nconf->nc_netid, ua); #endif nsa.fd = fd; --- old/usr/src/cmd/fs.d/nfs/nfsd/nfsd.c Wed Jun 17 00:15:44 2009 +++ new/usr/src/cmd/fs.d/nfs/nfsd/nfsd.c Wed Jun 17 00:15:43 2009 @@ -128,6 +128,19 @@ */ int nfs_server_delegation = NFS_SERVER_DELEGATION_DEFAULT; +/* + * Default values for TCP send and receive buffer size of NFS server + * connections. + * + * These values can be tuned by user via /etc/default/nfs configuration + * file by setting NFS_SERVER_SNDBUFSZ and NFS_SERVER_RCVBUFSZ. + * + * To force NFS connections to use system-wide default for TCP send and + * receive buffer, set NFS_SERVER_SNDBUFSZ and NFS_SERVER_RCVBUFSZ to 0. + */ +int nfs_server_sndbufsz = 1048576; +int nfs_server_rcvbufsz = 1048576; + int main(int ac, char *av[]) { @@ -139,7 +152,7 @@ int maxservers_set = 0; int logmaxservers = 0; int pid; - int i; + int i, bufsz; char *provider = (char *)NULL; char *df_provider = (char *)NULL; struct protob *protobp0, *protobp; @@ -235,6 +248,18 @@ nfs_server_delegation = FALSE; } } + if ((defval = defread("NFS_SERVER_SNDBUFSZ=")) != NULL) { + errno = 0; + bufsz = strtol(defval, (char **)NULL, 10); + if (errno == 0) + nfs_server_sndbufsz = bufsz; + } + if ((defval = defread("NFS_SERVER_RCVBUFSZ=")) != NULL) { + errno = 0; + bufsz = strtol(defval, (char **)NULL, 10); + if (errno == 0) + nfs_server_rcvbufsz = bufsz; + } /* close defaults file */ defopen(NULL); @@ -534,7 +559,8 @@ protobp->next = (struct protob *)NULL; if (allflag) { - if (do_all(protobp0, nfssvc, 0) == -1) { + if (do_all_setbuf(protobp0, nfssvc, 0, nfs_server_sndbufsz, + nfs_server_rcvbufsz) == -1) { fprintf(stderr, "setnetconfig failed : %s", strerror(errno)); exit(1); @@ -552,8 +578,9 @@ while (nconf = getnetconfig(nc)) { if (strcmp(nconf->nc_proto, proto) == 0) { protoFound = TRUE; - do_one(nconf->nc_device, NULL, - protobp0, nfssvc, 0); + do_one_setbuf(nconf->nc_device, NULL, + protobp0, nfssvc, 0, + nfs_server_sndbufsz, nfs_server_rcvbufsz); } } (void) endnetconfig(nc); @@ -563,12 +590,14 @@ proto); } } else if (provider) - do_one(provider, proto, protobp0, nfssvc, 0); + do_one_setbuf(provider, proto, protobp0, nfssvc, 0, + nfs_server_sndbufsz, nfs_server_rcvbufsz); else { for (providerp = defaultproviders; *providerp != NULL; providerp++) { provider = *providerp; - do_one(provider, NULL, protobp0, nfssvc, 0); + do_one_setbuf(provider, NULL, protobp0, nfssvc, 0, + nfs_server_sndbufsz, nfs_server_rcvbufsz); } } done: --- old/usr/src/uts/common/rpc/clnt_cots.c Wed Jun 17 00:15:45 2009 +++ new/usr/src/uts/common/rpc/clnt_cots.c Wed Jun 17 00:15:44 2009 @@ -190,6 +190,7 @@ #include #include #include +#include #define COTS_DEFAULT_ALLOCSIZE 2048 @@ -381,6 +382,10 @@ int, calllist_t *, int *, bool_t reconnect, const struct timeval *, bool_t, cred_t *); +static bool_t connmgr_getopt_int(queue_t *wq, int level, int name, int *val, + calllist_t *e, cred_t *cr); +static bool_t connmgr_setopt_int(queue_t *, int, int, int, + calllist_t *, cred_t *cr); static bool_t connmgr_setopt(queue_t *, int, int, calllist_t *, cred_t *cr); static void connmgr_sndrel(struct cm_xprt *); static void connmgr_snddis(struct cm_xprt *); @@ -502,7 +507,23 @@ static zone_key_t zone_cots_key; +#define TWO_GIGB 0x80000000 +int nfsd_port = NFS_PORT; /* + * Defaults TCP send and receive buffer size for NFS connections. + * These values can be tuned by /etc/default. + */ +int nfs_send_bufsz = 1024*1024; +int nfs_recv_bufsz = 1024*1024; +/* + * To use system-wide default for TCP send and receive buffer size, + * use /etc/system to set nfs_default_bufsz to 1: + * + * set rpcmod:nfs_default_bufsz=1 + */ +int nfs_default_bufsz = 0; + +/* * We need to do this after all kernel threads in the zone have exited. */ /* ARGSUSED */ @@ -2558,6 +2579,60 @@ } /* + * Set TCP receive and xmit buffer size for NFS connections. + */ +static bool_t +connmgr_nfs_setbufsz(calllist_t *e, int addrfmly, struct netbuf *addr, + queue_t *wq, cred_t *cr) +{ + struct sockaddr_in *sa; + int ok = FALSE; + int val; + uint32_t sbufsz, rbufsz; + + if (nfs_default_bufsz || + (addrfmly != AF_INET && addrfmly != AF_INET6)) + return (FALSE); + + sa = (struct sockaddr_in *)addr->buf; + if (ntohs(sa->sin_port) != nfsd_port) + return (FALSE); + /* + * For system with 2GB, or less, of physical memory set send + * and receive buffer size to half of nfs_send_bufsz and + * nfs_recv_bufsz respectively. + */ + if (ptob(physmem) <= TWO_GIGB) { + sbufsz = nfs_send_bufsz >> 1; + rbufsz = nfs_recv_bufsz >> 1; + } else { + sbufsz = nfs_send_bufsz; + rbufsz = nfs_recv_bufsz; + } + /* + * Only set new buffer size if it's larger than the system + * default buffer size. If smaller buffer size is needed + * then use /etc/system to set nfs_default_bufsz to 1. + */ + ok = connmgr_getopt_int(wq, SOL_SOCKET, SO_RCVBUF, &val, e, cr); + if ((ok == TRUE) && (val < sbufsz)) { + ok = connmgr_setopt_int(wq, SOL_SOCKET, SO_RCVBUF, + sbufsz, e, cr); + DTRACE_PROBE2(connmgr_nfs_rcvbufsz__setopt, + int, ok, calllist_t *, e); + } + + ok = connmgr_getopt_int(wq, SOL_SOCKET, SO_SNDBUF, &val, e, cr); + if ((ok == TRUE) && (val < rbufsz)) { + ok = connmgr_setopt_int(wq, SOL_SOCKET, SO_SNDBUF, + rbufsz, e, cr); + DTRACE_PROBE2(connmgr_nfs_sndbufsz__setopt, + int, ok, calllist_t *, e); + } + return (TRUE); +} + +/* * Given an open stream, connect to the remote. Returns true if connected, * false otherwise. */ @@ -2609,6 +2684,9 @@ return (FALSE); } + /* Set TCP buffer size for NFS connections if needed */ + (void) connmgr_nfs_setbufsz(e, addrfmly, addr, wq, cr); + mp->b_datap->db_type = M_PROTO; tcr = (struct T_conn_req *)mp->b_rptr; bzero(tcr, sizeof (*tcr)); @@ -2764,10 +2842,125 @@ } /* + * Verify that the specified offset falls within the mblk and + * that the resulting pointer is aligned. + * Returns NULL if not. + * + * code from fs/sockfs/socksubr.c + */ +static void * +connmgr_opt_getoff(mblk_t *mp, t_uscalar_t offset, + t_uscalar_t length, uint_t align_size) +{ + uintptr_t ptr1, ptr2; + + ASSERT(mp && mp->b_wptr >= mp->b_rptr); + ptr1 = (uintptr_t)mp->b_rptr + offset; + ptr2 = (uintptr_t)ptr1 + length; + if (ptr1 < (uintptr_t)mp->b_rptr || ptr2 > (uintptr_t)mp->b_wptr) { + return (NULL); + } + if ((ptr1 & (align_size - 1)) != 0) { + return (NULL); + } + return ((void *)ptr1); +} + +static bool_t +connmgr_getopt_int(queue_t *wq, int level, int name, int *val, + calllist_t *e, cred_t *cr) +{ + mblk_t *mp; + struct opthdr *opt, *opt_res; + struct T_optmgmt_req *tor; + struct T_optmgmt_ack *opt_ack; + struct timeval waitp; + int error; + + mp = allocb_cred(sizeof (struct T_optmgmt_req) + + sizeof (struct opthdr) + sizeof (int), cr, NOPID); + if (mp == NULL) { + RPCLOG0(1, "connmgr_getopt: cannot alloc mp for option " + "request\n"); + return (FALSE); + } + + mp->b_datap->db_type = M_PROTO; + tor = (struct T_optmgmt_req *)(mp->b_rptr); + tor->PRIM_type = T_SVR4_OPTMGMT_REQ; + tor->MGMT_flags = T_CURRENT; + tor->OPT_length = sizeof (struct opthdr) + sizeof (int); + tor->OPT_offset = sizeof (struct T_optmgmt_req); + + opt = (struct opthdr *)(mp->b_rptr + sizeof (struct T_optmgmt_req)); + opt->level = level; + opt->name = name; + opt->len = sizeof (int); + mp->b_wptr += sizeof (struct T_optmgmt_req) + sizeof (struct opthdr) + + sizeof (int); + + /* + * We will use this connection regardless + * of whether or not the option is readable. + */ + if (clnt_dispatch_send(wq, mp, e, 0, 0) != RPC_SUCCESS) { + DTRACE_PROBE(krpc__e__connmgr__getopt__cantsend); + freemsg(mp); + return (FALSE); + } + + mutex_enter(&clnt_pending_lock); + + waitp.tv_sec = clnt_cots_min_conntout; + waitp.tv_usec = 0; + error = waitforack(e, T_OPTMGMT_ACK, &waitp, 1); + + if (e->call_prev) + e->call_prev->call_next = e->call_next; + else + clnt_pending = e->call_next; + if (e->call_next) + e->call_next->call_prev = e->call_prev; + mutex_exit(&clnt_pending_lock); + + /* get reply message */ + mp = e->call_reply; + e->call_reply = NULL; + + if ((!mp) || (e->call_status != RPC_SUCCESS) || (error != 0)) { + + DTRACE_PROBE4(connmgr_getopt__failed, int, name, + int, e->call_status, int, error, mblk_t *, mp); + + if (mp) + freemsg(mp); + return (FALSE); + } + + opt_ack = (struct T_optmgmt_ack *)mp->b_rptr; + opt_res = (struct opthdr *)connmgr_opt_getoff(mp, opt_ack->OPT_offset, + opt_ack->OPT_length, __TPI_ALIGN_SIZE); + + if (!opt_res) { + DTRACE_PROBE4(connmgr_getopt__optres, mblk_t *, mp, int, name, + int, opt_ack->OPT_offset, int, opt_ack->OPT_length); + freemsg(mp); + return (FALSE); + } + *val = *(int *)&opt_res[1]; + + DTRACE_PROBE2(connmgr_getopt__ok, int, name, int, *val); + + freemsg(mp); + return (TRUE); +} + +/* * Called by connmgr_connect to set an option on the new stream. */ static bool_t -connmgr_setopt(queue_t *wq, int level, int name, calllist_t *e, cred_t *cr) +connmgr_setopt_int(queue_t *wq, int level, int name, int val, + calllist_t *e, cred_t *cr) { mblk_t *mp; struct opthdr *opt; @@ -2794,7 +2987,7 @@ opt->level = level; opt->name = name; opt->len = sizeof (int); - *(int *)((char *)opt + sizeof (*opt)) = 1; + *(int *)((char *)opt + sizeof (*opt)) = val; mp->b_wptr += sizeof (struct T_optmgmt_req) + sizeof (struct opthdr) + sizeof (int); @@ -2835,6 +3028,12 @@ return (TRUE); } +static bool_t +connmgr_setopt(queue_t *wq, int level, int name, calllist_t *e, cred_t *cr) +{ + return (connmgr_setopt_int(wq, level, name, 1, e, cr)); +} + #ifdef DEBUG /*