Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go/kbfs/libfuse/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func (f *File) sync(ctx context.Context) error {

// Fsync implements the fs.NodeFsyncer interface for File.
func (f *File) Fsync(ctx context.Context, req *fuse.FsyncRequest) (err error) {
ctx, maybeUnmounting, cancel := wrapCtxWithShorterTimeoutForUnmount(f.folder.fs.log, ctx, int(req.Pid))
ctx, maybeUnmounting, cancel := wrapCtxWithShorterTimeoutForUnmount(ctx, f.folder.fs.log, int(req.Pid))
defer cancel()
if maybeUnmounting {
f.folder.fs.log.CInfof(ctx, "Fsync: maybeUnmounting=true")
Expand Down
7 changes: 6 additions & 1 deletion go/kbfs/libfuse/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,9 +381,14 @@ func (f *FS) Root() (fs.Node, error) {
return f.root, nil
}

// quotaUsageStaleTolerance is the lifespan of stale usage data that libfuse
// accepts in the Statfs handler. In other words, this causes libkbfs to issue
// a fresh RPC call if cached usage data is older than 10s.
const quotaUsageStaleTolerance = 10 * time.Second

// Statfs implements the fs.FSStatfser interface for FS.
func (f *FS) Statfs(ctx context.Context, req *fuse.StatfsRequest, resp *fuse.StatfsResponse) error {
ctx, maybeUnmounting, cancel := wrapCtxWithShorterTimeoutForUnmount(f.log, ctx, int(req.Pid))
ctx, maybeUnmounting, cancel := wrapCtxWithShorterTimeoutForUnmount(ctx, f.log, int(req.Pid))
defer cancel()
if maybeUnmounting {
f.log.CInfof(ctx, "Statfs: maybeUnmounting=true")
Expand Down
2 changes: 1 addition & 1 deletion go/kbfs/libfuse/mounter_non_osx.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (m *mounter) reinstallMountDirIfPossible() {
var noop = func() {}

func wrapCtxWithShorterTimeoutForUnmount(
_ logger.Logger, ctx context.Context, _ int) (
ctx context.Context, _ logger.Logger, _ int) (
newCtx context.Context, maybeUnmounting bool, cancel context.CancelFunc) {
return ctx, false, noop
}
39 changes: 32 additions & 7 deletions go/kbfs/libfuse/mounter_osx.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@

package libfuse

// #include <libproc.h>
// #include <stdlib.h>
// #include <errno.h>
import "C"

import (
"context"
"errors"
"strconv"
"time"
"unsafe"

"bazil.org/fuse"
"github.com/keybase/client/go/install/libnativeinstaller"
Expand Down Expand Up @@ -88,11 +95,6 @@ func (m *mounter) reinstallMountDirIfPossible() {
m.log.Debug("InstallMountDir: err=%v", err)
}

// quotaUsageStaleTolerance is the lifespan of stale usage data that libfuse
// accepts in the Statfs handler. In other words, this causes libkbfs to issue
// a fresh RPC call if cached usage data is older than 10s.
const quotaUsageStaleTolerance = 10 * time.Second

const unmountCallTolerance = time.Second

var unmountingExecPaths = map[string]bool{
Expand All @@ -103,14 +105,37 @@ var unmountingExecPaths = map[string]bool{

var noop = func() {}

// pidPath returns the exec path for process pid. Adapted from
// https://ops.tips/blog/macos-pid-absolute-path-and-procfs-exploration/
func pidPath(pid int) (path string, err error) {
const bufSize = C.PROC_PIDPATHINFO_MAXSIZE
buf := C.CString(string(make([]byte, bufSize)))
defer C.free(unsafe.Pointer(buf))

ret, err := C.proc_pidpath(C.int(pid), unsafe.Pointer(buf), bufSize)
if err != nil {
return "", err
}
if ret < 0 {
return "", errors.New(
"error calling proc_pidpath. exit code: " + strconv.Itoa(int(ret)))
}
if ret == 0 {
return "", errors.New("proc_pidpath returned empty buffer")
}

path = C.GoString(buf)
return
}

// wrapCtxWithShorterTimeoutForUnmount wraps ctx witha a timeout of
// unmountCallTolerance if pid is /usr/sbin/diskutil, /usr/libexec/lsd, or
// /sbin/umount. This is useful for calls that usually happen during unmounting
// such as Statfs and Fsync. If we block on those calls, `diskutil umount force
// <mnt>` is blocked as well. So make them timeout after 2s to make unmounting
// work.
func wrapCtxWithShorterTimeoutForUnmount(
log logger.Logger, ctx context.Context, pid int) (
func wrapCtxWithShorterTimeoutForUnmount(ctx context.Context,
log logger.Logger, pid int) (
newCtx context.Context, maybeUnmounting bool, cancel context.CancelFunc) {
p, err := pidPath(pid)
if err != nil {
Expand Down
41 changes: 0 additions & 41 deletions go/kbfs/libfuse/pidpath_darwin.go

This file was deleted.

15 changes: 0 additions & 15 deletions go/kbfs/libfuse/pidpath_others.go

This file was deleted.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading