예제 #1
0
fsal_posixdb_status_t fsal_posixdb_delete(fsal_posixdb_conn * p_conn,   /* IN */
                                          posixfsal_handle_t * p_parent_directory_handle,       /* IN */
                                          fsal_name_t * p_filename,     /* IN */
                                          fsal_posixdb_fileinfo_t *
                                          p_object_info /* IN */ )
{
  result_handle_t res;
  fsal_posixdb_status_t st;
  char query[2048];

    /*******************
     * 1/ sanity check *
     *******************/

  if(!p_conn || !p_parent_directory_handle || !p_filename)
    ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);

  BeginTransaction(p_conn);

    /*******************************
     * 2/ we check the file exists *
     *******************************/

  snprintf(query, 2048, "SELECT Parent.handleid, Parent.handlets, "
           "Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype "
           "FROM Parent INNER JOIN Handle ON Parent.handleid = Handle.handleid "
           "AND Parent.handlets=Handle.handlets "
           "WHERE handleidparent=%llu AND handletsparent=%u AND name='%s' "
           "FOR UPDATE", p_parent_directory_handle->data.id,
           p_parent_directory_handle->data.ts, p_filename->name);

  st = db_exec_sql(p_conn, query, &res);
  if(FSAL_POSIXDB_IS_ERROR(st))
    goto rollback;

  if(mysql_num_rows(res) != 1)
    {
      /* parent entry not found */
      mysql_free_result(res);
      RollbackTransaction(p_conn);
      ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
    }
  mysql_free_result(res);

    /***********************************************
     * 3/ Get information about the file to delete *
     ***********************************************/

  st = fsal_posixdb_internal_delete(p_conn, p_parent_directory_handle->data.id,
                                    p_parent_directory_handle->data.ts,
                                    p_filename->name, p_object_info);
  if(FSAL_POSIXDB_IS_ERROR(st))
    goto rollback;

  return EndTransaction(p_conn);

 rollback:
  RollbackTransaction(p_conn);
  return st;
}
예제 #2
0
/*
 *  This function adds an entry in the database
 */
fsal_status_t fsal_internal_posixdb_add_entry(fsal_posixdb_conn * p_conn,
                                              fsal_name_t * p_filename,
                                              fsal_posixdb_fileinfo_t * p_info,
                                              posixfsal_handle_t * p_dir_handle,
                                              posixfsal_handle_t * p_new_handle)
{
  fsal_posixdb_status_t stdb;

  if(!p_info || !p_conn || !p_new_handle)       /* p_filename & p_dir_handle can be NULL for the root */
    ReturnCode(ERR_FSAL_FAULT, 0);

 add:
  stdb = fsal_posixdb_add(p_conn, p_info, p_dir_handle, p_filename, p_new_handle);

  if(stdb.major == ERR_FSAL_POSIXDB_CONSISTENCY)
    {                           /* there is already an entry with this path, but it's an inconsistent one */
      stdb = fsal_posixdb_deleteHandle(p_conn, p_new_handle);
      if(FSAL_POSIXDB_IS_ERROR(stdb))
        return posixdb2fsal_error(stdb);
      goto add;
    }
  else if(FSAL_POSIXDB_IS_ERROR(stdb))
    {
      return posixdb2fsal_error(stdb);
    }

  ReturnCode(ERR_FSAL_NO_ERROR, 0);
}
예제 #3
0
void display_directory(fsal_posixdb_conn * p_conn, posixfsal_handle_t * p_handle_parent,
                       char *basedir)
{
  fsal_posixdb_child *p_children;
  fsal_posixdb_status_t st;
  unsigned int count, i;

  st = fsal_posixdb_getChildren(p_conn, p_handle_parent, 0, &p_children, &count);
  if(FSAL_POSIXDB_IS_ERROR(st))
    {
      fprintf(stderr, "Error (%i/%i) while getting children of %s\n", st.major, st.minor,
              basedir);
      return;
    }
  for(i = 0; i < count; i++)
    {
      printf("%llu %s/%s\n", (unsigned long long int)p_children[i].handle.data.info.inode,
             basedir, p_children[i].name.name);
      if(p_children[i].handle.data.info.ftype == FSAL_TYPE_DIR)
        {
          char basedir_new[FSAL_MAX_PATH_LEN];

          memset( basedir_new, 0, FSAL_MAX_PATH_LEN ) ;
          strncpy(basedir_new, basedir, FSAL_MAX_PATH_LEN);
          strncat(basedir_new, "/", FSAL_MAX_PATH_LEN);
          strncat(basedir_new, p_children[i].name.name, FSAL_MAX_PATH_LEN);
          display_directory(p_conn, &(p_children[i].handle), basedir_new);
        }
    }
  gsh_free(p_children);
}
예제 #4
0
/** 
 * @brief Lock the line of the Handle table with inode & devid defined in p_info
 * 
 * @param p_conn
 *        Database connection
 * @param p_info 
 *        Information about the file
 * 
 * @return ERR_FSAL_POSIXDB_NOERR if no error,
 *         another error code else.
 */
