void nsm_disconnect() { if (nsm_count == 0 && nsm_clnt != NULL) { gsh_clnt_destroy(nsm_clnt); nsm_clnt = NULL; AUTH_DESTROY(nsm_auth); nsm_auth = NULL; gsh_free(nodename); nodename = NULL; } }
/* Client routine to send the asynchrnous response, * key is used to wait for a response */ int nlm_send_async(int proc, state_nlm_client_t *host, void *inarg, void *key) { struct timeval tout = { 0, 10 }; int retval, retry; struct timeval start, now; struct timespec timeout; for (retry = 1; retry <= MAX_ASYNC_RETRY; retry++) { if (host->slc_callback_clnt == NULL) { LogFullDebug(COMPONENT_NLM, "gsh_clnt_create %s", host->slc_nsm_client->ssc_nlm_caller_name); if (host->slc_client_type == XPRT_TCP) { int fd; struct sockaddr_in6 server_addr; struct netbuf *buf, local_buf; struct addrinfo *result; struct addrinfo hints; char port_str[20]; fd = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP); if (fd < 0) return -1; memcpy(&server_addr, &(host->slc_server_addr), sizeof(struct sockaddr_in6)); server_addr.sin6_port = 0; if (bind(fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { LogMajor(COMPONENT_NLM, "Cannot bind"); close(fd); return -1; } buf = rpcb_find_mapped_addr( (char *) xprt_type_to_str( host->slc_client_type), NLMPROG, NLM4_VERS, host->slc_nsm_client->ssc_nlm_caller_name); /* handle error here, for example, * client side blocking rpc call */ if (buf == NULL) { LogMajor(COMPONENT_NLM, "Cannot create NLM async %s connection to client %s", xprt_type_to_str( host->slc_client_type), host->slc_nsm_client-> ssc_nlm_caller_name); close(fd); return -1; } memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_INET6; /* only INET6 */ hints.ai_socktype = SOCK_STREAM; /* TCP */ hints.ai_protocol = 0; /* Any protocol */ hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; /* convert port to string format */ sprintf(port_str, "%d", htons(((struct sockaddr_in *) buf->buf)->sin_port)); /* buf with inet is only needed for the port */ gsh_free(buf->buf); gsh_free(buf); /* get the IPv4 mapped IPv6 address */ getaddrinfo(host->slc_nsm_client-> ssc_nlm_caller_name, port_str, &hints, &result); /* setup the netbuf with in6 address */ local_buf.buf = result->ai_addr; local_buf.len = local_buf.maxlen = result->ai_addrlen; host->slc_callback_clnt = clnt_vc_ncreate(fd, &local_buf, NLMPROG, NLM4_VERS, 0, 0); freeaddrinfo(result); } else { host->slc_callback_clnt = gsh_clnt_create( host->slc_nsm_client->ssc_nlm_caller_name, NLMPROG, NLM4_VERS, (char *) xprt_type_to_str( host->slc_client_type)); } if (host->slc_callback_clnt == NULL) { LogMajor(COMPONENT_NLM, "Cannot create NLM async %s connection to client %s", xprt_type_to_str(host-> slc_client_type), host->slc_nsm_client-> ssc_nlm_caller_name); return -1; } /* split auth (for authnone, idempotent) */ host->slc_callback_auth = authnone_create(); } PTHREAD_MUTEX_lock(&nlm_async_resp_mutex); resp_key = key; PTHREAD_MUTEX_unlock(&nlm_async_resp_mutex); LogFullDebug(COMPONENT_NLM, "About to make clnt_call"); retval = clnt_call(host->slc_callback_clnt, host->slc_callback_auth, proc, nlm_reply_proc[proc], inarg, (xdrproc_t) xdr_void, NULL, tout); LogFullDebug(COMPONENT_NLM, "Done with clnt_call"); if (retval == RPC_TIMEDOUT || retval == RPC_SUCCESS) { retval = RPC_SUCCESS; break; } LogCrit(COMPONENT_NLM, "NLM async Client procedure call %d failed with return code %d %s", proc, retval, clnt_sperror(host->slc_callback_clnt, "")); gsh_clnt_destroy(host->slc_callback_clnt); host->slc_callback_clnt = NULL; if (retry == MAX_ASYNC_RETRY) { LogMajor(COMPONENT_NLM, "NLM async Client exceeded retry count %d", MAX_ASYNC_RETRY); PTHREAD_MUTEX_lock(&nlm_async_resp_mutex); resp_key = NULL; PTHREAD_MUTEX_unlock(&nlm_async_resp_mutex); return retval; } } PTHREAD_MUTEX_lock(&nlm_async_resp_mutex); if (resp_key != NULL) { /* Wait for 5 seconds or a signal */ gettimeofday(&start, NULL); gettimeofday(&now, NULL); timeout.tv_sec = 5 + start.tv_sec; timeout.tv_nsec = 0; LogFullDebug(COMPONENT_NLM, "About to wait for signal for key %p", resp_key); while (resp_key != NULL && now.tv_sec < (start.tv_sec + 5)) { int rc; rc = pthread_cond_timedwait(&nlm_async_resp_cond, &nlm_async_resp_mutex, &timeout); LogFullDebug(COMPONENT_NLM, "pthread_cond_timedwait returned %d", rc); gettimeofday(&now, NULL); } LogFullDebug(COMPONENT_NLM, "Done waiting"); } PTHREAD_MUTEX_unlock(&nlm_async_resp_mutex); return retval; }