nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 */ 00004 00014 #ifdef HAVE_CONFIG_H 00015 #include "config.h" 00016 #endif 00017 00018 #ifdef _SOLARIS 00019 #include "solaris_port.h" 00020 #endif /* _SOLARIS */ 00021 00022 #ifdef _USE_GSSRPC 00023 #include <gssrpc/rpc.h> 00024 #include <gssrpc/clnt.h> 00025 #include <gssrpc/auth.h> 00026 #else 00027 #include <rpc/rpc.h> 00028 #include <rpc/xdr.h> 00029 #include <rpc/clnt.h> 00030 #include <rpc/auth.h> 00031 #endif 00032 #include "fsal.h" 00033 #include "fsal_internal.h" 00034 #include "fsal_common.h" 00035 #include "fsal_nfsv4_macros.h" 00036 #include <pwd.h> 00037 #include <errno.h> 00038 #include <stdlib.h> 00039 #include <string.h> 00040 #include <netdb.h> /* For rresvport */ 00041 00042 extern proxyfs_specific_initinfo_t global_fsal_proxy_specific_info; 00043 00046 /* define your specific NFS export options here : */ 00047 enum 00048 { 00049 YOUR_OPTION_1 = 0, 00050 YOUR_OPTION_2 = 1, 00051 YOUR_OPTION_3 = 2, 00052 YOUR_OPTION_4 = 3, 00053 }; 00054 00055 const char *fs_specific_opts[] = { 00056 "option1", 00057 "option2", 00058 "option3", 00059 "option4", 00060 NULL 00061 }; 00062 00067 static int Getsubopt(char **optionp, const char *const *tokens, char **valuep) 00068 { 00069 char *endp, *vstart; 00070 int cnt; 00071 00072 if(**optionp == '\0') 00073 return -1; 00074 00075 /* Find end of next token. */ 00076 endp = strchr(*optionp, ','); 00077 if(endp == NULL) 00078 endp = strchr(*optionp, '\0'); 00079 00080 /* Find start of value. */ 00081 vstart = memchr(*optionp, '=', endp - *optionp); 00082 if(vstart == NULL) 00083 vstart = endp; 00084 00085 /* Try to match the characters between *OPTIONP and VSTART against 00086 one of the TOKENS. */ 00087 for(cnt = 0; tokens[cnt] != NULL; ++cnt) 00088 if(memcmp(*optionp, tokens[cnt], vstart - *optionp) == 0 00089 && tokens[cnt][vstart - *optionp] == '\0') 00090 { 00091 /* We found the current option in TOKENS. */ 00092 *valuep = vstart != endp ? vstart + 1 : NULL; 00093 00094 if(*endp != '\0') 00095 *endp++ = '\0'; 00096 *optionp = endp; 00097 00098 return cnt; 00099 } 00100 00101 /* The current suboption does not match any option. */ 00102 *valuep = *optionp; 00103 00104 if(*endp != '\0') 00105 *endp++ = '\0'; 00106 *optionp = endp; 00107 00108 return -1; 00109 } 00110 00123 fsal_status_t PROXYFSAL_BuildExportContext(fsal_export_context_t * p_export_context, /* OUT */ 00124 fsal_path_t * p_export_path, /* IN */ 00125 char *fs_specific_options /* IN */ 00126 ) 00127 { 00128 char subopts[256]; 00129 char *p_subop; 00130 char *value; 00131 00132 /* sanity check */ 00133 if(!p_export_context) 00134 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_BuildExportContext); 00135 00136 /* Save pointer to fsal_staticfsinfo_t in export context */ 00137 p_export_context->fe_static_fs_info = &global_fs_info; 00138 00139 if((fs_specific_options != NULL) && (fs_specific_options[0] != '\0')) 00140 { 00141 00142 /* copy the option string (because it is modified by getsubopt call) */ 00143 strncpy(subopts, fs_specific_options, 256); 00144 subopts[255] = '\0'; 00145 p_subop = subopts; /* set initial pointer */ 00146 00147 /* parse the FS specific option string */ 00148 00149 switch (Getsubopt(&p_subop, fs_specific_opts, &value)) 00150 { 00151 case YOUR_OPTION_1: 00152 /* analyze your option 1 and fill the export_context structure */ 00153 break; 00154 00155 case YOUR_OPTION_2: 00156 /* analyze your option 2 and fill the export_context structure */ 00157 break; 00158 00159 case YOUR_OPTION_3: 00160 /* analyze your option 3 and fill the export_context structure */ 00161 break; 00162 00163 case YOUR_OPTION_4: 00164 /* analyze your option 4 and fill the export_context structure */ 00165 break; 00166 00167 default: 00168 { 00169 LogCrit(COMPONENT_FSAL, 00170 "FSAL LOAD PARAMETER: ERROR: Invalid suboption found in EXPORT::FS_Specific : %s : xxxxxx expected.", 00171 value); 00172 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_BuildExportContext); 00173 } 00174 } 00175 00176 } 00177 00178 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_BuildExportContext); 00179 } 00180 00181 fsal_status_t PROXYFSAL_InitClientContext(fsal_op_context_t *context) 00182 { 00183 fsal_status_t fsal_status; 00184 proxyfsal_op_context_t * p_thr_context = (proxyfsal_op_context_t *)context; 00185 00186 /* sanity check */ 00187 if(!p_thr_context) 00188 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_InitClientContext); 00189 00190 /* initialy set the export entry to none */ 00191 p_thr_context->export_context = NULL; 00192 00193 /* It is now time to initiate the rpc client within the thread's specific material */ 00194 /* Keep here the reference to the server */ 00195 p_thr_context->srv_prognum = global_fsal_proxy_specific_info.srv_prognum; 00196 p_thr_context->srv_addr = global_fsal_proxy_specific_info.srv_addr; 00197 p_thr_context->srv_port = global_fsal_proxy_specific_info.srv_port; 00198 p_thr_context->srv_sendsize = global_fsal_proxy_specific_info.srv_sendsize; 00199 p_thr_context->srv_recvsize = global_fsal_proxy_specific_info.srv_recvsize; 00200 p_thr_context->use_privileged_client_port = global_fsal_proxy_specific_info.use_privileged_client_port; 00201 p_thr_context->retry_sleeptime = global_fsal_proxy_specific_info.retry_sleeptime; 00202 p_thr_context->file_counter = 0LL; 00203 strncpy(p_thr_context->srv_proto, global_fsal_proxy_specific_info.srv_proto, MAXNAMLEN); 00204 pthread_mutex_init(&p_thr_context->lock, NULL); 00205 00206 00207 fsal_status = fsal_proxy_create_rpc_clnt(p_thr_context); 00208 if(FSAL_IS_ERROR(fsal_status)) 00209 ReturnStatus(fsal_status, INDEX_FSAL_InitClientContext); 00210 00211 fsal_status = FSAL_proxy_setclientid(p_thr_context); 00212 if(FSAL_IS_ERROR(fsal_status)) 00213 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_InitClientContext); 00214 00215 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_InitClientContext); 00216 } 00217 00218 /* @} */