fsal_posixdb_status_t fsal_posixdb_lockHandleForUpdate(fsal_posixdb_conn * p_conn,      /* IN */
                                                       fsal_posixdb_fileinfo_t *
                                                       p_info /* IN */ )
{
  result_handle_t res;
  fsal_posixdb_status_t st;
  char query[2048];

  BeginTransaction(p_conn);

  snprintf(query, 2048, "SELECT handleid, handlets, nlink, ctime, ftype "
           "FROM Handle WHERE deviceid=%llu AND inode=%llu "
           "FOR UPDATE", (unsigned long long)p_info->devid, (unsigned long long)p_info->inode);

  st = db_exec_sql(p_conn, query, &res);
  if(FSAL_POSIXDB_IS_ERROR(st))
    {
      RollbackTransaction(p_conn);
      return st;
    }

  mysql_free_result(res);

  /* Do not end the transaction, because it will be closed by the next call to a posixdb function */

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
예제 #5
0
fsal_posixdb_status_t fsal_posixdb_deleteHandle(fsal_posixdb_conn * p_conn,     /* IN */
                                                posixfsal_handle_t *
                                                p_parent_directory_handle /* IN */ )
{
/*    char           handleid_str[MAX_HANDLEIDSTR_SIZE];
    char           handlets_str[MAX_HANDLETSSTR_SIZE];
    const char    *paramValues[2]; */
  int found;
  result_handle_t res;
  fsal_posixdb_status_t st;
  char query[2048];

  BeginTransaction(p_conn);

  LogFullDebug(COMPONENT_FSAL, "Deleting %llu.%u\n", p_parent_directory_handle->data.id,
         p_parent_directory_handle->data.ts);

  snprintf(query, 2048,
           "SELECT Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype "
           "FROM Handle WHERE handleid=%llu AND handlets=%u FOR UPDATE",
           p_parent_directory_handle->data.id, p_parent_directory_handle->data.ts);

  st = db_exec_sql(p_conn, query, &res);
  if(FSAL_POSIXDB_IS_ERROR(st))
    goto rollback;

  found = mysql_num_rows(res);
  mysql_free_result(res);

  if(found)
    {
      /* entry found */
      st = fsal_posixdb_recursiveDelete(p_conn, p_parent_directory_handle->data.id,
                                        p_parent_directory_handle->data.ts, FSAL_TYPE_DIR);
      if(FSAL_POSIXDB_IS_ERROR(st))
        goto rollback;
    }

  return EndTransaction(p_conn);

 rollback:
  RollbackTransaction(p_conn);
  return st;

}
예제 #6
0
fsal_posixdb_status_t fsal_posixdb_getParentDirHandle(fsal_posixdb_conn * p_conn,       /* IN */
                                                      posixfsal_handle_t * p_object_handle,     /* IN */
                                                      posixfsal_handle_t * p_parent_directory_handle    /* OUT */
    )
{
  fsal_posixdb_status_t st;
  MYSQL_ROW row;
  result_handle_t res;
  char query[2048];

  /* sanity check */
  if(!p_conn || !p_parent_directory_handle || !p_object_handle)
    ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);

  /* no need to start a transaction, there is only one query */

  snprintf(query, 2048,
           "SELECT Parent.name, Parent.handleidparent, Parent.handletsparent, "
           "Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype "
           "FROM Parent LEFT JOIN Handle ON Parent.handleidparent = Handle.handleid AND Parent.handletsparent=Handle.handlets "
           "WHERE Parent.handleid=%llu AND Parent.handlets=%u", p_object_handle->data.id,
           p_object_handle->data.ts);

  st = db_exec_sql(p_conn, query, &res);
  if(FSAL_POSIXDB_IS_ERROR(st))
    return st;

  /* entry not found */
  if(mysql_num_rows(res) == 0)
    {
      mysql_free_result(res);
      ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
    }

  row = mysql_fetch_row(res);
  if(row == NULL)
    {
      mysql_free_result(res);
      ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
    }
  LogDebug(COMPONENT_FSAL, "lookupPathsExt");

  p_parent_directory_handle->data.id = atoll(row[1]);
  p_parent_directory_handle->data.ts = atoi(row[2]);
  posixdb_internal_fillFileinfoFromStrValues(&(p_parent_directory_handle->data.info), row[3],
                                             row[4], row[5], row[6], row[7]);

  mysql_free_result(res);

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
예제 #7
0
void emptydb(fsal_posixdb_conn * p_conn)
{
  fsal_posixdb_status_t st;

  st = fsal_posixdb_flush(p_conn);
  if(FSAL_POSIXDB_IS_ERROR(st))
    {
      fprintf(stderr, "Error (%i/%i) while emptying the database\n", st.major, st.minor);
    }
  else
    {
      printf("Database entries have been successfully deleted\n");
    }

  return;
}
예제 #8
0
/** 
 * @brief Get the handle of a file, knowing its name and its parent dir
 * 
 * @param p_context 
 * @param p_parent_dir_handle 
 *    Handle of the parent directory
 * @param p_fsalname 
 *    Name of the object
 * @param p_infofs
 *    Information about the file (taken from the filesystem) to be compared to information stored in database
 * @param p_object_handle 
 *    Handle of the file.
 * 
 * @return
 *    ERR_FSAL_NOERR, if no error
 *    Anothere error code else.
 */
fsal_status_t fsal_internal_getInfoFromName(posixfsal_op_context_t * p_context, /* IN */
                                            posixfsal_handle_t * p_parent_dir_handle,   /* IN */
                                            fsal_name_t * p_fsalname,   /* IN */
                                            fsal_posixdb_fileinfo_t * p_infofs, /* IN */
                                            posixfsal_handle_t * p_object_handle)       /* OUT */
{
  fsal_posixdb_status_t stdb;
  fsal_status_t st;

  stdb = fsal_posixdb_getInfoFromName(p_context->p_conn,
                                      p_parent_dir_handle,
                                      p_fsalname, NULL, p_object_handle);
  switch (stdb.major)
    {
    case ERR_FSAL_POSIXDB_NOERR:
      /* No error, the object is in the database */
      /* check consistency */
      if(fsal_posixdb_consistency_check(&(p_object_handle->data.info), p_infofs))
        {
          /* Entry not consistent */
          /* Delete the Handle entry, then add a new one (with a Parent entry) */
          stdb = fsal_posixdb_deleteHandle(p_context->p_conn, p_object_handle);
          if(FSAL_POSIXDB_IS_ERROR(stdb) && FSAL_IS_ERROR(st = posixdb2fsal_error(stdb)))
            return st;
          /* don't break, add a new entry */
        }
      else
        {
          break;
        }
    case ERR_FSAL_POSIXDB_NOENT:
      /* object not in the database, add a new entry */
      st = fsal_internal_posixdb_add_entry(p_context->p_conn,
                                           p_fsalname,
                                           p_infofs,
                                           p_parent_dir_handle, p_object_handle);
      if(FSAL_IS_ERROR(st))
        return st;
      break;
    default:
      /* error */
      if(FSAL_IS_ERROR(st = posixdb2fsal_error(stdb)))
        return st;
    }

  ReturnCode(ERR_FSAL_NO_ERROR, 0);
}
예제 #9
0
fsal_status_t POSIXFSAL_InitClientContext(fsal_op_context_t * thr_context)
{
  posixfsal_op_context_t * p_thr_context = (posixfsal_op_context_t *) thr_context;
  fsal_posixdb_status_t st;

  /* sanity check */
  if(!p_thr_context)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_InitClientContext);

  /* initialy set the export entry to none */
  p_thr_context->export_context = NULL;

  st = fsal_posixdb_connect(&global_posixdb_params, &(p_thr_context->p_conn));
  if(FSAL_POSIXDB_IS_ERROR(st))
    {
      LogCrit(COMPONENT_FSAL,
              "CRITICAL ERROR: Worker could not connect to database !!!");
      Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_InitClientContext);
    }
  else
    {
      LogEvent(COMPONENT_FSAL, "Worker successfuly connected to database");
    }

  /* sets the credential time */
