nfs-ganesha 1.4
|
00001 /* 00002 * Copyright IBM Corporation, 2010 00003 * Contributor: Aneesh Kumar K.v <aneesh.kumar@linux.vnet.ibm.com> 00004 * : M. Mohan Kumar <mohan@in.ibm.com> 00005 * 00006 * -------------------------- 00007 * 00008 * This program is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 3 of the License, or (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 * 00022 * 00023 */ 00024 00025 #include "config.h" 00026 #include <sys/utsname.h> 00027 #include "ganesha_rpc.h" 00028 #include "nsm.h" 00029 #include "nlm4.h" 00030 #include "log.h" 00031 #include "nfs_core.h" 00032 00033 pthread_mutex_t nsm_mutex = PTHREAD_MUTEX_INITIALIZER; 00034 CLIENT *nsm_clnt; 00035 unsigned long nsm_count; 00036 char * nodename; 00037 00038 bool_t nsm_connect() 00039 { 00040 struct utsname utsname; 00041 00042 if(nsm_clnt != NULL) 00043 return TRUE; 00044 00045 if(uname(&utsname) == -1) 00046 { 00047 LogDebug(COMPONENT_NLM, 00048 "uname failed with errno %d (%s)", 00049 errno, strerror(errno)); 00050 return FALSE; 00051 } 00052 00053 nodename = gsh_malloc(strlen(utsname.nodename)+1); 00054 if(nodename == NULL) 00055 { 00056 LogDebug(COMPONENT_NLM, 00057 "failed to allocate memory for nodename"); 00058 return FALSE; 00059 } 00060 00061 strcpy(nodename, utsname.nodename); 00062 00063 if(nsm_clnt == NULL) 00064 nsm_clnt = Clnt_create("localhost", SM_PROG, SM_VERS, "tcp"); 00065 00066 return nsm_clnt != NULL; 00067 } 00068 00069 void nsm_disconnect() 00070 { 00071 if(nsm_count == 0) 00072 { 00073 Clnt_destroy(nsm_clnt); 00074 nsm_clnt = NULL; 00075 if(nodename != NULL) 00076 gsh_free(nodename); 00077 } 00078 } 00079 00080 bool_t nsm_monitor(state_nsm_client_t *host) 00081 { 00082 enum clnt_stat ret; 00083 struct mon nsm_mon; 00084 struct sm_stat_res res; 00085 struct timeval tout = { 5, 0 }; 00086 00087 if(host == NULL) 00088 return TRUE; 00089 00090 if(host->ssc_monitored) 00091 return TRUE; 00092 00093 nsm_mon.mon_id.mon_name = host->ssc_nlm_caller_name; 00094 nsm_mon.mon_id.my_id.my_prog = NLMPROG; 00095 nsm_mon.mon_id.my_id.my_vers = NLM4_VERS; 00096 nsm_mon.mon_id.my_id.my_proc = NLMPROC4_SM_NOTIFY; 00097 /* nothing to put in the private data */ 00098 LogDebug(COMPONENT_NLM, 00099 "Monitor %s", 00100 host->ssc_nlm_caller_name); 00101 00102 P(nsm_mutex); 00103 00104 /* create a connection to nsm on the localhost */ 00105 if(!nsm_connect()) 00106 { 00107 LogDebug(COMPONENT_NLM, 00108 "Can not monitor %s clnt_create returned NULL", 00109 nsm_mon.mon_id.mon_name); 00110 V(nsm_mutex); 00111 return FALSE; 00112 } 00113 00114 /* Set this after we call nsm_connect() */ 00115 nsm_mon.mon_id.my_id.my_name = nodename; 00116 00117 ret = clnt_call(nsm_clnt, 00118 SM_MON, 00119 (xdrproc_t) xdr_mon, 00120 (caddr_t) & nsm_mon, 00121 (xdrproc_t) xdr_sm_stat_res, 00122 (caddr_t) & res, 00123 tout); 00124 00125 if(ret != RPC_SUCCESS) 00126 { 00127 LogDebug(COMPONENT_NLM, 00128 "Can not monitor %s SM_MON ret %d %s", 00129 nsm_mon.mon_id.mon_name, ret, clnt_sperror(nsm_clnt, "")); 00130 nsm_disconnect(); 00131 V(nsm_mutex); 00132 return FALSE; 00133 } 00134 00135 if(res.res_stat != STAT_SUCC) 00136 { 00137 LogDebug(COMPONENT_NLM, 00138 "Can not monitor %s SM_MON status %d", 00139 nsm_mon.mon_id.mon_name, res.res_stat); 00140 nsm_disconnect(); 00141 V(nsm_mutex); 00142 return FALSE; 00143 } 00144 00145 nsm_count++; 00146 host->ssc_monitored = TRUE; 00147 LogDebug(COMPONENT_NLM, 00148 "Monitored %s for nodename %s", nsm_mon.mon_id.mon_name, nodename); 00149 00150 V(nsm_mutex); 00151 return TRUE; 00152 } 00153 00154 bool_t nsm_unmonitor(state_nsm_client_t *host) 00155 { 00156 enum clnt_stat ret; 00157 struct sm_stat res; 00158 struct mon_id nsm_mon_id; 00159 struct timeval tout = { 5, 0 }; 00160 00161 if(host == NULL) 00162 return TRUE; 00163 00164 if(!host->ssc_monitored) 00165 return TRUE; 00166 00167 nsm_mon_id.mon_name = host->ssc_nlm_caller_name; 00168 nsm_mon_id.my_id.my_prog = NLMPROG; 00169 nsm_mon_id.my_id.my_vers = NLM4_VERS; 00170 nsm_mon_id.my_id.my_proc = NLMPROC4_SM_NOTIFY; 00171 00172 P(nsm_mutex); 00173 00174 /* create a connection to nsm on the localhost */ 00175 if(!nsm_connect()) 00176 { 00177 LogDebug(COMPONENT_NLM, 00178 "Can not unmonitor %s clnt_create returned NULL", 00179 nsm_mon_id.mon_name); 00180 V(nsm_mutex); 00181 return FALSE; 00182 } 00183 00184 /* Set this after we call nsm_connect() */ 00185 nsm_mon_id.my_id.my_name = nodename; 00186 00187 ret = clnt_call(nsm_clnt, 00188 SM_UNMON, 00189 (xdrproc_t) xdr_mon_id, 00190 (caddr_t) & nsm_mon_id, 00191 (xdrproc_t) xdr_sm_stat, 00192 (caddr_t) & res, 00193 tout); 00194 00195 if(ret != RPC_SUCCESS) 00196 { 00197 LogDebug(COMPONENT_NLM, 00198 "Can not unmonitor %s SM_MON ret %d %s", 00199 nsm_mon_id.mon_name, ret, clnt_sperror(nsm_clnt, "")); 00200 nsm_disconnect(); 00201 V(nsm_mutex); 00202 return FALSE; 00203 } 00204 00205 host->ssc_monitored = FALSE; 00206 nsm_count--; 00207 nsm_disconnect(); 00208 LogDebug(COMPONENT_NLM, 00209 "Unonitored %s for nodename %s", nsm_mon_id.mon_name, nodename); 00210 00211 V(nsm_mutex); 00212 return TRUE; 00213 } 00214 00215 void nsm_unmonitor_all(void) 00216 { 00217 enum clnt_stat ret; 00218 struct sm_stat res; 00219 struct my_id nsm_id; 00220 struct timeval tout = { 5, 0 }; 00221 00222 nsm_id.my_prog = NLMPROG; 00223 nsm_id.my_vers = NLM4_VERS; 00224 nsm_id.my_proc = NLMPROC4_SM_NOTIFY; 00225 00226 P(nsm_mutex); 00227 00228 /* create a connection to nsm on the localhost */ 00229 if(!nsm_connect()) 00230 { 00231 LogDebug(COMPONENT_NLM, 00232 "Can not unmonitor all clnt_create returned NULL"); 00233 V(nsm_mutex); 00234 return; 00235 } 00236 00237 /* Set this after we call nsm_connect() */ 00238 nsm_id.my_name = nodename; 00239 00240 ret = clnt_call(nsm_clnt, 00241 SM_UNMON_ALL, 00242 (xdrproc_t) xdr_my_id, 00243 (caddr_t) & nsm_id, 00244 (xdrproc_t) xdr_sm_stat, 00245 (caddr_t) & res, 00246 tout); 00247 00248 if(ret != RPC_SUCCESS) 00249 { 00250 LogDebug(COMPONENT_NLM, 00251 "Can not unmonitor all ret %d %s", 00252 ret, clnt_sperror(nsm_clnt, "")); 00253 } 00254 00255 nsm_disconnect(); 00256 V(nsm_mutex); 00257 }