clnt_vc.c (177685) | clnt_vc.c (180025) |
---|---|
1/* $NetBSD: clnt_vc.c,v 1.4 2000/07/14 08:40:42 fvdl Exp $ */ 2 3/* 4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5 * unrestricted use provided that this legend is included on all tape 6 * media and as a part of the software program in whole or part. Users 7 * may copy or modify Sun RPC without charge, but are not authorized 8 * to license or distribute it to anyone else except as part of a product or --- 21 unchanged lines hidden (view full) --- 30 */ 31 32#if defined(LIBC_SCCS) && !defined(lint) 33static char *sccsid2 = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro"; 34static char *sccsid = "@(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC"; 35static char sccsid3[] = "@(#)clnt_vc.c 1.19 89/03/16 Copyr 1988 Sun Micro"; 36#endif 37#include <sys/cdefs.h> | 1/* $NetBSD: clnt_vc.c,v 1.4 2000/07/14 08:40:42 fvdl Exp $ */ 2 3/* 4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5 * unrestricted use provided that this legend is included on all tape 6 * media and as a part of the software program in whole or part. Users 7 * may copy or modify Sun RPC without charge, but are not authorized 8 * to license or distribute it to anyone else except as part of a product or --- 21 unchanged lines hidden (view full) --- 30 */ 31 32#if defined(LIBC_SCCS) && !defined(lint) 33static char *sccsid2 = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro"; 34static char *sccsid = "@(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC"; 35static char sccsid3[] = "@(#)clnt_vc.c 1.19 89/03/16 Copyr 1988 Sun Micro"; 36#endif 37#include <sys/cdefs.h> |
38__FBSDID("$FreeBSD: head/sys/rpc/clnt_vc.c 177685 2008-03-28 09:50:32Z dfr $"); | 38__FBSDID("$FreeBSD: head/sys/rpc/clnt_vc.c 180025 2008-06-26 10:21:54Z dfr $"); |
39 40/* 41 * clnt_tcp.c, Implements a TCP/IP based, client side RPC. 42 * 43 * Copyright (C) 1984, Sun Microsystems, Inc. 44 * 45 * TCP based RPC supports 'batched calls'. 46 * A sequence of calls may be batched-up in a send buffer. The rpc call --- 28 unchanged lines hidden (view full) --- 75 76#define MCALL_MSG_SIZE 24 77 78struct cmessage { 79 struct cmsghdr cmsg; 80 struct cmsgcred cmcred; 81}; 82 | 39 40/* 41 * clnt_tcp.c, Implements a TCP/IP based, client side RPC. 42 * 43 * Copyright (C) 1984, Sun Microsystems, Inc. 44 * 45 * TCP based RPC supports 'batched calls'. 46 * A sequence of calls may be batched-up in a send buffer. The rpc call --- 28 unchanged lines hidden (view full) --- 75 76#define MCALL_MSG_SIZE 24 77 78struct cmessage { 79 struct cmsghdr cmsg; 80 struct cmsgcred cmcred; 81}; 82 |
83static enum clnt_stat clnt_vc_call(CLIENT *, rpcproc_t, xdrproc_t, void *, 84 xdrproc_t, void *, struct timeval); | 83static enum clnt_stat clnt_vc_call(CLIENT *, struct rpc_callextra *, 84 rpcproc_t, xdrproc_t, void *, xdrproc_t, void *, struct timeval); |
85static void clnt_vc_geterr(CLIENT *, struct rpc_err *); 86static bool_t clnt_vc_freeres(CLIENT *, xdrproc_t, void *); 87static void clnt_vc_abort(CLIENT *); 88static bool_t clnt_vc_control(CLIENT *, u_int, void *); 89static void clnt_vc_destroy(CLIENT *); 90static bool_t time_not_ok(struct timeval *); 91static void clnt_vc_soupcall(struct socket *so, void *arg, int waitflag); 92 93static struct clnt_ops clnt_vc_ops = { 94 .cl_call = clnt_vc_call, 95 .cl_abort = clnt_vc_abort, 96 .cl_geterr = clnt_vc_geterr, 97 .cl_freeres = clnt_vc_freeres, 98 .cl_destroy = clnt_vc_destroy, 99 .cl_control = clnt_vc_control 100}; 101 102/* | 85static void clnt_vc_geterr(CLIENT *, struct rpc_err *); 86static bool_t clnt_vc_freeres(CLIENT *, xdrproc_t, void *); 87static void clnt_vc_abort(CLIENT *); 88static bool_t clnt_vc_control(CLIENT *, u_int, void *); 89static void clnt_vc_destroy(CLIENT *); 90static bool_t time_not_ok(struct timeval *); 91static void clnt_vc_soupcall(struct socket *so, void *arg, int waitflag); 92 93static struct clnt_ops clnt_vc_ops = { 94 .cl_call = clnt_vc_call, 95 .cl_abort = clnt_vc_abort, 96 .cl_geterr = clnt_vc_geterr, 97 .cl_freeres = clnt_vc_freeres, 98 .cl_destroy = clnt_vc_destroy, 99 .cl_control = clnt_vc_control 100}; 101 102/* |
103 * A pending RPC request which awaits a reply. | 103 * A pending RPC request which awaits a reply. Requests which have 104 * received their reply will have cr_xid set to zero and cr_mrep to 105 * the mbuf chain of the reply. |
104 */ 105struct ct_request { 106 TAILQ_ENTRY(ct_request) cr_link; 107 uint32_t cr_xid; /* XID of request */ 108 struct mbuf *cr_mrep; /* reply received by upcall */ 109 int cr_error; /* any error from upcall */ 110}; 111 112TAILQ_HEAD(ct_request_list, ct_request); 113 114struct ct_data { 115 struct mtx ct_lock; | 106 */ 107struct ct_request { 108 TAILQ_ENTRY(ct_request) cr_link; 109 uint32_t cr_xid; /* XID of request */ 110 struct mbuf *cr_mrep; /* reply received by upcall */ 111 int cr_error; /* any error from upcall */ 112}; 113 114TAILQ_HEAD(ct_request_list, ct_request); 115 116struct ct_data { 117 struct mtx ct_lock; |
118 int ct_threads; /* number of threads in clnt_vc_call */ 119 bool_t ct_closing; /* TRUE if we are destroying client */ |
|
116 struct socket *ct_socket; /* connection socket */ 117 bool_t ct_closeit; /* close it on destroy */ 118 struct timeval ct_wait; /* wait interval in milliseconds */ 119 struct sockaddr_storage ct_addr; /* remote addr */ 120 struct rpc_err ct_error; 121 uint32_t ct_xid; 122 char ct_mcallc[MCALL_MSG_SIZE]; /* marshalled callmsg */ 123 size_t ct_mpos; /* pos after marshal */ --- 32 unchanged lines hidden (view full) --- 156{ 157 CLIENT *cl; /* client handle */ 158 struct ct_data *ct = NULL; /* client handle */ 159 struct timeval now; 160 struct rpc_msg call_msg; 161 static uint32_t disrupt; 162 struct __rpc_sockinfo si; 163 XDR xdrs; | 120 struct socket *ct_socket; /* connection socket */ 121 bool_t ct_closeit; /* close it on destroy */ 122 struct timeval ct_wait; /* wait interval in milliseconds */ 123 struct sockaddr_storage ct_addr; /* remote addr */ 124 struct rpc_err ct_error; 125 uint32_t ct_xid; 126 char ct_mcallc[MCALL_MSG_SIZE]; /* marshalled callmsg */ 127 size_t ct_mpos; /* pos after marshal */ --- 32 unchanged lines hidden (view full) --- 160{ 161 CLIENT *cl; /* client handle */ 162 struct ct_data *ct = NULL; /* client handle */ 163 struct timeval now; 164 struct rpc_msg call_msg; 165 static uint32_t disrupt; 166 struct __rpc_sockinfo si; 167 XDR xdrs; |
164 int error; | 168 int error, interrupted; |
165 166 if (disrupt == 0) 167 disrupt = (uint32_t)(long)raddr; 168 169 cl = (CLIENT *)mem_alloc(sizeof (*cl)); 170 ct = (struct ct_data *)mem_alloc(sizeof (*ct)); 171 172 mtx_init(&ct->ct_lock, "ct->ct_lock", NULL, MTX_DEF); | 169 170 if (disrupt == 0) 171 disrupt = (uint32_t)(long)raddr; 172 173 cl = (CLIENT *)mem_alloc(sizeof (*cl)); 174 ct = (struct ct_data *)mem_alloc(sizeof (*ct)); 175 176 mtx_init(&ct->ct_lock, "ct->ct_lock", NULL, MTX_DEF); |
177 ct->ct_threads = 0; 178 ct->ct_closing = FALSE; |
|
173 174 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) { 175 error = soconnect(so, raddr, curthread); | 179 180 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) { 181 error = soconnect(so, raddr, curthread); |
182 SOCK_LOCK(so); 183 interrupted = 0; 184 while ((so->so_state & SS_ISCONNECTING) 185 && so->so_error == 0) { 186 error = msleep(&so->so_timeo, SOCK_MTX(so), 187 PSOCK | PCATCH, "connec", 0); 188 if (error) { 189 if (error == EINTR || error == ERESTART) 190 interrupted = 1; 191 break; 192 } 193 } 194 if (error == 0) { 195 error = so->so_error; 196 so->so_error = 0; 197 } 198 SOCK_UNLOCK(so); |
|
176 if (error) { | 199 if (error) { |
200 if (!interrupted) 201 so->so_state &= ~SS_ISCONNECTING; |
|
177 rpc_createerr.cf_stat = RPC_SYSTEMERROR; 178 rpc_createerr.cf_error.re_errno = error; 179 goto err; 180 } 181 } 182 183 if (!__rpc_socket2sockinfo(so, &si)) 184 goto err; --- 34 unchanged lines hidden (view full) --- 219 XDR_DESTROY(&xdrs); 220 ct->ct_waitchan = "rpcrecv"; 221 ct->ct_waitflag = 0; 222 223 /* 224 * Create a client handle which uses xdrrec for serialization 225 * and authnone for authentication. 226 */ | 202 rpc_createerr.cf_stat = RPC_SYSTEMERROR; 203 rpc_createerr.cf_error.re_errno = error; 204 goto err; 205 } 206 } 207 208 if (!__rpc_socket2sockinfo(so, &si)) 209 goto err; --- 34 unchanged lines hidden (view full) --- 244 XDR_DESTROY(&xdrs); 245 ct->ct_waitchan = "rpcrecv"; 246 ct->ct_waitflag = 0; 247 248 /* 249 * Create a client handle which uses xdrrec for serialization 250 * and authnone for authentication. 251 */ |
252 cl->cl_refs = 1; |
|
227 cl->cl_ops = &clnt_vc_ops; 228 cl->cl_private = ct; 229 cl->cl_auth = authnone_create(); 230 sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz); 231 recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz); 232 233 SOCKBUF_LOCK(&ct->ct_socket->so_rcv); 234 ct->ct_socket->so_upcallarg = ct; --- 15 unchanged lines hidden (view full) --- 250 mem_free(cl, sizeof (CLIENT)); 251 } 252 return ((CLIENT *)NULL); 253} 254 255static enum clnt_stat 256clnt_vc_call( 257 CLIENT *cl, | 253 cl->cl_ops = &clnt_vc_ops; 254 cl->cl_private = ct; 255 cl->cl_auth = authnone_create(); 256 sendsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)sendsz); 257 recvsz = __rpc_get_t_size(si.si_af, si.si_proto, (int)recvsz); 258 259 SOCKBUF_LOCK(&ct->ct_socket->so_rcv); 260 ct->ct_socket->so_upcallarg = ct; --- 15 unchanged lines hidden (view full) --- 276 mem_free(cl, sizeof (CLIENT)); 277 } 278 return ((CLIENT *)NULL); 279} 280 281static enum clnt_stat 282clnt_vc_call( 283 CLIENT *cl, |
284 struct rpc_callextra *ext, |
|
258 rpcproc_t proc, 259 xdrproc_t xdr_args, 260 void *args_ptr, 261 xdrproc_t xdr_results, 262 void *results_ptr, 263 struct timeval utimeout) 264{ 265 struct ct_data *ct = (struct ct_data *) cl->cl_private; | 285 rpcproc_t proc, 286 xdrproc_t xdr_args, 287 void *args_ptr, 288 xdrproc_t xdr_results, 289 void *results_ptr, 290 struct timeval utimeout) 291{ 292 struct ct_data *ct = (struct ct_data *) cl->cl_private; |
293 AUTH *auth; |
|
266 XDR xdrs; 267 struct rpc_msg reply_msg; 268 bool_t ok; 269 int nrefreshes = 2; /* number of times to refresh cred */ 270 struct timeval timeout; 271 uint32_t xid; 272 struct mbuf *mreq = NULL; | 294 XDR xdrs; 295 struct rpc_msg reply_msg; 296 bool_t ok; 297 int nrefreshes = 2; /* number of times to refresh cred */ 298 struct timeval timeout; 299 uint32_t xid; 300 struct mbuf *mreq = NULL; |
273 struct ct_request cr; | 301 struct ct_request *cr; |
274 int error; 275 | 302 int error; 303 |
304 cr = malloc(sizeof(struct ct_request), M_RPC, M_WAITOK); 305 |
|
276 mtx_lock(&ct->ct_lock); 277 | 306 mtx_lock(&ct->ct_lock); 307 |
278 cr.cr_mrep = NULL; 279 cr.cr_error = 0; | 308 if (ct->ct_closing) { 309 mtx_unlock(&ct->ct_lock); 310 free(cr, M_RPC); 311 return (RPC_CANTSEND); 312 } 313 ct->ct_threads++; |
280 | 314 |
315 if (ext) 316 auth = ext->rc_auth; 317 else 318 auth = cl->cl_auth; 319 320 cr->cr_mrep = NULL; 321 cr->cr_error = 0; 322 |
|
281 if (ct->ct_wait.tv_usec == -1) { 282 timeout = utimeout; /* use supplied timeout */ 283 } else { 284 timeout = ct->ct_wait; /* use default timeout */ 285 } 286 287call_again: 288 mtx_assert(&ct->ct_lock, MA_OWNED); --- 17 unchanged lines hidden (view full) --- 306 */ 307 *mtod(mreq, uint32_t *) = htonl(xid); 308 309 xdrmbuf_create(&xdrs, mreq, XDR_ENCODE); 310 311 ct->ct_error.re_status = RPC_SUCCESS; 312 313 if ((! XDR_PUTINT32(&xdrs, &proc)) || | 323 if (ct->ct_wait.tv_usec == -1) { 324 timeout = utimeout; /* use supplied timeout */ 325 } else { 326 timeout = ct->ct_wait; /* use default timeout */ 327 } 328 329call_again: 330 mtx_assert(&ct->ct_lock, MA_OWNED); --- 17 unchanged lines hidden (view full) --- 348 */ 349 *mtod(mreq, uint32_t *) = htonl(xid); 350 351 xdrmbuf_create(&xdrs, mreq, XDR_ENCODE); 352 353 ct->ct_error.re_status = RPC_SUCCESS; 354 355 if ((! XDR_PUTINT32(&xdrs, &proc)) || |
314 (! AUTH_MARSHALL(cl->cl_auth, &xdrs)) || | 356 (! AUTH_MARSHALL(auth, &xdrs)) || |
315 (! (*xdr_args)(&xdrs, args_ptr))) { 316 if (ct->ct_error.re_status == RPC_SUCCESS) 317 ct->ct_error.re_status = RPC_CANTENCODEARGS; | 357 (! (*xdr_args)(&xdrs, args_ptr))) { 358 if (ct->ct_error.re_status == RPC_SUCCESS) 359 ct->ct_error.re_status = RPC_CANTENCODEARGS; |
318 m_freem(mreq); 319 return (ct->ct_error.re_status); | 360 mtx_lock(&ct->ct_lock); 361 goto out; |
320 } 321 m_fixhdr(mreq); 322 323 /* 324 * Prepend a record marker containing the packet length. 325 */ 326 M_PREPEND(mreq, sizeof(uint32_t), M_WAIT); 327 *mtod(mreq, uint32_t *) = 328 htonl(0x80000000 | (mreq->m_pkthdr.len - sizeof(uint32_t))); 329 | 362 } 363 m_fixhdr(mreq); 364 365 /* 366 * Prepend a record marker containing the packet length. 367 */ 368 M_PREPEND(mreq, sizeof(uint32_t), M_WAIT); 369 *mtod(mreq, uint32_t *) = 370 htonl(0x80000000 | (mreq->m_pkthdr.len - sizeof(uint32_t))); 371 |
330 cr.cr_xid = xid; | 372 cr->cr_xid = xid; |
331 mtx_lock(&ct->ct_lock); | 373 mtx_lock(&ct->ct_lock); |
332 TAILQ_INSERT_TAIL(&ct->ct_pending, &cr, cr_link); | 374 TAILQ_INSERT_TAIL(&ct->ct_pending, cr, cr_link); |
333 mtx_unlock(&ct->ct_lock); 334 335 /* 336 * sosend consumes mreq. 337 */ 338 error = sosend(ct->ct_socket, NULL, NULL, mreq, NULL, 0, curthread); 339 mreq = NULL; 340 341 reply_msg.acpted_rply.ar_verf = _null_auth; 342 reply_msg.acpted_rply.ar_results.where = results_ptr; 343 reply_msg.acpted_rply.ar_results.proc = xdr_results; 344 345 mtx_lock(&ct->ct_lock); | 375 mtx_unlock(&ct->ct_lock); 376 377 /* 378 * sosend consumes mreq. 379 */ 380 error = sosend(ct->ct_socket, NULL, NULL, mreq, NULL, 0, curthread); 381 mreq = NULL; 382 383 reply_msg.acpted_rply.ar_verf = _null_auth; 384 reply_msg.acpted_rply.ar_results.where = results_ptr; 385 reply_msg.acpted_rply.ar_results.proc = xdr_results; 386 387 mtx_lock(&ct->ct_lock); |
346 | |
347 if (error) { | 388 if (error) { |
348 TAILQ_REMOVE(&ct->ct_pending, &cr, cr_link); 349 | 389 TAILQ_REMOVE(&ct->ct_pending, cr, cr_link); |
350 ct->ct_error.re_errno = error; 351 ct->ct_error.re_status = RPC_CANTSEND; 352 goto out; 353 } 354 355 /* 356 * Check to see if we got an upcall while waiting for the 357 * lock. In both these cases, the request has been removed 358 * from ct->ct_pending. 359 */ | 390 ct->ct_error.re_errno = error; 391 ct->ct_error.re_status = RPC_CANTSEND; 392 goto out; 393 } 394 395 /* 396 * Check to see if we got an upcall while waiting for the 397 * lock. In both these cases, the request has been removed 398 * from ct->ct_pending. 399 */ |
360 if (cr.cr_error) { 361 ct->ct_error.re_errno = cr.cr_error; | 400 if (cr->cr_error) { 401 TAILQ_REMOVE(&ct->ct_pending, cr, cr_link); 402 ct->ct_error.re_errno = cr->cr_error; |
362 ct->ct_error.re_status = RPC_CANTRECV; 363 goto out; 364 } | 403 ct->ct_error.re_status = RPC_CANTRECV; 404 goto out; 405 } |
365 if (cr.cr_mrep) { | 406 if (cr->cr_mrep) { 407 TAILQ_REMOVE(&ct->ct_pending, cr, cr_link); |
366 goto got_reply; 367 } 368 369 /* 370 * Hack to provide rpc-based message passing 371 */ 372 if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { | 408 goto got_reply; 409 } 410 411 /* 412 * Hack to provide rpc-based message passing 413 */ 414 if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { |
373 if (cr.cr_xid) 374 TAILQ_REMOVE(&ct->ct_pending, &cr, cr_link); | 415 TAILQ_REMOVE(&ct->ct_pending, cr, cr_link); |
375 ct->ct_error.re_status = RPC_TIMEDOUT; 376 goto out; 377 } 378 | 416 ct->ct_error.re_status = RPC_TIMEDOUT; 417 goto out; 418 } 419 |
379 error = msleep(&cr, &ct->ct_lock, ct->ct_waitflag, ct->ct_waitchan, | 420 error = msleep(cr, &ct->ct_lock, ct->ct_waitflag, ct->ct_waitchan, |
380 tvtohz(&timeout)); 381 | 421 tvtohz(&timeout)); 422 |
423 TAILQ_REMOVE(&ct->ct_pending, cr, cr_link); 424 |
|
382 if (error) { 383 /* 384 * The sleep returned an error so our request is still 385 * on the list. Turn the error code into an 386 * appropriate client status. 387 */ | 425 if (error) { 426 /* 427 * The sleep returned an error so our request is still 428 * on the list. Turn the error code into an 429 * appropriate client status. 430 */ |
388 if (cr.cr_xid) 389 TAILQ_REMOVE(&ct->ct_pending, &cr, cr_link); | |
390 ct->ct_error.re_errno = error; 391 switch (error) { 392 case EINTR: 393 ct->ct_error.re_status = RPC_INTR; 394 break; 395 case EWOULDBLOCK: 396 ct->ct_error.re_status = RPC_TIMEDOUT; 397 break; 398 default: 399 ct->ct_error.re_status = RPC_CANTRECV; 400 } 401 goto out; 402 } else { 403 /* 404 * We were woken up by the upcall. If the 405 * upcall had a receive error, report that, 406 * otherwise we have a reply. 407 */ | 431 ct->ct_error.re_errno = error; 432 switch (error) { 433 case EINTR: 434 ct->ct_error.re_status = RPC_INTR; 435 break; 436 case EWOULDBLOCK: 437 ct->ct_error.re_status = RPC_TIMEDOUT; 438 break; 439 default: 440 ct->ct_error.re_status = RPC_CANTRECV; 441 } 442 goto out; 443 } else { 444 /* 445 * We were woken up by the upcall. If the 446 * upcall had a receive error, report that, 447 * otherwise we have a reply. 448 */ |
408 if (cr.cr_error) { 409 ct->ct_error.re_errno = cr.cr_error; | 449 if (cr->cr_error) { 450 ct->ct_error.re_errno = cr->cr_error; |
410 ct->ct_error.re_status = RPC_CANTRECV; 411 goto out; 412 } 413 } 414 415got_reply: 416 /* 417 * Now decode and validate the response. We need to drop the 418 * lock since xdr_replymsg may end up sleeping in malloc. 419 */ 420 mtx_unlock(&ct->ct_lock); 421 | 451 ct->ct_error.re_status = RPC_CANTRECV; 452 goto out; 453 } 454 } 455 456got_reply: 457 /* 458 * Now decode and validate the response. We need to drop the 459 * lock since xdr_replymsg may end up sleeping in malloc. 460 */ 461 mtx_unlock(&ct->ct_lock); 462 |
422 xdrmbuf_create(&xdrs, cr.cr_mrep, XDR_DECODE); | 463 xdrmbuf_create(&xdrs, cr->cr_mrep, XDR_DECODE); |
423 ok = xdr_replymsg(&xdrs, &reply_msg); 424 XDR_DESTROY(&xdrs); | 464 ok = xdr_replymsg(&xdrs, &reply_msg); 465 XDR_DESTROY(&xdrs); |
425 cr.cr_mrep = NULL; | 466 cr->cr_mrep = NULL; |
426 427 mtx_lock(&ct->ct_lock); 428 429 if (ok) { 430 if ((reply_msg.rm_reply.rp_stat == MSG_ACCEPTED) && 431 (reply_msg.acpted_rply.ar_stat == SUCCESS)) 432 ct->ct_error.re_status = RPC_SUCCESS; 433 else --- 27 unchanged lines hidden (view full) --- 461 else { 462 ct->ct_error.re_status = RPC_CANTDECODERES; 463 } 464out: 465 mtx_assert(&ct->ct_lock, MA_OWNED); 466 467 if (mreq) 468 m_freem(mreq); | 467 468 mtx_lock(&ct->ct_lock); 469 470 if (ok) { 471 if ((reply_msg.rm_reply.rp_stat == MSG_ACCEPTED) && 472 (reply_msg.acpted_rply.ar_stat == SUCCESS)) 473 ct->ct_error.re_status = RPC_SUCCESS; 474 else --- 27 unchanged lines hidden (view full) --- 502 else { 503 ct->ct_error.re_status = RPC_CANTDECODERES; 504 } 505out: 506 mtx_assert(&ct->ct_lock, MA_OWNED); 507 508 if (mreq) 509 m_freem(mreq); |
469 if (cr.cr_mrep) 470 m_freem(cr.cr_mrep); | 510 if (cr->cr_mrep) 511 m_freem(cr->cr_mrep); |
471 | 512 |
513 ct->ct_threads--; 514 if (ct->ct_closing) 515 wakeup(ct); 516 |
|
472 mtx_unlock(&ct->ct_lock); | 517 mtx_unlock(&ct->ct_lock); |
518 519 free(cr, M_RPC); 520 |
|
473 return (ct->ct_error.re_status); 474} 475 476static void 477clnt_vc_geterr(CLIENT *cl, struct rpc_err *errp) 478{ 479 struct ct_data *ct = (struct ct_data *) cl->cl_private; 480 --- 142 unchanged lines hidden (view full) --- 623 mtx_unlock(&ct->ct_lock); 624 return (TRUE); 625} 626 627static void 628clnt_vc_destroy(CLIENT *cl) 629{ 630 struct ct_data *ct = (struct ct_data *) cl->cl_private; | 521 return (ct->ct_error.re_status); 522} 523 524static void 525clnt_vc_geterr(CLIENT *cl, struct rpc_err *errp) 526{ 527 struct ct_data *ct = (struct ct_data *) cl->cl_private; 528 --- 142 unchanged lines hidden (view full) --- 671 mtx_unlock(&ct->ct_lock); 672 return (TRUE); 673} 674 675static void 676clnt_vc_destroy(CLIENT *cl) 677{ 678 struct ct_data *ct = (struct ct_data *) cl->cl_private; |
679 struct ct_request *cr; |
|
631 struct socket *so = NULL; 632 633 mtx_lock(&ct->ct_lock); 634 635 if (ct->ct_socket) { 636 SOCKBUF_LOCK(&ct->ct_socket->so_rcv); 637 ct->ct_socket->so_upcallarg = NULL; 638 ct->ct_socket->so_upcall = NULL; 639 ct->ct_socket->so_rcv.sb_flags &= ~SB_UPCALL; 640 SOCKBUF_UNLOCK(&ct->ct_socket->so_rcv); 641 | 680 struct socket *so = NULL; 681 682 mtx_lock(&ct->ct_lock); 683 684 if (ct->ct_socket) { 685 SOCKBUF_LOCK(&ct->ct_socket->so_rcv); 686 ct->ct_socket->so_upcallarg = NULL; 687 ct->ct_socket->so_upcall = NULL; 688 ct->ct_socket->so_rcv.sb_flags &= ~SB_UPCALL; 689 SOCKBUF_UNLOCK(&ct->ct_socket->so_rcv); 690 |
642 KASSERT(!TAILQ_FIRST(&ct->ct_pending), 643 ("Destroying RPC client with pending RPC requests")); | 691 /* 692 * Abort any pending requests and wait until everyone 693 * has finished with clnt_vc_call. 694 */ 695 ct->ct_closing = TRUE; 696 TAILQ_FOREACH(cr, &ct->ct_pending, cr_link) { 697 cr->cr_xid = 0; 698 cr->cr_error = ESHUTDOWN; 699 wakeup(cr); 700 } |
644 | 701 |
702 while (ct->ct_threads) 703 msleep(ct, &ct->ct_lock, 0, "rpcclose", 0); 704 |
|
645 if (ct->ct_closeit) { 646 so = ct->ct_socket; 647 } 648 } 649 650 mtx_unlock(&ct->ct_lock); 651 652 mtx_destroy(&ct->ct_lock); --- 74 unchanged lines hidden (view full) --- 727 error = ECONNRESET; 728 } 729 ct->ct_error.re_status = RPC_CANTRECV; 730 ct->ct_error.re_errno = error; 731 TAILQ_FOREACH(cr, &ct->ct_pending, cr_link) { 732 cr->cr_error = error; 733 wakeup(cr); 734 } | 705 if (ct->ct_closeit) { 706 so = ct->ct_socket; 707 } 708 } 709 710 mtx_unlock(&ct->ct_lock); 711 712 mtx_destroy(&ct->ct_lock); --- 74 unchanged lines hidden (view full) --- 787 error = ECONNRESET; 788 } 789 ct->ct_error.re_status = RPC_CANTRECV; 790 ct->ct_error.re_errno = error; 791 TAILQ_FOREACH(cr, &ct->ct_pending, cr_link) { 792 cr->cr_error = error; 793 wakeup(cr); 794 } |
735 TAILQ_INIT(&ct->ct_pending); | |
736 mtx_unlock(&ct->ct_lock); 737 break; 738 } 739 memcpy(&header, mtod(m, uint32_t *), sizeof(uint32_t)); 740 header = ntohl(header); 741 ct->ct_record = NULL; 742 ct->ct_record_resid = header & 0x7fffffff; 743 ct->ct_record_eor = ((header & 0x80000000) != 0); --- 46 unchanged lines hidden (view full) --- 790 xid = ntohl(xid); 791 792 mtx_lock(&ct->ct_lock); 793 foundreq = 0; 794 TAILQ_FOREACH(cr, &ct->ct_pending, cr_link) { 795 if (cr->cr_xid == xid) { 796 /* 797 * This one | 795 mtx_unlock(&ct->ct_lock); 796 break; 797 } 798 memcpy(&header, mtod(m, uint32_t *), sizeof(uint32_t)); 799 header = ntohl(header); 800 ct->ct_record = NULL; 801 ct->ct_record_resid = header & 0x7fffffff; 802 ct->ct_record_eor = ((header & 0x80000000) != 0); --- 46 unchanged lines hidden (view full) --- 849 xid = ntohl(xid); 850 851 mtx_lock(&ct->ct_lock); 852 foundreq = 0; 853 TAILQ_FOREACH(cr, &ct->ct_pending, cr_link) { 854 if (cr->cr_xid == xid) { 855 /* 856 * This one |
798 * matches. We snip it 799 * out of the pending 800 * list and leave the 801 * reply mbuf in | 857 * matches. We leave 858 * the reply mbuf in |
802 * cr->cr_mrep. Set 803 * the XID to zero so | 859 * cr->cr_mrep. Set 860 * the XID to zero so |
804 * that clnt_vc_call 805 * can know not to 806 * repeat the 807 * TAILQ_REMOVE. | 861 * that we will ignore 862 * any duplicaed 863 * replies. |
808 */ | 864 */ |
809 TAILQ_REMOVE(&ct->ct_pending, 810 cr, cr_link); | |
811 cr->cr_xid = 0; 812 cr->cr_mrep = ct->ct_record; 813 cr->cr_error = 0; 814 foundreq = 1; 815 wakeup(cr); 816 break; 817 } 818 } 819 mtx_unlock(&ct->ct_lock); 820 821 if (!foundreq) 822 m_freem(ct->ct_record); 823 ct->ct_record = NULL; 824 } 825 } 826 } while (m); 827} | 865 cr->cr_xid = 0; 866 cr->cr_mrep = ct->ct_record; 867 cr->cr_error = 0; 868 foundreq = 1; 869 wakeup(cr); 870 break; 871 } 872 } 873 mtx_unlock(&ct->ct_lock); 874 875 if (!foundreq) 876 m_freem(ct->ct_record); 877 ct->ct_record = NULL; 878 } 879 } 880 } while (m); 881} |