go9p

package
v1.34.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2024 License: Apache-2.0, BSD-3-Clause Imports: 15 Imported by: 20

README

This is go9p done in a way that I can understand.

To install: export GOPATH=~rminnich/go go get -a /k8s.io/minikube/third_party/go9p go get -a /k8s.io/minikube/third_party/go9p/ufs go install -a /k8s.io/minikube/third_party/go9p/ufs

~/go/bin/ufs

Documentation

Overview

The clnt package go9provides definitions and functions used to implement a 9P2000 file client.

The p9 package go9provides the definitions and functions used to implement the 9P2000 protocol. TODO. All the packet conversion code in this file is crap and needs a rewrite.

The srv package go9provides definitions and functions used to implement a 9P2000 file server.

Index

Constants

View Source
const (
	DbgPrintFcalls  = (1 << iota) // print all 9P messages on stderr
	DbgPrintPackets               // print the raw packets on stderr
	DbgLogFcalls                  // keep the last N 9P messages (can be accessed over http)
	DbgLogPackets                 // keep the last N 9P messages (can be accessed over http)
)

Debug flags

View Source
const (
	Tversion = 100 + iota
	Rversion
	Tauth
	Rauth
	Tattach
	Rattach
	Terror
	Rerror
	Tflush
	Rflush
	Twalk
	Rwalk
	Topen
	Ropen
	Tcreate
	Rcreate
	Tread
	Rread
	Twrite
	Rwrite
	Tclunk
	Rclunk
	Tremove
	Rremove
	Tstat
	Rstat
	Twstat
	Rwstat
	Tlast
)

9P2000 message types

View Source
const (
	MSIZE   = 1048576 + IOHDRSZ // default message size (1048576+IOHdrSz)
	IOHDRSZ = 24                // the non-data size of the Twrite messages
	PORT    = 564               // default port for 9P file servers
)
View Source
const (
	QTDIR     = 0x80 // directories
	QTAPPEND  = 0x40 // append only files
	QTEXCL    = 0x20 // exclusive use files
	QTMOUNT   = 0x10 // mounted channel
	QTAUTH    = 0x08 // authentication file
	QTTMP     = 0x04 // non-backed-up file
	QTSYMLINK = 0x02 // symbolic link (Unix, 9P2000.u)
	QTLINK    = 0x01 // hard link (Unix, 9P2000.u)
	QTFILE    = 0x00
)

Qid types

View Source
const (
	OREAD   = 0  // open read-only
	OWRITE  = 1  // open write-only
	ORDWR   = 2  // open read-write
	OEXEC   = 3  // execute (== read but check execute permission)
	OTRUNC  = 16 // or'ed in (except for exec), truncate file first
	OCEXEC  = 32 // or'ed in, close on exec
	ORCLOSE = 64 // or'ed in, remove on close
)

Flags for the mode field in Topen and Tcreate messages

View Source
const (
	DMDIR       = 0x80000000 // mode bit for directories
	DMAPPEND    = 0x40000000 // mode bit for append only files
	DMEXCL      = 0x20000000 // mode bit for exclusive use files
	DMMOUNT     = 0x10000000 // mode bit for mounted channel
	DMAUTH      = 0x08000000 // mode bit for authentication file
	DMTMP       = 0x04000000 // mode bit for non-backed-up file
	DMSYMLINK   = 0x02000000 // mode bit for symbolic link (Unix, 9P2000.u)
	DMLINK      = 0x01000000 // mode bit for hard link (Unix, 9P2000.u)
	DMDEVICE    = 0x00800000 // mode bit for device file (Unix, 9P2000.u)
	DMNAMEDPIPE = 0x00200000 // mode bit for named pipe (Unix, 9P2000.u)
	DMSOCKET    = 0x00100000 // mode bit for socket (Unix, 9P2000.u)
	DMSETUID    = 0x00080000 // mode bit for setuid (Unix, 9P2000.u)
	DMSETGID    = 0x00040000 // mode bit for setgid (Unix, 9P2000.u)
	DMREAD      = 0x4        // mode bit for read permission
	DMWRITE     = 0x2        // mode bit for write permission
	DMEXEC      = 0x1        // mode bit for execute permission
)

File modes

View Source
const (
	NOTAG uint16 = 0xFFFF     // no tag specified
	NOFID uint32 = 0xFFFFFFFF // no fid specified
	NOUID uint32 = 0xFFFFFFFF // no uid specified
)
View Source
const (
	EPERM   = 1
	ENOENT  = 2
	EIO     = 5
	EEXIST  = 17
	ENOTDIR = 20
	EINVAL  = 22
)

Error values

Variables

View Source
var Akaros = boolPointer(false)

(r2d4): We don't want this exposed in minikube right now var Akaros = flag.Bool("akaros", false, "Akaros extensions")

