src-d / go-billy

The missing interface filesystem abstraction for Go
https://godoc.org/gopkg.in/src-d/go-billy.v4
Apache License 2.0
199 stars 43 forks source link

Plan 9 Support #52

Open henesy opened 6 years ago

henesy commented 6 years ago

Getting Billy (osfs) to build on Plan 9 is possible by adding the following:

osfs/os_plan9.go

// +build plan9

package osfs

import (
    "os"
)

func (f *file) Lock() error {
    f.m.Lock()
    defer f.m.Unlock()

    s, err := f.Stat()
    if(err != nil) {
        return err
    }

    // Add exclusive bit
    return (f.File).Chmod(s.Mode() | os.ModeExclusive)
}

func (f *file) Unlock() error {
    f.m.Lock()
    defer f.m.Unlock()

    s, err := f.Stat()
    if(err != nil) {
        return err
    }

    // Remove exclusive bit
    return (f.File).Chmod(s.Mode() & ^os.ModeExclusive)
}

I changed osfs/os_posix.go's build header to the following, but I'm not sure it's necessary:

// +build !windows,!plan9
mcuadros commented 6 years ago

will be great if you can do a PR

fhs commented 4 years ago

@henesy I think Lock is supposed to block until it acquires the lock (the posix implementation doesn't use LOCK_NB with flock). Maybe we can do something similar to the lockedfile package used by cmd/go.

Go's internal/filelock package does not support Plan 9.

fhs commented 4 years ago

I'll be sending a PR for Plan 9 support soon.

It's not really possible to implement Lock/Unlock using the "exclusive use" bit:

Per http://man.cat-v.org/plan_9/5/stat: “Exclusive use files may be open for I/O by only one fid at a time across all clients of the server. If a second open is attempted, it draws an error.”

Since Lock is called on an open file, if we can't open a locked file in the first place, we never even get into the Lock function to wait for the file to be unlocked by the other client. I think go-billy will need to use an API similar to the lockedfile package to support file locking on Plan 9.

I got all the tests passing on Plan 9, but I found that running go test ./... hangs in TestTempFileMany and TestTempFileManyWithUtil if we're using test cache. This is possibly a go tool bug. If I run the tests with go test -count 1 ./... everything passes.