/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/kbfs/libfuse/start.go
186 строк
5 KB
chrisnojima-zoom
Version 670 - clean2 (#29122)
08 июн 2026, 19:31
Не верифицирован
08 июн 2026, 19:31
1943197
Код
Авторство
О чём код?
// Copyright 2016 Keybase Inc. All rights reserved. // Use of this source code is governed by a BSD // license that can be found in the LICENSE file. // //go:build !windows package libfuse import ( "context" "fmt" "os" "path" "bazil.org/fuse" "github.com/keybase/client/go/kbfs/libfs" "github.com/keybase/client/go/kbfs/libgit" "github.com/keybase/client/go/kbfs/libkbfs" "github.com/keybase/client/go/kbfs/simplefs" "github.com/keybase/client/go/libkb" "github.com/keybase/client/go/logger" "github.com/keybase/client/go/protocol/keybase1" "github.com/keybase/client/go/systemd" "github.com/keybase/go-framed-msgpack-rpc/rpc" ) // StartOptions are options for starting up type StartOptions struct { KbfsParams libkbfs.InitParams PlatformParams PlatformParams RuntimeDir string Label string ForceMount bool MountErrorIsFatal bool SkipMount bool MountPoint string } func startMounting(ctx context.Context, kbCtx libkbfs.Context, config libkbfs.Config, options StartOptions, log logger.Logger, mi *libfs.MountInterrupter, ) error { log.CDebugf(ctx, "Mounting: %q", options.MountPoint) mounter := &mounter{ options: options, log: log, runMode: kbCtx.GetRunMode(), } err := mi.MountAndSetUnmount(mounter) if err != nil { return err } log.CDebugf(ctx, "Creating filesystem") fs := NewFS(config, mounter.c, options.KbfsParams.Debug, options.PlatformParams) ctx, cancel := context.WithCancel(ctx) defer cancel() ctx = context.WithValue(ctx, libfs.CtxAppIDKey, fs) go func() { select { case <-mounter.c.Ready: // We wait for the mounter to finish asynchronously with // calling fs.Serve() below, for the rare osxfuse case // where `mount(2)` makes a blocking STATFS call before // completing. If we aren't listening for the STATFS call // when this happens, there will be a deadlock, and the // mount will silently fail after two minutes. See // KBFS-2409. err = mounter.c.MountError if err != nil { log.CWarningf(ctx, "Mount error: %+v", err) cancel() return } log.CDebugf(ctx, "Mount ready") case <-ctx.Done(): } }() log.CDebugf(ctx, "Serving filesystem") if err = fs.Serve(ctx); err != nil { return err } log.CDebugf(ctx, "Ending") return nil } // Start the filesystem func Start(options StartOptions, kbCtx libkbfs.Context) *libfs.Error { // Hook simplefs implementation in. shutdownSimpleFS := func(_ context.Context) error { return nil } createSimpleFS := func( libkbfsCtx libkbfs.Context, config libkbfs.Config, ) (rpc.Protocol, error) { var sfs *simplefs.SimpleFS sfs, shutdownSimpleFS = simplefs.NewSimpleFS( libkbfsCtx, config) config.AddResetForLoginTarget(sfs) return keybase1.SimpleFSProtocol(sfs), nil } // Hook git implementation in. shutdownGit := func() {} createGitHandler := func( libkbfsCtx libkbfs.Context, config libkbfs.Config, ) (rpc.Protocol, error) { var handler keybase1.KBFSGitInterface handler, shutdownGit = libgit.NewRPCHandlerWithCtx( libkbfsCtx, config, &options.KbfsParams) return keybase1.KBFSGitProtocol(handler), nil } defer func() { err := shutdownSimpleFS(context.Background()) if err != nil { fmt.Fprintf(os.Stderr, "Couldn't shut down SimpleFS: %+v\n", err) } shutdownGit() }() // Patch the kbfsParams to inject two additional protocols. options.KbfsParams.AdditionalProtocolCreators = []libkbfs.AdditionalProtocolCreator{ createSimpleFS, createGitHandler, } log, err := libkbfs.InitLog(options.KbfsParams, kbCtx) if err != nil { return libfs.InitError(err.Error()) } if options.RuntimeDir != "" { err := os.MkdirAll(options.RuntimeDir, libkb.PermDir) if err != nil { return libfs.InitError(err.Error()) } info := libkb.NewServiceInfo(libkb.Version, libkbfs.PrereleaseBuild, options.Label, os.Getpid()) err = info.WriteFile(path.Join(options.RuntimeDir, "kbfs.info"), log) if err != nil { return libfs.InitError(err.Error()) } } log.Debug("Initializing") mi := libfs.NewMountInterrupter(log) ctx := context.Background() config, err := libkbfs.Init( ctx, kbCtx, options.KbfsParams, nil, mi.Done, log) if err != nil { return libfs.InitError(err.Error()) } defer libkbfs.Shutdown() libfs.AddRootWrapper(config) if options.KbfsParams.Debug { fuseLog := config.MakeLogger("FUSE").CloneWithAddedDepth(1) fuse.Debug = MakeFuseVDebugFn( config.MakeVLogger(fuseLog), false /* superVerbose */) } // Report "startup successful" to the supervisor (currently just systemd on // Linux). This isn't necessary for correctness, but it allows commands // like "systemctl start kbfs.service" to report startup errors to the // terminal, by delaying their return until they get this notification // (Type=notify, in systemd lingo). systemd.NotifyStartupFinished() if options.SkipMount { log.Debug("Skipping mounting filesystem") } else { err = startMounting(ctx, kbCtx, config, options, log, mi) if err != nil { // Abort on error if we were force mounting, otherwise continue. if options.MountErrorIsFatal { // If we exit we might want to clean a mount behind us. _ = mi.Done() return libfs.MountError(err.Error()) } } } mi.Wait() return nil }