View Source
var DefaultDebuglevel int
View Source
var Ebadoffset error = &Error{"bad offset in directory read", EINVAL}
View Source
var Ebaduse error = &Error{"bad use of fid", EINVAL}
View Source
var Edirchange error = &Error{"cannot convert between files and directories", EINVAL}
View Source
var Eexist = &Error{"file already exists", EEXIST}
View Source
var Einuse error = &Error{"fid already in use", EINVAL}
View Source
var Enoauth error = &Error{"no authentication required", EINVAL}
View Source
var Enoent = &Error{"file not found", ENOENT}
View Source
var Enotdir error = &Error{"not a directory", ENOTDIR}
View Source
var Enotempty = &Error{"directory not empty", EPERM}
View Source
var Enotimpl error = &Error{"not implemented", EINVAL}
View Source
var Enouser error = &Error{"unknown user", EINVAL}
View Source
var Eopen error = &Error{"fid already opened", EINVAL}
View Source
var Eperm error = &Error{"permission denied", EPERM}
View Source
var Etoolarge error = &Error{"i/o count too large", EINVAL}
View Source
var Eunknownfid error = &Error{"unknown fid", EINVAL}
View Source
var OsUsers *osUsers

Simple Users implementation that fakes looking up users and groups by uid only. The names and groups memberships are empty

Functions

func Gint32

func Gint32(buf []byte) (uint32, []byte)

func InitRread

func InitRread(fc *Fcall, count uint32) error

Initializes the specified Fcall value to contain Rread message. The user should copy the returned data to the slice pointed by fc.Data and call SetRreadCount to update the data size to the actual value.

func PackDir

func PackDir(d *Dir, dotu bool) []byte

Converts a Dir value to its on-the-wire representation and writes it to the buf. Returns the number of bytes written, 0 if there is not enough space.

func PackRattach

func PackRattach(fc *Fcall, aqid *Qid) error

Create a Rattach message in the specified Fcall.

func PackRauth

func PackRauth(fc *Fcall, aqid *Qid) error

Create a Rauth message in the specified Fcall.

func PackRclunk

func PackRclunk(fc *Fcall) error

Create a Rclunk message in the specified Fcall.

func PackRcreate

func PackRcreate(fc *Fcall, qid *Qid, iounit uint32) error

Create a Rcreate message in the specified Fcall.

func PackRerror

func PackRerror(fc *Fcall, error string, errornum uint32, dotu bool) error

func PackRflush

func PackRflush(fc *Fcall) error

Create a Rflush message in the specified Fcall.

func PackRopen

func PackRopen(fc *Fcall, qid *Qid, iounit uint32) error

Create a Ropen message in the specified Fcall.

func PackRread

func PackRread(fc *Fcall, data []byte) error

Create a Rread message in the specified Fcall.

func PackRremove

func PackRremove(fc *Fcall) error

Create a Rremove message in the specified Fcall.

func PackRstat

func PackRstat(fc *Fcall, d *Dir, dotu bool) error

Create a Rstat message in the specified Fcall. If dotu is true, the function will create a 9P2000.u stat representation that includes st.Nuid, st.Ngid, st.Nmuid and st.Ext. Otherwise these values will be ignored.

func PackRversion

func PackRversion(fc *Fcall, msize uint32, version string) error

Create a Rversion message in the specified Fcall.

func PackRwalk

func PackRwalk(fc *Fcall, wqids []Qid) error

Create a Rwalk message in the specified Fcall.

func PackRwrite

func PackRwrite(fc *Fcall, count uint32) error

Create a Rwrite message in the specified Fcall.

func PackRwstat

func PackRwstat(fc *Fcall) error

Create a Rwstat message in the specified Fcall.

func PackTattach

func PackTattach(fc *Fcall, fid uint32, afid uint32, uname string, aname string, unamenum uint32, dotu bool) error

Create a Tattach message in the specified Fcall. If dotu is true, the function will create 9P2000.u including the nuname value, otherwise nuname is ignored.

func PackTauth

func PackTauth(fc *Fcall, fid uint32, uname string, aname string, unamenum uint32, dotu bool) error

Create a Tauth message in the specified Fcall.

func PackTclunk

func PackTclunk(fc *Fcall, fid uint32) error

Create a Tclunk message in the specified Fcall.

func PackTcreate

func PackTcreate(fc *Fcall, fid uint32, name string, perm uint32, mode uint8, ext string, dotu bool) error

Create a Tcreate message in the specified Fcall. If dotu is true, the function will create a 9P2000.u message that includes ext. Otherwise the ext value is ignored.

func PackTflush

func PackTflush(fc *Fcall, oldtag uint16) error

Create a Tflush message in the specified Fcall.

func PackTopen

func PackTopen(fc *Fcall, fid uint32, mode uint8) error

Create a Topen message in the specified Fcall.

func PackTread

func PackTread(fc *Fcall, fid uint32, offset uint64, count uint32) error

Create a Tread message in the specified Fcall.

func PackTremove

func PackTremove(fc *Fcall, fid uint32) error

Create a Tremove message in the specified Fcall.

func PackTstat

func PackTstat(fc *Fcall, fid uint32) error

Create a Tstat message in the specified Fcall.

func PackTversion

func PackTversion(fc *Fcall, msize uint32, version string) error

Create a Tversion message in the specified Fcall.

func PackTwalk

func PackTwalk(fc *Fcall, fid uint32, newfid uint32, wnames []string) error

Create a Twalk message in the specified Fcall.

func PackTwrite

func PackTwrite(fc *Fcall, fid uint32, offset uint64, count uint32, data []byte) error

Create a Twrite message in the specified Fcall.

func PackTwstat

func PackTwstat(fc *Fcall, fid uint32, d *Dir, dotu bool) error

Create a Twstat message in the specified Fcall. If dotu is true the function will create 9P2000.u message, otherwise the 9P2000.u specific fields from the Stat value will be ignored.

