Skip to content

Commit 05bb085

Browse files
Provide a mode to just disable kernel cache not the blobfuse cache (#1882)
1 parent eaa7846 commit 05bb085

File tree

5 files changed

+66
-18
lines changed

5 files changed

+66
-18
lines changed

cmd/mount.go

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -74,21 +74,22 @@ type mountOptions struct {
7474
inputMountPath string
7575
ConfigFile string
7676

77-
Logging LogOptions `config:"logging"`
78-
Components []string `config:"components"`
79-
Foreground bool `config:"foreground"`
80-
NonEmpty bool `config:"nonempty"`
81-
DefaultWorkingDir string `config:"default-working-dir"`
82-
CPUProfile string `config:"cpu-profile"`
83-
MemProfile string `config:"mem-profile"`
84-
PassPhrase string `config:"passphrase"`
85-
SecureConfig bool `config:"secure-config"`
86-
DynamicProfiler bool `config:"dynamic-profile"`
87-
ProfilerPort int `config:"profiler-port"`
88-
ProfilerIP string `config:"profiler-ip"`
89-
MonitorOpt monitorOptions `config:"health_monitor"`
90-
WaitForMount time.Duration `config:"wait-for-mount"`
91-
LazyWrite bool `config:"lazy-write"`
77+
Logging LogOptions `config:"logging"`
78+
Components []string `config:"components"`
79+
Foreground bool `config:"foreground"`
80+
NonEmpty bool `config:"nonempty"`
81+
DefaultWorkingDir string `config:"default-working-dir"`
82+
CPUProfile string `config:"cpu-profile"`
83+
MemProfile string `config:"mem-profile"`
84+
PassPhrase string `config:"passphrase"`
85+
SecureConfig bool `config:"secure-config"`
86+
DynamicProfiler bool `config:"dynamic-profile"`
87+
ProfilerPort int `config:"profiler-port"`
88+
ProfilerIP string `config:"profiler-ip"`
89+
MonitorOpt monitorOptions `config:"health_monitor"`
90+
WaitForMount time.Duration `config:"wait-for-mount"`
91+
LazyWrite bool `config:"lazy-write"`
92+
disableKernelCache bool `config:"disable-kernel-cache"`
9293

9394
// v1 support
9495
Streaming bool `config:"streaming"`
@@ -393,6 +394,11 @@ var mountCmd = &cobra.Command{
393394
}
394395
}
395396

397+
if config.IsSet("disable-kernel-cache") && directIO {
398+
// Both flag shall not be enable together
399+
return fmt.Errorf("direct-io and disable-kernel-cache cannot be enabled together")
400+
}
401+
396402
if !config.IsSet("logging.file-path") {
397403
options.Logging.LogFilePath = common.DefaultLogFilePath
398404
}
@@ -870,6 +876,9 @@ func init() {
870876

871877
mountCmd.PersistentFlags().DurationVar(&options.WaitForMount, "wait-for-mount", 5*time.Second, "Let parent process wait for given timeout before exit")
872878

879+
mountCmd.PersistentFlags().Bool("disable-kernel-cache", false, "Disable kerneel cache, but keep blobfuse cache. Default value false.")
880+
config.BindPFlag("disable-kernel-cache", mountCmd.PersistentFlags().Lookup("disable-kernel-cache"))
881+
873882
config.AttachToFlagSet(mountCmd.PersistentFlags())
874883
config.AttachFlagCompletions(mountCmd)
875884
config.AddConfigChangeEventListener(config.ConfigChangeEventHandlerFunc(OnConfigChange))

cmd/mount_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,21 @@ func (suite *mountTestSuite) TestStreamAttrCacheOptionsV1() {
360360
suite.assert.Contains(op, "failed to initialize new pipeline")
361361
}
362362

363+
func (suite *mountTestSuite) TestDirectIODisableKernelCacheCombo() {
364+
defer suite.cleanupTest()
365+
366+
mntDir, err := os.MkdirTemp("", "mntdir")
367+
suite.assert.Nil(err)
368+
defer os.RemoveAll(mntDir)
369+
370+
tempLogDir := "/tmp/templogs_" + randomString(6)
371+
defer os.RemoveAll(tempLogDir)
372+
373+
op, err := executeCommandC(rootCmd, "mount", mntDir, "-o", "direct_io", "--disable-kernel-cache")
374+
suite.assert.NotNil(err)
375+
suite.assert.Contains(op, "direct-io and disable-kernel-cache cannot be enabled together")
376+
}
377+
363378
// mount failure test where a libfuse option is incorrect
364379
func (suite *mountTestSuite) TestInvalidLibfuseOption() {
365380
defer suite.cleanupTest()

component/libfuse/libfuse.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ type Libfuse struct {
7575
maxFuseThreads uint32
7676
directIO bool
7777
umask uint32
78+
disableKernelCache bool
7879
}
7980

8081
// To support pagination in readdir calls this structure holds a block of items for a given directory
@@ -195,6 +196,12 @@ func (lf *Libfuse) Validate(opt *LibfuseOptions) error {
195196
lf.ownerUID = opt.Uid
196197
lf.umask = opt.Umask
197198

199+
if lf.disableKernelCache {
200+
opt.DirectIO = true
201+
lf.directIO = true
202+
log.Crit("Libfuse::Validate : Kernel cache disabled, setting direct-io mode in fuse")
203+
}
204+
198205
if opt.allowOther {
199206
lf.dirPermission = uint(common.DefaultAllowOtherPermissionBits)
200207
lf.filePermission = uint(common.DefaultAllowOtherPermissionBits)
@@ -326,6 +333,8 @@ func (lf *Libfuse) Configure(_ bool) error {
326333
return err
327334
}
328335

336+
_ = config.UnmarshalKey("disable-kernel-cache", &lf.disableKernelCache)
337+
329338
err = lf.Validate(&conf)
330339
if err != nil {
331340
log.Err("Libfuse::Configure : config error [invalid config settings]")
@@ -340,8 +349,8 @@ func (lf *Libfuse) Configure(_ bool) error {
340349
}
341350
}
342351

343-
log.Crit("Libfuse::Configure : read-only %t, allow-other %t, allow-root %t, default-perm %d, entry-timeout %d, attr-time %d, negative-timeout %d, ignore-open-flags %t, nonempty %t, direct_io %t, max-fuse-threads %d, fuse-trace %t, extension %s, disable-writeback-cache %t, dirPermission %v, mountPath %v, umask %v",
344-
lf.readOnly, lf.allowOther, lf.allowRoot, lf.filePermission, lf.entryExpiration, lf.attributeExpiration, lf.negativeTimeout, lf.ignoreOpenFlags, lf.nonEmptyMount, lf.directIO, lf.maxFuseThreads, lf.traceEnable, lf.extensionPath, lf.disableWritebackCache, lf.dirPermission, lf.mountPath, lf.umask)
352+
log.Crit("Libfuse::Configure : read-only %t, allow-other %t, allow-root %t, default-perm %d, entry-timeout %d, attr-time %d, negative-timeout %d, ignore-open-flags %t, nonempty %t, direct_io %t, max-fuse-threads %d, fuse-trace %t, extension %s, disable-writeback-cache %t, dirPermission %v, mountPath %v, umask %v, disableKernelCache %v",
353+
lf.readOnly, lf.allowOther, lf.allowRoot, lf.filePermission, lf.entryExpiration, lf.attributeExpiration, lf.negativeTimeout, lf.ignoreOpenFlags, lf.nonEmptyMount, lf.directIO, lf.maxFuseThreads, lf.traceEnable, lf.extensionPath, lf.disableWritebackCache, lf.dirPermission, lf.mountPath, lf.umask, lf.disableKernelCache)
345354

346355
return nil
347356
}

component/libfuse/libfuse_handler_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,20 @@ func (suite *libfuseTestSuite) TestConfigDefaultPermission() {
126126
suite.assert.True(suite.libfuse.directIO)
127127
}
128128

129+
func (suite *libfuseTestSuite) TestConfigDisableKernelCache() {
130+
defer suite.cleanupTest()
131+
suite.cleanupTest() // clean up the default libfuse generated
132+
config := "read-only: true\ndisable-kernel-cache: true\n\n"
133+
suite.setupTestHelper(config) // setup a new libfuse with a custom config (clean up will occur after the test as usual)
134+
135+
suite.assert.Equal(suite.libfuse.Name(), "libfuse")
136+
suite.assert.Empty(suite.libfuse.mountPath)
137+
suite.assert.Equal(suite.libfuse.entryExpiration, uint32(0))
138+
suite.assert.Equal(suite.libfuse.attributeExpiration, uint32(0))
139+
suite.assert.Equal(suite.libfuse.negativeTimeout, uint32(0))
140+
suite.assert.True(suite.libfuse.directIO)
141+
}
142+
129143
func (suite *libfuseTestSuite) TestConfigFuseTraceEnable() {
130144
defer suite.cleanupTest()
131145
suite.cleanupTest() // clean up the default libfuse generated

setup/advancedConfig.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ foreground: true|false <run blobfuse2 in foreground or background>
3434
# Common configurations
3535
allow-other: true|false <allow other users to access the mounted directory - used for FUSE and File Cache>
3636
nonempty: true|false <allow mounting on non-empty directory>
37+
disable-kernel-cache: true|false <disable kernel cache but keep blobfuse2 cache. Default - false>
3738

3839
# Dynamic profiler related configuration. This helps to root-cause high memory/cpu usage related issues.
3940
dynamic-profile: true|false <allows to turn on dynamic profiler for cpu/memory usage monitoring. Only for debugging, shall not be used in production>
@@ -67,7 +68,7 @@ libfuse:
6768
negative-entry-expiration-sec: <time kernel can cache attributes of non existent paths (in sec). Default - 120 sec>
6869
fuse-trace: true|false <enable libfuse api trace logs for debugging>
6970
extension: <physical path to extension library>
70-
direct-io: true|false <enable to bypass the kernel cache>
71+
direct-io: true|false <enable to bypass the kernel cache. It also disables blobfuse2 data and metadata caching. Default - false>
7172

7273
# Entry Cache configuration
7374
entry_cache:

0 commit comments

Comments
 (0)