nfs-ganesha 1.4

fsal_tools.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  */
00004 
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h"
00015 #endif
00016 
00017 #include "fsal.h"
00018 #include "fsal_internal.h"
00019 #include "fsal_convert.h"
00020 #include "config_parsing.h"
00021 #include <string.h>
00022 
00023 /* case unsensitivity */
00024 #define STRCMP   strcasecmp
00025 
00026 char *POSIXFSAL_GetFSName()
00027 {
00028   return "POSIX";
00029 }
00030 
00047 int POSIXFSAL_handlecmp(fsal_handle_t * hdl1, fsal_handle_t * hdl2,
00048                         fsal_status_t * status)
00049 {
00050   posixfsal_handle_t * handle1 = (posixfsal_handle_t *) hdl1;
00051   posixfsal_handle_t * handle2 = (posixfsal_handle_t *) hdl2;
00052   *status = FSAL_STATUS_NO_ERROR;
00053 
00054   if(!handle1 || !handle2)
00055     {
00056       status->major = ERR_FSAL_FAULT;
00057       return -1;
00058     }
00059 
00060   return (handle1->data.id != handle2->data.id) || (handle1->data.ts != handle2->data.ts);
00061 
00062 }
00063 
00078 unsigned int POSIXFSAL_Handle_to_HashIndex(fsal_handle_t * handle,
00079                                            unsigned int cookie,
00080                                            unsigned int alphabet_len,
00081                                            unsigned int index_size)
00082 {
00083   posixfsal_handle_t * p_handle = (posixfsal_handle_t *) handle;
00084   unsigned int h;
00085   h = (cookie * alphabet_len + ((unsigned int)p_handle->data.id ^ (unsigned int)p_handle->data.ts));
00086   return (3 * h + 1999) % index_size;
00087 }
00088 
00089 /*
00090  * FSAL_Handle_to_RBTIndex
00091  * This function is used for generating a RBT node ID
00092  * in order to identify entries into the RBT.
00093  *
00094  * \param p_handle      The handle to be hashed
00095  * \param cookie        Makes it possible to have different hash value for the
00096  *                      same handle, when cookie changes.
00097  *
00098  * \return The hash value
00099  */
00100 
00101 unsigned int POSIXFSAL_Handle_to_RBTIndex(fsal_handle_t * handle,
00102                                           unsigned int cookie)
00103 {
00104 #define MAGIC   0xABCD1234
00105   posixfsal_handle_t * p_handle = (posixfsal_handle_t *) handle;
00106   unsigned int h;
00107 
00108   h = (cookie ^ (unsigned int)p_handle->data.id ^ (unsigned int)p_handle->data.ts ^ MAGIC);
00109   return h;
00110 }
00111 
00128 fsal_status_t POSIXFSAL_DigestHandle(fsal_export_context_t * expcontext, /* IN */
00129                                      fsal_digesttype_t output_type,     /* IN */
00130                                      fsal_handle_t * in_fsal_handle,     /* IN */
00131                                      struct fsal_handle_desc *fh_desc     /* IN/OUT */
00132     )
00133 {
00134   posixfsal_export_context_t * p_expcontext
00135     = (posixfsal_export_context_t *) expcontext;
00136   posixfsal_handle_t * p_in_fsal_handle = (posixfsal_handle_t *) in_fsal_handle;
00137   size_t fh_size;
00138   caddr_t fh_data;
00139 
00140   /* sanity checks */
00141   if(!p_in_fsal_handle || !fh_desc || !fh_desc->start || !p_expcontext)
00142     ReturnCode(ERR_FSAL_FAULT, 0);
00143 
00144   switch (output_type)
00145     {
00146     /* NFS handle digest */
00147     case FSAL_DIGEST_NFSV2:
00148     case FSAL_DIGEST_NFSV3:
00149     case FSAL_DIGEST_NFSV4:
00150       fh_size = sizeof(p_in_fsal_handle->data.id) + sizeof(p_in_fsal_handle->data.ts);
00151       fh_data = (caddr_t) p_in_fsal_handle;
00152       break;
00153 
00154     /* FileId digest */
00155     case FSAL_DIGEST_FILEID2:
00156     case FSAL_DIGEST_FILEID3:
00157     case FSAL_DIGEST_FILEID4:
00158       /* XXX: does fh_desc need to be padded to FSAL_DIGEST_SIZE_FILEID{2,3,4} ?
00159        *      or is setting fh_size = sizeof(ino_t) sufficient? */
00160       fh_size = sizeof(p_in_fsal_handle->data.info.inode);
00161       fh_data = (caddr_t) &p_in_fsal_handle->data.info.inode;
00162       break;
00163 
00164     /* Nodetype digest. */
00165     case FSAL_DIGEST_NODETYPE:
00166       /* XXX: should fh_desc be padded to FSAL_DIGEST_SIZE_NODETYPE ? */
00167       fh_size = sizeof(p_in_fsal_handle->data.info.ftype);
00168       fh_data = (caddr_t) &p_in_fsal_handle->data.info.ftype;
00169       break;
00170 
00171     default:
00172       ReturnCode(ERR_FSAL_SERVERFAULT, 0);
00173     }
00174 
00175   if(fh_desc->len < fh_size)
00176     {
00177       LogMajor( COMPONENT_FSAL, "POSIX DigestHandle: too small for handle.  need %lu, have %lu",
00178                 fh_size, fh_desc->len);
00179       ReturnCode(ERR_FSAL_TOOSMALL, 0);
00180     }
00181 
00182   memcpy(fh_desc->start, fh_data, fh_size);
00183   fh_desc->len = fh_size;
00184 
00185   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00186 }
00187 
00201 fsal_status_t POSIXFSAL_ExpandHandle(fsal_export_context_t * expcontext, /* IN */
00202                                      fsal_digesttype_t in_type, /* IN */
00203                                      struct fsal_handle_desc *fh_desc /* IN/OUT */
00204     )
00205 {
00206   posixfsal_export_context_t * p_expcontext
00207     = (posixfsal_export_context_t *) expcontext;
00208 
00209   /* sanity checks */
00210   if(!fh_desc || !fh_desc->start || !p_expcontext)
00211     ReturnCode(ERR_FSAL_FAULT, 0);
00212 
00213   size_t fh_size = sizeof(fsal_u64_t) + sizeof(int);
00214   if (in_type == FSAL_DIGEST_NFSV2 && fh_desc->len < fh_size)
00215     {
00216       LogMajor(COMPONENT_FSAL,
00217                "POSIX ExpandHandle: V2 size too small for handle.  should be %lu, got %lu",
00218                fh_size, fh_desc->len);
00219       ReturnCode(ERR_FSAL_SERVERFAULT, 0);
00220     }
00221   else if (in_type != FSAL_DIGEST_SIZEOF && fh_desc->len != fh_size)
00222     {
00223       LogMajor(COMPONENT_FSAL,
00224                "POSIX ExpandHandle: size mismatch for handle.  should be %lu, got %lu",
00225                fh_size, fh_desc->len);
00226       ReturnCode(ERR_FSAL_SERVERFAULT, 0);
00227     }
00228 
00229   fh_desc->len = fh_size; /* pass back the actual size */
00230 
00231   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00232 }
00233 
00242 fsal_status_t POSIXFSAL_SetDefault_FS_specific_parameter(fsal_parameter_t * out_parameter)
00243 {
00244   posixfs_specific_initinfo_t * p_init_info;
00245 
00246   /* defensive programming... */
00247   if(out_parameter == NULL)
00248     ReturnCode(ERR_FSAL_FAULT, 0);
00249 
00250   /* set default values for all parameters of fs_specific_info */
00251   p_init_info = (posixfs_specific_initinfo_t *)&out_parameter->fs_specific_info;
00252 
00253 #ifdef _USE_PGSQL
00254 
00255   /* pgsql db */
00256   strcpy(p_init_info->dbparams.host, "localhost");
00257   strcpy(p_init_info->dbparams.port, "5432");
00258   p_init_info->dbparams.dbname[0] = '\0';
00259   p_init_info->dbparams.login[0] = '\0';
00260   p_init_info->dbparams.passwdfile[0] = '\0';
00261 
00262 #elif defined(_USE_MYSQL)
00263 
00264   strcpy(p_init_info->dbparams.host, "localhost");
00265   strcpy(p_init_info->dbparams.port, "");
00266   p_init_info->dbparams.dbname[0] = '\0';
00267   p_init_info->dbparams.login[0] = '\0';
00268   p_init_info->dbparams.passwdfile[0] = '\0';
00269 
00270 #endif
00271 
00272   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00273 
00274 }
00275 
00297 /* load FSAL init info */
00298 
00299 fsal_status_t POSIXFSAL_load_FS_specific_parameter_from_conf(config_file_t in_config,
00300                                                              fsal_parameter_t *
00301                                                              out_parameter)
00302 {
00303   posixfs_specific_initinfo_t * p_init_info;
00304   int err;
00305   int var_max, var_index;
00306   char *key_name;
00307   char *key_value;
00308   config_item_t block;
00309 
00310   /* defensive programming... */
00311   if(out_parameter == NULL)
00312     ReturnCode(ERR_FSAL_FAULT, 0);
00313 
00314   /* set default values for all parameters of fs_specific_info */
00315   p_init_info = (posixfs_specific_initinfo_t *)&out_parameter->fs_specific_info;
00316 
00317   block = config_FindItemByName(in_config, CONF_LABEL_FS_SPECIFIC);
00318 
00319   /* cannot read item */
00320   if(block == NULL)
00321     {
00322       LogCrit(COMPONENT_CONFIG, "FSAL LOAD PARAMETER: Cannot read item \"%s\" from configuration file",
00323               CONF_LABEL_FS_SPECIFIC);
00324       ReturnCode(ERR_FSAL_NOENT, 0);
00325     }
00326   else if(config_ItemType(block) != CONFIG_ITEM_BLOCK)
00327     {
00328       LogCrit(COMPONENT_CONFIG, "FSAL LOAD PARAMETER: Item \"%s\" is expected to be a block",
00329               CONF_LABEL_FS_SPECIFIC);
00330       ReturnCode(ERR_FSAL_INVAL, 0);
00331     }
00332 
00333   var_max = config_GetNbItems(block);
00334 
00335   for(var_index = 0; var_index < var_max; var_index++)
00336     {
00337       config_item_t item;
00338 
00339       item = config_GetItemByIndex(block, var_index);
00340 
00341       err = config_GetKeyValue(item, &key_name, &key_value);
00342       if(err)
00343         {
00344           LogCrit(COMPONENT_CONFIG,
00345                "FSAL LOAD PARAMETER: ERROR reading key[%d] from section \"%s\" of configuration file.",
00346                var_index, CONF_LABEL_FS_SPECIFIC);
00347           ReturnCode(ERR_FSAL_SERVERFAULT, err);
00348         }
00349       /* does the variable exists ? */
00350       if(!STRCMP(key_name, "DB_Host"))
00351         {
00352           strncpy(p_init_info->dbparams.host,
00353                   key_value, FSAL_MAX_DBHOST_NAME_LEN);
00354         }
00355       else if(!STRCMP(key_name, "DB_Port"))
00356         {
00357           int port;
00358           port = atoi(key_value);       /* XXX: replace atoi by my_atoi ?! */
00359           if(port <= 0 || port > USHRT_MAX)
00360             {
00361               LogCrit(COMPONENT_CONFIG,
00362                    "FSAL LOAD PARAMETER: ERROR: Unexpected value for %s: positive integer (< %i) expected.",
00363                    key_name, USHRT_MAX);
00364               ReturnCode(ERR_FSAL_INVAL, 0);
00365             }
00366           strncpy(p_init_info->dbparams.port,
00367                   key_value, FSAL_MAX_DBPORT_STR_LEN);
00368         }
00369       else if(!STRCMP(key_name, "DB_Name"))
00370         {
00371           strncpy(p_init_info->dbparams.dbname,
00372                   key_value, FSAL_MAX_DB_NAME_LEN);
00373         }
00374       else if(!STRCMP(key_name, "DB_Login"))
00375         {
00376           strncpy(p_init_info->dbparams.login,
00377                   key_value, FSAL_MAX_DB_LOGIN_LEN);
00378         }
00379       else if(!STRCMP(key_name, "DB_keytab"))
00380         {
00381           strncpy(p_init_info->dbparams.passwdfile,
00382                   key_value, FSAL_MAX_PATH_LEN);
00383         }
00384       else
00385         {
00386           LogCrit(COMPONENT_CONFIG,
00387                "FSAL LOAD PARAMETER: ERROR: Unknown or unsettable key: %s (item %s)",
00388                key_name, CONF_LABEL_FS_SPECIFIC);
00389           ReturnCode(ERR_FSAL_INVAL, 0);
00390         }
00391     }
00392 
00393   if(p_init_info->dbparams.host[0] == '\0'
00394      || p_init_info->dbparams.dbname[0] == '\0')
00395     {
00396       LogCrit(COMPONENT_CONFIG,
00397            "FSAL LOAD PARAMETER: DB_Host and DB_Name MUST be specified in the configuration file");
00398       ReturnCode(ERR_FSAL_NOENT, 0);
00399     }
00400 
00401   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00402 
00403 }                               /* FSAL_load_FS_specific_parameter_from_conf */