func SetRreadCount

func SetRreadCount(fc *Fcall, count uint32)

Updates the size of the data returned by Rread. Expects that the Fcall value is already initialized by InitRread.

func SetTag

func SetTag(fc *Fcall, tag uint16)

Sets the tag of a Fcall.

Types

type AuthOps

type AuthOps interface {
	// AuthInit is called when the user starts the authentication
	// process on SrvFid afid. The user that is being authenticated
	// is referred by afid.User. The function should return the Qid
	// for the authentication file, or an Error if the user can't be
	// authenticated
	AuthInit(afid *SrvFid, aname string) (*Qid, error)

	// AuthDestroy is called when an authentication fid is destroyed.
	AuthDestroy(afid *SrvFid)

	// AuthCheck is called after the authentication process is finished
	// when the user tries to attach to the file server. If the function
	// returns nil, the authentication was successful and the user has
	// permission to access the files.
	AuthCheck(fid *SrvFid, afid *SrvFid, aname string) error

	// AuthRead is called when the user attempts to read data from an
	// authentication fid.
	AuthRead(afid *SrvFid, offset uint64, data []byte) (count int, err error)

	// AuthWrite is called when the user attempts to write data to an
	// authentication fid.
	AuthWrite(afid *SrvFid, offset uint64, data []byte) (count int, err error)
}

Authentication operations. The file server should implement them if it requires user authentication. The authentication in 9P2000 is done by creating special authentication fids and performing I/O operations on them. Once the authentication is done, the authentication fid can be used by the user to get access to the actual files.

type Clnt

type Clnt struct {
	sync.Mutex
	Debuglevel int    // =0 don't print anything, >0 print Fcalls, >1 print raw packets
	Msize      uint32 // Maximum size of the 9P messages
	Dotu       bool   // If true, 9P2000.u protocol is spoken
	Root       *Fid   // Fid that points to the root directory
	Id         string // Used when printing debug messages
	Log        *Logger
	// contains filtered or unexported fields
}

The Clnt type represents a 9P2000 client. The client is connected to a 9P2000 file server and its methods can be used to access and manipulate the files exported by the server.

func Connect

func Connect(c net.Conn, msize uint32, dotu bool) (*Clnt, error)

Establishes a new socket connection to the 9P server and creates a client object for it. Negotiates the dialect and msize for the connection. Returns a Clnt object, or Error.

func Mount

func Mount(ntype, addr, aname string, msize uint32, user User) (*Clnt, error)

Connects to a file server and attaches to it as the specified user.

func MountConn

func MountConn(c net.Conn, aname string, msize uint32, user User) (*Clnt, error)

func NewClnt

func NewClnt(c net.Conn, msize uint32, dotu bool) *Clnt

Creates and initializes a new Clnt object. Doesn't send any data on the wire.

func (*Clnt) Attach

func (clnt *Clnt) Attach(afid *Fid, user User, aname string) (*Fid, error)

Creates a fid for the specified user that points to the root of the file server's file tree. Returns a Fid pointing to the root, if successful, or an Error.

func (*Clnt) Auth

func (clnt *Clnt) Auth(user User, aname string) (*Fid, error)

Creates an authentication fid for the specified user. Returns the fid, if successful, or an Error.

func (*Clnt) Clunk

func (clnt *Clnt) Clunk(fid *Fid) (err error)

Clunks a fid. Returns nil if successful.

func (*Clnt) Create

func (clnt *Clnt) Create(fid *Fid, name string, perm uint32, mode uint8, ext string) error

Creates a file in the directory associated with the fid. Returns nil if the operation is successful.

func (*Clnt) FCreate

func (clnt *Clnt) FCreate(path string, perm uint32, mode uint8) (*File, error)

Creates and opens a named file. Returns the file if the operation is successful, or an Error.

func (*Clnt) FOpen

func (clnt *Clnt) FOpen(path string, mode uint8) (*File, error)

Opens a named file. Returns the opened file, or an Error.

func (*Clnt) FRemove

func (clnt *Clnt) FRemove(path string) error

Removes the named file. Returns nil if the operation is successful.

func (*Clnt) FStat

func (clnt *Clnt) FStat(path string) (*Dir, error)

Returns the metadata for a named file, or an Error.

func (*Clnt) FWalk

func (clnt *Clnt) FWalk(path string) (*Fid, error)

Walks to a named file. Returns a Fid associated with the file, or an Error.

func (*Clnt) FidAlloc

func (clnt *Clnt) FidAlloc() *Fid

Creates a new Fid object for the client

func (*Clnt) FreeFcall

func (clnt *Clnt) FreeFcall(fc *Fcall)

func (*Clnt) NewFcall

func (clnt *Clnt) NewFcall() *Fcall

func (*Clnt) Open

func (clnt *Clnt) Open(fid *Fid, mode uint8) error

Opens the file associated with the fid. Returns nil if the operation is successful.

func (*Clnt) Read

func (clnt *Clnt) Read(fid *Fid, offset uint64, count uint32) ([]byte, error)

Reads count bytes starting from offset from the file associated with the fid. Returns a slice with the data read, if the operation was successful, or an Error.

func (*Clnt) Remove

func (clnt *Clnt) Remove(fid *Fid) error

Removes the file associated with the Fid. Returns nil if the operation is successful.