/*  p_thr_context->credential.last_update = time( NULL );*/

  /* traces: prints p_credential structure */

  /*
     LogDebug(COMPONENT_FSAL, "credential created:");
     LogDebug(COMPONENT_FSAL, "\tuid = %d, gid = %d",
     p_thr_context->credential.hpss_usercred.SecPWent.Uid, p_thr_context->credential.hpss_usercred.SecPWent.Gid);
     LogDebug(COMPONENT_FSAL, "\tName = %s",
     p_thr_context->credential.hpss_usercred.SecPWent.Name);

     for ( i=0; i< p_thr_context->credential.hpss_usercred.NumGroups; i++ )
     LogDebug(COMPONENT_FSAL, "\tAlt grp: %d",
     p_thr_context->credential.hpss_usercred.AltGroups[i] );
   */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_InitClientContext);

}
예제 #10
0
void find(fsal_posixdb_conn * p_conn)
{
  posixfsal_handle_t handle_root;
  fsal_posixdb_status_t st;

  st = fsal_posixdb_getInfoFromName(p_conn, NULL,       /* parent handle */
                                    NULL,       /* filename */
                                    NULL,       /* path */
                                    &handle_root);
  if(FSAL_POSIXDB_IS_NOENT(st))
    {
      fputs("Error : Root handle not found. Is the database empty ?", stderr);
      return;
    }
  else if(FSAL_POSIXDB_IS_ERROR(st))
    {
      fprintf(stderr, "Error (%i/%i) while getting root handle\n", st.major, st.minor);
      return;
    }

  display_directory(p_conn, &handle_root, "");
  return;
}
예제 #11
0
fsal_posixdb_status_t fsal_posixdb_recursiveDelete(fsal_posixdb_conn * p_conn,
                                                   char *handleid_str, char *handlets_str,
                                                   fsal_nodetype_t ftype)
{
  PGresult *p_res;
  fsal_posixdb_status_t st;
  fsal_nodetype_t ftype_tmp;
  unsigned int i;
  unsigned int i_max;
  const char *paramValues[2];

  /* Sanity check */
  if(!p_conn || !handleid_str || !handlets_str)
    {
      ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
    }

  if(ftype == FSAL_TYPE_DIR)
    {
      /* We find all the children of the directory in order to delete them, and then we delete the current handle */
      paramValues[0] = handleid_str;
      paramValues[1] = handlets_str;
      p_res = PQexecPrepared(p_conn, "lookupChildrenFU", 2, paramValues, NULL, NULL, 0);
      CheckResult(p_res);
      i_max = (unsigned int)PQntuples(p_res);
      for(i = 0; i < i_max; i++)
        {
          ftype_tmp = (fsal_nodetype_t) atoi(PQgetvalue(p_res, i, 2));
          if(ftype_tmp == FSAL_TYPE_DIR)
            {
              st = fsal_posixdb_recursiveDelete(p_conn, PQgetvalue(p_res, i, 0),
                                                PQgetvalue(p_res, i, 1), ftype_tmp);
            }
          else
            {
              st = fsal_posixdb_deleteParent(p_conn, PQgetvalue(p_res, i, 0),   /* handleidparent */
                                             PQgetvalue(p_res, i, 1),   /* handletsparent */
                                             handleid_str, handlets_str, PQgetvalue(p_res, i, 3),       /* filename */
                                             atoi(PQgetvalue(p_res, i, 4))      /* nlink */
                  );
            }
          if(FSAL_POSIXDB_IS_ERROR(st))
            {
              PQclear(p_res);
              return st;
            }
        }
      PQclear(p_res);
    }

  /* Delete the Handle */
  /* All Parent entries having this handle will be deleted thanks to foreign keys */
  paramValues[0] = handleid_str;
  paramValues[1] = handlets_str;

  /* invalidate name cache */
  fsal_posixdb_InvalidateCache();

  p_res = PQexecPrepared(p_conn, "deleteHandle", 2, paramValues, NULL, NULL, 0);
  CheckCommand(p_res);

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
예제 #12
0
fsal_posixdb_status_t fsal_posixdb_getInfoFromHandle(fsal_posixdb_conn * p_conn,        /* IN */
                                                     posixfsal_handle_t * p_object_handle,      /* IN/OUT */
                                                     fsal_path_t * p_paths,     /* OUT */
                                                     int paths_size,    /* IN */
                                                     int *p_count /* OUT */ )
{
  fsal_posixdb_status_t st;
  result_handle_t res;
  MYSQL_ROW row;
  posixfsal_handle_t parent_directory_handle;
  int i_path;
  int toomanypaths = 0;
  char query[2048];

  /* sanity check */
  if(!p_conn || !p_object_handle || ((!p_paths || !p_count) && paths_size > 0))
    {
      ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
    }
  LogFullDebug(COMPONENT_FSAL, "OBJECT_ID=%lli\n", p_object_handle->data.id);

  BeginTransaction(p_conn);

  /* lookup for the handle of the file */

  if(!fsal_posixdb_GetInodeCache(p_object_handle))
    {

      snprintf(query, 2048,
               "SELECT Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype "
               "FROM Handle WHERE handleid=%llu AND handlets=%u", p_object_handle->data.id,
               p_object_handle->data.ts);

      st = db_exec_sql(p_conn, query, &res);
      if(FSAL_POSIXDB_IS_ERROR(st))
        goto rollback;

      /* p_res contains : Handle.deviceId, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype  */

      LogDebug(COMPONENT_FSAL, "lookupHandle(%llu,%u)", p_object_handle->data.id,
                 (unsigned int)p_object_handle->data.ts);
      if((mysql_num_rows(res) != 1) || ((row = mysql_fetch_row(res)) == NULL))
        {
          LogDebug(COMPONENT_FSAL, "lookupHandle=%d entries", mysql_num_rows(res));
          mysql_free_result(res);
          RollbackTransaction(p_conn);
          ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
        }

      posixdb_internal_fillFileinfoFromStrValues(&(p_object_handle->data.info),
                                                 row[0], row[1], row[2], row[3], row[4]);
      mysql_free_result(res);

      /* update the inode */
      fsal_posixdb_UpdateInodeCache(p_object_handle);
    }

  /* Build the paths of the object */
  if(p_paths)
    {
      /* find all the paths to the object */

      snprintf(query, 2048, "SELECT name, handleidparent, handletsparent "
               "FROM Parent WHERE handleid=%llu AND handlets=%u",
               p_object_handle->data.id, p_object_handle->data.ts);

      st = db_exec_sql(p_conn, query, &res);
      if(FSAL_POSIXDB_IS_ERROR(st))
        goto rollback;

      /* res contains name, handleidparent, handletsparent */
      *p_count = mysql_num_rows(res);
      if(*p_count == 0)
        {
          mysql_free_result(res);
          RollbackTransaction(p_conn);
          ReturnCodeDB(ERR_FSAL_POSIXDB_NOPATH, 0);
        }
      else if(*p_count > paths_size)
        {
          toomanypaths = 1;

          LogCrit(COMPONENT_FSAL, "Too many paths found for object %llu.%u: found=%u, max=%d",
                     p_object_handle->data.id, p_object_handle->data.ts, *p_count, paths_size);

          *p_count = paths_size;
        }

      for(i_path = 0; i_path < *p_count; i_path++)
        {
          unsigned int tmp_len;

          row = mysql_fetch_row(res);
          if(row == NULL)
            {
              mysql_free_result(res);
              RollbackTransaction(p_conn);
              ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
            }

          /* build the path of the parent directory */
          parent_directory_handle.data.id = atoll(row[1]);
          parent_directory_handle.data.ts = atoi(row[2]);

          st = fsal_posixdb_buildOnePath(p_conn, &parent_directory_handle,
                                         &p_paths[i_path]);
          if(FSAL_POSIXDB_IS_ERROR(st))
            goto free_res;

          tmp_len = p_paths[i_path].len;

          if((tmp_len > 0) && (p_paths[i_path].path[tmp_len - 1] == '/'))
            {
              /* then concatenate the name of the file */
              /* but not concatenate '/' */
              if((tmp_len + strlen(row[0]) >= FSAL_MAX_PATH_LEN))
                {
                  mysql_free_result(res);
                  RollbackTransaction(p_conn);
                  ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0);
                }
              strcpy(&p_paths[i_path].path[tmp_len], row[0]);
              p_paths[i_path].len += strlen(row[0]);

            }
          else
            {
              /* then concatenate the name of the file */
              if((tmp_len + 1 + strlen(row[0]) >= FSAL_MAX_PATH_LEN))
                {
                  mysql_free_result(res);
                  RollbackTransaction(p_conn);
                  ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0);
                }
              p_paths[i_path].path[tmp_len] = '/';
              strcpy(&p_paths[i_path].path[tmp_len + 1], row[0]);
              p_paths[i_path].len += 1 + strlen(row[0]);
            }

          /* insert the object into cache */
          fsal_posixdb_CachePath(p_object_handle, &p_paths[i_path]);

        }

      mysql_free_result(res);
    }

  st = EndTransaction(p_conn);

  if(toomanypaths)
    ReturnCodeDB(ERR_FSAL_POSIXDB_TOOMANYPATHS, 0);
  else
    return st;

 free_res:
  mysql_free_result(res);
 rollback:
  RollbackTransaction(p_conn);
  return st;
}
예제 #13
0
fsal_posixdb_status_t fsal_posixdb_getInfoFromName(fsal_posixdb_conn * p_conn,  /* IN */
                                                   posixfsal_handle_t * p_parent_directory_handle,      /* IN/OUT */
                                                   fsal_name_t * p_objectname,  /* IN */
                                                   fsal_path_t * p_path,        /* OUT */
                                                   posixfsal_handle_t *
                                                   p_handle /* OUT */ )
{
  fsal_posixdb_status_t st;
  char query[2048];
  result_handle_t res;
  MYSQL_ROW row;

  /* sanity check */
  if(!p_conn || !p_handle)
    {
      ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);
    }
  LogFullDebug(COMPONENT_FSAL, "object_name='%s'\n", p_objectname->name ? p_objectname->name : "/");

  BeginTransaction(p_conn);
  /* lookup for the handle of the file */
  if(p_parent_directory_handle && p_parent_directory_handle->data.id)
    {
      snprintf(query, 2048,
               "SELECT Parent.handleid, Parent.handlets, Handle.deviceid, "
               "Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype "
               "FROM Parent INNER JOIN Handle ON Parent.handleid = Handle.handleid AND Parent.handlets=Handle.handlets "
               "WHERE handleidparent=%llu AND handletsparent=%u AND name='%s'",
               p_parent_directory_handle->data.id,
               p_parent_directory_handle->data.ts, p_objectname->name);

      st = db_exec_sql(p_conn, query, &res);
      if(FSAL_POSIXDB_IS_ERROR(st))
        goto rollback;
    }
  else
    {
      /* get root handle: */

      st = db_exec_sql(p_conn,
                       "SELECT Parent.handleid, Parent.handlets, Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype "
                       "FROM Parent INNER JOIN Handle ON Parent.handleid = Handle.handleid AND Parent.handlets=Handle.handlets "
                       "WHERE Parent.handleidparent=Parent.handleid AND Parent.handletsparent=Parent.handlets",
                       &res);
      if(FSAL_POSIXDB_IS_ERROR(st))
        goto rollback;
    }
  /* res contains : Parent.handleid, Parent.handlets, Handle.deviceid, Handle.inode, Handle.nlink, Handle.ctime, Handle.ftype  */

  /* entry not found */
  if((mysql_num_rows(res) != 1) || ((row = mysql_fetch_row(res)) == NULL))
    {
      mysql_free_result(res);
      RollbackTransaction(p_conn);
      ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
    }

  p_handle->data.id = atoll(row[0]);
  p_handle->data.ts = atoi(row[1]);
  posixdb_internal_fillFileinfoFromStrValues(&(p_handle->data.info), row[2], row[3], /* devid, inode */
                                             row[4],    /* nlink */
                                             row[5],    /* ctime */
                                             row[6]);   /* ftype */
  mysql_free_result(res);

  /* Build the path of the object */
  if(p_path && p_objectname)
    {
      /* build the path of the Parent */
      st = fsal_posixdb_buildOnePath(p_conn, p_parent_directory_handle, p_path);
      if(FSAL_POSIXDB_IS_ERROR(st))
        goto rollback;

      /* then concatenate the filename */
      if(!(p_path->len + 1 + p_objectname->len < FSAL_MAX_PATH_LEN))
        {
          RollbackTransaction(p_conn);
          ReturnCodeDB(ERR_FSAL_POSIXDB_PATHTOOLONG, 0);
        }
      p_path->path[p_path->len] = '/';
      strcpy(&p_path->path[p_path->len + 1], p_objectname->name);
      p_path->len += 1 + p_objectname->len;

      /* add the the path to cache */
      fsal_posixdb_CachePath(p_handle, p_path);
    }
  else
    {
      /* update handle if it was in cache */
      fsal_posixdb_UpdateInodeCache(p_handle);
    }

  return EndTransaction(p_conn);

 rollback:
  RollbackTransaction(p_conn);
  return st;
}
예제 #14
0
/**
 * FSAL_opendir :
 *     Opens a directory for reading its content.
 *     
 * \param dir_handle (input)
 *         the handle of the directory to be opened.
 * \param cred (input)
 *         Permission context for the operation (user,...).
 * \param dir_descriptor (output)
 *         pointer to an allocated structure that will receive
 *         directory stream informations, on successfull completion.
 * \param dir_attributes (optional output)
 *         On successfull completion,the structure pointed
 *         by dir_attributes receives the new directory attributes.
 *         May be NULL.
 * 
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t POSIXFSAL_opendir(fsal_handle_t * dir_handle,      /* IN */
                                fsal_op_context_t * context,     /* IN */
                                fsal_dir_t * dir_descriptor,     /* OUT */
                                fsal_attrib_list_t * p_dir_attributes   /* [ IN/OUT ] */
    )
{
  posixfsal_handle_t * p_dir_handle = (posixfsal_handle_t *) dir_handle;
  posixfsal_op_context_t * p_context = (posixfsal_op_context_t *) context;
  posixfsal_dir_t * p_dir_descriptor = (posixfsal_dir_t *) dir_descriptor;
  int rc, errsv;
  fsal_status_t status;

  fsal_path_t fsalpath;
  struct stat buffstat;

  /* sanity checks
   * note : dir_attributes is optionnal.
   */
  if(!p_dir_handle || !p_context || !p_dir_descriptor)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_opendir);

  /* get the path of the directory */
  status =
      fsal_internal_getPathFromHandle(p_context, p_dir_handle, 1, &fsalpath, &buffstat);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_opendir);

  /* Test access rights for this directory */

  status = fsal_internal_testAccess(p_context, FSAL_R_OK, &buffstat, NULL);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_opendir);

  /* if everything is OK, fills the dir_desc structure : */

  TakeTokenFSCall();
  p_dir_descriptor->p_dir = opendir(fsalpath.path);
  ReleaseTokenFSCall();
  if(!p_dir_descriptor->p_dir)
    Return(posix2fsal_error(errno), errno, INDEX_FSAL_opendir);

  memcpy(&(p_dir_descriptor->context), p_context, sizeof(posixfsal_op_context_t));
  memcpy(&(p_dir_descriptor->path), &fsalpath, sizeof(fsal_path_t));
  memcpy(&(p_dir_descriptor->handle), p_dir_handle, sizeof(posixfsal_handle_t));

