INTRO(5) File Formats Manual INTRO(5)
intro - introduction to the Plan 9 File Protocol, 9P
A Plan 9 server is an agent that provides one or more hierarchical file
systems -- file trees -- that may be accessed by Plan 9 processes. A
server responds to requests by 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 file server.
Another possibility for a server is to synthesize files on demand, per-
haps based on information on data structures inside the kernel; the
proc(3) kernel device is a part of the Plan 9 kernel that does this.
User programs can also act as servers.
A 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. A server's file tree is attached to a
process group's name space by bind(2) and mount calls; see intro(2).
Processes in the group are then clients of the servers: system calls
operating on files are translated into requests and responses transmit-
ted on the connection to the appropriate service.
The Plan 9 File Protocol, 9P, is used for messages between clients and
servers. A client transmits requests (T-messages) to a server, which
subsequently returns replies (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 transaction of that
Each message consists of a sequence of bytes. The first byte is the
message type, one of the constants in the enumeration in the include
file <<fcall.h>>. The remaining bytes are parameters. Each parameter
consists of a fixed number of bytes (except the data fields of write
requests or read replies); in the message descriptions below, the num-
ber of bytes in a field is given in brackets after the field name. The
two-, four-, and eight-byte fields may hold unsigned integers repre-
sented in little-endian order (least significant byte first). Fields
that contain names are 28-byte strings (including a terminal NUL (zero)
byte). Other than the NUL terminator, all characters are legal in file
names. (Systems may choose to reduce the set of legal characters to
reduce syntactic problems, for example to remove slashes from name com-
ponents, but the protocol has no such restriction. Plan 9 names may
contain any printable character (that is, any character outside hexa-
decimal 00-1F and 80-9F) except slash and blank.) Messages are trans-
ported in byte form to allow for machine independence; fcall(2)
describes routines that convert to and from this form into a machine-
dependent C structure.
Tsession tag chal
Rsession tag chal authid authdom
Rerror tag ename
Tflush tag oldtag
Tattach tag fid uid aname ticket auth
Rattach tag fid qid rauth
Tclone tag fid newfid
Rclone tag fid
Tclwalk tag fid newfid name
Rclwalk tag fid qid
Twalk tag fid name
Rwalk tag fid qid
Topen tag fid mode
Ropen tag fid qid
Tcreate tag fid name perm mode
Rcreate tag fid qid
Tread tag fid offset count
Rread tag fid count pad data[count]
Twrite tag fid offset count pad data[count]
Rwrite tag fid count
Tclunk tag fid
Rclunk tag fid
Tremove tag fid
Rremove tag fid
Tstat tag fid
Rstat tag fid stat
Twstat tag fid stat
Rwstat tag fid
Each T-message has a tag field, chosen and used by the client to iden-
tify the message. The reply to the message will have the same tag.
Clients must arrange that no two outstanding messages on the same con-
nection have the same tag. An exception is the tag 0xFFFF, meaning `no
tag': the client can use it, when establishing a connection, to over-
ride tag matching in nop and session messages.
The type of an R-message will either be one greater than the type of
the corresponding T-message or Rerror, indicating that the request
failed. In the latter case, the ename field contains a string describ-
ing the reason for failure.
The nop message request has no obvious effect. Its main purpose is in
debugging the connection between a client and a server. It is never
necessary. A session request initializes a connection and aborts all
outstanding I/O on the connection. The set of messages between session
requests is called a session.
Most T-messages contain a fid, a 16-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 stat(2) calls, and so on -- all files being manipu-
lated by the operating system -- are identified by fids. Fids are cho-
sen 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.
The first fid supplied (in an attach message) will be taken by the
server to refer to the root of the served file tree. The attach iden-
tifies the user to the server and may specify a particular file tree
served by the server (for those that supply more than one). A 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. Usu-
ally, a client maintains a fid for the root, and navigates by walks on
a fid cloned from the root fid.
A client can send multiple T-messages without waiting for the corre-
sponding R-messages, but all outstanding T-messages must specify dif-
ferent tags. The server may delay the response to a request on one fid
and respond to later requests on other fids; this is sometimes neces-
sary, for example when the client reads from a file that the server
synthesizes from external events such as keyboard characters.
Replies (R-messages) to attach, walk, open, and create requests convey
a 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 eight-byte qid fields rep-
resent two four-byte unsigned integers: first the qid path, then the
qid version. 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. Directories always have the CHDIR bit (0x80000000) set
in their qid path. The version is a version number for a file; typi-
cally, it is incremented every time the file is modified.
An existing file can be opened, or a new file may be created in the
current (directory) file. I/O of a given number of bytes (limited to
8192) at a given offset on an open file is done by read and write.
A client should clunk any fid that is no longer needed. The remove
transaction deletes files.
The stat transaction retrieves information about the file. The 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 stat(2)). The owner
and group identifications are 28-byte names. The wstat transaction
allows some of a file's properties to be changed.
A request can be aborted with a Tflush request. When a server receives
a Tflush, it should not reply to the message with tag oldtag (unless it
has already replied), and it should immediately send an Rflush. The
client should ignore replies with tag oldtag until it gets the Rflush,
at which point oldtag may be reused.
Most programs do not see the 9P protocol directly; instead calls to
library routines that access files are translated by the mount driver,
mnt(3), into 9P messages.
Directories are created by create with CHDIR set in the permissions
argument (see stat(5)). The members of a directory can be found with
read(5). All directories must support walks to the directory .. (dot-
dot) meaning parent directory, although by convention directories con-
tain no explicit entry for .. or . (dot). The parent of the root
directory of a server's tree is itself.
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 group leader
who has special privileges (see stat(5) and users(6)). Every file
request has an implicit user id (copied from the original attach) and
an implicit set of groups (every group of which the user is a member).
Each file has an associated owner and group id and three sets of per-
missions: 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 read-
ing is allowed, whether writing is allowed, and whether executing is
allowed. A walk in a directory is regarded as executing the directory,
not reading it. Permissions are kept in the low-order bits of the file
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.
The file mode contains some additional attributes besides the permis-
sions. If bit 31 is set, the file is a directory; if bit 30 is set,
the file is append-only (offset is ignored in writes); if bit 29 is
set, the file is exclusive-use (only one client may have it open at a