func (*Clnt) ReqAlloc

func (clnt *Clnt) ReqAlloc() *Req

func (*Clnt) ReqFree

func (clnt *Clnt) ReqFree(req *Req)

func (*Clnt) Rpc

func (clnt *Clnt) Rpc(tc *Fcall) (rc *Fcall, err error)

func (*Clnt) Rpcnb

func (clnt *Clnt) Rpcnb(r *Req) error

func (*Clnt) Stat

func (clnt *Clnt) Stat(fid *Fid) (*Dir, error)

Returns the metadata for the file associated with the Fid, or an Error.

func (*Clnt) TagAlloc

func (clnt *Clnt) TagAlloc(reqchan chan *Req) *Tag

func (*Clnt) TagFree

func (clnt *Clnt) TagFree(tag *Tag)

func (*Clnt) Unmount

func (clnt *Clnt) Unmount()

Closes the connection to the file server.

func (*Clnt) Walk

func (clnt *Clnt) Walk(fid *Fid, newfid *Fid, wnames []string) ([]Qid, error)

Starting from the file associated with fid, walks all wnames in sequence and associates the resulting file with newfid. If no wnames were walked successfully, an Error is returned. Otherwise a slice with a Qid for each walked name is returned.

func (*Clnt) Write

func (clnt *Clnt) Write(fid *Fid, data []byte, offset uint64) (int, error)

Write up to len(data) bytes starting from offset. Returns the number of bytes written, or an Error.

func (*Clnt) Wstat

func (clnt *Clnt) Wstat(fid *Fid, dir *Dir) error

Modifies the data of the file associated with the Fid, or an Error.

type ClntList

type ClntList struct {
	sync.Mutex
	// contains filtered or unexported fields
}

type Conn

type Conn struct {
	sync.Mutex
	Srv        *Srv
	Msize      uint32 // maximum size of 9P2000 messages for the connection
	Dotu       bool   // if true, both the client and the server speak 9P2000.u
	Id         string // used for debugging and stats
	Debuglevel int
	// contains filtered or unexported fields
}

The Conn type represents a connection from a client to the file server

func (*Conn) FidGet

func (conn *Conn) FidGet(fidno uint32) *SrvFid

Lookup a SrvFid struct based on the 32-bit identifier sent over the wire. Returns nil if the fid is not found. Increases the reference count of the returned fid. The user is responsible to call DecRef once it no longer needs it.

func (*Conn) FidNew

func (conn *Conn) FidNew(fidno uint32) *SrvFid

Creates a new SrvFid struct for the fidno integer. Returns nil if the SrvFid for that number already exists. The returned fid has reference count set to 1.

func (*Conn) LocalAddr

func (conn *Conn) LocalAddr() net.Addr

func (*Conn) RemoteAddr

func (conn *Conn) RemoteAddr() net.Addr

func (*Conn) String

func (conn *Conn) String() string

type ConnOps

type ConnOps interface {
	ConnOpened(*Conn)
	ConnClosed(*Conn)
}

Connection operations. These should be implemented if the file server needs to be called when a connection is opened or closed.

type Dir

type Dir struct {
	Size   uint16 // size-2 of the Dir on the wire
	Type   uint16
	Dev    uint32
	Qid           // file's Qid
	Mode   uint32 // permissions and flags
	Atime  uint32 // last access time in seconds
	Mtime  uint32 // last modified time in seconds
	Length uint64 // file length in bytes
	Name   string // file name
	Uid    string // owner name
	Gid    string // group name
	Muid   string // name of the last user that modified the file

	/* 9P2000.u extension */
	Ext     string // special file's descriptor
	Uidnum  uint32 // owner ID
	Gidnum  uint32 // group ID
	Muidnum uint32 // ID of the last user that modified the file
}

Dir describes a file

func UnpackDir

func UnpackDir(buf []byte, dotu bool) (d *Dir, b []byte, amt int, err error)

Converts the on-the-wire representation of a stat to Stat value. Returns an error if the conversion is impossible, otherwise a pointer to a Stat value.

func (*Dir) String

func (d *Dir) String() string

type Error

type Error struct {
	Err      string // textual representation of the error
	Errornum uint32 // numeric representation of the error (9P2000.u)
}

Error represents a 9P2000 (and 9P2000.u) error

func (*Error) Error

func (err *Error) Error() string

type FClunkOp

type FClunkOp interface {
	Clunk(fid *FFid) error
}

type FCreateOp

type FCreateOp interface {
	Create(fid *FFid, name string, perm uint32) (*srvFile, error)
}

If the FCreateOp interface is implemented, the Create operation will be called when the client attempts to create a file in the srvFile implementing the interface. If not implemented, "permission denied" error will be send back. If successful, the operation should call (*File)Add() to add the created file to the directory. The operation returns the created file, or the error occurred while creating it.

type FDestroyOp

type FDestroyOp interface {
	FidDestroy(fid *FFid)
}

type FFid

type FFid struct {
	F   *srvFile
	Fid *SrvFid
	// contains filtered or unexported fields
}

type FFlags

type FFlags int
const (
	Fremoved FFlags = 1 << iota
)

type FOpenOp

type FOpenOp interface {
	Open(fid *FFid, mode uint8) error
}

type FReadOp

type FReadOp interface {
	Read(fid *FFid, buf []byte, offset uint64) (int, error)
}

