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
|