mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-21 10:27:46 +08:00
Some checks are pending
CodeQL / codeql (push) Waiting to run
Docker Build / docker-build (push) Waiting to run
Gateway Conformance / gateway-conformance (push) Waiting to run
Gateway Conformance / gateway-conformance-libp2p-experiment (push) Waiting to run
Go Build / go-build (push) Waiting to run
Go Check / go-check (push) Waiting to run
Go Lint / go-lint (push) Waiting to run
Go Test / go-test (push) Waiting to run
Interop / interop-prep (push) Waiting to run
Interop / helia-interop (push) Blocked by required conditions
Interop / ipfs-webui (push) Blocked by required conditions
Sharness / sharness-test (push) Waiting to run
Spell Check / spellcheck (push) Waiting to run
* chore: update to go-log/v2 go-log v2 has been out for quite a while now and it is time to deprecate v1. Replace all use of go-log with go-log/v2 Makes /api/v0/log/tail useful over HTTP Updates dependencies that have moved to go-lov/v2 Removes support for ContextWithLoggable as this is not needed for tracing-like functionality - Replaces: PR #8765 - Closes issue #8753 - Closes issue #9245 - Closes issue #10809 Other fixes: * update go-ipfs-cmds * update http logs test * fix test * Read/send one line of log data at a time * Update -log-level docs
108 lines
2.3 KiB
Go
108 lines
2.3 KiB
Go
// package mount provides a simple abstraction around a mount point
|
|
package mount
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os/exec"
|
|
"runtime"
|
|
"time"
|
|
|
|
logging "github.com/ipfs/go-log/v2"
|
|
goprocess "github.com/jbenet/goprocess"
|
|
)
|
|
|
|
var log = logging.Logger("mount")
|
|
|
|
var MountTimeout = time.Second * 5
|
|
|
|
// Mount represents a filesystem mount.
|
|
type Mount interface {
|
|
// MountPoint is the path at which this mount is mounted
|
|
MountPoint() string
|
|
|
|
// Unmounts the mount
|
|
Unmount() error
|
|
|
|
// Checks if the mount is still active.
|
|
IsActive() bool
|
|
|
|
// Process returns the mount's Process to be able to link it
|
|
// to other processes. Unmount upon closing.
|
|
Process() goprocess.Process
|
|
}
|
|
|
|
// ForceUnmount attempts to forcibly unmount a given mount.
|
|
// It does so by calling diskutil or fusermount directly.
|
|
func ForceUnmount(m Mount) error {
|
|
point := m.MountPoint()
|
|
log.Warnf("Force-Unmounting %s...", point)
|
|
|
|
cmd, err := UnmountCmd(point)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
errc := make(chan error, 1)
|
|
go func() {
|
|
defer close(errc)
|
|
|
|
// try vanilla unmount first.
|
|
if err := exec.Command("umount", point).Run(); err == nil {
|
|
return
|
|
}
|
|
|
|
// retry to unmount with the fallback cmd
|
|
errc <- cmd.Run()
|
|
}()
|
|
|
|
select {
|
|
case <-time.After(7 * time.Second):
|
|
return fmt.Errorf("umount timeout")
|
|
case err := <-errc:
|
|
return err
|
|
}
|
|
}
|
|
|
|
// UnmountCmd creates an exec.Cmd that is GOOS-specific
|
|
// for unmount a FUSE mount.
|
|
func UnmountCmd(point string) (*exec.Cmd, error) {
|
|
switch runtime.GOOS {
|
|
case "darwin":
|
|
return exec.Command("diskutil", "umount", "force", point), nil
|
|
case "linux":
|
|
return exec.Command("fusermount", "-u", point), nil
|
|
default:
|
|
return nil, fmt.Errorf("unmount: unimplemented")
|
|
}
|
|
}
|
|
|
|
// ForceUnmountManyTimes attempts to forcibly unmount a given mount,
|
|
// many times. It does so by calling diskutil or fusermount directly.
|
|
// Attempts a given number of times.
|
|
func ForceUnmountManyTimes(m Mount, attempts int) error {
|
|
var err error
|
|
for i := 0; i < attempts; i++ {
|
|
err = ForceUnmount(m)
|
|
if err == nil {
|
|
return err
|
|
}
|
|
|
|
<-time.After(time.Millisecond * 500)
|
|
}
|
|
return fmt.Errorf("unmount %s failed after 10 seconds of trying", m.MountPoint())
|
|
}
|
|
|
|
type closer struct {
|
|
M Mount
|
|
}
|
|
|
|
func (c *closer) Close() error {
|
|
log.Warn(" (c *closer) Close(),", c.M.MountPoint())
|
|
return c.M.Unmount()
|
|
}
|
|
|
|
func Closer(m Mount) io.Closer {
|
|
return &closer{m}
|
|
}
|