forked from andy/lizardfs
mount: Added support for mounting with mount instead of using mfsmount directly
This commit adds support for new mount scheme that is compliant with other, non-LizardFS mounts. Instead of specifying master hostname, port and subfolder in mount options, it is now possible to specify them as mount user would probably expect, that is e.g.: `mfsmount lizardfs-master:9421:/ /mnt/lizardf` instead of `mfsmount -o mfssubfolder=/ -o mfsmaster=lizardfs-master -o mfsport=9421 /mnt/lizardfs`. New mount scheme applies both to /etc/fstab and CLI. Old scheme is still supported for backward compability. Fixes #822 Change-Id: Icb7bd6455e6c98493418bfd02602cea2dcc5f6ce
This commit is contained in:
parent
5adf40470f
commit
32e8d297f6
@ -16,32 +16,36 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
|
||||
)
|
||||
endif()
|
||||
|
||||
set(DEFAULT_USER "mfs" CACHE STRING "Default user to run daemons as")
|
||||
set(DEFAULT_GROUP "mfs" CACHE STRING "Default group to run daemons as")
|
||||
set(LIZARDFS_BLOCKS_IN_CHUNK 1024 CACHE INT "Number of blocks in one chunk")
|
||||
set(LIZARDFS_BLOCK_SIZE 65536 CACHE INT "Number of bytes in one block")
|
||||
option(ENABLE_WERROR "Enable treating compilation warnings as errors" OFF)
|
||||
option(ENABLE_LIGHTMFS "Enable light version of LizardFS" OFF)
|
||||
option(ENABLE_DEBIAN_PATHS "Enable Debian-style install paths" OFF)
|
||||
option(ENABLE_UTILS "Enable building additional binaries used e.g. in tests" OFF)
|
||||
option(ENABLE_TESTS "Enable building unit and functional tests" OFF)
|
||||
option(ENABLE_DOCS "Enable building the documentation" ON)
|
||||
option(ENABLE_EXIT_ON_USR1 "Enable handler for SIGUSR1 which calls exit()" OFF)
|
||||
option(THROW_INSTEAD_OF_ABORT "Throw std::exception instead of calling abort" OFF)
|
||||
option(ENABLE_DEBUG_LOG "Enable prefix based debug logs" OFF)
|
||||
option(ENABLE_URAFT "Enable installation of uraft util" ON)
|
||||
option(ENABLE_VERBOSE_ASCIIDOC "Enable verbose output of asciidoc" OFF)
|
||||
option(ENABLE_TCMALLOC "Enable use of tcmalloc-minimal library" OFF)
|
||||
option(ENABLE_POLONAISE "Enable polonaise" ON)
|
||||
option(ENABLE_CLIENT_LIB "Enable dynamic client library (liblizardfs-client)" OFF)
|
||||
option(ENABLE_OFFICIAL_BUILD "Make the build official" OFF)
|
||||
option(SET_RC_BUILD_NUMBER "Sets optional -rcN build suffix" OFF)
|
||||
set(DEFAULT_USER "mfs" CACHE STRING "Default user to run daemons as")
|
||||
set(DEFAULT_GROUP "mfs" CACHE STRING "Default group to run daemons as")
|
||||
set(DEFAULT_MASTER_HOSTNAME "mfsmaster" CACHE STRING "Default master server hostname")
|
||||
set(DEFAULT_MASTER_PORT "9421" CACHE STRING "Default master server port number")
|
||||
set(DEFAULT_MOUNTED_SUBFOLDER "/" CACHE STRING "Default subfolder to be mounted")
|
||||
set(DEFAULT_MSFMOUNT_CONFIG_PATH "${ETC_PATH}/mfsmount.cfg" CACHE STRING "Default full path to mfsmount configuration file")
|
||||
set(LIZARDFS_BLOCKS_IN_CHUNK 1024 CACHE INT "Number of blocks in one chunk")
|
||||
set(LIZARDFS_BLOCK_SIZE 65536 CACHE INT "Number of bytes in one block")
|
||||
option(ENABLE_WERROR "Enable treating compilation warnings as errors" OFF)
|
||||
option(ENABLE_LIGHTMFS "Enable light version of LizardFS" OFF)
|
||||
option(ENABLE_DEBIAN_PATHS "Enable Debian-style install paths" OFF)
|
||||
option(ENABLE_UTILS "Enable building additional binaries used e.g. in tests" OFF)
|
||||
option(ENABLE_TESTS "Enable building unit and functional tests" OFF)
|
||||
option(ENABLE_DOCS "Enable building the documentation" ON)
|
||||
option(ENABLE_EXIT_ON_USR1 "Enable handler for SIGUSR1 which calls exit()" OFF)
|
||||
option(THROW_INSTEAD_OF_ABORT "Throw std::exception instead of calling abort" OFF)
|
||||
option(ENABLE_DEBUG_LOG "Enable prefix based debug logs" OFF)
|
||||
option(ENABLE_URAFT "Enable installation of uraft util" ON)
|
||||
option(ENABLE_VERBOSE_ASCIIDOC "Enable verbose output of asciidoc" OFF)
|
||||
option(ENABLE_TCMALLOC "Enable use of tcmalloc-minimal library" OFF)
|
||||
option(ENABLE_POLONAISE "Enable polonaise" ON)
|
||||
option(ENABLE_CLIENT_LIB "Enable dynamic client library (liblizardfs-client)" OFF)
|
||||
option(ENABLE_OFFICIAL_BUILD "Make the build official" OFF)
|
||||
option(SET_RC_BUILD_NUMBER "Sets optional -rcN build suffix" OFF)
|
||||
# end of LizardFS options
|
||||
option(ENABLE_TRACES "Enable traces" OFF)
|
||||
option(ENABLE_CRC "Enable checksums" ON)
|
||||
option(ENABLE_REQUEST_LOG "Enable logging request times" OFF)
|
||||
option(USE_LEGACY_READ_MESSAGES "Enable sending old type of messages by mount" OFF)
|
||||
option(ENABLE_NFS_GANESHA "Enable nfs-ganesha plugin" OFF)
|
||||
option(ENABLE_TRACES "Enable traces" OFF)
|
||||
option(ENABLE_CRC "Enable checksums" ON)
|
||||
option(ENABLE_REQUEST_LOG "Enable logging request times" OFF)
|
||||
option(USE_LEGACY_READ_MESSAGES "Enable sending old type of messages by mount" OFF)
|
||||
option(ENABLE_NFS_GANESHA "Enable nfs-ganesha plugin" OFF)
|
||||
|
||||
message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
|
||||
message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
|
||||
@ -184,9 +188,6 @@ if(ENABLE_DEBIAN_PATHS)
|
||||
set(BIN_SUBDIR "usr/bin")
|
||||
set(SBIN_SUBDIR "usr/sbin")
|
||||
set(LIB_SUBDIR "usr/lib${LIBSUFFIX}")
|
||||
set(ETC_SUBDIR "etc/mfs")
|
||||
set(RUN_SUBDIR "var/run/mfs")
|
||||
set(DATA_SUBDIR "var/lib/mfs")
|
||||
set(MAN_SUBDIR "usr/share/man")
|
||||
set(CGI_SUBDIR "usr/share/mfscgi")
|
||||
set(INCL_SUBDIR "usr/include/lizardfs")
|
||||
@ -194,24 +195,25 @@ else()
|
||||
set(BIN_SUBDIR "bin")
|
||||
set(SBIN_SUBDIR "sbin")
|
||||
set(LIB_SUBDIR "lib${LIBSUFFIX}")
|
||||
set(ETC_SUBDIR "etc/mfs")
|
||||
set(RUN_SUBDIR "var/run/mfs")
|
||||
set(DATA_SUBDIR "var/lib/mfs")
|
||||
set(MAN_SUBDIR "share/man")
|
||||
set(CGI_SUBDIR "share/mfscgi")
|
||||
set(INCL_SUBDIR "include/lizardfs")
|
||||
endif()
|
||||
|
||||
set(ETC_SUBDIR "etc/mfs")
|
||||
set(RUN_SUBDIR "var/run/mfs")
|
||||
set(DATA_SUBDIR "var/lib/mfs")
|
||||
|
||||
string(REGEX REPLACE "/$" "" INSTALL_PREFIX_NO_SLASH ${CMAKE_INSTALL_PREFIX})
|
||||
set(BIN_PATH ${INSTALL_PREFIX_NO_SLASH}/${BIN_SUBDIR})
|
||||
set(SBIN_PATH ${INSTALL_PREFIX_NO_SLASH}/${SBIN_SUBDIR})
|
||||
set(LIB_PATH ${INSTALL_PREFIX_NO_SLASH}/${LIB_SUBDIR})
|
||||
set(ETC_PATH ${INSTALL_PREFIX_NO_SLASH}/${ETC_SUBDIR})
|
||||
set(RUN_PATH ${INSTALL_PREFIX_NO_SLASH}/${RUN_SUBDIR})
|
||||
set(DATA_PATH ${INSTALL_PREFIX_NO_SLASH}/${DATA_SUBDIR})
|
||||
set(MAN_PATH ${INSTALL_PREFIX_NO_SLASH}/${MAN_SUBDIR})
|
||||
set(CGI_PATH ${INSTALL_PREFIX_NO_SLASH}/${CGI_SUBDIR})
|
||||
set(INCL_PATH ${INSTALL_PREFIX_NO_SLASH}/${INCL_SUBDIR})
|
||||
set(ETC_PATH ${INSTALL_PREFIX_NO_SLASH}/${ETC_SUBDIR})
|
||||
set(RUN_PATH ${INSTALL_PREFIX_NO_SLASH}/${RUN_SUBDIR})
|
||||
set(DATA_PATH ${INSTALL_PREFIX_NO_SLASH}/${DATA_SUBDIR})
|
||||
|
||||
if(ENABLE_LIGHTMFS)
|
||||
set(PROTO_BASE 65536)
|
||||
|
@ -14,13 +14,17 @@
|
||||
#define MFSBLOCKSINCHUNK @LIZARDFS_BLOCKS_IN_CHUNK@
|
||||
#define MFSBLOCKSIZE @LIZARDFS_BLOCK_SIZE@
|
||||
|
||||
#define DATA_PATH "@DATA_PATH@"
|
||||
#define ETC_PATH "@ETC_PATH@"
|
||||
#define SBIN_PATH "@SBIN_PATH@"
|
||||
#define LIB_PATH "@LIB_PATH@"
|
||||
#define ETC_PATH "@ETC_PATH@"
|
||||
#define DATA_PATH "@DATA_PATH@"
|
||||
|
||||
#define DEFAULT_USER "@DEFAULT_USER@"
|
||||
#define DEFAULT_GROUP "@DEFAULT_GROUP@"
|
||||
#define DEFAULT_MASTER_HOSTNAME "@DEFAULT_MASTER_HOSTNAME@"
|
||||
#define DEFAULT_MASTER_PORT "@DEFAULT_MASTER_PORT@"
|
||||
#define DEFAULT_MOUNTED_SUBFOLDER "@DEFAULT_MOUNTED_SUBFOLDER@"
|
||||
#define DEFAULT_MSFMOUNT_CONFIG_PATH "@DEFAULT_MSFMOUNT_CONFIG_PATH@"
|
||||
|
||||
#define CHARTS_CSV_CHARTID_BASE @CHARTS_CSV_CHARTID_BASE@
|
||||
|
||||
|
1
debian/lizardfs-client.links
vendored
Normal file
1
debian/lizardfs-client.links
vendored
Normal file
@ -0,0 +1 @@
|
||||
/usr/bin/mfsmount /sbin/mount.lzfs
|
@ -8,7 +8,7 @@ mfsmount - mount Lizard File System
|
||||
== SYNOPSIS
|
||||
|
||||
[verse]
|
||||
*mfsmount* 'mountpoint' [*-d*] [*-f*] [*-s*] [*-m*] [*-n*] [*-p*]
|
||||
*mfsmount* [HOST:[PORT]]:[PATH] [*-d*] [*-f*] [*-s*] [*-m*] [*-n*] [*-p*]
|
||||
[*-H* 'HOST'] [*-P* 'PORT'] [*-S* 'PATH'] [*-o* 'opt'[,'opt']...]
|
||||
|
||||
[verse]
|
||||
@ -262,6 +262,20 @@ Only xfs on Linux works a little different. Beware that there is a strange
|
||||
operation - chown(-1,-1) which is usually converted by a kernel into something
|
||||
like 'chmod ug-s', and therefore can't be controlled by MFS as 'chown'
|
||||
|
||||
== FSTAB
|
||||
|
||||
Since version 3.13 you can define your `/etc/fstab` LizardFS share with new
|
||||
scheme:
|
||||
|
||||
lizardfs-master:/ /mnt/lizardfs lzfs default 0 0
|
||||
|
||||
instead of old fashioned (still supported for backward compatibility):
|
||||
|
||||
mfsmount /mnt/lizardfs fuse mfssubfolder=/,mfsmaster=lizardfs-master 0 0
|
||||
|
||||
This new scheme was implemented to be compliant with scheme introduced by
|
||||
FUSE's author (read more: https://lwn.net/Articles/221779/).
|
||||
|
||||
== REPORTING BUGS
|
||||
|
||||
Report bugs to <contact@lizardfs.org>.
|
||||
|
@ -15,6 +15,5 @@ if(FUSE3_FOUND)
|
||||
target_link_libraries(mfsmount3 mount mfscommon ${FUSE3_LIBRARY})
|
||||
target_include_directories(mfsmount3 PRIVATE ${FUSE3_INCLUDE_DIR})
|
||||
target_compile_definitions(mfsmount3 PRIVATE "-DAPPNAME=mfsmount3" ${FUSE3_CFLAGS_OTHER} "-DFUSE_USE_VERSION=30")
|
||||
|
||||
install(TARGETS mfsmount3 RUNTIME DESTINATION ${BIN_SUBDIR})
|
||||
endif()
|
||||
|
@ -137,7 +137,7 @@ static bool setup_password(std::vector<uint8_t> &md5pass) {
|
||||
memset(gMountOptions.password, 0, strlen(gMountOptions.password));
|
||||
} else if (gMountOptions.md5pass) {
|
||||
int ret = md5_parse(md5pass, gMountOptions.md5pass);
|
||||
if (ret < 0) {
|
||||
if (ret) {
|
||||
fprintf(stderr, "bad md5 definition (md5 should be given as 32 hex digits)\n");
|
||||
return false;
|
||||
}
|
||||
@ -169,9 +169,8 @@ int fuse_mnt_check_empty(const char *mnt, mode_t rootmode, off_t rootsize) {
|
||||
isempty = 0;
|
||||
}
|
||||
|
||||
if (!isempty) {
|
||||
if (!isempty)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -198,9 +197,8 @@ static int mainloop(struct fuse_args *args, const char *mountpoint, bool multith
|
||||
#endif
|
||||
}
|
||||
lzfs::add_log_syslog();
|
||||
if (!foreground) {
|
||||
if (!foreground)
|
||||
lzfs::add_log_stderr(lzfs::log_level::debug);
|
||||
}
|
||||
|
||||
struct rlimit rls;
|
||||
rls.rlim_cur = gMountOptions.nofile;
|
||||
@ -212,27 +210,24 @@ static int mainloop(struct fuse_args *args, const char *mountpoint, bool multith
|
||||
if (gMountOptions.memlock) {
|
||||
rls.rlim_cur = RLIM_INFINITY;
|
||||
rls.rlim_max = RLIM_INFINITY;
|
||||
if (setrlimit(RLIMIT_MEMLOCK, &rls) < 0) {
|
||||
if (setrlimit(RLIMIT_MEMLOCK, &rls))
|
||||
gMountOptions.memlock = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MFS_USE_MEMLOCK
|
||||
if (gMountOptions.memlock) {
|
||||
if (mlockall(MCL_CURRENT | MCL_FUTURE) == 0) {
|
||||
lzfs_pretty_syslog(LOG_NOTICE, "process memory was successfully locked in RAM");
|
||||
}
|
||||
}
|
||||
if (gMountOptions.memlock && !mlockall(MCL_CURRENT | MCL_FUTURE))
|
||||
lzfs_pretty_syslog(LOG_NOTICE, "process memory was "
|
||||
"successfully locked in RAM");
|
||||
#endif
|
||||
|
||||
std::vector<uint8_t> md5pass;
|
||||
if (!setup_password(md5pass)) {
|
||||
return 1;
|
||||
}
|
||||
LizardClient::FsInitParams params(gMountOptions.bindhost ? gMountOptions.bindhost : "",
|
||||
gMountOptions.masterhost, gMountOptions.masterport,
|
||||
mountpoint);
|
||||
LizardClient::FsInitParams params(gMountOptions.bindhost ?
|
||||
gMountOptions.bindhost : "", gMountOptions.masterhost,
|
||||
gMountOptions.masterport, mountpoint);
|
||||
params.verbose = true;
|
||||
params.meta = gMountOptions.meta;
|
||||
params.subfolder = gMountOptions.subfolder;
|
||||
@ -268,7 +263,7 @@ static int mainloop(struct fuse_args *args, const char *mountpoint, bool multith
|
||||
params.acl_cache_size = gMountOptions.aclcachesize;
|
||||
params.debug_mode = gMountOptions.debug;
|
||||
|
||||
if (gMountOptions.meta == 0) {
|
||||
if (!gMountOptions.meta) {
|
||||
LizardClient::fs_init(params);
|
||||
} else {
|
||||
masterproxy_init();
|
||||
@ -285,9 +280,9 @@ static int mainloop(struct fuse_args *args, const char *mountpoint, bool multith
|
||||
|
||||
#if FUSE_VERSION < 30
|
||||
struct fuse_chan *ch = fuse_mount(mountpoint, args);
|
||||
if (ch == NULL) {
|
||||
if (!ch) {
|
||||
fprintf(stderr, "error in fuse_mount\n");
|
||||
if (gMountOptions.meta == 0) {
|
||||
if (!gMountOptions.meta) {
|
||||
LizardClient::fs_term();
|
||||
} else {
|
||||
masterproxy_term();
|
||||
@ -306,7 +301,7 @@ static int mainloop(struct fuse_args *args, const char *mountpoint, bool multith
|
||||
} else {
|
||||
se = fuse_session_new(args, &mfs_oper, sizeof(mfs_oper), (void *)conn_opts);
|
||||
}
|
||||
if (se == NULL) {
|
||||
if (!se) {
|
||||
fprintf(stderr, "error in fuse_session_new\n");
|
||||
#else
|
||||
struct fuse_session *se;
|
||||
@ -316,12 +311,12 @@ static int mainloop(struct fuse_args *args, const char *mountpoint, bool multith
|
||||
} else {
|
||||
se = fuse_lowlevel_new(args, &mfs_oper, sizeof(mfs_oper), NULL);
|
||||
}
|
||||
if (se == NULL) {
|
||||
if (!se) {
|
||||
fuse_unmount(mountpoint, ch);
|
||||
fprintf(stderr, "error in fuse_lowlevel_new\n");
|
||||
#endif
|
||||
usleep(100000); // time for print other error messages by FUSE
|
||||
if (gMountOptions.meta == 0) {
|
||||
if (!gMountOptions.meta) {
|
||||
LizardClient::fs_term();
|
||||
} else {
|
||||
masterproxy_term();
|
||||
@ -331,13 +326,13 @@ static int mainloop(struct fuse_args *args, const char *mountpoint, bool multith
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fuse_set_signal_handlers(se) < 0) {
|
||||
if (fuse_set_signal_handlers(se)) {
|
||||
fprintf(stderr, "error in fuse_set_signal_handlers\n");
|
||||
fuse_session_destroy(se);
|
||||
#if FUSE_VERSION < 30
|
||||
fuse_unmount(mountpoint, ch);
|
||||
#endif
|
||||
if (gMountOptions.meta == 0) {
|
||||
if (!gMountOptions.meta) {
|
||||
LizardClient::fs_term();
|
||||
} else {
|
||||
masterproxy_term();
|
||||
@ -348,11 +343,11 @@ static int mainloop(struct fuse_args *args, const char *mountpoint, bool multith
|
||||
}
|
||||
|
||||
#if FUSE_VERSION >= 30
|
||||
if (fuse_session_mount(se, mountpoint) < 0) {
|
||||
if (fuse_session_mount(se, mountpoint)) {
|
||||
fprintf(stderr, "error in fuse_session_mount\n");
|
||||
fuse_remove_signal_handlers(se);
|
||||
fuse_session_destroy(se);
|
||||
if (gMountOptions.meta == 0) {
|
||||
if (!gMountOptions.meta) {
|
||||
LizardClient::fs_term();
|
||||
} else {
|
||||
masterproxy_term();
|
||||
@ -385,7 +380,7 @@ static int mainloop(struct fuse_args *args, const char *mountpoint, bool multith
|
||||
#if FUSE_VERSION < 30
|
||||
fuse_unmount(mountpoint, ch);
|
||||
#endif
|
||||
if (gMountOptions.meta == 0) {
|
||||
if (!gMountOptions.meta) {
|
||||
LizardClient::fs_term();
|
||||
} else {
|
||||
masterproxy_term();
|
||||
@ -442,150 +437,257 @@ static void make_fsname(struct fuse_args *args) {
|
||||
const char *fmt = libver >= 27 ? "-osubtype=mfs%s,fsname=" : "-ofsname=mfs%s#";
|
||||
l = snprintf(fsnamearg, 256, fmt, (gMountOptions.meta) ? "meta" : "");
|
||||
l += strncpy_commas(fsnamearg + l, 256 - l, gMountOptions.masterhost);
|
||||
if (l < 255) {
|
||||
|
||||
if (l < 255)
|
||||
fsnamearg[l++] = ':';
|
||||
}
|
||||
|
||||
l += strncpy_commas(fsnamearg + l, 256 - l, gMountOptions.masterport);
|
||||
if (gMountOptions.subfolder[0] != '/' && l < 255) {
|
||||
|
||||
if (gMountOptions.subfolder[0] != '/' && l < 255)
|
||||
fsnamearg[l++] = '/';
|
||||
}
|
||||
if (gMountOptions.subfolder[0] != '/' && gMountOptions.subfolder[1] != 0) {
|
||||
|
||||
if (gMountOptions.subfolder[0] != '/' && gMountOptions.subfolder[1] != 0)
|
||||
l += strncpy_commas(fsnamearg + l, 256 - l, gMountOptions.subfolder);
|
||||
}
|
||||
if (l > 255) {
|
||||
|
||||
if (l > 255)
|
||||
l = 255;
|
||||
}
|
||||
|
||||
fsnamearg[l] = 0;
|
||||
fuse_opt_insert_arg(args, 1, fsnamearg);
|
||||
}
|
||||
|
||||
static int is_dns_char(char c) {
|
||||
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
|
||||
(c >= '0' && c <= '9') || c == '-' || c == '.';
|
||||
}
|
||||
|
||||
static size_t count_colons_in_str(const char *str, size_t len) {
|
||||
size_t colons_count = 0;
|
||||
|
||||
for (size_t i = 0; i < len; i++)
|
||||
if (str[i] == ':')
|
||||
colons_count++;
|
||||
|
||||
return colons_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and parse arg that matches to HOST[:PORT]:[PATH] pattern.
|
||||
*/
|
||||
static int read_masterhost_if_present(struct fuse_args *args) {
|
||||
if (args->argc < 2)
|
||||
return 0;
|
||||
|
||||
char *c;
|
||||
int optpos = 1;
|
||||
|
||||
while (optpos < args->argc) {
|
||||
c = args->argv[optpos];
|
||||
|
||||
if (!strncmp(c, "-o", 2))
|
||||
optpos += strlen(c) > 2 ? 1 : 2;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (optpos >= args->argc)
|
||||
return 0;
|
||||
|
||||
size_t colons = count_colons_in_str(c, strlen(c));
|
||||
|
||||
if (!colons)
|
||||
return 0;
|
||||
|
||||
uint32_t hostlen = 0;
|
||||
|
||||
while (is_dns_char(*c)) {
|
||||
c++;
|
||||
hostlen++;
|
||||
}
|
||||
|
||||
if (!hostlen)
|
||||
return 0;
|
||||
|
||||
uint32_t portlen = 0;
|
||||
char *portbegin = NULL;
|
||||
|
||||
if (*c == ':' && colons > 1) {
|
||||
c++;
|
||||
portbegin = c;
|
||||
while (*c >= '0' && *c <= '9') {
|
||||
c++;
|
||||
portlen++;
|
||||
}
|
||||
}
|
||||
|
||||
if (*c != ':')
|
||||
return 0;
|
||||
|
||||
c++;
|
||||
|
||||
if (*c)
|
||||
gMountOptions.subfolder = strdup(c);
|
||||
|
||||
if (!(gMountOptions.masterhost = (char*)malloc(hostlen + 1)))
|
||||
return -1;
|
||||
strncpy(gMountOptions.masterhost, args->argv[optpos], hostlen);
|
||||
|
||||
if (portbegin && portlen) {
|
||||
if (!(gMountOptions.masterport = (char*)malloc(portlen + 1)))
|
||||
return -1;
|
||||
strncpy(gMountOptions.masterport, portbegin, portlen);
|
||||
}
|
||||
|
||||
for (int i = optpos + 1; i < args->argc; i++)
|
||||
args->argv[i - 1] = args->argv[i];
|
||||
|
||||
args->argc--;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) try {
|
||||
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
|
||||
struct fuse_args defaultargs = FUSE_ARGS_INIT(0, NULL);
|
||||
|
||||
fuse_opt_add_arg(&defaultargs, "fakeappname");
|
||||
|
||||
if (fuse_opt_parse(&args, &defaultargs, gMfsOptsStage1, mfs_opt_proc_stage1) < 0) {
|
||||
if (read_masterhost_if_present(&args))
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (gCustomCfg == 0) {
|
||||
mfs_opt_parse_cfg_file(ETC_PATH "/mfsmount.cfg", 1, &defaultargs);
|
||||
}
|
||||
|
||||
if (fuse_opt_parse(&defaultargs, &gMountOptions, gMfsOptsStage2, mfs_opt_proc_stage2) < 0) {
|
||||
if (fuse_opt_parse(&args, &defaultargs, gMfsOptsStage1, mfs_opt_proc_stage1))
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fuse_opt_parse(&args, &gMountOptions, gMfsOptsStage2, mfs_opt_proc_stage2) < 0) {
|
||||
if (!gCustomCfg)
|
||||
mfs_opt_parse_cfg_file(DEFAULT_MSFMOUNT_CONFIG_PATH, 1, &defaultargs);
|
||||
|
||||
if (fuse_opt_parse(&defaultargs, &gMountOptions, gMfsOptsStage2, mfs_opt_proc_stage2))
|
||||
exit(1);
|
||||
|
||||
if (fuse_opt_parse(&args, &gMountOptions, gMfsOptsStage2, mfs_opt_proc_stage2))
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#if FUSE_VERSION >= 30
|
||||
struct fuse_conn_info_opts *conn_opts;
|
||||
conn_opts = fuse_parse_conn_info_opts(&args);
|
||||
if (conn_opts == NULL) {
|
||||
if (!conn_opts) {
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
init_fuse_lowlevel_ops();
|
||||
|
||||
if (gMountOptions.cachemode != NULL && gMountOptions.cachefiles) {
|
||||
if (gMountOptions.cachemode && gMountOptions.cachefiles) {
|
||||
fprintf(stderr,
|
||||
"mfscachemode and mfscachefiles options are exclusive - use only "
|
||||
"mfscachemode\nsee: %s -h for help\n",
|
||||
"mfscachemode and mfscachefiles options are exclusive "
|
||||
"- use only " "mfscachemode\nsee: %s -h for help\n",
|
||||
argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (gMountOptions.cachemode == NULL) {
|
||||
if (!gMountOptions.cachemode) {
|
||||
gMountOptions.keepcache = (gMountOptions.cachefiles) ? 1 : 0;
|
||||
} else if (strcasecmp(gMountOptions.cachemode, "AUTO") == 0) {
|
||||
} else if (!strcasecmp(gMountOptions.cachemode, "AUTO")) {
|
||||
gMountOptions.keepcache = 0;
|
||||
} else if (strcasecmp(gMountOptions.cachemode, "YES") == 0 ||
|
||||
strcasecmp(gMountOptions.cachemode, "ALWAYS") == 0) {
|
||||
} else if (!strcasecmp(gMountOptions.cachemode, "YES") ||
|
||||
!strcasecmp(gMountOptions.cachemode, "ALWAYS")) {
|
||||
gMountOptions.keepcache = 1;
|
||||
} else if (strcasecmp(gMountOptions.cachemode, "NO") == 0 ||
|
||||
strcasecmp(gMountOptions.cachemode, "NONE") == 0 ||
|
||||
strcasecmp(gMountOptions.cachemode, "NEVER") == 0) {
|
||||
} else if (!strcasecmp(gMountOptions.cachemode, "NO") ||
|
||||
!strcasecmp(gMountOptions.cachemode, "NONE") ||
|
||||
!strcasecmp(gMountOptions.cachemode, "NEVER")) {
|
||||
gMountOptions.keepcache = 2;
|
||||
gMountOptions.cacheexpirationtime = 0;
|
||||
} else {
|
||||
fprintf(stderr, "unrecognized cachemode option\nsee: %s -h for help\n", argv[0]);
|
||||
fprintf(stderr, "unrecognized cachemode option\nsee: %s -h "
|
||||
"for help\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if (gMountOptions.sugidclearmodestr == NULL) {
|
||||
if (!gMountOptions.sugidclearmodestr) {
|
||||
gMountOptions.sugidclearmode = LizardClient::FsInitParams::kDefaultSugidClearMode;
|
||||
} else if (strcasecmp(gMountOptions.sugidclearmodestr, "NEVER") == 0) {
|
||||
} else if (!strcasecmp(gMountOptions.sugidclearmodestr, "NEVER")) {
|
||||
gMountOptions.sugidclearmode = SugidClearMode::kNever;
|
||||
} else if (strcasecmp(gMountOptions.sugidclearmodestr, "ALWAYS") == 0) {
|
||||
} else if (!strcasecmp(gMountOptions.sugidclearmodestr, "ALWAYS")) {
|
||||
gMountOptions.sugidclearmode = SugidClearMode::kAlways;
|
||||
} else if (strcasecmp(gMountOptions.sugidclearmodestr, "OSX") == 0) {
|
||||
} else if (!strcasecmp(gMountOptions.sugidclearmodestr, "OSX")) {
|
||||
gMountOptions.sugidclearmode = SugidClearMode::kOsx;
|
||||
} else if (strcasecmp(gMountOptions.sugidclearmodestr, "BSD") == 0) {
|
||||
} else if (!strcasecmp(gMountOptions.sugidclearmodestr, "BSD")) {
|
||||
gMountOptions.sugidclearmode = SugidClearMode::kBsd;
|
||||
} else if (strcasecmp(gMountOptions.sugidclearmodestr, "EXT") == 0) {
|
||||
} else if (!strcasecmp(gMountOptions.sugidclearmodestr, "EXT")) {
|
||||
gMountOptions.sugidclearmode = SugidClearMode::kExt;
|
||||
} else if (strcasecmp(gMountOptions.sugidclearmodestr, "XFS") == 0) {
|
||||
} else if (!strcasecmp(gMountOptions.sugidclearmodestr, "XFS")) {
|
||||
gMountOptions.sugidclearmode = SugidClearMode::kXfs;
|
||||
} else {
|
||||
fprintf(stderr, "unrecognized sugidclearmode option\nsee: %s -h for help\n", argv[0]);
|
||||
fprintf(stderr, "unrecognized sugidclearmode option\nsee: %s "
|
||||
"-h for help\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if (gMountOptions.masterhost == NULL) {
|
||||
gMountOptions.masterhost = strdup("mfsmaster");
|
||||
}
|
||||
if (gMountOptions.masterport == NULL) {
|
||||
gMountOptions.masterport = strdup("9421");
|
||||
}
|
||||
if (gMountOptions.subfolder == NULL) {
|
||||
gMountOptions.subfolder = strdup("/");
|
||||
}
|
||||
if (gMountOptions.nofile == 0) {
|
||||
|
||||
if (!gMountOptions.masterhost)
|
||||
gMountOptions.masterhost = strdup(DEFAULT_MASTER_HOSTNAME);
|
||||
|
||||
if (!gMountOptions.masterport)
|
||||
gMountOptions.masterport = strdup(DEFAULT_MASTER_PORT);
|
||||
|
||||
if (!gMountOptions.subfolder)
|
||||
gMountOptions.subfolder = strdup(DEFAULT_MOUNTED_SUBFOLDER);
|
||||
|
||||
if (!gMountOptions.nofile)
|
||||
gMountOptions.nofile = 100000;
|
||||
}
|
||||
if (gMountOptions.writecachesize == 0) {
|
||||
|
||||
if (!gMountOptions.writecachesize)
|
||||
gMountOptions.writecachesize = 128;
|
||||
}
|
||||
|
||||
if (gMountOptions.cachePerInodePercentage < 1) {
|
||||
fprintf(stderr, "cache per inode percentage too low (%u %%) - increased to 1%%\n",
|
||||
fprintf(stderr, "cache per inode percentage too low (%u %%) - "
|
||||
"increased to 1%%\n",
|
||||
gMountOptions.cachePerInodePercentage);
|
||||
gMountOptions.cachePerInodePercentage = 1;
|
||||
}
|
||||
|
||||
if (gMountOptions.cachePerInodePercentage > 100) {
|
||||
fprintf(stderr, "cache per inode percentage too big (%u %%) - decreased to 100%%\n",
|
||||
fprintf(stderr, "cache per inode percentage too big (%u %%) - "
|
||||
"decreased to 100%%\n",
|
||||
gMountOptions.cachePerInodePercentage);
|
||||
gMountOptions.cachePerInodePercentage = 100;
|
||||
}
|
||||
|
||||
if (gMountOptions.writecachesize < 16) {
|
||||
fprintf(stderr, "write cache size too low (%u MiB) - increased to 16 MiB\n",
|
||||
fprintf(stderr, "write cache size too low (%u MiB) - "
|
||||
"increased to 16 MiB\n",
|
||||
gMountOptions.writecachesize);
|
||||
gMountOptions.writecachesize = 16;
|
||||
}
|
||||
|
||||
if (gMountOptions.writecachesize > 1024 * 1024) {
|
||||
fprintf(stderr, "write cache size too big (%u MiB) - decreased to 1 TiB\n",
|
||||
fprintf(stderr, "write cache size too big (%u MiB) - "
|
||||
"decreased to 1 TiB\n",
|
||||
gMountOptions.writecachesize);
|
||||
gMountOptions.writecachesize = 1024 * 1024;
|
||||
}
|
||||
|
||||
if (gMountOptions.writeworkers < 1) {
|
||||
fprintf(stderr, "no write workers - increasing number of workers to 1\n");
|
||||
fprintf(stderr, "no write workers - increasing number of "
|
||||
"workers to 1\n");
|
||||
gMountOptions.writeworkers = 1;
|
||||
}
|
||||
|
||||
if (gMountOptions.writewindowsize < 1) {
|
||||
fprintf(stderr, "write window size is 0 - increasing to 1\n");
|
||||
gMountOptions.writewindowsize = 1;
|
||||
}
|
||||
if (gMountOptions.nostdmountoptions == 0) {
|
||||
|
||||
if (!gMountOptions.nostdmountoptions)
|
||||
fuse_opt_add_arg(&args, "-o" DEFAULT_OPTIONS);
|
||||
}
|
||||
|
||||
if (gMountOptions.aclcachesize > 1000 * 1000) {
|
||||
fprintf(stderr, "acl cache size too big (%u) - decreased to 1000000\n",
|
||||
gMountOptions.aclcachesize);
|
||||
fprintf(stderr, "acl cache size too big (%u) - decreased to "
|
||||
"1000000\n", gMountOptions.aclcachesize);
|
||||
gMountOptions.aclcachesize = 1000 * 1000;
|
||||
}
|
||||
|
||||
if (gMountOptions.direntrycachesize > 10000000) {
|
||||
fprintf(stderr, "directory entry cache size too big (%u) - decreased to 10000000\n",
|
||||
fprintf(stderr, "directory entry cache size too big (%u) - "
|
||||
"decreased to 10000000\n",
|
||||
gMountOptions.direntrycachesize);
|
||||
gMountOptions.direntrycachesize = 10000000;
|
||||
}
|
||||
@ -594,7 +696,7 @@ int main(int argc, char *argv[]) try {
|
||||
|
||||
#if FUSE_VERSION >= 30
|
||||
struct fuse_cmdline_opts fuse_opts;
|
||||
if (fuse_parse_cmdline(&args, &fuse_opts) < 0) {
|
||||
if (fuse_parse_cmdline(&args, &fuse_opts)) {
|
||||
fprintf(stderr, "see: %s -h for help\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
@ -614,16 +716,14 @@ int main(int argc, char *argv[]) try {
|
||||
int multithread, foreground;
|
||||
char *mountpoint;
|
||||
|
||||
if (fuse_parse_cmdline(&args, &mountpoint, &multithread, &foreground) < 0) {
|
||||
if (fuse_parse_cmdline(&args, &mountpoint, &multithread, &foreground)) {
|
||||
fprintf(stderr, "see: %s -h for help\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gMountOptions.passwordask && gMountOptions.password == NULL &&
|
||||
gMountOptions.md5pass == NULL) {
|
||||
if (gMountOptions.passwordask && !gMountOptions.password && !gMountOptions.md5pass)
|
||||
gMountOptions.password = getpass("LizardFS Password:");
|
||||
}
|
||||
|
||||
#if FUSE_VERSION >= 30
|
||||
if (!fuse_opts.mountpoint) {
|
||||
@ -649,48 +749,43 @@ int main(int argc, char *argv[]) try {
|
||||
fuse_opts.mountpoint, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
if (gMountOptions.nonemptymount == 0) {
|
||||
if (!gMountOptions.nonemptymount) {
|
||||
if (fuse_mnt_check_empty(fuse_opts.mountpoint, stbuf.st_mode,
|
||||
stbuf.st_size)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!fuse_opts.foreground) {
|
||||
|
||||
if (!fuse_opts.foreground)
|
||||
res = daemonize_and_wait(!gMountOptions.debug,
|
||||
std::bind(&mainloop, &args, &fuse_opts, conn_opts));
|
||||
} else {
|
||||
else
|
||||
res = mainloop(&args, &fuse_opts, conn_opts);
|
||||
}
|
||||
#else
|
||||
if (!foreground) {
|
||||
if (!foreground)
|
||||
res = daemonize_and_wait(!gMountOptions.debug,
|
||||
std::bind(&mainloop, &args, mountpoint, multithread, foreground));
|
||||
} else {
|
||||
else
|
||||
res = mainloop(&args, mountpoint, multithread, foreground);
|
||||
}
|
||||
#endif
|
||||
|
||||
fuse_opt_free_args(&args);
|
||||
fuse_opt_free_args(&defaultargs);
|
||||
free(gMountOptions.masterhost);
|
||||
free(gMountOptions.masterport);
|
||||
if (gMountOptions.bindhost) {
|
||||
if (gMountOptions.bindhost)
|
||||
free(gMountOptions.bindhost);
|
||||
}
|
||||
free(gMountOptions.subfolder);
|
||||
if (gMountOptions.iolimits) {
|
||||
if (gMountOptions.iolimits)
|
||||
free(gMountOptions.iolimits);
|
||||
}
|
||||
#if FUSE_VERSION >= 30
|
||||
if (gDefaultMountpoint && gDefaultMountpoint != fuse_opts.mountpoint) {
|
||||
if (gDefaultMountpoint && gDefaultMountpoint != fuse_opts.mountpoint)
|
||||
free(gDefaultMountpoint);
|
||||
}
|
||||
free(fuse_opts.mountpoint);
|
||||
free(conn_opts);
|
||||
#else
|
||||
if (gDefaultMountpoint && gDefaultMountpoint != mountpoint) {
|
||||
if (gDefaultMountpoint && gDefaultMountpoint != mountpoint)
|
||||
free(gDefaultMountpoint);
|
||||
}
|
||||
free(mountpoint);
|
||||
#endif
|
||||
stats_term();
|
||||
|
@ -117,7 +117,7 @@ struct fuse_opt gMfsOptsStage2[] = {
|
||||
|
||||
void usage(const char *progname) {
|
||||
printf(
|
||||
"usage: %s mountpoint [options]\n"
|
||||
"usage: %s [HOST[/PORT]:[PATH]] [options] mountpoint\n"
|
||||
"\n", progname);
|
||||
|
||||
printf("general options:\n");
|
||||
@ -139,58 +139,98 @@ printf(
|
||||
" -P PORT equivalent to '-o mfsport=PORT'\n"
|
||||
" -B IP equivalent to '-o mfsbind=IP'\n"
|
||||
" -S PATH equivalent to '-o mfssubfolder=PATH'\n"
|
||||
" -p --password similar to '-o mfspassword=PASSWORD', but show prompt and ask user for password\n"
|
||||
" -n --nostdopts do not add standard LizardFS mount options: '-o " DEFAULT_OPTIONS ",fsname=MFS'\n"
|
||||
" -p --password similar to '-o mfspassword=PASSWORD', but "
|
||||
"show prompt and ask user for password\n"
|
||||
" -n --nostdopts do not add standard LizardFS mount options: "
|
||||
"'-o " DEFAULT_OPTIONS ",fsname=MFS'\n"
|
||||
" --nonempty allow mounts over non-empty file/dir\n"
|
||||
" -o nostdmountoptions equivalent of --nostdopts for /etc/fstab\n"
|
||||
" -o mfscfgfile=CFGFILE load some mount options from external file (if not specified then use default file: " ETC_PATH "/mfsmount.cfg)\n"
|
||||
" -o mfscfgfile=CFGFILE load some mount options from external file "
|
||||
"(if not specified then use default file: "
|
||||
ETC_PATH "/mfsmount.cfg)\n"
|
||||
" -o mfsdebug print some debugging information\n"
|
||||
" -o mfsmeta mount meta filesystem (trash etc.)\n"
|
||||
" -o mfsdelayedinit connection with master is done in background - with this option mount can be run without network (good for being run from fstab / init scripts etc.)\n"
|
||||
" -o mfsacl DEPRECATED, used to enable/disable ACL support, ignored now\n"
|
||||
" -o mfsrwlock=0|1 when set to 1, parallel reads from the same descriptor are"
|
||||
" performed (default: %d)\n"
|
||||
" -o mfsmkdircopysgid=N sgid bit should be copied during mkdir operation (default: %d)\n"
|
||||
" -o mfsdelayedinit connection with master is done in background "
|
||||
"- with this option mount can be run without "
|
||||
"network (good for being run from fstab/init "
|
||||
"scripts etc.)\n"
|
||||
" -o mfsacl DEPRECATED, used to enable/disable ACL "
|
||||
"support, ignored now\n"
|
||||
" -o mfsrwlock=0|1 when set to 1, parallel reads from the same "
|
||||
"descriptor are performed (default: %d)\n"
|
||||
" -o mfsmkdircopysgid=N sgid bit should be copied during mkdir "
|
||||
"operation (default: %d)\n"
|
||||
" -o mfssugidclearmode=SMODE set sugid clear mode (see below ; default: %s)\n"
|
||||
" -o mfscachemode=CMODE set cache mode (see below ; default: AUTO)\n"
|
||||
" -o mfscachefiles (deprecated) equivalent to '-o mfscachemode=YES'\n"
|
||||
" -o mfsattrcacheto=SEC set attributes cache timeout in seconds (default: %.2f)\n"
|
||||
" -o mfsentrycacheto=SEC set file entry cache timeout in seconds (default: %.2f)\n"
|
||||
" -o mfsdirentrycacheto=SEC set directory entry cache timeout in seconds (default: %.2f)\n"
|
||||
" -o mfsdirentrycachesize=N define directory entry cache size in number of entries (default: %u)\n"
|
||||
" -o mfsattrcacheto=SEC set attributes cache timeout in seconds "
|
||||
"(default: %.2f)\n"
|
||||
" -o mfsentrycacheto=SEC set file entry cache timeout in seconds "
|
||||
"(default: %.2f)\n"
|
||||
" -o mfsdirentrycacheto=SEC set directory entry cache timeout in seconds "
|
||||
"(default: %.2f)\n"
|
||||
" -o mfsdirentrycachesize=N define directory entry cache size in number "
|
||||
"of entries (default: %u)\n"
|
||||
" -o mfsaclcacheto=SEC set ACL cache timeout in seconds (default: %.2f)\n"
|
||||
" -o mfsreportreservedperiod=SEC set reporting reserved inodes interval in seconds (default: %u)\n"
|
||||
" -o mfschunkserverrtt=MSEC set timeout after which SYN packet is considered lost during the first retry of connecting a chunkserver (default: %u)\n"
|
||||
" -o mfschunkserverconnectreadto=MSEC set timeout for connecting with chunkservers during read operation in milliseconds (default: %u)\n"
|
||||
" -o mfschunkserverwavereadto=MSEC set timeout for executing each wave of a read operation in milliseconds (default: %u)\n"
|
||||
" -o mfschunkservertotalreadto=MSEC set timeout for the whole communication with chunkservers during a read operation in milliseconds (default: %u)\n"
|
||||
" -o cacheexpirationtime=MSEC set timeout for read cache entries to be considered valid in milliseconds (0 disables cache) (default: %u)\n"
|
||||
" -o readaheadmaxwindowsize=KB set max value of readahead window per single descriptor in kibibytes (default: %u)\n"
|
||||
" -o mfsprefetchxorstripes prefetch full xor stripe on every first read of a xor chunk\n"
|
||||
" -o mfschunkserverwriteto=MSEC set chunkserver response timeout during write operation in milliseconds (default: %u)\n"
|
||||
" -o mfsnice=N on startup mfsmount tries to change his 'nice' value (default: -19)\n"
|
||||
" -o mfsreportreservedperiod=SEC set reporting reserved inodes interval in "
|
||||
"seconds (default: %u)\n"
|
||||
" -o mfschunkserverrtt=MSEC set timeout after which SYN packet is "
|
||||
"considered lost during the first retry of "
|
||||
"connecting a chunkserver (default: %u)\n"
|
||||
" -o mfschunkserverconnectreadto=MSEC set timeout for connecting with "
|
||||
"chunkservers during read operation in "
|
||||
"milliseconds (default: %u)\n"
|
||||
" -o mfschunkserverwavereadto=MSEC set timeout for executing each wave "
|
||||
"of a read operation in milliseconds (default: %u)\n"
|
||||
" -o mfschunkservertotalreadto=MSEC set timeout for the whole "
|
||||
"communication with chunkservers during a "
|
||||
"read operation in milliseconds (default: %u)\n"
|
||||
" -o cacheexpirationtime=MSEC set timeout for read cache entries to be "
|
||||
"considered valid in milliseconds (0 disables "
|
||||
"cache) (default: %u)\n"
|
||||
" -o readaheadmaxwindowsize=KB set max value of readahead window per single "
|
||||
"descriptor in kibibytes (default: %u)\n"
|
||||
" -o mfsprefetchxorstripes prefetch full xor stripe on every first read "
|
||||
"of a xor chunk\n"
|
||||
" -o mfschunkserverwriteto=MSEC set chunkserver response timeout during "
|
||||
"write operation in milliseconds (default: %u)\n"
|
||||
" -o mfsnice=N on startup mfsmount tries to change his "
|
||||
"'nice' value (default: -19)\n"
|
||||
#ifdef MFS_USE_MEMLOCK
|
||||
" -o mfsmemlock try to lock memory\n"
|
||||
#endif
|
||||
" -o mfswritecachesize=N define size of write cache in MiB (default: %u)\n"
|
||||
" -o mfsaclcachesize=N define ACL cache size in number of entries (0: no cache; default: %u)\n"
|
||||
" -o mfscacheperinodepercentage define what part of the write cache non occupied by other inodes can a single inode occupy (in %%, default: %u)\n"
|
||||
" -o mfsaclcachesize=N define ACL cache size in number of entries "
|
||||
"(0: no cache; default: %u)\n"
|
||||
" -o mfscacheperinodepercentage define what part of the write cache non "
|
||||
"occupied by other inodes can a single inode "
|
||||
"occupy (in %%, default: %u)\n"
|
||||
" -o mfswriteworkers=N define number of write workers (default: %u)\n"
|
||||
" -o mfsioretries=N define number of retries before I/O error is returned (default: %u)\n"
|
||||
" -o mfswritewindowsize=N define write window size (in blocks) for each chunk (default: %u)\n"
|
||||
" -o mfsioretries=N define number of retries before I/O error is "
|
||||
"returned (default: %u)\n"
|
||||
" -o mfswritewindowsize=N define write window size (in blocks) for "
|
||||
"each chunk (default: %u)\n"
|
||||
" -o mfsmaster=HOST define mfsmaster location (default: mfsmaster)\n"
|
||||
" -o mfsport=PORT define mfsmaster port number (default: 9421)\n"
|
||||
" -o mfsbind=IP define source ip address for connections (default: NOT DEFINED - chosen automatically by OS)\n"
|
||||
" -o mfsbind=IP define source ip address for connections "
|
||||
"(default: NOT DEFINED - chosen automatically "
|
||||
"by OS)\n"
|
||||
" -o mfssubfolder=PATH define subfolder to mount as root (default: %s)\n"
|
||||
" -o mfspassword=PASSWORD authenticate to mfsmaster with password\n"
|
||||
" -o mfsmd5pass=MD5 authenticate to mfsmaster using directly given md5 (only if mfspassword is not defined)\n"
|
||||
" -o mfsmd5pass=MD5 authenticate to mfsmaster using directly "
|
||||
"given md5 (only if mfspassword is not defined)\n"
|
||||
" -o askpassword show prompt and ask user for password\n"
|
||||
" -o mfsdonotrememberpassword do not remember password in memory - more secure, but when session is lost then new session is created without password\n"
|
||||
" -o mfsdonotrememberpassword do not remember password in memory - more "
|
||||
"secure, but when session is lost then new "
|
||||
"session is created without password\n"
|
||||
" -o mfsiolimits=FILE define I/O limits configuration file\n"
|
||||
" -o symlinkcachetimeout=N define timeout of symlink cache in seconds (default: %u)\n"
|
||||
" -o bandwidthoveruse=N define ratio of allowed bandwidth overuse when fetching data (default: %.2f)\n"
|
||||
" -o symlinkcachetimeout=N define timeout of symlink cache in seconds "
|
||||
"(default: %u)\n"
|
||||
" -o bandwidthoveruse=N define ratio of allowed bandwidth overuse "
|
||||
"when fetching data (default: %.2f)\n"
|
||||
#if FUSE_VERSION >= 26
|
||||
" -o enablefilelocks=0|1 enables/disables global file locking (disabled by default)\n"
|
||||
" -o enablefilelocks=0|1 enables/disables global file locking "
|
||||
"(disabled by default)\n"
|
||||
#endif
|
||||
#if FUSE_VERSION >= 30
|
||||
" -o nonempty allow mounts over non-empty file/dir\n"
|
||||
@ -224,18 +264,31 @@ printf(
|
||||
);
|
||||
printf(
|
||||
"CMODE can be set to:\n"
|
||||
" NO,NONE or NEVER never allow files data to be kept in cache (safest but can reduce efficiency)\n"
|
||||
" YES or ALWAYS always allow files data to be kept in cache (dangerous)\n"
|
||||
" AUTO file cache is managed by mfsmaster automatically (should be very safe and efficient)\n"
|
||||
" NO,NONE or NEVER never allow files data to be kept in cache "
|
||||
"(safest but can reduce efficiency)\n"
|
||||
" YES or ALWAYS always allow files data to be kept in cache "
|
||||
"(dangerous)\n"
|
||||
" AUTO file cache is managed by mfsmaster "
|
||||
"automatically (should be very safe and "
|
||||
"efficient)\n"
|
||||
"\n");
|
||||
printf(
|
||||
"SMODE can be set to:\n"
|
||||
" NEVER LizardFS will not change suid and sgid bit on chown\n"
|
||||
" ALWAYS clear suid and sgid on every chown - safest operation\n"
|
||||
" OSX standard behavior in OS X and Solaris (chown made by unprivileged user clear suid and sgid)\n"
|
||||
" BSD standard behavior in *BSD systems (like in OSX, but only when something is really changed)\n"
|
||||
" EXT standard behavior in most file systems on Linux (directories not changed, others: suid cleared always, sgid only when group exec bit is set)\n"
|
||||
" XFS standard behavior in XFS on Linux (like EXT but directories are changed by unprivileged users)\n"
|
||||
" NEVER LizardFS will not change suid and sgid bit "
|
||||
"on chown\n"
|
||||
" ALWAYS clear suid and sgid on every chown - safest "
|
||||
"operation\n"
|
||||
" OSX standard behavior in OS X and Solaris (chown "
|
||||
"made by unprivileged user clear suid and sgid)\n"
|
||||
" BSD standard behavior in *BSD systems (like in "
|
||||
"OSX, but only when something is really changed)\n"
|
||||
" EXT standard behavior in most file systems on "
|
||||
"Linux (directories not changed, others: suid "
|
||||
"cleared always, sgid only when group exec "
|
||||
"bit is set)\n"
|
||||
" XFS standard behavior in XFS on Linux (like EXT "
|
||||
"but directories are changed by unprivileged "
|
||||
"users)\n"
|
||||
"SMODE extra info:\n"
|
||||
" btrfs,ext2,ext3,ext4,hfs[+],jfs,ntfs and reiserfs on Linux work as 'EXT'.\n"
|
||||
" Only xfs on Linux works a little different. Beware that there is a strange\n"
|
||||
@ -277,47 +330,54 @@ printf(
|
||||
|
||||
void mfs_opt_parse_cfg_file(const char *filename,int optional,struct fuse_args *outargs) {
|
||||
FILE *fd;
|
||||
char lbuff[1000],*p;
|
||||
constexpr size_t N = 1000;
|
||||
char lbuff[N],*p;
|
||||
|
||||
fd = fopen(filename,"r");
|
||||
if (fd==NULL) {
|
||||
if (optional==0) {
|
||||
fd = fopen(filename, "r");
|
||||
if (!fd) {
|
||||
if (!optional) {
|
||||
fprintf(stderr,"can't open cfg file: %s\n",filename);
|
||||
abort();
|
||||
}
|
||||
return;
|
||||
}
|
||||
gCustomCfg = 1;
|
||||
while (fgets(lbuff,999,fd)) {
|
||||
if (lbuff[0]!='#' && lbuff[0]!=';') {
|
||||
lbuff[999]=0;
|
||||
for (p = lbuff ; *p ; p++) {
|
||||
if (*p=='\r' || *p=='\n') {
|
||||
*p=0;
|
||||
break;
|
||||
}
|
||||
while (fgets(lbuff, N - 1, fd)) {
|
||||
if (lbuff[0] == '#' || lbuff[0] == ';')
|
||||
continue;
|
||||
|
||||
lbuff[N - 1] = 0;
|
||||
|
||||
for (p = lbuff; *p; p++) {
|
||||
if (*p == '\r' || *p == '\n') {
|
||||
*p = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p--;
|
||||
|
||||
while (p >= lbuff && (*p == ' ' || *p == '\t')) {
|
||||
*p = 0;
|
||||
p--;
|
||||
while (p>=lbuff && (*p==' ' || *p=='\t')) {
|
||||
*p=0;
|
||||
p--;
|
||||
}
|
||||
p = lbuff;
|
||||
while (*p==' ' || *p=='\t') {
|
||||
p++;
|
||||
}
|
||||
if (*p) {
|
||||
if (*p=='-') {
|
||||
fuse_opt_add_arg(outargs,p);
|
||||
} else if (*p=='/') {
|
||||
if (gDefaultMountpoint) {
|
||||
free(gDefaultMountpoint);
|
||||
}
|
||||
gDefaultMountpoint = strdup(p);
|
||||
} else {
|
||||
fuse_opt_add_arg(outargs,"-o");
|
||||
fuse_opt_add_arg(outargs,p);
|
||||
}
|
||||
}
|
||||
|
||||
p = lbuff;
|
||||
|
||||
while (*p == ' ' || *p == '\t') {
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p) {
|
||||
if (*p == '-') {
|
||||
fuse_opt_add_arg(outargs,p);
|
||||
} else if (*p == '/') {
|
||||
if (gDefaultMountpoint)
|
||||
free(gDefaultMountpoint);
|
||||
gDefaultMountpoint = strdup(p);
|
||||
} else {
|
||||
fuse_opt_add_arg(outargs,"-o");
|
||||
fuse_opt_add_arg(outargs,p);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -325,21 +385,26 @@ void mfs_opt_parse_cfg_file(const char *filename,int optional,struct fuse_args *
|
||||
}
|
||||
|
||||
// Function for FUSE: has to have these arguments
|
||||
int mfs_opt_proc_stage1(void *data, const char *arg, int key, struct fuse_args *outargs) {
|
||||
struct fuse_args *defargs = (struct fuse_args*)data;
|
||||
(void)outargs; // remove unused argument warning
|
||||
int mfs_opt_proc_stage1(struct fuse_args *defargs, const char *arg, int key) {
|
||||
const char *mfscfgfile_opt = "mfscfgfile=";
|
||||
const int n = strlen(mfscfgfile_opt);
|
||||
|
||||
if (key == KEY_CFGFILE) {
|
||||
if (!strncmp(arg, mfscfgfile_opt, n))
|
||||
mfs_opt_parse_cfg_file(arg + n, 0, defargs);
|
||||
else if (!strncmp(arg, "-c", 2))
|
||||
mfs_opt_parse_cfg_file(arg + 2, 0, defargs);
|
||||
|
||||
if (key==KEY_CFGFILE) {
|
||||
if (memcmp(arg,"mfscfgfile=",11)==0) {
|
||||
mfs_opt_parse_cfg_file(arg+11,0,defargs);
|
||||
} else if (arg[0]=='-' && arg[1]=='c') {
|
||||
mfs_opt_parse_cfg_file(arg+2,0,defargs);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int mfs_opt_proc_stage1(void *data, const char *arg, int key, struct fuse_args *outargs) {
|
||||
(void)outargs; // remove unused argument warning
|
||||
return mfs_opt_proc_stage1((struct fuse_args*)data, arg, key);
|
||||
}
|
||||
|
||||
// Function for FUSE: has to have these arguments
|
||||
// return value:
|
||||
// 0 - discard this arg
|
||||
@ -354,28 +419,24 @@ int mfs_opt_proc_stage2(void *data, const char *arg, int key, struct fuse_args *
|
||||
case FUSE_OPT_KEY_NONOPT:
|
||||
return 1;
|
||||
case KEY_HOST:
|
||||
if (gMountOptions.masterhost!=NULL) {
|
||||
if (gMountOptions.masterhost)
|
||||
free(gMountOptions.masterhost);
|
||||
}
|
||||
gMountOptions.masterhost = strdup(arg+2);
|
||||
gMountOptions.masterhost = strdup(arg + 2);
|
||||
return 0;
|
||||
case KEY_PORT:
|
||||
if (gMountOptions.masterport!=NULL) {
|
||||
if (gMountOptions.masterport)
|
||||
free(gMountOptions.masterport);
|
||||
}
|
||||
gMountOptions.masterport = strdup(arg+2);
|
||||
gMountOptions.masterport = strdup(arg + 2);
|
||||
return 0;
|
||||
case KEY_BIND:
|
||||
if (gMountOptions.bindhost!=NULL) {
|
||||
if (gMountOptions.bindhost)
|
||||
free(gMountOptions.bindhost);
|
||||
}
|
||||
gMountOptions.bindhost = strdup(arg+2);
|
||||
gMountOptions.bindhost = strdup(arg + 2);
|
||||
return 0;
|
||||
case KEY_PATH:
|
||||
if (gMountOptions.subfolder!=NULL) {
|
||||
if (gMountOptions.subfolder)
|
||||
free(gMountOptions.subfolder);
|
||||
}
|
||||
gMountOptions.subfolder = strdup(arg+2);
|
||||
gMountOptions.subfolder = strdup(arg + 2);
|
||||
return 0;
|
||||
case KEY_PASSWORDASK:
|
||||
gMountOptions.passwordask = 1;
|
||||
@ -396,9 +457,9 @@ int mfs_opt_proc_stage2(void *data, const char *arg, int key, struct fuse_args *
|
||||
printf("LizardFS version %s\n", LIZARDFS_PACKAGE_VERSION);
|
||||
{
|
||||
struct fuse_args helpargs = FUSE_ARGS_INIT(0, NULL);
|
||||
fuse_opt_add_arg(&helpargs,outargs->argv[0]);
|
||||
fuse_opt_add_arg(&helpargs,"--version");
|
||||
fuse_parse_cmdline(&helpargs,NULL,NULL,NULL);
|
||||
fuse_opt_add_arg(&helpargs, outargs->argv[0]);
|
||||
fuse_opt_add_arg(&helpargs, "--version");
|
||||
fuse_parse_cmdline(&helpargs, NULL, NULL, NULL);
|
||||
fuse_unmount(NULL, fuse_mount(NULL, &helpargs));
|
||||
}
|
||||
exit(0);
|
||||
@ -407,8 +468,8 @@ int mfs_opt_proc_stage2(void *data, const char *arg, int key, struct fuse_args *
|
||||
{
|
||||
struct fuse_args helpargs = FUSE_ARGS_INIT(0, NULL);
|
||||
fuse_opt_add_arg(&helpargs,outargs->argv[0]);
|
||||
fuse_opt_add_arg(&helpargs,"-ho");
|
||||
fuse_parse_cmdline(&helpargs,NULL,NULL,NULL);
|
||||
fuse_opt_add_arg(&helpargs, "-ho");
|
||||
fuse_parse_cmdline(&helpargs, NULL, NULL, NULL);
|
||||
fuse_unmount(NULL, fuse_mount(NULL, &helpargs));
|
||||
}
|
||||
exit(0);
|
||||
|
@ -45,7 +45,7 @@ typedef uint32_t JobId;
|
||||
typedef uint32_t NamedInodeOffset;
|
||||
|
||||
struct FsInitParams {
|
||||
static constexpr const char *kDefaultSubfolder = "/";
|
||||
static constexpr const char *kDefaultSubfolder = DEFAULT_MOUNTED_SUBFOLDER;
|
||||
static constexpr bool kDefaultDoNotRememberPassword = false;
|
||||
static constexpr bool kDefaultDelayedInit = false;
|
||||
#ifdef _WIN32
|
||||
|
Loading…
Reference in New Issue
Block a user