1
0

names.ms 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. .TL
  2. The Use of Name Spaces in Plan 9
  3. .AU
  4. Rob Pike
  5. Dave Presotto
  6. Ken Thompson
  7. Howard Trickey
  8. Phil Winterbottom
  9. .AI
  10. .MH
  11. USA
  12. .AB
  13. .FS
  14. Appeared in
  15. .I
  16. Operating Systems Review,
  17. .R
  18. Vol. 27, #2, April 1993, pp. 72-76
  19. (reprinted from
  20. .I
  21. Proceedings of the 5th ACM SIGOPS European Workshop,
  22. .R
  23. Mont Saint-Michel, 1992, Paper nº 34).
  24. .FE
  25. Plan 9 is a distributed system built at the Computing Sciences Research
  26. Center of AT&T Bell Laboratories (now Lucent Technologies, Bell Labs) over the last few years.
  27. Its goal is to provide a production-quality system for software
  28. development and general computation using heterogeneous hardware
  29. and minimal software. A Plan 9 system comprises CPU and file
  30. servers in a central location connected together by fast networks.
  31. Slower networks fan out to workstation-class machines that serve as
  32. user terminals. Plan 9 argues that given a few carefully
  33. implemented abstractions
  34. it is possible to
  35. produce a small operating system that provides support for the largest systems
  36. on a variety of architectures and networks. The foundations of the system are
  37. built on two ideas: a per-process name space and a simple message-oriented
  38. file system protocol.
  39. .AE
  40. .PP
  41. The operating system for the CPU servers and terminals is
  42. structured as a traditional kernel: a single compiled image
  43. containing code for resource management, process control,
  44. user processes,
  45. virtual memory, and I/O. Because the file server is a separate
  46. machine, the file system is not compiled in, although the management
  47. of the name space, a per-process attribute, is.
  48. The entire kernel for the multiprocessor SGI Power Series machine
  49. is 25000 lines of C,
  50. the largest part of which is code for four networks including the
  51. Ethernet with the Internet protocol suite.
  52. Fewer than 1500 lines are machine-specific, and a
  53. functional kernel with minimal I/O can be put together from
  54. source files totaling 6000 lines. [Pike90]
  55. .PP
  56. The system is relatively small for several reasons.
  57. First, it is all new: it has not had time to accrete as many fixes
  58. and features as other systems.
  59. Also, other than the network protocol, it adheres to no
  60. external interface; in particular, it is not Unix-compatible.
  61. Economy stems from careful selection of services and interfaces.
  62. Finally, wherever possible the system is built around
  63. two simple ideas:
  64. every resource in the system, either local or remote,
  65. is represented by a hierarchical file system; and
  66. a user or process
  67. assembles a private view of the system by constructing a file
  68. .I
  69. name space
  70. .R
  71. that connects these resources. [Needham]
  72. .SH
  73. File Protocol
  74. .PP
  75. All resources in Plan 9 look like file systems.
  76. That does not mean that they are repositories for
  77. permanent files on disk, but that the interface to them
  78. is file-oriented: finding files (resources) in a hierarchical
  79. name tree, attaching to them by name, and accessing their contents
  80. by read and write calls.
  81. There are dozens of file system types in Plan 9, but only a few
  82. represent traditional files.
  83. At this level of abstraction, files in Plan 9 are similar
  84. to objects, except that files are already provided with naming,
  85. access, and protection methods that must be created afresh for
  86. objects. Object-oriented readers may approach the rest of this
  87. paper as a study in how to make objects look like files.
  88. .PP
  89. The interface to file systems is defined by a protocol, called 9P,
  90. analogous but not very similar to the NFS protocol.
  91. The protocol talks about files, not blocks; given a connection to the root
  92. directory of a file server,
  93. the 9P messages navigate the file hierarchy, open files for I/O,
  94. and read or write arbitrary bytes in the files.
  95. 9P contains 17 message types: three for
  96. initializing and
  97. authenticating a connection and fourteen for manipulating objects.
  98. The messages are generated by the kernel in response to user- or
  99. kernel-level I/O requests.
  100. Here is a quick tour of the major message types.
  101. The
  102. .CW auth
  103. and
  104. .CW attach
  105. messages authenticate a connection, established by means outside 9P,
  106. and validate its user.
  107. The result is an authenticated
  108. .I channel
  109. that points to the root of the
  110. server.
  111. The
  112. .CW clone
  113. message makes a new channel identical to an existing channel,
  114. which may be moved to a file on the server using a
  115. .CW walk
  116. message to descend each level in the hierarchy.
  117. The
  118. .CW stat
  119. and
  120. .CW wstat
  121. messages read and write the attributes of the file pointed to by a channel.
  122. The
  123. .CW open
  124. message prepares a channel for subsequent
  125. .CW read
  126. and
  127. .CW write
  128. messages to access the contents of the file, while
  129. .CW create
  130. and
  131. .CW remove
  132. perform, on the files, the actions implied by their names.
  133. The
  134. .CW clunk
  135. message discards a channel without affecting the file.
  136. None of the 9P messages consider caching; file caches are provided,
  137. when needed, either within the server (centralized caching)
  138. or by implementing the cache as a transparent file system between the
  139. client and the 9P connection to the server (client caching).
  140. .PP
  141. For efficiency, the connection to local
  142. kernel-resident file systems, misleadingly called
  143. .I devices,
  144. is by regular rather than remote procedure calls.
  145. The procedures map one-to-one with 9P message types.
  146. Locally each channel has an associated data structure
  147. that holds a type field used to index
  148. a table of procedure calls, one set per file system type,
  149. analogous to selecting the method set for an object.
  150. One kernel-resident file system, the
  151. .I
  152. mount device,
  153. .R
  154. translates the local 9P procedure calls into RPC messages to
  155. remote services over a separately provided transport protocol
  156. such as TCP or IL, a new reliable datagram protocol, or over a pipe to
  157. a user process.
  158. Write and read calls transmit the messages over the transport layer.
  159. The mount device is the sole bridge between the procedural
  160. interface seen by user programs and remote and user-level services.
  161. It does all associated marshaling, buffer
  162. management, and multiplexing and is
  163. the only integral RPC mechanism in Plan 9.
  164. The mount device is in effect a proxy object.
  165. There is no RPC stub compiler; instead the mount driver and
  166. all servers just share a library that packs and unpacks 9P messages.
  167. .SH
  168. Examples
  169. .PP
  170. One file system type serves
  171. permanent files from the main file server,
  172. a stand-alone multiprocessor system with a
  173. 350-gigabyte
  174. optical WORM jukebox that holds the data, fronted by a two-level
  175. block cache comprising 7 gigabytes of
  176. magnetic disk and 128 megabytes of RAM.
  177. Clients connect to the file server using any of a variety of
  178. networks and protocols and access files using 9P.
  179. The file server runs a distinct operating system and has no
  180. support for user processes; other than a restricted set of commands
  181. available on the console, all it does is answer 9P messages from clients.
  182. .PP
  183. Once a day, at 5:00 AM,
  184. the file server sweeps through the cache blocks and marks dirty blocks
  185. copy-on-write.
  186. It creates a copy of the root directory
  187. and labels it with the current date, for example
  188. .CW 1995/0314 .
  189. It then starts a background process to copy the dirty blocks to the WORM.
  190. The result is that the server retains an image of the file system as it was
  191. early each morning.
  192. The set of old root directories is accessible using 9P, so a client
  193. may examine backup files using ordinary commands.
  194. Several advantages stem from having the backup service implemented
  195. as a plain file system.
  196. Most obviously, ordinary commands can access them.
  197. For example, to see when a bug was fixed
  198. .P1
  199. grep 'mouse bug fix' 1995/*/sys/src/cmd/8½/file.c
  200. .P2
  201. The owner, access times, permissions, and other properties of the
  202. files are also backed up.
  203. Because it is a file system, the backup
  204. still has protections;
  205. it is not possible to subvert security by looking at the backup.
  206. .PP
  207. The file server is only one type of file system.
  208. A number of unusual services are provided within the kernel as
  209. local file systems.
  210. These services are not limited to I/O devices such
  211. as disks. They include network devices and their associated protocols,
  212. the bitmap display and mouse,
  213. a representation of processes similar to
  214. .CW /proc
  215. [Killian], the name/value pairs that form the `environment'
  216. passed to a new process, profiling services,
  217. and other resources.
  218. Each of these is represented as a file system \(em
  219. directories containing sets of files \(em
  220. but the constituent files do not represent permanent storage on disk.
  221. Instead, they are closer in properties to UNIX device files.
  222. .PP
  223. For example, the
  224. .I console
  225. device contains the file
  226. .CW /dev/cons ,
  227. similar to the UNIX file
  228. .CW /dev/console :
  229. when written,
  230. .CW /dev/cons
  231. appends to the console typescript; when read,
  232. it returns characters typed on the keyboard.
  233. Other files in the console device include
  234. .CW /dev/time ,
  235. the number of seconds since the epoch,
  236. .CW /dev/cputime ,
  237. the computation time used by the process reading the device,
  238. .CW /dev/pid ,
  239. the process id of the process reading the device, and
  240. .CW /dev/user ,
  241. the login name of the user accessing the device.
  242. All these files contain text, not binary numbers,
  243. so their use is free of byte-order problems.
  244. Their contents are synthesized on demand when read; when written,
  245. they cause modifications to kernel data structures.
  246. .PP
  247. The
  248. .I process
  249. device contains one directory per live local process, named by its numeric
  250. process id:
  251. .CW /proc/1 ,
  252. .CW /proc/2 ,
  253. etc.
  254. Each directory contains a set of files that access the process.
  255. For example, in each directory the file
  256. .CW mem
  257. is an image of the virtual memory of the process that may be read or
  258. written for debugging.
  259. The
  260. .CW text
  261. file is a sort of link to the file from which the process was executed;
  262. it may be opened to read the symbol tables for the process.
  263. The
  264. .CW ctl
  265. file may be written textual messages such as
  266. .CW stop
  267. or
  268. .CW kill
  269. to control the execution of the process.
  270. The
  271. .CW status
  272. file contains a fixed-format line of text containing information about
  273. the process: its name, owner, state, and so on.
  274. Text strings written to the
  275. .CW note
  276. file are delivered to the process as
  277. .I notes,
  278. analogous to UNIX signals.
  279. By providing these services as textual I/O on files rather
  280. than as system calls (such as
  281. .CW kill )
  282. or special-purpose operations (such as
  283. .CW ptrace ),
  284. the Plan 9 process device simplifies the implementation of
  285. debuggers and related programs.
  286. For example, the command
  287. .P1
  288. cat /proc/*/status
  289. .P2
  290. is a crude form of the
  291. .CW ps
  292. command; the actual
  293. .CW ps
  294. merely reformats the data so obtained.
  295. .PP
  296. The
  297. .I bitmap
  298. device contains three files,
  299. .CW /dev/mouse ,
  300. .CW /dev/screen ,
  301. and
  302. .CW /dev/bitblt ,
  303. that provide an interface to the local bitmap display (if any) and pointing device.
  304. The
  305. .CW mouse
  306. file returns a fixed-format record containing
  307. 1 byte of button state and 4 bytes each of
  308. .I x
  309. and
  310. .I y
  311. position of the mouse.
  312. If the mouse has not moved since the file was last read, a subsequent read will
  313. block.
  314. The
  315. .CW screen
  316. file contains a memory image of the contents of the display;
  317. the
  318. .CW bitblt
  319. file provides a procedural interface.
  320. Calls to the graphics library are translated into messages that are written
  321. to the
  322. .CW bitblt
  323. file to perform bitmap graphics operations. (This is essentially a nested
  324. RPC protocol.)
  325. .PP
  326. The various services being used by a process are gathered together into the
  327. process's
  328. .I
  329. name space,
  330. .R
  331. a single rooted hierarchy of file names.
  332. When a process forks, the child process shares the name space with the parent.
  333. Several system calls manipulate name spaces.
  334. Given a file descriptor
  335. .CW fd
  336. that holds an open communications channel to a service,
  337. the call
  338. .P1
  339. mount(int fd, char *old, int flags)
  340. .P2
  341. authenticates the user and attaches the file tree of the service to
  342. the directory named by
  343. .CW old .
  344. The
  345. .CW flags
  346. specify how the tree is to be attached to
  347. .CW old :
  348. replacing the current contents or appearing before or after the
  349. current contents of the directory.
  350. A directory with several services mounted is called a
  351. .I union
  352. directory and is searched in the specified order.
  353. The call
  354. .P1
  355. bind(char *new, char *old, int flags)
  356. .P2
  357. takes the portion of the existing name space visible at
  358. .CW new ,
  359. either a file or a directory, and makes it also visible at
  360. .CW old .
  361. For example,
  362. .P1
  363. bind("1995/0301/sys/include", "/sys/include", REPLACE)
  364. .P2
  365. causes the directory of include files to be overlaid with its
  366. contents from the dump on March first.
  367. .PP
  368. A process is created by the
  369. .CW rfork
  370. system call, which takes as argument a bit vector defining which
  371. attributes of the process are to be shared between parent
  372. and child instead of copied.
  373. One of the attributes is the name space: when shared, changes
  374. made by either process are visible in the other; when copied,
  375. changes are independent.
  376. .PP
  377. Although there is no global name space,
  378. for a process to function sensibly the local name spaces must adhere
  379. to global conventions.
  380. Nonetheless, the use of local name spaces is critical to the system.
  381. Both these ideas are illustrated by the use of the name space to
  382. handle heterogeneity.
  383. The binaries for a given architecture are contained in a directory
  384. named by the architecture, for example
  385. .CW /mips/bin ;
  386. in use, that directory is bound to the conventional location
  387. .CW /bin .
  388. Programs such as shell scripts need not know the CPU type they are
  389. executing on to find binaries to run.
  390. A directory of private binaries
  391. is usually unioned with
  392. .CW /bin .
  393. (Compare this to the
  394. .I
  395. ad hoc
  396. .R
  397. and special-purpose idea of the
  398. .CW PATH
  399. variable, which is not used in the Plan 9 shell.)
  400. Local bindings are also helpful for debugging, for example by binding
  401. an old library to the standard place and linking a program to see
  402. if recent changes to the library are responsible for a bug in the program.
  403. .PP
  404. The window system,
  405. .CW 8½
  406. [Pike91], is a server for files such as
  407. .CW /dev/cons
  408. and
  409. .CW /dev/bitblt .
  410. Each client sees a distinct copy of these files in its local
  411. name space: there are many instances of
  412. .CW /dev/cons ,
  413. each served by
  414. .CW 8½
  415. to the local name space of a window.
  416. Again,
  417. .CW 8½
  418. implements services using
  419. local name spaces plus the use
  420. of I/O to conventionally named files.
  421. Each client just connects its standard input, output, and error files
  422. to
  423. .CW /dev/cons ,
  424. with analogous operations to access bitmap graphics.
  425. Compare this to the implementation of
  426. .CW /dev/tty
  427. on UNIX, which is done by special code in the kernel
  428. that overloads the file, when opened,
  429. with the standard input or output of the process.
  430. Special arrangement must be made by a UNIX window system for
  431. .CW /dev/tty
  432. to behave as expected;
  433. .CW 8½
  434. instead uses the provision of the corresponding file as its
  435. central idea, which to succeed depends critically on local name spaces.
  436. .PP
  437. The environment
  438. .CW 8½
  439. provides its clients is exactly the environment under which it is implemented:
  440. a conventional set of files in
  441. .CW /dev .
  442. This permits the window system to be run recursively in one of its own
  443. windows, which is handy for debugging.
  444. It also means that if the files are exported to another machine,
  445. as described below, the window system or client applications may be
  446. run transparently on remote machines, even ones without graphics hardware.
  447. This mechanism is used for Plan 9's implementation of the X window
  448. system: X is run as a client of
  449. .CW 8½ ,
  450. often on a remote machine with lots of memory.
  451. In this configuration, using Ethernet to connect
  452. MIPS machines, we measure only a 10% degradation in graphics
  453. performance relative to running X on
  454. a bare Plan 9 machine.
  455. .PP
  456. An unusual application of these ideas is a statistics-gathering
  457. file system implemented by a command called
  458. .CW iostats .
  459. The command encapsulates a process in a local name space, monitoring 9P
  460. requests from the process to the outside world \(em the name space in which
  461. .CW iostats
  462. is itself running. When the command completes,
  463. .CW iostats
  464. reports usage and performance figures for file activity.
  465. For example
  466. .P1
  467. iostats 8½
  468. .P2
  469. can be used to discover how much I/O the window system
  470. does to the bitmap device, font files, and so on.
  471. .PP
  472. The
  473. .CW import
  474. command connects a piece of name space from a remote system
  475. to the local name space.
  476. Its implementation is to dial the remote machine and start
  477. a process there that serves the remote name space using 9P.
  478. It then calls
  479. .CW mount
  480. to attach the connection to the name space and finally dies;
  481. the remote process continues to serve the files.
  482. One use is to access devices not available
  483. locally. For example, to write a floppy one may say
  484. .P1
  485. import lab.pc /a: /n/dos
  486. cp foo /n/dos/bar
  487. .P2
  488. The call to
  489. .CW import
  490. connects the file tree from
  491. .CW /a:
  492. on the machine
  493. .CW lab.pc
  494. (which must support 9P) to the local directory
  495. .CW /n/dos .
  496. Then the file
  497. .CW foo
  498. can be written to the floppy just by copying it across.
  499. .PP
  500. Another application is remote debugging:
  501. .P1
  502. import helix /proc
  503. .P2
  504. makes the process file system on machine
  505. .CW helix
  506. available locally; commands such as
  507. .CW ps
  508. then see
  509. .CW helix 's
  510. processes instead of the local ones.
  511. The debugger may then look at a remote process:
  512. .P1
  513. db /proc/27/text /proc/27/mem
  514. .P2
  515. allows breakpoint debugging of the remote process.
  516. Since
  517. .CW db
  518. infers the CPU type of the process from the executable header on
  519. the text file, it supports
  520. cross-architecture debugging, too.
  521. Care is taken within
  522. .CW db
  523. to handle issues of byte order and floating point; it is possible to
  524. breakpoint debug a big-endian MIPS process from a little-endian i386.
  525. .PP
  526. Network interfaces are also implemented as file systems [Presotto].
  527. For example,
  528. .CW /net/tcp
  529. is a directory somewhat like
  530. .CW /proc :
  531. it contains a set of numbered directories, one per connection,
  532. each of which contains files to control and communicate on the connection.
  533. A process allocates a new connection by accessing
  534. .CW /net/tcp/clone ,
  535. which evaluates to the directory of an unused connection.
  536. To make a call, the process writes a textual message such as
  537. .CW 'connect
  538. .CW 135.104.53.2!512'
  539. to the
  540. .CW ctl
  541. file and then reads and writes the
  542. .CW data
  543. file.
  544. An
  545. .CW rlogin
  546. service can be implemented in a few of lines of shell code.
  547. .PP
  548. This structure makes network gatewaying easy to provide.
  549. We have machines with Datakit interfaces but no Internet interface.
  550. On such a machine one may type
  551. .P1
  552. import helix /net
  553. telnet tcp!ai.mit.edu
  554. .P2
  555. The
  556. .CW import
  557. uses Datakit to pull in the TCP interface from
  558. .CW helix ,
  559. which can then be used directly; the
  560. .CW tcp!
  561. notation is necessary because we routinely use multiple networks
  562. and protocols on Plan 9\(emit identifies the network in which
  563. .CW ai.mit.edu
  564. is a valid name.
  565. .PP
  566. In practice we do not use
  567. .CW rlogin
  568. or
  569. .CW telnet
  570. between Plan 9 machines. Instead a command called
  571. .CW cpu
  572. in effect replaces the CPU in a window with that
  573. on another machine, typically a fast multiprocessor CPU server.
  574. The implementation is to recreate the
  575. name space on the remote machine, using the equivalent of
  576. .CW import
  577. to connect pieces of the terminal's name space to that of
  578. the process (shell) on the CPU server, making the terminal
  579. a file server for the CPU.
  580. CPU-local devices such as fast file system connections
  581. are still local; only terminal-resident devices are
  582. imported.
  583. The result is unlike UNIX
  584. .CW rlogin ,
  585. which moves into a distinct name space on the remote machine,
  586. or file sharing with
  587. .CW NFS ,
  588. which keeps the name space the same but forces processes to execute
  589. locally.
  590. Bindings in
  591. .CW /bin
  592. may change because of a change in CPU architecture, and
  593. the networks involved may be different because of differing hardware,
  594. but the effect feels like simply speeding up the processor in the
  595. current name space.
  596. .SH
  597. Position
  598. .PP
  599. These examples illustrate how the ideas of representing resources
  600. as file systems and per-process name spaces can be used to solve
  601. problems often left to more exotic mechanisms.
  602. Nonetheless there are some operations in Plan 9 that are not
  603. mapped into file I/O.
  604. An example is process creation.
  605. We could imagine a message to a control file in
  606. .CW /proc
  607. that creates a process, but the details of
  608. constructing the environment of the new process \(em its open files,
  609. name space, memory image, etc. \(em are too intricate to
  610. be described easily in a simple I/O operation.
  611. Therefore new processes on Plan 9 are created by fairly conventional
  612. .CW rfork
  613. and
  614. .CW exec
  615. system calls;
  616. .CW /proc
  617. is used only to represent and control existing processes.
  618. .PP
  619. Plan 9 does not attempt to map network name spaces into the file
  620. system name space, for several reasons.
  621. The different addressing rules for various networks and protocols
  622. cannot be mapped uniformly into a hierarchical file name space.
  623. Even if they could be,
  624. the various mechanisms to authenticate,
  625. select a service,
  626. and control the connection would not map consistently into
  627. operations on a file.
  628. .PP
  629. Shared memory is another resource not adequately represented by a
  630. file name space.
  631. Plan 9 takes care to provide mechanisms
  632. to allow groups of local processes to share and map memory.
  633. Memory is controlled
  634. by system calls rather than special files, however,
  635. since a representation in the file system would imply that memory could
  636. be imported from remote machines.
  637. .PP
  638. Despite these limitations, file systems and name spaces offer an effective
  639. model around which to build a distributed system.
  640. Used well, they can provide a uniform, familiar, transparent
  641. interface to a diverse set of distributed resources.
  642. They carry well-understood properties of access, protection,
  643. and naming.
  644. The integration of devices into the hierarchical file system
  645. was the best idea in UNIX.
  646. Plan 9 pushes the concepts much further and shows that
  647. file systems, when used inventively, have plenty of scope
  648. for productive research.
  649. .SH
  650. References
  651. .LP
  652. [Killian] T. Killian, ``Processes as Files'', USENIX Summer Conf. Proc., Salt Lake City, 1984
  653. .br
  654. [Needham] R. Needham, ``Names'', in
  655. .I
  656. Distributed systems,
  657. .R
  658. S. Mullender, ed.,
  659. Addison Wesley, 1989
  660. .br
  661. [Pike90] R. Pike, D. Presotto, K. Thompson, H. Trickey,
  662. ``Plan 9 from Bell Labs'',
  663. UKUUG Proc. of the Summer 1990 Conf.,
  664. London, England,
  665. 1990
  666. .br
  667. [Presotto] D. Presotto, ``Multiprocessor Streams for Plan 9'',
  668. UKUUG Proc. of the Summer 1990 Conf.,
  669. London, England,
  670. 1990
  671. .br
  672. [Pike91] Pike, R., ``8.5, The Plan 9 Window System'', USENIX Summer
  673. Conf. Proc., Nashville, 1991