If the FReadOp interface is implemented, the Read operation will be called to read from the file. If not implemented, "permission denied" error will be send back. The operation returns the number of bytes read, or the error occurred while reading.

type FRemoveOp

type FRemoveOp interface {
	Remove(*FFid) error
}

If the FRemoveOp interface is implemented, the Remove operation will be called when the client attempts to create a file in the srvFile implementing the interface. If not implemented, "permission denied" error will be send back. The operation returns nil if successful, or the error that occurred while removing the file.

type FStatOp

type FStatOp interface {
	Stat(fid *FFid) error
}

The FStatOp interface provides a single operation (Stat) that will be called before a file stat is sent back to the client. If implemented, the operation should update the data in the srvFile struct.

type FWriteOp

type FWriteOp interface {
	Write(fid *FFid, data []byte, offset uint64) (int, error)
}

If the FWriteOp interface is implemented, the Write operation will be called to write to the file. If not implemented, "permission denied" error will be send back. The operation returns the number of bytes written, or the error occurred while writing.

type FWstatOp

type FWstatOp interface {
	Wstat(*FFid, *Dir) error
}

The FWstatOp interface provides a single operation (Wstat) that will be called when the client requests the srvFile metadata to be modified. If implemented, the operation will be called when Twstat message is received. If not implemented, "permission denied" error will be sent back. If the operation returns an Error, the error is send back to the client.

type Fcall

type Fcall struct {
	Size    uint32   // size of the message
	Type    uint8    // message type
	Fid     uint32   // file identifier
	Tag     uint16   // message tag
	Msize   uint32   // maximum message size (used by Tversion, Rversion)
	Version string   // protocol version (used by Tversion, Rversion)
	Oldtag  uint16   // tag of the message to flush (used by Tflush)
	Error   string   // error (used by Rerror)
	Qid              // file Qid (used by Rauth, Rattach, Ropen, Rcreate)
	Iounit  uint32   // maximum bytes read without breaking in multiple messages (used by Ropen, Rcreate)
	Afid    uint32   // authentication fid (used by Tauth, Tattach)
	Uname   string   // user name (used by Tauth, Tattach)
	Aname   string   // attach name (used by Tauth, Tattach)
	Perm    uint32   // file permission (mode) (used by Tcreate)
	Name    string   // file name (used by Tcreate)
	Mode    uint8    // open mode (used by Topen, Tcreate)
	Newfid  uint32   // the fid that represents the file walked to (used by Twalk)
	Wname   []string // list of names to walk (used by Twalk)
	Wqid    []Qid    // list of Qids for the walked files (used by Rwalk)
	Offset  uint64   // offset in the file to read/write from/to (used by Tread, Twrite)
	Count   uint32   // number of bytes read/written (used by Tread, Rread, Twrite, Rwrite)
	Data    []uint8  // data read/to-write (used by Rread, Twrite)
	Dir              // file description (used by Rstat, Twstat)

	/* 9P2000.u extensions */
	Errornum uint32 // error code, 9P2000.u only (used by Rerror)
	Ext      string // special file description, 9P2000.u only (used by Tcreate)
	Unamenum uint32 // user ID, 9P2000.u only (used by Tauth, Tattach)

	Pkt []uint8 // raw packet data
	Buf []uint8 // buffer to put the raw data in
}

Fcall represents a 9P2000 message

func NewFcall

func NewFcall(sz uint32) *Fcall

Allocates a new Fcall.

func Unpack

func Unpack(buf []byte, dotu bool) (fc *Fcall, err error, fcsz int)

Creates a Fcall value from the on-the-wire representation. If dotu is true, reads 9P2000.u messages. Returns the unpacked message, error and how many bytes from the buffer were used by the message.

func (*Fcall) String

func (fc *Fcall) String() string

type Fid

type Fid struct {
	sync.Mutex
	Clnt   *Clnt // Client the fid belongs to
	Iounit uint32
	Qid           // The Qid description for the file
	Mode   uint8  // Open mode (one of O* values) (if file is open)
	Fid    uint32 // Fid number
	User          // The user the fid belongs to
	// contains filtered or unexported fields
}

A Fid type represents a file on the server. Fids are used for the low level methods that correspond directly to the 9P2000 message requests

type File

type File struct {
	Fid *Fid
	// contains filtered or unexported fields
}

The file is similar to the Fid, but is used in the high-level client interface. We expose the Fid so that client code can use Remove on a fid, the same way a kernel can.

func FidFile

func FidFile(fid *Fid, offset uint64) *File

FidFile returns a File that represents the given Fid, initially at the given offset.

func (*File) Close

func (file *File) Close() error

Closes a file. Returns nil if successful.

func (*File) Read

func (file *File) Read(buf []byte) (int, error)

Reads up to len(buf) bytes from the File. Returns the number of bytes read, or an Error.

func (*File) ReadAt

func (file *File) ReadAt(buf []byte, offset int64) (int, error)

Reads up to len(buf) bytes from the file starting from offset. Returns the number of bytes read, or an Error.

func (*File) Readdir

func (file *File) Readdir(num int) ([]*Dir, error)

Reads the content of the directory associated with the File. Returns an array of maximum num entries (if num is 0, returns all entries from the directory). If the operation fails, returns an Error.

func (*File) Readn

func (file *File) Readn(buf []byte, offset uint64) (int, error)

