aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/bazil.org/fuse/mount_freebsd.go
diff options
context:
space:
mode:
authorZahoor Mohamed <zahoor@zahoor.in>2017-03-23 21:56:06 +0800
committerFelix Lange <fjl@users.noreply.github.com>2017-03-23 21:56:06 +0800
commit11e7a712f469fb24ddb88ecebcefab6ed8880eb8 (patch)
treec052776c80475767eb7a038bef99ff784b071ef7 /vendor/bazil.org/fuse/mount_freebsd.go
parent61d2150a0750a554250c3bf090ef994be6c060f0 (diff)
downloadgo-tangerine-11e7a712f469fb24ddb88ecebcefab6ed8880eb8.tar
go-tangerine-11e7a712f469fb24ddb88ecebcefab6ed8880eb8.tar.gz
go-tangerine-11e7a712f469fb24ddb88ecebcefab6ed8880eb8.tar.bz2
go-tangerine-11e7a712f469fb24ddb88ecebcefab6ed8880eb8.tar.lz
go-tangerine-11e7a712f469fb24ddb88ecebcefab6ed8880eb8.tar.xz
go-tangerine-11e7a712f469fb24ddb88ecebcefab6ed8880eb8.tar.zst
go-tangerine-11e7a712f469fb24ddb88ecebcefab6ed8880eb8.zip
swarm/api: support mounting manifests via FUSE (#3690)
Diffstat (limited to 'vendor/bazil.org/fuse/mount_freebsd.go')
-rw-r--r--vendor/bazil.org/fuse/mount_freebsd.go111
1 files changed, 111 insertions, 0 deletions
diff --git a/vendor/bazil.org/fuse/mount_freebsd.go b/vendor/bazil.org/fuse/mount_freebsd.go
new file mode 100644
index 000000000..70bb41024
--- /dev/null
+++ b/vendor/bazil.org/fuse/mount_freebsd.go
@@ -0,0 +1,111 @@
+package fuse
+
+import (
+ "fmt"
+ "log"
+ "os"
+ "os/exec"
+ "strings"
+ "sync"
+ "syscall"
+)
+
+func handleMountFusefsStderr(errCh chan<- error) func(line string) (ignore bool) {
+ return func(line string) (ignore bool) {
+ const (
+ noMountpointPrefix = `mount_fusefs: `
+ noMountpointSuffix = `: No such file or directory`
+ )
+ if strings.HasPrefix(line, noMountpointPrefix) && strings.HasSuffix(line, noMountpointSuffix) {
+ // re-extract it from the error message in case some layer
+ // changed the path
+ mountpoint := line[len(noMountpointPrefix) : len(line)-len(noMountpointSuffix)]
+ err := &MountpointDoesNotExistError{
+ Path: mountpoint,
+ }
+ select {
+ case errCh <- err:
+ return true
+ default:
+ // not the first error; fall back to logging it
+ return false
+ }
+ }
+
+ return false
+ }
+}
+
+// isBoringMountFusefsError returns whether the Wait error is
+// uninteresting; exit status 1 is.
+func isBoringMountFusefsError(err error) bool {
+ if err, ok := err.(*exec.ExitError); ok && err.Exited() {
+ if status, ok := err.Sys().(syscall.WaitStatus); ok && status.ExitStatus() == 1 {
+ return true
+ }
+ }
+ return false
+}
+
+func mount(dir string, conf *mountConfig, ready chan<- struct{}, errp *error) (*os.File, error) {
+ for k, v := range conf.options {
+ if strings.Contains(k, ",") || strings.Contains(v, ",") {
+ // Silly limitation but the mount helper does not
+ // understand any escaping. See TestMountOptionCommaError.
+ return nil, fmt.Errorf("mount options cannot contain commas on FreeBSD: %q=%q", k, v)
+ }
+ }
+
+ f, err := os.OpenFile("/dev/fuse", os.O_RDWR, 0000)
+ if err != nil {
+ *errp = err
+ return nil, err
+ }
+
+ cmd := exec.Command(
+ "/sbin/mount_fusefs",
+ "--safe",
+ "-o", conf.getOptions(),
+ "3",
+ dir,
+ )
+ cmd.ExtraFiles = []*os.File{f}
+
+ stdout, err := cmd.StdoutPipe()
+ if err != nil {
+ return nil, fmt.Errorf("setting up mount_fusefs stderr: %v", err)
+ }
+ stderr, err := cmd.StderrPipe()
+ if err != nil {
+ return nil, fmt.Errorf("setting up mount_fusefs stderr: %v", err)
+ }
+
+ if err := cmd.Start(); err != nil {
+ return nil, fmt.Errorf("mount_fusefs: %v", err)
+ }
+ helperErrCh := make(chan error, 1)
+ var wg sync.WaitGroup
+ wg.Add(2)
+ go lineLogger(&wg, "mount helper output", neverIgnoreLine, stdout)
+ go lineLogger(&wg, "mount helper error", handleMountFusefsStderr(helperErrCh), stderr)
+ wg.Wait()
+ if err := cmd.Wait(); err != nil {
+ // see if we have a better error to report
+ select {
+ case helperErr := <-helperErrCh:
+ // log the Wait error if it's not what we expected
+ if !isBoringMountFusefsError(err) {
+ log.Printf("mount helper failed: %v", err)
+ }
+ // and now return what we grabbed from stderr as the real
+ // error
+ return nil, helperErr
+ default:
+ // nope, fall back to generic message
+ }
+ return nil, fmt.Errorf("mount_fusefs: %v", err)
+ }
+
+ close(ready)
+ return f, nil
+}