|
@ -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) |
|
|
|
|
|
|
|
|
|
|
|
// detect current user
|
|
|
|
|
|
uid, gid := uint32(0), uint32(0) |
|
|
|
|
|
|
|
|
if uid == 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, |
|
|
|
|
|
Replication: *mountOptions.replication, |
|
|
|
|
|
TtlSec: int32(*mountOptions.ttlSec), |
|
|
|
|
|
ChunkSizeLimit: int64(*mountOptions.chunkSizeLimitMB) * 1024 * 1024, |
|
|
|
|
|
DataCenter: *mountOptions.dataCenter, |
|
|
|
|
|
DirListingLimit: *mountOptions.dirListingLimit, |
|
|
|
|
|
|
|
|
Collection: collection, |
|
|
|
|
|
Replication: replication, |
|
|
|
|
|
TtlSec: int32(ttlSec), |
|
|
|
|
|
ChunkSizeLimit: int64(chunkSizeLimitMB) * 1024 * 1024, |
|
|
|
|
|
DataCenter: dataCenter, |
|
|
|
|
|
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
|
|
|