nfs-ganesha 1.4

fsal_context.c

Go to the documentation of this file.
00001 
00010 #ifdef HAVE_CONFIG_H
00011 #include "config.h"
00012 #endif
00013 
00014 #include "fsal.h"
00015 #include "fsal_internal.h"
00016 #include "fsal_convert.h"
00017 #include <pwd.h>
00018 #include <errno.h>
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <unistd.h>
00022 #include <time.h>
00023 #include <stdio.h>
00024 #include <pthread.h>
00025 #include <mntent.h>             /* for handling mntent */
00026 #include <libgen.h>             /* for dirname */
00027 
00039 fsal_status_t LUSTREFSAL_BuildExportContext(fsal_export_context_t *exp_context,     /* OUT */
00040                                             fsal_path_t * p_export_path,        /* IN */
00041                                             char *fs_specific_options   /* IN */
00042     )
00043 {
00044   /* Get the mount point for this lustre FS,
00045    * so it can be used for building .lustre/fid paths.
00046    */
00047 
00048   FILE *fp;
00049   struct mntent *p_mnt;
00050   struct stat pathstat;
00051   lustrefsal_export_context_t * p_export_context = (lustrefsal_export_context_t *)exp_context;
00052 
00053   char rpath[MAXPATHLEN];
00054   char mntdir[MAXPATHLEN];
00055   char fs_spec[MAXPATHLEN];
00056   char *ptr;
00057 
00058   char type[256];
00059 
00060   size_t pathlen, outlen;
00061   int rc;
00062 
00063   /* sanity check */
00064   if((p_export_context == NULL) || (p_export_path == NULL))
00065     {
00066       LogCrit(COMPONENT_FSAL, "NULL mandatory argument passed to %s()", __FUNCTION__);
00067       Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_BuildExportContext);
00068     }
00069 
00070   /* convert to canonical path */
00071   if(!realpath(p_export_path->path, rpath))
00072     {
00073       rc = errno;
00074       LogCrit(COMPONENT_FSAL, "Error %d in realpath(%s): %s",
00075                       rc, p_export_path->path, strerror(rc));
00076       Return(posix2fsal_error(rc), rc, INDEX_FSAL_BuildExportContext);
00077     }
00078 
00079   /* open mnt file */
00080   outlen = 0;
00081 
00082   fp = setmntent(MOUNTED, "r");
00083 
00084   if(fp == NULL)
00085     {
00086       rc = errno;
00087       LogCrit(COMPONENT_FSAL, "Error %d in setmntent(%s): %s", rc, MOUNTED,
00088                       strerror(rc));
00089       Return(posix2fsal_error(rc), rc, INDEX_FSAL_BuildExportContext);
00090     }
00091 
00092   while((p_mnt = getmntent(fp)) != NULL)
00093     {
00094       /* get the longer path that matches export path */
00095 
00096       if(p_mnt->mnt_dir != NULL)
00097         {
00098 
00099           pathlen = strlen(p_mnt->mnt_dir);
00100 
00101           if((pathlen > outlen) && !strcmp(p_mnt->mnt_dir, "/"))
00102             {
00103               LogDebug(COMPONENT_FSAL,
00104                               "Root mountpoint is allowed for matching %s, type=%s, fs=%s",
00105                               rpath, p_mnt->mnt_type, p_mnt->mnt_fsname);
00106               outlen = pathlen;
00107               strncpy(mntdir, p_mnt->mnt_dir, MAXPATHLEN);
00108               strncpy(type, p_mnt->mnt_type, 256);
00109               strncpy(fs_spec, p_mnt->mnt_fsname, MAXPATHLEN);
00110             }
00111           /* in other cases, the filesystem must be <mountpoint>/<smthg> or <mountpoint>\0 */
00112           else if((pathlen > outlen) &&
00113                   !strncmp(rpath, p_mnt->mnt_dir, pathlen) &&
00114                   ((rpath[pathlen] == '/') || (rpath[pathlen] == '\0')))
00115             {
00116               LogFullDebug(COMPONENT_FSAL, "%s is under mountpoint %s, type=%s, fs=%s",
00117                               rpath, p_mnt->mnt_dir, p_mnt->mnt_type, p_mnt->mnt_fsname);
00118 
00119               outlen = pathlen;
00120               strncpy(mntdir, p_mnt->mnt_dir, MAXPATHLEN);
00121               strncpy(type, p_mnt->mnt_type, 256);
00122               strncpy(fs_spec, p_mnt->mnt_fsname, MAXPATHLEN);
00123             }
00124         }
00125     }
00126 
00127   if(outlen <= 0)
00128     {
00129       LogCrit(COMPONENT_FSAL, "No mount entry matches '%s' in %s", rpath, MOUNTED);
00130       endmntent(fp);
00131       Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_BuildExportContext);
00132     }
00133 
00134   /* display the mnt entry found */
00135   LogEvent(COMPONENT_FSAL, "'%s' matches mount point '%s', type=%s, fs=%s", rpath,
00136                   mntdir, type, fs_spec);
00137 
00138   /* Check it is a Lustre FS */
00139   if(!llapi_is_lustre_mnttype(type))
00140     {
00141       LogCrit(COMPONENT_FSAL,
00142                       "/!\\ ERROR /!\\ '%s' (type: %s) is not recognized as a Lustre Filesystem",
00143                       rpath, type);
00144       endmntent(fp);
00145       Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_BuildExportContext);
00146     }
00147 
00148   /* retrieve export info */
00149   if(stat(rpath, &pathstat) != 0)
00150     {
00151       rc = errno;
00152       LogCrit(COMPONENT_FSAL, "/!\\ ERROR /!\\ Couldn't stat '%s': %s", rpath,
00153                       strerror(rc));
00154       endmntent(fp);
00155 
00156       Return(posix2fsal_error(rc), rc, INDEX_FSAL_BuildExportContext);
00157     }
00158 
00159   /* all checks are OK, fill export context */
00160   strncpy(p_export_context->mount_point, mntdir, FSAL_MAX_PATH_LEN);
00161   p_export_context->mnt_len = strlen(mntdir);
00162   ptr = strrchr(fs_spec, '/');
00163   if (ptr) {
00164       ptr++;
00165       LogDebug(COMPONENT_FSAL, "Lustre fsname for %s is '%s'", mntdir, ptr);
00166       strncpy(p_export_context->fsname, ptr, MAX_LUSTRE_FSNAME);
00167   }
00168   p_export_context->dev_id = pathstat.st_dev;
00169 
00170   /* Save pointer to fsal_staticfsinfo_t in export context */
00171   p_export_context->fe_static_fs_info = &global_fs_info;
00172 
00173   endmntent(fp);
00174 
00175   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_BuildExportContext);
00176 }