#ifdef _USE_POSIXDB_READDIR_BLOCK
  p_dir_descriptor->p_dbentries = NULL;
  p_dir_descriptor->dbentries_count = 0;
  /* fill the p_dbentries list */
  statusdb = fsal_posixdb_getChildren(p_dir_descriptor->context.p_conn,
                                      &(p_dir_descriptor->handle),
                                      FSAL_POSIXDB_MAXREADDIRBLOCKSIZE,
                                      &(p_dir_descriptor->p_dbentries),
                                      &(p_dir_descriptor->dbentries_count));
  if(FSAL_POSIXDB_IS_ERROR(statusdb))   /* too many entries in the directory, or another error */
    p_dir_descriptor->dbentries_count = -1;

#endif
  if(p_dir_attributes)
    {

      TakeTokenFSCall();
      rc = lstat(fsalpath.path, &buffstat);
      errsv = errno;
      ReleaseTokenFSCall();
      if(rc)                    /* lstat failed */
        goto attr_err;

      status = posix2fsal_attributes(&buffstat, p_dir_attributes);
      if(FSAL_IS_ERROR(status))
        {
 attr_err:
          FSAL_CLEAR_MASK(p_dir_attributes->asked_attributes);
          FSAL_SET_MASK(p_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }
    }

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_opendir);

}
예제 #15
0
/**
 * FSAL_readdir :
 *     Read the entries of an opened directory.
 *     
 * \param dir_descriptor (input):
 *        Pointer to the directory descriptor filled by FSAL_opendir.
 * \param start_position (input):
 *        Cookie that indicates the first object to be read during
 *        this readdir operation.
 *        This should be :
 *        - FSAL_READDIR_FROM_BEGINNING for reading the content
 *          of the directory from the beginning.
 *        - The end_position parameter returned by the previous
 *          call to FSAL_readdir.
 * \param get_attr_mask (input)
 *        Specify the set of attributes to be retrieved for directory entries.
 * \param buffersize (input)
 *        The size (in bytes) of the buffer where
 *        the direntries are to be stored.
 * \param pdirent (output)
 *        Adresse of the buffer where the direntries are to be stored.
 * \param end_position (output)
 *        Cookie that indicates the current position in the directory.
 * \param nb_entries (output)
 *        Pointer to the number of entries read during the call.
 * \param end_of_dir (output)
 *        Pointer to a boolean that indicates if the end of dir
 *        has been reached during the call.
 * 
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t POSIXFSAL_readdir(fsal_dir_t * dir_descriptor,     /* IN */
                                fsal_cookie_t start_pos,      /* IN */
                                fsal_attrib_mask_t get_attr_mask,       /* IN */
                                fsal_mdsize_t buffersize,       /* IN */
                                fsal_dirent_t * p_pdirent,      /* OUT */
                                fsal_cookie_t * end_position,    /* OUT */
                                fsal_count_t * p_nb_entries,    /* OUT */
                                fsal_boolean_t * p_end_of_dir   /* OUT */
    )
{
  posixfsal_dir_t * p_dir_descriptor = (posixfsal_dir_t *) dir_descriptor;
  posixfsal_cookie_t start_position, telldir_pos;
  posixfsal_cookie_t * p_end_position = (posixfsal_cookie_t *) end_position;
  fsal_status_t st;
  fsal_posixdb_status_t stdb;
  fsal_count_t max_dir_entries;
  struct dirent *dp;
  struct dirent dpe;
  struct stat buffstat;
  fsal_path_t fsalpath;
  fsal_posixdb_fileinfo_t infofs;
  int rc;

  /*****************/
  /* sanity checks */
  /*****************/

  if(!p_dir_descriptor || !p_pdirent || !p_end_position || !p_nb_entries || !p_end_of_dir)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir);

  max_dir_entries = (buffersize / sizeof(fsal_dirent_t));

  /***************************/
  /* seek into the directory */
  /***************************/
  memcpy ( (char *)&start_position.data.cookie, (char *)&start_pos.data, sizeof( off_t ) ) ;

  errno = 0;
  if(start_position.data.cookie == 0)
    {
      rewinddir(p_dir_descriptor->p_dir);
      rc = errno;
    }
  else
    {
      seekdir(p_dir_descriptor->p_dir, start_position.data.cookie);
      rc = errno;
    }

  if(rc)
    {
      st.major = posix2fsal_error(rc);
      st.minor = rc;
      goto readdir_error;
    }

  /************************/
  /* browse the directory */
  /************************/

  *p_nb_entries = 0;
  while(*p_nb_entries < max_dir_entries)
    {
    /***********************/
      /* read the next entry */
    /***********************/
      TakeTokenFSCall();
      rc = readdir_r(p_dir_descriptor->p_dir, &dpe, &dp);
      ReleaseTokenFSCall();
      if(rc)
        {
          st.major = posix2fsal_error(errno);
          st.minor = errno;
          goto readdir_error;
        }                       /* End of directory */
      if(!dp)
        {
          *p_end_of_dir = 1;
          break;
        }

    /***********************************/
      /* Get information about the entry */
    /***********************************/

      /* build the full path of the file into "fsalpath */
      if(FSAL_IS_ERROR
         (st =
          FSAL_str2name(dp->d_name, FSAL_MAX_NAME_LEN, &(p_pdirent[*p_nb_entries].name))))
        goto readdir_error;
      memcpy(&fsalpath, &(p_dir_descriptor->path), sizeof(fsal_path_t));
      st = fsal_internal_appendFSALNameToFSALPath(&fsalpath,
                                                  &(p_pdirent[*p_nb_entries].name));
      if(FSAL_IS_ERROR(st))
        goto readdir_error;

      /* get object info */
      TakeTokenFSCall();
      rc = lstat(fsalpath.path, &buffstat);
      ReleaseTokenFSCall();
      if(rc)
        {
          st.major = posix2fsal_error(errno);
          st.minor = errno;
          goto readdir_error;
        }
      if(FSAL_IS_ERROR(st = fsal_internal_posix2posixdb_fileinfo(&buffstat, &infofs)))
        goto readdir_error;

    /********************/
      /* fills the handle */
    /********************/

      /* check for "." and ".." */
      if(!strcmp(dp->d_name, "."))
        {
          memcpy(&(p_pdirent[*p_nb_entries].handle), &(p_dir_descriptor->handle),
                 sizeof(posixfsal_handle_t));
        }
      else if(!strcmp(dp->d_name, ".."))
        {
          stdb = fsal_posixdb_getParentDirHandle(p_dir_descriptor->context.p_conn,
                                                 &(p_dir_descriptor->handle),
                                                 (posixfsal_handle_t *) &(p_pdirent[*p_nb_entries].handle));
          if(FSAL_POSIXDB_IS_ERROR(stdb) && FSAL_IS_ERROR(st = posixdb2fsal_error(stdb)))
            goto readdir_error;
        }
      else
        {
#ifdef _USE_POSIXDB_READDIR_BLOCK
          if(p_dir_descriptor->dbentries_count > -1)
            {                   /* look for the entry in dbentries */
              st = fsal_internal_getInfoFromChildrenList(&(p_dir_descriptor->context),
                                                         &(p_dir_descriptor->handle),
                                                         &(p_pdirent[*p_nb_entries].name),
                                                         &infofs,
                                                         p_dir_descriptor->p_dbentries,
                                                         p_dir_descriptor->
                                                         dbentries_count,
                                                         &(p_pdirent[*p_nb_entries].
                                                           handle));
            }
          else
#endif
            {                   /* get handle for the entry */
              st = fsal_internal_getInfoFromName(&(p_dir_descriptor->context),
                                                 &(p_dir_descriptor->handle),
                                                 &(p_pdirent[*p_nb_entries].name),
                                                 &infofs,
                                                 (posixfsal_handle_t *) &(p_pdirent[*p_nb_entries].handle));
            }
          if(FSAL_IS_ERROR(st))
            goto readdir_error;
        }                       /* end of name check for "." and ".." */

    /************************
     * Fills the attributes *
     ************************/
      p_pdirent[*p_nb_entries].attributes.asked_attributes = get_attr_mask;
      st = posix2fsal_attributes(&buffstat, &(p_pdirent[*p_nb_entries].attributes));
      if(FSAL_IS_ERROR(st))
        goto readdir_error;

      /*
       * 
       **/
      telldir_pos.data.cookie = telldir(p_dir_descriptor->p_dir);
      memcpy(&p_pdirent[*p_nb_entries].cookie, &telldir_pos, sizeof(fsal_cookie_t));
      p_pdirent[*p_nb_entries].nextentry = NULL;
      if(*p_nb_entries)
        p_pdirent[*p_nb_entries - 1].nextentry = &(p_pdirent[*p_nb_entries]);

      memcpy(p_end_position, &p_pdirent[*p_nb_entries].cookie, sizeof(fsal_cookie_t));
      (*p_nb_entries)++;
    };

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readdir);

  /* return error, and free what must be freed */
 readdir_error:
  Return(st.major, st.minor, INDEX_FSAL_readdir);
}
예제 #16
0
fsal_posixdb_status_t fsal_posixdb_add(fsal_posixdb_conn * p_conn,      /* IN */
                                       fsal_posixdb_fileinfo_t * p_object_info, /* IN */
                                       posixfsal_handle_t * p_parent_directory_handle,  /* IN */
                                       fsal_name_t * p_filename,        /* IN */
                                       posixfsal_handle_t * p_object_handle /* OUT */ )
{
  PGresult *p_res;
  char handleid_str[MAX_HANDLEIDSTR_SIZE];
  char handlets_str[MAX_HANDLETSSTR_SIZE];
  char handleidparent_str[MAX_HANDLEIDSTR_SIZE];
  char handletsparent_str[MAX_HANDLETSSTR_SIZE];
  char devid_str[MAX_DEVICEIDSTR_SIZE];
  char inode_str[MAX_INODESTR_SIZE];
  int found;
  const char *paramValues[6];
  fsal_posixdb_status_t st;

  /*******************
   * 1/ sanity check *
   *******************/

  /* parent_directory and filename are NULL only if it is the root directory */
  if(!p_conn || !p_object_info || !p_object_handle
     || (p_filename && !p_parent_directory_handle) || (!p_filename
                                                       && p_parent_directory_handle))
    ReturnCodeDB(ERR_FSAL_POSIXDB_FAULT, 0);

  CheckConn(p_conn);

  LogFullDebug(COMPONENT_FSAL, "adding entry with parentid=%llu, id=%"PRIu64", name=%s\n",
         p_parent_directory_handle ? p_parent_directory_handle->data.id : 0,
         p_object_info ? p_object_info->inode : 0,
         p_filename ? p_filename->name : "NULL");

  BeginTransaction(p_conn, p_res);

  /*********************************
   * 2/ we check the parent handle *
   *********************************/

  if(p_parent_directory_handle)
    {                           /* the root has no parent */
      snprintf(handleidparent_str, MAX_HANDLEIDSTR_SIZE, "%llu",
               p_parent_directory_handle->data.id);
      snprintf(handletsparent_str, MAX_HANDLETSSTR_SIZE, "%i",
               p_parent_directory_handle->data.ts);
      paramValues[0] = handleidparent_str;
      paramValues[1] = handletsparent_str;
      p_res = PQexecPrepared(p_conn, "lookupHandle", 2, paramValues, NULL, NULL, 0);
      CheckResult(p_res);

      if(PQntuples(p_res) != 1)
        {
          /* parent entry not found */
          RollbackTransaction(p_conn, p_res);
          ReturnCodeDB(ERR_FSAL_POSIXDB_NOENT, 0);
        }
      PQclear(p_res);
    }
  /**********************************************************
   * 3/ Check if there is an existing Handle for the object *
   **********************************************************/
  snprintf(devid_str, MAX_DEVICEIDSTR_SIZE, "%llu",
           (unsigned long long int)p_object_info->devid);
  snprintf(inode_str, MAX_INODESTR_SIZE, "%llu",
           (unsigned long long int)p_object_info->inode);
  paramValues[0] = devid_str;
  paramValues[1] = inode_str;
  p_res = PQexecPrepared(p_conn, "lookupHandleByInodeFU", 2, paramValues, NULL, NULL, 0);
  CheckResult(p_res);
  found = (PQntuples(p_res) == 1);

  if(found)
    {                           /* a Handle (that matches devid & inode) already exists */
      /* fill 'info' with information about the handle in the database */
      posixdb_internal_fillFileinfoFromStrValues(&(p_object_handle->data.info), NULL, NULL, PQgetvalue(p_res, 0, 2), /* nlink */
                                                 PQgetvalue(p_res, 0, 3),       /* ctime */
                                                 PQgetvalue(p_res, 0, 4)        /* ftype */
          );
      p_object_handle->data.info.inode = p_object_info->inode;
      p_object_handle->data.info.devid = p_object_info->devid;
      strncpy(handleid_str, PQgetvalue(p_res, 0, 0), MAX_HANDLEIDSTR_SIZE);
      strncpy(handlets_str, PQgetvalue(p_res, 0, 1), MAX_HANDLETSSTR_SIZE);
      PQclear(p_res);

      p_object_handle->data.id = atoll(handleid_str);
      p_object_handle->data.ts = atoi(handlets_str);

      /* check the consistency of the handle */
      if(fsal_posixdb_consistency_check(&(p_object_handle->data.info), p_object_info))
        {
          /* consistency check failed */
          /* p_object_handle has been filled in order to be able to fix the consistency later */
          RollbackTransaction(p_conn, p_res);
          ReturnCodeDB(ERR_FSAL_POSIXDB_CONSISTENCY, 0);
        }

      /* update nlink & ctime if needed */
      if(p_object_info->nlink != p_object_handle->data.info.nlink
         || p_object_info->ctime != p_object_handle->data.info.ctime)
        {
          char nlink_str[MAX_NLINKSTR_SIZE];
          char ctime_str[MAX_CTIMESTR_SIZE];

          snprintf(nlink_str, MAX_NLINKSTR_SIZE, "%i", p_object_info->nlink);
          snprintf(ctime_str, MAX_CTIMESTR_SIZE, "%i", (int)p_object_info->ctime);
          paramValues[0] = handleid_str;
          paramValues[1] = handlets_str;
          paramValues[2] = nlink_str;
          paramValues[3] = ctime_str;

          p_object_handle->data.info = *p_object_info;

          p_res = PQexecPrepared(p_conn, "updateHandle", 4, paramValues, NULL, NULL, 0);
          CheckCommand(p_res);
        }

      fsal_posixdb_UpdateInodeCache(p_object_handle);

    }
  else
    {                           /* no handle found */
      /* Handle does not exist, add a new Handle entry */
      char nlink_str[MAX_NLINKSTR_SIZE];
      char ctime_str[MAX_CTIMESTR_SIZE];
      char ftype_str[MAX_FTYPESTR_SIZE];
      PQclear(p_res);

      p_object_handle->data.ts = (int)time(NULL);
      p_object_handle->data.info = *p_object_info;
      snprintf(handlets_str, MAX_HANDLETSSTR_SIZE, "%i", p_object_handle->data.ts);
      snprintf(nlink_str, MAX_NLINKSTR_SIZE, "%i", p_object_info->nlink);
      snprintf(ctime_str, MAX_CTIMESTR_SIZE, "%i", (int)p_object_info->ctime);
      snprintf(ftype_str, MAX_CTIMESTR_SIZE, "%i", (int)p_object_info->ftype);

      paramValues[0] = devid_str;
      paramValues[1] = inode_str;
      paramValues[2] = handlets_str;
      paramValues[3] = nlink_str;
      paramValues[4] = ctime_str;
      paramValues[5] = ftype_str;

      p_res = PQexecPrepared(p_conn, "insertHandle", 6, paramValues, NULL, NULL, 0);
      CheckCommand(p_res);

      PQclear(p_res);

      p_res =
          PQexecPrepared(p_conn, "lookupHandleByInodeFU", 2, paramValues, NULL, NULL, 0);
      CheckResult(p_res);

      strncpy(handleid_str, PQgetvalue(p_res, 0, 0), MAX_HANDLEIDSTR_SIZE);
      strncpy(handlets_str, PQgetvalue(p_res, 0, 1), MAX_HANDLETSSTR_SIZE);
      p_object_handle->data.id = atoll(PQgetvalue(p_res, 0, 0));
      PQclear(p_res);

      /* now, we have the handle id */
      fsal_posixdb_UpdateInodeCache(p_object_handle);

    }

  /************************************************
   * add (or update) an entry in the Parent table *
   ************************************************/
  paramValues[0] = p_parent_directory_handle ? handleidparent_str : handleid_str;
  paramValues[1] = p_parent_directory_handle ? handletsparent_str : handlets_str;
  paramValues[2] = p_filename ? p_filename->name : "";
  p_res = PQexecPrepared(p_conn, "lookupParent", 3, paramValues, NULL, NULL, 0);
  CheckResult(p_res);
  /* p-res contains handleid & handlets */
  found = (PQntuples(p_res) == 1);
  paramValues[3] = handleid_str;
  paramValues[4] = handlets_str;
  if(found)
    {
      /* update the Parent entry if necessary (there entry exists with another handle) */
      if((fsal_u64_t) atoll(PQgetvalue(p_res, 0, 0)) != p_object_handle->data.id
         || atoi(PQgetvalue(p_res, 0, 1)) != p_object_handle->data.ts)
        {
          /* steps :
             - check the nlink value of the Parent entry to be overwritten
             - if nlink = 1, then we can delete the handle.
             else we have to update it (nlink--) : that is done by fsal_posixdb_deleteParent
             - update the handle of the entry
           */
          char bad_handleid_str[MAX_HANDLEIDSTR_SIZE];
          char bad_handlets_str[MAX_HANDLETSSTR_SIZE];
          int nlink;

          strncpy(bad_handleid_str, PQgetvalue(p_res, 0, 0), MAX_HANDLEIDSTR_SIZE);
          strncpy(bad_handlets_str, PQgetvalue(p_res, 0, 1), MAX_HANDLETSSTR_SIZE);
          PQclear(p_res);       /* clear old res before a new query */

          /* check the nlink value of the entry to be updated */
          paramValues[0] = handleidparent_str;
          paramValues[1] = handletsparent_str;
          p_res = PQexecPrepared(p_conn, "lookupHandleFU", 2, paramValues, NULL, NULL, 0);
          CheckResult(p_res);

          found = (PQntuples(p_res) == 1);

          if(found)
            {                   /* we have retrieved the handle information of the bad entry */
              nlink = atoi(PQgetvalue(p_res, 0, 4));
              PQclear(p_res);   /* clear old res before a new query */

              /* a Parent entry already exists, we delete it */

              st = fsal_posixdb_deleteParent(p_conn, bad_handleid_str, bad_handlets_str,
                                             p_parent_directory_handle ?
                                             handleidparent_str : handleid_str,
                                             p_parent_directory_handle ?
                                             handletsparent_str : handlets_str,
                                             p_filename ? p_filename->name : "", nlink);
              if(FSAL_POSIXDB_IS_ERROR(st))
                {
                  RollbackTransaction(p_conn, p_res);
                  return st;
                }
            }
          else
            {                   /* the Handle line has been deleted */
              PQclear(p_res);   /* clear old res before a new query */
            }

          /* the bad entry has been deleted. Now we had a new Parent entry */
          goto add_new_parent_entry;

        }
      else
        {
          /* a Parent entry exists with our handle, nothing to do */
          PQclear(p_res);
        }
    }
  else
    {
      /* add a Parent entry */
      PQclear(p_res);
 add_new_parent_entry:
      paramValues[0] = p_parent_directory_handle ? handleidparent_str : handleid_str;
      paramValues[1] = p_parent_directory_handle ? handletsparent_str : handlets_str;
      paramValues[2] = p_filename ? p_filename->name : "";
      paramValues[3] = handleid_str;
      paramValues[4] = handlets_str;

      p_res = PQexecPrepared(p_conn, "insertParent", 5, paramValues, NULL, NULL, 0);
      CheckCommand(p_res);
      PQclear(p_res);
      /* XXX : is it possible to have unique key violation ? */
    }

  EndTransaction(p_conn, p_res);

  ReturnCodeDB(ERR_FSAL_POSIXDB_NOERR, 0);
}
예제 #17
0
int main(int argc, char **argv)
{
  fsal_posixdb_conn_params_t dbparams;
  char exec_name[MAXPATHLEN];
  char c, op = 0;
  fsal_posixdb_conn *p_conn;
  fsal_posixdb_status_t statusdb;
  char path[MAXPATHLEN];
  int rc;

  char options[] = "h@H:P:L:D:K:";
  char usage[] =
      "Usage: %s [-h][-H <host>][-P <port>][-L <login>][-D <dbname>][-K <passwd file>] operation operation_parameters\n"
      "\t[-h]               display this help\n"
      "\t[-H <host>]        Database host\n"
      "\t[-P <port>]        Database port\n"
      "\t[-L <login>]       Database login\n"
      "\t[-D <dbname>]      Name of the database\n"
      "\t[-K <passwd file>] Path of the file where is stored the password\n"
      "------------- Default Values -------------\n"
      "host        : localhost\n"
      "port        : default DB port\n"
      "dbname      : posixdb\n"
      "login       : current unix user\n"
      "passwd file : default path ($PGPASSFILE)\n"
      "------------- Operations -----------------\n"
      "test_connection       : try to connect to the database\n"
      "empty_database        : Delete all entries in the database\n"
      "find                  : Print the entries of the database (as 'find' would do it)\n"
      "populate <path>       : Add (recursively) the object in <path> into the database\n\n";

  memset(&dbparams, 0, sizeof(fsal_posixdb_conn_params_t));
  strcpy(dbparams.host, "localhost");
  strcpy(dbparams.dbname, "posixdb");

  /* What is the executable file's name */
  if(*exec_name == '\0')
    strcpy((char *)exec_name, basename(argv[0]));

  /* now parsing options with getopt */
  while((c = getopt(argc, argv, options)) != EOF)
    {
      switch (c)
        {
        case '@':
          /* A litlle backdoor to keep track of binary versions */
          printf("%s compiled on %s at %s\n", exec_name, __DATE__, __TIME__);
          exit(0);
          break;
        case 'H':
          strncpy(dbparams.host, optarg, FSAL_MAX_DBHOST_NAME_LEN);
          break;
        case 'P':
          strncpy(dbparams.port, optarg, FSAL_MAX_DBPORT_STR_LEN);
          break;
        case 'L':
          strncpy(dbparams.login, optarg, FSAL_MAX_DB_LOGIN_LEN);
          break;
        case 'D':
          strncpy(dbparams.dbname, optarg, FSAL_MAX_DB_NAME_LEN);
          break;
        case 'K':
          strncpy(dbparams.passwdfile, optarg, PATH_MAX);
          break;
        default:
          /* display the help */
          fprintf(stderr, usage, exec_name);
          exit(0);
          break;
        }
    }

  if(optind == argc)
    {
      fprintf(stderr, "No operation specified.\n");
      fprintf(stderr, usage, exec_name);
      exit(0);
    }
  if(optind < argc)
    {
      if(!strcmp(argv[optind], "test_connection"))
        {
          op = OP_TESTCONN;
        }
      else if(!strcmp(argv[optind], "empty_database"))
        {
          op = OP_EMPTYDB;
        }
      else if(!strcmp(argv[optind], "find"))
        {
          op = OP_FIND;
        }
      else if(!strcmp(argv[optind], "populate"))
        {
          op = OP_POPULATE;
          optind++;
          if(optind < argc)
            {
              strncpy(path, argv[optind], MAXPATHLEN);
            }
          else
            {
              fputs("Operation 'populate' need a parameter", stderr);
              fprintf(stderr, usage, exec_name);
              exit(-1);
            }
        }
      else
        {
          fprintf(stderr, "Unknown operation : %s\n", argv[optind]);
          fprintf(stderr, usage, exec_name);
          exit(-1);
        }
    }

  /* Connecting to database */
  if(*(dbparams.passwdfile) != '\0')
    {
      rc = setenv("PGPASSFILE", dbparams.passwdfile, 1);
      if(rc != 0)
        fputs("Could not set POSTGRESQL keytab path.", stderr);
    }

  fprintf(stderr, "Opening database connection to %s...\n", dbparams.host);
  statusdb = fsal_posixdb_connect(&dbparams, &p_conn);
  if(FSAL_POSIXDB_IS_ERROR(statusdb))
    {
      fprintf(stderr, "Error %i. exiting.\n", statusdb.minor);
      exit(-1);
    }
  else
    {
      fprintf(stderr, "Connected.\n");
    }

  /* Execute the operation */
  switch (op)
    {
    case OP_TESTCONN:
      /* nothing to do */
      break;
    case OP_EMPTYDB:
      emptydb(p_conn);
      break;
    case OP_FIND:
      find(p_conn);
      break;
    case OP_POPULATE:
      populatedb(p_conn, path);
      break;
    default:
      puts("Bad operation !!");
      fprintf(stderr, usage, exec_name);
    }

  fsal_posixdb_disconnect(p_conn);

  exit(0);
}
예제 #18
0
/**
 * Get a valid path associated to an handle.
 * The function selects many paths from the DB and return the first valid one. If is_dir is set, then only 1 path will be constructed from the database.
 */
