|  | 
 NAME     
 |  |  |  | intro – introduction to the Plan 9 File Protocol, 9P 
 | 
 SYNOPSIS     
 DESCRIPTION     
 |  |  |  | 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, perhaps based on information on data structures maintained
    in memory; the plumber(4) server is an example of such a server.
    
    
    
    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. 
    
    
    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 type. 
    
    
    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, n, followed by 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
    utf(7)). Text strings in 9P messages are not NUL-terminated: n
    counts the bytes of UTF-8 data, which include no final zero byte.
    The NUL character is illegal in all text strings in 9P, and is
    therefore excluded from file names, user names, and so on. 
    
    
    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 <fcall.h>.
    The next two bytes are an identifying 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 parameter[n] where n is not a constant represents
    a variable-length parameter: n[2] followed by n bytes of data
    forming the parameter. The notation string[s] (using a literal
    s character) is shorthand for s[2]
    followed by 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;
    fcall(3) describes routines that convert to and from this form
    into a machine-dependent C structure. 
 | 
 MESSAGES     
 |  |  |  | Each T-message has a 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 NOTAG, defined as (ushort)~0 in <fcall.h>: the client can use
    it, when establishing a
    connection, to override tag matching in version 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 describing the reason for failure. 
    
    
    The 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 version requests
    is called a session. 
    
    
    Most T-messages contain a 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 stat(3) calls, and so on -- all files being
    manipulated by the operating system
    -- 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. 
    
    
    The fid supplied in an attach message will be taken by the server
    to refer to the root of the served file tree. The 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). 
    
    
    Permission to attach to the service is proven by providing a special
    fid, called afid, in the attach message. This afid is established
    by exchanging auth messages and subsequently manipulated using
    read and write messages to exchange authentication information
    not defined explicitly by 9P. Once the authentication protocol
    is complete, the
    afid is presented in the attach to permit the user to access the
    service. 
    
    
    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, or one of its subdirectories. Walk returns a new fid that
    refers to the resulting file. Usually, a client maintains a fid
    for the root, and navigates by walks from the root fid. 
    
    
    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. 
    
    
    Replies (R-messages) to auth, 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 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
    version, then the eight-byte qid 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. 
    
    
    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 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. 
    
    
    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 openfd(9p) and 9pclient(3) for details. 
    
    
    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(3)). The owner and group identifications are textual names.
    The wstat transaction allows
    some of a file’s properties to be changed. 
    
    
    A request can be aborted with a flush 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 must wait until it gets the Rflush (even if the reply
    to the original message arrives in the interim), at which point
    oldtag may be reused.
    
    
    
    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 Rstat of the file or 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 Rerror message should be truncated
    if necessary, since the string is only advisory and in some sense
    arbitrary. 
    
    
    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.|  |  |  | size[4] Tversion tag[2] msize[4] version[s] size[4] Rversion tag[2] msize[4] version[s]
 size[4] Tauth tag[2] afid[4] uname[s] aname[s]
 size[4] Rauth tag[2] aqid[13]
 size[4] Rerror tag[2] ename[s]
 size[4] Tflush tag[2] oldtag[2]
 size[4] Rflush tag[2]
 size[4] Tattach tag[2] fid[4] afid[4] uname[s] aname[s]
 size[4] Rattach tag[2] qid[13]
 size[4] Twalk tag[2] fid[4] newfid[4] nwname[2] nwname*(wname[s])
 size[4] Rwalk tag[2] nwqid[2] nwqid*(wqid[13])
 size[4] Topen tag[2] fid[4] mode[1]
 size[4] Ropen tag[2] qid[13] iounit[4]
 size[4] Topenfd tag[2] fid[4] mode[1]
 size[4] Ropenfd tag[2] qid[13] iounit[4] unixfd[4]
 size[4] Tcreate tag[2] fid[4] name[s] perm[4] mode[1]
 size[4] Rcreate tag[2] qid[13] iounit[4]
 size[4] Tread tag[2] fid[4] offset[8] count[4]
 size[4] Rread tag[2] count[4] data[count]
 size[4] Twrite tag[2] fid[4] offset[8] count[4] data[count]
 size[4] Rwrite tag[2] count[4]
 size[4] Tclunk tag[2] fid[4]
 size[4] Rclunk tag[2]
 size[4] Tremove tag[2] fid[4]
 size[4] Rremove tag[2]
 size[4] Tstat tag[2] fid[4]
 size[4] Rstat tag[2] stat[n]
 size[4] Twstat tag[2] fid[4] stat[n]
 size[4] Rwstat tag[2]
 | 
 
 Unix     On Unix, 9P services are posted as Unix domain sockets in a well-known
    directory (see getns(3) and 9pserve(4)). Clients connect to these
    servers using a 9P client library (see 9pclient(3)).
 
 | 
 DIRECTORIES     
 |  |  |  | Directories are created by create with DMDIR set in the permissions
    argument (see stat(9P)). The members of a directory can be found
    with read(9P). All directories must support walks to the directory
    .. (dot-dot) meaning parent directory, although by convention
    directories contain no explicit entry for .. or . (dot). The parent
    of the root directory of
    a server’s tree is itself. 
 | 
 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. 
    
    
    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(9P) and Plan
    9’s 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 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 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
    permissions. If bit 31 (DMDIR) is set, the file is a directory;
    if bit 30 (DMAPPEND) is set, the file is append-only (offset is
    ignored in writes); if bit 29 (DMEXCL) is set, the file is exclusive-use
    (only one client may have it open at a time); if bit 27 (DMAUTH)
    is set, the file is an authentication file
    established by auth messages; if bit 26 (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: QTDIR, QTAPPEND,
    QTEXCL, (skipping one bit) QTAUTH, and QTTMP. The name QTFILE,
    defined to be
    zero, identifies the value of the type for a plain file. 
 | 
 |  |