1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 27*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 28*7c478bd9Sstevel@tonic-gate /* 29*7c478bd9Sstevel@tonic-gate * Portions of this source code were derived from Berkeley 30*7c478bd9Sstevel@tonic-gate * 4.3 BSD under license from the Regents of the University of 31*7c478bd9Sstevel@tonic-gate * California. 32*7c478bd9Sstevel@tonic-gate */ 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate /* 35*7c478bd9Sstevel@tonic-gate * svc.h, Server-side remote procedure call interface. 36*7c478bd9Sstevel@tonic-gate */ 37*7c478bd9Sstevel@tonic-gate 38*7c478bd9Sstevel@tonic-gate #ifndef _RPC_SVC_H 39*7c478bd9Sstevel@tonic-gate #define _RPC_SVC_H 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate #include <rpc/rpc_com.h> 44*7c478bd9Sstevel@tonic-gate #include <rpc/rpc_msg.h> 45*7c478bd9Sstevel@tonic-gate #include <sys/tihdr.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/poll.h> 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 49*7c478bd9Sstevel@tonic-gate #include <rpc/svc_auth.h> 50*7c478bd9Sstevel@tonic-gate #include <sys/callb.h> 51*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate /* 54*7c478bd9Sstevel@tonic-gate * This interface must manage two items concerning remote procedure calling: 55*7c478bd9Sstevel@tonic-gate * 56*7c478bd9Sstevel@tonic-gate * 1) An arbitrary number of transport connections upon which rpc requests 57*7c478bd9Sstevel@tonic-gate * are received. They are created and registered by routines in svc_generic.c, 58*7c478bd9Sstevel@tonic-gate * svc_vc.c and svc_dg.c; they in turn call xprt_register and 59*7c478bd9Sstevel@tonic-gate * xprt_unregister. 60*7c478bd9Sstevel@tonic-gate * 61*7c478bd9Sstevel@tonic-gate * 2) An arbitrary number of locally registered services. Services are 62*7c478bd9Sstevel@tonic-gate * described by the following four data: program number, version number, 63*7c478bd9Sstevel@tonic-gate * "service dispatch" function, a transport handle, and a boolean that 64*7c478bd9Sstevel@tonic-gate * indicates whether or not the exported program should be registered with a 65*7c478bd9Sstevel@tonic-gate * local binder service; if true the program's number and version and the 66*7c478bd9Sstevel@tonic-gate * address from the transport handle are registered with the binder. 67*7c478bd9Sstevel@tonic-gate * These data are registered with rpcbind via svc_reg(). 68*7c478bd9Sstevel@tonic-gate * 69*7c478bd9Sstevel@tonic-gate * A service's dispatch function is called whenever an rpc request comes in 70*7c478bd9Sstevel@tonic-gate * on a transport. The request's program and version numbers must match 71*7c478bd9Sstevel@tonic-gate * those of the registered service. The dispatch function is passed two 72*7c478bd9Sstevel@tonic-gate * parameters, struct svc_req * and SVCXPRT *, defined below. 73*7c478bd9Sstevel@tonic-gate */ 74*7c478bd9Sstevel@tonic-gate 75*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 76*7c478bd9Sstevel@tonic-gate extern "C" { 77*7c478bd9Sstevel@tonic-gate #endif 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate /* 80*7c478bd9Sstevel@tonic-gate * Server-side transport handles. 81*7c478bd9Sstevel@tonic-gate * The actual type definitions are below. 82*7c478bd9Sstevel@tonic-gate */ 83*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 84*7c478bd9Sstevel@tonic-gate typedef struct __svcmasterxprt SVCMASTERXPRT; /* Master transport handle */ 85*7c478bd9Sstevel@tonic-gate typedef struct __svcxprt SVCXPRT; /* Per-thread clone handle */ 86*7c478bd9Sstevel@tonic-gate typedef struct __svcpool SVCPOOL; /* Kernel thread pool */ 87*7c478bd9Sstevel@tonic-gate #else /* _KERNEL */ 88*7c478bd9Sstevel@tonic-gate typedef struct __svcxprt SVCXPRT; /* Server transport handle */ 89*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate /* 92*7c478bd9Sstevel@tonic-gate * Prototype of error handler callback 93*7c478bd9Sstevel@tonic-gate */ 94*7c478bd9Sstevel@tonic-gate #ifndef _KERNEL 95*7c478bd9Sstevel@tonic-gate typedef void (*svc_errorhandler_t)(const SVCXPRT* svc, const bool_t isAConn); 96*7c478bd9Sstevel@tonic-gate #endif 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate /* 99*7c478bd9Sstevel@tonic-gate * Service request. 100*7c478bd9Sstevel@tonic-gate * 101*7c478bd9Sstevel@tonic-gate * PSARC 2003/523 Contract Private Interface 102*7c478bd9Sstevel@tonic-gate * svc_req 103*7c478bd9Sstevel@tonic-gate * Changes must be reviewed by Solaris File Sharing 104*7c478bd9Sstevel@tonic-gate * Changes must be communicated to contract-2003-523@sun.com 105*7c478bd9Sstevel@tonic-gate */ 106*7c478bd9Sstevel@tonic-gate struct svc_req { 107*7c478bd9Sstevel@tonic-gate rpcprog_t rq_prog; /* service program number */ 108*7c478bd9Sstevel@tonic-gate rpcvers_t rq_vers; /* service protocol version */ 109*7c478bd9Sstevel@tonic-gate rpcproc_t rq_proc; /* the desired procedure */ 110*7c478bd9Sstevel@tonic-gate struct opaque_auth rq_cred; /* raw creds from the wire */ 111*7c478bd9Sstevel@tonic-gate caddr_t rq_clntcred; /* read only cooked cred */ 112*7c478bd9Sstevel@tonic-gate SVCXPRT *rq_xprt; /* associated transport */ 113*7c478bd9Sstevel@tonic-gate }; 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 116*7c478bd9Sstevel@tonic-gate struct dupreq { 117*7c478bd9Sstevel@tonic-gate uint32_t dr_xid; 118*7c478bd9Sstevel@tonic-gate rpcproc_t dr_proc; 119*7c478bd9Sstevel@tonic-gate rpcvers_t dr_vers; 120*7c478bd9Sstevel@tonic-gate rpcprog_t dr_prog; 121*7c478bd9Sstevel@tonic-gate struct netbuf dr_addr; 122*7c478bd9Sstevel@tonic-gate struct netbuf dr_resp; 123*7c478bd9Sstevel@tonic-gate void (*dr_resfree)(); 124*7c478bd9Sstevel@tonic-gate int dr_status; 125*7c478bd9Sstevel@tonic-gate struct dupreq *dr_next; 126*7c478bd9Sstevel@tonic-gate struct dupreq *dr_chain; 127*7c478bd9Sstevel@tonic-gate }; 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate /* 130*7c478bd9Sstevel@tonic-gate * States of requests for duplicate request caching. 131*7c478bd9Sstevel@tonic-gate */ 132*7c478bd9Sstevel@tonic-gate #define DUP_NEW 0x00 /* new entry */ 133*7c478bd9Sstevel@tonic-gate #define DUP_INPROGRESS 0x01 /* request already going */ 134*7c478bd9Sstevel@tonic-gate #define DUP_DONE 0x02 /* request done */ 135*7c478bd9Sstevel@tonic-gate #define DUP_DROP 0x03 /* request dropped */ 136*7c478bd9Sstevel@tonic-gate #define DUP_ERROR 0x04 /* error in dup req cache */ 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate /* 139*7c478bd9Sstevel@tonic-gate * Prototype for a service dispatch routine. 140*7c478bd9Sstevel@tonic-gate */ 141*7c478bd9Sstevel@tonic-gate typedef void (SVC_DISPATCH)(struct svc_req *, SVCXPRT *); 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate /* 144*7c478bd9Sstevel@tonic-gate * The service provider callout. 145*7c478bd9Sstevel@tonic-gate * Each entry identifies a dispatch routine to be called 146*7c478bd9Sstevel@tonic-gate * for a given RPC program number and a version fitting 147*7c478bd9Sstevel@tonic-gate * into the registered range. 148*7c478bd9Sstevel@tonic-gate */ 149*7c478bd9Sstevel@tonic-gate typedef struct { 150*7c478bd9Sstevel@tonic-gate rpcprog_t sc_prog; /* RPC Program number */ 151*7c478bd9Sstevel@tonic-gate rpcvers_t sc_versmin; /* Min version number */ 152*7c478bd9Sstevel@tonic-gate rpcvers_t sc_versmax; /* Max version number */ 153*7c478bd9Sstevel@tonic-gate SVC_DISPATCH *sc_dispatch; /* Dispatch routine */ 154*7c478bd9Sstevel@tonic-gate } SVC_CALLOUT; 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate /* 157*7c478bd9Sstevel@tonic-gate * Table of service provider `callouts' for an RPC 158*7c478bd9Sstevel@tonic-gate * transport handle. If sct_free is TRUE then transport 159*7c478bd9Sstevel@tonic-gate * destructor is supposed to deallocate this table. 160*7c478bd9Sstevel@tonic-gate */ 161*7c478bd9Sstevel@tonic-gate typedef struct { 162*7c478bd9Sstevel@tonic-gate size_t sct_size; /* Number of entries */ 163*7c478bd9Sstevel@tonic-gate bool_t sct_free; /* Deallocate if true */ 164*7c478bd9Sstevel@tonic-gate SVC_CALLOUT *sct_sc; /* Callout entries */ 165*7c478bd9Sstevel@tonic-gate } SVC_CALLOUT_TABLE; 166*7c478bd9Sstevel@tonic-gate 167*7c478bd9Sstevel@tonic-gate struct svc_ops { 168*7c478bd9Sstevel@tonic-gate bool_t (*xp_recv)(SVCXPRT *, mblk_t *, struct rpc_msg *); 169*7c478bd9Sstevel@tonic-gate /* receive incoming requests */ 170*7c478bd9Sstevel@tonic-gate bool_t (*xp_getargs)(SVCXPRT *, xdrproc_t, caddr_t); 171*7c478bd9Sstevel@tonic-gate /* get arguments */ 172*7c478bd9Sstevel@tonic-gate bool_t (*xp_reply)(SVCXPRT *, struct rpc_msg *); 173*7c478bd9Sstevel@tonic-gate /* send reply */ 174*7c478bd9Sstevel@tonic-gate bool_t (*xp_freeargs)(SVCXPRT *, xdrproc_t, caddr_t); 175*7c478bd9Sstevel@tonic-gate /* free mem allocated for args */ 176*7c478bd9Sstevel@tonic-gate void (*xp_destroy)(SVCMASTERXPRT *); 177*7c478bd9Sstevel@tonic-gate /* destroy this struct */ 178*7c478bd9Sstevel@tonic-gate int (*xp_dup)(struct svc_req *, caddr_t, int, 179*7c478bd9Sstevel@tonic-gate struct dupreq **, bool_t *); 180*7c478bd9Sstevel@tonic-gate /* check for dup */ 181*7c478bd9Sstevel@tonic-gate void (*xp_dupdone)(struct dupreq *, caddr_t, void (*)(), int, int); 182*7c478bd9Sstevel@tonic-gate /* mark dup entry as completed */ 183*7c478bd9Sstevel@tonic-gate int32_t *(*xp_getres)(SVCXPRT *, int); 184*7c478bd9Sstevel@tonic-gate /* get pointer to response buffer */ 185*7c478bd9Sstevel@tonic-gate void (*xp_freeres)(SVCXPRT *); 186*7c478bd9Sstevel@tonic-gate /* destroy pre-serialized response */ 187*7c478bd9Sstevel@tonic-gate void (*xp_clone_destroy)(SVCXPRT *); 188*7c478bd9Sstevel@tonic-gate /* destroy a clone xprt */ 189*7c478bd9Sstevel@tonic-gate void (*xp_start)(SVCMASTERXPRT *); 190*7c478bd9Sstevel@tonic-gate /* `ready-to-receive' */ 191*7c478bd9Sstevel@tonic-gate }; 192*7c478bd9Sstevel@tonic-gate #else /* _KERNEL */ 193*7c478bd9Sstevel@tonic-gate /* 194*7c478bd9Sstevel@tonic-gate * Service control requests 195*7c478bd9Sstevel@tonic-gate */ 196*7c478bd9Sstevel@tonic-gate #define SVCGET_VERSQUIET 1 197*7c478bd9Sstevel@tonic-gate #define SVCSET_VERSQUIET 2 198*7c478bd9Sstevel@tonic-gate #define SVCGET_XID 4 199*7c478bd9Sstevel@tonic-gate #define SVCSET_KEEPALIVE 5 200*7c478bd9Sstevel@tonic-gate #define SVCSET_CONNMAXREC 6 201*7c478bd9Sstevel@tonic-gate #define SVCGET_CONNMAXREC 7 202*7c478bd9Sstevel@tonic-gate #define SVCGET_RECVERRHANDLER 8 203*7c478bd9Sstevel@tonic-gate #define SVCSET_RECVERRHANDLER 9 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate enum xprt_stat { 206*7c478bd9Sstevel@tonic-gate XPRT_DIED, 207*7c478bd9Sstevel@tonic-gate XPRT_MOREREQS, 208*7c478bd9Sstevel@tonic-gate XPRT_IDLE 209*7c478bd9Sstevel@tonic-gate }; 210*7c478bd9Sstevel@tonic-gate 211*7c478bd9Sstevel@tonic-gate struct xp_ops { 212*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 213*7c478bd9Sstevel@tonic-gate bool_t (*xp_recv)(SVCXPRT *, struct rpc_msg *); 214*7c478bd9Sstevel@tonic-gate /* receive incoming requests */ 215*7c478bd9Sstevel@tonic-gate enum xprt_stat (*xp_stat)(SVCXPRT *); 216*7c478bd9Sstevel@tonic-gate /* get transport status */ 217*7c478bd9Sstevel@tonic-gate bool_t (*xp_getargs)(SVCXPRT *, xdrproc_t, caddr_t); 218*7c478bd9Sstevel@tonic-gate /* get arguments */ 219*7c478bd9Sstevel@tonic-gate bool_t (*xp_reply)(SVCXPRT *, struct rpc_msg *); 220*7c478bd9Sstevel@tonic-gate /* send reply */ 221*7c478bd9Sstevel@tonic-gate bool_t (*xp_freeargs)(SVCXPRT *, xdrproc_t, caddr_t); 222*7c478bd9Sstevel@tonic-gate /* free mem allocated for args */ 223*7c478bd9Sstevel@tonic-gate void (*xp_destroy)(SVCXPRT *); 224*7c478bd9Sstevel@tonic-gate /* destroy this struct */ 225*7c478bd9Sstevel@tonic-gate bool_t (*xp_control)(SVCXPRT *, const uint_t, void *); 226*7c478bd9Sstevel@tonic-gate /* catch-all control function */ 227*7c478bd9Sstevel@tonic-gate #else /* __STDC__ */ 228*7c478bd9Sstevel@tonic-gate bool_t (*xp_recv)(); /* receive incoming requests */ 229*7c478bd9Sstevel@tonic-gate enum xprt_stat (*xp_stat)(); /* get transport status */ 230*7c478bd9Sstevel@tonic-gate bool_t (*xp_getargs)(); /* get arguments */ 231*7c478bd9Sstevel@tonic-gate bool_t (*xp_reply)(); /* send reply */ 232*7c478bd9Sstevel@tonic-gate bool_t (*xp_freeargs)(); /* free mem allocated for args */ 233*7c478bd9Sstevel@tonic-gate void (*xp_destroy)(); /* destroy this struct */ 234*7c478bd9Sstevel@tonic-gate bool_t (*xp_control)(); /* catch-all control function */ 235*7c478bd9Sstevel@tonic-gate #endif /* __STDC__ */ 236*7c478bd9Sstevel@tonic-gate }; 237*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 240*7c478bd9Sstevel@tonic-gate /* 241*7c478bd9Sstevel@tonic-gate * SVCPOOL 242*7c478bd9Sstevel@tonic-gate * Kernel RPC server-side thread pool structure. 243*7c478bd9Sstevel@tonic-gate */ 244*7c478bd9Sstevel@tonic-gate typedef struct __svcxprt_qnode __SVCXPRT_QNODE; /* Defined in svc.c */ 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate struct __svcpool { 247*7c478bd9Sstevel@tonic-gate /* 248*7c478bd9Sstevel@tonic-gate * Thread pool variables. 249*7c478bd9Sstevel@tonic-gate * 250*7c478bd9Sstevel@tonic-gate * The pool's thread lock p_thread_lock protects: 251*7c478bd9Sstevel@tonic-gate * - p_threads, p_detached_threads, p_reserved_threads and p_closing 252*7c478bd9Sstevel@tonic-gate * The pool's request lock protects: 253*7c478bd9Sstevel@tonic-gate * - p_asleep, p_drowsy, p_reqs, p_walkers, p_req_cv. 254*7c478bd9Sstevel@tonic-gate * The following fields are `initialized constants': 255*7c478bd9Sstevel@tonic-gate * - p_id, p_stksize, p_timeout. 256*7c478bd9Sstevel@tonic-gate * Access to p_next and p_prev is protected by the pool 257*7c478bd9Sstevel@tonic-gate * list lock. 258*7c478bd9Sstevel@tonic-gate */ 259*7c478bd9Sstevel@tonic-gate SVCPOOL *p_next; /* Next pool in the list */ 260*7c478bd9Sstevel@tonic-gate SVCPOOL *p_prev; /* Prev pool in the list */ 261*7c478bd9Sstevel@tonic-gate int p_id; /* Pool id */ 262*7c478bd9Sstevel@tonic-gate int p_threads; /* Non-detached threads */ 263*7c478bd9Sstevel@tonic-gate int p_detached_threads; /* Detached threads */ 264*7c478bd9Sstevel@tonic-gate int p_maxthreads; /* Max threads in the pool */ 265*7c478bd9Sstevel@tonic-gate int p_redline; /* `Redline' for the pool */ 266*7c478bd9Sstevel@tonic-gate int p_reserved_threads; /* Reserved threads */ 267*7c478bd9Sstevel@tonic-gate kmutex_t p_thread_lock; /* Thread lock */ 268*7c478bd9Sstevel@tonic-gate int p_asleep; /* Asleep threads */ 269*7c478bd9Sstevel@tonic-gate int p_drowsy; /* Drowsy flag */ 270*7c478bd9Sstevel@tonic-gate kcondvar_t p_req_cv; /* svc_poll() sleep var. */ 271*7c478bd9Sstevel@tonic-gate clock_t p_timeout; /* svc_poll() timeout */ 272*7c478bd9Sstevel@tonic-gate kmutex_t p_req_lock; /* Request lock */ 273*7c478bd9Sstevel@tonic-gate int p_reqs; /* Pending requests */ 274*7c478bd9Sstevel@tonic-gate int p_walkers; /* Walking threads */ 275*7c478bd9Sstevel@tonic-gate int p_max_same_xprt; /* Max reqs from the xprt */ 276*7c478bd9Sstevel@tonic-gate int p_stksize; /* Stack size for svc_run */ 277*7c478bd9Sstevel@tonic-gate bool_t p_closing : 1; /* Pool is closing */ 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate /* 280*7c478bd9Sstevel@tonic-gate * Thread creator variables. 281*7c478bd9Sstevel@tonic-gate * The `creator signaled' flag is turned on when a signal is send 282*7c478bd9Sstevel@tonic-gate * to the creator thread (to create a new service thread). The 283*7c478bd9Sstevel@tonic-gate * creator clears when the thread is created. The protocol is not 284*7c478bd9Sstevel@tonic-gate * to signal the creator thread when the flag is on. However, 285*7c478bd9Sstevel@tonic-gate * a new thread should signal the creator if there are more 286*7c478bd9Sstevel@tonic-gate * requests in the queue. 287*7c478bd9Sstevel@tonic-gate * 288*7c478bd9Sstevel@tonic-gate * When the pool is closing (ie it has been already unregistered from 289*7c478bd9Sstevel@tonic-gate * the pool list) the last thread on the last transport should turn 290*7c478bd9Sstevel@tonic-gate * the p_creator_exit flag on. This tells the creator thread to 291*7c478bd9Sstevel@tonic-gate * free the pool structure and exit. 292*7c478bd9Sstevel@tonic-gate */ 293*7c478bd9Sstevel@tonic-gate bool_t p_creator_signaled : 1; /* Create requested flag */ 294*7c478bd9Sstevel@tonic-gate bool_t p_creator_exit : 1; /* If true creator exits */ 295*7c478bd9Sstevel@tonic-gate kcondvar_t p_creator_cv; /* Creator cond. variable */ 296*7c478bd9Sstevel@tonic-gate kmutex_t p_creator_lock; /* Creator lock */ 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate /* 299*7c478bd9Sstevel@tonic-gate * Doubly linked list containing `registered' master transport handles. 300*7c478bd9Sstevel@tonic-gate * There is no special structure for a list node. Instead the 301*7c478bd9Sstevel@tonic-gate * SVCMASTERXPRT structure has the xp_next and xp_prev fields. 302*7c478bd9Sstevel@tonic-gate * 303*7c478bd9Sstevel@tonic-gate * The p_lrwlock protects access to xprt->xp_next and xprt->xp_prev. 304*7c478bd9Sstevel@tonic-gate * A service thread should also acquire a reader lock before accessing 305*7c478bd9Sstevel@tonic-gate * any transports it is no longer linked to (to prevent them from 306*7c478bd9Sstevel@tonic-gate * being destroyed). 307*7c478bd9Sstevel@tonic-gate * 308*7c478bd9Sstevel@tonic-gate * The list lock governs also the `pool is closing' flag. 309*7c478bd9Sstevel@tonic-gate */ 310*7c478bd9Sstevel@tonic-gate size_t p_lcount; /* Current count */ 311*7c478bd9Sstevel@tonic-gate SVCMASTERXPRT *p_lhead; /* List head */ 312*7c478bd9Sstevel@tonic-gate krwlock_t p_lrwlock; /* R/W lock */ 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate /* 315*7c478bd9Sstevel@tonic-gate * Circular linked list for the `xprt-ready' queue (FIFO). 316*7c478bd9Sstevel@tonic-gate * Must be initialized with svc_xprt_qinit() before it is used. 317*7c478bd9Sstevel@tonic-gate * 318*7c478bd9Sstevel@tonic-gate * The writer's end is protected by the pool's request lock 319*7c478bd9Sstevel@tonic-gate * (pool->p_req_lock). The reader's end is protected by q_end_lock. 320*7c478bd9Sstevel@tonic-gate * 321*7c478bd9Sstevel@tonic-gate * When the queue is full the p_qoverflow flag is raised. It stays 322*7c478bd9Sstevel@tonic-gate * on until all the pending request are drained. 323*7c478bd9Sstevel@tonic-gate */ 324*7c478bd9Sstevel@tonic-gate size_t p_qsize; /* Number of queue nodes */ 325*7c478bd9Sstevel@tonic-gate int p_qoverflow : 1; /* Overflow flag */ 326*7c478bd9Sstevel@tonic-gate __SVCXPRT_QNODE *p_qbody; /* Queue body (array) */ 327*7c478bd9Sstevel@tonic-gate __SVCXPRT_QNODE *p_qtop; /* Writer's end of FIFO */ 328*7c478bd9Sstevel@tonic-gate __SVCXPRT_QNODE *p_qend; /* Reader's end of FIFO */ 329*7c478bd9Sstevel@tonic-gate kmutex_t p_qend_lock; /* Reader's end lock */ 330*7c478bd9Sstevel@tonic-gate 331*7c478bd9Sstevel@tonic-gate /* 332*7c478bd9Sstevel@tonic-gate * Userspace thread creator variables. 333*7c478bd9Sstevel@tonic-gate * Thread creation is actually done in userland, via a thread 334*7c478bd9Sstevel@tonic-gate * that is parked in the kernel. When that thread is signaled, 335*7c478bd9Sstevel@tonic-gate * it returns back down to the daemon from whence it came and 336*7c478bd9Sstevel@tonic-gate * does the lwp create. 337*7c478bd9Sstevel@tonic-gate * 338*7c478bd9Sstevel@tonic-gate * A parallel "creator" thread runs in the kernel. That is the 339*7c478bd9Sstevel@tonic-gate * thread that will signal for the user thread to return to 340*7c478bd9Sstevel@tonic-gate * userland and do its work. 341*7c478bd9Sstevel@tonic-gate * 342*7c478bd9Sstevel@tonic-gate * Since the thread doesn't always exist (there could be a race 343*7c478bd9Sstevel@tonic-gate * if two threads are created in rapid succession), we set 344*7c478bd9Sstevel@tonic-gate * p_signal_create_thread to FALSE when we're ready to accept work. 345*7c478bd9Sstevel@tonic-gate * 346*7c478bd9Sstevel@tonic-gate * p_user_exit is set to true when the service pool is about 347*7c478bd9Sstevel@tonic-gate * to close. This is done so that the user creation thread 348*7c478bd9Sstevel@tonic-gate * can be informed and cleanup any userland state. 349*7c478bd9Sstevel@tonic-gate */ 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate bool_t p_signal_create_thread : 1; /* Create requested flag */ 352*7c478bd9Sstevel@tonic-gate bool_t p_user_exit : 1; /* If true creator exits */ 353*7c478bd9Sstevel@tonic-gate bool_t p_user_waiting : 1; /* Thread waiting for work */ 354*7c478bd9Sstevel@tonic-gate kcondvar_t p_user_cv; /* Creator cond. variable */ 355*7c478bd9Sstevel@tonic-gate kmutex_t p_user_lock; /* Creator lock */ 356*7c478bd9Sstevel@tonic-gate void (*p_offline)(); /* callout for unregister */ 357*7c478bd9Sstevel@tonic-gate void (*p_shutdown)(); /* callout for shutdown */ 358*7c478bd9Sstevel@tonic-gate }; 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate /* 361*7c478bd9Sstevel@tonic-gate * Server side transport handle (SVCMASTERXPRT). 362*7c478bd9Sstevel@tonic-gate * xprt->xp_req_lock governs the following fields in xprt: 363*7c478bd9Sstevel@tonic-gate * xp_req_head, xp_req_tail. 364*7c478bd9Sstevel@tonic-gate * xprt->xp_thread_lock governs the following fields in xprt: 365*7c478bd9Sstevel@tonic-gate * xp_threads, xp_detached_threads. 366*7c478bd9Sstevel@tonic-gate * 367*7c478bd9Sstevel@tonic-gate * xp_req_tail is only valid if xp_req_head is non-NULL 368*7c478bd9Sstevel@tonic-gate * 369*7c478bd9Sstevel@tonic-gate * The xp_threads count is the number of attached threads. These threads 370*7c478bd9Sstevel@tonic-gate * are able to handle new requests, and it is expected that they will not 371*7c478bd9Sstevel@tonic-gate * block for a very long time handling a given request. The 372*7c478bd9Sstevel@tonic-gate * xp_detached_threads count is the number of threads that have detached 373*7c478bd9Sstevel@tonic-gate * themselves from the transport. These threads can block indefinitely 374*7c478bd9Sstevel@tonic-gate * while handling a request. Once they complete the request, they exit. 375*7c478bd9Sstevel@tonic-gate * 376*7c478bd9Sstevel@tonic-gate * A kernel service provider may register a callback function "closeproc" 377*7c478bd9Sstevel@tonic-gate * for a transport. When the transport is closing the last exiting attached 378*7c478bd9Sstevel@tonic-gate * thread - xp_threads goes to zero - it calls the callback function, passing 379*7c478bd9Sstevel@tonic-gate * it a reference to the transport. This call is made with xp_thread_lock 380*7c478bd9Sstevel@tonic-gate * held, so any cleanup bookkeeping it does should be done quickly. 381*7c478bd9Sstevel@tonic-gate * 382*7c478bd9Sstevel@tonic-gate * When the transport is closing the last exiting thread is supposed 383*7c478bd9Sstevel@tonic-gate * to destroy/free the data structure. 384*7c478bd9Sstevel@tonic-gate */ 385*7c478bd9Sstevel@tonic-gate typedef struct __svcxprt_common { 386*7c478bd9Sstevel@tonic-gate struct file *xpc_fp; 387*7c478bd9Sstevel@tonic-gate struct svc_ops *xpc_ops; 388*7c478bd9Sstevel@tonic-gate queue_t *xpc_wq; /* queue to write onto */ 389*7c478bd9Sstevel@tonic-gate cred_t *xpc_cred; /* cached cred for server to use */ 390*7c478bd9Sstevel@tonic-gate int32_t xpc_type; /* transport type */ 391*7c478bd9Sstevel@tonic-gate int xpc_msg_size; /* TSDU or TIDU size */ 392*7c478bd9Sstevel@tonic-gate struct netbuf xpc_rtaddr; /* remote transport address */ 393*7c478bd9Sstevel@tonic-gate SVC_CALLOUT_TABLE *xpc_sct; 394*7c478bd9Sstevel@tonic-gate } __SVCXPRT_COMMON; 395*7c478bd9Sstevel@tonic-gate 396*7c478bd9Sstevel@tonic-gate #define xp_fp xp_xpc.xpc_fp 397*7c478bd9Sstevel@tonic-gate #define xp_ops xp_xpc.xpc_ops 398*7c478bd9Sstevel@tonic-gate #define xp_wq xp_xpc.xpc_wq 399*7c478bd9Sstevel@tonic-gate #define xp_cred xp_xpc.xpc_cred 400*7c478bd9Sstevel@tonic-gate #define xp_type xp_xpc.xpc_type 401*7c478bd9Sstevel@tonic-gate #define xp_msg_size xp_xpc.xpc_msg_size 402*7c478bd9Sstevel@tonic-gate #define xp_rtaddr xp_xpc.xpc_rtaddr 403*7c478bd9Sstevel@tonic-gate #define xp_sct xp_xpc.xpc_sct 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate struct __svcmasterxprt { 406*7c478bd9Sstevel@tonic-gate SVCMASTERXPRT *xp_next; /* Next transport in the list */ 407*7c478bd9Sstevel@tonic-gate SVCMASTERXPRT *xp_prev; /* Prev transport in the list */ 408*7c478bd9Sstevel@tonic-gate __SVCXPRT_COMMON xp_xpc; /* Fields common with the clone */ 409*7c478bd9Sstevel@tonic-gate SVCPOOL *xp_pool; /* Pointer to the pool */ 410*7c478bd9Sstevel@tonic-gate mblk_t *xp_req_head; /* Request queue head */ 411*7c478bd9Sstevel@tonic-gate mblk_t *xp_req_tail; /* Request queue tail */ 412*7c478bd9Sstevel@tonic-gate kmutex_t xp_req_lock; /* Request lock */ 413*7c478bd9Sstevel@tonic-gate int xp_threads; /* Current num. of attached threads */ 414*7c478bd9Sstevel@tonic-gate int xp_detached_threads; /* num. of detached threads */ 415*7c478bd9Sstevel@tonic-gate kmutex_t xp_thread_lock; /* Thread count lock */ 416*7c478bd9Sstevel@tonic-gate void (*xp_closeproc)(const SVCMASTERXPRT *); 417*7c478bd9Sstevel@tonic-gate /* optional; see comments above */ 418*7c478bd9Sstevel@tonic-gate char *xp_netid; /* network token */ 419*7c478bd9Sstevel@tonic-gate struct netbuf xp_addrmask; /* address mask */ 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate caddr_t xp_p2; /* private: for use by svc ops */ 422*7c478bd9Sstevel@tonic-gate }; 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate /* 425*7c478bd9Sstevel@tonic-gate * Service thread `clone' transport handle (SVCXPRT) 426*7c478bd9Sstevel@tonic-gate * 427*7c478bd9Sstevel@tonic-gate * PSARC 2003/523 Contract Private Interface 428*7c478bd9Sstevel@tonic-gate * SVCXPRT 429*7c478bd9Sstevel@tonic-gate * Changes must be reviewed by Solaris File Sharing 430*7c478bd9Sstevel@tonic-gate * Changes must be communicated to contract-2003-523@sun.com 431*7c478bd9Sstevel@tonic-gate * 432*7c478bd9Sstevel@tonic-gate * The xp_p2buf buffer is used as the storage for a transport type 433*7c478bd9Sstevel@tonic-gate * specific structure. It is private for the svc ops for a given 434*7c478bd9Sstevel@tonic-gate * transport type. 435*7c478bd9Sstevel@tonic-gate */ 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate #define SVC_P2LEN 64 438*7c478bd9Sstevel@tonic-gate 439*7c478bd9Sstevel@tonic-gate struct __svcxprt { 440*7c478bd9Sstevel@tonic-gate __SVCXPRT_COMMON xp_xpc; 441*7c478bd9Sstevel@tonic-gate SVCMASTERXPRT *xp_master; /* back ptr to master */ 442*7c478bd9Sstevel@tonic-gate 443*7c478bd9Sstevel@tonic-gate /* The following fileds are on a per-thread basis */ 444*7c478bd9Sstevel@tonic-gate callb_cpr_t *xp_cprp; /* unused padding for Contract */ 445*7c478bd9Sstevel@tonic-gate bool_t xp_reserved : 1; /* is thread reserved? */ 446*7c478bd9Sstevel@tonic-gate bool_t xp_detached : 1; /* is thread detached? */ 447*7c478bd9Sstevel@tonic-gate int xp_same_xprt; /* Reqs from the same xprt */ 448*7c478bd9Sstevel@tonic-gate 449*7c478bd9Sstevel@tonic-gate /* The following fields are used on a per-request basis */ 450*7c478bd9Sstevel@tonic-gate struct opaque_auth xp_verf; /* raw response verifier */ 451*7c478bd9Sstevel@tonic-gate SVCAUTH xp_auth; /* auth flavor of current req */ 452*7c478bd9Sstevel@tonic-gate void *xp_cookie; /* a cookie */ 453*7c478bd9Sstevel@tonic-gate uint32_t xp_xid; /* id */ 454*7c478bd9Sstevel@tonic-gate XDR xp_xdrin; /* input xdr stream */ 455*7c478bd9Sstevel@tonic-gate XDR xp_xdrout; /* output xdr stream */ 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate /* Private for svc ops */ 458*7c478bd9Sstevel@tonic-gate char xp_p2buf[SVC_P2LEN]; /* udp_data or cots_data_t */ 459*7c478bd9Sstevel@tonic-gate /* or clone_rdma_data_t */ 460*7c478bd9Sstevel@tonic-gate }; 461*7c478bd9Sstevel@tonic-gate #else /* _KERNEL */ 462*7c478bd9Sstevel@tonic-gate struct __svcxprt { 463*7c478bd9Sstevel@tonic-gate int xp_fd; 464*7c478bd9Sstevel@tonic-gate #define xp_sock xp_fd 465*7c478bd9Sstevel@tonic-gate ushort_t xp_port; 466*7c478bd9Sstevel@tonic-gate /* 467*7c478bd9Sstevel@tonic-gate * associated port number. 468*7c478bd9Sstevel@tonic-gate * Obsolete, but still used to 469*7c478bd9Sstevel@tonic-gate * specify whether rendezvouser 470*7c478bd9Sstevel@tonic-gate * or normal connection 471*7c478bd9Sstevel@tonic-gate */ 472*7c478bd9Sstevel@tonic-gate struct xp_ops *xp_ops; 473*7c478bd9Sstevel@tonic-gate int xp_addrlen; /* length of remote addr. Obsoleted */ 474*7c478bd9Sstevel@tonic-gate char *xp_tp; /* transport provider device name */ 475*7c478bd9Sstevel@tonic-gate char *xp_netid; /* network token */ 476*7c478bd9Sstevel@tonic-gate struct netbuf xp_ltaddr; /* local transport address */ 477*7c478bd9Sstevel@tonic-gate struct netbuf xp_rtaddr; /* remote transport address */ 478*7c478bd9Sstevel@tonic-gate char xp_raddr[16]; /* remote address. Now obsoleted */ 479*7c478bd9Sstevel@tonic-gate struct opaque_auth xp_verf; /* raw response verifier */ 480*7c478bd9Sstevel@tonic-gate caddr_t xp_p1; /* private: for use by svc ops */ 481*7c478bd9Sstevel@tonic-gate caddr_t xp_p2; /* private: for use by svc ops */ 482*7c478bd9Sstevel@tonic-gate caddr_t xp_p3; /* private: for use by svc lib */ 483*7c478bd9Sstevel@tonic-gate int xp_type; /* transport type */ 484*7c478bd9Sstevel@tonic-gate /* 485*7c478bd9Sstevel@tonic-gate * callback on client death 486*7c478bd9Sstevel@tonic-gate * First parameter is the current structure, 487*7c478bd9Sstevel@tonic-gate * Second parameter : 488*7c478bd9Sstevel@tonic-gate * - FALSE for the service listener 489*7c478bd9Sstevel@tonic-gate * - TRUE for a real connected socket 490*7c478bd9Sstevel@tonic-gate */ 491*7c478bd9Sstevel@tonic-gate svc_errorhandler_t xp_closeclnt; 492*7c478bd9Sstevel@tonic-gate }; 493*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 494*7c478bd9Sstevel@tonic-gate 495*7c478bd9Sstevel@tonic-gate /* 496*7c478bd9Sstevel@tonic-gate * Approved way of getting address of caller, 497*7c478bd9Sstevel@tonic-gate * address mask, and netid of transport. 498*7c478bd9Sstevel@tonic-gate */ 499*7c478bd9Sstevel@tonic-gate #define svc_getrpccaller(x) (&(x)->xp_rtaddr) 500*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 501*7c478bd9Sstevel@tonic-gate #define svc_getcaller(x) (&(x)->xp_rtaddr.buf) 502*7c478bd9Sstevel@tonic-gate #define svc_getaddrmask(x) (&(x)->xp_master->xp_addrmask) 503*7c478bd9Sstevel@tonic-gate #define svc_getnetid(x) ((x)->xp_master->xp_netid) 504*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate /* 507*7c478bd9Sstevel@tonic-gate * Operations defined on an SVCXPRT handle 508*7c478bd9Sstevel@tonic-gate */ 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 511*7c478bd9Sstevel@tonic-gate #define SVC_RECV(clone_xprt, mp, msg) \ 512*7c478bd9Sstevel@tonic-gate (*(clone_xprt)->xp_ops->xp_recv)((clone_xprt), (mp), (msg)) 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate /* 515*7c478bd9Sstevel@tonic-gate * PSARC 2003/523 Contract Private Interface 516*7c478bd9Sstevel@tonic-gate * SVC_GETARGS 517*7c478bd9Sstevel@tonic-gate * Changes must be reviewed by Solaris File Sharing 518*7c478bd9Sstevel@tonic-gate * Changes must be communicated to contract-2003-523@sun.com 519*7c478bd9Sstevel@tonic-gate */ 520*7c478bd9Sstevel@tonic-gate #define SVC_GETARGS(clone_xprt, xargs, argsp) \ 521*7c478bd9Sstevel@tonic-gate (*(clone_xprt)->xp_ops->xp_getargs)((clone_xprt), (xargs), (argsp)) 522*7c478bd9Sstevel@tonic-gate 523*7c478bd9Sstevel@tonic-gate #define SVC_REPLY(clone_xprt, msg) \ 524*7c478bd9Sstevel@tonic-gate (*(clone_xprt)->xp_ops->xp_reply) ((clone_xprt), (msg)) 525*7c478bd9Sstevel@tonic-gate 526*7c478bd9Sstevel@tonic-gate #define SVC_FREEARGS(clone_xprt, xargs, argsp) \ 527*7c478bd9Sstevel@tonic-gate (*(clone_xprt)->xp_ops->xp_freeargs)((clone_xprt), (xargs), (argsp)) 528*7c478bd9Sstevel@tonic-gate 529*7c478bd9Sstevel@tonic-gate #define SVC_GETRES(clone_xprt, size) \ 530*7c478bd9Sstevel@tonic-gate (*(clone_xprt)->xp_ops->xp_getres)((clone_xprt), (size)) 531*7c478bd9Sstevel@tonic-gate 532*7c478bd9Sstevel@tonic-gate #define SVC_FREERES(clone_xprt) \ 533*7c478bd9Sstevel@tonic-gate (*(clone_xprt)->xp_ops->xp_freeres)(clone_xprt) 534*7c478bd9Sstevel@tonic-gate 535*7c478bd9Sstevel@tonic-gate #define SVC_DESTROY(xprt) \ 536*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_destroy)(xprt) 537*7c478bd9Sstevel@tonic-gate 538*7c478bd9Sstevel@tonic-gate /* 539*7c478bd9Sstevel@tonic-gate * PSARC 2003/523 Contract Private Interfaces 540*7c478bd9Sstevel@tonic-gate * SVC_DUP, SVC_DUPDONE, SVC_DUP_EXT, SVC_DUPDONE_EXT 541*7c478bd9Sstevel@tonic-gate * Changes must be reviewed by Solaris File Sharing 542*7c478bd9Sstevel@tonic-gate * Changes must be communicated to contract-2003-523@sun.com 543*7c478bd9Sstevel@tonic-gate * 544*7c478bd9Sstevel@tonic-gate * SVC_DUP and SVC_DUPDONE are defined here for backward compatibility. 545*7c478bd9Sstevel@tonic-gate */ 546*7c478bd9Sstevel@tonic-gate #define SVC_DUP_EXT(clone_xprt, req, res, size, drpp, dupcachedp) \ 547*7c478bd9Sstevel@tonic-gate (*(clone_xprt)->xp_ops->xp_dup)(req, res, size, drpp, dupcachedp) 548*7c478bd9Sstevel@tonic-gate 549*7c478bd9Sstevel@tonic-gate #define SVC_DUPDONE_EXT(clone_xprt, dr, res, resfree, size, status) \ 550*7c478bd9Sstevel@tonic-gate (*(clone_xprt)->xp_ops->xp_dupdone)(dr, res, resfree, size, status) 551*7c478bd9Sstevel@tonic-gate 552*7c478bd9Sstevel@tonic-gate #define SVC_DUP(clone_xprt, req, res, size, drpp) \ 553*7c478bd9Sstevel@tonic-gate (*(clone_xprt)->xp_ops->xp_dup)(req, res, size, drpp, NULL) 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate #define SVC_DUPDONE(clone_xprt, dr, res, size, status) \ 556*7c478bd9Sstevel@tonic-gate (*(clone_xprt)->xp_ops->xp_dupdone)(dr, res, NULL, size, status) 557*7c478bd9Sstevel@tonic-gate 558*7c478bd9Sstevel@tonic-gate #define SVC_CLONE_DESTROY(clone_xprt) \ 559*7c478bd9Sstevel@tonic-gate (*(clone_xprt)->xp_ops->xp_clone_destroy)(clone_xprt) 560*7c478bd9Sstevel@tonic-gate 561*7c478bd9Sstevel@tonic-gate 562*7c478bd9Sstevel@tonic-gate #define SVC_START(xprt) \ 563*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_start)(xprt) 564*7c478bd9Sstevel@tonic-gate 565*7c478bd9Sstevel@tonic-gate #else /* _KERNEL */ 566*7c478bd9Sstevel@tonic-gate 567*7c478bd9Sstevel@tonic-gate #define SVC_RECV(xprt, msg) \ 568*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) 569*7c478bd9Sstevel@tonic-gate #define svc_recv(xprt, msg) \ 570*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) 571*7c478bd9Sstevel@tonic-gate 572*7c478bd9Sstevel@tonic-gate #define SVC_STAT(xprt) \ 573*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_stat)(xprt) 574*7c478bd9Sstevel@tonic-gate #define svc_stat(xprt) \ 575*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_stat)(xprt) 576*7c478bd9Sstevel@tonic-gate 577*7c478bd9Sstevel@tonic-gate #define SVC_GETARGS(xprt, xargs, argsp) \ 578*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) 579*7c478bd9Sstevel@tonic-gate #define svc_getargs(xprt, xargs, argsp) \ 580*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate #define SVC_REPLY(xprt, msg) \ 583*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) 584*7c478bd9Sstevel@tonic-gate #define svc_reply(xprt, msg) \ 585*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) 586*7c478bd9Sstevel@tonic-gate 587*7c478bd9Sstevel@tonic-gate #define SVC_FREEARGS(xprt, xargs, argsp) \ 588*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) 589*7c478bd9Sstevel@tonic-gate #define svc_freeargs(xprt, xargs, argsp) \ 590*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate #define SVC_GETRES(xprt, size) \ 593*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_getres)((xprt), (size)) 594*7c478bd9Sstevel@tonic-gate #define svc_getres(xprt, size) \ 595*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_getres)((xprt), (size)) 596*7c478bd9Sstevel@tonic-gate 597*7c478bd9Sstevel@tonic-gate #define SVC_FREERES(xprt) \ 598*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_freeres)(xprt) 599*7c478bd9Sstevel@tonic-gate #define svc_freeres(xprt) \ 600*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_freeres)(xprt) 601*7c478bd9Sstevel@tonic-gate 602*7c478bd9Sstevel@tonic-gate #define SVC_DESTROY(xprt) \ 603*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_destroy)(xprt) 604*7c478bd9Sstevel@tonic-gate #define svc_destroy(xprt) \ 605*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_destroy)(xprt) 606*7c478bd9Sstevel@tonic-gate 607*7c478bd9Sstevel@tonic-gate /* 608*7c478bd9Sstevel@tonic-gate * PSARC 2003/523 Contract Private Interface 609*7c478bd9Sstevel@tonic-gate * SVC_CONTROL 610*7c478bd9Sstevel@tonic-gate * Changes must be reviewed by Solaris File Sharing 611*7c478bd9Sstevel@tonic-gate * Changes must be communicated to contract-2003-523@sun.com 612*7c478bd9Sstevel@tonic-gate */ 613*7c478bd9Sstevel@tonic-gate #define SVC_CONTROL(xprt, rq, in) \ 614*7c478bd9Sstevel@tonic-gate (*(xprt)->xp_ops->xp_control)((xprt), (rq), (in)) 615*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 616*7c478bd9Sstevel@tonic-gate 617*7c478bd9Sstevel@tonic-gate /* 618*7c478bd9Sstevel@tonic-gate * Pool id's reserved for NFS, NLM, and the NFSv4 callback program. 619*7c478bd9Sstevel@tonic-gate */ 620*7c478bd9Sstevel@tonic-gate #define NFS_SVCPOOL_ID 0x01 621*7c478bd9Sstevel@tonic-gate #define NLM_SVCPOOL_ID 0x02 622*7c478bd9Sstevel@tonic-gate #define NFS_CB_SVCPOOL_ID 0x03 623*7c478bd9Sstevel@tonic-gate #define RDC_SVCPOOL_ID 0x05 /* SNDR, PSARC 2001/699 */ 624*7c478bd9Sstevel@tonic-gate 625*7c478bd9Sstevel@tonic-gate struct svcpool_args { 626*7c478bd9Sstevel@tonic-gate uint32_t id; /* Pool id */ 627*7c478bd9Sstevel@tonic-gate uint32_t maxthreads; /* Max threads in the pool */ 628*7c478bd9Sstevel@tonic-gate uint32_t redline; /* `Redline' for the pool */ 629*7c478bd9Sstevel@tonic-gate uint32_t qsize; /* `xprt-ready' queue size */ 630*7c478bd9Sstevel@tonic-gate uint32_t timeout; /* svc_poll() timeout */ 631*7c478bd9Sstevel@tonic-gate uint32_t stksize; /* svc_run() stack size */ 632*7c478bd9Sstevel@tonic-gate uint32_t max_same_xprt; /* Max reqs from the same xprt */ 633*7c478bd9Sstevel@tonic-gate }; 634*7c478bd9Sstevel@tonic-gate 635*7c478bd9Sstevel@tonic-gate 636*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 637*7c478bd9Sstevel@tonic-gate /* 638*7c478bd9Sstevel@tonic-gate * Transport registration and thread pool creation. 639*7c478bd9Sstevel@tonic-gate */ 640*7c478bd9Sstevel@tonic-gate extern int svc_xprt_register(SVCMASTERXPRT *, int); 641*7c478bd9Sstevel@tonic-gate extern void svc_xprt_unregister(SVCMASTERXPRT *); 642*7c478bd9Sstevel@tonic-gate extern int svc_pool_create(struct svcpool_args *); 643*7c478bd9Sstevel@tonic-gate extern int svc_wait(int); 644*7c478bd9Sstevel@tonic-gate extern int svc_do_run(int); 645*7c478bd9Sstevel@tonic-gate #define SVCPSET_SHUTDOWN_PROC 1 646*7c478bd9Sstevel@tonic-gate #define SVCPSET_UNREGISTER_PROC 2 647*7c478bd9Sstevel@tonic-gate extern int svc_pool_control(int, int, void *); 648*7c478bd9Sstevel@tonic-gate #else /* _KERNEL */ 649*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 650*7c478bd9Sstevel@tonic-gate extern bool_t rpc_reg(const rpcprog_t, const rpcvers_t, const rpcproc_t, 651*7c478bd9Sstevel@tonic-gate char *(*)(char *), const xdrproc_t, const xdrproc_t, 652*7c478bd9Sstevel@tonic-gate const char *); 653*7c478bd9Sstevel@tonic-gate 654*7c478bd9Sstevel@tonic-gate /* 655*7c478bd9Sstevel@tonic-gate * Service registration 656*7c478bd9Sstevel@tonic-gate * 657*7c478bd9Sstevel@tonic-gate * svc_reg(xprt, prog, vers, dispatch, nconf) 658*7c478bd9Sstevel@tonic-gate * const SVCXPRT *xprt; 659*7c478bd9Sstevel@tonic-gate * const rpcprog_t prog; 660*7c478bd9Sstevel@tonic-gate * const rpcvers_t vers; 661*7c478bd9Sstevel@tonic-gate * const void (*dispatch)(); 662*7c478bd9Sstevel@tonic-gate * const struct netconfig *nconf; 663*7c478bd9Sstevel@tonic-gate */ 664*7c478bd9Sstevel@tonic-gate extern bool_t svc_reg(const SVCXPRT *, const rpcprog_t, const rpcvers_t, 665*7c478bd9Sstevel@tonic-gate void (*)(struct svc_req *, SVCXPRT *), 666*7c478bd9Sstevel@tonic-gate const struct netconfig *); 667*7c478bd9Sstevel@tonic-gate 668*7c478bd9Sstevel@tonic-gate /* 669*7c478bd9Sstevel@tonic-gate * Service authentication registration 670*7c478bd9Sstevel@tonic-gate * 671*7c478bd9Sstevel@tonic-gate * svc_auth_reg(cred_flavor, handler) 672*7c478bd9Sstevel@tonic-gate * int cred_flavor; 673*7c478bd9Sstevel@tonic-gate * enum auth_stat (*handler)(); 674*7c478bd9Sstevel@tonic-gate */ 675*7c478bd9Sstevel@tonic-gate extern int svc_auth_reg(int, enum auth_stat (*)()); 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate /* 678*7c478bd9Sstevel@tonic-gate * Service un-registration 679*7c478bd9Sstevel@tonic-gate * 680*7c478bd9Sstevel@tonic-gate * svc_unreg(prog, vers) 681*7c478bd9Sstevel@tonic-gate * const rpcprog_t prog; 682*7c478bd9Sstevel@tonic-gate * const rpcvers_t vers; 683*7c478bd9Sstevel@tonic-gate */ 684*7c478bd9Sstevel@tonic-gate extern void svc_unreg(const rpcprog_t, const rpcvers_t); 685*7c478bd9Sstevel@tonic-gate 686*7c478bd9Sstevel@tonic-gate /* 687*7c478bd9Sstevel@tonic-gate * Transport registration/unregistration. 688*7c478bd9Sstevel@tonic-gate * 689*7c478bd9Sstevel@tonic-gate * xprt_register(xprt) 690*7c478bd9Sstevel@tonic-gate * const SVCXPRT *xprt; 691*7c478bd9Sstevel@tonic-gate * 692*7c478bd9Sstevel@tonic-gate * xprt_unregister(xprt) 693*7c478bd9Sstevel@tonic-gate * const SVCXPRT *xprt; 694*7c478bd9Sstevel@tonic-gate */ 695*7c478bd9Sstevel@tonic-gate extern void xprt_register(const SVCXPRT *); 696*7c478bd9Sstevel@tonic-gate extern void xprt_unregister(const SVCXPRT *); 697*7c478bd9Sstevel@tonic-gate #else /* __STDC__ */ 698*7c478bd9Sstevel@tonic-gate extern bool_t rpc_reg(); 699*7c478bd9Sstevel@tonic-gate extern bool_t svc_reg(); 700*7c478bd9Sstevel@tonic-gate extern bool_t svc_auth_reg(); 701*7c478bd9Sstevel@tonic-gate extern void svc_unreg(); 702*7c478bd9Sstevel@tonic-gate extern void xprt_register(); 703*7c478bd9Sstevel@tonic-gate extern void xprt_unregister(); 704*7c478bd9Sstevel@tonic-gate #endif /* __STDC__ */ 705*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 706*7c478bd9Sstevel@tonic-gate 707*7c478bd9Sstevel@tonic-gate 708*7c478bd9Sstevel@tonic-gate /* 709*7c478bd9Sstevel@tonic-gate * When the service routine is called, it must first check to see if it 710*7c478bd9Sstevel@tonic-gate * knows about the procedure; if not, it should call svcerr_noproc 711*7c478bd9Sstevel@tonic-gate * and return. If so, it should deserialize its arguments via 712*7c478bd9Sstevel@tonic-gate * SVC_GETARGS (defined above). If the deserialization does not work, 713*7c478bd9Sstevel@tonic-gate * svcerr_decode should be called followed by a return. Successful 714*7c478bd9Sstevel@tonic-gate * decoding of the arguments should be followed the execution of the 715*7c478bd9Sstevel@tonic-gate * procedure's code and a call to svc_sendreply. 716*7c478bd9Sstevel@tonic-gate * 717*7c478bd9Sstevel@tonic-gate * Also, if the service refuses to execute the procedure due to too- 718*7c478bd9Sstevel@tonic-gate * weak authentication parameters, svcerr_weakauth should be called. 719*7c478bd9Sstevel@tonic-gate * Note: do not confuse access-control failure with weak authentication! 720*7c478bd9Sstevel@tonic-gate * 721*7c478bd9Sstevel@tonic-gate * NB: In pure implementations of rpc, the caller always waits for a reply 722*7c478bd9Sstevel@tonic-gate * msg. This message is sent when svc_sendreply is called. 723*7c478bd9Sstevel@tonic-gate * Therefore pure service implementations should always call 724*7c478bd9Sstevel@tonic-gate * svc_sendreply even if the function logically returns void; use 725*7c478bd9Sstevel@tonic-gate * xdr.h - xdr_void for the xdr routine. HOWEVER, connectionful rpc allows 726*7c478bd9Sstevel@tonic-gate * for the abuse of pure rpc via batched calling or pipelining. In the 727*7c478bd9Sstevel@tonic-gate * case of a batched call, svc_sendreply should NOT be called since 728*7c478bd9Sstevel@tonic-gate * this would send a return message, which is what batching tries to avoid. 729*7c478bd9Sstevel@tonic-gate * It is the service/protocol writer's responsibility to know which calls are 730*7c478bd9Sstevel@tonic-gate * batched and which are not. Warning: responding to batch calls may 731*7c478bd9Sstevel@tonic-gate * deadlock the caller and server processes! 732*7c478bd9Sstevel@tonic-gate */ 733*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 734*7c478bd9Sstevel@tonic-gate extern bool_t svc_sendreply(const SVCXPRT *, const xdrproc_t, const caddr_t); 735*7c478bd9Sstevel@tonic-gate extern void svcerr_decode(const SVCXPRT *); 736*7c478bd9Sstevel@tonic-gate extern void svcerr_weakauth(const SVCXPRT *); 737*7c478bd9Sstevel@tonic-gate extern void svcerr_noproc(const SVCXPRT *); 738*7c478bd9Sstevel@tonic-gate extern void svcerr_progvers(const SVCXPRT *, const rpcvers_t, 739*7c478bd9Sstevel@tonic-gate const rpcvers_t); 740*7c478bd9Sstevel@tonic-gate extern void svcerr_auth(const SVCXPRT *, const enum auth_stat); 741*7c478bd9Sstevel@tonic-gate extern void svcerr_noprog(const SVCXPRT *); 742*7c478bd9Sstevel@tonic-gate extern void svcerr_systemerr(const SVCXPRT *); 743*7c478bd9Sstevel@tonic-gate #else /* __STDC__ */ 744*7c478bd9Sstevel@tonic-gate extern bool_t svc_sendreply(); 745*7c478bd9Sstevel@tonic-gate extern void svcerr_decode(); 746*7c478bd9Sstevel@tonic-gate extern void svcerr_weakauth(); 747*7c478bd9Sstevel@tonic-gate extern void svcerr_noproc(); 748*7c478bd9Sstevel@tonic-gate extern void svcerr_progvers(); 749*7c478bd9Sstevel@tonic-gate extern void svcerr_auth(); 750*7c478bd9Sstevel@tonic-gate extern void svcerr_noprog(); 751*7c478bd9Sstevel@tonic-gate extern void svcerr_systemerr(); 752*7c478bd9Sstevel@tonic-gate #endif /* __STDC__ */ 753*7c478bd9Sstevel@tonic-gate 754*7c478bd9Sstevel@tonic-gate #ifdef _KERNEL 755*7c478bd9Sstevel@tonic-gate /* 756*7c478bd9Sstevel@tonic-gate * Kernel RPC functions. 757*7c478bd9Sstevel@tonic-gate */ 758*7c478bd9Sstevel@tonic-gate extern void svc_init(void); 759*7c478bd9Sstevel@tonic-gate extern void svc_cots_init(void); 760*7c478bd9Sstevel@tonic-gate extern void svc_clts_init(void); 761*7c478bd9Sstevel@tonic-gate extern void mt_kstat_init(void); 762*7c478bd9Sstevel@tonic-gate extern void mt_kstat_fini(void); 763*7c478bd9Sstevel@tonic-gate extern int svc_tli_kcreate(struct file *, uint_t, char *, 764*7c478bd9Sstevel@tonic-gate struct netbuf *, SVCMASTERXPRT **, 765*7c478bd9Sstevel@tonic-gate SVC_CALLOUT_TABLE *, 766*7c478bd9Sstevel@tonic-gate void (*closeproc)(const SVCMASTERXPRT *), 767*7c478bd9Sstevel@tonic-gate int, bool_t); 768*7c478bd9Sstevel@tonic-gate extern int svc_clts_kcreate(struct file *, uint_t, struct T_info_ack *, 769*7c478bd9Sstevel@tonic-gate SVCMASTERXPRT **); 770*7c478bd9Sstevel@tonic-gate extern int svc_cots_kcreate(struct file *, uint_t, struct T_info_ack *, 771*7c478bd9Sstevel@tonic-gate SVCMASTERXPRT **); 772*7c478bd9Sstevel@tonic-gate extern void svc_queuereq(queue_t *, mblk_t *); 773*7c478bd9Sstevel@tonic-gate extern void svc_queueclean(queue_t *); 774*7c478bd9Sstevel@tonic-gate extern void svc_queueclose(queue_t *); 775*7c478bd9Sstevel@tonic-gate extern int svc_reserve_thread(SVCXPRT *); 776*7c478bd9Sstevel@tonic-gate extern void svc_unreserve_thread(SVCXPRT *); 777*7c478bd9Sstevel@tonic-gate extern callb_cpr_t *svc_detach_thread(SVCXPRT *); 778*7c478bd9Sstevel@tonic-gate 779*7c478bd9Sstevel@tonic-gate /* 780*7c478bd9Sstevel@tonic-gate * For RDMA based kRPC. 781*7c478bd9Sstevel@tonic-gate * "rdma_xprt_record" is a reference to master transport handles 782*7c478bd9Sstevel@tonic-gate * in kRPC thread pools. This is an easy way of tracking and shuting 783*7c478bd9Sstevel@tonic-gate * down rdma based kRPC transports on demand. 784*7c478bd9Sstevel@tonic-gate * "rdma_xprt_group" is a list of RDMA based mster transport handles 785*7c478bd9Sstevel@tonic-gate * or records in a kRPC thread pool. 786*7c478bd9Sstevel@tonic-gate */ 787*7c478bd9Sstevel@tonic-gate typedef struct rdma_xprt_record rdma_xprt_record_t; 788*7c478bd9Sstevel@tonic-gate struct rdma_xprt_record { 789*7c478bd9Sstevel@tonic-gate int rtr_type; /* Type of rdma; IB/VI/RDDP */ 790*7c478bd9Sstevel@tonic-gate SVCMASTERXPRT *rtr_xprt_ptr; /* Ptr to master xprt handle */ 791*7c478bd9Sstevel@tonic-gate rdma_xprt_record_t *rtr_next; /* Ptr to next record */ 792*7c478bd9Sstevel@tonic-gate }; 793*7c478bd9Sstevel@tonic-gate 794*7c478bd9Sstevel@tonic-gate typedef struct { 795*7c478bd9Sstevel@tonic-gate int rtg_count; /* Number transport records */ 796*7c478bd9Sstevel@tonic-gate int rtg_poolid; /* Pool Id for this group */ 797*7c478bd9Sstevel@tonic-gate rdma_xprt_record_t *rtg_listhead; /* Head of the records list */ 798*7c478bd9Sstevel@tonic-gate } rdma_xprt_group_t; 799*7c478bd9Sstevel@tonic-gate 800*7c478bd9Sstevel@tonic-gate extern int svc_rdma_kcreate(char *, SVC_CALLOUT_TABLE *, int, 801*7c478bd9Sstevel@tonic-gate rdma_xprt_group_t *); 802*7c478bd9Sstevel@tonic-gate extern void svc_rdma_kstop(SVCMASTERXPRT *); 803*7c478bd9Sstevel@tonic-gate extern void svc_rdma_kdestroy(SVCMASTERXPRT *); 804*7c478bd9Sstevel@tonic-gate extern void rdma_stop(rdma_xprt_group_t); 805*7c478bd9Sstevel@tonic-gate 806*7c478bd9Sstevel@tonic-gate /* 807*7c478bd9Sstevel@tonic-gate * GSS cleanup method. 808*7c478bd9Sstevel@tonic-gate */ 809*7c478bd9Sstevel@tonic-gate extern void rpc_gss_cleanup(SVCXPRT *); 810*7c478bd9Sstevel@tonic-gate #else /* _KERNEL */ 811*7c478bd9Sstevel@tonic-gate /* 812*7c478bd9Sstevel@tonic-gate * Lowest level dispatching -OR- who owns this process anyway. 813*7c478bd9Sstevel@tonic-gate * Somebody has to wait for incoming requests and then call the correct 814*7c478bd9Sstevel@tonic-gate * service routine. The routine svc_run does infinite waiting; i.e., 815*7c478bd9Sstevel@tonic-gate * svc_run never returns. 816*7c478bd9Sstevel@tonic-gate * Since another (co-existant) package may wish to selectively wait for 817*7c478bd9Sstevel@tonic-gate * incoming calls or other events outside of the rpc architecture, the 818*7c478bd9Sstevel@tonic-gate * routine svc_getreq_poll is provided. It must be passed pollfds, the 819*7c478bd9Sstevel@tonic-gate * "in-place" results of a poll call (see poll, section 2). 820*7c478bd9Sstevel@tonic-gate */ 821*7c478bd9Sstevel@tonic-gate 822*7c478bd9Sstevel@tonic-gate /* 823*7c478bd9Sstevel@tonic-gate * Global keeper of rpc service descriptors in use 824*7c478bd9Sstevel@tonic-gate * dynamic; must be inspected before each call to select or poll 825*7c478bd9Sstevel@tonic-gate */ 826*7c478bd9Sstevel@tonic-gate extern pollfd_t *svc_pollfd; 827*7c478bd9Sstevel@tonic-gate extern int svc_max_pollfd; 828*7c478bd9Sstevel@tonic-gate extern fd_set svc_fdset; 829*7c478bd9Sstevel@tonic-gate #if !defined(_LP64) && FD_SETSIZE > 1024 830*7c478bd9Sstevel@tonic-gate extern fd_set _new_svc_fdset; 831*7c478bd9Sstevel@tonic-gate #ifdef __PRAGMA_REDEFINE_EXTNAME 832*7c478bd9Sstevel@tonic-gate #pragma redefine_extname svc_fdset _new_svc_fdset 833*7c478bd9Sstevel@tonic-gate #else /* __PRAGMA_REDEFINE_EXTNAME */ 834*7c478bd9Sstevel@tonic-gate #define svc_fdset _new_svc_fdset 835*7c478bd9Sstevel@tonic-gate #endif /* __PRAGMA_REDEFINE_EXTNAME */ 836*7c478bd9Sstevel@tonic-gate #endif /* LP64 && FD_SETSIZE > 1024 */ 837*7c478bd9Sstevel@tonic-gate #define svc_fds svc_fdset.fds_bits[0] /* compatibility */ 838*7c478bd9Sstevel@tonic-gate 839*7c478bd9Sstevel@tonic-gate /* 840*7c478bd9Sstevel@tonic-gate * A small program implemented by the svc_rpc implementation itself. 841*7c478bd9Sstevel@tonic-gate * Also see clnt.h for protocol numbers. 842*7c478bd9Sstevel@tonic-gate */ 843*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 844*7c478bd9Sstevel@tonic-gate extern void svc_getreq(int); 845*7c478bd9Sstevel@tonic-gate extern void svc_getreq_common(const int); 846*7c478bd9Sstevel@tonic-gate extern void svc_getreqset(fd_set *); /* takes fdset instead of int */ 847*7c478bd9Sstevel@tonic-gate extern void svc_getreq_poll(struct pollfd *, const int); 848*7c478bd9Sstevel@tonic-gate extern void svc_run(void); 849*7c478bd9Sstevel@tonic-gate extern void svc_exit(void); 850*7c478bd9Sstevel@tonic-gate #else /* __STDC__ */ 851*7c478bd9Sstevel@tonic-gate extern void rpctest_service(); 852*7c478bd9Sstevel@tonic-gate extern void svc_getreqset(); 853*7c478bd9Sstevel@tonic-gate extern void svc_getreq(); 854*7c478bd9Sstevel@tonic-gate extern void svc_getreq_common(); 855*7c478bd9Sstevel@tonic-gate extern void svc_getreqset(); /* takes fdset instead of int */ 856*7c478bd9Sstevel@tonic-gate extern void svc_getreq_poll(); 857*7c478bd9Sstevel@tonic-gate extern void svc_run(); 858*7c478bd9Sstevel@tonic-gate extern void svc_exit(); 859*7c478bd9Sstevel@tonic-gate #endif /* __STDC__ */ 860*7c478bd9Sstevel@tonic-gate 861*7c478bd9Sstevel@tonic-gate /* 862*7c478bd9Sstevel@tonic-gate * Functions used to manage user file descriptors 863*7c478bd9Sstevel@tonic-gate */ 864*7c478bd9Sstevel@tonic-gate typedef int svc_input_id_t; 865*7c478bd9Sstevel@tonic-gate typedef void (*svc_callback_t)(svc_input_id_t id, int fd, 866*7c478bd9Sstevel@tonic-gate unsigned int events, void* cookie); 867*7c478bd9Sstevel@tonic-gate 868*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 869*7c478bd9Sstevel@tonic-gate extern svc_input_id_t svc_add_input(int fd, unsigned int events, 870*7c478bd9Sstevel@tonic-gate svc_callback_t user_callback, 871*7c478bd9Sstevel@tonic-gate void* cookie); 872*7c478bd9Sstevel@tonic-gate extern int svc_remove_input(svc_input_id_t id); 873*7c478bd9Sstevel@tonic-gate #else /* __STDC__ */ 874*7c478bd9Sstevel@tonic-gate extern svc_input_id_t svc_add_input(); 875*7c478bd9Sstevel@tonic-gate extern int svc_remove_input(); 876*7c478bd9Sstevel@tonic-gate #endif 877*7c478bd9Sstevel@tonic-gate 878*7c478bd9Sstevel@tonic-gate /* 879*7c478bd9Sstevel@tonic-gate * These are the existing service side transport implementations. 880*7c478bd9Sstevel@tonic-gate * 881*7c478bd9Sstevel@tonic-gate * Transport independent svc_create routine. 882*7c478bd9Sstevel@tonic-gate */ 883*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 884*7c478bd9Sstevel@tonic-gate extern int svc_create(void (*)(struct svc_req *, SVCXPRT *), 885*7c478bd9Sstevel@tonic-gate const rpcprog_t, const rpcvers_t, 886*7c478bd9Sstevel@tonic-gate const char *); 887*7c478bd9Sstevel@tonic-gate /* 888*7c478bd9Sstevel@tonic-gate * void (*dispatch)(); -- dispatch routine 889*7c478bd9Sstevel@tonic-gate * const rpcprog_t prognum; -- program number 890*7c478bd9Sstevel@tonic-gate * const rpcvers_t versnum; -- version number 891*7c478bd9Sstevel@tonic-gate * const char *nettype; -- network type 892*7c478bd9Sstevel@tonic-gate */ 893*7c478bd9Sstevel@tonic-gate 894*7c478bd9Sstevel@tonic-gate /* 895*7c478bd9Sstevel@tonic-gate * Generic server creation routine. It takes a netconfig structure 896*7c478bd9Sstevel@tonic-gate * instead of a nettype. 897*7c478bd9Sstevel@tonic-gate */ 898*7c478bd9Sstevel@tonic-gate extern SVCXPRT *svc_tp_create(void (*)(struct svc_req *, SVCXPRT *), 899*7c478bd9Sstevel@tonic-gate const rpcprog_t, const rpcvers_t, 900*7c478bd9Sstevel@tonic-gate const struct netconfig *); 901*7c478bd9Sstevel@tonic-gate /* 902*7c478bd9Sstevel@tonic-gate * void (*dispatch)(); -- dispatch routine 903*7c478bd9Sstevel@tonic-gate * const rpcprog_t prognum; -- program number 904*7c478bd9Sstevel@tonic-gate * const rpcvers_t versnum; -- version number 905*7c478bd9Sstevel@tonic-gate * const struct netconfig *nconf; -- netconfig structure 906*7c478bd9Sstevel@tonic-gate */ 907*7c478bd9Sstevel@tonic-gate 908*7c478bd9Sstevel@tonic-gate /* 909*7c478bd9Sstevel@tonic-gate * Generic TLI create routine 910*7c478bd9Sstevel@tonic-gate */ 911*7c478bd9Sstevel@tonic-gate extern SVCXPRT *svc_tli_create(const int, const struct netconfig *, 912*7c478bd9Sstevel@tonic-gate const struct t_bind *, const uint_t, 913*7c478bd9Sstevel@tonic-gate const uint_t); 914*7c478bd9Sstevel@tonic-gate /* 915*7c478bd9Sstevel@tonic-gate * const int fd; -- connection end point 916*7c478bd9Sstevel@tonic-gate * const struct netconfig *nconf; -- netconfig structure 917*7c478bd9Sstevel@tonic-gate * const struct t_bind *bindaddr; -- local bind address 918*7c478bd9Sstevel@tonic-gate * const uint_t sendsz; -- max sendsize 919*7c478bd9Sstevel@tonic-gate * const uint_t recvsz; -- max recvsize 920*7c478bd9Sstevel@tonic-gate */ 921*7c478bd9Sstevel@tonic-gate 922*7c478bd9Sstevel@tonic-gate /* 923*7c478bd9Sstevel@tonic-gate * Connectionless and connectionful create routines. 924*7c478bd9Sstevel@tonic-gate */ 925*7c478bd9Sstevel@tonic-gate extern SVCXPRT *svc_vc_create(const int, const uint_t, const uint_t); 926*7c478bd9Sstevel@tonic-gate /* 927*7c478bd9Sstevel@tonic-gate * const int fd; -- open connection end point 928*7c478bd9Sstevel@tonic-gate * const uint_t sendsize; -- max send size 929*7c478bd9Sstevel@tonic-gate * const uint_t recvsize; -- max recv size 930*7c478bd9Sstevel@tonic-gate */ 931*7c478bd9Sstevel@tonic-gate 932*7c478bd9Sstevel@tonic-gate extern SVCXPRT *svc_dg_create(const int, const uint_t, const uint_t); 933*7c478bd9Sstevel@tonic-gate /* 934*7c478bd9Sstevel@tonic-gate * const int fd; -- open connection 935*7c478bd9Sstevel@tonic-gate * const uint_t sendsize; -- max send size 936*7c478bd9Sstevel@tonic-gate * const uint_t recvsize; -- max recv size 937*7c478bd9Sstevel@tonic-gate */ 938*7c478bd9Sstevel@tonic-gate 939*7c478bd9Sstevel@tonic-gate /* 940*7c478bd9Sstevel@tonic-gate * the routine takes any *open* TLI file 941*7c478bd9Sstevel@tonic-gate * descriptor as its first input and is used for open connections. 942*7c478bd9Sstevel@tonic-gate */ 943*7c478bd9Sstevel@tonic-gate extern SVCXPRT *svc_fd_create(const int, const uint_t, const uint_t); 944*7c478bd9Sstevel@tonic-gate /* 945*7c478bd9Sstevel@tonic-gate * const int fd; -- open connection end point 946*7c478bd9Sstevel@tonic-gate * const uint_t sendsize; -- max send size 947*7c478bd9Sstevel@tonic-gate * const uint_t recvsize; -- max recv size 948*7c478bd9Sstevel@tonic-gate */ 949*7c478bd9Sstevel@tonic-gate 950*7c478bd9Sstevel@tonic-gate /* 951*7c478bd9Sstevel@tonic-gate * Memory based rpc (for speed check and testing) 952*7c478bd9Sstevel@tonic-gate */ 953*7c478bd9Sstevel@tonic-gate extern SVCXPRT *svc_raw_create(void); 954*7c478bd9Sstevel@tonic-gate 955*7c478bd9Sstevel@tonic-gate /* 956*7c478bd9Sstevel@tonic-gate * Creation of service over doors transport. 957*7c478bd9Sstevel@tonic-gate */ 958*7c478bd9Sstevel@tonic-gate extern SVCXPRT *svc_door_create(void (*)(struct svc_req *, SVCXPRT *), 959*7c478bd9Sstevel@tonic-gate const rpcprog_t, const rpcvers_t, 960*7c478bd9Sstevel@tonic-gate const uint_t); 961*7c478bd9Sstevel@tonic-gate /* 962*7c478bd9Sstevel@tonic-gate * void (*dispatch)(); -- dispatch routine 963*7c478bd9Sstevel@tonic-gate * const rpcprog_t prognum; -- program number 964*7c478bd9Sstevel@tonic-gate * const rpcvers_t versnum; -- version number 965*7c478bd9Sstevel@tonic-gate * const uint_t sendsize; -- send buffer size 966*7c478bd9Sstevel@tonic-gate */ 967*7c478bd9Sstevel@tonic-gate 968*7c478bd9Sstevel@tonic-gate /* 969*7c478bd9Sstevel@tonic-gate * Service control interface 970*7c478bd9Sstevel@tonic-gate */ 971*7c478bd9Sstevel@tonic-gate extern bool_t svc_control(SVCXPRT *, const uint_t, void *); 972*7c478bd9Sstevel@tonic-gate /* 973*7c478bd9Sstevel@tonic-gate * SVCXPRT *svc; -- service to manipulate 974*7c478bd9Sstevel@tonic-gate * const uint_t req; -- request 975*7c478bd9Sstevel@tonic-gate * void *info; -- argument to request 976*7c478bd9Sstevel@tonic-gate */ 977*7c478bd9Sstevel@tonic-gate 978*7c478bd9Sstevel@tonic-gate /* 979*7c478bd9Sstevel@tonic-gate * svc_dg_enable_cache() enables the cache on dg transports. 980*7c478bd9Sstevel@tonic-gate */ 981*7c478bd9Sstevel@tonic-gate extern int svc_dg_enablecache(SVCXPRT *, const uint_t); 982*7c478bd9Sstevel@tonic-gate #else /* __STDC__ */ 983*7c478bd9Sstevel@tonic-gate extern int svc_create(); 984*7c478bd9Sstevel@tonic-gate extern SVCXPRT *svc_tp_create(); 985*7c478bd9Sstevel@tonic-gate extern SVCXPRT *svc_tli_create(); 986*7c478bd9Sstevel@tonic-gate extern SVCXPRT *svc_vc_create(); 987*7c478bd9Sstevel@tonic-gate extern SVCXPRT *svc_dg_create(); 988*7c478bd9Sstevel@tonic-gate extern SVCXPRT *svc_fd_create(); 989*7c478bd9Sstevel@tonic-gate extern SVCXPRT *svc_raw_create(); 990*7c478bd9Sstevel@tonic-gate extern SVCXPRT *svc_door_create(); 991*7c478bd9Sstevel@tonic-gate extern int svc_dg_enablecache(); 992*7c478bd9Sstevel@tonic-gate #endif /* __STDC__ */ 993*7c478bd9Sstevel@tonic-gate 994*7c478bd9Sstevel@tonic-gate #ifdef PORTMAP 995*7c478bd9Sstevel@tonic-gate /* For backward compatibility */ 996*7c478bd9Sstevel@tonic-gate #include <rpc/svc_soc.h> 997*7c478bd9Sstevel@tonic-gate #endif /* PORTMAP */ 998*7c478bd9Sstevel@tonic-gate 999*7c478bd9Sstevel@tonic-gate /* 1000*7c478bd9Sstevel@tonic-gate * For user level MT hot server functions 1001*7c478bd9Sstevel@tonic-gate */ 1002*7c478bd9Sstevel@tonic-gate 1003*7c478bd9Sstevel@tonic-gate /* 1004*7c478bd9Sstevel@tonic-gate * Different MT modes 1005*7c478bd9Sstevel@tonic-gate */ 1006*7c478bd9Sstevel@tonic-gate #define RPC_SVC_MT_NONE 0 /* default, single-threaded */ 1007*7c478bd9Sstevel@tonic-gate #define RPC_SVC_MT_AUTO 1 /* automatic MT mode */ 1008*7c478bd9Sstevel@tonic-gate #define RPC_SVC_MT_USER 2 /* user MT mode */ 1009*7c478bd9Sstevel@tonic-gate 1010*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 1011*7c478bd9Sstevel@tonic-gate extern void svc_done(SVCXPRT *); 1012*7c478bd9Sstevel@tonic-gate #else 1013*7c478bd9Sstevel@tonic-gate extern void svc_done(); 1014*7c478bd9Sstevel@tonic-gate #endif /* __STDC__ */ 1015*7c478bd9Sstevel@tonic-gate 1016*7c478bd9Sstevel@tonic-gate /* 1017*7c478bd9Sstevel@tonic-gate * Obtaining local credentials. 1018*7c478bd9Sstevel@tonic-gate */ 1019*7c478bd9Sstevel@tonic-gate typedef struct __svc_local_cred_t { 1020*7c478bd9Sstevel@tonic-gate uid_t euid; /* effective uid */ 1021*7c478bd9Sstevel@tonic-gate gid_t egid; /* effective gid */ 1022*7c478bd9Sstevel@tonic-gate uid_t ruid; /* real uid */ 1023*7c478bd9Sstevel@tonic-gate gid_t rgid; /* real gid */ 1024*7c478bd9Sstevel@tonic-gate pid_t pid; /* caller's pid, or -1 if not available */ 1025*7c478bd9Sstevel@tonic-gate } svc_local_cred_t; 1026*7c478bd9Sstevel@tonic-gate 1027*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 1028*7c478bd9Sstevel@tonic-gate struct ucred_s; 1029*7c478bd9Sstevel@tonic-gate extern void svc_fd_negotiate_ucred(int); 1030*7c478bd9Sstevel@tonic-gate extern int svc_getcallerucred(const SVCXPRT *, struct ucred_s **); 1031*7c478bd9Sstevel@tonic-gate extern bool_t svc_get_local_cred(SVCXPRT *, svc_local_cred_t *); 1032*7c478bd9Sstevel@tonic-gate #else 1033*7c478bd9Sstevel@tonic-gate extern void svc_fd_negotiate_ucred(); 1034*7c478bd9Sstevel@tonic-gate extern int svc_getcallerucred(); 1035*7c478bd9Sstevel@tonic-gate extern bool_t svc_get_local_cred(); 1036*7c478bd9Sstevel@tonic-gate #endif /* __STDC__ */ 1037*7c478bd9Sstevel@tonic-gate 1038*7c478bd9Sstevel@tonic-gate /* 1039*7c478bd9Sstevel@tonic-gate * Private interfaces and structures for user level duplicate request caching. 1040*7c478bd9Sstevel@tonic-gate * The interfaces and data structures are not committed and subject to 1041*7c478bd9Sstevel@tonic-gate * change in future releases. Currently only intended for use by automountd. 1042*7c478bd9Sstevel@tonic-gate */ 1043*7c478bd9Sstevel@tonic-gate struct dupreq { 1044*7c478bd9Sstevel@tonic-gate uint32_t dr_xid; 1045*7c478bd9Sstevel@tonic-gate rpcproc_t dr_proc; 1046*7c478bd9Sstevel@tonic-gate rpcvers_t dr_vers; 1047*7c478bd9Sstevel@tonic-gate rpcprog_t dr_prog; 1048*7c478bd9Sstevel@tonic-gate struct netbuf dr_addr; 1049*7c478bd9Sstevel@tonic-gate struct netbuf dr_resp; 1050*7c478bd9Sstevel@tonic-gate int dr_status; 1051*7c478bd9Sstevel@tonic-gate time_t dr_time; 1052*7c478bd9Sstevel@tonic-gate uint_t dr_hash; 1053*7c478bd9Sstevel@tonic-gate struct dupreq *dr_next; 1054*7c478bd9Sstevel@tonic-gate struct dupreq *dr_prev; 1055*7c478bd9Sstevel@tonic-gate struct dupreq *dr_chain; 1056*7c478bd9Sstevel@tonic-gate struct dupreq *dr_prevchain; 1057*7c478bd9Sstevel@tonic-gate }; 1058*7c478bd9Sstevel@tonic-gate 1059*7c478bd9Sstevel@tonic-gate /* 1060*7c478bd9Sstevel@tonic-gate * The fixedtime state is defined if we want to expand the routines to 1061*7c478bd9Sstevel@tonic-gate * handle and encompass fixed size caches. 1062*7c478bd9Sstevel@tonic-gate */ 1063*7c478bd9Sstevel@tonic-gate #define DUPCACHE_FIXEDTIME 0 1064*7c478bd9Sstevel@tonic-gate 1065*7c478bd9Sstevel@tonic-gate /* 1066*7c478bd9Sstevel@tonic-gate * States of requests for duplicate request caching. 1067*7c478bd9Sstevel@tonic-gate * These are the same as defined for the kernel. 1068*7c478bd9Sstevel@tonic-gate */ 1069*7c478bd9Sstevel@tonic-gate #define DUP_NEW 0x00 /* new entry */ 1070*7c478bd9Sstevel@tonic-gate #define DUP_INPROGRESS 0x01 /* request already going */ 1071*7c478bd9Sstevel@tonic-gate #define DUP_DONE 0x02 /* request done */ 1072*7c478bd9Sstevel@tonic-gate #define DUP_DROP 0x03 /* request dropped */ 1073*7c478bd9Sstevel@tonic-gate #define DUP_ERROR 0x04 /* error in dup req cache */ 1074*7c478bd9Sstevel@tonic-gate 1075*7c478bd9Sstevel@tonic-gate #ifdef __STDC__ 1076*7c478bd9Sstevel@tonic-gate extern bool_t __svc_dupcache_init(void *, int, char **); 1077*7c478bd9Sstevel@tonic-gate extern int __svc_dup(struct svc_req *, caddr_t *, uint_t *, char *); 1078*7c478bd9Sstevel@tonic-gate extern int __svc_dupdone(struct svc_req *, caddr_t, uint_t, int, char *); 1079*7c478bd9Sstevel@tonic-gate extern bool_t __svc_vc_dupcache_init(SVCXPRT *, void *, int); 1080*7c478bd9Sstevel@tonic-gate extern int __svc_vc_dup(struct svc_req *, caddr_t *, uint_t *); 1081*7c478bd9Sstevel@tonic-gate extern int __svc_vc_dupdone(struct svc_req *, caddr_t, uint_t, int); 1082*7c478bd9Sstevel@tonic-gate #else 1083*7c478bd9Sstevel@tonic-gate extern bool_t __svc_dupcache_init(); 1084*7c478bd9Sstevel@tonic-gate extern int __svc_dup(); 1085*7c478bd9Sstevel@tonic-gate extern int __svc_dupdone(); 1086*7c478bd9Sstevel@tonic-gate extern bool_t __svc_vc_dupcache_init(); 1087*7c478bd9Sstevel@tonic-gate extern int __svc_vc_dup(); 1088*7c478bd9Sstevel@tonic-gate extern int __svc_vc_dupdone(); 1089*7c478bd9Sstevel@tonic-gate #endif /* __STDC__ */ 1090*7c478bd9Sstevel@tonic-gate #endif /* _KERNEL */ 1091*7c478bd9Sstevel@tonic-gate 1092*7c478bd9Sstevel@tonic-gate #ifdef __cplusplus 1093*7c478bd9Sstevel@tonic-gate } 1094*7c478bd9Sstevel@tonic-gate #endif 1095*7c478bd9Sstevel@tonic-gate 1096*7c478bd9Sstevel@tonic-gate #endif /* !_RPC_SVC_H */ 1097