nfs-ganesha 1.4
|
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 }