nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 3 of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00017 * 00018 * --------------------------------------- 00019 */ 00020 00025 #ifdef HAVE_CONFIG_H 00026 #include "config.h" 00027 #endif 00028 00029 #ifdef _SOLARIS 00030 #include "solaris_port.h" 00031 #endif 00032 00033 #include <pthread.h> 00034 #include <unistd.h> 00035 #include "log.h" 00036 #include "nfs4.h" 00037 #include "sal_functions.h" 00038 #include "nfs_proto_functions.h" 00039 #include "nfs_core.h" 00040 #include "log.h" 00041 00042 #define REAPER_DELAY 10 00043 00044 unsigned int reaper_delay = REAPER_DELAY; 00045 00046 static void reap_hash_table(hash_table_t * ht_reap) 00047 { 00048 struct rbt_head * head_rbt; 00049 hash_data_t * pdata = NULL; 00050 uint32_t i; 00051 int v4, rc; 00052 struct rbt_node * pn; 00053 nfs_client_id_t * pclientid; 00054 nfs_client_record_t * precord; 00055 00056 /* For each bucket of the requested hashtable */ 00057 for(i = 0; i < ht_reap->parameter.index_size; i++) 00058 { 00059 head_rbt = &ht_reap->partitions[i].rbt; 00060 00061 restart: 00062 /* acquire mutex */ 00063 pthread_rwlock_wrlock(&ht_reap->partitions[i].lock); 00064 00065 /* go through all entries in the red-black-tree*/ 00066 RBT_LOOP(head_rbt, pn) 00067 { 00068 pdata = RBT_OPAQ(pn); 00069 00070 pclientid = (nfs_client_id_t *)pdata->buffval.pdata; 00071 /* 00072 * little hack: only want to reap v4 clients 00073 * 4.1 initializess this field to '1' 00074 */ 00075 v4 = (pclientid->cid_create_session_sequence == 0); 00076 00077 P(pclientid->cid_mutex); 00078 00079 if(!valid_lease(pclientid) && v4) 00080 { 00081 inc_client_id_ref(pclientid); 00082 00083 /* Take a reference to the client record */ 00084 precord = pclientid->cid_client_record; 00085 inc_client_record_ref(precord); 00086 00087 V(pclientid->cid_mutex); 00088 00089 pthread_rwlock_unlock(&ht_reap->partitions[i].lock); 00090 00091 if(isDebug(COMPONENT_CLIENTID)) 00092 { 00093 char str[HASHTABLE_DISPLAY_STRLEN]; 00094 00095 display_client_id_rec(pclientid, str); 00096 00097 LogFullDebug(COMPONENT_CLIENTID, 00098 "Expire index %d %s", 00099 i, str); 00100 } 00101 00102 /* Take cr_mutex and expire clientid */ 00103 P(precord->cr_mutex); 00104 00105 rc = nfs_client_id_expire(pclientid); 00106 00107 V(precord->cr_mutex); 00108 00109 dec_client_id_ref(pclientid); 00110 dec_client_record_ref(precord); 00111 if(rc) 00112 goto restart; 00113 } 00114 else 00115 { 00116 V(pclientid->cid_mutex); 00117 } 00118 00119 RBT_INCREMENT(pn); 00120 } 00121 00122 pthread_rwlock_unlock(&ht_reap->partitions[i].lock); 00123 } 00124 } 00125 00126 void *reaper_thread(void *UnusedArg) 00127 { 00128 int old_state_cleaned = 0; 00129 00130 SetNameFunction("reaper_thr"); 00131 00132 if(nfs_param.nfsv4_param.lease_lifetime < (2 * REAPER_DELAY)) 00133 reaper_delay = nfs_param.nfsv4_param.lease_lifetime / 2; 00134 00135 while(1) 00136 { 00137 /* Initial wait */ 00139 /* sleep(nfs_param.core_param.reaper_delay); */ 00140 sleep(reaper_delay); 00141 00142 if (old_state_cleaned == 0) 00143 { 00144 /* if not in grace period, clean up the old state */ 00145 if(!nfs_in_grace()) 00146 { 00147 nfs4_clean_old_recov_dir(); 00148 old_state_cleaned = 1; 00149 } 00150 } 00151 00152 LogFullDebug(COMPONENT_CLIENTID, 00153 "Now checking NFS4 clients for expiration%s", 00154 nfs_in_grace() ? " IN GRACE" : ""); 00155 00156 reap_hash_table(ht_confirmed_client_id); 00157 reap_hash_table(ht_unconfirmed_client_id); 00158 } /* while ( 1 ) */ 00159 00160 return NULL; 00161 }