From d67b83e671f1749cfdb73e251ddc0eae93e3c881 Mon Sep 17 00:00:00 2001 From: Carsten Grohmann Date: Sun, 13 Jun 2021 20:45:56 +0200 Subject: [PATCH] Allow configuration for temporary files directory --- Makefile.am | 1 - doc/man/s3fs.1 | 3 ++ src/fdcache.cpp | 94 ++++++++++++++++++++++++++++-------------- src/fdcache.h | 5 +++ src/fdcache_entity.cpp | 8 ++-- src/s3fs.cpp | 12 ++++++ src/s3fs_help.cpp | 3 ++ 7 files changed, 90 insertions(+), 36 deletions(-) diff --git a/Makefile.am b/Makefile.am index 3877d0b..ebea5ea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 \ diff --git a/doc/man/s3fs.1 b/doc/man/s3fs.1 index 2d840fe..b796693 100644 --- a/doc/man/s3fs.1 +++ b/doc/man/s3fs.1 @@ -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 diff --git a/src/fdcache.cpp b/src/fdcache.cpp index 4f93145..83a18b4 100644 --- a/src/fdcache.cpp +++ b/src/fdcache.cpp @@ -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); diff --git a/src/fdcache.h b/src/fdcache.h index 7393556..a5adbd1 100644 --- a/src/fdcache.h +++ b/src/fdcache.h @@ -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); diff --git a/src/fdcache_entity.cpp b/src/fdcache_entity.cpp index 4c5150f..38ac1c3 100644 --- a/src/fdcache_entity.cpp +++ b/src/fdcache_entity.cpp @@ -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); } diff --git a/src/s3fs.cpp b/src/s3fs.cpp index 8faa5a9..c3678ec 100644 --- a/src/s3fs.cpp +++ b/src/s3fs.cpp @@ -4250,6 +4250,10 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar S3fsCurl::SetRetries(static_cast(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."); diff --git a/src/s3fs_help.cpp b/src/s3fs_help.cpp index 01ca1de..757f4e4 100644 --- a/src/s3fs_help.cpp +++ b/src/s3fs_help.cpp @@ -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"