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
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]
24 * Allows for gathering of statistics
26 * Copyright (c) 1990 by Sun Microsystems, Inc.
29 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
33 #include <netconfig.h>
35 #include <rpc/rpcb_prot.h>
38 #include <rpc/pmap_prot.h>
48 static rpcb_stat_byvers inf
;
49 static rwlock_t inf_lock
= DEFAULTRWLOCK
;
52 rpcbs_procinfo(int rtype
, rpcproc_t proc
)
54 assert(rtype
>= 0 && rtype
< RPCBVERS_STAT
);
57 if ((rtype
== RPCBVERS_2_STAT
) && (proc
> rpcb_highproc_2
))
60 assert(rtype
!= RPCBVERS_2_STAT
);
63 if ((rtype
== RPCBVERS_3_STAT
) && (proc
> rpcb_highproc_3
))
66 if ((rtype
== RPCBVERS_4_STAT
) && (proc
> rpcb_highproc_4
))
69 atomic_add_int((uint_t
*)&inf
[rtype
].info
[proc
], 1);
73 rpcbs_set(int rtype
, bool_t success
)
75 assert(rtype
>= 0 && rtype
< RPCBVERS_STAT
);
80 atomic_add_int((uint_t
*)&inf
[rtype
].setinfo
, 1);
84 rpcbs_unset(int rtype
, bool_t success
)
86 assert(rtype
>= 0 && rtype
< RPCBVERS_STAT
);
91 atomic_add_int((uint_t
*)&inf
[rtype
].unsetinfo
, 1);
95 rpcbs_getaddr(int rtype
, rpcprog_t prog
, rpcvers_t vers
, char *netid
,
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] == NULL
))
115 atomic_add_int((uint_t
*)&al
->failure
, 1);
117 atomic_add_int((uint_t
*)&al
->success
, 1);
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
);
133 al
= (rpcbs_addrlist
*) malloc(sizeof (rpcbs_addrlist
));
140 al
->netid
= nconf
->nc_netid
;
141 if ((uaddr
== NULL
) || (uaddr
[0] == NULL
)) {
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
);
157 if ((uaddr
== NULL
) || (uaddr
[0] == NULL
))
158 atomic_add_int((uint_t
*)&wal
->failure
, 1);
160 atomic_add_int((uint_t
*)&wal
->success
, 1);
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
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);
197 atomic_add_int((uint_t
*)&rl
->success
, 1);
198 if (rpcbproc
== RPCBPROC_INDIRECT
)
199 atomic_add_int((uint_t
*)&rl
->indirect
, 1);
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
);
215 rl
= (rpcbs_rmtcalllist
*) malloc(sizeof (rpcbs_rmtcalllist
));
223 rl
->netid
= nconf
->nc_netid
;
224 if ((rbl
== NULL
) || (rbl
->rpcb_map
.r_vers
!= vers
)) {
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
);
241 if ((rbl
== NULL
) || (rbl
->rpcb_map
.r_vers
!= vers
))
242 atomic_add_int((uint_t
*)&wrl
->failure
, 1);
244 atomic_add_int((uint_t
*)&wrl
->success
, 1);
245 if (rpcbproc
== RPCBPROC_INDIRECT
)
246 atomic_add_int((uint_t
*)&wrl
->indirect
, 1);
252 rl
->next
= inf
[rtype
].rmtinfo
;
253 inf
[rtype
].rmtinfo
= rl
;
254 (void) rw_unlock(&inf_lock
);
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
);
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
);
280 return (xdr_rpcb_stat_byvers(xdrs
, (rpcb_stat
*)*objp
));