970 p->cku_err.re_errno = EIO;
971
972 RPCLOG(1, "clnt_cots_kcallit: transport failed: %d\n",
973 p->cku_err.re_errno);
974
975 break;
976
977 default:
978 /*
979 * We delay here because it is better to err
980 * on the side of caution. If we got here then
981 * status could have been RPC_SUCCESS, but we
982 * know that we did not get a connection, so
983 * force the rpc status to RPC_CANTCONNECT.
984 */
985 p->cku_err.re_status = RPC_CANTCONNECT;
986 p->cku_err.re_errno = EIO;
987 break;
988 }
989 if (delay_first == TRUE)
990 ticks = clnt_cots_min_tout * drv_usectohz(1000000);
991 goto cots_done;
992 }
993
994 /*
995 * If we've never sent any request on this connection (send count
996 * is zero, or the connection has been reset), cache the
997 * the connection's create time and send a request (possibly a retry)
998 */
999 if ((p->cku_flags & CKU_SENT) == 0 ||
1000 p->cku_ctime != cm_entry->x_ctime) {
1001 p->cku_ctime = cm_entry->x_ctime;
1002
1003 } else if ((p->cku_flags & CKU_SENT) && (p->cku_flags & CKU_ONQUEUE) &&
1004 (call->call_reply != NULL ||
1005 p->cku_recv_attempts < clnt_cots_maxrecv)) {
1006
1007 /*
1008 * If we've sent a request and our call is on the dispatch
1009 * queue and we haven't made too many receive attempts, then
1010 * don't re-send, just receive.
1102
1103 wq = cm_entry->x_wq;
1104 waitsecs = 0;
1105
1106 dispatch_again:
1107 status = clnt_dispatch_send(wq, mp, call, p->cku_xid,
1108 (p->cku_flags & CKU_ONQUEUE));
1109
1110 if ((status == RPC_CANTSEND) && (call->call_reason == ENOBUFS)) {
1111 /*
1112 * QFULL condition, allow some time for queue to drain
1113 * and try again. Give up after waiting for all timeout
1114 * specified for the call, or zone is going away.
1115 */
1116 max_waitsecs = wait.tv_sec ? wait.tv_sec : clnt_cots_min_tout;
1117 if ((waitsecs++ < max_waitsecs) &&
1118 !(zone_status_get(curproc->p_zone) >=
1119 ZONE_IS_SHUTTING_DOWN)) {
1120
1121 /* wait 1 sec for queue to drain */
1122 if (clnt_delay(drv_usectohz(1000000),
1123 h->cl_nosignal) == EINTR) {
1124 p->cku_err.re_errno = EINTR;
1125 p->cku_err.re_status = RPC_INTR;
1126
1127 goto cots_done;
1128 }
1129
1130 /* and try again */
1131 goto dispatch_again;
1132 }
1133 p->cku_err.re_status = status;
1134 p->cku_err.re_errno = call->call_reason;
1135 DTRACE_PROBE(krpc__e__clntcots__kcallit__cantsend);
1136
1137 goto cots_done;
1138 }
1139
1140 if (waitsecs) {
1141 /* adjust timeout to account for time wait to send */
1142 wait.tv_sec -= waitsecs;
1166 mutex_enter(&call->call_lock);
1167 interrupted = 0;
1168 if (call->call_status == RPC_TIMEDOUT) {
1169 /*
1170 * Indicate that the lwp is not to be stopped while waiting
1171 * for this network traffic. This is to avoid deadlock while
1172 * debugging a process via /proc and also to avoid recursive
1173 * mutex_enter()s due to NFS page faults while stopping
1174 * (NFS holds locks when it calls here).
1175 */
1176 clock_t cv_wait_ret;
1177 clock_t timout;
1178 clock_t oldlbolt;
1179
1180 klwp_t *lwp = ttolwp(curthread);
1181
1182 if (lwp != NULL)
1183 lwp->lwp_nostop++;
1184
1185 oldlbolt = ddi_get_lbolt();
1186 timout = wait.tv_sec * drv_usectohz(1000000) +
1187 drv_usectohz(wait.tv_usec) + oldlbolt;
1188 /*
1189 * Iterate until the call_status is changed to something
1190 * other that RPC_TIMEDOUT, or if cv_timedwait_sig() returns
1191 * something <=0 zero. The latter means that we timed
1192 * out.
1193 */
1194 if (h->cl_nosignal)
1195 while ((cv_wait_ret = cv_timedwait(&call->call_cv,
1196 &call->call_lock, timout)) > 0 &&
1197 call->call_status == RPC_TIMEDOUT)
1198 ;
1199 else
1200 while ((cv_wait_ret = cv_timedwait_sig(
1201 &call->call_cv,
1202 &call->call_lock, timout)) > 0 &&
1203 call->call_status == RPC_TIMEDOUT)
1204 ;
1205
1206 switch (cv_wait_ret) {
1215 case -1:
1216 /* cv_timedwait_sig() timed out */
1217 break;
1218 default:
1219
1220 /*
1221 * We were cv_signaled(). If we didn't
1222 * get a successful call_status and returned
1223 * before time expired, delay up to clnt_cots_min_tout
1224 * seconds so that the caller doesn't immediately
1225 * try to call us again and thus force the
1226 * same condition that got us here (such
1227 * as a RPC_XPRTFAILED due to the server not
1228 * listening on the end-point.
1229 */
1230 if (call->call_status != RPC_SUCCESS) {
1231 clock_t curlbolt;
1232 clock_t diff;
1233
1234 curlbolt = ddi_get_lbolt();
1235 ticks = clnt_cots_min_tout *
1236 drv_usectohz(1000000);
1237 diff = curlbolt - oldlbolt;
1238 if (diff < ticks) {
1239 delay_first = TRUE;
1240 if (diff > 0)
1241 ticks -= diff;
1242 }
1243 }
1244 break;
1245 }
1246
1247 if (lwp != NULL)
1248 lwp->lwp_nostop--;
1249 }
1250 /*
1251 * Get the reply message, if any. This will be freed at the end
1252 * whether or not an error occurred.
1253 */
1254 mp = call->call_reply;
1255 call->call_reply = NULL;
1256
1698 clock_t timout, cv_stat;
1699 enum clnt_stat clstat;
1700 unsigned int old_state;
1701
1702 ASSERT(MUTEX_HELD(&connmgr_lock));
1703 /*
1704 * We wait for the transport connection to be made, or an
1705 * indication that it could not be made.
1706 */
1707 clstat = RPC_TIMEDOUT;
1708 interrupted = FALSE;
1709
1710 old_state = cm_entry->x_state_flags;
1711 /*
1712 * Now loop until cv_timedwait{_sig} returns because of
1713 * a signal(0) or timeout(-1) or cv_signal(>0). But it may be
1714 * cv_signalled for various other reasons too. So loop
1715 * until there is a state change on the connection.
1716 */
1717
1718 timout = waitp->tv_sec * drv_usectohz(1000000) +
1719 drv_usectohz(waitp->tv_usec) + ddi_get_lbolt();
1720
1721 if (nosignal) {
1722 while ((cv_stat = cv_timedwait(&cm_entry->x_conn_cv,
1723 &connmgr_lock, timout)) > 0 &&
1724 cm_entry->x_state_flags == old_state)
1725 ;
1726 } else {
1727 while ((cv_stat = cv_timedwait_sig(&cm_entry->x_conn_cv,
1728 &connmgr_lock, timout)) > 0 &&
1729 cm_entry->x_state_flags == old_state)
1730 ;
1731
1732 if (cv_stat == 0) /* got intr signal? */
1733 interrupted = TRUE;
1734 }
1735
1736 if ((cm_entry->x_state_flags & (X_BADSTATES|X_CONNECTED)) ==
1737 X_CONNECTED) {
1738 clstat = RPC_SUCCESS;
2336 * wait for it to complete the connection.
2337 */
2338 if (cm_entry->x_thread == TRUE) {
2339 rpcerr->re_status = connmgr_cwait(cm_entry, waitp, nosignal);
2340
2341 if (rpcerr->re_status != RPC_SUCCESS) {
2342 mutex_exit(&connmgr_lock);
2343 connmgr_release(cm_entry);
2344 return (NULL);
2345 }
2346 } else {
2347 bool_t connected;
2348 calllist_t call;
2349
2350 cm_entry->x_thread = TRUE;
2351
2352 while (cm_entry->x_needrel == TRUE) {
2353 cm_entry->x_needrel = FALSE;
2354
2355 connmgr_sndrel(cm_entry);
2356 delay(drv_usectohz(1000000));
2357
2358 mutex_enter(&connmgr_lock);
2359 }
2360
2361 /*
2362 * If we need to send a T_DISCON_REQ, send one.
2363 */
2364 connmgr_dis_and_wait(cm_entry);
2365
2366 mutex_exit(&connmgr_lock);
2367
2368 bzero(&call, sizeof (call));
2369 cv_init(&call.call_cv, NULL, CV_DEFAULT, NULL);
2370
2371 connected = connmgr_connect(cm_entry, cm_entry->x_wq,
2372 destaddr, addrfmly, &call, &cm_entry->x_tidu_size,
2373 reconnect, waitp, nosignal, cr);
2374
2375 *rpcerr = call.call_err;
2376 cv_destroy(&call.call_cv);
2452 for (;;) {
2453 while (cm_entry->x_needdis == TRUE) {
2454 RPCLOG(8, "connmgr_dis_and_wait: need "
2455 "T_DISCON_REQ for connection 0x%p\n",
2456 (void *)cm_entry);
2457 cm_entry->x_needdis = FALSE;
2458 cm_entry->x_waitdis = TRUE;
2459
2460 connmgr_snddis(cm_entry);
2461
2462 mutex_enter(&connmgr_lock);
2463 }
2464
2465 if (cm_entry->x_waitdis == TRUE) {
2466 clock_t timout;
2467
2468 RPCLOG(8, "connmgr_dis_and_wait waiting for "
2469 "T_DISCON_REQ's ACK for connection %p\n",
2470 (void *)cm_entry);
2471
2472 timout = clnt_cots_min_conntout * drv_usectohz(1000000);
2473
2474 /*
2475 * The TPI spec says that the T_DISCON_REQ
2476 * will get acknowledged, but in practice
2477 * the ACK may never get sent. So don't
2478 * block forever.
2479 */
2480 (void) cv_reltimedwait(&cm_entry->x_dis_cv,
2481 &connmgr_lock, timout, TR_CLOCK_TICK);
2482 }
2483 /*
2484 * If we got the ACK, break. If we didn't,
2485 * then send another T_DISCON_REQ.
2486 */
2487 if (cm_entry->x_waitdis == FALSE) {
2488 break;
2489 } else {
2490 RPCLOG(8, "connmgr_dis_and_wait: did"
2491 "not get T_DISCON_REQ's ACK for "
2492 "connection %p\n", (void *)cm_entry);
3691 {
3692 (void) zone_key_delete(zone_cots_key);
3693 }
3694
3695 /*
3696 * Wait for TPI ack, returns success only if expected ack is received
3697 * within timeout period.
3698 */
3699
3700 static int
3701 waitforack(calllist_t *e, t_scalar_t ack_prim, const struct timeval *waitp,
3702 bool_t nosignal)
3703 {
3704 union T_primitives *tpr;
3705 clock_t timout;
3706 int cv_stat = 1;
3707
3708 ASSERT(MUTEX_HELD(&clnt_pending_lock));
3709 while (e->call_reply == NULL) {
3710 if (waitp != NULL) {
3711 timout = waitp->tv_sec * drv_usectohz(MICROSEC) +
3712 drv_usectohz(waitp->tv_usec);
3713 if (nosignal)
3714 cv_stat = cv_reltimedwait(&e->call_cv,
3715 &clnt_pending_lock, timout, TR_CLOCK_TICK);
3716 else
3717 cv_stat = cv_reltimedwait_sig(&e->call_cv,
3718 &clnt_pending_lock, timout, TR_CLOCK_TICK);
3719 } else {
3720 if (nosignal)
3721 cv_wait(&e->call_cv, &clnt_pending_lock);
3722 else
3723 cv_stat = cv_wait_sig(&e->call_cv,
3724 &clnt_pending_lock);
3725 }
3726 if (cv_stat == -1)
3727 return (ETIME);
3728 if (cv_stat == 0)
3729 return (EINTR);
3730 /*
3731 * if we received an error from the server and we know a reply
|
970 p->cku_err.re_errno = EIO;
971
972 RPCLOG(1, "clnt_cots_kcallit: transport failed: %d\n",
973 p->cku_err.re_errno);
974
975 break;
976
977 default:
978 /*
979 * We delay here because it is better to err
980 * on the side of caution. If we got here then
981 * status could have been RPC_SUCCESS, but we
982 * know that we did not get a connection, so
983 * force the rpc status to RPC_CANTCONNECT.
984 */
985 p->cku_err.re_status = RPC_CANTCONNECT;
986 p->cku_err.re_errno = EIO;
987 break;
988 }
989 if (delay_first == TRUE)
990 ticks = drv_sectohz(clnt_cots_min_tout);
991 goto cots_done;
992 }
993
994 /*
995 * If we've never sent any request on this connection (send count
996 * is zero, or the connection has been reset), cache the
997 * the connection's create time and send a request (possibly a retry)
998 */
999 if ((p->cku_flags & CKU_SENT) == 0 ||
1000 p->cku_ctime != cm_entry->x_ctime) {
1001 p->cku_ctime = cm_entry->x_ctime;
1002
1003 } else if ((p->cku_flags & CKU_SENT) && (p->cku_flags & CKU_ONQUEUE) &&
1004 (call->call_reply != NULL ||
1005 p->cku_recv_attempts < clnt_cots_maxrecv)) {
1006
1007 /*
1008 * If we've sent a request and our call is on the dispatch
1009 * queue and we haven't made too many receive attempts, then
1010 * don't re-send, just receive.
1102
1103 wq = cm_entry->x_wq;
1104 waitsecs = 0;
1105
1106 dispatch_again:
1107 status = clnt_dispatch_send(wq, mp, call, p->cku_xid,
1108 (p->cku_flags & CKU_ONQUEUE));
1109
1110 if ((status == RPC_CANTSEND) && (call->call_reason == ENOBUFS)) {
1111 /*
1112 * QFULL condition, allow some time for queue to drain
1113 * and try again. Give up after waiting for all timeout
1114 * specified for the call, or zone is going away.
1115 */
1116 max_waitsecs = wait.tv_sec ? wait.tv_sec : clnt_cots_min_tout;
1117 if ((waitsecs++ < max_waitsecs) &&
1118 !(zone_status_get(curproc->p_zone) >=
1119 ZONE_IS_SHUTTING_DOWN)) {
1120
1121 /* wait 1 sec for queue to drain */
1122 if (clnt_delay(drv_sectohz(1),
1123 h->cl_nosignal) == EINTR) {
1124 p->cku_err.re_errno = EINTR;
1125 p->cku_err.re_status = RPC_INTR;
1126
1127 goto cots_done;
1128 }
1129
1130 /* and try again */
1131 goto dispatch_again;
1132 }
1133 p->cku_err.re_status = status;
1134 p->cku_err.re_errno = call->call_reason;
1135 DTRACE_PROBE(krpc__e__clntcots__kcallit__cantsend);
1136
1137 goto cots_done;
1138 }
1139
1140 if (waitsecs) {
1141 /* adjust timeout to account for time wait to send */
1142 wait.tv_sec -= waitsecs;
1166 mutex_enter(&call->call_lock);
1167 interrupted = 0;
1168 if (call->call_status == RPC_TIMEDOUT) {
1169 /*
1170 * Indicate that the lwp is not to be stopped while waiting
1171 * for this network traffic. This is to avoid deadlock while
1172 * debugging a process via /proc and also to avoid recursive
1173 * mutex_enter()s due to NFS page faults while stopping
1174 * (NFS holds locks when it calls here).
1175 */
1176 clock_t cv_wait_ret;
1177 clock_t timout;
1178 clock_t oldlbolt;
1179
1180 klwp_t *lwp = ttolwp(curthread);
1181
1182 if (lwp != NULL)
1183 lwp->lwp_nostop++;
1184
1185 oldlbolt = ddi_get_lbolt();
1186 timout = drv_sectohz(wait.tv_sec) +
1187 drv_usectohz(wait.tv_usec) + oldlbolt;
1188 /*
1189 * Iterate until the call_status is changed to something
1190 * other that RPC_TIMEDOUT, or if cv_timedwait_sig() returns
1191 * something <=0 zero. The latter means that we timed
1192 * out.
1193 */
1194 if (h->cl_nosignal)
1195 while ((cv_wait_ret = cv_timedwait(&call->call_cv,
1196 &call->call_lock, timout)) > 0 &&
1197 call->call_status == RPC_TIMEDOUT)
1198 ;
1199 else
1200 while ((cv_wait_ret = cv_timedwait_sig(
1201 &call->call_cv,
1202 &call->call_lock, timout)) > 0 &&
1203 call->call_status == RPC_TIMEDOUT)
1204 ;
1205
1206 switch (cv_wait_ret) {
1215 case -1:
1216 /* cv_timedwait_sig() timed out */
1217 break;
1218 default:
1219
1220 /*
1221 * We were cv_signaled(). If we didn't
1222 * get a successful call_status and returned
1223 * before time expired, delay up to clnt_cots_min_tout
1224 * seconds so that the caller doesn't immediately
1225 * try to call us again and thus force the
1226 * same condition that got us here (such
1227 * as a RPC_XPRTFAILED due to the server not
1228 * listening on the end-point.
1229 */
1230 if (call->call_status != RPC_SUCCESS) {
1231 clock_t curlbolt;
1232 clock_t diff;
1233
1234 curlbolt = ddi_get_lbolt();
1235 ticks = drv_sectohz(clnt_cots_min_tout);
1236 diff = curlbolt - oldlbolt;
1237 if (diff < ticks) {
1238 delay_first = TRUE;
1239 if (diff > 0)
1240 ticks -= diff;
1241 }
1242 }
1243 break;
1244 }
1245
1246 if (lwp != NULL)
1247 lwp->lwp_nostop--;
1248 }
1249 /*
1250 * Get the reply message, if any. This will be freed at the end
1251 * whether or not an error occurred.
1252 */
1253 mp = call->call_reply;
1254 call->call_reply = NULL;
1255
1697 clock_t timout, cv_stat;
1698 enum clnt_stat clstat;
1699 unsigned int old_state;
1700
1701 ASSERT(MUTEX_HELD(&connmgr_lock));
1702 /*
1703 * We wait for the transport connection to be made, or an
1704 * indication that it could not be made.
1705 */
1706 clstat = RPC_TIMEDOUT;
1707 interrupted = FALSE;
1708
1709 old_state = cm_entry->x_state_flags;
1710 /*
1711 * Now loop until cv_timedwait{_sig} returns because of
1712 * a signal(0) or timeout(-1) or cv_signal(>0). But it may be
1713 * cv_signalled for various other reasons too. So loop
1714 * until there is a state change on the connection.
1715 */
1716
1717 timout = drv_sectohz(waitp->tv_sec) +
1718 drv_usectohz(waitp->tv_usec) + ddi_get_lbolt();
1719
1720 if (nosignal) {
1721 while ((cv_stat = cv_timedwait(&cm_entry->x_conn_cv,
1722 &connmgr_lock, timout)) > 0 &&
1723 cm_entry->x_state_flags == old_state)
1724 ;
1725 } else {
1726 while ((cv_stat = cv_timedwait_sig(&cm_entry->x_conn_cv,
1727 &connmgr_lock, timout)) > 0 &&
1728 cm_entry->x_state_flags == old_state)
1729 ;
1730
1731 if (cv_stat == 0) /* got intr signal? */
1732 interrupted = TRUE;
1733 }
1734
1735 if ((cm_entry->x_state_flags & (X_BADSTATES|X_CONNECTED)) ==
1736 X_CONNECTED) {
1737 clstat = RPC_SUCCESS;
2335 * wait for it to complete the connection.
2336 */
2337 if (cm_entry->x_thread == TRUE) {
2338 rpcerr->re_status = connmgr_cwait(cm_entry, waitp, nosignal);
2339
2340 if (rpcerr->re_status != RPC_SUCCESS) {
2341 mutex_exit(&connmgr_lock);
2342 connmgr_release(cm_entry);
2343 return (NULL);
2344 }
2345 } else {
2346 bool_t connected;
2347 calllist_t call;
2348
2349 cm_entry->x_thread = TRUE;
2350
2351 while (cm_entry->x_needrel == TRUE) {
2352 cm_entry->x_needrel = FALSE;
2353
2354 connmgr_sndrel(cm_entry);
2355 delay(drv_sectohz(1));
2356
2357 mutex_enter(&connmgr_lock);
2358 }
2359
2360 /*
2361 * If we need to send a T_DISCON_REQ, send one.
2362 */
2363 connmgr_dis_and_wait(cm_entry);
2364
2365 mutex_exit(&connmgr_lock);
2366
2367 bzero(&call, sizeof (call));
2368 cv_init(&call.call_cv, NULL, CV_DEFAULT, NULL);
2369
2370 connected = connmgr_connect(cm_entry, cm_entry->x_wq,
2371 destaddr, addrfmly, &call, &cm_entry->x_tidu_size,
2372 reconnect, waitp, nosignal, cr);
2373
2374 *rpcerr = call.call_err;
2375 cv_destroy(&call.call_cv);
2451 for (;;) {
2452 while (cm_entry->x_needdis == TRUE) {
2453 RPCLOG(8, "connmgr_dis_and_wait: need "
2454 "T_DISCON_REQ for connection 0x%p\n",
2455 (void *)cm_entry);
2456 cm_entry->x_needdis = FALSE;
2457 cm_entry->x_waitdis = TRUE;
2458
2459 connmgr_snddis(cm_entry);
2460
2461 mutex_enter(&connmgr_lock);
2462 }
2463
2464 if (cm_entry->x_waitdis == TRUE) {
2465 clock_t timout;
2466
2467 RPCLOG(8, "connmgr_dis_and_wait waiting for "
2468 "T_DISCON_REQ's ACK for connection %p\n",
2469 (void *)cm_entry);
2470
2471 timout = drv_sectohz(clnt_cots_min_conntout);
2472
2473 /*
2474 * The TPI spec says that the T_DISCON_REQ
2475 * will get acknowledged, but in practice
2476 * the ACK may never get sent. So don't
2477 * block forever.
2478 */
2479 (void) cv_reltimedwait(&cm_entry->x_dis_cv,
2480 &connmgr_lock, timout, TR_CLOCK_TICK);
2481 }
2482 /*
2483 * If we got the ACK, break. If we didn't,
2484 * then send another T_DISCON_REQ.
2485 */
2486 if (cm_entry->x_waitdis == FALSE) {
2487 break;
2488 } else {
2489 RPCLOG(8, "connmgr_dis_and_wait: did"
2490 "not get T_DISCON_REQ's ACK for "
2491 "connection %p\n", (void *)cm_entry);
3690 {
3691 (void) zone_key_delete(zone_cots_key);
3692 }
3693
3694 /*
3695 * Wait for TPI ack, returns success only if expected ack is received
3696 * within timeout period.
3697 */
3698
3699 static int
3700 waitforack(calllist_t *e, t_scalar_t ack_prim, const struct timeval *waitp,
3701 bool_t nosignal)
3702 {
3703 union T_primitives *tpr;
3704 clock_t timout;
3705 int cv_stat = 1;
3706
3707 ASSERT(MUTEX_HELD(&clnt_pending_lock));
3708 while (e->call_reply == NULL) {
3709 if (waitp != NULL) {
3710 timout = drv_sectohz(waitp->tv_sec) +
3711 drv_usectohz(waitp->tv_usec);
3712 if (nosignal)
3713 cv_stat = cv_reltimedwait(&e->call_cv,
3714 &clnt_pending_lock, timout, TR_CLOCK_TICK);
3715 else
3716 cv_stat = cv_reltimedwait_sig(&e->call_cv,
3717 &clnt_pending_lock, timout, TR_CLOCK_TICK);
3718 } else {
3719 if (nosignal)
3720 cv_wait(&e->call_cv, &clnt_pending_lock);
3721 else
3722 cv_stat = cv_wait_sig(&e->call_cv,
3723 &clnt_pending_lock);
3724 }
3725 if (cv_stat == -1)
3726 return (ETIME);
3727 if (cv_stat == 0)
3728 return (EINTR);
3729 /*
3730 * if we received an error from the server and we know a reply
|