Reads exactly len(buf) bytes from the File starting from offset. Returns the number of bytes read (could be less than len(buf) if end-of-file is reached), or an Error.

func (*File) Write

func (file *File) Write(buf []byte) (int, error)

Writes up to len(buf) bytes to a file. Returns the number of bytes written, or an Error.

func (*File) WriteAt

func (file *File) WriteAt(buf []byte, offset int64) (int, error)

Writes up to len(buf) bytes starting from offset. Returns the number of bytes written, or an Error.

func (*File) Writen

func (file *File) Writen(buf []byte, offset uint64) (int, error)

Writes exactly len(buf) bytes starting from offset. Returns the number of bytes written. If Error is returned the number of bytes can be less than len(buf).

type FlushOp

type FlushOp interface {
	Flush(*SrvReq)
}

Flush operation. This interface should be implemented if the file server can flush pending requests. If the interface is not implemented, requests that were passed to the file server implementation won't be flushed. The flush method should call the (req *SrvReq) srv.Flush() method if the flush was successful so the request can be marked appropriately.

type Fsrv

type Fsrv struct {
	Srv
	Root *srvFile
}

The Fsrv can be used to create file servers that serve simple trees of synthetic files.

func NewsrvFileSrv

func NewsrvFileSrv(root *srvFile) *Fsrv

Creates a file server with root as root directory

func (*Fsrv) Attach

func (s *Fsrv) Attach(req *SrvReq)

func (*Fsrv) Clunk

func (*Fsrv) Clunk(req *SrvReq)

func (*Fsrv) Create

func (*Fsrv) Create(req *SrvReq)

func (*Fsrv) FidDestroy

func (*Fsrv) FidDestroy(ffid *SrvFid)

func (*Fsrv) Open

func (*Fsrv) Open(req *SrvReq)

func (*Fsrv) Read

func (*Fsrv) Read(req *SrvReq)

func (*Fsrv) Remove

func (*Fsrv) Remove(req *SrvReq)

func (*Fsrv) Stat

func (*Fsrv) Stat(req *SrvReq)

func (*Fsrv) Walk

func (*Fsrv) Walk(req *SrvReq)

func (*Fsrv) Write

func (*Fsrv) Write(req *SrvReq)

func (*Fsrv) Wstat

func (*Fsrv) Wstat(req *SrvReq)

type Group

type Group interface {
	Name() string    // group name
	Id() int         // group id
	Members() []User // list of members that belong to the group (can return nil)
}

Represents a group of users

type Log

type Log struct {
	Data  interface{}
	Owner interface{}
	Type  int
}

type Logger

type Logger struct {
	// contains filtered or unexported fields
}
var DefaultLogger *Logger

func NewLogger

func NewLogger(sz int) *Logger

func (*Logger) Filter

func (l *Logger) Filter(owner interface{}, itype int) []*Log

func (*Logger) Log

func (l *Logger) Log(data, owner interface{}, itype int)

func (*Logger) Resize

func (l *Logger) Resize(sz int)

type Pipefs

type Pipefs struct {
	Srv
	Root string
}

func (*Pipefs) Attach

func (pipe *Pipefs) Attach(req *SrvReq)

func (*Pipefs) Clunk

func (*Pipefs) Clunk(req *SrvReq)

func (*Pipefs) ConnClosed

func (*Pipefs) ConnClosed(conn *Conn)

func (*Pipefs) ConnOpened

func (*Pipefs) ConnOpened(conn *Conn)

func (*Pipefs) Create

func (*Pipefs) Create(req *SrvReq)

func (*Pipefs) FidDestroy

func (*Pipefs) FidDestroy(sfid *SrvFid)

func (*Pipefs) Flush

func (*Pipefs) Flush(req *SrvReq)

func (*Pipefs) Open

func (*Pipefs) Open(req *SrvReq)

func (*Pipefs) Read

func (*Pipefs) Read(req *SrvReq)

func (*Pipefs) Remove

func (*Pipefs) Remove(req *SrvReq)

func (*Pipefs) Stat

func (*Pipefs) Stat(req *SrvReq)

func (*Pipefs) Walk

func (*Pipefs) Walk(req *SrvReq)

func (*Pipefs) Write

func (*Pipefs) Write(req *SrvReq)

func (*Pipefs) Wstat

func (*Pipefs) Wstat(req *SrvReq)

type Qid

type Qid struct {
	Type    uint8  // type of the file (high 8 bits of the mode)
	Version uint32 // version number for the path
	Path    uint64 // server's unique identification of the file
}

File identifier

func (*Qid) String

func (qid *Qid) String() string

type Req

type Req struct {
	sync.Mutex
	Clnt *Clnt
	Tc   *Fcall
	Rc   *Fcall
	Err  error
	Done chan *Req
	// contains filtered or unexported fields
}

type Srv

type Srv struct {
	sync.Mutex
	Id         string // Used for debugging and stats
	Msize      uint32 // Maximum size of the 9P2000 messages supported by the server
	Dotu       bool   // If true, the server supports the 9P2000.u extension
	Debuglevel int    // debug level
	Upool      Users  // Interface for finding users and groups known to the file server
	Maxpend    int    // Maximum pending outgoing requests
	Log        *Logger
	// contains filtered or unexported fields
}

