groff 1.23.0 added .MR to its -man macro package. The NEWS file states
that the inclusion of the macro "was prompted by its introduction to
Plan 9 from User Space's troff in August 2020." From d32deab it seems
that the name for Plan 9 from User Space's implementation was suggested
by groff maintainer G. Brandon Robinson.
Not sure if the intention was to make these definitions compatible, but
it would be nice if they were.
Currently, Plan 9 from User Space's .MR expects its second argument to
be parenthesized. groff's .MR does not. This results in extra
parentheses appearing in manual references when viewing Plan 9 from User
Space's manual pages on a system using groff.
631 lines
14 KiB
Plaintext
631 lines
14 KiB
Plaintext
.TH INTRO 9P
|
|
.SH NAME
|
|
intro \- introduction to the Plan 9 File Protocol, 9P
|
|
.SH SYNOPSIS
|
|
.B #include <fcall.h>
|
|
.SH DESCRIPTION
|
|
A Plan 9
|
|
.I server
|
|
is an agent that provides one or more hierarchical file systems
|
|
\(em file trees \(em
|
|
that may be accessed by Plan 9 processes.
|
|
A server responds to requests by
|
|
.I clients
|
|
to navigate the hierarchy,
|
|
and to create, remove, read, and write files.
|
|
The prototypical server is a separate machine that stores
|
|
large numbers of user files on permanent media;
|
|
such a machine is called, somewhat confusingly, a
|
|
.I file
|
|
.IR server .
|
|
Another possibility for a server is to synthesize
|
|
files on demand, perhaps based on information on data structures
|
|
maintained in memory; the
|
|
.MR plumber 4
|
|
server is an example of such a server.
|
|
.PP
|
|
A
|
|
.I connection
|
|
to a server is a bidirectional communication path from the client to the server.
|
|
There may be a single client or
|
|
multiple clients sharing the same connection.
|
|
.PP
|
|
The
|
|
.IR "Plan 9 File Protocol" ,
|
|
9P, is used for messages between
|
|
.I clients
|
|
and
|
|
.IR servers .
|
|
A client transmits
|
|
.I requests
|
|
.RI ( T-messages )
|
|
to a server, which
|
|
subsequently returns
|
|
.I replies
|
|
.RI ( R-messages )
|
|
to the client.
|
|
The combined acts of transmitting (receiving) a request of a particular type,
|
|
and receiving (transmitting)
|
|
its reply is called a
|
|
.I transaction
|
|
of that type.
|
|
.PP
|
|
Each message consists of a sequence of bytes.
|
|
Two-, four-, and eight-byte fields hold unsigned
|
|
integers represented in little-endian order
|
|
(least significant byte first).
|
|
Data items of larger or variable lengths are represented
|
|
by a two-byte field specifying a count,
|
|
.IR n ,
|
|
followed by
|
|
.I n
|
|
bytes of data.
|
|
Text strings are represented this way,
|
|
with the text itself stored as a UTF-8
|
|
encoded sequence of Unicode characters (see
|
|
.MR utf 7 ).
|
|
Text strings in 9P messages are not
|
|
.SM NUL\c
|
|
-terminated:
|
|
.I n
|
|
counts the bytes of UTF-8 data, which include no final zero byte.
|
|
The
|
|
.SM NUL
|
|
character is illegal in all text strings in 9P, and is therefore
|
|
excluded from file names, user names, and so on.
|
|
.PP
|
|
Each 9P message begins with a four-byte size field
|
|
specifying the length in bytes of the complete message including
|
|
the four bytes of the size field itself.
|
|
The next byte is the message type, one of the constants
|
|
in the enumeration in the include file
|
|
.BR <fcall.h> .
|
|
The next two bytes are an identifying
|
|
.IR tag ,
|
|
described below.
|
|
The remaining bytes are parameters of different sizes.
|
|
In the message descriptions, the number of bytes in a field
|
|
is given in brackets after the field name.
|
|
The notation
|
|
.IR parameter [ n ]
|
|
where
|
|
.I n
|
|
is not a constant represents a variable-length parameter:
|
|
.IR n [2]
|
|
followed by
|
|
.I n
|
|
bytes of data forming the
|
|
.IR parameter .
|
|
The notation
|
|
.IR string [ s ]
|
|
(using a literal
|
|
.I s
|
|
character)
|
|
is shorthand for
|
|
.IR s [2]
|
|
followed by
|
|
.I s
|
|
bytes of UTF-8 text.
|
|
(Systems may choose to reduce the set of legal characters
|
|
to reduce syntactic problems,
|
|
for example to remove slashes from name components,
|
|
but the protocol has no such restriction.
|
|
Plan 9 names may contain any printable character (that is, any character
|
|
outside hexadecimal 00-1F and 80-9F)
|
|
except slash.)
|
|
Messages are transported in byte form to allow for machine independence;
|
|
.MR fcall 3
|
|
describes routines that convert to and from this form into a machine-dependent
|
|
C structure.
|
|
.SH MESSAGES
|
|
.ta \w'\fLTsession 'u
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Tversion
|
|
.IR tag [2]
|
|
.IR msize [4]
|
|
.IR version [ s ]
|
|
.br
|
|
.IR size [4]
|
|
.B Rversion
|
|
.IR tag [2]
|
|
.IR msize [4]
|
|
.IR version [ s ]
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Tauth
|
|
.IR tag [2]
|
|
.IR afid [4]
|
|
.IR uname [ s ]
|
|
.IR aname [ s ]
|
|
.br
|
|
.br
|
|
.IR size [4]
|
|
.B Rauth
|
|
.IR tag [2]
|
|
.IR aqid [13]
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Rerror
|
|
.IR tag [2]
|
|
.IR ename [ s ]
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Tflush
|
|
.IR tag [2]
|
|
.IR oldtag [2]
|
|
.br
|
|
.IR size [4]
|
|
.B Rflush
|
|
.IR tag [2]
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Tattach
|
|
.IR tag [2]
|
|
.IR fid [4]
|
|
.IR afid [4]
|
|
.IR uname [ s ]
|
|
.IR aname [ s ]
|
|
.br
|
|
.IR size [4]
|
|
.B Rattach
|
|
.IR tag [2]
|
|
.IR qid [13]
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Twalk
|
|
.IR tag [2]
|
|
.IR fid [4]
|
|
.IR newfid [4]
|
|
.IR nwname [2]
|
|
.IR nwname *( wname [ s ])
|
|
.br
|
|
.IR size [4]
|
|
.B Rwalk
|
|
.IR tag [2]
|
|
.IR nwqid [2]
|
|
.IR nwqid *( wqid [13])
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Topen
|
|
.IR tag [2]
|
|
.IR fid [4]
|
|
.IR mode [1]
|
|
.br
|
|
.IR size [4]
|
|
.B Ropen
|
|
.IR tag [2]
|
|
.IR qid [13]
|
|
.IR iounit [4]
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Topenfd
|
|
.IR tag [2]
|
|
.IR fid [4]
|
|
.IR mode [1]
|
|
.br
|
|
.IR size [4]
|
|
.B Ropenfd
|
|
.IR tag [2]
|
|
.IR qid [13]
|
|
.IR iounit [4]
|
|
.IR unixfd [4]
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Tcreate
|
|
.IR tag [2]
|
|
.IR fid [4]
|
|
.IR name [ s ]
|
|
.IR perm [4]
|
|
.IR mode [1]
|
|
.br
|
|
.IR size [4]
|
|
.B Rcreate
|
|
.IR tag [2]
|
|
.IR qid [13]
|
|
.IR iounit [4]
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Tread
|
|
.IR tag [2]
|
|
.IR fid [4]
|
|
.IR offset [8]
|
|
.IR count [4]
|
|
.br
|
|
.IR size [4]
|
|
.B Rread
|
|
.IR tag [2]
|
|
.IR count [4]
|
|
.IR data [ count ]
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Twrite
|
|
.IR tag [2]
|
|
.IR fid [4]
|
|
.IR offset [8]
|
|
.IR count [4]
|
|
.IR data [ count ]
|
|
.br
|
|
.IR size [4]
|
|
.B Rwrite
|
|
.IR tag [2]
|
|
.IR count [4]
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Tclunk
|
|
.IR tag [2]
|
|
.IR fid [4]
|
|
.br
|
|
.IR size [4]
|
|
.B Rclunk
|
|
.IR tag [2]
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Tremove
|
|
.IR tag [2]
|
|
.IR fid [4]
|
|
.br
|
|
.IR size [4]
|
|
.B Rremove
|
|
.IR tag [2]
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Tstat
|
|
.IR tag [2]
|
|
.IR fid [4]
|
|
.br
|
|
.IR size [4]
|
|
.B Rstat
|
|
.IR tag [2]
|
|
.IR stat [ n ]
|
|
.IP
|
|
.ne 2v
|
|
.IR size [4]
|
|
.B Twstat
|
|
.IR tag [2]
|
|
.IR fid [4]
|
|
.IR stat [ n ]
|
|
.br
|
|
.IR size [4]
|
|
.B Rwstat
|
|
.IR tag [2]
|
|
.PP
|
|
Each T-message has a
|
|
.I tag
|
|
field, chosen and used by the client to identify the message.
|
|
The reply to the message will have the same tag.
|
|
Clients must arrange that no two outstanding messages
|
|
on the same connection have the same tag.
|
|
An exception is the tag
|
|
.BR NOTAG ,
|
|
defined as
|
|
.B (ushort)~0
|
|
in
|
|
.BR <fcall.h> :
|
|
the client can use it, when establishing a connection,
|
|
to
|
|
override tag matching in
|
|
.B version
|
|
messages.
|
|
.PP
|
|
The type of an R-message will either be one greater than the type
|
|
of the corresponding T-message or
|
|
.BR Rerror ,
|
|
indicating that the request failed.
|
|
In the latter case, the
|
|
.I ename
|
|
field contains a string describing the reason for failure.
|
|
.PP
|
|
The
|
|
.B version
|
|
message identifies the version of the protocol and indicates
|
|
the maximum message size the system is prepared to handle.
|
|
It also initializes the connection and
|
|
aborts all outstanding I/O on the connection.
|
|
The set of messages between
|
|
.B version
|
|
requests is called a
|
|
.IR session .
|
|
.PP
|
|
Most T-messages contain a
|
|
.IR fid ,
|
|
a 32-bit unsigned integer that the client uses to identify
|
|
a ``current file'' on the server.
|
|
Fids are somewhat like file descriptors in a user process,
|
|
but they are not restricted to files open for I/O:
|
|
directories being examined, files being accessed by
|
|
.MR stat 3
|
|
calls, and so on \(em all files being manipulated by the operating
|
|
system \(em are identified by fids.
|
|
Fids are chosen by the client.
|
|
All requests on a connection share the same fid space;
|
|
when several clients share a connection,
|
|
the agent managing the sharing must arrange
|
|
that no two clients choose the same fid.
|
|
.PP
|
|
The fid supplied in an
|
|
.B attach
|
|
message
|
|
will be taken by the server to refer to the root of the served file tree.
|
|
The
|
|
.B attach
|
|
identifies the user
|
|
to the server and may specify a particular file tree served
|
|
by the server (for those that supply more than one).
|
|
.PP
|
|
Permission to attach to the service is proven by providing a special fid, called
|
|
.BR afid ,
|
|
in the
|
|
.B attach
|
|
message. This
|
|
.B afid
|
|
is established by exchanging
|
|
.B auth
|
|
messages and subsequently manipulated using
|
|
.B read
|
|
and
|
|
.B write
|
|
messages to exchange authentication information not defined explicitly by 9P.
|
|
Once the authentication protocol is complete, the
|
|
.B afid
|
|
is presented in the
|
|
.B attach
|
|
to permit the user to access the service.
|
|
.PP
|
|
A
|
|
.B walk
|
|
message causes the server to change the current file associated
|
|
with a fid to be a file in the directory that is the old current file, or one of
|
|
its subdirectories.
|
|
.B Walk
|
|
returns a new fid that refers to the resulting file.
|
|
Usually, a client maintains a fid for the root,
|
|
and navigates by
|
|
.B walks
|
|
from the root fid.
|
|
.PP
|
|
A client can send multiple T-messages without waiting for the corresponding
|
|
R-messages, but all outstanding T-messages must specify different tags.
|
|
The server may delay the response to a request
|
|
and respond to later ones;
|
|
this is sometimes necessary, for example when the client reads
|
|
from a file that the server synthesizes from external events
|
|
such as keyboard characters.
|
|
.PP
|
|
Replies (R-messages) to
|
|
.BR auth ,
|
|
.BR attach ,
|
|
.BR walk ,
|
|
.BR open ,
|
|
and
|
|
.B create
|
|
requests convey a
|
|
.I qid
|
|
field back to the client.
|
|
The qid represents the server's unique identification for the
|
|
file being accessed:
|
|
two files on the same server hierarchy are the same if and only if their qids
|
|
are the same.
|
|
(The client may have multiple fids pointing to a single file on a server
|
|
and hence having a single qid.)
|
|
The thirteen-byte qid fields hold a one-byte type,
|
|
specifying whether the file is a directory, append-only file, etc.,
|
|
and two unsigned integers:
|
|
first the four-byte qid
|
|
.IR version ,
|
|
then the eight-byte qid
|
|
.IR path .
|
|
The path is an integer unique among all files in the hierarchy.
|
|
If a file is deleted and recreated with the
|
|
same name in the same directory, the old and new path components of the qids
|
|
should be different.
|
|
The version is a version number for a file;
|
|
typically, it is incremented every time the file is modified.
|
|
.PP
|
|
An existing file can be
|
|
.BR opened ,
|
|
or a new file may be
|
|
.B created
|
|
in the current (directory) file.
|
|
I/O of a given number of bytes
|
|
at a given offset
|
|
on an open file is done by
|
|
.B read
|
|
and
|
|
.BR write .
|
|
.PP
|
|
A client should
|
|
.B clunk
|
|
any fid that is no longer needed.
|
|
The
|
|
.B remove
|
|
transaction deletes files.
|
|
.PP
|
|
.B Openfd
|
|
is an extension used by Unix utilities to allow traditional Unix programs
|
|
to have their input or output attached to fids on 9P servers.
|
|
See
|
|
.IR openfd (9p)
|
|
and
|
|
.MR 9pclient 3
|
|
for details.
|
|
.PP
|
|
The
|
|
.B stat
|
|
transaction retrieves information about the file.
|
|
The
|
|
.I stat
|
|
field in the reply includes the file's
|
|
name,
|
|
access permissions (read, write and execute for owner, group and public),
|
|
access and modification times, and
|
|
owner and group identifications
|
|
(see
|
|
.MR stat 3 ).
|
|
The owner and group identifications are textual names.
|
|
The
|
|
.B wstat
|
|
transaction allows some of a file's properties
|
|
to be changed.
|
|
.PP
|
|
A request can be aborted with a
|
|
flush
|
|
request.
|
|
When a server receives a
|
|
.BR Tflush ,
|
|
it should not reply to the message with tag
|
|
.I oldtag
|
|
(unless it has already replied),
|
|
and it should immediately send an
|
|
.BR Rflush .
|
|
The client must wait
|
|
until it gets the
|
|
.B Rflush
|
|
(even if the reply to the original message arrives in the interim),
|
|
at which point
|
|
.I oldtag
|
|
may be reused.
|
|
.PP
|
|
Because the message size is negotiable and some elements of the
|
|
protocol are variable length, it is possible (although unlikely) to have
|
|
a situation where a valid message is too large to fit within the negotiated size.
|
|
For example, a very long file name may cause a
|
|
.B Rstat
|
|
of the file or
|
|
.B Rread
|
|
of its directory entry to be too large to send.
|
|
In most such cases, the server should generate an error rather than
|
|
modify the data to fit, such as by truncating the file name.
|
|
The exception is that a long error string in an
|
|
.B Rerror
|
|
message should be truncated if necessary, since the string is only
|
|
advisory and in some sense arbitrary.
|
|
.PP
|
|
Most programs do not see the 9P protocol directly;
|
|
on Plan 9, calls to library
|
|
routines that access files are
|
|
translated by the kernel's mount driver
|
|
into 9P messages.
|
|
.SS Unix
|
|
On Unix, 9P services are posted as Unix domain sockets in a
|
|
well-known directory (see
|
|
.MR getns 3
|
|
and
|
|
.MR 9pserve 4 ).
|
|
Clients connect to these servers using a 9P client library
|
|
(see
|
|
.MR 9pclient 3 ).
|
|
.SH DIRECTORIES
|
|
Directories are created by
|
|
.B create
|
|
with
|
|
.B DMDIR
|
|
set in the permissions argument (see
|
|
.IR stat (9P)).
|
|
The members of a directory can be found with
|
|
.IR read (9P).
|
|
All directories must support
|
|
.B walks
|
|
to the directory
|
|
.B ..
|
|
(dot-dot)
|
|
meaning parent directory, although by convention directories
|
|
contain no explicit entry for
|
|
.B ..
|
|
or
|
|
.B .
|
|
(dot).
|
|
The parent of the root directory of a server's tree is itself.
|
|
.SH "ACCESS PERMISSIONS"
|
|
This section describes the access permission conventions
|
|
implemented by most Plan 9 file servers. These conventions
|
|
are not enforced by the protocol and may differ between servers,
|
|
especially servers built on top of foreign operating systems.
|
|
.PP
|
|
Each file server maintains a set of user and group names.
|
|
Each user can be a member of any number of groups.
|
|
Each group has a
|
|
.I group leader
|
|
who has special privileges (see
|
|
.IR stat (9P)
|
|
and
|
|
Plan 9's \fIusers\fR(6)).
|
|
Every file request has an implicit user id (copied from the original
|
|
.BR attach )
|
|
and an implicit set of groups (every group of which the user is a member).
|
|
.PP
|
|
Each file has an associated
|
|
.I owner
|
|
and
|
|
.I group
|
|
id and
|
|
three sets of permissions:
|
|
those of the owner, those of the group, and those of ``other'' users.
|
|
When the owner attempts to do something to a file, the owner, group,
|
|
and other permissions are consulted, and if any of them grant
|
|
the requested permission, the operation is allowed.
|
|
For someone who is not the owner, but is a member of the file's group,
|
|
the group and other permissions are consulted.
|
|
For everyone else, the other permissions are used.
|
|
Each set of permissions says whether reading is allowed,
|
|
whether writing is allowed, and whether executing is allowed.
|
|
A
|
|
.B walk
|
|
in a directory is regarded as executing the directory,
|
|
not reading it.
|
|
Permissions are kept in the low-order bits of the file
|
|
.IR mode :
|
|
owner read/write/execute permission represented as 1 in bits 8, 7, and 6
|
|
respectively (using 0 to number the low order).
|
|
The group permissions are in bits 5, 4, and 3,
|
|
and the other permissions are in bits 2, 1, and 0.
|
|
.PP
|
|
The file
|
|
.I mode
|
|
contains some additional attributes besides the permissions.
|
|
If bit 31
|
|
.RB ( DMDIR )
|
|
is set, the file is a directory;
|
|
if bit 30
|
|
.RB ( DMAPPEND )
|
|
is set, the file is append-only (offset is ignored in writes);
|
|
if bit 29
|
|
.RB ( DMEXCL )
|
|
is set, the file is exclusive-use (only one client may have it
|
|
open at a time);
|
|
if bit 27
|
|
.RB ( DMAUTH )
|
|
is set, the file is an authentication file established by
|
|
.B auth
|
|
messages;
|
|
if bit 26
|
|
.RB ( DMTMP )
|
|
is set, the contents of the file (or directory) are not included in nightly archives.
|
|
(Bit 28 is skipped for historical reasons.)
|
|
These bits are reproduced, from the top bit down, in the type byte of the Qid:
|
|
.BR QTDIR ,
|
|
.BR QTAPPEND ,
|
|
.BR QTEXCL ,
|
|
(skipping one bit)
|
|
.BR QTAUTH ,
|
|
and
|
|
.BR QTTMP .
|
|
The name
|
|
.BR QTFILE ,
|
|
defined to be zero,
|
|
identifies the value of the type for a plain file.
|