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 00034 #ifdef HAVE_CONFIG_H 00035 #include "config.h" 00036 #endif 00037 00038 #include "nfs_init.h" 00039 #include "fsal.h" 00040 #include <stdio.h> 00041 #include <string.h> 00042 #include <pthread.h> 00043 #include <signal.h> /* for sigaction */ 00044 #include <errno.h> 00045 #include <ctype.h> 00046 00047 #define CMD_BUFFER_SIZE 1024 00048 #define DEFAULT_CONFIG_FILE "/etc/ganesha/"FS_NAME".ganesha.nfsd.conf" 00049 00050 short HashFileID4(u_int64_t fileid4); 00051 time_t ServerBootTime; 00052 00053 char ganesha_exec_path[MAXPATHLEN]; /* Just because the symbol is required to compile */ 00054 00055 /* determine buffer type and display it */ 00056 void print_buffer(caddr_t buffer, size_t sz_returned) 00057 { 00058 unsigned int i; 00059 int ascii, numeric, hexa; 00060 00061 /* print the value */ 00062 if(sz_returned == 0) 00063 { 00064 printf("(empty)\n"); 00065 return; 00066 } 00067 00068 /* ascii, numeric or hexa ? */ 00069 ascii = numeric = hexa = FALSE; 00070 00071 /* is it ascii ? */ 00072 if(strlen(buffer) == sz_returned - 1 || strlen(buffer) == sz_returned) 00073 { 00074 char *str = buffer; 00075 int tmp_is_ascii = TRUE; 00076 00077 for(i = 0; i < strlen(str); i++) 00078 { 00079 if(!isprint(str[i]) && !isspace(str[i])) 00080 { 00081 tmp_is_ascii = FALSE; 00082 break; 00083 } 00084 } 00085 if(tmp_is_ascii) 00086 ascii = TRUE; 00087 } 00088 00089 /* is it numeric ? */ 00090 if(!ascii) 00091 { 00092 if(sz_returned == 1 || sz_returned == 2 || sz_returned == 4 || sz_returned == 8) 00093 numeric = TRUE; 00094 else 00095 hexa = TRUE; 00096 } 00097 00098 if(ascii) 00099 { 00100 printf("%s\n", buffer); 00101 } 00102 else if(numeric) 00103 { 00104 if(sz_returned == 1) 00105 printf("%hhu\n", buffer[0]); 00106 else if(sz_returned == 2) 00107 printf("%hu\n", *((unsigned short *)buffer)); 00108 else if(sz_returned == 4) 00109 printf("%u\n", *((unsigned int *)buffer)); 00110 else if(sz_returned == 8) 00111 printf("%llu\n", *((unsigned long long *)buffer)); 00112 else 00113 { 00114 for(i = 0; i < sz_returned; i += 8) 00115 { 00116 unsigned long long *p64 = (unsigned long long *)(buffer + i); 00117 if(i == 0) 00118 printf("%llu", *p64); 00119 else 00120 printf(".%llu", *p64); 00121 } 00122 printf("\n"); 00123 } 00124 } 00125 else if(hexa) /* hexa */ 00126 { 00127 printf("0x"); 00128 for(i = 0; i < sz_returned; i++) 00129 { 00130 unsigned char val = buffer[i]; 00131 printf("%hhX", val); 00132 } 00133 printf("\n"); 00134 00135 } 00136 00137 return; 00138 } /* print_buffer */ 00139 00140 int main(int argc, char *argv[]) 00141 { 00142 int c; 00143 int exportid = 0; 00144 char buffer[CMD_BUFFER_SIZE]; 00145 char str[2 * CMD_BUFFER_SIZE]; 00146 fhandle2 filehandle_v2; 00147 struct nfs_fh3 filehandle_v3; 00148 nfs_fh4 filehandle_v4; 00149 int flag_i = FALSE; 00150 char exec_name[MAXPATHLEN]; 00151 char *tempo_exec_name = NULL; 00152 cache_inode_fsal_data_t fsal_data; 00153 fsal_op_context_t fsal_op_context; 00154 fsal_export_context_t fsal_export_context; 00155 exportlist_t *pexportlist = NULL; 00156 exportlist_t *pexport = NULL; 00157 nfs_start_info_t nfs_start_info; 00158 fsal_status_t fsal_status; 00159 unsigned int nfs_version = 3; 00160 path_str_t fsal_path_lib[NB_AVAILABLE_FSAL]; 00161 char entry_path[MAXPATHLEN]; 00162 00163 fsal_path_t export_path = FSAL_PATH_INITIALIZER; 00164 unsigned int cookie; 00165 fsal_xattrent_t xattr_array[256]; 00166 unsigned int nb_returned; 00167 int eol; 00168 char attr_buffer[4096]; 00169 size_t sz_returned; 00170 fsal_u64_t objid; 00171 struct fsal_handle_desc fh_desc; 00172 char options[] = "h@f:v:i:"; 00173 char usage[] = "%s [-h][-f <cfg_path>] {-v 2|3|4 <NFS_FileHandle> | -i <inum>}\n" 00174 " -h : prints this help\n" 00175 " -f <config_file> : sets the ganesha configuration file to be used\n" 00176 " -v <nfs_version> : sets the NFS version the file handle passed as argument\n" 00177 " -i <inum> : get datacache path for the given inode number (decimal)\n"; 00178 00179 /* Set the server's boot time and epoch */ 00180 ServerBootTime = time(NULL); 00181 ServerEpoch = ServerBootTime; 00182 00183 SetDefaultLogging("STDERR"); 00184 00185 /* What is the executable file's name */ 00186 if((tempo_exec_name = strrchr(argv[0], '/')) != NULL) 00187 strcpy((char *)exec_name, tempo_exec_name + 1); 00188 00189 strncpy(config_path, DEFAULT_CONFIG_FILE, MAXPATHLEN); 00190 00191 /* now parsing options with getopt */ 00192 while((c = getopt(argc, argv, options)) != EOF) 00193 { 00194 switch (c) 00195 { 00196 case '@': 00197 printf("%s compiled on %s at %s\n", exec_name, __DATE__, __TIME__); 00198 exit(0); 00199 break; 00200 00201 case 'h': 00202 printf(usage, exec_name); 00203 exit(0); 00204 break; 00205 00206 case 'f': 00207 strncpy(config_path, optarg, MAXPATHLEN); 00208 break; 00209 00210 case 'i': 00211 if(sscanf(optarg, "%llu", &objid) != 1) 00212 { 00213 fprintf(stderr, "Invalid object_id %s (base-10 integer expected)\n", 00214 optarg); 00215 exit(1); 00216 } 00217 flag_i = TRUE; 00218 break; 00219 00220 case 'v': 00221 nfs_version = atoi(optarg); 00222 if((nfs_version < 2) || (nfs_version > 4)) 00223 { 00224 fprintf(stderr, "Invalid nfs version %u\n", nfs_version); 00225 exit(1); 00226 } 00227 break; 00228 case '?': 00229 printf("Unknown option: %c\n", optopt); 00230 printf(usage, exec_name); 00231 exit(1); 00232 } 00233 } 00234 00235 if(!flag_i && (optind != argc - 1)) 00236 { 00237 printf("Missing argument: <NFS_FileHandle>\n"); 00238 printf(usage, exec_name); 00239 exit(1); 00240 } 00241 00242 /* initialize memory and logging */ 00243 00244 nfs_prereq_init("convert_fh", "localhost", NIV_MAJ, "/dev/tty"); 00245 00246 /* Load the FSAL library (if needed) */ 00247 if(!FSAL_LoadLibrary((char *)fsal_path_lib)) 00248 { 00249 fprintf(stderr, "NFS MAIN: Could not load FSAL dynamic library %s", (char *)fsal_path_lib[0]); 00250 exit(1); 00251 } 00252 00253 /* Get the FSAL functions */ 00254 FSAL_LoadFunctions(); 00255 00256 /* Get the FSAL consts */ 00257 FSAL_LoadConsts(); 00258 00259 /* initialize default parameters */ 00260 00261 nfs_set_param_default(); 00262 00263 /* parse configuration file */ 00264 00265 if(nfs_set_param_from_conf(&nfs_start_info)) 00266 { 00267 fprintf(stderr, "Error parsing configuration file '%s'", config_path); 00268 exit(1); 00269 } 00270 00271 /* check parameters consitency */ 00272 00273 if(nfs_check_param_consistency()) 00274 { 00275 fprintf(stderr, "Inconsistent parameters found"); 00276 exit(1); 00277 } 00278 00279 if(!nfs_param.pexportlist) 00280 { 00281 fprintf(stderr, "No export entries found in configuration file !!!\n"); 00282 return -1; 00283 } 00284 00285 pexportlist = nfs_param.pexportlist; 00286 00287 /* not initialization is needed for converting fileid to path in datacache */ 00288 if(!flag_i) 00289 { 00290 00291 fsal_status = FSAL_Init(&nfs_param.fsal_param); 00292 if(FSAL_IS_ERROR(fsal_status)) 00293 { 00294 /* Failed init */ 00295 fprintf(stderr, "FSAL library could not be initialized, major=%d minor=%d\n", 00296 fsal_status.major, fsal_status.minor); 00297 exit(1); 00298 } 00299 00300 strncpy(str, argv[optind], 2 * CMD_BUFFER_SIZE); 00301 00302 switch (nfs_version) 00303 { 00304 case 2: 00305 if(sscanmem(filehandle_v2, sizeof(file_handle_v2_t), (char *)str) == -1) 00306 { 00307 fprintf(stderr, "Bad FH as input (expected size: %lu bytes)\n", 00308 (unsigned long)sizeof(file_handle_v2_t)); 00309 exit(1); 00310 } 00311 00312 exportid = nfs2_FhandleToExportId(&filehandle_v2); 00313 00314 break; 00315 00316 case 3: 00317 if(sscanmem(buffer, sizeof(file_handle_v3_t), (char *)str) == -1) 00318 { 00319 fprintf(stderr, "Bad FH as input (expected size: %lu bytes)\n", 00320 (unsigned long)sizeof(file_handle_v3_t)); 00321 exit(1); 00322 } 00323 filehandle_v3.data.data_val = (char *)buffer; 00324 filehandle_v3.data.data_len = sizeof(file_handle_v3_t); 00325 00326 exportid = nfs3_FhandleToExportId(&filehandle_v3); 00327 break; 00328 00329 case 4: 00330 if(sscanmem(buffer, sizeof(file_handle_v4_t), (char *)str) == -1) 00331 { 00332 fprintf(stderr, "Bad FH as input (expected size: %lu bytes)\n", 00333 (unsigned long)sizeof(file_handle_v4_t)); 00334 exit(1); 00335 } 00336 filehandle_v4.nfs_fh4_val = (char *)buffer; 00337 filehandle_v4.nfs_fh4_len = sizeof(file_handle_v4_t); 00338 00339 exportid = nfs4_FhandleToExportId(&filehandle_v4); 00340 break; 00341 00342 } 00343 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 00344 { 00345 fprintf(stderr, "NFS FH has exportid %u which is invalid....\n", exportid); 00346 exit(1); 00347 } 00348 00349 /* INITIALIZING A CLIENT CONTEXT FOR FSAL */ 00350 00351 FSAL_str2path(pexport->fullpath, MAXPATHLEN, &export_path); 00352 00353 if(FSAL_IS_ERROR 00354 (fsal_status = 00355 FSAL_BuildExportContext(&fsal_export_context, &export_path, 00356 pexport->FS_specific))) 00357 { 00358 fprintf(stderr, "Error in FSAL_BuildExportContext, major=%u, minor=%u\n", 00359 fsal_status.major, fsal_status.minor); 00360 exit(1); 00361 } 00362 00363 fsal_status = FSAL_InitClientContext(&fsal_op_context); 00364 if(FSAL_IS_ERROR(fsal_status)) 00365 { 00366 /* Failed init */ 00367 fprintf(stderr, "Could not init client context... major=%d minor=%d\n", 00368 fsal_status.major, fsal_status.minor); 00369 exit(1); 00370 } 00371 00372 fsal_status = FSAL_GetClientContext(&fsal_op_context, 00373 &fsal_export_context, 0, 0, NULL, 0); 00374 00375 if(FSAL_IS_ERROR(fsal_status)) 00376 { 00377 /* Failed init */ 00378 fprintf(stderr, "Could not get cred for uid=%d gid=%d, major=%d minor=%d\n", 00379 getuid(), getgid(), fsal_status.major, fsal_status.minor); 00380 exit(1); 00381 } 00382 00383 /* now, can use the fsal_op_context */ 00384 switch (nfs_version) 00385 { 00386 case 2: 00387 if(!nfs2_FhandleToFSAL(&filehandle_v2, &fsal_data.fh_desc, &fsal_op_context)) 00388 { 00389 fprintf(stderr, "Cannot convert Fhandle to FSAL\n"); 00390 exit(1); 00391 } 00392 break; 00393 00394 case 3: 00395 if(!nfs3_FhandleToFSAL(&filehandle_v3, &fsal_data.fh_desc, &fsal_op_context)) 00396 { 00397 fprintf(stderr, "Cannot convert Fhandle to FSAL\n"); 00398 exit(1); 00399 } 00400 break; 00401 00402 case 4: 00403 if(!nfs4_FhandleToFSAL(&filehandle_v4, &fsal_data.fh_desc, &fsal_op_context)) 00404 { 00405 fprintf(stderr, "Cannot convert Fhandle to FSAL\n"); 00406 exit(1); 00407 } 00408 break; 00409 } 00410 00411 printf("\n"); 00412 00413 snprintmem((caddr_t) str, 2 * CMD_BUFFER_SIZE, fsal_data.fh_desc.start, 00414 fsal_data.fh_desc.len); 00415 00416 printf("%-18s = %s\n", "FSAL Handle", str); 00417 00418 /* Now, list FSAL extended attributes */ 00419 00420 cookie = XATTRS_READLIST_FROM_BEGINNING; 00421 eol = FALSE; 00422 00423 while(!eol) 00424 { 00425 unsigned int index; 00426 00427 fsal_status = FSAL_ListXAttrs((fsal_handle_t *)fsal_data.fh_desc.start, cookie, &fsal_op_context, 00428 xattr_array, 256, &nb_returned, &eol); 00429 00430 if(FSAL_IS_ERROR(fsal_status)) 00431 { 00432 fprintf(stderr, "Error executing FSAL_ListXAttrs\n"); 00433 exit(1); 00434 } 00435 00436 /* list attributes and get their value */ 00437 00438 for(index = 0; index < nb_returned; index++) 00439 { 00440 cookie = xattr_array[index].xattr_cookie; 00441 00442 printf("%-18s = ", xattr_array[index].xattr_name.name); 00443 00444 fsal_status = 00445 FSAL_GetXAttrValueByName((fsal_handle_t *)fsal_data.fh_desc.start, 00446 &xattr_array[index].xattr_name, 00447 &fsal_op_context, attr_buffer, 4096, 00448 &sz_returned); 00449 00450 if(FSAL_IS_ERROR(fsal_status)) 00451 { 00452 fprintf(stderr, "Error executing FSAL_GetXAttrValueByName\n"); 00453 } 00454 00455 /* Display it */ 00456 print_buffer(attr_buffer, sz_returned); 00457 00458 } 00459 00460 } 00461 00462 /* get object ID */ 00463 fh_desc.start = (caddr_t) & objid; 00464 fh_desc.len = sizeof(fsal_u64_t); 00465 fsal_status = 00466 FSAL_DigestHandle(&fsal_export_context, FSAL_DIGEST_FILEID4, 00467 (fsal_handle_t *)fsal_data.fh_desc.start, 00468 &fh_desc); 00469 00470 if(FSAL_IS_ERROR(fsal_status)) 00471 { 00472 fprintf(stderr, "Error retrieving fileid from handle\n"); 00473 } 00474 else 00475 { 00476 printf("%-18s = %llu\n", "FileId", objid); 00477 } 00478 00479 } 00480 00481 /* for limiting the number of entries into each datacache directory 00482 * we create 256 subdirectories on 2 levels, depending on the entry's fileid. 00483 */ 00484 snprintf(entry_path, MAXPATHLEN, "export_id=%d", 0); 00485 00486 exit(0); 00487 }