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:
Patryk 2019-04-29 14:36:01 +02:00
parent 5adf40470f
commit 32e8d297f6
8 changed files with 422 additions and 246 deletions

View File

@ -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)

View File

@ -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
View File

@ -0,0 +1 @@
/usr/bin/mfsmount /sbin/mount.lzfs

View File

@ -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>.

View File

@ -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()

View File

@ -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();

View File

@ -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);

View File

@ -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