nfs-ganesha 1.4

nsm.c

Go to the documentation of this file.
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 }