dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / rpcbind / rpcb_stat.c
blob4b998af55145b63514c9c198e3823f17ed90be5f
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * rpcb_stat.c
24 * Allows for gathering of statistics
26 * Copyright (c) 1990 by Sun Microsystems, Inc.
29 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
32 #include <stdio.h>
33 #include <netconfig.h>
34 #include <rpc/rpc.h>
35 #include <rpc/rpcb_prot.h>
36 #include <sys/stat.h>
37 #ifdef PORTMAP
38 #include <rpc/pmap_prot.h>
39 #endif
40 #include <stdlib.h>
41 #include <atomic.h>
42 #include <assert.h>
43 #include <thread.h>
44 #include <synch.h>
45 #include <string.h>
46 #include "rpcbind.h"
48 static rpcb_stat_byvers inf;
49 static rwlock_t inf_lock = DEFAULTRWLOCK;
51 void
52 rpcbs_procinfo(int rtype, rpcproc_t proc)
54 assert(rtype >= 0 && rtype < RPCBVERS_STAT);
56 #ifdef PORTMAP
57 if ((rtype == RPCBVERS_2_STAT) && (proc > rpcb_highproc_2))
58 return;
59 #else
60 assert(rtype != RPCBVERS_2_STAT);
61 #endif
63 if ((rtype == RPCBVERS_3_STAT) && (proc > rpcb_highproc_3))
64 return;
66 if ((rtype == RPCBVERS_4_STAT) && (proc > rpcb_highproc_4))
67 return;
69 atomic_add_int((uint_t *)&inf[rtype].info[proc], 1);
72 void
73 rpcbs_set(int rtype, bool_t success)
75 assert(rtype >= 0 && rtype < RPCBVERS_STAT);
77 if (success == FALSE)
78 return;
80 atomic_add_int((uint_t *)&inf[rtype].setinfo, 1);
83 void
84 rpcbs_unset(int rtype, bool_t success)
86 assert(rtype >= 0 && rtype < RPCBVERS_STAT);
88 if (success == FALSE)
89 return;
91 atomic_add_int((uint_t *)&inf[rtype].unsetinfo, 1);
94 void
95 rpcbs_getaddr(int rtype, rpcprog_t prog, rpcvers_t vers, char *netid,
96 char *uaddr)
98 rpcbs_addrlist *al;
99 rpcbs_addrlist *s;
100 rpcbs_addrlist *wal;
101 struct netconfig *nconf;
103 assert(rtype >= 0 && rtype < RPCBVERS_STAT);
106 * First try with read lock only.
108 (void) rw_rdlock(&inf_lock);
109 for (s = al = inf[rtype].addrinfo; al; al = al->next) {
110 if ((al->prog == prog) && (al->vers == vers) &&
111 (strcmp(al->netid, netid) == 0)) {
112 (void) rw_unlock(&inf_lock);
114 if ((uaddr == NULL) || (uaddr[0] == '\0'))
115 atomic_add_int((uint_t *)&al->failure, 1);
116 else
117 atomic_add_int((uint_t *)&al->success, 1);
119 return;
122 (void) rw_unlock(&inf_lock);
125 * If not found, we will likely need to add a new entry,
126 * so pre-allocate it, and then try to search again with write lock.
128 nconf = rpcbind_get_conf(netid);
129 if (nconf == NULL) {
130 return;
133 al = (rpcbs_addrlist *) malloc(sizeof (rpcbs_addrlist));
134 if (al == NULL) {
135 return;
138 al->prog = prog;
139 al->vers = vers;
140 al->netid = nconf->nc_netid;
141 if ((uaddr == NULL) || (uaddr[0] == '\0')) {
142 al->failure = 1;
143 al->success = 0;
144 } else {
145 al->failure = 0;
146 al->success = 1;
149 (void) rw_wrlock(&inf_lock);
150 for (wal = inf[rtype].addrinfo; wal != s; wal = wal->next) {
151 if ((wal->prog == prog) && (wal->vers == vers) &&
152 (strcmp(wal->netid, netid) == 0)) {
153 (void) rw_unlock(&inf_lock);
155 free(al);
157 if ((uaddr == NULL) || (uaddr[0] == '\0'))
158 atomic_add_int((uint_t *)&wal->failure, 1);
159 else
160 atomic_add_int((uint_t *)&wal->success, 1);
162 return;
166 al->next = inf[rtype].addrinfo;
167 inf[rtype].addrinfo = al;
168 (void) rw_unlock(&inf_lock);
172 * rpcbproc - rpcbind proc number on which this was called
174 void
175 rpcbs_rmtcall(int rtype, rpcproc_t rpcbproc, rpcprog_t prog, rpcvers_t vers,
176 rpcproc_t proc, char *netid, rpcblist_ptr rbl)
178 rpcbs_rmtcalllist *rl;
179 rpcbs_rmtcalllist *s;
180 rpcbs_rmtcalllist *wrl;
181 struct netconfig *nconf;
183 assert(rtype >= 0 && rtype < RPCBVERS_STAT);
186 * First try with read lock only.
188 (void) rw_rdlock(&inf_lock);
189 for (s = rl = inf[rtype].rmtinfo; rl; rl = rl->next) {
190 if ((rl->prog == prog) && (rl->vers == vers) &&
191 (rl->proc == proc) && (strcmp(rl->netid, netid) == 0)) {
192 (void) rw_unlock(&inf_lock);
194 if ((rbl == NULL) || (rbl->rpcb_map.r_vers != vers))
195 atomic_add_int((uint_t *)&rl->failure, 1);
196 else
197 atomic_add_int((uint_t *)&rl->success, 1);
198 if (rpcbproc == RPCBPROC_INDIRECT)
199 atomic_add_int((uint_t *)&rl->indirect, 1);
201 return;
204 (void) rw_unlock(&inf_lock);
207 * If not found, we will likely need to add a new entry,
208 * so pre-allocate it, and then try to search again with write lock.
210 nconf = rpcbind_get_conf(netid);
211 if (nconf == NULL) {
212 return;
215 rl = (rpcbs_rmtcalllist *) malloc(sizeof (rpcbs_rmtcalllist));
216 if (rl == NULL) {
217 return;
220 rl->prog = prog;
221 rl->vers = vers;
222 rl->proc = proc;
223 rl->netid = nconf->nc_netid;
224 if ((rbl == NULL) || (rbl->rpcb_map.r_vers != vers)) {
225 rl->failure = 1;
226 rl->success = 0;
227 } else {
228 rl->failure = 0;
229 rl->success = 1;
231 rl->indirect = rpcbproc == RPCBPROC_INDIRECT ? 1 : 0;
233 (void) rw_wrlock(&inf_lock);
234 for (wrl = inf[rtype].rmtinfo; wrl != s; wrl = wrl->next) {
235 if ((wrl->prog == prog) && (wrl->vers == vers) &&
236 (wrl->proc == proc) && (strcmp(wrl->netid, netid) == 0)) {
237 (void) rw_unlock(&inf_lock);
239 free(rl);
241 if ((rbl == NULL) || (rbl->rpcb_map.r_vers != vers))
242 atomic_add_int((uint_t *)&wrl->failure, 1);
243 else
244 atomic_add_int((uint_t *)&wrl->success, 1);
245 if (rpcbproc == RPCBPROC_INDIRECT)
246 atomic_add_int((uint_t *)&wrl->indirect, 1);
248 return;
252 rl->next = inf[rtype].rmtinfo;
253 inf[rtype].rmtinfo = rl;
254 (void) rw_unlock(&inf_lock);
257 /* ARGSUSED */
258 bool_t
259 rpcbproc_getstat(void *argp, rpcb_stat_byvers **result)
262 * inf_lock is unlocked in xdr_rpcb_stat_byvers_ptr()
264 (void) rw_rdlock(&inf_lock);
265 *result = &inf;
266 return (TRUE);
269 bool_t
270 xdr_rpcb_stat_byvers_ptr(XDR *xdrs, rpcb_stat_byvers **objp)
272 if (xdrs->x_op == XDR_FREE) {
274 * inf_lock is locked in rpcbproc_getstat()
276 (void) rw_unlock(&inf_lock);
277 return (TRUE);
280 return (xdr_rpcb_stat_byvers(xdrs, (rpcb_stat *)*objp));