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 * 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 00036 #ifdef HAVE_CONFIG_H 00037 #include "config.h" 00038 #endif 00039 00040 #ifdef _SOLARIS 00041 #include "solaris_port.h" 00042 #endif 00043 00044 #include <stdio.h> 00045 #include <string.h> 00046 #include <pthread.h> 00047 #include <assert.h> 00048 #include <sys/stat.h> 00049 #include <time.h> 00050 #include "nfs_core.h" 00051 #include "nfs_stat.h" 00052 #include "nfs_exports.h" 00053 #include "log.h" 00054 00055 extern hash_table_t *ht_ip_stats[NB_MAX_WORKER_THREAD]; 00056 00057 void set_min_latency(nfs_request_stat_item_t *cur_stat, unsigned int val) 00058 { 00059 if(val > 0) 00060 { 00061 if(val < cur_stat->min_latency) 00062 { 00063 cur_stat->min_latency = val; 00064 } 00065 } 00066 } 00067 00068 void set_max_latency(nfs_request_stat_item_t *cur_stat, unsigned int val) 00069 { 00070 if(val > cur_stat->max_latency) 00071 { 00072 cur_stat->max_latency = val; 00073 } 00074 } 00075 00076 /* 00077 * This function collects statistics from all Ganesha system modules so that they can then 00078 * be pushed into various users (e.g.: a statistics file, a network mgmt serviece, ...) 00079 * That is why collection of statistics is separated into its own function so that any user 00080 * can call for it. 00081 */ 00082 void stats_collect (ganesha_stats_t *ganesha_stats) 00083 { 00084 hash_stat_t *cache_inode_stat = &ganesha_stats->cache_inode_hstat; 00085 nfs_worker_stat_t *global_worker_stat = &ganesha_stats->global_worker_stat; 00086 fsal_statistics_t *global_fsal_stat = &ganesha_stats->global_fsal; 00087 unsigned int i, j; 00088 00089 /* This is done only on worker[0]: the hashtable is shared and worker 0 always exists */ 00090 HashTable_GetStats(fh_to_cache_entry_ht, cache_inode_stat); 00091 00092 /* Merging the NFS protocols stats together */ 00093 global_worker_stat->nb_total_req = 0; 00094 global_worker_stat->nb_udp_req = 0; 00095 global_worker_stat->nb_tcp_req = 0; 00096 global_worker_stat->stat_req.nb_mnt1_req = 0; 00097 global_worker_stat->stat_req.nb_mnt3_req = 0; 00098 global_worker_stat->stat_req.nb_nfs2_req = 0; 00099 global_worker_stat->stat_req.nb_nfs3_req = 0; 00100 global_worker_stat->stat_req.nb_nfs4_req = 0; 00101 global_worker_stat->stat_req.nb_nlm4_req = 0; 00102 global_worker_stat->stat_req.nb_nfs40_op = 0; 00103 global_worker_stat->stat_req.nb_nfs41_op = 0; 00104 global_worker_stat->stat_req.nb_rquota1_req = 0; 00105 global_worker_stat->stat_req.nb_rquota2_req = 0; 00106 00107 /* prepare for computing pending request stats */ 00108 ganesha_stats->min_pending_request = 10000000; 00109 ganesha_stats->max_pending_request = 0; 00110 ganesha_stats->total_pending_request = 0; 00111 ganesha_stats->average_pending_request = 0; 00112 ganesha_stats->len_pending_request = 0; 00113 00114 for (i = 0; i < nfs_param.core_param.nb_worker; i++) { 00115 global_worker_stat->nb_total_req += workers_data[i].stats.nb_total_req; 00116 global_worker_stat->nb_udp_req += workers_data[i].stats.nb_udp_req; 00117 global_worker_stat->nb_tcp_req += workers_data[i].stats.nb_tcp_req; 00118 global_worker_stat->stat_req.nb_mnt1_req += 00119 workers_data[i].stats.stat_req.nb_mnt1_req; 00120 global_worker_stat->stat_req.nb_mnt3_req += 00121 workers_data[i].stats.stat_req.nb_mnt3_req; 00122 global_worker_stat->stat_req.nb_nfs2_req += 00123 workers_data[i].stats.stat_req.nb_nfs2_req; 00124 global_worker_stat->stat_req.nb_nfs3_req += 00125 workers_data[i].stats.stat_req.nb_nfs3_req; 00126 global_worker_stat->stat_req.nb_nfs4_req += 00127 workers_data[i].stats.stat_req.nb_nfs4_req; 00128 global_worker_stat->stat_req.nb_nfs40_op += 00129 workers_data[i].stats.stat_req.nb_nfs40_op; 00130 global_worker_stat->stat_req.nb_nfs41_op += 00131 workers_data[i].stats.stat_req.nb_nfs41_op; 00132 00133 global_worker_stat->stat_req.nb_nlm4_req += 00134 workers_data[i].stats.stat_req.nb_nlm4_req; 00135 00136 global_worker_stat->stat_req.nb_rquota1_req += 00137 workers_data[i].stats.stat_req.nb_nlm4_req; 00138 00139 global_worker_stat->stat_req.nb_rquota2_req += 00140 workers_data[i].stats.stat_req.nb_nlm4_req; 00141 00142 for (j = 0; j < MNT_V1_NB_COMMAND; j++) { 00143 if (i == 0) { 00144 global_worker_stat->stat_req.stat_req_mnt1[j].total = 00145 workers_data[i].stats.stat_req.stat_req_mnt1[j].total; 00146 global_worker_stat->stat_req.stat_req_mnt1[j].success = 00147 workers_data[i].stats.stat_req.stat_req_mnt1[j].success; 00148 global_worker_stat->stat_req.stat_req_mnt1[j].dropped = 00149 workers_data[i].stats.stat_req.stat_req_mnt1[j].dropped; 00150 } else { 00151 global_worker_stat->stat_req.stat_req_mnt1[j].total += 00152 workers_data[i].stats.stat_req.stat_req_mnt1[j].total; 00153 global_worker_stat->stat_req.stat_req_mnt1[j].success += 00154 workers_data[i].stats.stat_req.stat_req_mnt1[j].success; 00155 global_worker_stat->stat_req.stat_req_mnt1[j].dropped += 00156 workers_data[i].stats.stat_req.stat_req_mnt1[j].dropped; 00157 } 00158 } 00159 00160 for (j = 0; j < MNT_V3_NB_COMMAND; j++) { 00161 if (i == 0) { 00162 global_worker_stat->stat_req.stat_req_mnt3[j].total = 00163 workers_data[i].stats.stat_req.stat_req_mnt3[j].total; 00164 global_worker_stat->stat_req.stat_req_mnt3[j].success = 00165 workers_data[i].stats.stat_req.stat_req_mnt3[j].success; 00166 global_worker_stat->stat_req.stat_req_mnt3[j].dropped = 00167 workers_data[i].stats.stat_req.stat_req_mnt3[j].dropped; 00168 } else { 00169 global_worker_stat->stat_req.stat_req_mnt3[j].total += 00170 workers_data[i].stats.stat_req.stat_req_mnt3[j].total; 00171 global_worker_stat->stat_req.stat_req_mnt3[j].success += 00172 workers_data[i].stats.stat_req.stat_req_mnt3[j].success; 00173 global_worker_stat->stat_req.stat_req_mnt3[j].dropped += 00174 workers_data[i].stats.stat_req.stat_req_mnt3[j].dropped; 00175 } 00176 } 00177 00178 for (j = 0; j < NFS_V2_NB_COMMAND; j++) { 00179 if (i == 0) { 00180 global_worker_stat->stat_req.stat_req_nfs2[j].total = 00181 workers_data[i].stats.stat_req.stat_req_nfs2[j].total; 00182 global_worker_stat->stat_req.stat_req_nfs2[j].success = 00183 workers_data[i].stats.stat_req.stat_req_nfs2[j].success; 00184 global_worker_stat->stat_req.stat_req_nfs2[j].dropped = 00185 workers_data[i].stats.stat_req.stat_req_nfs2[j].dropped; 00186 } else { 00187 global_worker_stat->stat_req.stat_req_nfs2[j].total += 00188 workers_data[i].stats.stat_req.stat_req_nfs2[j].total; 00189 global_worker_stat->stat_req.stat_req_nfs2[j].success += 00190 workers_data[i].stats.stat_req.stat_req_nfs2[j].success; 00191 global_worker_stat->stat_req.stat_req_nfs2[j].dropped += 00192 workers_data[i].stats.stat_req.stat_req_nfs2[j].dropped; 00193 } 00194 } 00195 00196 for (j = 0; j < NFS_V3_NB_COMMAND; j++) { 00197 if (i == 0) { 00198 global_worker_stat->stat_req.stat_req_nfs3[j].total = 00199 workers_data[i].stats.stat_req.stat_req_nfs3[j].total; 00200 global_worker_stat->stat_req.stat_req_nfs3[j].success = 00201 workers_data[i].stats.stat_req.stat_req_nfs3[j].success; 00202 global_worker_stat->stat_req.stat_req_nfs3[j].dropped = 00203 workers_data[i].stats.stat_req.stat_req_nfs3[j].dropped; 00204 global_worker_stat->stat_req.stat_req_nfs3[j].tot_latency = 00205 workers_data[i].stats.stat_req.stat_req_nfs3[j].tot_latency; 00206 global_worker_stat->stat_req.stat_req_nfs3[j].min_latency = 00207 workers_data[i].stats.stat_req.stat_req_nfs3[j].min_latency; 00208 global_worker_stat->stat_req.stat_req_nfs3[j].max_latency = 00209 workers_data[i].stats.stat_req.stat_req_nfs3[j].max_latency; 00210 } else { 00211 global_worker_stat->stat_req.stat_req_nfs3[j].total += 00212 workers_data[i].stats.stat_req.stat_req_nfs3[j].total; 00213 global_worker_stat->stat_req.stat_req_nfs3[j].success += 00214 workers_data[i].stats.stat_req.stat_req_nfs3[j].success; 00215 global_worker_stat->stat_req.stat_req_nfs3[j].dropped += 00216 workers_data[i].stats.stat_req.stat_req_nfs3[j].dropped; 00217 global_worker_stat->stat_req.stat_req_nfs3[j].tot_latency += 00218 workers_data[i].stats.stat_req.stat_req_nfs3[j].tot_latency; 00219 set_min_latency(&(global_worker_stat->stat_req.stat_req_nfs3[j]), 00220 workers_data[i].stats.stat_req.stat_req_nfs3[j].min_latency); 00221 set_max_latency(&(global_worker_stat->stat_req.stat_req_nfs3[j]), 00222 workers_data[i].stats.stat_req.stat_req_nfs3[j].max_latency); 00223 } 00224 } 00225 00226 for (j = 0; j < NFS_V4_NB_COMMAND; j++) { 00227 if (i == 0) { 00228 global_worker_stat->stat_req.stat_req_nfs4[j].total = 00229 workers_data[i].stats.stat_req.stat_req_nfs4[j].total; 00230 global_worker_stat->stat_req.stat_req_nfs4[j].success = 00231 workers_data[i].stats.stat_req.stat_req_nfs4[j].success; 00232 global_worker_stat->stat_req.stat_req_nfs4[j].dropped = 00233 workers_data[i].stats.stat_req.stat_req_nfs4[j].dropped; 00234 } else { 00235 global_worker_stat->stat_req.stat_req_nfs4[j].total += 00236 workers_data[i].stats.stat_req.stat_req_nfs4[j].total; 00237 global_worker_stat->stat_req.stat_req_nfs4[j].success += 00238 workers_data[i].stats.stat_req.stat_req_nfs4[j].success; 00239 global_worker_stat->stat_req.stat_req_nfs4[j].dropped += 00240 workers_data[i].stats.stat_req.stat_req_nfs4[j].dropped; 00241 } 00242 } 00243 00244 for (j = 0; j < NFS_V40_NB_OPERATION; j++) { 00245 if (i == 0) { 00246 global_worker_stat->stat_req.stat_op_nfs40[j].total = 00247 workers_data[i].stats.stat_req.stat_op_nfs40[j].total; 00248 global_worker_stat->stat_req.stat_op_nfs40[j].success = 00249 workers_data[i].stats.stat_req.stat_op_nfs40[j].success; 00250 global_worker_stat->stat_req.stat_op_nfs40[j].failed = 00251 workers_data[i].stats.stat_req.stat_op_nfs40[j].failed; 00252 } else { 00253 global_worker_stat->stat_req.stat_op_nfs40[j].total += 00254 workers_data[i].stats.stat_req.stat_op_nfs40[j].total; 00255 global_worker_stat->stat_req.stat_op_nfs40[j].success += 00256 workers_data[i].stats.stat_req.stat_op_nfs40[j].success; 00257 global_worker_stat->stat_req.stat_op_nfs40[j].failed += 00258 workers_data[i].stats.stat_req.stat_op_nfs40[j].failed; 00259 } 00260 } 00261 00262 for (j = 0; j < NFS_V41_NB_OPERATION; j++) { 00263 if (i == 0) { 00264 global_worker_stat->stat_req.stat_op_nfs41[j].total = 00265 workers_data[i].stats.stat_req.stat_op_nfs41[j].total; 00266 global_worker_stat->stat_req.stat_op_nfs41[j].success = 00267 workers_data[i].stats.stat_req.stat_op_nfs41[j].success; 00268 global_worker_stat->stat_req.stat_op_nfs41[j].failed = 00269 workers_data[i].stats.stat_req.stat_op_nfs41[j].failed; 00270 } else { 00271 global_worker_stat->stat_req.stat_op_nfs41[j].total += 00272 workers_data[i].stats.stat_req.stat_op_nfs41[j].total; 00273 global_worker_stat->stat_req.stat_op_nfs41[j].success += 00274 workers_data[i].stats.stat_req.stat_op_nfs41[j].success; 00275 global_worker_stat->stat_req.stat_op_nfs41[j].failed += 00276 workers_data[i].stats.stat_req.stat_op_nfs41[j].failed; 00277 } 00278 } 00279 00280 for (j = 0; j < NLM_V4_NB_OPERATION; j++) { 00281 if (i == 0) { 00282 global_worker_stat->stat_req.stat_req_nlm4[j].total = 00283 workers_data[i].stats.stat_req.stat_req_nlm4[j].total; 00284 global_worker_stat->stat_req.stat_req_nlm4[j].success = 00285 workers_data[i].stats.stat_req.stat_req_nlm4[j].success; 00286 global_worker_stat->stat_req.stat_req_nlm4[j].dropped = 00287 workers_data[i].stats.stat_req.stat_req_nlm4[j].dropped; 00288 } else { 00289 global_worker_stat->stat_req.stat_req_nlm4[j].total += 00290 workers_data[i].stats.stat_req.stat_req_nlm4[j].total; 00291 global_worker_stat->stat_req.stat_req_nlm4[j].success += 00292 workers_data[i].stats.stat_req.stat_req_nlm4[j].success; 00293 global_worker_stat->stat_req.stat_req_nlm4[j].dropped += 00294 workers_data[i].stats.stat_req.stat_req_nlm4[j].dropped; 00295 } 00296 } 00297 00298 for (j = 0; j < RQUOTA_NB_COMMAND; j++) { 00299 if (i == 0) { 00300 global_worker_stat->stat_req.stat_req_rquota1[j].total = 00301 workers_data[i].stats.stat_req.stat_req_rquota1[j].total; 00302 global_worker_stat->stat_req.stat_req_rquota1[j].success = 00303 workers_data[i].stats.stat_req.stat_req_rquota1[j].success; 00304 global_worker_stat->stat_req.stat_req_rquota1[j].dropped = 00305 workers_data[i].stats.stat_req.stat_req_rquota1[j].dropped; 00306 00307 global_worker_stat->stat_req.stat_req_rquota2[j].total = 00308 workers_data[i].stats.stat_req.stat_req_rquota2[j].total; 00309 global_worker_stat->stat_req.stat_req_rquota2[j].success = 00310 workers_data[i].stats.stat_req.stat_req_rquota2[j].success; 00311 global_worker_stat->stat_req.stat_req_rquota2[j].dropped = 00312 workers_data[i].stats.stat_req.stat_req_rquota2[j].dropped; 00313 } else { 00314 global_worker_stat->stat_req.stat_req_rquota1[j].total += 00315 workers_data[i].stats.stat_req.stat_req_rquota1[j].total; 00316 global_worker_stat->stat_req.stat_req_rquota1[j].success += 00317 workers_data[i].stats.stat_req.stat_req_rquota1[j].success; 00318 global_worker_stat->stat_req.stat_req_rquota1[j].dropped += 00319 workers_data[i].stats.stat_req.stat_req_rquota1[j].dropped; 00320 00321 global_worker_stat->stat_req.stat_req_rquota2[j].total += 00322 workers_data[i].stats.stat_req.stat_req_rquota2[j].total; 00323 global_worker_stat->stat_req.stat_req_rquota2[j].success += 00324 workers_data[i].stats.stat_req.stat_req_rquota2[j].success; 00325 global_worker_stat->stat_req.stat_req_rquota2[j].dropped += 00326 workers_data[i].stats.stat_req.stat_req_rquota2[j].dropped; 00327 } 00328 } 00329 00330 ganesha_stats->len_pending_request = workers_data[i].pending_request_len; 00331 if (ganesha_stats->len_pending_request < ganesha_stats->min_pending_request) 00332 ganesha_stats->min_pending_request = ganesha_stats->len_pending_request; 00333 00334 if (ganesha_stats->len_pending_request > ganesha_stats->max_pending_request) 00335 ganesha_stats->max_pending_request = ganesha_stats->len_pending_request; 00336 00337 ganesha_stats->total_pending_request += ganesha_stats->len_pending_request; 00338 } /* for( i = 0 ; i < nfs_param.core_param.nb_worker ; i++ ) */ 00339 00340 /* Compute average pending request */ 00341 ganesha_stats->average_pending_request = ganesha_stats->total_pending_request / nfs_param.core_param.nb_worker; 00342 00343 for (j = 0; j < NFS_V3_NB_COMMAND; j++) { 00344 if (global_worker_stat->stat_req.stat_req_nfs3[j].total > 0) { 00345 ganesha_stats->avg_latency = (global_worker_stat->stat_req.stat_req_nfs3[j].tot_latency / 00346 global_worker_stat->stat_req.stat_req_nfs3[j].total); 00347 } else { 00348 ganesha_stats->avg_latency = 0; 00349 } 00350 } 00351 00352 /* Printing the cache inode hash stat */ 00353 nfs_dupreq_get_stats(&ganesha_stats->drc_udp, &ganesha_stats->drc_tcp); 00354 00355 /* Printing the UIDMAP_TYPE hash table stats */ 00356 idmap_get_stats(UIDMAP_TYPE, &ganesha_stats->uid_map, &ganesha_stats->uid_reverse); 00357 /* Printing the GIDMAP_TYPE hash table stats */ 00358 idmap_get_stats(GIDMAP_TYPE, &ganesha_stats->gid_map, &ganesha_stats->gid_reverse); 00359 /* Stats for the IP/Name hashtable */ 00360 nfs_ip_name_get_stats(&ganesha_stats->ip_name_map); 00361 00362 /* fsal statistics */ 00363 memset(global_fsal_stat, 0, sizeof(fsal_statistics_t)); 00364 ganesha_stats->total_fsal_calls = 0; 00365 00366 for (i = 0; i < nfs_param.core_param.nb_worker; i++) { 00367 for (j = 0; j < FSAL_NB_FUNC; j++) { 00368 ganesha_stats->total_fsal_calls += workers_data[i].stats.fsal_stats.func_stats.nb_call[j]; 00369 00370 global_fsal_stat->func_stats.nb_call[j] += 00371 workers_data[i].stats.fsal_stats.func_stats.nb_call[j]; 00372 global_fsal_stat->func_stats.nb_success[j] += 00373 workers_data[i].stats.fsal_stats.func_stats.nb_success[j]; 00374 global_fsal_stat->func_stats.nb_err_retryable[j] += 00375 workers_data[i].stats.fsal_stats.func_stats.nb_err_retryable[j]; 00376 global_fsal_stat->func_stats.nb_err_unrecover[j] += 00377 workers_data[i].stats.fsal_stats.func_stats.nb_err_unrecover[j]; 00378 } 00379 } 00380 } 00381 00382 void *stats_thread(void *UnusedArg) 00383 { 00384 FILE *stats_file = NULL; 00385 struct stat statref; 00386 struct stat stattest; 00387 time_t current_time; 00388 struct tm *current_time_struct; 00389 struct tm *boot_time_struct; 00390 char strdate[1024]; 00391 char strbootdate[1024]; 00392 unsigned int j = 0; 00393 int reopen_stats = FALSE; 00394 00395 ganesha_stats_t ganesha_stats; 00396 nfs_worker_stat_t *global_worker_stat = &ganesha_stats.global_worker_stat; 00397 hash_stat_t *cache_inode_stat = &ganesha_stats.cache_inode_hstat; 00398 hash_stat_t *uid_map_hstat = &ganesha_stats.uid_map; 00399 hash_stat_t *gid_map_hstat = &ganesha_stats.gid_map; 00400 hash_stat_t *ip_name_hstat = &ganesha_stats.ip_name_map; 00401 hash_stat_t *hstat_uid_reverse = &ganesha_stats.uid_reverse; 00402 hash_stat_t *hstat_gid_reverse = &ganesha_stats.gid_reverse; 00403 hash_stat_t *hstat_drc_udp = &ganesha_stats.drc_udp; 00404 hash_stat_t *hstat_drc_tcp = &ganesha_stats.drc_tcp; 00405 fsal_statistics_t *global_fsal_stat = &ganesha_stats.global_fsal; 00406 00407 00408 SetNameFunction("stat_thr"); 00409 00410 /* Open the stats file, in append mode */ 00411 if((stats_file = fopen(nfs_param.core_param.stats_file_path, "a")) == NULL) 00412 { 00413 LogCrit(COMPONENT_MAIN, 00414 "NFS STATS : Could not open stats file %s, no stats will be made...", 00415 nfs_param.core_param.stats_file_path); 00416 return NULL; 00417 } 00418 00419 if(stat(nfs_param.core_param.stats_file_path, &statref) != 0) 00420 { 00421 LogCrit(COMPONENT_MAIN, 00422 "NFS STATS : Could not get inode for %s, no stats will be made...", 00423 nfs_param.core_param.stats_file_path); 00424 fclose(stats_file); 00425 return NULL; 00426 } 00427 00428 #ifdef _SNMP_ADM_ACTIVE 00429 /* start snmp library */ 00430 if(stats_snmp() == 0) 00431 LogInfo(COMPONENT_MAIN, 00432 "NFS STATS: SNMP stats service was started successfully"); 00433 else 00434 LogCrit(COMPONENT_MAIN, 00435 "NFS STATS: ERROR starting SNMP stats export thread"); 00436 #endif /*_SNMP_ADM_ACTIVE*/ 00437 00438 while(1) 00439 { 00440 /* Initial wait */ 00441 sleep(nfs_param.core_param.stats_update_delay); 00442 00443 /* Debug trace */ 00444 LogInfo(COMPONENT_MAIN, "NFS STATS : now dumping stats"); 00445 00446 /* Stats main loop */ 00447 if(stat(nfs_param.core_param.stats_file_path, &stattest) == 0) 00448 { 00449 if(stattest.st_ino != statref.st_ino) 00450 reopen_stats = TRUE; 00451 } 00452 else 00453 { 00454 if(errno == ENOENT) 00455 reopen_stats = TRUE; 00456 } 00457 00458 /* Check is file has changed (the inode number will be different) */ 00459 if(reopen_stats == TRUE) 00460 { 00461 /* Stats file has changed */ 00462 LogEvent(COMPONENT_MAIN, 00463 "NFS STATS : stats file has changed or was removed, I close and reopen it"); 00464 fflush(stats_file); 00465 fclose(stats_file); 00466 if((stats_file = fopen(nfs_param.core_param.stats_file_path, "a")) == NULL) 00467 { 00468 LogCrit(COMPONENT_MAIN, 00469 "NFS STATS : Could not open stats file %s, no further stats will be made...", 00470 nfs_param.core_param.stats_file_path); 00471 return NULL; 00472 } 00473 statref = stattest; 00474 reopen_stats = FALSE; 00475 } 00476 00477 /* Get the current epoch time */ 00478 current_time = time(NULL); 00479 current_time_struct = localtime(¤t_time); 00480 snprintf(strdate, 1024, "%u, %.2d/%.2d/%.4d %.2d:%.2d:%.2d ", 00481 (unsigned int)current_time, 00482 current_time_struct->tm_mday, 00483 current_time_struct->tm_mon + 1, 00484 1900 + current_time_struct->tm_year, 00485 current_time_struct->tm_hour, 00486 current_time_struct->tm_min, 00487 current_time_struct->tm_sec); 00488 00489 /* Printing the general Stats */ 00490 boot_time_struct = localtime(&ServerBootTime); 00491 snprintf(strbootdate, 1024, "%u, %.2d/%.2d/%.4d %.2d:%.2d:%.2d ", 00492 (unsigned int)ServerBootTime, 00493 boot_time_struct->tm_mday, 00494 boot_time_struct->tm_mon + 1, 00495 1900 + boot_time_struct->tm_year, 00496 boot_time_struct->tm_hour, 00497 boot_time_struct->tm_min, 00498 boot_time_struct->tm_sec); 00499 00500 fprintf(stats_file, "NFS_SERVER_GENERAL,%s;%s\n", strdate, strbootdate); 00501 00502 /* collect statistics */ 00503 stats_collect(&ganesha_stats); 00504 00505 /* Pinting the cache inode hash stat */ 00506 /* This is done only on worker[0]: the hashtable is shared and worker 0 always exists */ 00507 HashTable_GetStats(fh_to_cache_entry_ht, cache_inode_stat); 00508 00509 fprintf(stats_file, 00510 "CACHE_INODE_HASH,%s;%zu,%zu,%zu,%zu\n", 00511 strdate, cache_inode_stat->entries, 00512 cache_inode_stat->min_rbt_num_node, 00513 cache_inode_stat->max_rbt_num_node, 00514 cache_inode_stat->average_rbt_num_node); 00515 00516 fprintf(stats_file, "NFS/MOUNT STATISTICS,%s;%u,%u,%u|%u,%u,%u,%u,%u|%u,%u,%u,%u\n", 00517 strdate, 00518 global_worker_stat->nb_total_req, 00519 global_worker_stat->nb_udp_req, 00520 global_worker_stat->nb_tcp_req, 00521 global_worker_stat->stat_req.nb_mnt1_req, 00522 global_worker_stat->stat_req.nb_mnt3_req, 00523 global_worker_stat->stat_req.nb_nfs2_req, 00524 global_worker_stat->stat_req.nb_nfs3_req, 00525 global_worker_stat->stat_req.nb_nfs4_req, 00526 ganesha_stats.total_pending_request, 00527 ganesha_stats.min_pending_request, 00528 ganesha_stats.max_pending_request, 00529 ganesha_stats.average_pending_request); 00530 00531 fprintf(stats_file, "MNT V1 REQUEST,%s;%u", strdate, 00532 global_worker_stat->stat_req.nb_mnt1_req); 00533 for(j = 0; j < MNT_V1_NB_COMMAND; j++) 00534 fprintf(stats_file, "|%u,%u,%u", 00535 global_worker_stat->stat_req.stat_req_mnt1[j].total, 00536 global_worker_stat->stat_req.stat_req_mnt1[j].success, 00537 global_worker_stat->stat_req.stat_req_mnt1[j].dropped); 00538 fprintf(stats_file, "\n"); 00539 00540 fprintf(stats_file, "MNT V3 REQUEST,%s;%u", strdate, 00541 global_worker_stat->stat_req.nb_mnt3_req); 00542 for(j = 0; j < MNT_V3_NB_COMMAND; j++) 00543 fprintf(stats_file, "|%u,%u,%u", 00544 global_worker_stat->stat_req.stat_req_mnt3[j].total, 00545 global_worker_stat->stat_req.stat_req_mnt3[j].success, 00546 global_worker_stat->stat_req.stat_req_mnt3[j].dropped); 00547 fprintf(stats_file, "\n"); 00548 00549 fprintf(stats_file, "NFS V2 REQUEST,%s;%u", strdate, 00550 global_worker_stat->stat_req.nb_nfs2_req); 00551 for(j = 0; j < NFS_V2_NB_COMMAND; j++) 00552 fprintf(stats_file, "|%u,%u,%u", 00553 global_worker_stat->stat_req.stat_req_nfs2[j].total, 00554 global_worker_stat->stat_req.stat_req_nfs2[j].success, 00555 global_worker_stat->stat_req.stat_req_nfs2[j].dropped); 00556 fprintf(stats_file, "\n"); 00557 00558 fprintf(stats_file, "NFS V3 REQUEST,%s;%u", strdate, 00559 global_worker_stat->stat_req.nb_nfs3_req); 00560 for (j = 0; j < NFS_V3_NB_COMMAND; j++) 00561 { 00562 fprintf(stats_file, "|%u,%u,%u,%u,%u,%u,%u", 00563 global_worker_stat->stat_req.stat_req_nfs3[j].total, 00564 global_worker_stat->stat_req.stat_req_nfs3[j].success, 00565 global_worker_stat->stat_req.stat_req_nfs3[j].dropped, 00566 global_worker_stat->stat_req.stat_req_nfs3[j].tot_latency, 00567 ganesha_stats.avg_latency, 00568 global_worker_stat->stat_req.stat_req_nfs3[j].min_latency, 00569 global_worker_stat->stat_req.stat_req_nfs3[j].max_latency); 00570 } 00571 fprintf(stats_file, "\n"); 00572 00573 fprintf(stats_file, "NFS V4 REQUEST,%s;%u", strdate, 00574 global_worker_stat->stat_req.nb_nfs4_req); 00575 for(j = 0; j < NFS_V4_NB_COMMAND; j++) 00576 fprintf(stats_file, "|%u,%u,%u", 00577 global_worker_stat->stat_req.stat_req_nfs4[j].total, 00578 global_worker_stat->stat_req.stat_req_nfs4[j].success, 00579 global_worker_stat->stat_req.stat_req_nfs4[j].dropped); 00580 fprintf(stats_file, "\n"); 00581 00582 fprintf(stats_file, "NFS V4.0 OPERATIONS,%s;%u", strdate, 00583 global_worker_stat->stat_req.nb_nfs40_op); 00584 for(j = 0; j < NFS_V40_NB_OPERATION; j++) 00585 fprintf(stats_file, "|%u,%u,%u", 00586 global_worker_stat->stat_req.stat_op_nfs40[j].total, 00587 global_worker_stat->stat_req.stat_op_nfs40[j].success, 00588 global_worker_stat->stat_req.stat_op_nfs40[j].failed); 00589 fprintf(stats_file, "\n"); 00590 00591 fprintf(stats_file, "NFS V4.1 OPERATIONS,%s;%u", strdate, 00592 global_worker_stat->stat_req.nb_nfs41_op); 00593 for(j = 0; j < NFS_V41_NB_OPERATION; j++) 00594 fprintf(stats_file, "|%u,%u,%u", 00595 global_worker_stat->stat_req.stat_op_nfs41[j].total, 00596 global_worker_stat->stat_req.stat_op_nfs41[j].success, 00597 global_worker_stat->stat_req.stat_op_nfs41[j].failed); 00598 fprintf(stats_file, "\n"); 00599 00600 fprintf(stats_file, "NLM V4 REQUEST,%s;%u", strdate, 00601 global_worker_stat->stat_req.nb_nlm4_req); 00602 for(j = 0; j < NLM_V4_NB_OPERATION; j++) 00603 fprintf(stats_file, "|%u,%u,%u", 00604 global_worker_stat->stat_req.stat_req_nlm4[j].total, 00605 global_worker_stat->stat_req.stat_req_nlm4[j].success, 00606 global_worker_stat->stat_req.stat_req_nlm4[j].dropped); 00607 fprintf(stats_file, "\n"); 00608 00609 fprintf(stats_file, "RQUOTA V1 REQUEST,%s;%u", strdate, 00610 global_worker_stat->stat_req.nb_rquota1_req); 00611 for(j = 0; j < RQUOTA_NB_COMMAND; j++) 00612 fprintf(stats_file, "|%u,%u,%u", 00613 global_worker_stat->stat_req.stat_req_rquota1[j].total, 00614 global_worker_stat->stat_req.stat_req_rquota1[j].success, 00615 global_worker_stat->stat_req.stat_req_rquota1[j].dropped); 00616 fprintf(stats_file, "\n"); 00617 00618 fprintf(stats_file, "RQUOTA V2 REQUEST,%s;%u", strdate, 00619 global_worker_stat->stat_req.nb_rquota2_req); 00620 for(j = 0; j < RQUOTA_NB_COMMAND; j++) 00621 fprintf(stats_file, "|%u,%u,%u", 00622 global_worker_stat->stat_req.stat_req_rquota2[j].total, 00623 global_worker_stat->stat_req.stat_req_rquota2[j].success, 00624 global_worker_stat->stat_req.stat_req_rquota2[j].dropped); 00625 fprintf(stats_file, "\n"); 00626 00627 fprintf(stats_file, 00628 "DUP_REQ_HASH,%s;%zu,%zu,%zu,%zu\n", 00629 strdate, 00630 hstat_drc_udp->entries + hstat_drc_tcp->entries, 00631 hstat_drc_udp->min_rbt_num_node + 00632 hstat_drc_tcp->min_rbt_num_node, 00633 hstat_drc_udp->max_rbt_num_node + 00634 hstat_drc_tcp->max_rbt_num_node, 00635 hstat_drc_udp->average_rbt_num_node + 00636 hstat_drc_tcp->average_rbt_num_node); 00637 00638 fprintf(stats_file, 00639 "UIDMAP_HASH,%s;%zu,%zu,%zu,%zu\n", strdate, 00640 uid_map_hstat->entries, uid_map_hstat->min_rbt_num_node, 00641 uid_map_hstat->max_rbt_num_node, 00642 uid_map_hstat->average_rbt_num_node); 00643 fprintf(stats_file, 00644 "UNAMEMAP_HASH,%s;%zu,%zu,%zu,%zu", 00645 strdate, hstat_uid_reverse->entries, 00646 hstat_uid_reverse->min_rbt_num_node, 00647 hstat_uid_reverse->max_rbt_num_node, 00648 hstat_uid_reverse->average_rbt_num_node); 00649 00650 fprintf(stats_file, 00651 "GIDMAP_HASH,%s;%zu,%zu,%zu,%zu\n", strdate, 00652 gid_map_hstat->entries, 00653 gid_map_hstat->min_rbt_num_node, 00654 gid_map_hstat->max_rbt_num_node, 00655 gid_map_hstat->average_rbt_num_node); 00656 fprintf(stats_file, 00657 "GNAMEMAP_HASH,%s;%zu,%zu,%zu,%zu\n", 00658 strdate, hstat_gid_reverse->entries, 00659 hstat_gid_reverse->min_rbt_num_node, 00660 hstat_gid_reverse->max_rbt_num_node, 00661 hstat_gid_reverse->average_rbt_num_node); 00662 00663 fprintf(stats_file, 00664 "IP_NAME_HASH,%s;%zu,%zu,%zu,%zu\n", 00665 strdate, ip_name_hstat->entries, 00666 ip_name_hstat->min_rbt_num_node, 00667 ip_name_hstat->max_rbt_num_node, 00668 ip_name_hstat->average_rbt_num_node); 00669 00670 fprintf(stats_file, "FSAL_CALLS,%s;%llu", strdate, 00671 ganesha_stats.total_fsal_calls); 00672 for(j = 0; j < FSAL_NB_FUNC; j++) 00673 fprintf(stats_file, "|%u,%u,%u,%u", 00674 global_fsal_stat->func_stats.nb_call[j], 00675 global_fsal_stat->func_stats.nb_success[j], 00676 global_fsal_stat->func_stats.nb_err_retryable[j], 00677 global_fsal_stat->func_stats.nb_err_unrecover[j]); 00678 fprintf(stats_file, "\n"); 00679 00680 /* Flush the data written */ 00681 fprintf(stats_file, "END, ----- NO MORE STATS FOR THIS PASS ----\n"); 00682 fflush(stats_file); 00683 00684 /* Now managed IP stats dump */ 00685 nfs_ip_stats_dump(ht_ip_stats, 00686 nfs_param.core_param.nb_worker, 00687 nfs_param.core_param.stats_per_client_directory); 00688 00689 } /* while ( 1 ) */ 00690 00691 return NULL; 00692 } /* stats_thread */