Skip to content

Commit

Permalink
[PR-2][Phase1 Implementation] Ignore GCSFuse interrupts (#1860)
Browse files Browse the repository at this point in the history
* implementation for ignoring interrupts

* refactoring and unit tests

* update flag

* add integration tests

* lint fixes

* use mount config instead of flag

* update integration tests to include config file

* update integration tests to include config file

* review comments

* run tests only for static mounting

* minor update to comments

* minor log fix

* rebase changes

* typo in function name

* review comments

* review comments
  • Loading branch information
ashmeenkaur authored May 2, 2024
1 parent 485cd8d commit 4499126
Show file tree
Hide file tree
Showing 9 changed files with 415 additions and 60 deletions.
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require (
github.com/jacobsa/syncutil v0.0.0-20180201203307-228ac8e5a6c3
github.com/jacobsa/timeutil v0.0.0-20170205232429-577e5acbbcf6
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0
github.com/stretchr/testify v1.9.0
github.com/urfave/cli v1.22.14
go.opencensus.io v0.24.0
golang.org/x/net v0.22.0
Expand Down Expand Up @@ -46,6 +47,7 @@ require (
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/envoyproxy/go-control-plane v0.12.0 // indirect
github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
Expand All @@ -61,6 +63,7 @@ require (
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/pkg/xattr v0.4.9 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/prometheus v0.35.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
Expand Down
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1076,8 +1076,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
Expand Down
121 changes: 113 additions & 8 deletions internal/fs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package fs

import (
"context"
"errors"
"fmt"
"io"
Expand All @@ -30,7 +31,7 @@ import (
"github.com/googlecloudplatform/gcsfuse/v2/internal/cache/file"
"github.com/googlecloudplatform/gcsfuse/v2/internal/cache/file/downloader"
"github.com/googlecloudplatform/gcsfuse/v2/internal/cache/lru"
"github.com/googlecloudplatform/gcsfuse/v2/internal/cache/util"
cacheutil "github.com/googlecloudplatform/gcsfuse/v2/internal/cache/util"
"github.com/googlecloudplatform/gcsfuse/v2/internal/config"
"github.com/googlecloudplatform/gcsfuse/v2/internal/contentcache"
"github.com/googlecloudplatform/gcsfuse/v2/internal/fs/handle"
Expand All @@ -39,11 +40,11 @@ import (
"github.com/googlecloudplatform/gcsfuse/v2/internal/locker"
"github.com/googlecloudplatform/gcsfuse/v2/internal/logger"
"github.com/googlecloudplatform/gcsfuse/v2/internal/storage/gcs"
"github.com/googlecloudplatform/gcsfuse/v2/internal/util"
"github.com/jacobsa/fuse"
"github.com/jacobsa/fuse/fuseops"
"github.com/jacobsa/fuse/fuseutil"
"github.com/jacobsa/timeutil"
"golang.org/x/net/context"
)

type ServerConfig struct {
Expand Down Expand Up @@ -223,20 +224,20 @@ func createFileCacheHandler(cfg *ServerConfig) (fileCacheHandler *file.CacheHand
if cfg.MountConfig.FileCacheConfig.MaxSizeMB == -1 {
sizeInBytes = math.MaxUint64
} else {
sizeInBytes = uint64(cfg.MountConfig.FileCacheConfig.MaxSizeMB) * util.MiB
sizeInBytes = uint64(cfg.MountConfig.FileCacheConfig.MaxSizeMB) * cacheutil.MiB
}
fileInfoCache := lru.NewCache(sizeInBytes)

cacheDir := string(cfg.MountConfig.CacheDir)
// Adding a new directory inside cacheDir to keep file-cache separate from
// metadata cache if and when we support storing metadata cache on disk in
// the future.
cacheDir = path.Join(cacheDir, util.FileCache)
cacheDir = path.Join(cacheDir, cacheutil.FileCache)

filePerm := util.DefaultFilePerm
dirPerm := util.DefaultDirPerm
filePerm := cacheutil.DefaultFilePerm
dirPerm := cacheutil.DefaultDirPerm

cacheDirErr := util.CreateCacheDirectoryIfNotPresentAt(cacheDir, dirPerm)
cacheDirErr := cacheutil.CreateCacheDirectoryIfNotPresentAt(cacheDir, dirPerm)
if cacheDirErr != nil {
return nil, fmt.Errorf("createFileCacheHandler: while creating file cache directory: %w", cacheDirErr)
}
Expand Down Expand Up @@ -1313,6 +1314,13 @@ func (fs *fileSystem) StatFS(
func (fs *fileSystem) LookUpInode(
ctx context.Context,
op *fuseops.LookUpInodeOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the parent directory in question.
fs.mu.Lock()
parent := fs.dirInodeOrDie(op.Parent)
Expand Down Expand Up @@ -1342,6 +1350,13 @@ func (fs *fileSystem) LookUpInode(
func (fs *fileSystem) GetInodeAttributes(
ctx context.Context,
op *fuseops.GetInodeAttributesOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the inode.
fs.mu.Lock()
in := fs.inodeOrDie(op.Inode)
Expand All @@ -1363,6 +1378,13 @@ func (fs *fileSystem) GetInodeAttributes(
func (fs *fileSystem) SetInodeAttributes(
ctx context.Context,
op *fuseops.SetInodeAttributesOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the inode.
fs.mu.Lock()
in := fs.inodeOrDie(op.Inode)
Expand Down Expand Up @@ -1422,6 +1444,13 @@ func (fs *fileSystem) ForgetInode(
func (fs *fileSystem) MkDir(
ctx context.Context,
op *fuseops.MkDirOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the parent.
fs.mu.Lock()
parent := fs.dirInodeOrDie(op.Parent)
Expand Down Expand Up @@ -1474,6 +1503,13 @@ func (fs *fileSystem) MkDir(
func (fs *fileSystem) MkNode(
ctx context.Context,
op *fuseops.MkNodeOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
if (op.Mode & (iofs.ModeNamedPipe | iofs.ModeSocket)) != 0 {
return syscall.ENOTSUP
}
Expand Down Expand Up @@ -1597,6 +1633,13 @@ func (fs *fileSystem) createLocalFile(
func (fs *fileSystem) CreateFile(
ctx context.Context,
op *fuseops.CreateFileOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Create the child.
var child inode.Inode
if fs.mountConfig.CreateEmptyFile {
Expand Down Expand Up @@ -1639,6 +1682,13 @@ func (fs *fileSystem) CreateFile(
func (fs *fileSystem) CreateSymlink(
ctx context.Context,
op *fuseops.CreateSymlinkOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the parent.
fs.mu.Lock()
parent := fs.dirInodeOrDie(op.Parent)
Expand Down Expand Up @@ -1702,6 +1752,13 @@ func (fs *fileSystem) RmDir(

ctx context.Context,
op *fuseops.RmDirOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the parent.
fs.mu.Lock()
parent := fs.dirInodeOrDie(op.Parent)
Expand Down Expand Up @@ -1797,6 +1854,13 @@ func (fs *fileSystem) RmDir(
func (fs *fileSystem) Rename(
ctx context.Context,
op *fuseops.RenameOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the old and new parents.
fs.mu.Lock()
oldParent := fs.dirInodeOrDie(op.OldParent)
Expand Down Expand Up @@ -2009,6 +2073,13 @@ func (fs *fileSystem) renameDir(
func (fs *fileSystem) Unlink(
ctx context.Context,
op *fuseops.UnlinkOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the parent.
fs.mu.Lock()
parent := fs.dirInodeOrDie(op.Parent)
Expand Down Expand Up @@ -2077,6 +2148,13 @@ func (fs *fileSystem) OpenDir(
func (fs *fileSystem) ReadDir(
ctx context.Context,
op *fuseops.ReadDirOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the handle.
fs.mu.Lock()
dh := fs.handles[op.Handle].(*handle.DirHandle)
Expand Down Expand Up @@ -2142,7 +2220,13 @@ func (fs *fileSystem) OpenFile(
func (fs *fileSystem) ReadFile(
ctx context.Context,
op *fuseops.ReadFileOp) (err error) {

if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Save readOp in context for access in logs.
ctx = context.WithValue(ctx, gcsx.ReadOp, op)

Expand Down Expand Up @@ -2187,6 +2271,13 @@ func (fs *fileSystem) ReadSymlink(
func (fs *fileSystem) WriteFile(
ctx context.Context,
op *fuseops.WriteFileOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the inode.
fs.mu.Lock()
in := fs.fileInodeOrDie(op.Inode)
Expand All @@ -2207,6 +2298,13 @@ func (fs *fileSystem) WriteFile(
func (fs *fileSystem) SyncFile(
ctx context.Context,
op *fuseops.SyncFileOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the inode.
fs.mu.Lock()
in := fs.inodeOrDie(op.Inode)
Expand All @@ -2233,6 +2331,13 @@ func (fs *fileSystem) SyncFile(
func (fs *fileSystem) FlushFile(
ctx context.Context,
op *fuseops.FlushFileOp) (err error) {
if fs.mountConfig.FileSystemConfig.IgnoreInterrupts {
// When ignore interrupts config is set, we are creating a new context not
// cancellable by parent context.
var cancel context.CancelFunc
ctx, cancel = util.IsolateContextFromParentContext(ctx)
defer cancel()
}
// Find the inode.
fs.mu.Lock()
in := fs.fileInodeOrDie(op.Inode)
Expand Down
8 changes: 8 additions & 0 deletions internal/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package util

import (
"context"
"encoding/json"
"fmt"
"math"
Expand Down Expand Up @@ -102,3 +103,10 @@ func BytesToHigherMiBs(bytes uint64) uint64 {
const bytesInOneMiB uint64 = 1 << 20
return uint64(math.Ceil(float64(bytes) / float64(bytesInOneMiB)))
}

// IsolateContextFromParentContext creates a copy of the parent context which is
// not cancelled when parent context is cancelled.
func IsolateContextFromParentContext(ctx context.Context) (context.Context, context.CancelFunc) {
ctx = context.WithoutCancel(ctx)
return context.WithCancel(ctx)
}
Loading

0 comments on commit 4499126

Please sign in to comment.