nfs-ganesha 1.4

nfs41_session_id.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  *
00004  * Copyright CEA/DAM/DIF  (2008)
00005  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00006  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
00007  *
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 3 of the License, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  * ---------------------------------------
00024  */
00025 
00029 #ifdef HAVE_CONFIG_H
00030 #include "config.h"
00031 #endif
00032 
00033 #ifdef _SOLARIS
00034 #include "solaris_port.h"
00035 #endif
00036 
00037 #include "sal_functions.h"
00038 
00039 pool_t *nfs41_session_pool = NULL;
00040 
00041 size_t strnlen(const char *s, size_t maxlen);
00042 
00043 hash_table_t *ht_session_id;
00044 uint64_t global_sequence = 0;
00045 pthread_mutex_t mutex_sequence = PTHREAD_MUTEX_INITIALIZER;
00046 
00047 int display_session_id(char *session_id, char * str)
00048 {
00049   return DisplayOpaqueValue(session_id,
00050                             NFS4_SESSIONID_SIZE,
00051                             str);
00052 }
00053 
00054 int display_session_id_key(hash_buffer_t * pbuff, char *str)
00055 {
00056   char * strtmp = str;
00057 
00058   strtmp += sprintf(strtmp, "sessionid=");
00059 
00060   strtmp += display_session_id(pbuff->pdata, strtmp);
00061 
00062   return strtmp - str;
00063 }
00064 
00065 int display_session(nfs41_session_t * psession, char * str)
00066 {
00067   char            * strtmp = str;
00068 
00069   strtmp += sprintf(strtmp, "sessionid=");
00070 
00071   strtmp += display_session_id(psession->session_id, strtmp);
00072 
00073   return strtmp - str;
00074 }
00075 
00076 int display_session_id_val(hash_buffer_t * pbuff, char *str)
00077 {
00078   return display_session((nfs41_session_t *)pbuff->pdata, str);
00079 }
00080 
00081 int compare_session_id(hash_buffer_t * buff1, hash_buffer_t * buff2)
00082 {
00083   return memcmp(buff1->pdata, buff2->pdata, NFS4_SESSIONID_SIZE);
00084 }
00085 
00086 uint32_t session_id_value_hash_func(hash_parameter_t * p_hparam,
00087                                     hash_buffer_t    * buffclef)
00088 {
00089   /* Only need to hash the global counter portion since it is unique */
00090   uint64_t sum;
00091 
00092   memcpy(&sum, ((char *)buffclef->pdata) + sizeof(clientid4), sizeof(sum));
00093 
00094   if(isFullDebug(COMPONENT_SESSIONS) && isDebug(COMPONENT_HASHTABLE))
00095     {
00096       char str[HASHTABLE_DISPLAY_STRLEN];
00097 
00098       display_session_id_key(buffclef, str);
00099       LogFullDebug(COMPONENT_SESSIONS,
00100                    "value hash: %s=%"PRIu32,
00101                    str,
00102                    (uint32_t)(sum % p_hparam->index_size));
00103     }
00104 
00105   return (uint32_t)(sum % p_hparam->index_size);
00106 }                               /*  client_id_reverse_value_hash_func */
00107 
00108 uint64_t session_id_rbt_hash_func(hash_parameter_t * p_hparam,
00109                                   hash_buffer_t    * buffclef)
00110 {
00111   /* Only need to hash the global counter portion since it is unique */
00112   uint64_t i1 = 0;
00113 
00114   memcpy(&i1, ((char *)buffclef->pdata) + sizeof(clientid4), sizeof(i1));
00115 
00116   if(isFullDebug(COMPONENT_SESSIONS) && isDebug(COMPONENT_HASHTABLE))
00117     {
00118       char str[HASHTABLE_DISPLAY_STRLEN];
00119 
00120       display_session_id_key(buffclef, str);
00121       LogFullDebug(COMPONENT_SESSIONS,
00122                    "rbt hash: %s=%"PRIu64,
00123                    str,
00124                    i1);
00125     }
00126 
00127   return i1;
00128 }                               /* session_id_rbt_hash_func */
00129 
00141 int nfs41_Init_session_id(nfs_session_id_parameter_t param)
00142 {
00143   if((ht_session_id = HashTable_Init(&param.hash_param)) == NULL)
00144     {
00145       LogCrit(COMPONENT_SESSIONS,
00146               "NFS SESSION_ID: Cannot init Session Id cache");
00147       return -1;
00148     }
00149 
00150   return 0;
00151 }                               /* nfs_Init_sesion_id */
00152 
00166 void nfs41_Build_sessionid(clientid4 * pclientid, char * sessionid)
00167 {
00168   uint64_t seq;
00169 
00170   P(mutex_sequence);
00171   seq = ++global_sequence;
00172   V(mutex_sequence);
00173 
00174   memset(sessionid, 0, NFS4_SESSIONID_SIZE);
00175   memcpy(sessionid, pclientid, sizeof(clientid4));
00176   memcpy(sessionid + sizeof(clientid4), &seq, sizeof(seq));
00177 }                               /* nfs41_Build_sessionid */
00178 
00190 int nfs41_Session_Set(char sessionid[NFS4_SESSIONID_SIZE],
00191                       nfs41_session_t * psession_data)
00192 {
00193   hash_buffer_t buffkey;
00194   hash_buffer_t buffval;
00195   char          str[HASHTABLE_DISPLAY_STRLEN];
00196 
00197   if(isFullDebug(COMPONENT_SESSIONS))
00198     {
00199       display_session_id(sessionid, str);
00200       LogFullDebug(COMPONENT_SESSIONS,
00201                    "Set SSession %s", str);
00202     }
00203 
00204   if((buffkey.pdata = gsh_malloc(NFS4_SESSIONID_SIZE)) == NULL)
00205     return 0;
00206   memcpy(buffkey.pdata, sessionid, NFS4_SESSIONID_SIZE);
00207   buffkey.len = NFS4_SESSIONID_SIZE;
00208 
00209   buffval.pdata = (caddr_t) psession_data;
00210   buffval.len = sizeof(nfs41_session_t);
00211 
00212   if(HashTable_Test_And_Set
00213      (ht_session_id, &buffkey, &buffval,
00214       HASHTABLE_SET_HOW_SET_NO_OVERWRITE) != HASHTABLE_SUCCESS)
00215     return 0;
00216 
00217   return 1;
00218 }                               /* nfs41_Session_Set */
00219 
00232 int nfs41_Session_Get_Pointer(char sessionid[NFS4_SESSIONID_SIZE],
00233                               nfs41_session_t * *psession_data)
00234 {
00235   hash_buffer_t buffkey;
00236   hash_buffer_t buffval;
00237   char          str[HASHTABLE_DISPLAY_STRLEN];
00238 
00239   if(isFullDebug(COMPONENT_SESSIONS))
00240     {
00241       display_session_id(sessionid, str);
00242       LogFullDebug(COMPONENT_SESSIONS,
00243                    "Get Session %s", str);
00244     }
00245 
00246   buffkey.pdata = (caddr_t) sessionid;
00247   buffkey.len = NFS4_SESSIONID_SIZE;
00248 
00249   if(HashTable_Get(ht_session_id, &buffkey, &buffval) != HASHTABLE_SUCCESS)
00250     {
00251       LogFullDebug(COMPONENT_SESSIONS,
00252                    "Session %s Not Found", str);
00253       return 0;
00254     }
00255 
00256   *psession_data = (nfs41_session_t *) buffval.pdata;
00257 
00258   LogFullDebug(COMPONENT_SESSIONS,
00259                "Session %s Found", str);
00260 
00261   return 1;
00262 }                               /* nfs41_Session_Get_Pointer */
00263 
00275 int nfs41_Session_Del(char sessionid[NFS4_SESSIONID_SIZE])
00276 {
00277   hash_buffer_t buffkey, old_key, old_value;
00278   char          str[HASHTABLE_DISPLAY_STRLEN];
00279 
00280   if(isFullDebug(COMPONENT_SESSIONS))
00281     {
00282       display_session_id(sessionid, str);
00283       LogFullDebug(COMPONENT_SESSIONS,
00284                    "Delete Session %s", str);
00285     }
00286 
00287   buffkey.pdata = (caddr_t) sessionid;
00288   buffkey.len = NFS4_SESSIONID_SIZE;
00289 
00290   if(HashTable_Del(ht_session_id, &buffkey, &old_key, &old_value) == HASHTABLE_SUCCESS)
00291     {
00292       nfs41_session_t * psession = (nfs41_session_t *) old_value.pdata;
00293 
00294       /* free the key that was stored in hash table */
00295       gsh_free(old_key.pdata);
00296 
00297       /* Decrement our reference to the clientid record */
00298       dec_client_id_ref(psession->pclientid_record);
00299 
00300       /* Free the memory for the session */
00301       pool_free(nfs41_session_pool, psession);
00302 
00303       return 1;
00304     }
00305   else
00306     return 0;
00307 }                               /* nfs41_Session_Del */
00308 
00318 void nfs41_Session_PrintAll(void)
00319 {
00320   HashTable_Log(COMPONENT_SESSIONS, ht_session_id);
00321 }                               /* nfs41_Session_PrintAll */