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 00048 #ifdef HAVE_CONFIG_H 00049 #include "config.h" 00050 #endif 00051 00052 #include "shell.h" 00053 #include "Getopt.h" 00054 #include <libgen.h> 00055 #include <pthread.h> 00056 #include <stdlib.h> 00057 #include <string.h> 00058 00059 #include <stdio.h> 00060 00061 #ifdef HAVE_LIBREADLINE 00062 #include <readline/readline.h> 00063 #include <readline/history.h> 00064 #endif 00065 00066 #define NBTHRMAX 64 00067 00068 /* ServerEpoch is ServerBootTime unless overriden by -E command line option */ 00069 time_t ServerBootTime; 00070 time_t ServerEpoch; 00071 00072 typedef struct shell_info__ 00073 { 00074 00075 int shell_id; 00076 00077 char prompt[32]; 00078 char script_file[128]; 00079 00080 pthread_t thread; 00081 pthread_attr_t attrs; 00082 00083 int status; 00084 00085 } shell_info_t; 00086 00087 shell_info_t thrlist[NBTHRMAX]; 00088 00089 int verbose = 0; 00090 00091 void *LaunchShell(void *arg) 00092 { 00093 int rc; 00094 00095 shell_info_t *p_info = (shell_info_t *) arg; 00096 00097 rc = shell_Init(verbose, p_info->script_file, p_info->prompt, p_info->shell_id); 00098 00099 if(rc) 00100 { 00101 fprintf(stderr, "GANESHELL: ERROR %d in shell_Init\n", rc); 00102 p_info->status = rc; 00103 pthread_exit(&p_info->status); 00104 } 00105 00106 rc = shell_Launch(); 00107 00108 if(rc) 00109 { 00110 fprintf(stderr, "GANESHELL: ERROR %d in shell_Launch\n", rc); 00111 p_info->status = rc; 00112 pthread_exit(&p_info->status); 00113 } 00114 00115 p_info->status = 0; 00116 00117 /* never reached */ 00118 return &p_info->status; 00119 00120 } 00121 00122 int main(int argc, char **argv) 00123 { 00124 00125 static char *format = "h@vn:E:"; 00126 static char *help = "Usage: %s [-h][-v][-n <nb>][-E <epoch>][Script_File1 [Script_File2]...]\n"; 00127 00128 int option, rc; 00129 00130 int err_flag = 0; 00131 int flag_h = 0; 00132 00133 int nb_instance = 0; 00134 00135 char *prompt = "ganeshell>"; 00136 char *script_file = NULL; 00137 00138 char *progname = basename(argv[0]); 00139 00140 int nb_threads = 0; 00141 00142 /* Set the server's boot time and epoch */ 00143 ServerBootTime = time(NULL); 00144 ServerEpoch = ServerBootTime; 00145 00146 /* disables Getopt error message */ 00147 Opterr = 0; 00148 00149 /* reinits Getopt processing */ 00150 Optind = 1; 00151 00152 while((option = Getopt(argc, argv, format)) != -1) 00153 { 00154 switch (option) 00155 { 00156 case 'h': 00157 if(flag_h) 00158 fprintf(stderr, 00159 "%s: warning: option 'h' has been specified more than once.\n", 00160 progname); 00161 else 00162 flag_h++; 00163 break; 00164 00165 case '@': 00166 /* A litlle backdoor to keep track of binary versions */ 00167 printf("%s compiled on %s at %s\n", progname, __DATE__, __TIME__); 00168 printf("Release = %s\n", VERSION); 00169 printf("Release comment = %s\n", VERSION_COMMENT); 00170 exit(0); 00171 break; 00172 00173 case 'n': 00174 if(nb_instance) 00175 fprintf(stderr, 00176 "%s: warning: option 'n' has been specified more than once.\n", 00177 progname); 00178 else 00179 nb_instance = atoi(Optarg); 00180 00181 break; 00182 00183 case 'v': 00184 if(verbose) 00185 fprintf(stderr, 00186 "%s: warning: option 'v' has been specified more than once.\n", 00187 progname); 00188 else 00189 verbose++; 00190 break; 00191 00192 case 'E': 00193 ServerEpoch = (time_t) atoll(Optarg); 00194 break; 00195 00196 case '?': 00197 fprintf(stderr, "%s: unknown option : %c\n", progname, Optopt); 00198 err_flag++; 00199 break; 00200 } 00201 } 00202 00203 /* help flag */ 00204 if(flag_h || err_flag) 00205 { 00206 fprintf(stderr, help, basename(progname)); 00207 exit(err_flag); 00208 } 00209 #ifdef HAVE_LIBREADLINE 00210 /* Initialize history */ 00211 using_history(); 00212 #endif 00213 00214 /* case when the 'n' option is specified */ 00215 if(nb_instance != 0) 00216 { 00217 int i; 00218 /* case when there two or more threads */ 00219 00220 for(i = 0; i < nb_instance; i++) 00221 { 00222 00223 if(verbose) 00224 fprintf(stderr, "Starting thread %d using file %s...\n", 00225 nb_threads, argv[Optind]); 00226 00227 thrlist[nb_threads].shell_id = nb_threads; 00228 00229 snprintf(thrlist[nb_threads].prompt, 32, "ganeshell-%d>", nb_threads); 00230 strncpy(thrlist[nb_threads].script_file, argv[Optind], 128); 00231 00232 pthread_attr_init(&thrlist[nb_threads].attrs); 00233 pthread_attr_setscope(&thrlist[nb_threads].attrs, PTHREAD_SCOPE_SYSTEM); 00234 00235 nb_threads++; 00236 00237 if(nb_threads >= NBTHRMAX) 00238 { 00239 fprintf(stderr, "GANESHELL: Too much threads (%d > %d)\n", nb_threads, 00240 NBTHRMAX); 00241 exit(1); 00242 } 00243 00244 } 00245 00246 /* inits shell barriers */ 00247 00248 rc = shell_BarrierInit(nb_threads); 00249 00250 if(rc) 00251 { 00252 fprintf(stderr, "GANESHELL: ERROR %d in shell_BarrierInit\n", rc); 00253 exit(1); 00254 } 00255 00256 /* launching threads */ 00257 00258 for(i = 0; i < nb_threads; i++) 00259 { 00260 rc = pthread_create(&thrlist[i].thread, 00261 &thrlist[i].attrs, LaunchShell, &thrlist[i]); 00262 00263 if(rc) 00264 { 00265 fprintf(stderr, "GANESHELL: ERROR %d in pthread_create\n", rc); 00266 exit(1); 00267 } 00268 00269 } 00270 00271 /* waiting for thread termination */ 00272 00273 for(i = 0; i < nb_threads; i++) 00274 { 00275 void *ret; 00276 pthread_join(thrlist[i].thread, &ret); 00277 00278 } 00279 00280 exit(0); 00281 00282 } 00283 /* case when there is only zero or one script file */ 00284 else if(Optind >= (argc - 1)) 00285 { 00286 00287 if(Optind == (argc - 1)) 00288 { 00289 script_file = argv[Optind]; 00290 } 00291 00292 rc = shell_Init(verbose, script_file, prompt, 0); 00293 00294 if(rc) 00295 { 00296 fprintf(stderr, "GANESHELL: ERROR %d in shell_Init\n", rc); 00297 exit(1); 00298 } 00299 00300 rc = shell_Launch(); 00301 00302 if(rc) 00303 { 00304 fprintf(stderr, "GANESHELL: ERROR %d in shell_Launch\n", rc); 00305 exit(1); 00306 } 00307 00308 exit(0); 00309 00310 } 00311 else 00312 { 00313 int i; 00314 /* case when there two or more threads */ 00315 00316 for(i = Optind; i < argc; i++) 00317 { 00318 00319 if(verbose) 00320 fprintf(stderr, "Starting thread %d using file %s...\n", nb_threads, argv[i]); 00321 00322 thrlist[nb_threads].shell_id = nb_threads; 00323 00324 snprintf(thrlist[nb_threads].prompt, 32, "ganeshell-%d>", nb_threads); 00325 strncpy(thrlist[nb_threads].script_file, argv[i], 128); 00326 00327 pthread_attr_init(&thrlist[nb_threads].attrs); 00328 pthread_attr_setscope(&thrlist[nb_threads].attrs, PTHREAD_SCOPE_SYSTEM); 00329 00330 nb_threads++; 00331 00332 if(nb_threads >= NBTHRMAX) 00333 { 00334 fprintf(stderr, "GANESHELL: Too much threads (%d > %d)\n", nb_threads, 00335 NBTHRMAX); 00336 exit(1); 00337 } 00338 00339 } 00340 00341 /* inits shell barriers */ 00342 00343 rc = shell_BarrierInit(nb_threads); 00344 00345 if(rc) 00346 { 00347 fprintf(stderr, "GANESHELL: ERROR %d in shell_BarrierInit\n", rc); 00348 exit(1); 00349 } 00350 00351 /* launching threads */ 00352 00353 for(i = 0; i < nb_threads; i++) 00354 { 00355 rc = pthread_create(&thrlist[i].thread, 00356 &thrlist[i].attrs, LaunchShell, &thrlist[i]); 00357 00358 if(rc) 00359 { 00360 fprintf(stderr, "GANESHELL: ERROR %d in pthread_create\n", rc); 00361 exit(1); 00362 } 00363 00364 } 00365 00366 /* waiting for thread termination */ 00367 00368 for(i = 0; i < nb_threads; i++) 00369 { 00370 void *ret; 00371 pthread_join(thrlist[i].thread, &ret); 00372 00373 } 00374 00375 exit(0); 00376 00377 } 00378 00379 }