nfs-ganesha 1.4
|
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(¶m.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 */