fsal_status_t fsal_internal_getPathFromHandle(posixfsal_op_context_t * p_context,       /* IN */
                                              posixfsal_handle_t * p_handle,    /* IN */
                                              int is_dir,       /* IN */
                                              fsal_path_t * p_fsalpath, /* OUT */
                                              struct stat *p_buffstat /* OUT */ )
{
  fsal_status_t status;
  fsal_posixdb_status_t statusdb;
  int rc, errsv, count, i;
  fsal_posixdb_fileinfo_t infofs;
  fsal_path_t paths[global_fs_info.maxlink];

  if(!p_context || !p_handle || !p_fsalpath)
    ReturnCode(ERR_FSAL_FAULT, 0);

  /* if there is a path in the posixfsal_handle_t variable, then try to use it instead of querying the database for it */
  /* Read the path from the Handle. If it's valid & coherent, then no need to query the database ! */
  /* if !p_buffstat, we don't need to check the path */
  statusdb = fsal_posixdb_getInfoFromHandle(p_context->p_conn,
                                            p_handle,
                                            paths,
                                            (is_dir ? 1 : global_fs_info.maxlink),
                                            &count);
  if(FSAL_POSIXDB_IS_ERROR(statusdb)
     && FSAL_IS_ERROR(status = posixdb2fsal_error(statusdb)))
    return status;

