826                                 delay(SEC_TO_TICK(NLM_NSM_RPCBIND_TIMEOUT));
 827                                 continue;
 828                         }
 829                 }
 830 
 831                 break;
 832         }
 833 
 834         if (stat != RPC_SUCCESS) {
 835                 DTRACE_PROBE2(rpcbind__error, enum clnt_stat, stat,
 836                     int, retries);
 837                 error = ENOENT;
 838                 goto error;
 839         }
 840 
 841         /*
 842          * Create an RPC handle that'll be used for communication with local
 843          * statd using the status monitor protocol.
 844          */
 845         error = clnt_tli_kcreate(&nsm->ns_knc, &nsm->ns_addr, SM_PROG, SM_VERS,
 846             0, NLM_RPC_RETRIES, kcred, &nsm->ns_handle);
 847         if (error != 0)
 848                 goto error;
 849 
 850         /*
 851          * Create an RPC handle that'll be used for communication with the
 852          * local statd using the address registration protocol.
 853          */
 854         error = clnt_tli_kcreate(&nsm->ns_knc, &nsm->ns_addr, NSM_ADDR_PROGRAM,
 855             NSM_ADDR_V1, 0, NLM_RPC_RETRIES, kcred, &nsm->ns_addr_handle);
 856         if (error != 0)
 857                 goto error;
 858 
 859         sema_init(&nsm->ns_sem, 1, NULL, SEMA_DEFAULT, NULL);
 860         return (0);
 861 
 862 error:
 863         kmem_free(nsm->ns_addr.buf, nsm->ns_addr.maxlen);
 864         if (nsm->ns_handle)
 865                 CLNT_DESTROY(nsm->ns_handle);
 866 
 867         return (error);
 868 }
 869 
 870 static void
 871 nlm_nsm_fini(struct nlm_nsm *nsm)
 872 {
 873         kmem_free(nsm->ns_addr.buf, nsm->ns_addr.maxlen);
 874         CLNT_DESTROY(nsm->ns_addr_handle);
 875         nsm->ns_addr_handle = NULL;
 876         CLNT_DESTROY(nsm->ns_handle);
 877         nsm->ns_handle = NULL;
 878         sema_destroy(&nsm->ns_sem);
 879 }
 880 
 881 static enum clnt_stat
 882 nlm_nsm_simu_crash(struct nlm_nsm *nsm)
 883 {
 884         enum clnt_stat stat;
 885 
 886         sema_p(&nsm->ns_sem);
 887         nlm_nsm_clnt_init(nsm->ns_handle, nsm);
 888         stat = sm_simu_crash_1(NULL, NULL, nsm->ns_handle);
 889         sema_v(&nsm->ns_sem);
 890 
 891         return (stat);
 892 }
 893 
 894 static enum clnt_stat
 895 nlm_nsm_stat(struct nlm_nsm *nsm, int32_t *out_stat)
 
