Mount on non-empty path (#1311)
This commit is contained in:
Родитель
e377ebec6e
Коммит
d918c11e5a
|
@ -2,6 +2,7 @@
|
|||
**Bug Fixes**
|
||||
- Invalidate attribute cache entry on `PathAlreadyExists` error in create directory operation.
|
||||
- When `$HOME` environment variable is not present, use the current directory.
|
||||
- Fixed mount failure on nonempty mount path for fuse3.
|
||||
|
||||
**Features**
|
||||
- Support CPK for block storage accounts.
|
||||
|
|
|
@ -35,6 +35,7 @@ steps:
|
|||
- script: |
|
||||
sudo apt-get update --fix-missing
|
||||
sudo apt-get install ${{ parameters.fuselib }} -y
|
||||
fusermount -V
|
||||
displayName: 'Libfuse Setup'
|
||||
condition: eq('${{ parameters.hostedAgent }}', true)
|
||||
|
||||
|
|
|
@ -139,6 +139,9 @@ stages:
|
|||
- script: |
|
||||
sudo apt-get update --fix-missing
|
||||
sudo apt-get install $(fuselib) -y
|
||||
if [ $(tags) == "fuse2" ]; then
|
||||
sudo apt-get install fuse -y
|
||||
fi
|
||||
displayName: 'Install libfuse'
|
||||
|
||||
# -------------------------------------------------------
|
||||
|
@ -412,6 +415,9 @@ stages:
|
|||
- script: |
|
||||
sudo apt-get update --fix-missing
|
||||
sudo apt-get install $(fuselib) -y
|
||||
if [ $(tags) == "fuse2" ]; then
|
||||
sudo apt-get install fuse -y
|
||||
fi
|
||||
displayName: 'Install libfuse'
|
||||
|
||||
# -------------------------------------------------------
|
||||
|
|
16
cmd/mount.go
16
cmd/mount.go
|
@ -97,7 +97,7 @@ type mountOptions struct {
|
|||
|
||||
var options mountOptions
|
||||
|
||||
func (opt *mountOptions) validate(skipEmptyMount bool) error {
|
||||
func (opt *mountOptions) validate(skipNonEmptyMount bool) error {
|
||||
if opt.MountPath == "" {
|
||||
return fmt.Errorf("mount path not provided")
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ func (opt *mountOptions) validate(skipEmptyMount bool) error {
|
|||
return fmt.Errorf("mount directory does not exists")
|
||||
} else if common.IsDirectoryMounted(opt.MountPath) {
|
||||
return fmt.Errorf("directory is already mounted")
|
||||
} else if !skipEmptyMount && !common.IsDirectoryEmpty(opt.MountPath) {
|
||||
} else if !skipNonEmptyMount && !common.IsDirectoryEmpty(opt.MountPath) {
|
||||
return fmt.Errorf("mount directory is not empty")
|
||||
}
|
||||
|
||||
|
@ -285,8 +285,6 @@ var mountCmd = &cobra.Command{
|
|||
options.Components = pipeline
|
||||
}
|
||||
|
||||
skipNonEmpty := false
|
||||
|
||||
if config.IsSet("libfuse-options") {
|
||||
for _, v := range options.LibfuseOptions {
|
||||
parameter := strings.Split(v, "=")
|
||||
|
@ -309,8 +307,11 @@ var mountCmd = &cobra.Command{
|
|||
config.Set("read-only", "true")
|
||||
} else if v == "allow_root" || v == "allow_root=true" {
|
||||
config.Set("allow-root", "true")
|
||||
} else if v == "nonempty" {
|
||||
skipNonEmpty = true
|
||||
} else if v == "nonempty" || v == "nonempty=true" {
|
||||
// For fuse3, -o nonempty mount option has been removed and
|
||||
// mounting over non-empty directories is now always allowed.
|
||||
// For fuse2, this option is supported.
|
||||
options.NonEmpty = true
|
||||
config.Set("nonempty", "true")
|
||||
} else if strings.HasPrefix(v, "umask=") {
|
||||
umask, err := strconv.ParseUint(parameter[1], 10, 32)
|
||||
|
@ -346,7 +347,7 @@ var mountCmd = &cobra.Command{
|
|||
options.Logging.LogLevel = "LOG_WARNING"
|
||||
}
|
||||
|
||||
err = options.validate(options.NonEmpty || skipNonEmpty)
|
||||
err = options.validate(options.NonEmpty)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -402,6 +403,7 @@ var mountCmd = &cobra.Command{
|
|||
|
||||
log.Crit("Starting Blobfuse2 Mount : %s on [%s]", common.Blobfuse2Version, common.GetCurrentDistro())
|
||||
log.Crit("Logging level set to : %s", logLevel.String())
|
||||
log.Debug("Mount allowed on nonempty path : %v", options.NonEmpty)
|
||||
pipeline, err = internal.NewPipeline(options.Components, !daemon.WasReborn())
|
||||
if err != nil {
|
||||
log.Err("mount : failed to initialize new pipeline [%v]", err)
|
||||
|
|
|
@ -62,6 +62,7 @@ azstorage:
|
|||
mode: key
|
||||
endpoint: myEndpoint
|
||||
container: myContainer
|
||||
max-retries: 1
|
||||
components:
|
||||
- libfuse
|
||||
- file_cache
|
||||
|
@ -73,20 +74,6 @@ health_monitor:
|
|||
- blobfuse_stats
|
||||
`
|
||||
|
||||
var configMountLoopback string = `
|
||||
logging:
|
||||
type: syslog
|
||||
default-working-dir: /tmp/blobfuse2
|
||||
components:
|
||||
- libfuse
|
||||
- loopbackfs
|
||||
libfuse:
|
||||
attribute-expiration-sec: 120
|
||||
entry-expiration-sec: 60
|
||||
loopbackfs:
|
||||
path: /tmp/bfuseloopback
|
||||
`
|
||||
|
||||
var configPriorityTest string = `
|
||||
logging:
|
||||
type: syslog
|
||||
|
@ -164,8 +151,9 @@ func (suite *mountTestSuite) TestMountDirNotEmpty() {
|
|||
suite.assert.NotNil(err)
|
||||
suite.assert.Contains(op, "mount directory is not empty")
|
||||
|
||||
op, err = executeCommandC(rootCmd, "mount", mntDir, fmt.Sprintf("--config-file=%s", confFileMntTest), "-o", "nonempty", "--foreground")
|
||||
op, err = executeCommandC(rootCmd, "mount", mntDir, fmt.Sprintf("--config-file=%s", confFileMntTest), "-o", "nonempty")
|
||||
suite.assert.NotNil(err)
|
||||
suite.assert.Contains(op, "failed to initialize new pipeline")
|
||||
}
|
||||
|
||||
// mount failure test where the mount path is not provided
|
||||
|
|
|
@ -110,7 +110,6 @@ func (lf *Libfuse) convertConfig() *C.fuse_options_t {
|
|||
fuse_opts.allow_other = C.bool(lf.allowOther)
|
||||
fuse_opts.allow_root = C.bool(lf.allowRoot)
|
||||
fuse_opts.trace_enable = C.bool(lf.traceEnable)
|
||||
fuse_opts.non_empty = C.bool(lf.nonEmptyMount)
|
||||
fuse_opts.umask = C.int(lf.umask)
|
||||
|
||||
return fuse_opts
|
||||
|
@ -210,10 +209,6 @@ func populateFuseArgs(opts *C.fuse_options_t, args *C.fuse_args_t) (*C.fuse_opti
|
|||
options += ",allow_root"
|
||||
}
|
||||
|
||||
if opts.non_empty {
|
||||
options += ",nonempty"
|
||||
}
|
||||
|
||||
if opts.readonly {
|
||||
options += ",ro"
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ foreground: true|false <run blobfuse2 in foreground or background>
|
|||
# Common configurations
|
||||
read-only: true|false <mount in read only mode - used for Streaming and FUSE>
|
||||
allow-other: true|false <allow other users to access the mounted directory - used for FUSE and File Cache>
|
||||
nonempty: true|false <allow mounting on non-empty directory - used for FUSE>
|
||||
nonempty: true|false <allow mounting on non-empty directory>
|
||||
|
||||
# Dynamic profiler related configuration. This helps to root-cause high memory/cpu usage related issues.
|
||||
dynamic-profile: true|false <allows to turn on dynamic profiler for cpu/memory usage monitoring. Only for debugging, shall not be used in production>
|
||||
|
|
|
@ -140,7 +140,7 @@ func (suite *mountSuite) TestMountDirNotExists() {
|
|||
}
|
||||
|
||||
// mount failure test where the mount directory is not empty
|
||||
func (suite *mountSuite) TestMountDirNotEmpty() {
|
||||
func (suite *mountSuite) TestMountDirNotEmptyFailure() {
|
||||
tempDir := filepath.Join(mntDir, "tempdir")
|
||||
_ = os.Mkdir(tempDir, 0777)
|
||||
mountCmd := exec.Command(blobfuseBinary, "mount", mntDir, "--config-file="+configFile)
|
||||
|
@ -162,6 +162,32 @@ func (suite *mountSuite) TestMountDirNotEmpty() {
|
|||
blobfuseUnmount(suite, "Nothing to unmount")
|
||||
}
|
||||
|
||||
// mount non-empty directory using nonempty flag
|
||||
func (suite *mountSuite) TestMountDirNotEmptySuccess() {
|
||||
tempDir := filepath.Join(mntDir, "tempdir")
|
||||
_ = os.Mkdir(tempDir, 0777)
|
||||
|
||||
mountCmd := exec.Command(blobfuseBinary, "mount", mntDir, "--config-file="+configFile, "-o", "nonempty")
|
||||
cliOut, err := mountCmd.Output()
|
||||
suite.Equal(0, len(cliOut))
|
||||
suite.Equal(nil, err)
|
||||
|
||||
// wait for mount
|
||||
time.Sleep(10 * time.Second)
|
||||
|
||||
// validate mount
|
||||
cliOut = listBlobfuseMounts(suite)
|
||||
suite.NotEqual(0, len(cliOut))
|
||||
suite.Contains(string(cliOut), mntDir)
|
||||
|
||||
remountCheck(suite)
|
||||
|
||||
// unmount
|
||||
blobfuseUnmount(suite, mntDir)
|
||||
|
||||
os.RemoveAll(tempDir)
|
||||
}
|
||||
|
||||
// mount failure test where the mount path is not provided
|
||||
func (suite *mountSuite) TestMountPathNotProvided() {
|
||||
mountCmd := exec.Command(blobfuseBinary, "mount", "", "--config-file="+configFile)
|
||||
|
|
Загрузка…
Ссылка в новой задаче