  /* if !p_buffstat, then we do not stat the path to test if file is valid */
  if(p_buffstat)
    {
      for(i = 0; i < count; i++)
        {
          TakeTokenFSCall();
          rc = lstat(paths[i].path, p_buffstat);
          errsv = errno;
          ReleaseTokenFSCall();

          if(rc)
            {
              /* error : delete the bad path from the database */
              char dirc[FSAL_MAX_PATH_LEN];
              char basec[FSAL_MAX_PATH_LEN];
              fsal_path_t parentdir;
              fsal_name_t filename;
              posixfsal_handle_t parenthdl;
              char *dname, *bname;

              /* split /path/to/filename in /path/to & filename */
              strncpy(dirc, paths[i].path, FSAL_MAX_PATH_LEN);
              strncpy(basec, paths[i].path, FSAL_MAX_PATH_LEN);
              dname = dirname(dirc);
              bname = basename(basec);

              status = FSAL_str2path(dname, FSAL_MAX_PATH_LEN, &parentdir);
              status = FSAL_str2name(bname, FSAL_MAX_NAME_LEN, &filename);

              /* get the handle of /path/to */
              status = POSIXFSAL_lookupPath(&parentdir, p_context, &parenthdl, NULL);

              if(!FSAL_IS_ERROR(status))
                {
                  statusdb =
                      fsal_posixdb_delete(p_context->p_conn, &parenthdl, &filename, NULL);
                  /* no need to check if there was an error, because it doesn't change the behavior of the function */
                }

            }
          else
            {                   /* no error */
              FSAL_pathcpy(p_fsalpath, &(paths[0]));
              break;
            }
        }
      if(i == count)
        ReturnCode(ERR_FSAL_STALE, 0);

      /* check consistency */
      status = fsal_internal_posix2posixdb_fileinfo(p_buffstat, &infofs);
      if(FSAL_IS_ERROR(status))
        return status;

      if(fsal_posixdb_consistency_check(&(p_handle->data.info), &infofs))
        {
          /* not consistent !! */
          /* delete the stale handle */
          statusdb = fsal_posixdb_deleteHandle(p_context->p_conn, p_handle);
          if(FSAL_POSIXDB_IS_ERROR(statusdb)
             && FSAL_IS_ERROR(status = posixdb2fsal_error(statusdb)))
            return status;

          ReturnCode(ERR_FSAL_STALE, 0);
        }

    }
  else
    {
      /* @TODO : check that there si at liste 1 path */
      FSAL_pathcpy(p_fsalpath, &(paths[0]));
    }

