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 XFSFSAL_BuildExportContext(fsal_export_context_t *export_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 
00051   char rpath[MAXPATHLEN];
00052   char mntdir[MAXPATHLEN];
00053   char fs_spec[MAXPATHLEN];
00054 
00055   char *first_xfs_dir = NULL;
00056   char type[256];
00057 
00058   size_t pathlen, outlen;
00059   int rc;
00060 
00061   char *handle;
00062   size_t handle_len = 0;
00063   struct stat sb;
00064   xfsfsal_export_context_t *p_export_context =
00065     (xfsfsal_export_context_t *)export_context;
00066 
00067   /* sanity check */
00068   if(p_export_context == NULL)
00069     {
00070       LogCrit(COMPONENT_FSAL, "NULL mandatory argument passed to %s()", __FUNCTION__);
00071       Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_BuildExportContext);
00072     }
00073 
00074   outlen = 0;
00075 
00076   if(p_export_path != NULL)
00077     strncpy(rpath, p_export_path->path, MAXPATHLEN);
00078 
00079   /* open mnt file */
00080   fp = setmntent(MOUNTED, "r");
00081 
00082   if(fp == NULL)
00083     {
00084       rc = errno;
00085       LogCrit(COMPONENT_FSAL, "Error %d in setmntent(%s): %s", rc, MOUNTED,
00086                       strerror(rc));
00087       Return(posix2fsal_error(rc), rc, INDEX_FSAL_BuildExportContext);
00088     }
00089 
00090   while((p_mnt = getmntent(fp)) != NULL)
00091     {
00092       /* get the longer path xfs related export that matches export path */
00093 
00094       if(p_mnt->mnt_dir != NULL)
00095         {
00096 
00097           pathlen = strlen(p_mnt->mnt_dir);
00098 
00099           if(strncmp(p_mnt->mnt_type, "xfs", 256))
00100             continue;
00101 
00102           if(first_xfs_dir == NULL)
00103             first_xfs_dir = p_mnt->mnt_dir;
00104 
00105           if((pathlen > outlen) && !strcmp(p_mnt->mnt_dir, "/"))
00106             {
00107               LogDebug(COMPONENT_FSAL,
00108                               "Root mountpoint is allowed for matching %s, type=%s, fs=%s",
00109                               rpath, p_mnt->mnt_type, p_mnt->mnt_fsname);
00110               outlen = pathlen;
00111               strncpy(mntdir, p_mnt->mnt_dir, MAXPATHLEN);
00112               strncpy(type, p_mnt->mnt_type, 256);
00113               strncpy(fs_spec, p_mnt->mnt_fsname, MAXPATHLEN);
00114             }
00115           /* in other cases, the filesystem must be <mountpoint>/<smthg> or <mountpoint>\0 */
00116           else if((pathlen > outlen) &&
00117                   !strncmp(rpath, p_mnt->mnt_dir, pathlen) &&
00118                   ((rpath[pathlen] == '/') || (rpath[pathlen] == '\0')))
00119             {
00120               LogFullDebug(COMPONENT_FSAL, "%s is under mountpoint %s, type=%s, fs=%s",
00121                               rpath, p_mnt->mnt_dir, p_mnt->mnt_type, p_mnt->mnt_fsname);
00122 
00123               outlen = pathlen;
00124               strncpy(mntdir, p_mnt->mnt_dir, MAXPATHLEN);
00125               strncpy(type, p_mnt->mnt_type, 256);
00126               strncpy(fs_spec, p_mnt->mnt_fsname, MAXPATHLEN);
00127             }
00128         }
00129     }
00130 
00131   if(outlen <= 0)
00132     {
00133       if(p_export_path == NULL)
00134         strncpy(mntdir, first_xfs_dir, MAXPATHLEN);
00135       else
00136         {
00137           LogCrit(COMPONENT_FSAL, "No mount entry matches '%s' in %s", rpath, MOUNTED);
00138           endmntent(fp);
00139           Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_BuildExportContext);
00140         }
00141     }
00142   endmntent(fp);
00143 
00144   /* Save pointer to fsal_staticfsinfo_t in export context */
00145   p_export_context->fe_static_fs_info = &global_fs_info;
00146 
00147   /* Do the path_to_fshandle call to init the xfs's libhandle */
00148   strncpy(p_export_context->mount_point, mntdir, MAXPATHLEN);
00149 
00150   if((rc = path_to_fshandle(mntdir, (void **)(&handle), &handle_len)) < 0)
00151     Return(ERR_FSAL_FAULT, errno, INDEX_FSAL_BuildExportContext);
00152 
00153   if (handle_len > sizeof(p_export_context->mnt_fshandle_val))
00154     {
00155       free_handle(handle, handle_len);
00156       Return(ERR_FSAL_FAULT, E2BIG, INDEX_FSAL_BuildExportContext);
00157     }
00158   memcpy(p_export_context->mnt_fshandle_val, handle, handle_len);
00159   p_export_context->mnt_fshandle_len = handle_len;
00160   free_handle(handle, handle_len);
00161 
00162   if((rc = path_to_handle(mntdir, (void **)(&handle), &handle_len)) < 0)
00163     Return(ERR_FSAL_FAULT, errno, INDEX_FSAL_BuildExportContext);
00164 
00165   if (handle_len > sizeof(p_export_context->mnt_handle_val))
00166     {
00167       free_handle(handle, handle_len);
00168       Return(ERR_FSAL_FAULT, E2BIG, INDEX_FSAL_BuildExportContext);
00169     }
00170   memcpy(p_export_context->mnt_handle_val, handle, handle_len);
00171   p_export_context->mnt_handle_len = handle_len;
00172   free_handle(handle, handle_len);
00173 
00174   if(stat(mntdir, &sb) < 0)
00175     Return(ERR_FSAL_FAULT, errno, INDEX_FSAL_BuildExportContext);
00176 
00177   p_export_context->dev_id = sb.st_dev;
00178   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_BuildExportContext);
00179 }