aboutsummaryrefslogtreecommitdiff
path: root/weed/command/mount_std.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/command/mount_std.go')
-rw-r--r--weed/command/mount_std.go168
1 files changed, 73 insertions, 95 deletions
diff --git a/weed/command/mount_std.go b/weed/command/mount_std.go
index 8f62b4ec9..d865e053f 100644
--- a/weed/command/mount_std.go
+++ b/weed/command/mount_std.go
@@ -1,34 +1,28 @@
-//go:build linux || darwin || freebsd
-// +build linux darwin freebsd
+//go:build linux || darwin
+// +build linux darwin
package command
import (
"context"
"fmt"
+ "github.com/chrislusf/seaweedfs/weed/glog"
+ "github.com/chrislusf/seaweedfs/weed/mount"
+ "github.com/chrislusf/seaweedfs/weed/mount/meta_cache"
+ "github.com/chrislusf/seaweedfs/weed/mount/unmount"
+ "github.com/chrislusf/seaweedfs/weed/pb"
+ "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
+ "github.com/chrislusf/seaweedfs/weed/security"
+ "github.com/chrislusf/seaweedfs/weed/storage/types"
+ "github.com/hanwen/go-fuse/v2/fuse"
"net/http"
"os"
"os/user"
- "path"
- "path/filepath"
"runtime"
"strconv"
"strings"
- "syscall"
"time"
- "github.com/chrislusf/seaweedfs/weed/storage/types"
-
- "github.com/chrislusf/seaweedfs/weed/filesys/meta_cache"
-
- "github.com/seaweedfs/fuse"
- "github.com/seaweedfs/fuse/fs"
-
- "github.com/chrislusf/seaweedfs/weed/filesys"
- "github.com/chrislusf/seaweedfs/weed/glog"
- "github.com/chrislusf/seaweedfs/weed/pb"
- "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
- "github.com/chrislusf/seaweedfs/weed/security"
"github.com/chrislusf/seaweedfs/weed/util"
"github.com/chrislusf/seaweedfs/weed/util/grace"
)
@@ -58,27 +52,18 @@ func runMount(cmd *Command, args []string) bool {
return RunMount(&mountOptions, os.FileMode(umask))
}
-func getParentInode(mountDir string) (uint64, error) {
- parentDir := filepath.Clean(filepath.Join(mountDir, ".."))
- fi, err := os.Stat(parentDir)
- if err != nil {
- return 0, err
- }
+func RunMount(option *MountOptions, umask os.FileMode) bool {
- stat, ok := fi.Sys().(*syscall.Stat_t)
- if !ok {
- return 0, nil
+ // basic checks
+ chunkSizeLimitMB := *mountOptions.chunkSizeLimitMB
+ if chunkSizeLimitMB <= 0 {
+ fmt.Printf("Please specify a reasonable buffer size.")
+ return false
}
- return stat.Ino, nil
-}
-
-func RunMount(option *MountOptions, umask os.FileMode) bool {
-
+ // try to connect to filer
filerAddresses := pb.ServerAddresses(*option.filer).ToAddresses()
-
util.LoadConfiguration("security", false)
- // try to connect to filer, filerBucketsPath may be useful later
grpcDialOption := security.LoadClientTLS(util.GetViper(), "grpc.client")
var cipher bool
var err error
@@ -103,26 +88,15 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
}
filerMountRootPath := *option.filerMountRootPath
- dir := util.ResolvePath(*option.dir)
- parentInode, err := getParentInode(dir)
- if err != nil {
- glog.Errorf("failed to retrieve inode for parent directory of %s: %v", dir, err)
- return true
- }
- fmt.Printf("This is SeaweedFS version %s %s %s\n", util.Version(), runtime.GOOS, runtime.GOARCH)
+ // clean up mount point
+ dir := util.ResolvePath(*option.dir)
if dir == "" {
fmt.Printf("Please specify the mount directory via \"-dir\"")
return false
}
- chunkSizeLimitMB := *mountOptions.chunkSizeLimitMB
- if chunkSizeLimitMB <= 0 {
- fmt.Printf("Please specify a reasonable buffer size.")
- return false
- }
-
- fuse.Unmount(dir)
+ unmount.Unmount(dir)
// detect mount folder mode
if *option.dirAutoCreate {
@@ -130,6 +104,7 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
}
fileInfo, err := os.Stat(dir)
+ // collect uid, gid
uid, gid := uint32(0), uint32(0)
mountMode := os.ModeDir | 0777
if err == nil {
@@ -141,6 +116,7 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
return false
}
+ // detect uid, gid
if uid == 0 {
if u, err := user.Current(); err == nil {
if parsedId, pe := strconv.ParseUint(u.Uid, 10, 32); pe == nil {
@@ -166,35 +142,51 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
return true
}
- mountName := path.Base(dir)
-
- options := []fuse.MountOption{
- fuse.VolumeName(mountName),
- fuse.FSName(*option.filer + ":" + filerMountRootPath),
- fuse.Subtype("seaweedfs"),
- // fuse.NoAppleDouble(), // include .DS_Store, otherwise can not delete non-empty folders
- fuse.NoAppleXattr(),
- fuse.ExclCreate(),
- fuse.DaemonTimeout("3600"),
- fuse.AllowDev(),
- fuse.AllowSUID(),
- fuse.DefaultPermissions(),
- fuse.MaxReadahead(1024 * 512),
- fuse.AsyncRead(),
- // fuse.WritebackCache(),
- // fuse.MaxBackground(1024),
- // fuse.CongestionThreshold(1024),
- }
-
- options = append(options, osSpecificMountOptions()...)
- if *option.allowOthers {
- options = append(options, fuse.AllowOther())
+ serverFriendlyName := strings.ReplaceAll(*option.filer, ",", "+")
+
+ // mount fuse
+ fuseMountOptions := &fuse.MountOptions{
+ AllowOther: *option.allowOthers,
+ Options: nil,
+ MaxBackground: 128,
+ MaxWrite: 1024 * 1024 * 2,
+ MaxReadAhead: 1024 * 1024 * 2,
+ IgnoreSecurityLabels: false,
+ RememberInodes: false,
+ FsName: serverFriendlyName + ":" + filerMountRootPath,
+ Name: "seaweedfs",
+ SingleThreaded: false,
+ DisableXAttrs: false,
+ Debug: *option.debug,
+ EnableLocks: false,
+ ExplicitDataCacheControl: false,
+ DirectMount: true,
+ DirectMountFlags: 0,
+ //SyncRead: false, // set to false to enable the FUSE_CAP_ASYNC_READ capability
+ //EnableAcl: true,
}
if *option.nonempty {
- options = append(options, fuse.AllowNonEmptyMount())
+ fuseMountOptions.Options = append(fuseMountOptions.Options, "nonempty")
}
if *option.readOnly {
- options = append(options, fuse.ReadOnly())
+ if runtime.GOOS == "darwin" {
+ fuseMountOptions.Options = append(fuseMountOptions.Options, "rdonly")
+ } else {
+ fuseMountOptions.Options = append(fuseMountOptions.Options, "ro")
+ }
+ }
+ if runtime.GOOS == "darwin" {
+ // https://github-wiki-see.page/m/macfuse/macfuse/wiki/Mount-Options
+ ioSizeMB := 1
+ for ioSizeMB*2 <= *option.chunkSizeLimitMB && ioSizeMB*2 <= 32 {
+ ioSizeMB *= 2
+ }
+ fuseMountOptions.Options = append(fuseMountOptions.Options, "daemon_timeout=600")
+ fuseMountOptions.Options = append(fuseMountOptions.Options, "noapplexattr")
+ // fuseMountOptions.Options = append(fuseMountOptions.Options, "novncache") // need to test effectiveness
+ fuseMountOptions.Options = append(fuseMountOptions.Options, "slow_statfs")
+ fuseMountOptions.Options = append(fuseMountOptions.Options, "volname="+serverFriendlyName)
+ fuseMountOptions.Options = append(fuseMountOptions.Options, fmt.Sprintf("iosize=%d", ioSizeMB*1024*1024))
}
// find mount point
@@ -203,9 +195,7 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
mountRoot = mountRoot[0 : len(mountRoot)-1]
}
- diskType := types.ToDiskType(*option.diskType)
-
- seaweedFileSystem := filesys.NewSeaweedFileSystem(&filesys.Option{
+ seaweedFileSystem := mount.NewSeaweedFileSystem(&mount.Option{
MountDirectory: dir,
FilerAddresses: filerAddresses,
GrpcDialOption: grpcDialOption,
@@ -213,49 +203,37 @@ func RunMount(option *MountOptions, umask os.FileMode) bool {
Collection: *option.collection,
Replication: *option.replication,
TtlSec: int32(*option.ttlSec),
- DiskType: diskType,
+ DiskType: types.ToDiskType(*option.diskType),
ChunkSizeLimit: int64(chunkSizeLimitMB) * 1024 * 1024,
ConcurrentWriters: *option.concurrentWriters,
CacheDir: *option.cacheDir,
CacheSizeMB: *option.cacheSizeMB,
DataCenter: *option.dataCenter,
+ Quota: int64(*option.collectionQuota) * 1024 * 1024,
MountUid: uid,
MountGid: gid,
MountMode: mountMode,
MountCtime: fileInfo.ModTime(),
MountMtime: time.Now(),
- MountParentInode: parentInode,
Umask: umask,
VolumeServerAccess: *mountOptions.volumeServerAccess,
Cipher: cipher,
UidGidMapper: uidGidMapper,
})
- // mount
- c, err := fuse.Mount(dir, options...)
+ server, err := fuse.NewServer(seaweedFileSystem, dir, fuseMountOptions)
if err != nil {
- glog.V(0).Infof("mount: %v", err)
- return true
+ glog.Fatalf("Mount fail: %v", err)
}
- defer fuse.Unmount(dir)
-
grace.OnInterrupt(func() {
- fuse.Unmount(dir)
- c.Close()
+ unmount.Unmount(dir)
})
- glog.V(0).Infof("mounted %s%s to %v", *option.filer, mountRoot, dir)
- server := fs.New(c, nil)
- seaweedFileSystem.Server = server
seaweedFileSystem.StartBackgroundTasks()
- err = server.Serve(seaweedFileSystem)
- // check if the mount process has an error to report
- <-c.Ready
- if err := c.MountError; err != nil {
- glog.V(0).Infof("mount process: %v", err)
- return true
- }
+ fmt.Printf("This is SeaweedFS version %s %s %s\n", util.Version(), runtime.GOOS, runtime.GOARCH)
+
+ server.Serve()
return true
}