  ReturnCode(ERR_FSAL_NO_ERROR, 0);
}
예제 #19
0
/** 
 * @brief Get the handle of a file from a fsal_posixdb_child array, knowing its name
 * 
 * @param p_context 
 * @param p_parent_dir_handle 
 *    Handle of the parent directory
 * @param p_fsalname 
 *    Name of the object
 * @param p_infofs
 *    Information about the file (taken from the filesystem) to be compared to information stored in database
 * @param p_children
 *    fsal_posixdb_child array (that contains the entries of the directory stored in the db)
 * @param p_object_handle 
 *    Handle of the file.
 * 
 * @return
 *    ERR_FSAL_NOERR, if no error
 *    Anothere error code else.
 */
fsal_status_t fsal_internal_getInfoFromChildrenList(posixfsal_op_context_t * p_context, /* IN */
                                                    posixfsal_handle_t * p_parent_dir_handle,   /* IN */
                                                    fsal_name_t * p_fsalname,   /* IN */
                                                    fsal_posixdb_fileinfo_t * p_infofs, /* IN */
                                                    fsal_posixdb_child * p_children,    /* IN */
                                                    unsigned int children_count,        /* IN */
                                                    posixfsal_handle_t * p_object_handle)       /* OUT */
{
  fsal_posixdb_status_t stdb;
  fsal_status_t st;
  int cmp = -1;                 /* when no children is available */
  unsigned int count;

  /* sanity check */
  if(!p_context || !p_parent_dir_handle || !p_fsalname || (!p_children && children_count)
     || !p_object_handle)
    ReturnCode(ERR_FSAL_FAULT, 0);

  /* check if the filename is in the list */
  for(count = 0; count < children_count; count++)
    {
      cmp = FSAL_namecmp(p_fsalname, &(p_children[count].name));
      if(!cmp)
        break;
      /* maybe a sorted list could give better result */
    }

  switch (cmp)
    {
    case 0:
      /* Entry found : check consistency */

      if(fsal_posixdb_consistency_check(&(p_children[count].handle.data.info), p_infofs))
        {
          /* Entry not consistent */
          /* Delete the Handle entry, then add a new one (with a Parent entry) */
          stdb =
              fsal_posixdb_deleteHandle(p_context->p_conn, &(p_children[count].handle));

          if(FSAL_POSIXDB_IS_ERROR(stdb) && FSAL_IS_ERROR(st = posixdb2fsal_error(stdb)))
            return st;

          /* don't break, add a new entry */

        }
      else
        {
          memcpy(p_object_handle, &(p_children[count].handle),
                 sizeof(posixfsal_handle_t));
          break;
        }

    default:
      /* not found ! Add it */
      st = fsal_internal_posixdb_add_entry(p_context->p_conn,
                                           p_fsalname,
                                           p_infofs,
                                           p_parent_dir_handle, p_object_handle);
      if(FSAL_IS_ERROR(st))
        return st;
    }

  ReturnCode(ERR_FSAL_NO_ERROR, 0);
}