The Srv type contains the basic fields used to control the 9P2000 file server. Each file server implementation should create a value of Srv type, initialize the values it cares about and pass the struct to the (Srv *) srv.Start(ops) method together with the object that implements the file server operations.

func (*Srv) NewConn

func (srv *Srv) NewConn(c net.Conn)

func (*Srv) Start

func (srv *Srv) Start(ops interface{}) bool

The Start method should be called once the file server implementor initializes the Srv struct with the preferred values. It sets default values to the fields that are not initialized and creates the goroutines required for the server's operation. The method receives an empty interface value, ops, that should implement the interfaces the file server is interested in. Ops must implement the SrvReqOps interface.

func (*Srv) StartListener

func (srv *Srv) StartListener(l net.Listener) error

Start listening on the specified network and address for incoming connections. Once a connection is established, create a new Conn value, read messages from the socket, send them to the specified server, and send back responses received from the server.

func (*Srv) StartNetListener

func (srv *Srv) StartNetListener(ntype, addr string) error

func (*Srv) String

func (srv *Srv) String() string

type SrvFid

type SrvFid struct {
	sync.Mutex

	Fconn     *Conn       // Connection the SrvFid belongs to
	Omode     uint8       // Open mode (O* flags), if the fid is opened
	Type      uint8       // SrvFid type (QT* flags)
	Diroffset uint64      // If directory, the next valid read position
	Dirents   []byte      // If directory, the serialized dirents
	User      User        // The SrvFid's user
	Aux       interface{} // Can be used by the file server implementation for per-SrvFid data
	// contains filtered or unexported fields
}

The SrvFid type identifies a file on the file server. A new SrvFid is created when the user attaches to the file server (the Attach operation), or when Walk-ing to a file. The SrvFid values are created automatically by the srv implementation. The SrvFidDestroy operation is called when a SrvFid is destroyed.

func (*SrvFid) DecRef

func (fid *SrvFid) DecRef()

Decrease the reference count for the fid. When the reference count reaches 0, the fid is no longer valid.

func (*SrvFid) IncRef

func (fid *SrvFid) IncRef()

Increase the reference count for the fid.

type SrvFidOps

type SrvFidOps interface {
	FidDestroy(*SrvFid)
}

SrvFid operations. This interface should be implemented if the file server needs to be called when a SrvFid is destroyed.

type SrvReq

type SrvReq struct {
	sync.Mutex
	Tc     *Fcall  // Incoming 9P2000 message
	Rc     *Fcall  // Outgoing 9P2000 response
	Fid    *SrvFid // The SrvFid value for all messages that contain fid[4]
	Afid   *SrvFid // The SrvFid value for the messages that contain afid[4] (Tauth and Tattach)
	Newfid *SrvFid // The SrvFid value for the messages that contain newfid[4] (Twalk)
	Conn   *Conn   // Connection that the request belongs to
	// contains filtered or unexported fields
}

The SrvReq type represents a 9P2000 request. Each request has a T-message (Tc) and a R-message (Rc). If the SrvReqProcessOps don't override the default behavior, the implementation initializes SrvFid, Afid and Newfid values and automatically keeps track on when the SrvFids should be destroyed.

func (*SrvReq) Flush

func (req *SrvReq) Flush()

Should be called to cancel a request. Should only be called from the Flush operation if the FlushOp is implemented.

func (*SrvReq) PostProcess

func (req *SrvReq) PostProcess()

Performs the post processing required if the (*SrvReq) Process() method is called for a request. The file server implementer should call it only if the file server implements the SrvReqProcessOps within the SrvReqRespond operation.

func (*SrvReq) Process

func (req *SrvReq) Process()

Performs the default processing of a request. Initializes the SrvFid, Afid and Newfid fields and calls the appropriate SrvReqOps operation for the message. The file server implementer should call it only if the file server implements the SrvReqProcessOps within the SrvReqProcess operation.

func (*SrvReq) Respond

func (req *SrvReq) Respond()

The Respond method sends response back to the client. The req.Rc value should be initialized and contain valid 9P2000 message. In most cases the file server implementer shouldn't call this method directly. Instead one of the RespondR* methods should be used.

func (*SrvReq) RespondError

func (req *SrvReq) RespondError(err interface{})

Respond to the request with Rerror message

func (*SrvReq) RespondRattach

func (req *SrvReq) RespondRattach(aqid *Qid)

Respond to the request with Rattach message

func (*SrvReq) RespondRauth

func (req *SrvReq) RespondRauth(aqid *Qid)

Respond to the request with Rauth message

func (*SrvReq) RespondRclunk

func (req *SrvReq) RespondRclunk()

Respond to the request with Rclunk message

func (*SrvReq) RespondRcreate

func (req *SrvReq) RespondRcreate(qid *Qid, iounit uint32)

Respond to the request with Rcreate message

func (*SrvReq) RespondRflush

func (req *SrvReq) RespondRflush()

Respond to the request with Rflush message

func (*SrvReq) RespondRopen

func (req *SrvReq) RespondRopen(qid *Qid, iounit uint32)

Respond to the request with Ropen message

func (*SrvReq) RespondRread

func (req *SrvReq) RespondRread(data []byte)

Respond to the request with Rread message

func (*SrvReq) RespondRremove

func (req *SrvReq) RespondRremove()

Respond to the request with Rremove message

func (*SrvReq) RespondRstat

func (req *SrvReq) RespondRstat(st *Dir)

