nfs-ganesha 1.4

ConvertFh.c

Go to the documentation of this file.
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 }