作者:nc
项目:rclon
// mountOptions configures the options from the command line flags
func mountOptions(device string) (options []fuse.MountOption) {
options = []fuse.MountOption{
fuse.MaxReadahead(uint32(maxReadAhead)),
fuse.Subtype("rclone"),
fuse.FSName(device), fuse.VolumeName(device),
fuse.NoAppleDouble(),
fuse.NoAppleXattr(),
// Options from benchmarking in the fuse module
//fuse.MaxReadahead(64 * 1024 * 1024),
//fuse.AsyncRead(), - FIXME this causes
// ReadFileHandle.Read error: read /home/files/ISOs/xubuntu-15.10-desktop-amd64.iso: bad file descriptor
// which is probably related to errors people are having
//fuse.WritebackCache(),
}
if allowNonEmpty {
options = append(options, fuse.AllowNonEmptyMount())
}
if allowOther {
options = append(options, fuse.AllowOther())
}
if allowRoot {
options = append(options, fuse.AllowRoot())
}
if defaultPermissions {
options = append(options, fuse.DefaultPermissions())
}
if readOnly {
options = append(options, fuse.ReadOnly())
}
if writebackCache {
options = append(options, fuse.WritebackCache())
}
return options
}
作者:mehulsbhat
项目:pachyder
func (m *mounter) Mount(
address string,
mountPoint string,
shard uint64,
modulus uint64,
) (retErr error) {
// TODO: should we make the caller do this?
if err := os.MkdirAll(mountPoint, 0777); err != nil {
return err
}
name := namePrefix + address
conn, err := fuse.Mount(
mountPoint,
fuse.FSName(name),
fuse.VolumeName(name),
fuse.Subtype(subtype),
fuse.AllowOther(),
fuse.WritebackCache(),
fuse.MaxReadahead(1<<32-1),
)
if err != nil {
return err
}
defer func() {
if err := conn.Close(); err != nil && retErr == nil {
retErr = err
}
}()
if err := fs.Serve(conn, newFilesystem(m.apiClient, shard, modulus)); err != nil {
return err
}
<-conn.Ready
return conn.MountError
}
作者:saakaifoundr
项目:pachyder
func (m *mounter) Mount(
mountPoint string,
shard *pfsclient.Shard,
commitMounts []*CommitMount,
ready chan bool,
debug bool,
) (retErr error) {
var once sync.Once
defer once.Do(func() {
if ready != nil {
close(ready)
}
})
name := namePrefix + m.address
conn, err := fuse.Mount(
mountPoint,
fuse.FSName(name),
fuse.VolumeName(name),
fuse.Subtype(subtype),
fuse.AllowOther(),
fuse.WritebackCache(),
fuse.MaxReadahead(1<<32-1),
)
if err != nil {
return err
}
defer func() {
if err := conn.Close(); err != nil && retErr == nil {
retErr = err
}
}()
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt)
go func() {
<-sigChan
m.Unmount(mountPoint)
}()
once.Do(func() {
if ready != nil {
close(ready)
}
})
config := &fs.Config{}
if debug {
config.Debug = func(msg interface{}) { lion.Printf("%+v", msg) }
}
if err := fs.New(conn, config).Serve(newFilesystem(m.apiClient, shard, commitMounts)); err != nil {
return err
}
<-conn.Ready
return conn.MountError
}
作者:GoogleCloudPlatfor
项目:cloudsql-prox
// NewConnSrc returns a source of new connections based on Lookups in the
// provided mount directory. If there isn't a directory located at tmpdir one
// is created. The second return parameter can be used to shutdown and release
// any resources. As a result of this shutdown, or during any other fatal
// error, the returned chan will be closed.
//
// The connset parameter is optional.
func NewConnSrc(mountdir, tmpdir string, connset *proxy.ConnSet) (<-chan proxy.Conn, io.Closer, error) {
if err := os.MkdirAll(tmpdir, 0777); err != nil {
return nil, nil, err
}
if err := fuse.Unmount(mountdir); err != nil {
// The error is too verbose to be useful to print out
}
log.Printf("Mounting %v...", mountdir)
c, err := fuse.Mount(mountdir, fuse.AllowOther())
if err != nil {
return nil, nil, fmt.Errorf("cannot mount %q: %v", mountdir, err)
}
log.Printf("Mounted %v", mountdir)
if connset == nil {
// Make a dummy one.
connset = proxy.NewConnSet()
}
conns := make(chan proxy.Conn, 1)
root := &fsRoot{
tmpDir: tmpdir,
linkDir: mountdir,
dst: conns,
links: make(map[string]symlink),
closers: []io.Closer{c},
connset: connset,
}
server := fs.New(c, &fs.Config{
Debug: func(msg interface{}) {
if false {
log.Print(msg)
}
},
})
go func() {
if err := server.Serve(root); err != nil {
log.Printf("serve %q exited due to error: %v", mountdir, err)
}
// The server exited but we don't know whether this is because of a
// graceful reason (via root.Close) or via an external force unmounting.
// Closing the root will ensure the 'dst' chan is closed correctly to
// signify that no new connections are possible.
if err := root.Close(); err != nil {
log.Printf("root.Close() error: %v", err)
}
log.Printf("FUSE exited")
}()
return conns, root, nil
}
作者:pellaeo
项目:fus
func TestMountOptionAllowRootThenAllowOther(t *testing.T) {
t.Parallel()
mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{fstestutil.Dir{}},
fuse.AllowRoot(),
fuse.AllowOther(),
)
if err == nil {
mnt.Close()
}
if g, e := err, fuse.ErrCannotCombineAllowOtherAndAllowRoot; g != e {
t.Fatalf("wrong error: %v != %v", g, e)
}
}
作者:Microsof
项目:hdfs-moun
// Mounts the filesystem
func (this *FileSystem) Mount() (*fuse.Conn, error) {
conn, err := fuse.Mount(
this.MountPoint,
fuse.FSName("hdfs"),
fuse.Subtype("hdfs"),
fuse.VolumeName("HDFS filesystem"),
fuse.AllowOther(),
fuse.WritebackCache(),
fuse.MaxReadahead(1024*64)) //TODO: make configurable
if err != nil {
return nil, err
}
this.Mounted = true
return conn, nil
}
作者:berea
项目:pachyder
func (m *mounter) Mount(
repositoryName string,
commitID string,
mountPoint string,
shard uint64,
modulus uint64,
) (retErr error) {
// TODO(pedge): should we make the caller do this?
if err := os.MkdirAll(mountPoint, 0777); err != nil {
return err
}
name := namePrefix + repositoryName
if commitID != "" {
name = name + "-" + commitID
}
conn, err := fuse.Mount(
mountPoint,
fuse.FSName(name),
fuse.VolumeName(name),
fuse.Subtype(subtype),
fuse.AllowOther(),
fuse.WritebackCache(),
fuse.MaxReadahead(1<<32-1),
)
if err != nil {
return err
}
errChan := make(chan error, 1)
m.lock.Lock()
if _, ok := m.mountpointToErrChan[mountPoint]; ok {
m.lock.Unlock()
return fmt.Errorf("mountpoint %s already exists", mountPoint)
}
m.mountpointToErrChan[mountPoint] = errChan
m.lock.Unlock()
go func() {
err := fs.Serve(conn, newFilesystem(m.apiClient, repositoryName, commitID, shard, modulus))
closeErr := conn.Close()
if err != nil {
errChan <- err
} else {
errChan <- closeErr
}
}()
<-conn.Ready
return conn.MountError
}
作者:angelabier
项目:pachyder
func (m *mounter) Mount(
mountPoint string,
shard *pfs.Shard,
commitMounts []*CommitMount,
ready chan bool,
) (retErr error) {
var once sync.Once
defer once.Do(func() {
if ready != nil {
close(ready)
}
})
// TODO: should we make the caller do this?
if err := os.MkdirAll(mountPoint, 0777); err != nil {
return err
}
name := namePrefix + m.address
conn, err := fuse.Mount(
mountPoint,
fuse.FSName(name),
fuse.VolumeName(name),
fuse.Subtype(subtype),
fuse.AllowOther(),
fuse.WritebackCache(),
fuse.MaxReadahead(1<<32-1),
)
if err != nil {
return err
}
defer func() {
if err := conn.Close(); err != nil && retErr == nil {
retErr = err
}
}()
once.Do(func() {
if ready != nil {
close(ready)
}
})
if err := fs.Serve(conn, newFilesystem(m.apiClient, shard, commitMounts)); err != nil {
return err
}
<-conn.Ready
return conn.MountError
}
作者:dankomiocevi
项目:mulif
// mount calls the fuse library to specify
// the details of the mounted filesystem.
func mount(path, mountpoint string) error {
// TODO: Check that there is no folder named
mountOptions := []fuse.MountOption{
fuse.FSName("MuLi"),
fuse.Subtype("MuLiFS"),
fuse.LocalVolume(),
fuse.VolumeName("Music Library"),
}
if config_params.allow_users {
mountOptions = append(mountOptions, fuse.AllowOther())
} else {
if config_params.allow_root {
mountOptions = append(mountOptions, fuse.AllowRoot())
}
}
// playlist or drop in the path.
c, err := fuse.Mount(
mountpoint, mountOptions...)
if err != nil {
return err
}
defer c.Close()
filesys := &FS{
mPoint: path,
}
if err := fs.Serve(c, filesys); err != nil {
return err
}
// check if the mount process has an error to report
<-c.Ready
if err := c.MountError; err != nil {
return err
}
return nil
}
作者:ov
项目:svf
func mountOptions(device string) (options []fuse.MountOption) {
if svfs.AllowOther {
options = append(options, fuse.AllowOther())
}
if svfs.AllowRoot {
options = append(options, fuse.AllowRoot())
}
if svfs.DefaultPermissions {
options = append(options, fuse.DefaultPermissions())
}
if svfs.ReadOnly {
options = append(options, fuse.ReadOnly())
}
options = append(options, fuse.MaxReadahead(uint32(svfs.ReadAheadSize)))
options = append(options, fuse.Subtype("svfs"))
options = append(options, fuse.FSName(device))
return options
}
作者:elgutierre
项目:mirrorf
func main() {
flag.Usage = usage
flag.Parse()
if *mount == "" || *mirror == "" {
usage()
os.Exit(2)
}
c, err := fuse.Mount(
*mount,
fuse.FSName("mirrorfs"),
fuse.Subtype("mirrorfs"),
fuse.VolumeName("Mirror FS"),
// fuse.LocalVolume(),
fuse.AllowOther(),
)
if err != nil {
log.Fatal(err)
}
defer c.Close()
cfg := &fs.Config{}
if *debug {
cfg.Debug = debugLog
}
srv := fs.New(c, cfg)
filesys := mirrorfs.NewMirrorFS(*mirror)
if err := srv.Serve(filesys); err != nil {
log.Fatal(err)
}
// Check if the mount process has an error to report.
<-c.Ready
if err := c.MountError; err != nil {
log.Fatal(err)
}
}
作者:chenchu
项目:cgroupf
func Serve(mountPoint, cgroupDir string) error {
c, err := fuse.Mount(
mountPoint,
fuse.FSName("cgroupfs"),
fuse.Subtype("cgroupfs"),
fuse.LocalVolume(),
fuse.VolumeName("cgroup volume"),
fuse.AllowOther(),
)
if err != nil {
return err
}
defer c.Close()
go handleStopSignals(mountPoint)
var srv *fusefs.Server
if os.Getenv("FUSE_DEBUG") != "" {
srv = fusefs.New(c, &fusefs.Config{
Debug: func(msg interface{}) {
fmt.Printf("%s\n", msg)
},
})
} else {
srv = fusefs.New(c, nil)
}
err = srv.Serve(fs.FS{cgroupDir})
if err != nil {
return err
}
// check if the mount process has an error to report
<-c.Ready
if err := c.MountError; err != nil {
return err
}
return nil
}
作者:chzye
项目:simsat
func process(c *Config) (conn *fuse.Conn, err error) {
if err = fuse.Unmount(c.Base); err == nil {
logex.Info("last not unmount")
time.Sleep(1000 * time.Millisecond)
err = nil
} else {
err = nil
}
ops := []fuse.MountOption{
fuse.AllowOther(),
fuse.FSName(FsName),
fuse.LocalVolume(),
}
conn, err = fuse.Mount(c.Base, ops...)
if err != nil {
return nil, logex.Trace(err)
}
go fs.Serve(conn, NewTree("/", c.Target))
logex.Info("connected.")
return conn, nil
}
作者:Meroviu
项目:etcdf
func run() error {
flag.Usage = usage
flag.Parse()
if *debug {
fuse.Debug = func(v interface{}) { log.Println("[fuse]", v) }
}
var subdir, mountpoint string
switch flag.NArg() {
case 1:
subdir = "/"
mountpoint = flag.Arg(0)
case 2:
subdir = path.Join("/", flag.Arg(0))
mountpoint = flag.Arg(1)
default:
usage()
os.Exit(1)
}
var endpoints []string
if ep := os.Getenv("ETCD_ENDPOINTS"); ep != "" {
endpoints = strings.Split(ep, ",")
} else {
endpoints = []string{"localhost:4001"}
}
log.Printf("Using endpoints %v", endpoints)
cfg := client.Config{
Endpoints: endpoints,
}
etcd, err := client.New(cfg)
if err != nil {
return err
}
var mountOpts []fuse.MountOption
if *allowOther {
mountOpts = append(mountOpts, fuse.AllowOther())
}
if *allowRoot {
mountOpts = append(mountOpts, fuse.AllowRoot())
}
mountOpts = append(mountOpts, fuse.DefaultPermissions())
mountOpts = append(mountOpts, fuse.FSName("etcd:"+subdir))
mountOpts = append(mountOpts, fuse.ReadOnly())
mountOpts = append(mountOpts, fuse.Subtype("etcdFS"))
log.Printf("Mounting etcd:%s to %s", subdir, mountpoint)
c, err := fuse.Mount(
mountpoint,
mountOpts...,
)
if err != nil {
return err
}
defer c.Close()
srv := fs.New(c, nil)
filesys := &etcdFS{
etcd: client.NewKeysAPI(etcd),
base: subdir,
}
errch := make(chan error)
log.Printf("Start serving")
go func() {
errch <- srv.Serve(filesys)
}()
<-c.Ready
if c.MountError != nil {
return c.MountError
}
sigs := make(chan os.Signal)
signal.Notify(sigs, syscall.SIGHUP, syscall.SIGINT, syscall.SIGKILL, syscall.SIGTERM)
select {
case err := <-errch:
return err
case s := <-sigs:
log.Printf("Caught signal: %v", s)
err := c.Close()
log.Printf("Error: %v", err)
return err
}
}
作者:hatchlin
项目:fuse_gdriv
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
runtime.SetBlockProfileRate(1)
flag.Usage = Usage
flag.Parse()
if flag.NArg() != 1 {
Usage()
os.Exit(2)
}
mountpoint := flag.Arg(0)
if *debugGdrive {
debug = true
}
userCurrent, err := user.Current()
if err != nil {
log.Fatalf("unable to get UID/GID of current user: %v", err)
}
uidInt, err := strconv.Atoi(userCurrent.Uid)
if err != nil {
log.Fatalf("unable to get UID/GID of current user: %v", err)
}
uid := uint32(uidInt)
gidInt, err := strconv.Atoi(userCurrent.Gid)
if err != nil {
log.Fatalf("unable to get UID/GID of current user: %v", err)
}
gid := uint32(gidInt)
if err = sanityCheck(mountpoint); err != nil {
log.Fatalf("sanityCheck failed: %s\n", err)
}
http.HandleFunc("/", RootHandler)
go http.ListenAndServe(fmt.Sprintf("localhost:%s", *port), nil)
var client *http.Client
if *readOnly {
client = getOAuthClient(drive.DriveReadonlyScope)
} else {
client = getOAuthClient(drive.DriveScope)
}
driveCache := cache.NewCache("/tmp", client)
// TODO: move into drivedb, so we don't create a service twice
service, _ := drive.New(client)
about, err := service.About.Get().Do()
if err != nil {
log.Fatalf("drive.service.About.Get().Do: %v\n", err)
}
// fileId of the root of the FS (aka "My Drive")
rootId := about.RootFolderId
// email address of the mounted google drive account
account := about.User.EmailAddress
// Ensure the token's always fresh
// TODO: Remove this once goauth2 changes are accepted upstream
// https://code.google.com/p/goauth2/issues/detail?id=47
go tokenKicker(client, 59*time.Minute)
// Create and start the drive metadata syncer.
db, err := drive_db.NewDriveDB(client, *dbDir, *cacheDir, *driveMetadataLatency, rootId)
if err != nil {
log.Fatalf("could not open leveldb: %v", err)
}
defer db.Close()
db.WaitUntilSynced()
log.Printf("synced!")
options := []fuse.MountOption{
fuse.FSName("GoogleDrive"),
fuse.Subtype("gdrive"),
fuse.VolumeName(account),
}
if *allowOther {
options = append(options, fuse.AllowOther())
}
if *readOnly {
options = append(options, fuse.ReadOnly())
}
c, err := fuse.Mount(mountpoint, options...)
if err != nil {
log.Fatal(err)
}
defer c.Close()
// Trap control-c (sig INT) and unmount
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt)
go func() {
for _ = range sig {
if err := fuse.Unmount(mountpoint); err != nil {
log.Printf("fuse.Unmount failed: %v", err)
}
}
//.........这里部分代码省略.........
作者:bweste
项目:consulf
func main() {
allowOther := flag.Bool("allow-other", false, "allow all users access to the filesystem")
allowRoot := flag.Bool("allow-root", false, "allow root to access the filesystem")
debug := flag.Bool("debug", false, "enable debug output")
gid := flag.Int("gid", os.Getgid(), "set the GID that should own all files")
perm := flag.Int("perm", 0, "set the file permission flags for all files")
ro := flag.Bool("ro", false, "mount the filesystem read-only")
root := flag.String("root", "", "path in Consul to the root of the filesystem")
timeout := flag.String("timeout", defaultTimeout, "timeout for Consul requests")
uid := flag.Int("uid", os.Getuid(), "set the UID that should own all files")
flag.Parse()
logger := logrus.New()
if *debug {
logger.Level = logrus.DebugLevel
}
consulConfig := &consul.Config{}
var mountPoint string
switch flag.NArg() {
case 1:
mountPoint = flag.Arg(0)
case 2:
consulConfig.Address = flag.Arg(0)
mountPoint = flag.Arg(1)
default:
flag.Usage()
}
// Initialize a Consul client. TODO: connection parameters
client, err := consul.NewClient(consulConfig)
if err != nil {
logrus.NewEntry(logger).WithError(err).Error("could not initialize consul")
os.Exit(1)
}
// Configure some mount options
timeoutDuration, err := time.ParseDuration(*timeout)
if err != nil {
logrus.NewEntry(logger).WithError(err).Fatal("invalid -timeout value")
}
mountOptions := []fuse.MountOption{
fuse.DefaultPermissions(),
fuse.DaemonTimeout(fmt.Sprint(int64(timeoutDuration.Seconds() + 1))),
fuse.NoAppleDouble(),
fuse.NoAppleXattr(),
}
if *allowOther {
mountOptions = append(mountOptions, fuse.AllowOther())
}
if *allowRoot {
mountOptions = append(mountOptions, fuse.AllowRoot())
}
if *ro {
mountOptions = append(mountOptions, fuse.ReadOnly())
}
// Mount the file system to start receiving FS events at the mount point.
logger.WithField("location", mountPoint).Info("mounting kvfs")
conn, err := fuse.Mount(mountPoint, mountOptions...)
if err != nil {
logrus.NewEntry(logger).WithError(err).Fatal("error mounting kvfs")
}
defer conn.Close()
// Try to cleanly unmount the FS if SIGINT or SIGTERM is received
sigs := make(chan os.Signal, 10)
signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)
go func() {
for sig := range sigs {
logger.WithField("signal", sig).Info("attempting to unmount")
err := fuse.Unmount(mountPoint)
if err != nil {
logrus.NewEntry(logger).WithError(err).Error("cannot unmount")
}
}
}()
// Create a file system object and start handing its requests
server := fs.New(conn, &fs.Config{
Debug: func(m interface{}) { logger.Debug(m) },
WithContext: func(ctx context.Context, req fuse.Request) context.Context {
// The returned cancel function doesn't matter: the request handler will
// cancel the parent context at the end of the request.
newCtx, _ := context.WithTimeout(ctx, timeoutDuration)
return newCtx
},
})
f := &consulfs.ConsulFS{
Consul: &consulfs.CancelConsulKV{
Client: client,
Logger: logger,
},
Logger: logger,
UID: uint32(*uid),
GID: uint32(*gid),
Perms: os.FileMode(*perm),
RootPath: *root,
}
err = server.Serve(f)
//.........这里部分代码省略.........
作者:funkyga
项目:gafk
func (this *Mount) Run(args []string) (exitCode int) {
cmdFlags := flag.NewFlagSet("mount", flag.ContinueOnError)
cmdFlags.Usage = func() { this.Ui.Output(this.Help()) }
cmdFlags.StringVar(&this.zone, "z", ctx.ZkDefaultZone(), "")
cmdFlags.StringVar(&this.cluster, "c", "", "")
cmdFlags.StringVar(&this.logLevel, "l", "info", "")
if err := cmdFlags.Parse(args); err != nil {
return 1
}
if validateArgs(this, this.Ui).
on("-z", "-c").
invalid(args) {
return 2
}
this.mountPoint = args[len(args)-1]
if !strings.HasPrefix(this.mountPoint, "/") {
this.Ui.Error("mount point must start with /")
return 1
}
setupLogging("stdout", this.logLevel, "")
c, err := fuse.Mount(
this.mountPoint,
fuse.FSName("kfs"),
fuse.Subtype("kfs"),
fuse.VolumeName("Kafka FS"),
fuse.ReadOnly(),
fuse.AllowOther(),
)
if err != nil {
log.Critical(err)
}
signal.RegisterHandler(func(sig os.Signal) {
var err error
for i := 0; i < 5; i++ {
err = fuse.Unmount(this.mountPoint)
if err == nil {
break
}
log.Warn(err)
time.Sleep(time.Second * 5)
}
if err == nil {
log.Info("Kafka FS unmounted")
} else {
log.Error("Kafka FS unable to umount")
}
c.Close()
os.Exit(0)
}, syscall.SIGINT, syscall.SIGTERM)
srv := fs.New(c, &fs.Config{})
fs := kfs.New(this.zone, this.cluster)
if err := srv.Serve(fs); err != nil {
log.Error(err)
}
<-c.Ready
if err := c.MountError; err != nil {
log.Error(err)
}
return
}
作者:wrees
项目:cfs-binary-releas
//.........这里部分代码省略.........
ws := mb.NewFileSystemAPIClient(conn)
result, err := ws.LookupAddrFS(context.Background(), &mb.LookupAddrFSRequest{FSid: fsNum, Addr: c.String("addr")})
if err != nil {
log.Fatalf("Bad Request: %v", err)
conn.Close()
os.Exit(1)
}
conn.Close()
log.Printf("Result: %s\n", result.Status)
},
},
{
Name: "mount",
Usage: "mount a file system",
ArgsUsage: "<region>://<file system uuid> <mount point> -o [OPTIONS]",
Flags: []cli.Flag{
cli.StringFlag{
Name: "o",
Value: "",
Usage: "mount options",
},
},
Action: func(c *cli.Context) {
if !c.Args().Present() {
fmt.Println("Invalid syntax for revoke.")
os.Exit(1)
}
serverAddr, fsNum, _ = parseurl(c.Args().Get(0), "8445")
fsnum, err := uuid.FromString(fsNum)
if err != nil {
fmt.Print("File System id is not valid: ", err)
}
mountpoint := c.Args().Get(1)
// check mountpoint exists
if _, ferr := os.Stat(mountpoint); os.IsNotExist(ferr) {
log.Printf("Mount point %s does not exist\n\n", mountpoint)
os.Exit(1)
}
fusermountPath()
// process file system options
if c.String("o") != "" {
clargs := getArgs(c.String("o"))
// crapy debug log handling :)
if debug, ok := clargs["debug"]; ok {
if debug == "false" {
log.SetFlags(0)
log.SetOutput(ioutil.Discard)
}
} else {
log.SetFlags(0)
log.SetOutput(ioutil.Discard)
}
}
// Setup grpc
var opts []grpc.DialOption
creds := credentials.NewTLS(&tls.Config{
InsecureSkipVerify: true,
})
opts = append(opts, grpc.WithTransportCredentials(creds))
conn, err := grpc.Dial(serverAddr, opts...)
if err != nil {
log.Fatalf("failed to dial: %v", err)
}
defer conn.Close()
// Work with fuse
cfs, err := fuse.Mount(
mountpoint,
fuse.FSName("cfs"),
fuse.Subtype("cfs"),
fuse.LocalVolume(),
fuse.VolumeName("CFS"),
fuse.AllowOther(),
fuse.DefaultPermissions(),
)
if err != nil {
log.Fatal(err)
}
defer cfs.Close()
rpc := newrpc(conn)
fs := newfs(cfs, rpc, fsnum.String())
err = fs.InitFs()
if err != nil {
log.Fatal(err)
}
srv := newserver(fs)
if err := srv.serve(); err != nil {
log.Fatal(err)
}
<-cfs.Ready
if err := cfs.MountError; err != nil {
log.Fatal(err)
}
},
},
}
app.Run(os.Args)
}