Respond to the request with Rstat message

func (*SrvReq) RespondRversion

func (req *SrvReq) RespondRversion(msize uint32, version string)

Respond to the request with Rversion message

func (*SrvReq) RespondRwalk

func (req *SrvReq) RespondRwalk(wqids []Qid)

Respond to the request with Rwalk message

func (*SrvReq) RespondRwrite

func (req *SrvReq) RespondRwrite(count uint32)

Respond to the request with Rwrite message

func (*SrvReq) RespondRwstat

func (req *SrvReq) RespondRwstat()

Respond to the request with Rwstat message

type SrvReqOps

type SrvReqOps interface {
	Attach(*SrvReq)
	Walk(*SrvReq)
	Open(*SrvReq)
	Create(*SrvReq)
	Read(*SrvReq)
	Write(*SrvReq)
	Clunk(*SrvReq)
	Remove(*SrvReq)
	Stat(*SrvReq)
	Wstat(*SrvReq)
}

SrvRequest operations. This interface should be implemented by all file servers. The operations correspond directly to most of the 9P2000 message types.

type SrvReqProcessOps

type SrvReqProcessOps interface {
	// Called when a new request is received from the client. If the
	// interface is not implemented, (req *SrvReq) srv.Process() method is
	// called. If the interface is implemented, it is the user's
	// responsibility to call srv.Process. If srv.Process isn't called,
	// SrvFid, Afid and Newfid fields in SrvReq are not set, and the SrvReqOps
	// methods are not called.
	SrvReqProcess(*SrvReq)

	// Called when a request is responded, i.e. when (req *SrvReq)srv.Respond()
	// is called and before the response is sent. If the interface is not
	// implemented, (req *SrvReq) srv.PostProcess() method is called to finalize
	// the request. If the interface is implemented and SrvReqProcess calls
	// the srv.Process method, SrvReqRespond should call the srv.PostProcess
	// method.
	SrvReqRespond(*SrvReq)
}

Request operations. This interface should be implemented if the file server needs to bypass the default request process, or needs to perform certain operations before the (any) request is processed, or before (any) response sent back to the client.

type StatsOps

type StatsOps interface {
	// contains filtered or unexported methods
}

type Tag

type Tag struct {
	// contains filtered or unexported fields
}

func (*Tag) Attach

func (tag *Tag) Attach(fid, afid *Fid, user User, aname string) error

func (*Tag) Auth

func (tag *Tag) Auth(afid *Fid, user User, aname string) error

func (*Tag) Clunk

func (tag *Tag) Clunk(fid *Fid) error

func (*Tag) Create

func (tag *Tag) Create(fid *Fid, name string, perm uint32, mode uint8, ext string) error

func (*Tag) Open

func (tag *Tag) Open(fid *Fid, mode uint8) error

func (*Tag) Read

func (tag *Tag) Read(fid *Fid, offset uint64, count uint32) error

func (*Tag) Remove

func (tag *Tag) Remove(fid *Fid) error

func (*Tag) ReqFree

func (tag *Tag) ReqFree(r *Req)

func (*Tag) Stat

func (tag *Tag) Stat(fid *Fid) error

func (*Tag) Walk

func (tag *Tag) Walk(fid *Fid, newfid *Fid, wnames []string) error

func (*Tag) Write

func (tag *Tag) Write(fid *Fid, data []byte, offset uint64) error

func (*Tag) Wstat

func (tag *Tag) Wstat(fid *Fid, dir *Dir) error

type Ufs

type Ufs struct {
	Srv
	Root string
}

func (*Ufs) Attach

func (ufs *Ufs) Attach(req *SrvReq)

func (*Ufs) Clunk

func (*Ufs) Clunk(req *SrvReq)

func (*Ufs) ConnClosed

func (*Ufs) ConnClosed(conn *Conn)

func (*Ufs) ConnOpened

func (*Ufs) ConnOpened(conn *Conn)

func (*Ufs) Create

func (*Ufs) Create(req *SrvReq)

func (*Ufs) FidDestroy

func (*Ufs) FidDestroy(sfid *SrvFid)

func (*Ufs) Flush

func (*Ufs) Flush(req *SrvReq)

func (*Ufs) Open

func (*Ufs) Open(req *SrvReq)

func (*Ufs) Read

func (*Ufs) Read(req *SrvReq)

func (*Ufs) Remove

func (*Ufs) Remove(req *SrvReq)

func (*Ufs) Stat

func (*Ufs) Stat(req *SrvReq)

func (*Ufs) Walk

func (*Ufs) Walk(req *SrvReq)

func (*Ufs) Write

func (*Ufs) Write(req *SrvReq)

func (*Ufs) Wstat

func (u *Ufs) Wstat(req *SrvReq)

type User

type User interface {
	Name() string          // user name
	Id() int               // user id
	Groups() []Group       // groups the user belongs to (can return nil)
	IsMember(g Group) bool // returns true if the user is member of the specified group
}

Represents a user

type Users

type Users interface {
	Uid2User(uid int) User
	Uname2User(uname string) User
	Gid2Group(gid int) Group
	Gname2Group(gname string) Group
}

Interface for accessing users and groups

Notes

Bugs

  • LookupId will never find names for groups, as it only operates on user ids.

  • Lookup will never find gids corresponding to group names, because it only operates on user names.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL