1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28*0Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* SVr4.0 */
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate /*
34*0Sstevel@tonic-gate  * Define and initialize MT client/server data.
35*0Sstevel@tonic-gate  */
36*0Sstevel@tonic-gate 
37*0Sstevel@tonic-gate #include	<sys/types.h>
38*0Sstevel@tonic-gate #include	<sys/t_lock.h>
39*0Sstevel@tonic-gate #include	<sys/kstat.h>
40*0Sstevel@tonic-gate #include	<sys/systm.h>
41*0Sstevel@tonic-gate #include	<sys/zone.h>
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate #include	<rpc/types.h>
44*0Sstevel@tonic-gate #include	<rpc/auth.h>
45*0Sstevel@tonic-gate #include	<rpc/clnt.h>
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate kmutex_t xid_lock;		/* XID allocation */
48*0Sstevel@tonic-gate kmutex_t clnt_pending_lock;	/* for list of pending calls awaiting replies */
49*0Sstevel@tonic-gate kmutex_t clnt_max_msg_lock;	/* updating max message sanity check for cots */
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate zone_key_t	rpcstat_zone_key;
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate /*
54*0Sstevel@tonic-gate  * rpcstat_zone_[init|fini]_common() ends up being nearly identical to
55*0Sstevel@tonic-gate  * nfsstat_zone_[init|fini]_common().  Due to them necessarily being in
56*0Sstevel@tonic-gate  * different modules, however, we end up needing to duplicate the code.
57*0Sstevel@tonic-gate  */
58*0Sstevel@tonic-gate kstat_named_t *
59*0Sstevel@tonic-gate rpcstat_zone_init_common(zoneid_t zoneid, const char *module, const char *name,
60*0Sstevel@tonic-gate     const kstat_named_t *template, size_t template_size)
61*0Sstevel@tonic-gate {
62*0Sstevel@tonic-gate 	kstat_t *ksp;
63*0Sstevel@tonic-gate 	kstat_named_t *ks_data;
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate 
66*0Sstevel@tonic-gate /*
67*0Sstevel@tonic-gate  * PSARC 2001/697 Contract Private Interface
68*0Sstevel@tonic-gate  * rpc_clts_client
69*0Sstevel@tonic-gate  * rpc_cots_client
70*0Sstevel@tonic-gate  * Changes must be reviewed by Solaris File Sharing
71*0Sstevel@tonic-gate  * Changes must be communicated to contract-2001-697@sun.com
72*0Sstevel@tonic-gate  *
73*0Sstevel@tonic-gate  */
74*0Sstevel@tonic-gate 	ks_data = kmem_alloc(template_size, KM_SLEEP);
75*0Sstevel@tonic-gate 	bcopy(template, ks_data, template_size);
76*0Sstevel@tonic-gate 	if ((ksp = kstat_create_zone((char *)module, 0, (char *)name, "rpc",
77*0Sstevel@tonic-gate 	    KSTAT_TYPE_NAMED, template_size / sizeof (kstat_named_t),
78*0Sstevel@tonic-gate 	    KSTAT_FLAG_VIRTUAL | KSTAT_FLAG_WRITABLE, zoneid)) != NULL) {
79*0Sstevel@tonic-gate 		ksp->ks_data = ks_data;
80*0Sstevel@tonic-gate 		kstat_install(ksp);
81*0Sstevel@tonic-gate 	}
82*0Sstevel@tonic-gate 	return (ks_data);
83*0Sstevel@tonic-gate }
84*0Sstevel@tonic-gate 
85*0Sstevel@tonic-gate void
86*0Sstevel@tonic-gate rpcstat_zone_fini_common(zoneid_t zoneid, const char *module, const char *name)
87*0Sstevel@tonic-gate {
88*0Sstevel@tonic-gate 	kstat_delete_byname_zone((char *)module, 0, (char *)name, zoneid);
89*0Sstevel@tonic-gate }
90*0Sstevel@tonic-gate 
91*0Sstevel@tonic-gate static void *
92*0Sstevel@tonic-gate mt_kstat_zone_init(zoneid_t zoneid)
93*0Sstevel@tonic-gate {
94*0Sstevel@tonic-gate 	struct rpcstat *rpcstat;
95*0Sstevel@tonic-gate 
96*0Sstevel@tonic-gate 	rpcstat = kmem_alloc(sizeof (*rpcstat), KM_SLEEP);
97*0Sstevel@tonic-gate 
98*0Sstevel@tonic-gate 	clnt_clts_stats_init(zoneid, &rpcstat->rpc_clts_client);
99*0Sstevel@tonic-gate 	svc_clts_stats_init(zoneid, &rpcstat->rpc_clts_server);
100*0Sstevel@tonic-gate 
101*0Sstevel@tonic-gate 	clnt_cots_stats_init(zoneid, &rpcstat->rpc_cots_client);
102*0Sstevel@tonic-gate 	svc_cots_stats_init(zoneid, &rpcstat->rpc_cots_server);
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate 	return (rpcstat);
105*0Sstevel@tonic-gate }
106*0Sstevel@tonic-gate 
107*0Sstevel@tonic-gate /*
108*0Sstevel@tonic-gate  * Deletes the previously allocated "rpc" kstats
109*0Sstevel@tonic-gate  */
110*0Sstevel@tonic-gate static void
111*0Sstevel@tonic-gate mt_kstat_zone_fini(zoneid_t zoneid, void *data)
112*0Sstevel@tonic-gate {
113*0Sstevel@tonic-gate 	struct rpcstat *rpcstat = data;
114*0Sstevel@tonic-gate 
115*0Sstevel@tonic-gate 	clnt_cots_stats_fini(zoneid, &rpcstat->rpc_cots_client);
116*0Sstevel@tonic-gate 	svc_cots_stats_fini(zoneid, &rpcstat->rpc_cots_server);
117*0Sstevel@tonic-gate 
118*0Sstevel@tonic-gate 	clnt_clts_stats_fini(zoneid, &rpcstat->rpc_clts_client);
119*0Sstevel@tonic-gate 	svc_clts_stats_fini(zoneid, &rpcstat->rpc_clts_server);
120*0Sstevel@tonic-gate 
121*0Sstevel@tonic-gate 	kmem_free(rpcstat, sizeof (*rpcstat));
122*0Sstevel@tonic-gate }
123*0Sstevel@tonic-gate 
124*0Sstevel@tonic-gate void
125*0Sstevel@tonic-gate mt_kstat_init(void)
126*0Sstevel@tonic-gate {
127*0Sstevel@tonic-gate 	zone_key_create(&rpcstat_zone_key, mt_kstat_zone_init, NULL,
128*0Sstevel@tonic-gate 	    mt_kstat_zone_fini);
129*0Sstevel@tonic-gate }
130*0Sstevel@tonic-gate 
131*0Sstevel@tonic-gate void
132*0Sstevel@tonic-gate mt_kstat_fini(void)
133*0Sstevel@tonic-gate {
134*0Sstevel@tonic-gate 	(void) zone_key_delete(rpcstat_zone_key);
135*0Sstevel@tonic-gate }
136*0Sstevel@tonic-gate 
137*0Sstevel@tonic-gate static bool_t	clnt_xid_initialized = FALSE;
138*0Sstevel@tonic-gate static uint32_t clnt_xid = 0;	/* transaction id used by all clients */
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate uint32_t
141*0Sstevel@tonic-gate alloc_xid(void)
142*0Sstevel@tonic-gate {
143*0Sstevel@tonic-gate 	uint32_t  xid;
144*0Sstevel@tonic-gate 	timestruc_t now;
145*0Sstevel@tonic-gate 
146*0Sstevel@tonic-gate 	/*
147*0Sstevel@tonic-gate 	 * Do a one time initialzation to better utilize the number
148*0Sstevel@tonic-gate 	 * space.
149*0Sstevel@tonic-gate 	 */
150*0Sstevel@tonic-gate 	mutex_enter(&xid_lock);
151*0Sstevel@tonic-gate 	if (clnt_xid_initialized == FALSE) {
152*0Sstevel@tonic-gate 		clnt_xid_initialized = TRUE;
153*0Sstevel@tonic-gate 		gethrestime(&now);
154*0Sstevel@tonic-gate 		clnt_xid = (uint32_t)((now.tv_sec << 20) |
155*0Sstevel@tonic-gate 		    (now.tv_nsec >> 10));
156*0Sstevel@tonic-gate 	}
157*0Sstevel@tonic-gate 
158*0Sstevel@tonic-gate 	xid = clnt_xid++;
159*0Sstevel@tonic-gate 
160*0Sstevel@tonic-gate 	/*
161*0Sstevel@tonic-gate 	 * Don't return a zero xid.  This could happen if the initialization
162*0Sstevel@tonic-gate 	 * happens to return zero or if clnt_xid wraps.
163*0Sstevel@tonic-gate 	 */
164*0Sstevel@tonic-gate 	if (xid == 0)
165*0Sstevel@tonic-gate 		xid = clnt_xid++;
166*0Sstevel@tonic-gate 
167*0Sstevel@tonic-gate 	mutex_exit(&xid_lock);
168*0Sstevel@tonic-gate 	return (xid);
169*0Sstevel@tonic-gate }
170