2610                         nvp->nv_refcnt--;
2611                 }
2612                 mutex_exit(&hostp->nh_lock);
2613 
2614                 mutex_enter(&g->lock);
2615                 nlm_host_release_locked(g, hostp);
2616 
2617                 hostp = AVL_NEXT(&g->nlm_hosts_tree, hostp);
2618         }
2619 
2620         mutex_exit(&g->lock);
2621 }
2622 
2623 void
2624 nlm_unexport(struct exportinfo *exi)
2625 {
2626         struct nlm_globals *g;
2627 
2628         rw_enter(&lm_lck, RW_READER);
2629         TAILQ_FOREACH(g, &nlm_zones_list, nlm_link) {
2630                 if (g->nlm_zoneid != exi->exi_zoneid)
2631                         continue;
2632                 nlm_zone_unexport(g, exi);
2633         }
2634         rw_exit(&lm_lck);
2635 }
2636 
2637 /*
2638  * Allocate new unique sysid.
2639  * In case of failure (no available sysids)
2640  * return LM_NOSYSID.
2641  */
2642 sysid_t
2643 nlm_sysid_alloc(void)
2644 {
2645         sysid_t ret_sysid = LM_NOSYSID;
2646 
2647         rw_enter(&lm_lck, RW_WRITER);
2648         if (nlm_sysid_nidx > LM_SYSID_MAX)
2649                 nlm_sysid_nidx = LM_SYSID;
2650 
2651         if (!BT_TEST(nlm_sysid_bmap, nlm_sysid_nidx)) {
2652                 BT_SET(nlm_sysid_bmap, nlm_sysid_nidx);
2653                 ret_sysid = nlm_sysid_nidx++;
 
2785 
2786         rw_exit(&lm_lck);
2787 }
2788 
2789 void
2790 nlm_cprresume(void)
2791 {
2792         struct nlm_globals *g;
2793 
2794         rw_enter(&lm_lck, RW_READER);
2795         TAILQ_FOREACH(g, &nlm_zones_list, nlm_link)
2796                 nlm_resume_zone(g);
2797 
2798         rw_exit(&lm_lck);
2799 }
2800 
2801 static void
2802 nlm_nsm_clnt_init(CLIENT *clnt, struct nlm_nsm *nsm)
2803 {
2804         (void) clnt_tli_kinit(clnt, &nsm->ns_knc, &nsm->ns_addr, 0,
2805             NLM_RPC_RETRIES, kcred);
2806 }
2807 
2808 static void
2809 nlm_netbuf_to_netobj(struct netbuf *addr, int *family, netobj *obj)
2810 {
2811         /* LINTED pointer alignment */
2812         struct sockaddr *sa = (struct sockaddr *)addr->buf;
2813 
2814         *family = sa->sa_family;
2815 
2816         switch (sa->sa_family) {
2817         case AF_INET: {
2818                 /* LINTED pointer alignment */
2819                 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
2820 
2821                 obj->n_len = sizeof (sin->sin_addr);
2822                 obj->n_bytes = (char *)&sin->sin_addr;
2823                 break;
2824         }
2825 
 | 
 
 
 826                                 delay(SEC_TO_TICK(NLM_NSM_RPCBIND_TIMEOUT));
 827                                 continue;
 828                         }
 829                 }
 830 
 831                 break;
 832         }
 833 
 834         if (stat != RPC_SUCCESS) {
 835                 DTRACE_PROBE2(rpcbind__error, enum clnt_stat, stat,
 836                     int, retries);
 837                 error = ENOENT;
 838                 goto error;
 839         }
 840 
 841         /*
 842          * Create an RPC handle that'll be used for communication with local
 843          * statd using the status monitor protocol.
 844          */
 845         error = clnt_tli_kcreate(&nsm->ns_knc, &nsm->ns_addr, SM_PROG, SM_VERS,
 846             0, NLM_RPC_RETRIES, zone_kcred(), &nsm->ns_handle);
 847         if (error != 0)
 848                 goto error;
 849 
 850         /*
 851          * Create an RPC handle that'll be used for communication with the
 852          * local statd using the address registration protocol.
 853          */
 854         error = clnt_tli_kcreate(&nsm->ns_knc, &nsm->ns_addr, NSM_ADDR_PROGRAM,
 855             NSM_ADDR_V1, 0, NLM_RPC_RETRIES, zone_kcred(),
 856             &nsm->ns_addr_handle);
 857         if (error != 0)
 858                 goto error;
 859 
 860         sema_init(&nsm->ns_sem, 1, NULL, SEMA_DEFAULT, NULL);
 861         return (0);
 862 
 863 error:
 864         kmem_free(nsm->ns_addr.buf, nsm->ns_addr.maxlen);
 865         if (nsm->ns_handle) {
 866                 ASSERT(nsm->ns_handle->cl_auth != NULL);
 867                 auth_destroy(nsm->ns_handle->cl_auth);
 868                 CLNT_DESTROY(nsm->ns_handle);
 869         }
 870 
 871         return (error);
 872 }
 873 
 874 static void
 875 nlm_nsm_fini(struct nlm_nsm *nsm)
 876 {
 877         kmem_free(nsm->ns_addr.buf, nsm->ns_addr.maxlen);
 878         if (nsm->ns_addr_handle->cl_auth != NULL)
 879                 auth_destroy(nsm->ns_addr_handle->cl_auth);
 880         CLNT_DESTROY(nsm->ns_addr_handle);
 881         nsm->ns_addr_handle = NULL;
 882         if (nsm->ns_handle->cl_auth != NULL)
 883                 auth_destroy(nsm->ns_handle->cl_auth);
 884         CLNT_DESTROY(nsm->ns_handle);
 885         nsm->ns_handle = NULL;
 886         sema_destroy(&nsm->ns_sem);
 887 }
 888 
 889 static enum clnt_stat
 890 nlm_nsm_simu_crash(struct nlm_nsm *nsm)
 891 {
 892         enum clnt_stat stat;
 893 
 894         sema_p(&nsm->ns_sem);
 895         nlm_nsm_clnt_init(nsm->ns_handle, nsm);
 896         stat = sm_simu_crash_1(NULL, NULL, nsm->ns_handle);
 897         sema_v(&nsm->ns_sem);
 898 
 899         return (stat);
 900 }
 901 
 902 static enum clnt_stat
 903 nlm_nsm_stat(struct nlm_nsm *nsm, int32_t *out_stat)
 
