Allow configuration for temporary files directory

This commit is contained in:
Carsten Grohmann 2021-06-13 20:45:56 +02:00 committed by Andrew Gaul
parent a100be9dce
commit d67b83e671
7 changed files with 90 additions and 36 deletions

View File

@ -37,7 +37,6 @@ cppcheck:
-D HAVE_SYS_EXTATTR_H \
-D HAVE_MALLOC_TRIM \
-U CURLE_PEER_FAILED_VERIFICATION \
-U P_tmpdir \
-U ENOATTR \
--enable=warning,style,information,missingInclude \
--suppress=missingIncludeSystem \

View File

@ -70,6 +70,9 @@ see https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl
\fB\-o\fR retries (default="5")
number of times to retry a failed S3 transaction.
.TP
\fB\-o\fR tmpdir (default="/tmp")
local folder for temporary files.
.TP
\fB\-o\fR use_cache (default="" which means disabled)
local folder to use for local file cache.
.TP

View File

@ -34,20 +34,6 @@
#include "string_util.h"
#include "autolock.h"
//------------------------------------------------
// Symbols
//------------------------------------------------
#define TMPFILE_FOR_CHECK_HOLE "/tmp/.s3fs_hole_check.tmp"
//
// For cache directory top path
//
#if defined(P_tmpdir)
#define TMPFILE_DIR_0PATH P_tmpdir
#else
#define TMPFILE_DIR_0PATH "/tmp"
#endif
//
// The following symbols are used by FdManager::RawCheckAllCache().
//
@ -99,6 +85,7 @@ off_t FdManager::free_disk_space = 0;
std::string FdManager::check_cache_output;
bool FdManager::checked_lseek(false);
bool FdManager::have_lseek_hole(false);
std::string FdManager::tmp_dir = "/tmp";
//------------------------------------------------
// FdManager class methods
@ -250,17 +237,7 @@ bool FdManager::CheckCacheDirExist()
if(FdManager::cache_dir.empty()){
return true;
}
// check the directory
struct stat st;
if(0 != stat(cache_dir.c_str(), &st)){
S3FS_PRN_ERR("could not access to cache directory(%s) by errno(%d).", cache_dir.c_str(), errno);
return false;
}
if(!S_ISDIR(st.st_mode)){
S3FS_PRN_ERR("the cache directory(%s) is not directory.", cache_dir.c_str());
return false;
}
return true;
return IsDir(&cache_dir);
}
off_t FdManager::GetEnsureFreeDiskSpace()
@ -288,7 +265,7 @@ off_t FdManager::GetFreeDiskSpace(const char* path)
ctoppath += "/";
}
}else{
ctoppath = TMPFILE_DIR_0PATH "/";
ctoppath = tmp_dir + "/";
}
if(path && '\0' != *path){
ctoppath += path;
@ -314,10 +291,14 @@ bool FdManager::HaveLseekHole()
return FdManager::have_lseek_hole;
}
// create tempolary file
int fd;
if(-1 == (fd = open(TMPFILE_FOR_CHECK_HOLE, O_CREAT|O_RDWR, 0600))){
S3FS_PRN_ERR("failed to open tempolary file(%s) - errno(%d)", TMPFILE_FOR_CHECK_HOLE, errno);
// create temporary file
FILE* ptmpfp;
int fd;
if(NULL == (ptmpfp = MakeTempFile()) || -1 == (fd = fileno(ptmpfp))){
S3FS_PRN_ERR("failed to open temporary file by errno(%d)", errno);
if(ptmpfp){
fclose(ptmpfp);
}
FdManager::checked_lseek = true;
FdManager::have_lseek_hole = false;
return FdManager::have_lseek_hole;
@ -338,13 +319,64 @@ bool FdManager::HaveLseekHole()
}
}
close(fd);
unlink(TMPFILE_FOR_CHECK_HOLE);
FdManager::checked_lseek = true;
FdManager::have_lseek_hole = result;
return FdManager::have_lseek_hole;
}
bool FdManager::SetTmpDir(const char *dir)
{
if(!dir || '\0' == dir[0]){
tmp_dir = "/tmp";
}else{
tmp_dir = dir;
}
return true;
}
bool FdManager::IsDir(const std::string* dir)
{
// check the directory
struct stat st;
if(0 != stat(dir->c_str(), &st)){
S3FS_PRN_ERR("could not stat() directory %s by errno(%d).", dir->c_str(), errno);
return false;
}
if(!S_ISDIR(st.st_mode)){
S3FS_PRN_ERR("the directory %s is not a directory.", dir->c_str());
return false;
}
return true;
}
bool FdManager::CheckTmpDirExist()
{
if(FdManager::tmp_dir.empty()){
return true;
}
return IsDir(&tmp_dir);
}
FILE* FdManager::MakeTempFile() {
int fd;
char cfn[PATH_MAX];
std::string fn = tmp_dir + "/s3fstmp.XXXXXX";
strncpy(cfn, fn.c_str(), sizeof(cfn) - 1);
cfn[sizeof(cfn) - 1] = '\0';
fd = mkstemp(cfn);
if (-1 == fd) {
S3FS_PRN_ERR("failed to create tmp file. errno(%d)", errno);
return NULL;
}
if (-1 == unlink(cfn)) {
S3FS_PRN_ERR("failed to delete tmp file. errno(%d)", errno);
return NULL;
}
return fdopen(fd, "rb+");
}
bool FdManager::HasOpenEntityFd(const char* path)
{
AutoLock auto_lock(&FdManager::fd_manager_lock);

View File

@ -40,6 +40,7 @@ class FdManager
static std::string check_cache_output;
static bool checked_lseek;
static bool have_lseek_hole;
static std::string tmp_dir;
fdent_map_t fent;
@ -47,6 +48,7 @@ class FdManager
static off_t GetFreeDiskSpace(const char* path);
void CleanupCacheDirInternal(const std::string &path = "");
bool RawCheckAllCache(FILE* fp, const char* cache_stat_top_dir, const char* sub_path, int& total_file_cnt, int& err_file_cnt, int& err_dir_cnt);
static bool IsDir(const std::string* dir);
public:
FdManager();
@ -74,6 +76,9 @@ class FdManager
static void FreeReservedDiskSpace(off_t size);
static bool ReserveDiskSpace(off_t size);
static bool HaveLseekHole();
static bool SetTmpDir(const char* dir);
static bool CheckTmpDirExist();
static FILE* MakeTempFile();
// Return FdEntity associated with path, returning NULL on error. This operation increments the reference count; callers must decrement via Close after use.
FdEntity* GetFdEntity(const char* path, int& existfd, bool newfd = true, bool lock_already_held = false);

View File

@ -562,8 +562,8 @@ int FdEntity::Open(headers_t* pmeta, off_t size, time_t time, int flags, AutoLoc
inode = 0;
// open temporary file
if(NULL == (pfile = tmpfile()) || -1 ==(physical_fd = fileno(pfile))){
S3FS_PRN_ERR("failed to open tmp file. err(%d)", errno);
if(NULL == (pfile = FdManager::MakeTempFile()) || -1 ==(physical_fd = fileno(pfile))){
S3FS_PRN_ERR("failed to open temporary file by errno(%d)", errno);
if(pfile){
fclose(pfile);
pfile = NULL;
@ -1088,8 +1088,8 @@ int FdEntity::NoCacheLoadAndPost(PseudoFdInfo* pseudo_obj, off_t start, off_t si
// open temporary file
FILE* ptmpfp;
int tmpfd;
if(NULL == (ptmpfp = tmpfile()) || -1 ==(tmpfd = fileno(ptmpfp))){
S3FS_PRN_ERR("failed to open tmp file. err(%d)", errno);
if(NULL == (ptmpfp = FdManager::MakeTempFile()) || -1 ==(tmpfd = fileno(ptmpfp))){
S3FS_PRN_ERR("failed to open temporary file by errno(%d)", errno);
if(ptmpfp){
fclose(ptmpfp);
}

View File

@ -4250,6 +4250,10 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
S3fsCurl::SetRetries(static_cast<int>(retries));
return 0;
}
if(is_prefix(arg, "tmpdir=")){
FdManager::SetTmpDir(strchr(arg, '=') + sizeof(char));
return 0;
}
if(is_prefix(arg, "use_cache=")){
FdManager::SetCacheDir(strchr(arg, '=') + sizeof(char));
return 0;
@ -5099,6 +5103,14 @@ int main(int argc, char* argv[])
// like checking for appropriate lengths and characters
}
// check tmp dir permission
if(!FdManager::CheckTmpDirExist()){
S3FS_PRN_EXIT("temporary directory doesn't exists.");
S3fsCurl::DestroyS3fsCurl();
s3fs_destroy_global_ssl();
exit(EXIT_FAILURE);
}
// check cache dir permission
if(!FdManager::CheckCacheDirExist() || !FdManager::CheckCacheTopDir() || !CacheFileStat::CheckCacheFileStatTopDir()){
S3FS_PRN_EXIT("could not allow cache directory permission, check permission of cache directories.");

View File

@ -70,6 +70,9 @@ static const char help_string[] =
" retries (default=\"5\")\n"
" - number of times to retry a failed S3 transaction\n"
"\n"
" tmpdir (default=\"/tmp\")\n"
" - local folder for temporary files.\n"
"\n"
" use_cache (default=\"\" which means disabled)\n"
" - local folder to use for local file cache\n"
"\n"