846
847 /*
848 * Create an RPC handle that'll be used for communication with local
849 * statd using the status monitor protocol.
850 */
851 error = clnt_tli_kcreate(&nsm->ns_knc, &nsm->ns_addr, SM_PROG, SM_VERS,
852 0, NLM_RPC_RETRIES, zone_kcred(), &nsm->ns_handle);
853 if (error != 0)
854 goto error;
855
856 /*
857 * Create an RPC handle that'll be used for communication with the
858 * local statd using the address registration protocol.
859 */
860 error = clnt_tli_kcreate(&nsm->ns_knc, &nsm->ns_addr, NSM_ADDR_PROGRAM,
861 NSM_ADDR_V1, 0, NLM_RPC_RETRIES, zone_kcred(),
862 &nsm->ns_addr_handle);
863 if (error != 0)
864 goto error;
865
866 sema_init(&nsm->ns_sem, 1, NULL, SEMA_DEFAULT, NULL);
867 return (0);
868
869 error:
870 kmem_free(nsm->ns_addr.buf, nsm->ns_addr.maxlen);
871 if (nsm->ns_handle) {
872 ASSERT(nsm->ns_handle->cl_auth != NULL);
873 auth_destroy(nsm->ns_handle->cl_auth);
874 CLNT_DESTROY(nsm->ns_handle);
875 }
876
877 return (error);
878 }
879
880 static void
881 nlm_nsm_fini(struct nlm_nsm *nsm)
882 {
883 kmem_free(nsm->ns_addr.buf, nsm->ns_addr.maxlen);
884 if (nsm->ns_addr_handle->cl_auth != NULL)
885 auth_destroy(nsm->ns_addr_handle->cl_auth);
886 CLNT_DESTROY(nsm->ns_addr_handle);
887 nsm->ns_addr_handle = NULL;
888 if (nsm->ns_handle->cl_auth != NULL)
889 auth_destroy(nsm->ns_handle->cl_auth);
890 CLNT_DESTROY(nsm->ns_handle);
891 nsm->ns_handle = NULL;
892 sema_destroy(&nsm->ns_sem);
893 }
894
895 static enum clnt_stat
896 nlm_nsm_simu_crash(struct nlm_nsm *nsm)
897 {
898 enum clnt_stat stat;
899
900 sema_p(&nsm->ns_sem);
901 nlm_nsm_clnt_init(nsm->ns_handle, nsm);
902 stat = sm_simu_crash_1(NULL, NULL, nsm->ns_handle);
903 sema_v(&nsm->ns_sem);
904
905 return (stat);
906 }
907
908 static enum clnt_stat
909 nlm_nsm_stat(struct nlm_nsm *nsm, int32_t *out_stat)
910 {
911 struct sm_name args;
912 struct sm_stat_res res;
913 enum clnt_stat stat;
914
915 args.mon_name = uts_nodename();
916 bzero(&res, sizeof (res));
917
918 sema_p(&nsm->ns_sem);
919 nlm_nsm_clnt_init(nsm->ns_handle, nsm);
920 stat = sm_stat_1(&args, &res, nsm->ns_handle);
921 sema_v(&nsm->ns_sem);
922
923 if (stat == RPC_SUCCESS)
924 *out_stat = res.state;
925
926 return (stat);
927 }
928
929 static enum clnt_stat
930 nlm_nsm_mon(struct nlm_nsm *nsm, char *hostname, uint16_t priv)
931 {
932 struct mon args;
933 struct sm_stat_res res;
934 enum clnt_stat stat;
935
936 bzero(&args, sizeof (args));
937 bzero(&res, sizeof (res));
938
939 args.mon_id.mon_name = hostname;
940 args.mon_id.my_id.my_name = uts_nodename();
941 args.mon_id.my_id.my_prog = NLM_PROG;
942 args.mon_id.my_id.my_vers = NLM_SM;
943 args.mon_id.my_id.my_proc = NLM_SM_NOTIFY1;
944 bcopy(&priv, args.priv, sizeof (priv));
945
946 sema_p(&nsm->ns_sem);
947 nlm_nsm_clnt_init(nsm->ns_handle, nsm);
948 stat = sm_mon_1(&args, &res, nsm->ns_handle);
949 sema_v(&nsm->ns_sem);
950
951 return (stat);
952 }
953
954 static enum clnt_stat
955 nlm_nsm_unmon(struct nlm_nsm *nsm, char *hostname)
956 {
957 struct mon_id args;
958 struct sm_stat res;
959 enum clnt_stat stat;
960
961 bzero(&args, sizeof (args));
962 bzero(&res, sizeof (res));
963
964 args.mon_name = hostname;
965 args.my_id.my_name = uts_nodename();
966 args.my_id.my_prog = NLM_PROG;
967 args.my_id.my_vers = NLM_SM;
968 args.my_id.my_proc = NLM_SM_NOTIFY1;
969
970 sema_p(&nsm->ns_sem);
971 nlm_nsm_clnt_init(nsm->ns_handle, nsm);
972 stat = sm_unmon_1(&args, &res, nsm->ns_handle);
973 sema_v(&nsm->ns_sem);
974
975 return (stat);
976 }
977
978 static enum clnt_stat
979 nlm_nsmaddr_reg(struct nlm_nsm *nsm, char *name, int family, netobj *address)
980 {
981 struct reg1args args = { 0 };
982 struct reg1res res = { 0 };
983 enum clnt_stat stat;
984
985 args.family = family;
986 args.name = name;
987 args.address = *address;
988
989 sema_p(&nsm->ns_sem);
990 nlm_nsm_clnt_init(nsm->ns_addr_handle, nsm);
991 stat = nsmaddrproc1_reg_1(&args, &res, nsm->ns_addr_handle);
992 sema_v(&nsm->ns_sem);
993
994 return (stat);
995 }
996
997 /*
998 * Get NLM vhold object corresponding to vnode "vp".
999 * If no such object was found, create a new one.
1000 *
1001 * The purpose of this function is to associate vhold
1002 * object with given vnode, so that:
1003 * 1) vnode is hold (VN_HOLD) while vhold object is alive.
1004 * 2) host has a track of all vnodes it touched by lock
1005 * or share operations. These vnodes are accessible
1006 * via collection of vhold objects.
1007 */
1008 struct nlm_vhold *
1009 nlm_vhold_get(struct nlm_host *hostp, vnode_t *vp)
1010 {
1011 struct nlm_vhold *nvp, *new_nvp = NULL;
1012
|
846
847 /*
848 * Create an RPC handle that'll be used for communication with local
849 * statd using the status monitor protocol.
850 */
851 error = clnt_tli_kcreate(&nsm->ns_knc, &nsm->ns_addr, SM_PROG, SM_VERS,
852 0, NLM_RPC_RETRIES, zone_kcred(), &nsm->ns_handle);
853 if (error != 0)
854 goto error;
855
856 /*
857 * Create an RPC handle that'll be used for communication with the
858 * local statd using the address registration protocol.
859 */
860 error = clnt_tli_kcreate(&nsm->ns_knc, &nsm->ns_addr, NSM_ADDR_PROGRAM,
861 NSM_ADDR_V1, 0, NLM_RPC_RETRIES, zone_kcred(),
862 &nsm->ns_addr_handle);
863 if (error != 0)
864 goto error;
865
866 mutex_init(&nsm->ns_lock, NULL, MUTEX_DEFAULT, NULL);
867 return (0);
868
869 error:
870 kmem_free(nsm->ns_addr.buf, nsm->ns_addr.maxlen);
871 if (nsm->ns_handle) {
872 ASSERT(nsm->ns_handle->cl_auth != NULL);
873 auth_destroy(nsm->ns_handle->cl_auth);
874 CLNT_DESTROY(nsm->ns_handle);
875 }
876
877 return (error);
878 }
879
880 static void
881 nlm_nsm_fini(struct nlm_nsm *nsm)
882 {
883 kmem_free(nsm->ns_addr.buf, nsm->ns_addr.maxlen);
884 if (nsm->ns_addr_handle->cl_auth != NULL)
885 auth_destroy(nsm->ns_addr_handle->cl_auth);
886 CLNT_DESTROY(nsm->ns_addr_handle);
887 nsm->ns_addr_handle = NULL;
888 if (nsm->ns_handle->cl_auth != NULL)
889 auth_destroy(nsm->ns_handle->cl_auth);
890 CLNT_DESTROY(nsm->ns_handle);
891 nsm->ns_handle = NULL;
892 mutex_destroy(&nsm->ns_lock);
893 }
894
895 static enum clnt_stat
896 nlm_nsm_simu_crash(struct nlm_nsm *nsm)
897 {
898 enum clnt_stat stat;
899
900 mutex_enter(&nsm->ns_lock);
901 nlm_nsm_clnt_init(nsm->ns_handle, nsm);
902 stat = sm_simu_crash_1(NULL, NULL, nsm->ns_handle);
903 mutex_exit(&nsm->ns_lock);
904
905 return (stat);
906 }
907
908 static enum clnt_stat
909 nlm_nsm_stat(struct nlm_nsm *nsm, int32_t *out_stat)
910 {
911 struct sm_name args;
912 struct sm_stat_res res;
913 enum clnt_stat stat;
914
915 args.mon_name = uts_nodename();
916 bzero(&res, sizeof (res));
917
918 mutex_enter(&nsm->ns_lock);
919 nlm_nsm_clnt_init(nsm->ns_handle, nsm);
920 stat = sm_stat_1(&args, &res, nsm->ns_handle);
921 mutex_exit(&nsm->ns_lock);
922
923 if (stat == RPC_SUCCESS)
924 *out_stat = res.state;
925
926 return (stat);
927 }
928
929 static enum clnt_stat
930 nlm_nsm_mon(struct nlm_nsm *nsm, char *hostname, uint16_t priv)
931 {
932 struct mon args;
933 struct sm_stat_res res;
934 enum clnt_stat stat;
935
936 bzero(&args, sizeof (args));
937 bzero(&res, sizeof (res));
938
939 args.mon_id.mon_name = hostname;
940 args.mon_id.my_id.my_name = uts_nodename();
941 args.mon_id.my_id.my_prog = NLM_PROG;
942 args.mon_id.my_id.my_vers = NLM_SM;
943 args.mon_id.my_id.my_proc = NLM_SM_NOTIFY1;
944 bcopy(&priv, args.priv, sizeof (priv));
945
946 mutex_enter(&nsm->ns_lock);
947 nlm_nsm_clnt_init(nsm->ns_handle, nsm);
948 stat = sm_mon_1(&args, &res, nsm->ns_handle);
949 mutex_exit(&nsm->ns_lock);
950
951 return (stat);
952 }
953
954 static enum clnt_stat
955 nlm_nsm_unmon(struct nlm_nsm *nsm, char *hostname)
956 {
957 struct mon_id args;
958 struct sm_stat res;
959 enum clnt_stat stat;
960
961 bzero(&args, sizeof (args));
962 bzero(&res, sizeof (res));
963
964 args.mon_name = hostname;
965 args.my_id.my_name = uts_nodename();
966 args.my_id.my_prog = NLM_PROG;
967 args.my_id.my_vers = NLM_SM;
968 args.my_id.my_proc = NLM_SM_NOTIFY1;
969
970 mutex_enter(&nsm->ns_lock);
971 nlm_nsm_clnt_init(nsm->ns_handle, nsm);
972 stat = sm_unmon_1(&args, &res, nsm->ns_handle);
973 mutex_exit(&nsm->ns_lock);
974
975 return (stat);
976 }
977
978 static enum clnt_stat
979 nlm_nsmaddr_reg(struct nlm_nsm *nsm, char *name, int family, netobj *address)
980 {
981 struct reg1args args = { 0 };
982 struct reg1res res = { 0 };
983 enum clnt_stat stat;
984
985 args.family = family;
986 args.name = name;
987 args.address = *address;
988
989 mutex_enter(&nsm->ns_lock);
990 nlm_nsm_clnt_init(nsm->ns_addr_handle, nsm);
991 stat = nsmaddrproc1_reg_1(&args, &res, nsm->ns_addr_handle);
992 mutex_exit(&nsm->ns_lock);
993
994 return (stat);
995 }
996
997 /*
998 * Get NLM vhold object corresponding to vnode "vp".
999 * If no such object was found, create a new one.
1000 *
1001 * The purpose of this function is to associate vhold
1002 * object with given vnode, so that:
1003 * 1) vnode is hold (VN_HOLD) while vhold object is alive.
1004 * 2) host has a track of all vnodes it touched by lock
1005 * or share operations. These vnodes are accessible
1006 * via collection of vhold objects.
1007 */
1008 struct nlm_vhold *
1009 nlm_vhold_get(struct nlm_host *hostp, vnode_t *vp)
1010 {
1011 struct nlm_vhold *nvp, *new_nvp = NULL;
1012
|