2618                         nvp->nv_refcnt--;
2619                 }
2620                 mutex_exit(&hostp->nh_lock);
2621 
2622                 mutex_enter(&g->lock);
2623                 nlm_host_release_locked(g, hostp);
2624 
2625                 hostp = AVL_NEXT(&g->nlm_hosts_tree, hostp);
2626         }
2627 
2628         mutex_exit(&g->lock);
2629 }
2630 
2631 void
2632 nlm_unexport(struct exportinfo *exi)
2633 {
2634         struct nlm_globals *g;
2635 
2636         rw_enter(&lm_lck, RW_READER);
2637         TAILQ_FOREACH(g, &nlm_zones_list, nlm_link) {
2638                 if (g->nlm_zoneid == exi->exi_zoneid) {
2639                         /*
2640                          * NOTE: If we want to drop lm_lock before
2641                          * calling nlm_zone_unexport(), we should break,
2642                          * and have a post-rw_exit() snippit like:
2643                          *      if (g != NULL)
2644                          *              nlm_zone_unexport(g, exi);
2645                          */
2646                         nlm_zone_unexport(g, exi);
2647                         break; /* Only going to match once! */
2648                 }
2649         }
2650         rw_exit(&lm_lck);
2651 }
2652 
2653 /*
2654  * Allocate new unique sysid.
2655  * In case of failure (no available sysids)
2656  * return LM_NOSYSID.
2657  */
2658 sysid_t
2659 nlm_sysid_alloc(void)
2660 {
2661         sysid_t ret_sysid = LM_NOSYSID;
2662 
2663         rw_enter(&lm_lck, RW_WRITER);
2664         if (nlm_sysid_nidx > LM_SYSID_MAX)
2665                 nlm_sysid_nidx = LM_SYSID;
2666 
2667         if (!BT_TEST(nlm_sysid_bmap, nlm_sysid_nidx)) {
2668                 BT_SET(nlm_sysid_bmap, nlm_sysid_nidx);
2669                 ret_sysid = nlm_sysid_nidx++;
 
2801 
2802         rw_exit(&lm_lck);
2803 }
2804 
2805 void
2806 nlm_cprresume(void)
2807 {
2808         struct nlm_globals *g;
2809 
2810         rw_enter(&lm_lck, RW_READER);
2811         TAILQ_FOREACH(g, &nlm_zones_list, nlm_link)
2812                 nlm_resume_zone(g);
2813 
2814         rw_exit(&lm_lck);
2815 }
2816 
2817 static void
2818 nlm_nsm_clnt_init(CLIENT *clnt, struct nlm_nsm *nsm)
2819 {
2820         (void) clnt_tli_kinit(clnt, &nsm->ns_knc, &nsm->ns_addr, 0,
2821             NLM_RPC_RETRIES, zone_kcred());
2822 }
2823 
2824 static void
2825 nlm_netbuf_to_netobj(struct netbuf *addr, int *family, netobj *obj)
2826 {
2827         /* LINTED pointer alignment */
2828         struct sockaddr *sa = (struct sockaddr *)addr->buf;
2829 
2830         *family = sa->sa_family;
2831 
2832         switch (sa->sa_family) {
2833         case AF_INET: {
2834                 /* LINTED pointer alignment */
2835                 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
2836 
2837                 obj->n_len = sizeof (sin->sin_addr);
2838                 obj->n_bytes = (char *)&sin->sin_addr;
2839                 break;
2840         }
2841 
 |