add weedfuse

This commit is contained in:
Chris Lu
2019-05-10 15:03:31 -07:00
parent 69b7dd398d
commit 1ca1ec906a
4 changed files with 118 additions and 33 deletions

View File

@@ -4,9 +4,6 @@ package command
import ( import (
"fmt" "fmt"
"github.com/chrislusf/seaweedfs/weed/security"
"github.com/chrislusf/seaweedfs/weed/server"
"github.com/spf13/viper"
"os" "os"
"os/user" "os/user"
"path" "path"
@@ -15,6 +12,10 @@ import (
"strings" "strings"
"time" "time"
"github.com/chrislusf/seaweedfs/weed/security"
"github.com/chrislusf/seaweedfs/weed/server"
"github.com/spf13/viper"
"github.com/chrislusf/seaweedfs/weed/filesys" "github.com/chrislusf/seaweedfs/weed/filesys"
"github.com/chrislusf/seaweedfs/weed/glog" "github.com/chrislusf/seaweedfs/weed/glog"
"github.com/chrislusf/seaweedfs/weed/util" "github.com/chrislusf/seaweedfs/weed/util"
@@ -24,30 +25,51 @@ import (
func runMount(cmd *Command, args []string) bool { func runMount(cmd *Command, args []string) bool {
util.SetupProfiling(*mountCpuProfile, *mountMemProfile)
return RunMount(
*mountOptions.filer,
*mountOptions.filerMountRootPath,
*mountOptions.dir,
*mountOptions.collection,
*mountOptions.replication,
*mountOptions.dataCenter,
*mountOptions.chunkSizeLimitMB,
*mountOptions.allowOthers,
*mountOptions.ttlSec,
*mountOptions.dirListingLimit,
)
}
func RunMount(filer, filerMountRootPath, dir, collection, replication, dataCenter string, chunkSizeLimitMB int,
allowOthers bool, ttlSec int, dirListingLimit int) bool {
weed_server.LoadConfiguration("security", false) weed_server.LoadConfiguration("security", false)
fmt.Printf("This is SeaweedFS version %s %s %s\n", util.VERSION, runtime.GOOS, runtime.GOARCH) fmt.Printf("This is SeaweedFS version %s %s %s\n", util.VERSION, runtime.GOOS, runtime.GOARCH)
if *mountOptions.dir == "" { if dir == "" {
fmt.Printf("Please specify the mount directory via \"-dir\"") fmt.Printf("Please specify the mount directory via \"-dir\"")
return false return false
} }
if *mountOptions.chunkSizeLimitMB <= 0 { if chunkSizeLimitMB <= 0 {
fmt.Printf("Please specify a reasonable buffer size.") fmt.Printf("Please specify a reasonable buffer size.")
return false return false
} }
fuse.Unmount(*mountOptions.dir) fuse.Unmount(dir)
uid, gid := uint32(0), uint32(0)
// detect mount folder mode // detect mount folder mode
mountMode := os.ModeDir | 0755 mountMode := os.ModeDir | 0755
if fileInfo, err := os.Stat(*mountOptions.dir); err == nil { fileInfo, err := os.Stat(dir)
if err == nil {
mountMode = os.ModeDir | fileInfo.Mode() mountMode = os.ModeDir | fileInfo.Mode()
uid, gid = util.GetFileUidGid(fileInfo)
fmt.Printf("mount point owner uid=%d gid=%d mode=%s\n", uid, gid, fileInfo.Mode())
} }
mountName := path.Base(*mountOptions.dir) if uid == 0 {
// detect current user
uid, gid := uint32(0), uint32(0)
if u, err := user.Current(); err == nil { if u, err := user.Current(); err == nil {
if parsedId, pe := strconv.ParseUint(u.Uid, 10, 32); pe == nil { if parsedId, pe := strconv.ParseUint(u.Uid, 10, 32); pe == nil {
uid = uint32(parsedId) uid = uint32(parsedId)
@@ -55,9 +77,11 @@ func runMount(cmd *Command, args []string) bool {
if parsedId, pe := strconv.ParseUint(u.Gid, 10, 32); pe == nil { if parsedId, pe := strconv.ParseUint(u.Gid, 10, 32); pe == nil {
gid = uint32(parsedId) gid = uint32(parsedId)
} }
fmt.Printf("current uid=%d gid=%d\n", uid, gid)
}
} }
util.SetupProfiling(*mountCpuProfile, *mountMemProfile) mountName := path.Base(dir)
options := []fuse.MountOption{ options := []fuse.MountOption{
fuse.VolumeName(mountName), fuse.VolumeName(mountName),
@@ -76,28 +100,28 @@ func runMount(cmd *Command, args []string) bool {
fuse.WritebackCache(), fuse.WritebackCache(),
fuse.AllowNonEmptyMount(), fuse.AllowNonEmptyMount(),
} }
if *mountOptions.allowOthers { if allowOthers {
options = append(options, fuse.AllowOther()) options = append(options, fuse.AllowOther())
} }
c, err := fuse.Mount(*mountOptions.dir, options...) c, err := fuse.Mount(dir, options...)
if err != nil { if err != nil {
glog.Fatal(err) glog.Fatal(err)
return false return false
} }
util.OnInterrupt(func() { util.OnInterrupt(func() {
fuse.Unmount(*mountOptions.dir) fuse.Unmount(dir)
c.Close() c.Close()
}) })
filerGrpcAddress, err := parseFilerGrpcAddress(*mountOptions.filer) filerGrpcAddress, err := parseFilerGrpcAddress(filer)
if err != nil { if err != nil {
glog.Fatal(err) glog.Fatal(err)
return false return false
} }
mountRoot := *mountOptions.filerMountRootPath mountRoot := filerMountRootPath
if mountRoot != "/" && strings.HasSuffix(mountRoot, "/") { if mountRoot != "/" && strings.HasSuffix(mountRoot, "/") {
mountRoot = mountRoot[0 : len(mountRoot)-1] mountRoot = mountRoot[0 : len(mountRoot)-1]
} }
@@ -106,19 +130,21 @@ func runMount(cmd *Command, args []string) bool {
FilerGrpcAddress: filerGrpcAddress, FilerGrpcAddress: filerGrpcAddress,
GrpcDialOption: security.LoadClientTLS(viper.Sub("grpc"), "client"), GrpcDialOption: security.LoadClientTLS(viper.Sub("grpc"), "client"),
FilerMountRootPath: mountRoot, FilerMountRootPath: mountRoot,
Collection: *mountOptions.collection, Collection: collection,
Replication: *mountOptions.replication, Replication: replication,
TtlSec: int32(*mountOptions.ttlSec), TtlSec: int32(ttlSec),
ChunkSizeLimit: int64(*mountOptions.chunkSizeLimitMB) * 1024 * 1024, ChunkSizeLimit: int64(chunkSizeLimitMB) * 1024 * 1024,
DataCenter: *mountOptions.dataCenter, DataCenter: dataCenter,
DirListingLimit: *mountOptions.dirListingLimit, DirListingLimit: dirListingLimit,
EntryCacheTtl: 3 * time.Second, EntryCacheTtl: 3 * time.Second,
MountUid: uid, MountUid: uid,
MountGid: gid, MountGid: gid,
MountMode: mountMode, MountMode: mountMode,
MountCtime: fileInfo.ModTime(),
MountMtime: time.Now(),
})) }))
if err != nil { if err != nil {
fuse.Unmount(*mountOptions.dir) fuse.Unmount(dir)
} }
// check if the mount process has an error to report // check if the mount process has an error to report

View File

@@ -0,0 +1,49 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/chrislusf/seaweedfs/weed/command"
)
var (
options = flag.String("o", "", "comma separated options rw,uid=xxx,gid=xxx")
)
func main() {
flag.Parse()
device := flag.Arg(0)
mountPoint := flag.Arg(1)
fmt.Printf("source: %v\n", device)
fmt.Printf("target: %v\n", mountPoint)
maybeSetupPath()
parts := strings.SplitN(device, "/", 2)
filer, filerPath := parts[0], parts[1]
command.RunMount(
filer, "/"+filerPath, mountPoint, "", "000", "",
4, true, 0, 1000000)
}
func maybeSetupPath() {
// sudo mount -av may not include PATH in some linux, e.g., Ubuntu
hasPathEnv := false
for _, e := range os.Environ() {
if strings.HasPrefix(e, "PATH=") {
hasPathEnv = true
}
fmt.Println(e)
}
if !hasPathEnv {
os.Setenv("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")
}
}

View File

@@ -34,9 +34,7 @@ func (dir *Dir) Attr(ctx context.Context, attr *fuse.Attr) error {
attr.Valid = time.Second attr.Valid = time.Second
if dir.Path == dir.wfs.option.FilerMountRootPath { if dir.Path == dir.wfs.option.FilerMountRootPath {
attr.Uid = dir.wfs.option.MountUid dir.setRootDirAttributes(attr)
attr.Gid = dir.wfs.option.MountGid
attr.Mode = dir.wfs.option.MountMode
return nil return nil
} }
@@ -72,6 +70,16 @@ func (dir *Dir) Attr(ctx context.Context, attr *fuse.Attr) error {
return nil return nil
} }
func (dir *Dir) setRootDirAttributes(attr *fuse.Attr) {
attr.Uid = dir.wfs.option.MountUid
attr.Gid = dir.wfs.option.MountGid
attr.Mode = dir.wfs.option.MountMode
attr.Crtime = dir.wfs.option.MountCtime
attr.Ctime = dir.wfs.option.MountCtime
attr.Mtime = dir.wfs.option.MountMtime
attr.Atime = dir.wfs.option.MountMtime
}
func (dir *Dir) newFile(name string, entry *filer_pb.Entry) *File { func (dir *Dir) newFile(name string, entry *filer_pb.Entry) *File {
return &File{ return &File{
Name: name, Name: name,

View File

@@ -32,6 +32,8 @@ type Option struct {
MountUid uint32 MountUid uint32
MountGid uint32 MountGid uint32
MountMode os.FileMode MountMode os.FileMode
MountCtime time.Time
MountMtime time.Time
} }
var _ = fs.FS(&WFS{}) var _ = fs.FS(&WFS{})