Documentation ¶
Index ¶
- Constants
- Variables
- func NewAdbFile(opts AdbFileOpenOptions) nodefs.File
- func NewAdbFileSystem(config Config) (pathfs.FileSystem, error)
- type AdbFile
- func (f *AdbFile) Flush() fuse.Status
- func (f *AdbFile) Fsync(flags int) fuse.Status
- func (f *AdbFile) GetAttr(out *fuse.Attr) fuse.Status
- func (f *AdbFile) InnerFile() nodefs.File
- func (f *AdbFile) Read(buf []byte, off int64) (fuse.ReadResult, fuse.Status)
- func (f *AdbFile) Release()
- func (f *AdbFile) Truncate(size uint64) fuse.Status
- func (f *AdbFile) Write(data []byte, off int64) (uint32, fuse.Status)
- type AdbFileOpenOptions
- type AdbFileSystem
- func (fs *AdbFileSystem) Access(name string, mode uint32, context *fuse.Context) fuse.Status
- func (fs *AdbFileSystem) Chmod(name string, mode uint32, context *fuse.Context) (code fuse.Status)
- func (fs *AdbFileSystem) Chown(name string, uid uint32, gid uint32, context *fuse.Context) (code fuse.Status)
- func (fs *AdbFileSystem) Create(name string, rawFlags uint32, perms uint32, context *fuse.Context) (nodefs.File, fuse.Status)
- func (fs *AdbFileSystem) GetAttr(name string, _ *fuse.Context) (attr *fuse.Attr, status fuse.Status)
- func (fs *AdbFileSystem) GetXAttr(name string, attribute string, context *fuse.Context) (data []byte, code fuse.Status)
- func (fs *AdbFileSystem) Link(oldName string, newName string, context *fuse.Context) fuse.Status
- func (fs *AdbFileSystem) ListXAttr(name string, context *fuse.Context) (attributes []string, code fuse.Status)
- func (fs *AdbFileSystem) Mkdir(name string, perms uint32, context *fuse.Context) fuse.Status
- func (fs *AdbFileSystem) Mknod(name string, mode uint32, dev uint32, context *fuse.Context) fuse.Status
- func (fs *AdbFileSystem) OnMount(nodeFs *pathfs.PathNodeFs)
- func (fs *AdbFileSystem) OnUnmount()
- func (fs *AdbFileSystem) Open(name string, flags uint32, context *fuse.Context) (nodefs.File, fuse.Status)
- func (fs *AdbFileSystem) OpenDir(name string, _ *fuse.Context) ([]fuse.DirEntry, fuse.Status)
- func (fs *AdbFileSystem) Readlink(name string, context *fuse.Context) (target string, status fuse.Status)
- func (fs *AdbFileSystem) RemoveXAttr(name string, attr string, context *fuse.Context) fuse.Status
- func (fs *AdbFileSystem) Rename(oldName, newName string, context *fuse.Context) fuse.Status
- func (fs *AdbFileSystem) Rmdir(name string, context *fuse.Context) fuse.Status
- func (fs *AdbFileSystem) SetDebug(debug bool)
- func (fs *AdbFileSystem) SetXAttr(name string, attr string, data []byte, flags int, context *fuse.Context) fuse.Status
- func (fs *AdbFileSystem) StatFs(name string) *fuse.StatfsOut
- func (fs *AdbFileSystem) String() string
- func (fs *AdbFileSystem) Symlink(oldName string, newName string, context *fuse.Context) fuse.Status
- func (fs *AdbFileSystem) Truncate(name string, size uint64, context *fuse.Context) (code fuse.Status)
- func (fs *AdbFileSystem) Unlink(name string, context *fuse.Context) fuse.Status
- func (fs *AdbFileSystem) Utimens(name string, Atime *time.Time, Mtime *time.Time, context *fuse.Context) (code fuse.Status)
- type CachedDirEntries
- type CachingDeviceClient
- func (c *CachingDeviceClient) ListDirEntries(path string, log *LogEntry) ([]*adb.DirEntry, error)
- func (c *CachingDeviceClient) OpenWrite(name string, perms os.FileMode, mtime time.Time, log *LogEntry) (io.WriteCloser, error)
- func (c *CachingDeviceClient) Stat(name string, log *LogEntry) (*adb.DirEntry, error)
- type Config
- type DeviceClient
- type DeviceClientFactory
- type DirEntryCache
- type DirEntryLoader
- type FileBuffer
- func (f *FileBuffer) Contents() string
- func (f *FileBuffer) DecRefCount() int
- func (f *FileBuffer) Flush(logEntry *LogEntry) error
- func (f *FileBuffer) IncRefCount() int
- func (f *FileBuffer) IsDirty() bool
- func (f *FileBuffer) ReadAt(buf []byte, off int64) (n int, err error)
- func (f *FileBuffer) RefCount() int
- func (f *FileBuffer) SetSize(size int64)
- func (f *FileBuffer) Size() int64
- func (f *FileBuffer) Sync(logEntry *LogEntry) error
- func (f *FileBuffer) SyncIfTooDirty(logEntry *LogEntry) error
- func (f *FileBuffer) WriteAt(data []byte, off int64) (int, error)
- type FileBufferOptions
- type FileOpenFlags
- type LogEntry
- func (r *LogEntry) CacheUsed(hit bool)
- func (r *LogEntry) Error(err error)
- func (r *LogEntry) ErrorMsg(err error, msg string, args ...interface{})
- func (r *LogEntry) FinishOperation()
- func (r *LogEntry) Result(msg string, args ...interface{})
- func (r *LogEntry) Status(status syscall.Errno) syscall.Errno
- func (r *LogEntry) SuppressFinishOperation()
- type OpenFiles
- type OpenFilesOptions
- type WrappingFile
- func (f *WrappingFile) Allocate(off uint64, size uint64, mode uint32) (code fuse.Status)
- func (f *WrappingFile) Chmod(perms uint32) (code fuse.Status)
- func (f *WrappingFile) Chown(uid uint32, gid uint32) (code fuse.Status)
- func (f *WrappingFile) Flush() (code fuse.Status)
- func (f *WrappingFile) Fsync(flags int) (code fuse.Status)
- func (f *WrappingFile) GetAttr(out *fuse.Attr) (code fuse.Status)
- func (f *WrappingFile) InnerFile() (file nodefs.File)
- func (f *WrappingFile) Read(dest []byte, off int64) (result fuse.ReadResult, code fuse.Status)
- func (f *WrappingFile) Release()
- func (f *WrappingFile) SetInode(inode *nodefs.Inode)
- func (f *WrappingFile) String() string
- func (f *WrappingFile) Truncate(size uint64) (code fuse.Status)
- func (f *WrappingFile) Utimens(atime *time.Time, mtime *time.Time) (code fuse.Status)
- func (f *WrappingFile) Write(data []byte, off int64) (written uint32, code fuse.Status)
Constants ¶
const ( // See AdbFileOpenOptions.Perms. DontSetPerms = os.FileMode(0) // This seems pretty long, but every write that occurs after this period will // flush the entire buffer to the device – this could take a while, and if we do it // to often we're effectively thrashing. If a file has been written to continuously for // this time, it's guaranteed to take at least as long, probably a lot longer, to flush // to the device (process->kernel->fuse has lower latency than process->adb->device). DefaultDirtyTimeout = 5 * time.Minute )
const ( ReadlinkInvalidArgument = "readlink: Invalid argument" ReadlinkPermissionDenied = "readlink: Permission denied" )
Error messages returned by the readlink command on Android devices. Should these be moved into goadb instead?
const ( O_RDONLY = FileOpenFlags(os.O_RDONLY) O_WRONLY = FileOpenFlags(os.O_WRONLY) O_RDWR = FileOpenFlags(os.O_RDWR) O_APPEND = FileOpenFlags(os.O_APPEND) O_CREATE = FileOpenFlags(os.O_CREATE) O_EXCL = FileOpenFlags(os.O_EXCL) O_SYNC = FileOpenFlags(os.O_SYNC) O_TRUNC = FileOpenFlags(os.O_TRUNC) )
const CachePurgeInterval = 5 * time.Minute
const DefaultFilePermissions = os.FileMode(0664)
const MaxLinkResolveDepth = 64
64 symlinks ought to be deep enough for anybody.
const OK = syscall.Errno(0)
Variables ¶
var ( // A symlink cycle is detected. ErrLinkTooDeep = errors.New("link recursion too deep") ErrNotALink = errors.New("not a link") // The user doesn't have permission to perform an operation. ErrNoPermission = os.ErrPermission // The operation is not permitted due to reasons other than user permission. ErrNotPermitted = errors.New("operation not permitted") )
Functions ¶
func NewAdbFile ¶
func NewAdbFile(opts AdbFileOpenOptions) nodefs.File
NewAdbFile returns a File that reads and writes to name on the device. perms should be set from the existing file if it exists, or to the desired new permissions if new.
func NewAdbFileSystem ¶
func NewAdbFileSystem(config Config) (pathfs.FileSystem, error)
Types ¶
type AdbFile ¶
type AdbFile struct { nodefs.File AdbFileOpenOptions }
AdbFile is a nodefs.File that is backed by a file on an adb device. There is one AdbFile for each file descriptor. All AdbFiles that point to the same path are backed by the same FileBuffer.
Note: On OSX at least, the OS will automatically map multiple open files to a single AdbFile.
type AdbFileOpenOptions ¶
type AdbFileOpenOptions struct { // If the create flag is set, the file will immediately be created if it does not exist. Flags FileOpenFlags FileBuffer *FileBuffer }
type AdbFileSystem ¶
type AdbFileSystem struct {
// contains filtered or unexported fields
}
AdbFileSystem is an implementation of fuse.pathfs.FileSystem that exposes the filesystem on an adb device.
Since all operations go through a single adb server, short-lived connections are throttled by using a fixed-size pool of device clients. The pool is initially filled by calling Config.ClientFactory. The pool is not used for long-lived connections such as file transfers, which may be kept open for arbitrary periods of time by processes using the filesystem.
func (*AdbFileSystem) Mkdir ¶
Mkdir creates name on the device with the default permissions. perms is ignored.
func (*AdbFileSystem) OnMount ¶
func (fs *AdbFileSystem) OnMount(nodeFs *pathfs.PathNodeFs)
func (*AdbFileSystem) OnUnmount ¶
func (fs *AdbFileSystem) OnUnmount()
func (*AdbFileSystem) RemoveXAttr ¶
func (*AdbFileSystem) SetDebug ¶
func (fs *AdbFileSystem) SetDebug(debug bool)
func (*AdbFileSystem) String ¶
func (fs *AdbFileSystem) String() string
type CachedDirEntries ¶
type CachedDirEntries struct { InOrder []*adb.DirEntry ByName map[string]*adb.DirEntry }
func NewCachedDirEntries ¶
func NewCachedDirEntries(entries []*adb.DirEntry) *CachedDirEntries
type CachingDeviceClient ¶
type CachingDeviceClient struct { DeviceClient Cache DirEntryCache }
func (*CachingDeviceClient) ListDirEntries ¶
func (c *CachingDeviceClient) ListDirEntries(path string, log *LogEntry) ([]*adb.DirEntry, error)
type Config ¶
type Config struct { // Serial number of the device for which ClientFactory returns clients. DeviceSerial string // Absolute path to mountpoint, used to resolve symlinks. Mountpoint string // Directory on device to consider root. DeviceRoot string // Used to initially populate the device client pool, and create clients for open files. ClientFactory DeviceClientFactory // Maximum number of concurrent connections for short-lived connections (does not restrict // the number of concurrently open files). // Values <1 are treated as 1. ConnectionPoolSize int ReadOnly bool }
Config stores arguments used by AdbFileSystem.
type DeviceClient ¶
type DeviceClient interface { OpenRead(path string, log *LogEntry) (io.ReadCloser, error) OpenWrite(path string, perms os.FileMode, mtime time.Time, log *LogEntry) (io.WriteCloser, error) Stat(path string, log *LogEntry) (*adb.DirEntry, error) ListDirEntries(path string, log *LogEntry) ([]*adb.DirEntry, error) RunCommand(cmd string, args ...string) (string, error) }
DeviceClient wraps adb.DeviceClient for testing.
type DeviceClientFactory ¶
type DeviceClientFactory func() DeviceClient
func NewCachingDeviceClientFactory ¶
func NewCachingDeviceClientFactory(cache DirEntryCache, factory DeviceClientFactory) DeviceClientFactory
func NewGoadbDeviceClientFactory ¶
func NewGoadbDeviceClientFactory(server adb.Server, deviceSerial string, deviceDisconnectedHandler func()) DeviceClientFactory
type DirEntryCache ¶
type DirEntryCache interface { GetOrLoad(path string, loader DirEntryLoader) (entries *CachedDirEntries, err error, hit bool) Get(path string) (entries *CachedDirEntries, found bool) // Removes the entry for path from the cache without blocking on other cache operations. RemoveEventually(path string) }
DirEntryCache is a key-value cache of normalized directory paths to slices of *adb.FileEntries.
func NewDirEntryCache ¶
func NewDirEntryCache(ttl time.Duration) DirEntryCache
type DirEntryLoader ¶
type DirEntryLoader func(path string) (*CachedDirEntries, error)
type FileBuffer ¶
type FileBuffer struct { FileBufferOptions // contains filtered or unexported fields }
FileBuffer loads, provides read/write access to, and saves a file on the device. A single FileBuffer backs all the open files for a given path to provide as consistent a view of that file as possible. 1 or more AdbFiles may point to a single FileBuffer.
Note: On OSX at least, the OS will automatically map multiple open files to a single AdbFile. Still, this type is still useful because it separates the file model and logic from the go-fuse-specific integration code.
func NewFileBuffer ¶
func NewFileBuffer(initialFlags FileOpenFlags, opts FileBufferOptions, logEntry *LogEntry) (file *FileBuffer, err error)
NewFileBuffer returns a File that reads and writes to name on the device. initialFlags are the flags being used to open the file the first time, and are only used to determine if the buffer needs to be read into memory when initializing.
func (*FileBuffer) Contents ¶
func (f *FileBuffer) Contents() string
func (*FileBuffer) DecRefCount ¶
func (f *FileBuffer) DecRefCount() int
func (*FileBuffer) Flush ¶
func (f *FileBuffer) Flush(logEntry *LogEntry) error
Flush saves the buffer to the device if dirty, else does nothing. Like Sync, but without the read.
func (*FileBuffer) IncRefCount ¶
func (f *FileBuffer) IncRefCount() int
func (*FileBuffer) IsDirty ¶
func (f *FileBuffer) IsDirty() bool
func (*FileBuffer) ReadAt ¶
func (f *FileBuffer) ReadAt(buf []byte, off int64) (n int, err error)
ReadAt implements the io.ReaderAt interface.
func (*FileBuffer) RefCount ¶
func (f *FileBuffer) RefCount() int
func (*FileBuffer) SetSize ¶
func (f *FileBuffer) SetSize(size int64)
func (*FileBuffer) Size ¶
func (f *FileBuffer) Size() int64
func (*FileBuffer) Sync ¶
func (f *FileBuffer) Sync(logEntry *LogEntry) error
Sync saves the buffer to the device if dirty, else reloads the buffer from the device. Like Flush, but reloads the buffer if not dirty.
func (*FileBuffer) SyncIfTooDirty ¶
func (f *FileBuffer) SyncIfTooDirty(logEntry *LogEntry) error
SyncIfTooDirty performs a sync if the buffer has been dirty for longer than the timeout specified in FileBufferOptions.
type FileBufferOptions ¶
type FileBufferOptions struct { Path string Client DeviceClient Clock Clock DirtyTimeout time.Duration // The permissions to set on the file when flushing. // If this is DontSetPerms, the file's existing permissions will be used. // Set from the existing file if it exists, or to the desired new permissions if new. Perms os.FileMode // Function called when ref count hits 0. // Note that, because concurrency, the ref count may be incremented again by the time // this function is executed. ZeroRefCountHandler func(*FileBuffer) }
type FileOpenFlags ¶
type FileOpenFlags uint32
Helper methods around the flags passed to the Open call.
func (FileOpenFlags) CanRead ¶
func (f FileOpenFlags) CanRead() bool
func (FileOpenFlags) CanWrite ¶
func (f FileOpenFlags) CanWrite() bool
func (FileOpenFlags) Contains ¶
func (f FileOpenFlags) Contains(bits FileOpenFlags) bool
Contains returns true if the current flags contain any of the bits in bits.
func (FileOpenFlags) GoString ¶
func (f FileOpenFlags) GoString() string
func (FileOpenFlags) String ¶
func (f FileOpenFlags) String() string
type LogEntry ¶
type LogEntry struct {
// contains filtered or unexported fields
}
LogEntry reports results, errors, and statistics for an individual operation. Each method can only be called once, and will panic on subsequent calls.
If an error is reported, it is logged as a separate entry.
Example Usage
func DoTheThing(path string) fuse.Status { logEntry := StartOperation("DoTheThing", path) defer FinishOperation(log) // Where log is a logrus logger. result, err := perform(path) if err != nil { logEntry.Error(err) return err } logEntry.Result(result) return logEntry.Status(fuse.OK) }
func StartFileOperation ¶
func StartOperation ¶
StartOperation creates a new LogEntry with the current time. Should be immediately followed by a deferred call to FinishOperation.
func (*LogEntry) CacheUsed ¶
CacheUsed records that a cache was used to attempt to retrieve a result.
func (*LogEntry) FinishOperation ¶
func (r *LogEntry) FinishOperation()
FinishOperation should be deferred. It will log the duration of the operation, as well as any results and/or errors.
func (*LogEntry) SuppressFinishOperation ¶
func (r *LogEntry) SuppressFinishOperation()
type OpenFiles ¶
type OpenFiles struct { OpenFilesOptions // contains filtered or unexported fields }
OpenFiles tracks and manages the set of all open files in a filesystem.
func NewOpenFiles ¶
func NewOpenFiles(opts OpenFilesOptions) *OpenFiles
func (*OpenFiles) GetOrLoad ¶
func (f *OpenFiles) GetOrLoad(path string, openFlags FileOpenFlags, perms os.FileMode, logEntry *LogEntry) (file *FileBuffer, err error)
type OpenFilesOptions ¶
type WrappingFile ¶
type WrappingFile struct { nodefs.File BeforeCall func(fs *WrappingFile, method string, args ...interface{}) (call interface{}) // AfterCall is called after every operation on the file with the method receiver, // the name of the method, and slices of all the passed and returned values. AfterCall func(fs *WrappingFile, call interface{}, status *fuse.Status, results ...interface{}) }
WrappingFile is an implementation of nodefs.File that invokes a callback after every method call.
func (*WrappingFile) Chown ¶
func (f *WrappingFile) Chown(uid uint32, gid uint32) (code fuse.Status)
func (*WrappingFile) Flush ¶
func (f *WrappingFile) Flush() (code fuse.Status)
Flush is called for close() call on a file descriptor. In case of duplicated descriptor, it may be called more than once for a file.
func (*WrappingFile) InnerFile ¶
func (f *WrappingFile) InnerFile() (file nodefs.File)
Wrappers around other File implementations, should return the inner file here.
func (*WrappingFile) Read ¶
func (f *WrappingFile) Read(dest []byte, off int64) (result fuse.ReadResult, code fuse.Status)
func (*WrappingFile) Release ¶
func (f *WrappingFile) Release()
This is called to before the file handle is forgotten. This method has no return value, so nothing can synchronizes on the call. Any cleanup that requires specific synchronization or could fail with I/O errors should happen in Flush instead.
func (*WrappingFile) SetInode ¶
func (f *WrappingFile) SetInode(inode *nodefs.Inode)
Called upon registering the filehandle in the inode.
func (*WrappingFile) String ¶
func (f *WrappingFile) String() string
The String method is for debug printing.
func (*WrappingFile) Truncate ¶
func (f *WrappingFile) Truncate(size uint64) (code fuse.Status)
The methods below may be called on closed files, due to concurrency. In that case, you should return EBADF.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
cmd
|
|
adbfs
Another FUSE filesystem that can mount any device visible to your adb server.
|
Another FUSE filesystem that can mount any device visible to your adb server. |
adbfs-automount
Connects to the adb server to listen for new devices, and mounts devices under a certain directory when connected.
|
Connects to the adb server to listen for new devices, and mounts devices under a certain directory when connected. |
internal
|
|
cli
Command-line options and utilities used by multiple cmds.
|
Command-line options and utilities used by multiple cmds. |