xref: /plan9-contrib/sys/doc/lexnames.ms (revision 426d2b71458df9b491ba6c167f699b3f1f7b0428)
1*426d2b71SDavid du Colombier.HTML "Lexical File Names in Plan 9 or Getting Dot-Dot Right
27dd7cddfSDavid du Colombier.hw re-create
37dd7cddfSDavid du Colombier.hw re-created
47dd7cddfSDavid du Colombier.TL
57dd7cddfSDavid du ColombierLexical File Names in Plan 9
67dd7cddfSDavid du Colombier.br
77dd7cddfSDavid du Colombieror
87dd7cddfSDavid du Colombier.br
97dd7cddfSDavid du ColombierGetting Dot-Dot Right
107dd7cddfSDavid du Colombier.AU
117dd7cddfSDavid du ColombierRob Pike
127dd7cddfSDavid du Colombier.CW rob@plan9.bell-labs.com
137dd7cddfSDavid du Colombier.AI
147dd7cddfSDavid du Colombier.MH
157dd7cddfSDavid du Colombier.AB
167dd7cddfSDavid du Colombier.LP
177dd7cddfSDavid du ColombierSymbolic links make the Unix file system non-hierarchical, resulting in
187dd7cddfSDavid du Colombiermultiple valid path names for a given file.
197dd7cddfSDavid du ColombierThis ambiguity is a source of confusion, especially since some shells
207dd7cddfSDavid du Colombierwork overtime to present a consistent view from programs such as
217dd7cddfSDavid du Colombier.CW pwd ,
227dd7cddfSDavid du Colombierwhile other programs and
237dd7cddfSDavid du Colombierthe kernel itself do nothing about the problem.
247dd7cddfSDavid du Colombier.LP
257dd7cddfSDavid du ColombierPlan 9 has no symbolic links but it does have other mechanisms that produce the same difficulty.
267dd7cddfSDavid du ColombierMoreover, Plan 9 is founded on the ability to control a program's environment
277dd7cddfSDavid du Colombierby manipulating its name space.
287dd7cddfSDavid du ColombierAmbiguous names muddle the result of operations such as copying a name space across
297dd7cddfSDavid du Colombierthe network.
307dd7cddfSDavid du Colombier.LP
317dd7cddfSDavid du ColombierTo address these problems,
327dd7cddfSDavid du Colombierthe Plan 9 kernel has been modified to maintain an accurate path name for every active
337dd7cddfSDavid du Colombierfile (open file, working directory, mount table entry) in the system.
347dd7cddfSDavid du ColombierThe definition of `accurate' is that the path name for a file is guaranteed to be the rooted,
357dd7cddfSDavid du Colombierabsolute name
367dd7cddfSDavid du Colombierthe program used to acquire it.
377dd7cddfSDavid du ColombierThese names are maintained by an efficient method that combines lexical processing\(emsuch as
387dd7cddfSDavid du Colombierevaluating
397dd7cddfSDavid du Colombier.CW ..
407dd7cddfSDavid du Colombierby just removing the last path name element of a directory\(emwith
417dd7cddfSDavid du Colombierlocal operations within the file system to maintain a consistently, easily understood view
427dd7cddfSDavid du Colombierof the name system.
437dd7cddfSDavid du ColombierAmbiguous situations are resolved by examining the lexically maintained names themselves.
447dd7cddfSDavid du Colombier.LP
457dd7cddfSDavid du ColombierA new kernel call,
467dd7cddfSDavid du Colombier.CW fd2path ,
477dd7cddfSDavid du Colombierreturns the file name associated with an open file,
487dd7cddfSDavid du Colombierpermitting the use of reliable names to improve system
497dd7cddfSDavid du Colombierservices ranging from
507dd7cddfSDavid du Colombier.CW pwd
517dd7cddfSDavid du Colombierto debugging.
527dd7cddfSDavid du ColombierAlthough this work was done in Plan 9,
537dd7cddfSDavid du ColombierUnix systems could also benefit from the addition of
547dd7cddfSDavid du Colombiera method to recover the accurate name of an
557dd7cddfSDavid du Colombieropen file or the current directory.
567dd7cddfSDavid du Colombier.AE
577dd7cddfSDavid du Colombier.SH
587dd7cddfSDavid du ColombierMotivation
597dd7cddfSDavid du Colombier.LP
607dd7cddfSDavid du ColombierConsider the following unedited transcript of a session running the Bourne shell on a modern
617dd7cddfSDavid du ColombierUnix system:
627dd7cddfSDavid du Colombier.P1
637dd7cddfSDavid du Colombier% echo $HOME
647dd7cddfSDavid du Colombier/home/rob
657dd7cddfSDavid du Colombier% cd $HOME
667dd7cddfSDavid du Colombier% pwd
677dd7cddfSDavid du Colombier/n/bopp/v7/rob
687dd7cddfSDavid du Colombier% cd /home/rob
697dd7cddfSDavid du Colombier% cd /home/ken
707dd7cddfSDavid du Colombier% cd ../rob
717dd7cddfSDavid du Colombier\&../rob: bad directory
727dd7cddfSDavid du Colombier%
737dd7cddfSDavid du Colombier.P2
747dd7cddfSDavid du Colombier(The same output results from running
757dd7cddfSDavid du Colombier.CW tcsh ;
767dd7cddfSDavid du Colombierwe'll discuss
777dd7cddfSDavid du Colombier.CW ksh
787dd7cddfSDavid du Colombierin a moment.)
797dd7cddfSDavid du ColombierTo a neophyte being schooled in the delights of a hierarchical file name space,
807dd7cddfSDavid du Colombierthis behavior must be baffling.
817dd7cddfSDavid du ColombierIt is, of course, the consequence of a series of symbolic links intended to give users
827dd7cddfSDavid du Colombierthe illusion they share a disk, when in fact their files are scattered over several devices:
837dd7cddfSDavid du Colombier.P1
847dd7cddfSDavid du Colombier.ps -1
857dd7cddfSDavid du Colombier% ls -ld /home/rob /home/ken
867dd7cddfSDavid du Colombierlrwxr-xr-x  1 root  sys   14 Dec 26  1998 /home/ken -> /n/bopp/v6/ken
877dd7cddfSDavid du Colombierlrwxr-xr-x  1 root  sys   14 Dec 23  1998 /home/rob -> /n/bopp/v7/rob
887dd7cddfSDavid du Colombier%
897dd7cddfSDavid du Colombier.ps
907dd7cddfSDavid du Colombier.P2
917dd7cddfSDavid du ColombierThe introduction of symbolic links has changed the Unix file system from a true
927dd7cddfSDavid du Colombierhierarchy into a directed graph, rendering
937dd7cddfSDavid du Colombier.CW ..
947dd7cddfSDavid du Colombierambiguous and sowing confusion.
957dd7cddfSDavid du Colombier.LP
967dd7cddfSDavid du ColombierUnix popularized hierarchical naming, but the introduction of symbolic links
977dd7cddfSDavid du Colombiermade its naming irregular.
987dd7cddfSDavid du ColombierWorse, the
997dd7cddfSDavid du Colombier.CW pwd
1007dd7cddfSDavid du Colombiercommand, through the underlying
1017dd7cddfSDavid du Colombier.CW getwd
1027dd7cddfSDavid du Colombierlibrary routine,
1037dd7cddfSDavid du Colombieruses a tricky, expensive algorithm that often delivers the wrong answer.
1047dd7cddfSDavid du ColombierStarting from the current directory,
1057dd7cddfSDavid du Colombier.CW getwd
1067dd7cddfSDavid du Colombieropens the parent,
1077dd7cddfSDavid du Colombier.CW .. ,
1087dd7cddfSDavid du Colombierand searches it for an entry whose i-number matches the current directory;
1097dd7cddfSDavid du Colombierthe matching entry is the final path element of the ultimate result.
1107dd7cddfSDavid du ColombierApplying this process iteratively,
1117dd7cddfSDavid du Colombier.CW getwd
1127dd7cddfSDavid du Colombierworks back towards the root.
1137dd7cddfSDavid du ColombierSince
1147dd7cddfSDavid du Colombier.CW getwd
1157dd7cddfSDavid du Colombierknows nothing about symbolic links, it will recover surprising names for
1167dd7cddfSDavid du Colombierdirectories reached by them,
1177dd7cddfSDavid du Colombieras illustrated by the example;
1187dd7cddfSDavid du Colombierthe backward paths
1197dd7cddfSDavid du Colombier.CW getwd
1207dd7cddfSDavid du Colombiertraverses will not backtrack across the links.
1217dd7cddfSDavid du Colombier.LP
1227dd7cddfSDavid du ColombierPartly for efficiency and partly to make
1237dd7cddfSDavid du Colombier.CW cd
1247dd7cddfSDavid du Colombierand
1257dd7cddfSDavid du Colombier.CW pwd
1267dd7cddfSDavid du Colombiermore predictable, the Korn shell
1277dd7cddfSDavid du Colombier.CW ksh
1287dd7cddfSDavid du Colombier[Korn94]
1297dd7cddfSDavid du Colombierimplements
1307dd7cddfSDavid du Colombier.CW pwd
1317dd7cddfSDavid du Colombieras a builtin.
1327dd7cddfSDavid du Colombier(The
1337dd7cddfSDavid du Colombier.CW cd
1347dd7cddfSDavid du Colombiercommand must be a builtin in any shell, since the current directory is unique to each process.)
1357dd7cddfSDavid du Colombier.CW Ksh
1367dd7cddfSDavid du Colombiermaintains its own private view of the file system to try to disguise symbolic links;
1377dd7cddfSDavid du Colombierin particular,
1387dd7cddfSDavid du Colombier.CW cd
1397dd7cddfSDavid du Colombierand
1407dd7cddfSDavid du Colombier.CW pwd
1417dd7cddfSDavid du Colombierinvolve some lexical processing (somewhat like the
1427dd7cddfSDavid du Colombier.CW cleanname
1437dd7cddfSDavid du Colombierfunction discussed later
1447dd7cddfSDavid du Colombierin this paper), augmented by heuristics such as examining the environment
1457dd7cddfSDavid du Colombierfor names like
1467dd7cddfSDavid du Colombier.CW $HOME
1477dd7cddfSDavid du Colombierand
1487dd7cddfSDavid du Colombier.CW $PWD
1497dd7cddfSDavid du Colombierto assist initialization of the state of the private view. [Korn00]
1507dd7cddfSDavid du Colombier.LP
1517dd7cddfSDavid du ColombierThis transcript begins with a Bourne shell running:
1527dd7cddfSDavid du Colombier.P1
1537dd7cddfSDavid du Colombier% cd /home/rob
1547dd7cddfSDavid du Colombier% pwd
1557dd7cddfSDavid du Colombier/n/bopp/v7/rob
1567dd7cddfSDavid du Colombier% ksh
1577dd7cddfSDavid du Colombier$ pwd
1587dd7cddfSDavid du Colombier/home/rob
1597dd7cddfSDavid du Colombier$
1607dd7cddfSDavid du Colombier.P2
1617dd7cddfSDavid du ColombierThis result is encouraging.  Another example, again starting from a Bourne shell:
1627dd7cddfSDavid du Colombier.P1
1637dd7cddfSDavid du Colombier% cd /home/rob
1647dd7cddfSDavid du Colombier% cd ../ken
1657dd7cddfSDavid du Colombier\&../ken: bad directory
1667dd7cddfSDavid du Colombier% ksh
1677dd7cddfSDavid du Colombier$ pwd
1687dd7cddfSDavid du Colombier/home/rob
1697dd7cddfSDavid du Colombier$ cd ../ken
1707dd7cddfSDavid du Colombier$ pwd
1717dd7cddfSDavid du Colombier/home/ken
1727dd7cddfSDavid du Colombier$
1737dd7cddfSDavid du Colombier.P2
1747dd7cddfSDavid du ColombierBy doing extra work,
1757dd7cddfSDavid du Colombierthe Korn shell is providing more sensible behavior,
1767dd7cddfSDavid du Colombierbut it is easy to defeat:
1777dd7cddfSDavid du Colombier.P1
1787dd7cddfSDavid du Colombier% cd /home/rob
1797dd7cddfSDavid du Colombier% pwd
1807dd7cddfSDavid du Colombier/n/bopp/v7/rob
1817dd7cddfSDavid du Colombier% cd bin
1827dd7cddfSDavid du Colombier% pwd
1837dd7cddfSDavid du Colombier/n/bopp/v7/rob/bin
1847dd7cddfSDavid du Colombier% ksh
1857dd7cddfSDavid du Colombier$ pwd
1867dd7cddfSDavid du Colombier/n/bopp/v7/rob/bin
1877dd7cddfSDavid du Colombier$ exit
1887dd7cddfSDavid du Colombier% cd /home/ken
1897dd7cddfSDavid du Colombier% pwd
1907dd7cddfSDavid du Colombier/n/bopp/v6/ken
1917dd7cddfSDavid du Colombier% ksh
1927dd7cddfSDavid du Colombier$ pwd
1937dd7cddfSDavid du Colombier/n/bopp/v6/ken
1947dd7cddfSDavid du Colombier$
1957dd7cddfSDavid du Colombier.P2
1967dd7cddfSDavid du ColombierIn these examples,
1977dd7cddfSDavid du Colombier.CW ksh 's
1987dd7cddfSDavid du Colombierbuilt-in
1997dd7cddfSDavid du Colombier.CW pwd
2007dd7cddfSDavid du Colombierfailed to produce the results
2017dd7cddfSDavid du Colombier.CW /home/rob/bin "" (
2027dd7cddfSDavid du Colombierand
2037dd7cddfSDavid du Colombier.CW /home/ken )
2047dd7cddfSDavid du Colombierthat the previous example might have led us to expect.
2057dd7cddfSDavid du ColombierThe Korn shell is hiding the problem, not solving it, and in fact is not even hiding it very well.
2067dd7cddfSDavid du Colombier.LP
2077dd7cddfSDavid du ColombierA deeper question is whether the shell should even be trying to make
2087dd7cddfSDavid du Colombier.CW pwd
2097dd7cddfSDavid du Colombierand
2107dd7cddfSDavid du Colombier.CW cd
2117dd7cddfSDavid du Colombierdo a better job.
2127dd7cddfSDavid du ColombierIf it does, then the
2137dd7cddfSDavid du Colombier.CW getwd
2147dd7cddfSDavid du Colombierlibrary call and every program that uses it will behave differently from the shell,
2157dd7cddfSDavid du Colombiera situation that is sure to confuse.
2167dd7cddfSDavid du ColombierMoreover, the ability to change directory to
2177dd7cddfSDavid du Colombier.CW ../ken
2187dd7cddfSDavid du Colombierwith the Korn shell's
2197dd7cddfSDavid du Colombier.CW cd
2207dd7cddfSDavid du Colombiercommand but not with the
2217dd7cddfSDavid du Colombier.CW chdir
2227dd7cddfSDavid du Colombiersystem call is a symptom of a diseased system, not a healthy shell.
2237dd7cddfSDavid du Colombier.LP
2247dd7cddfSDavid du ColombierThe operating system should provide names that work and make sense.
2257dd7cddfSDavid du ColombierSymbolic links, though, are here to stay, so we need a way to provide
2267dd7cddfSDavid du Colombiersensible, unambiguous names in the face of a non-hierarchical name space.
2277dd7cddfSDavid du ColombierThis paper shows how the challenge was met on Plan 9, an operating system
2287dd7cddfSDavid du Colombierwith Unix-like naming.
2297dd7cddfSDavid du Colombier.SH
2307dd7cddfSDavid du ColombierNames in Plan 9
2317dd7cddfSDavid du Colombier.LP
2327dd7cddfSDavid du ColombierExcept for some details involved with bootstrapping, file names in Plan 9 have the same syntax as in Unix.
2337dd7cddfSDavid du ColombierPlan 9 has no symbolic links, but its name space construction operators,
2347dd7cddfSDavid du Colombier.CW bind
2357dd7cddfSDavid du Colombierand
2367dd7cddfSDavid du Colombier.CW mount ,
2377dd7cddfSDavid du Colombiermake it possible to build the same sort of non-hierarchical structures created
2387dd7cddfSDavid du Colombierby symbolically linking directories on Unix.
2397dd7cddfSDavid du Colombier.LP
2407dd7cddfSDavid du ColombierPlan 9's
2417dd7cddfSDavid du Colombier.CW mount
2427dd7cddfSDavid du Colombiersystem call takes a file descriptor
2437dd7cddfSDavid du Colombierand attaches to the local name space the file system service it represents:
2447dd7cddfSDavid du Colombier.P1
2457dd7cddfSDavid du Colombiermount(fd, "/dir", flags)
2467dd7cddfSDavid du Colombier.P2
2477dd7cddfSDavid du ColombierHere
2487dd7cddfSDavid du Colombier.CW fd
2497dd7cddfSDavid du Colombieris a file descriptor to a communications port such as a pipe or network connection;
2507dd7cddfSDavid du Colombierat the other end of the port is a service, such as file server, that talks 9P, the Plan 9 file
2517dd7cddfSDavid du Colombiersystem protocol.
2527dd7cddfSDavid du ColombierAfter the call succeeds, the root directory of the service will be visible at the
2537dd7cddfSDavid du Colombier.I "mount point
2547dd7cddfSDavid du Colombier.CW /dir ,
2557dd7cddfSDavid du Colombiermuch as with the
2567dd7cddfSDavid du Colombier.CW mount
2577dd7cddfSDavid du Colombiercall of Unix.
2587dd7cddfSDavid du ColombierThe
2597dd7cddfSDavid du Colombier.CW flag
2607dd7cddfSDavid du Colombierargument specifies the nature of the attachment:
2617dd7cddfSDavid du Colombier.CW MREPL
2627dd7cddfSDavid du Colombiersays that the contents of the root directory (appear to) replace the current contents of
2637dd7cddfSDavid du Colombier.CW /dir ;
2647dd7cddfSDavid du Colombier.CW MAFTER
2657dd7cddfSDavid du Colombiersays that the current contents of
2667dd7cddfSDavid du Colombier.CW dir
2677dd7cddfSDavid du Colombierremain visible, with the mounted directory's contents appearing
2687dd7cddfSDavid du Colombier.I after
2697dd7cddfSDavid du Colombierany existing files;
2707dd7cddfSDavid du Colombierand
2717dd7cddfSDavid du Colombier.CW MBEFORE
2727dd7cddfSDavid du Colombiersays that the contents remain visible, with
2737dd7cddfSDavid du Colombierthe mounted directory's contents appearing
2747dd7cddfSDavid du Colombier.I before
2757dd7cddfSDavid du Colombierany existing files.
2767dd7cddfSDavid du ColombierThese multicomponent directories are called
2777dd7cddfSDavid du Colombier.I "union directories
2787dd7cddfSDavid du Colombierand are somewhat different from union directories in 4.4BSD-Lite [PeMc95], because
2797dd7cddfSDavid du Colombieronly the top-level directory itself is unioned, not its descendents, recursively.
2807dd7cddfSDavid du Colombier(Plan 9's union directories are used differently from 4.4BSD-Lite's, as will become apparent.)
2817dd7cddfSDavid du Colombier.LP
2827dd7cddfSDavid du ColombierFor example, to bootstrap a diskless computer the system builds a local name space containing
2837dd7cddfSDavid du Colombieronly the root directory,
2847dd7cddfSDavid du Colombier.CW / ,
2857dd7cddfSDavid du Colombierthen uses the network to open a connection
2867dd7cddfSDavid du Colombierto the main file server.
2877dd7cddfSDavid du ColombierIt then executes
2887dd7cddfSDavid du Colombier.P1
2897dd7cddfSDavid du Colombiermount(rootfd, "/", MREPL);
2907dd7cddfSDavid du Colombier.P2
2917dd7cddfSDavid du ColombierAfter this call, the entire file server's tree is visible, starting from the root of the local machine.
2927dd7cddfSDavid du Colombier.LP
2937dd7cddfSDavid du ColombierWhile
2947dd7cddfSDavid du Colombier.CW mount
2957dd7cddfSDavid du Colombierconnects a new service to the local name space,
2967dd7cddfSDavid du Colombier.CW bind
2977dd7cddfSDavid du Colombierrearranges the existing name space:
2987dd7cddfSDavid du Colombier.P1
2997dd7cddfSDavid du Colombierbind("tofile", "fromfile", flags)
3007dd7cddfSDavid du Colombier.P2
3017dd7cddfSDavid du Colombiercauses subsequent mention of the
3027dd7cddfSDavid du Colombier.CW fromfile
3037dd7cddfSDavid du Colombier(which may be a plain file or a directory)
3047dd7cddfSDavid du Colombierto behave as though
3057dd7cddfSDavid du Colombier.CW tofile
3067dd7cddfSDavid du Colombierhad been mentioned instead, somewhat like a symbolic link.
3077dd7cddfSDavid du Colombier(Note, however, that the arguments are in the opposite order
3087dd7cddfSDavid du Colombiercompared to
3097dd7cddfSDavid du Colombier.CW ln
3107dd7cddfSDavid du Colombier.CW -s ).
3117dd7cddfSDavid du ColombierThe
3127dd7cddfSDavid du Colombier.CW flags
3137dd7cddfSDavid du Colombierargument is the same as with
3147dd7cddfSDavid du Colombier.CW mount .
3157dd7cddfSDavid du Colombier.LP
3167dd7cddfSDavid du ColombierAs an example, a sequence something like the following is done at bootstrap time to
3177dd7cddfSDavid du Colombierassemble, under the single directory
3187dd7cddfSDavid du Colombier.CW /bin ,
3197dd7cddfSDavid du Colombierall of the binaries suitable for this architecture, represented by (say) the string
3207dd7cddfSDavid du Colombier.CW sparc :
3217dd7cddfSDavid du Colombier.P1
3227dd7cddfSDavid du Colombierbind("/sparc/bin", "/bin", MREPL);
3237dd7cddfSDavid du Colombierbind("/usr/rob/sparc/bin", "/bin", MAFTER);
3247dd7cddfSDavid du Colombier.P2
3257dd7cddfSDavid du ColombierThis sequence of
3267dd7cddfSDavid du Colombier.CW binds
3277dd7cddfSDavid du Colombiercauses
3287dd7cddfSDavid du Colombier.CW /bin
3297dd7cddfSDavid du Colombierto contain first the standard binaries, then the contents of
3307dd7cddfSDavid du Colombier.CW rob 's
3317dd7cddfSDavid du Colombierprivate SPARC binaries.
3327dd7cddfSDavid du ColombierThe ability to build such union directories
3337dd7cddfSDavid du Colombierobviates the need for a shell
3347dd7cddfSDavid du Colombier.CW $PATH
3357dd7cddfSDavid du Colombiervariable
3367dd7cddfSDavid du Colombierwhile providing opportunities for managing heterogeneity.
3377dd7cddfSDavid du ColombierIf the system were a Power PC, the same sequence would be run with
3387dd7cddfSDavid du Colombier.CW power
3397dd7cddfSDavid du Colombiertextually substituted for
3407dd7cddfSDavid du Colombier.CW sparc
3417dd7cddfSDavid du Colombierto place the Power PC binaries in
3427dd7cddfSDavid du Colombier.CW /bin
3437dd7cddfSDavid du Colombierrather than the SPARC binaries.
3447dd7cddfSDavid du Colombier.LP
3457dd7cddfSDavid du ColombierTrouble is already brewing.  After these bindings are set up,
3467dd7cddfSDavid du Colombierwhere does
3477dd7cddfSDavid du Colombier.P1
3487dd7cddfSDavid du Colombier% cd /bin
3497dd7cddfSDavid du Colombier% cd ..
3507dd7cddfSDavid du Colombier.P2
3517dd7cddfSDavid du Colombierset the current working directory, to
3527dd7cddfSDavid du Colombier.CW /
3537dd7cddfSDavid du Colombieror
3547dd7cddfSDavid du Colombier.CW /sparc
3557dd7cddfSDavid du Colombieror
3567dd7cddfSDavid du Colombier.CW /usr/rob/sparc ?
3577dd7cddfSDavid du ColombierWe will return to this issue.
3587dd7cddfSDavid du Colombier.LP
3597dd7cddfSDavid du ColombierThere are some important differences between
3607dd7cddfSDavid du Colombier.CW binds
3617dd7cddfSDavid du Colombierand symbolic links.
3627dd7cddfSDavid du ColombierFirst,
3637dd7cddfSDavid du Colombiersymbolic links are a static part of the file system, while
3647dd7cddfSDavid du ColombierPlan 9 bindings are created at run time, are stored in the kernel,
3657dd7cddfSDavid du Colombierand endure only as long as the system maintains them;
3667dd7cddfSDavid du Colombierthey are temporary.
3677dd7cddfSDavid du ColombierSince they are known to the kernel but not the file system, they must
3687dd7cddfSDavid du Colombierbe set up each time the kernel boots or a user logs in;
3697dd7cddfSDavid du Colombierpermanent bindings are created by editing system initialization scripts
3707dd7cddfSDavid du Colombierand user profiles rather than by building them in the file system itself.
3717dd7cddfSDavid du Colombier.LP
3727dd7cddfSDavid du ColombierThe Plan 9 kernel records what bindings are active for a process,
3737dd7cddfSDavid du Colombierwhereas symbolic links, being held on the Unix file server, may strike whenever the process evaluates
3747dd7cddfSDavid du Colombiera file name.
3757dd7cddfSDavid du ColombierAlso, symbolic links apply to all processes that evaluate the affected file, whereas
3767dd7cddfSDavid du Colombier.CW bind
3777dd7cddfSDavid du Colombierhas a local scope, applying only to the process that executes it and possibly some of its
3787dd7cddfSDavid du Colombierpeers, as discussed in the next section.
3797dd7cddfSDavid du ColombierSymbolic links cannot construct the sort of
3807dd7cddfSDavid du Colombier.CW /bin
3817dd7cddfSDavid du Colombierdirectory built here; it is possible to have multiple directories point to
3827dd7cddfSDavid du Colombier.CW /bin
3837dd7cddfSDavid du Colombierbut not the other way around.
3847dd7cddfSDavid du Colombier.LP
3857dd7cddfSDavid du ColombierFinally,
3867dd7cddfSDavid du Colombiersymbolic links are symbolic, like macros: they evaluate the associated names each time
3877dd7cddfSDavid du Colombierthey are accessed.
3887dd7cddfSDavid du ColombierBindings, on the other hand, are evaluated only once, when the bind is executed;
3897dd7cddfSDavid du Colombierafter the binding is set up, the kernel associates the underlying files, rather than their names.
3907dd7cddfSDavid du ColombierIn fact, the kernel's representation of a bind is identical to its representation of a mount;
3917dd7cddfSDavid du Colombierin effect, a bind is a mount of the
3927dd7cddfSDavid du Colombier.CW tofile
3937dd7cddfSDavid du Colombierupon the
3947dd7cddfSDavid du Colombier.CW fromfile .
3957dd7cddfSDavid du ColombierThe binds and mounts coexist in a single
3967dd7cddfSDavid du Colombier.I "mount table" ,
3977dd7cddfSDavid du Colombierthe subject of the next section.
3987dd7cddfSDavid du Colombier.SH
3997dd7cddfSDavid du ColombierThe Mount Table
4007dd7cddfSDavid du Colombier.LP
4017dd7cddfSDavid du ColombierUnix has a single global mount table
4027dd7cddfSDavid du Colombierfor all processes in the system, but Plan 9's mount tables are local to each process.
4037dd7cddfSDavid du ColombierBy default it is inherited when a process forks, so mounts and binds made by one
4047dd7cddfSDavid du Colombierprocess affect the other, but a process may instead inherit a copy,
4057dd7cddfSDavid du Colombierso modifications it makes will be invisible to other processes.
4067dd7cddfSDavid du ColombierThe convention is that related processes, such
4077dd7cddfSDavid du Colombieras processes running in a single window, share a mount table, while sets of processes
4087dd7cddfSDavid du Colombierin different windows have distinct mount tables.
4097dd7cddfSDavid du ColombierIn practice, the name spaces of the two windows will appear largely the same,
4107dd7cddfSDavid du Colombierbut the possibility for different processes to see different files (hence services) under
4117dd7cddfSDavid du Colombierthe same name is fundamental to the system,
4127dd7cddfSDavid du Colombieraffecting the design of key programs such as the
4137dd7cddfSDavid du Colombierwindow system [Pike91].
4147dd7cddfSDavid du Colombier.LP
4157dd7cddfSDavid du ColombierThe Plan 9 mount table is little more than an ordered list of pairs, mapping the
4167dd7cddfSDavid du Colombier.CW fromfiles
4177dd7cddfSDavid du Colombierto the
4187dd7cddfSDavid du Colombier.CW tofiles .
4197dd7cddfSDavid du ColombierFor mounts, the
4207dd7cddfSDavid du Colombier.CW tofile
4217dd7cddfSDavid du Colombierwill be an item called a
4227dd7cddfSDavid du Colombier.CW Channel ,
4237dd7cddfSDavid du Colombiersimilar to a Unix
4247dd7cddfSDavid du Colombier.CW vnode ,
4257dd7cddfSDavid du Colombierpointing to the root of the file service,
4267dd7cddfSDavid du Colombierwhile for a bind it will be the
4277dd7cddfSDavid du Colombier.CW Channel
4287dd7cddfSDavid du Colombierpointing to the
4297dd7cddfSDavid du Colombier.CW tofile
4307dd7cddfSDavid du Colombiermentioned in the
4317dd7cddfSDavid du Colombier.CW bind
4327dd7cddfSDavid du Colombiercall.
4337dd7cddfSDavid du ColombierIn both cases, the
4347dd7cddfSDavid du Colombier.CW fromfile
4357dd7cddfSDavid du Colombierentry in the table
4367dd7cddfSDavid du Colombierwill be a
4377dd7cddfSDavid du Colombier.CW Channel
4387dd7cddfSDavid du Colombierpointing to the
4397dd7cddfSDavid du Colombier.CW fromfile
4407dd7cddfSDavid du Colombieritself.
4417dd7cddfSDavid du Colombier.LP
4427dd7cddfSDavid du ColombierThe evaluation of a file name proceeds as follows.
4437dd7cddfSDavid du ColombierIf the name begins with a slash, start with the
4447dd7cddfSDavid du Colombier.CW Channel
4457dd7cddfSDavid du Colombierfor the root; otherwise start with the
4467dd7cddfSDavid du Colombier.CW Channel
4477dd7cddfSDavid du Colombierfor the current directory of the process.
4487dd7cddfSDavid du ColombierFor each path element in the name,
4497dd7cddfSDavid du Colombiersuch as
4507dd7cddfSDavid du Colombier.CW usr
4517dd7cddfSDavid du Colombierin
4527dd7cddfSDavid du Colombier.CW /usr/rob ,
4537dd7cddfSDavid du Colombiertry to `walk' the
4547dd7cddfSDavid du Colombier.CW Channel
4557dd7cddfSDavid du Colombierto that element [Pike93].
4567dd7cddfSDavid du ColombierIf the walk succeeds, look to see if the resulting
4577dd7cddfSDavid du Colombier.CW Channel
4587dd7cddfSDavid du Colombieris the same as any
4597dd7cddfSDavid du Colombier.CW fromfile
4607dd7cddfSDavid du Colombierin the mount table, and if so, replace it by the corresponding
4617dd7cddfSDavid du Colombier.CW tofile .
4627dd7cddfSDavid du ColombierAdvance to the next element and continue.
4637dd7cddfSDavid du Colombier.LP
4647dd7cddfSDavid du ColombierThere are a couple of nuances.  If the directory being walked is a union directory,
4657dd7cddfSDavid du Colombierthe walk is attempted in the elements of the union, in order, until a walk succeeds.
4667dd7cddfSDavid du ColombierIf none succeed, the operation fails.
4677dd7cddfSDavid du ColombierAlso, when the destination of a walk is a directory for a purpose such as the
4687dd7cddfSDavid du Colombier.CW chdir
4697dd7cddfSDavid du Colombiersystem call or the
4707dd7cddfSDavid du Colombier.CW fromfile
4717dd7cddfSDavid du Colombierin a
4727dd7cddfSDavid du Colombier.CW bind ,
4737dd7cddfSDavid du Colombieronce the final walk of the sequence has completed the operation stops;
4747dd7cddfSDavid du Colombierthe final check through the mount table is not done.
4757dd7cddfSDavid du ColombierAmong other things, this simplifies the management of union directories;
4767dd7cddfSDavid du Colombierfor example, subsequent
4777dd7cddfSDavid du Colombier.CW bind
4787dd7cddfSDavid du Colombiercalls will append to the union associated with the underlying
4797dd7cddfSDavid du Colombier.CW fromfile
4807dd7cddfSDavid du Colombierinstead of what is bound upon it.
4817dd7cddfSDavid du Colombier.SH
4827dd7cddfSDavid du ColombierA Definition of Dot-Dot
4837dd7cddfSDavid du Colombier.LP
4847dd7cddfSDavid du ColombierThe ability to construct union directories and other intricate naming structures
4857dd7cddfSDavid du Colombierintroduces some thorny problems: as with symbolic links,
4867dd7cddfSDavid du Colombierthe name space is no longer hierarchical, files and directories can have multiple
4877dd7cddfSDavid du Colombiernames, and the meaning of
4887dd7cddfSDavid du Colombier.CW .. ,
4897dd7cddfSDavid du Colombierthe parent directory, can be ambiguous.
4907dd7cddfSDavid du Colombier.LP
4917dd7cddfSDavid du ColombierThe meaning of
4927dd7cddfSDavid du Colombier.CW ..
4937dd7cddfSDavid du Colombieris straightforward if the directory is in a locally hierarchical part of the name space,
4947dd7cddfSDavid du Colombierbut if we ask what
4957dd7cddfSDavid du Colombier.CW ..
4967dd7cddfSDavid du Colombiershould identify when the current directory is a mount point or union directory or
4977dd7cddfSDavid du Colombiermultiply symlinked spot (which we will henceforth call just a mount point, for brevity),
4987dd7cddfSDavid du Colombierthere is no obvious answer.
4997dd7cddfSDavid du ColombierName spaces have been part of Plan 9 from the beginning, but the definition of
5007dd7cddfSDavid du Colombier.CW ..
5017dd7cddfSDavid du Colombierhas changed several times as we grappled with this issue.
5027dd7cddfSDavid du ColombierIn fact, several attempts to clarify the meaning of
5037dd7cddfSDavid du Colombier.CW ..
5047dd7cddfSDavid du Colombierby clever coding
5057dd7cddfSDavid du Colombierresulted in definitions that could charitably be summarized as `what the implementation gives.'
5067dd7cddfSDavid du Colombier.LP
5077dd7cddfSDavid du ColombierFrustrated by this situation, and eager to have better-defined names for some of the
5087dd7cddfSDavid du Colombierapplications described later in this paper, we recently proposed the following definition
5097dd7cddfSDavid du Colombierfor
5107dd7cddfSDavid du Colombier.CW .. :
5117dd7cddfSDavid du Colombier.IP
5127dd7cddfSDavid du ColombierThe parent of a directory
5137dd7cddfSDavid du Colombier.I X ,
5147dd7cddfSDavid du Colombier.I X\f(CW/..\f1,
5157dd7cddfSDavid du Colombieris the same directory that would obtain if
5167dd7cddfSDavid du Colombierwe instead accessed the directory named by stripping away the last
5177dd7cddfSDavid du Colombierpath name element of
5187dd7cddfSDavid du Colombier.I X .
5197dd7cddfSDavid du Colombier.LP
5207dd7cddfSDavid du ColombierFor example, if we are in the directory
5217dd7cddfSDavid du Colombier.CW /a/b/c
5227dd7cddfSDavid du Colombierand
5237dd7cddfSDavid du Colombier.CW chdir
5247dd7cddfSDavid du Colombierto
5257dd7cddfSDavid du Colombier.CW .. ,
5267dd7cddfSDavid du Colombierthe result is
5277dd7cddfSDavid du Colombier.I exactly
5287dd7cddfSDavid du Colombieras if we had executed a
5297dd7cddfSDavid du Colombier.CW chdir
5307dd7cddfSDavid du Colombierto
5317dd7cddfSDavid du Colombier.CW /a/b .
5327dd7cddfSDavid du Colombier.LP
5337dd7cddfSDavid du ColombierThis definition is easy to understand and seems natural.
5347dd7cddfSDavid du ColombierIt is, however, a purely
5357dd7cddfSDavid du Colombier.I lexical
5367dd7cddfSDavid du Colombierdefinition that flatly ignores evaluated file names, mount tables, and
5377dd7cddfSDavid du Colombierother kernel-resident data structures.
5387dd7cddfSDavid du ColombierOur challenge is to implement it efficiently.
5397dd7cddfSDavid du ColombierOne obvious (and correct)
5407dd7cddfSDavid du Colombierimplementation is to rewrite path names lexically to fold out
5417dd7cddfSDavid du Colombier.CW .. ,
5427dd7cddfSDavid du Colombierand then evaluate the file name forward from the root,
5437dd7cddfSDavid du Colombierbut this is expensive and unappealing.
5447dd7cddfSDavid du ColombierWe want to be able to use local operations to evaluate file names,
5457dd7cddfSDavid du Colombierbut maintain the global, lexical definition of dot-dot.
5467dd7cddfSDavid du ColombierIt isn't too hard.
5477dd7cddfSDavid du Colombier.SH
5487dd7cddfSDavid du ColombierThe Implementation
5497dd7cddfSDavid du Colombier.LP
5507dd7cddfSDavid du ColombierTo operate lexically on file names, we associate a name with each open file in the kernel, that
5517dd7cddfSDavid du Colombieris, with each
5527dd7cddfSDavid du Colombier.CW Channel
5537dd7cddfSDavid du Colombierdata structure.
5547dd7cddfSDavid du ColombierThe first step is therefore to store a
5557dd7cddfSDavid du Colombier.CW char*
5567dd7cddfSDavid du Colombierwith each
5577dd7cddfSDavid du Colombier.CW Channel
5587dd7cddfSDavid du Colombierin the system, called its
5597dd7cddfSDavid du Colombier.CW Cname ,
5607dd7cddfSDavid du Colombierthat records the
5617dd7cddfSDavid du Colombier.I absolute
5627dd7cddfSDavid du Colombierrooted
5637dd7cddfSDavid du Colombierfile name for the
5647dd7cddfSDavid du Colombier.CW Channel .
5657dd7cddfSDavid du Colombier.CW Cnames
5667dd7cddfSDavid du Colombierare stored as full text strings, shared copy-on-write for efficiency.
5677dd7cddfSDavid du ColombierThe task is to maintain each
5687dd7cddfSDavid du Colombier.CW Cname
5697dd7cddfSDavid du Colombieras an accurate absolute name using only local operations.
5707dd7cddfSDavid du Colombier.LP
5717dd7cddfSDavid du ColombierWhen a file is opened, the file name argument in the
5727dd7cddfSDavid du Colombier.CW open
5737dd7cddfSDavid du Colombier(or
5747dd7cddfSDavid du Colombier.CW chdir
5757dd7cddfSDavid du Colombieror
5767dd7cddfSDavid du Colombier.CW bind
5777dd7cddfSDavid du Colombieror ...) call is recorded in the
5787dd7cddfSDavid du Colombier.CW Cname
5797dd7cddfSDavid du Colombierof the resulting
5807dd7cddfSDavid du Colombier.CW Channel .
5817dd7cddfSDavid du ColombierWhen the file name begins with a slash, the name is stored as is,
5827dd7cddfSDavid du Colombiersubject to a cleanup pass described in the next section.
5837dd7cddfSDavid du ColombierOtherwise, it is a local name, and the file name must be made
5847dd7cddfSDavid du Colombierabsolute by prefixing it with the
5857dd7cddfSDavid du Colombier.CW Cname
5867dd7cddfSDavid du Colombierof the current directory, followed by a slash.
5877dd7cddfSDavid du ColombierFor example, if we are in
5887dd7cddfSDavid du Colombier.CW /home/rob
5897dd7cddfSDavid du Colombierand
5907dd7cddfSDavid du Colombier.CW chdir
5917dd7cddfSDavid du Colombierto
5927dd7cddfSDavid du Colombier.CW bin ,
5937dd7cddfSDavid du Colombierthe
5947dd7cddfSDavid du Colombier.CW Cname
5957dd7cddfSDavid du Colombierof the resulting
5967dd7cddfSDavid du Colombier.CW Channel
5977dd7cddfSDavid du Colombierwill be the string
5987dd7cddfSDavid du Colombier.CW /home/rob/bin .
5997dd7cddfSDavid du Colombier.LP
6007dd7cddfSDavid du ColombierThis assumes, of course, that the local file name contains no
6017dd7cddfSDavid du Colombier.CW ..
6027dd7cddfSDavid du Colombierelements.
6037dd7cddfSDavid du ColombierIf it does, instead of storing for example
6047dd7cddfSDavid du Colombier.CW /home/rob/..
6057dd7cddfSDavid du Colombierwe delete the last element of the existing name and set the
6067dd7cddfSDavid du Colombier.CW Cname
6077dd7cddfSDavid du Colombierto
6087dd7cddfSDavid du Colombier.CW /home .
6097dd7cddfSDavid du ColombierTo maintain the lexical naming property we must guarantee that the resulting
6107dd7cddfSDavid du Colombier.CW Cname ,
6117dd7cddfSDavid du Colombierif it were to be evaluated, would yield the identical directory to the one
6127dd7cddfSDavid du Colombierwe actually do get by the local
6137dd7cddfSDavid du Colombier.CW ..
6147dd7cddfSDavid du Colombieroperation.
6157dd7cddfSDavid du Colombier.LP
6167dd7cddfSDavid du ColombierIf the current directory is not a mount point, it is easy to maintain the lexical property.
6177dd7cddfSDavid du ColombierIf it is a mount point, though, it is still possible to maintain it on Plan 9
6187dd7cddfSDavid du Colombierbecause the mount table, a kernel-resident data structure, contains all the
6197dd7cddfSDavid du Colombierinformation about the non-hierarchical connectivity of the name space.
6207dd7cddfSDavid du Colombier(On Unix, by contrast, symbolic links are stored on the file server rather than in the kernel.)
6217dd7cddfSDavid du ColombierMoreover, the presence of a full file name for each
6227dd7cddfSDavid du Colombier.CW Channel
6237dd7cddfSDavid du Colombierin the mount table provides the information necessary to resolve ambiguities.
6247dd7cddfSDavid du Colombier.LP
6257dd7cddfSDavid du ColombierThe mount table is examined in the
6267dd7cddfSDavid du Colombier.CW from\f1\(->\fPto
6277dd7cddfSDavid du Colombierdirection when evaluating a name, but
6287dd7cddfSDavid du Colombier.CW ..
6297dd7cddfSDavid du Colombierpoints backwards in the hierarchy, so to evaluate
6307dd7cddfSDavid du Colombier.CW ..
6317dd7cddfSDavid du Colombierthe table must be examined in the
6327dd7cddfSDavid du Colombier.CW to\f1\(->\fPfrom
6337dd7cddfSDavid du Colombierdirection.
6347dd7cddfSDavid du Colombier(``How did we get here?'')
6357dd7cddfSDavid du Colombier.LP
6367dd7cddfSDavid du ColombierThe value of
6377dd7cddfSDavid du Colombier.CW ..
6387dd7cddfSDavid du Colombieris ambiguous when there are multiple bindings (mount points) that point to
6397dd7cddfSDavid du Colombierthe directories involved in the evaluation of
6407dd7cddfSDavid du Colombier.CW .. .
6417dd7cddfSDavid du ColombierFor example, return to our original script with
6427dd7cddfSDavid du Colombier.CW /n/bopp/v6
6437dd7cddfSDavid du Colombier(containing a home directory for
6447dd7cddfSDavid du Colombier.CW ken )
6457dd7cddfSDavid du Colombierand
6467dd7cddfSDavid du Colombier.CW /n/bopp/v7
6477dd7cddfSDavid du Colombier(containing a home directory for
6487dd7cddfSDavid du Colombier.CW rob )
6497dd7cddfSDavid du Colombierunioned into
6507dd7cddfSDavid du Colombier.CW /home .
6517dd7cddfSDavid du ColombierThis is represented by two entries in the mount table,
6527dd7cddfSDavid du Colombier.CW from=/home ,
6537dd7cddfSDavid du Colombier.CW to=/n/bopp/v6
6547dd7cddfSDavid du Colombierand
6557dd7cddfSDavid du Colombier.CW from=/home ,
6567dd7cddfSDavid du Colombier.CW to=/n/bopp/v7 .
6577dd7cddfSDavid du ColombierIf we have set our current directory to
6587dd7cddfSDavid du Colombier.CW /home/rob
6597dd7cddfSDavid du Colombier(which has landed us in the physical location
6607dd7cddfSDavid du Colombier.CW /n/bopp/v7/rob )
6617dd7cddfSDavid du Colombierour current directory is not a mount point but its parent is.
6627dd7cddfSDavid du ColombierThe value of
6637dd7cddfSDavid du Colombier.CW ..
6647dd7cddfSDavid du Colombieris ambiguous: it could be
6657dd7cddfSDavid du Colombier.CW /home ,
6667dd7cddfSDavid du Colombier.CW /n/bopp/v7 ,
6677dd7cddfSDavid du Colombieror maybe even
6687dd7cddfSDavid du Colombier.CW /n/bopp/v6 ,
6697dd7cddfSDavid du Colombierand the ambiguity is caused by two
6707dd7cddfSDavid du Colombier.CW tofiles
6717dd7cddfSDavid du Colombierbound to the same
6727dd7cddfSDavid du Colombier.CW fromfile .
6737dd7cddfSDavid du ColombierBy our definition, if we now evaluate
6747dd7cddfSDavid du Colombier.CW .. ,
6757dd7cddfSDavid du Colombierwe should acquire the directory
6767dd7cddfSDavid du Colombier.CW /home ;
6777dd7cddfSDavid du Colombierotherwise
6787dd7cddfSDavid du Colombier.CW ../ken
6797dd7cddfSDavid du Colombiercould not possibly result in
6807dd7cddfSDavid du Colombier.CW ken 's
6817dd7cddfSDavid du Colombierhome directory, which it should.
6827dd7cddfSDavid du ColombierOn the other hand, if we had originally gone to
6837dd7cddfSDavid du Colombier.CW /n/bopp/v7/rob ,
6847dd7cddfSDavid du Colombierthe name
6857dd7cddfSDavid du Colombier.CW ../ken
6867dd7cddfSDavid du Colombiershould
6877dd7cddfSDavid du Colombier.I not
6887dd7cddfSDavid du Colombierevaluate to
6897dd7cddfSDavid du Colombier.CW ken 's
6907dd7cddfSDavid du Colombierhome directory because there is no directory
6917dd7cddfSDavid du Colombier.CW /n/bopp/v7/ken
6927dd7cddfSDavid du Colombier.CW ken 's (
6937dd7cddfSDavid du Colombierhome directory is on
6947dd7cddfSDavid du Colombier.CW v6 ).
6957dd7cddfSDavid du ColombierThe problem is that by using local file operations, it is impossible
6967dd7cddfSDavid du Colombierto distinguish these cases: regardless of whether we got here using the name
6977dd7cddfSDavid du Colombier.CW /home/rob
6987dd7cddfSDavid du Colombieror
6997dd7cddfSDavid du Colombier.CW /n/bopp/v7/rob ,
7007dd7cddfSDavid du Colombierthe resulting directory is the same.
7017dd7cddfSDavid du ColombierMoreover, the mount table does not itself have enough information
7027dd7cddfSDavid du Colombierto disambiguate: when we do a local operation to evaluate
7037dd7cddfSDavid du Colombier.CW ..
7047dd7cddfSDavid du Colombierand land in
7057dd7cddfSDavid du Colombier.CW /n/bopp/v7 ,
7067dd7cddfSDavid du Colombierwe discover that the directory is a
7077dd7cddfSDavid du Colombier.CW tofile
7087dd7cddfSDavid du Colombierin the mount table; should we step back through the table to
7097dd7cddfSDavid du Colombier.CW /home
7107dd7cddfSDavid du Colombieror not?
7117dd7cddfSDavid du Colombier.LP
7127dd7cddfSDavid du ColombierThe solution comes from the
7137dd7cddfSDavid du Colombier.CW Cnames
7147dd7cddfSDavid du Colombierthemselves.
7157dd7cddfSDavid du ColombierWhether to step back through the mount point
7167dd7cddfSDavid du Colombier.CW from=/home ,
7177dd7cddfSDavid du Colombier.CW to=/n/bopp/v7
7187dd7cddfSDavid du Colombierwhen evaluating
7197dd7cddfSDavid du Colombier.CW ..
7207dd7cddfSDavid du Colombierin
7217dd7cddfSDavid du Colombier.CW rob 's
7227dd7cddfSDavid du Colombierdirectory is trivially resolved by asking the question,
7237dd7cddfSDavid du ColombierDoes the
7247dd7cddfSDavid du Colombier.CW Cname
7257dd7cddfSDavid du Colombierfor the directory begin
7267dd7cddfSDavid du Colombier.CW /home ?
7277dd7cddfSDavid du ColombierIf it does, then the path that was evaluated to get us to the current
7287dd7cddfSDavid du Colombierdirectory must have gone through this mount point, and we should
7297dd7cddfSDavid du Colombierback up through it to evaluate
7307dd7cddfSDavid du Colombier.CW .. ;
7317dd7cddfSDavid du Colombierif not, then this mount table entry is irrelevant.
7327dd7cddfSDavid du Colombier.LP
7337dd7cddfSDavid du ColombierMore precisely,
7347dd7cddfSDavid du Colombierboth
7357dd7cddfSDavid du Colombier.I before
7367dd7cddfSDavid du Colombierand
7377dd7cddfSDavid du Colombier.I after
7387dd7cddfSDavid du Colombiereach
7397dd7cddfSDavid du Colombier.CW ..
7407dd7cddfSDavid du Colombierelement in the path name is evaluated,
7417dd7cddfSDavid du Colombierif the directory is a
7427dd7cddfSDavid du Colombier.CW tofile
7437dd7cddfSDavid du Colombierin the mount table, the corresponding
7447dd7cddfSDavid du Colombier.CW fromfile
7457dd7cddfSDavid du Colombieris taken instead, provided the
7467dd7cddfSDavid du Colombier.CW Cname
7477dd7cddfSDavid du Colombierof the corresponding
7487dd7cddfSDavid du Colombier.CW fromfile
7497dd7cddfSDavid du Colombieris the prefix of the
7507dd7cddfSDavid du Colombier.CW Cname
7517dd7cddfSDavid du Colombierof the original directory.
7527dd7cddfSDavid du ColombierSince we always know the full name of the directory
7537dd7cddfSDavid du Colombierwe are evaluating, we can always compare it against all the entries in the mount table that point
7547dd7cddfSDavid du Colombierto it, thereby resolving ambiguous situations
7557dd7cddfSDavid du Colombierand maintaining the
7567dd7cddfSDavid du Colombierlexical property of
7577dd7cddfSDavid du Colombier.CW .. .
7587dd7cddfSDavid du ColombierThis check also guarantees we don't follow a misleading mount point, such as the entry pointing to
7597dd7cddfSDavid du Colombier.CW /home
7607dd7cddfSDavid du Colombierwhen we are really in
7617dd7cddfSDavid du Colombier.CW /n/bopp/v7/rob .
7627dd7cddfSDavid du ColombierKeeping the full names with the
7637dd7cddfSDavid du Colombier.CW Channels
7647dd7cddfSDavid du Colombiermakes it easy to use the mount table to decide how we got here and, therefore,
7657dd7cddfSDavid du Colombierhow to get back.
7667dd7cddfSDavid du Colombier.LP
7677dd7cddfSDavid du ColombierIn summary, the algorithm is as follows.
7687dd7cddfSDavid du ColombierUse the usual file system operations to walk to
7697dd7cddfSDavid du Colombier.CW .. ;
7707dd7cddfSDavid du Colombiercall the resulting directory
7717dd7cddfSDavid du Colombier.I d .
7727dd7cddfSDavid du ColombierLexically remove
7737dd7cddfSDavid du Colombierthe last element of the initial file name.
7747dd7cddfSDavid du ColombierExamine all entries in the mount table whose
7757dd7cddfSDavid du Colombier.CW tofile
7767dd7cddfSDavid du Colombieris
7777dd7cddfSDavid du Colombier.I d
7787dd7cddfSDavid du Colombierand whose
7797dd7cddfSDavid du Colombier.CW fromfile
7807dd7cddfSDavid du Colombierhas a
7817dd7cddfSDavid du Colombier.CW Cname
7827dd7cddfSDavid du Colombieridentical to the truncated name.
7837dd7cddfSDavid du ColombierIf one exists, that
7847dd7cddfSDavid du Colombier.CW fromfile
7857dd7cddfSDavid du Colombieris the correct result; by construction, it also has the right
7867dd7cddfSDavid du Colombier.CW Cname .
7877dd7cddfSDavid du ColombierIn our example, evaluating
7887dd7cddfSDavid du Colombier.CW ..
7897dd7cddfSDavid du Colombierin
7907dd7cddfSDavid du Colombier.CW /home/rob
7917dd7cddfSDavid du Colombier(really
7927dd7cddfSDavid du Colombier.CW /n/bopp/v7/rob )
7937dd7cddfSDavid du Colombierwill set
7947dd7cddfSDavid du Colombier.I d
7957dd7cddfSDavid du Colombierto
7967dd7cddfSDavid du Colombier.CW /n/bopp/v7 ;
7977dd7cddfSDavid du Colombierthat is a
7987dd7cddfSDavid du Colombier.CW tofile
7997dd7cddfSDavid du Colombierwhose
8007dd7cddfSDavid du Colombier.CW fromfile
8017dd7cddfSDavid du Colombieris
8027dd7cddfSDavid du Colombier.CW /home .
8037dd7cddfSDavid du ColombierRemoving the
8047dd7cddfSDavid du Colombier.CW /rob
8057dd7cddfSDavid du Colombierfrom the original
8067dd7cddfSDavid du Colombier.CW Cname ,
8077dd7cddfSDavid du Colombierwe find the name
8087dd7cddfSDavid du Colombier.CW /home ,
8097dd7cddfSDavid du Colombierwhich matches that of the
8107dd7cddfSDavid du Colombier.CW fromfile ,
8117dd7cddfSDavid du Colombierso the result is the
8127dd7cddfSDavid du Colombier.CW fromfile ,
8137dd7cddfSDavid du Colombier.CW /home .
8147dd7cddfSDavid du Colombier.LP
8157dd7cddfSDavid du ColombierSince this implementation uses only local operations to maintain its names,
8167dd7cddfSDavid du Colombierit is possible to confuse it by external changes to the file system.
8177dd7cddfSDavid du ColombierDeleting or renaming directories and files that are part of a
8187dd7cddfSDavid du Colombier.CW Cname ,
8197dd7cddfSDavid du Colombieror modifying the mount table, can introduce errors.
8207dd7cddfSDavid du ColombierWith more implementation work, such mistakes could probably be caught,
8217dd7cddfSDavid du Colombierbut in a networked environment, with machines sharing a remote file server, renamings
8227dd7cddfSDavid du Colombierand deletions made by one machine may go unnoticed by others.
8237dd7cddfSDavid du ColombierThese problems, however, are minor, uncommon and, most important, easy to understand.
8247dd7cddfSDavid du ColombierThe method maintains the lexical property of file names unless an external
8257dd7cddfSDavid du Colombieragent changes the name surreptitiously;
8267dd7cddfSDavid du Colombierwithin a stable file system, it is always maintained and
8277dd7cddfSDavid du Colombier.CW pwd
8287dd7cddfSDavid du Colombieris always right.
8297dd7cddfSDavid du Colombier.LP
8307dd7cddfSDavid du ColombierTo recapitulate, maintaining the
8317dd7cddfSDavid du Colombier.CW Channel 's
8327dd7cddfSDavid du Colombierabsolute file names lexically and using the names to disambiguate the
8337dd7cddfSDavid du Colombiermount table entries when evaluating
8347dd7cddfSDavid du Colombier.CW ..
8357dd7cddfSDavid du Colombierat a mount point
8367dd7cddfSDavid du Colombiercombine to maintain the lexical definition of
8377dd7cddfSDavid du Colombier.CW ..
8387dd7cddfSDavid du Colombierefficiently.
8397dd7cddfSDavid du Colombier.SH
8407dd7cddfSDavid du ColombierCleaning names
8417dd7cddfSDavid du Colombier.LP
8427dd7cddfSDavid du ColombierThe lexical processing can generate names that are messy or redundant,
8437dd7cddfSDavid du Colombierones with extra slashes or embedded
8447dd7cddfSDavid du Colombier.CW ../
8457dd7cddfSDavid du Colombieror
8467dd7cddfSDavid du Colombier.CW ./
8477dd7cddfSDavid du Colombierelements and other extraneous artifacts.
8487dd7cddfSDavid du ColombierAs part of the kernel's implementation, we wrote a procedure,
8497dd7cddfSDavid du Colombier.CW cleanname ,
8507dd7cddfSDavid du Colombierthat rewrites a name in place to canonicalize its appearance.
8517dd7cddfSDavid du ColombierThe procedure is useful enough that it is now part of the Plan 9 C
8527dd7cddfSDavid du Colombierlibrary and is employed by many programs to make sure they always
8537dd7cddfSDavid du Colombierpresent clean file names.
8547dd7cddfSDavid du Colombier.LP
8557dd7cddfSDavid du Colombier.CW Cleanname
8567dd7cddfSDavid du Colombieris analogous to the URL-cleaning rules defined in RFC 1808 [Field95], although
8577dd7cddfSDavid du Colombierthe rules are slightly different.
8587dd7cddfSDavid du Colombier.CW Cleanname
8597dd7cddfSDavid du Colombieriteratively does the following until no further processing can be done:
8607dd7cddfSDavid du Colombier.IP
8617dd7cddfSDavid du Colombier1. Reduce multiple slashes to a single slash.
8627dd7cddfSDavid du Colombier.IP
8637dd7cddfSDavid du Colombier2. Eliminate
8647dd7cddfSDavid du Colombier.CW .
8657dd7cddfSDavid du Colombierpath name elements
8667dd7cddfSDavid du Colombier(the current directory).
8677dd7cddfSDavid du Colombier.IP
8687dd7cddfSDavid du Colombier3. Eliminate
8697dd7cddfSDavid du Colombier.CW ..
8707dd7cddfSDavid du Colombierpath name elements (the parent directory) and the
8717dd7cddfSDavid du Colombier.CW . "" non-
8727dd7cddfSDavid du Colombier.CW .., "" non-
8737dd7cddfSDavid du Colombierelement that precedes them.
8747dd7cddfSDavid du Colombier.IP
8757dd7cddfSDavid du Colombier4. Eliminate
8767dd7cddfSDavid du Colombier.CW ..
8777dd7cddfSDavid du Colombierelements that begin a rooted path, that is, replace
8787dd7cddfSDavid du Colombier.CW /..
8797dd7cddfSDavid du Colombierby
8807dd7cddfSDavid du Colombier.CW /
8817dd7cddfSDavid du Colombierat the beginning of a path.
8827dd7cddfSDavid du Colombier.IP
8837dd7cddfSDavid du Colombier5. Leave intact
8847dd7cddfSDavid du Colombier.CW ..
8857dd7cddfSDavid du Colombierelements that begin a non-rooted path.
8867dd7cddfSDavid du Colombier.LP
8877dd7cddfSDavid du ColombierIf the result of this process is a null string,
8887dd7cddfSDavid du Colombier.CW cleanname
8897dd7cddfSDavid du Colombierreturns the string
8907dd7cddfSDavid du Colombier.CW \&"." ,
8917dd7cddfSDavid du Colombierrepresenting the current directory.
8927dd7cddfSDavid du Colombier.SH
8937dd7cddfSDavid du ColombierThe fd2path system call
8947dd7cddfSDavid du Colombier.LP
8957dd7cddfSDavid du ColombierPlan 9 has a new system call,
8967dd7cddfSDavid du Colombier.CW fd2path ,
8977dd7cddfSDavid du Colombierto enable programs to extract the
8987dd7cddfSDavid du Colombier.CW Cname
8997dd7cddfSDavid du Colombierassociated with an open file descriptor.
9007dd7cddfSDavid du ColombierIt takes three arguments: a file descriptor, a buffer, and the size of the buffer:
9017dd7cddfSDavid du Colombier.P1
9027dd7cddfSDavid du Colombierint fd2path(int fd, char *buf, int nbuf)
9037dd7cddfSDavid du Colombier.P2
9047dd7cddfSDavid du ColombierIt returns an error if the file descriptor is invalid; otherwise it fills the buffer with the name
9057dd7cddfSDavid du Colombierassociated with
9067dd7cddfSDavid du Colombier.CW fd .
9077dd7cddfSDavid du Colombier(If the name is too long, it is truncated; perhaps this condition should also draw an error.)
9087dd7cddfSDavid du ColombierThe
9097dd7cddfSDavid du Colombier.CW fd2path
9107dd7cddfSDavid du Colombiersystem call is very cheap, since all it does is copy the
9117dd7cddfSDavid du Colombier.CW Cname
9127dd7cddfSDavid du Colombierstring to user space.
9137dd7cddfSDavid du Colombier.LP
9147dd7cddfSDavid du ColombierThe Plan 9 implementation of
9157dd7cddfSDavid du Colombier.CW getwd
9167dd7cddfSDavid du Colombieruses
9177dd7cddfSDavid du Colombier.CW fd2path
9187dd7cddfSDavid du Colombierrather than the tricky algorithm necessary in Unix:
9197dd7cddfSDavid du Colombier.P1
9207dd7cddfSDavid du Colombierchar*
9217dd7cddfSDavid du Colombiergetwd(char *buf, int nbuf)
9227dd7cddfSDavid du Colombier{
9237dd7cddfSDavid du Colombier	int n, fd;
9247dd7cddfSDavid du Colombier
9257dd7cddfSDavid du Colombier	fd = open(".", OREAD);
9267dd7cddfSDavid du Colombier	if(fd < 0)
9277dd7cddfSDavid du Colombier		return NULL;
9287dd7cddfSDavid du Colombier	n = fd2path(fd, buf, nbuf);
9297dd7cddfSDavid du Colombier	close(fd);
9307dd7cddfSDavid du Colombier	if(n < 0)
9317dd7cddfSDavid du Colombier		return NULL;
9327dd7cddfSDavid du Colombier	return buf;
9337dd7cddfSDavid du Colombier}
9347dd7cddfSDavid du Colombier.P2
9357dd7cddfSDavid du Colombier(The Unix specification of
9367dd7cddfSDavid du Colombier.CW getwd
9377dd7cddfSDavid du Colombierdoes not include a count argument.)
9387dd7cddfSDavid du ColombierThis version of
9397dd7cddfSDavid du Colombier.CW getwd
9407dd7cddfSDavid du Colombieris not only straightforward, it is very efficient, reducing the performance
9417dd7cddfSDavid du Colombieradvantage of a built-in
9427dd7cddfSDavid du Colombier.CW pwd
9437dd7cddfSDavid du Colombiercommand while guaranteeing that all commands, not just
9447dd7cddfSDavid du Colombier.CW pwd ,
9457dd7cddfSDavid du Colombiersee sensible directory names.
9467dd7cddfSDavid du Colombier.LP
9477dd7cddfSDavid du ColombierHere is a routine that prints the file name associated
9487dd7cddfSDavid du Colombierwith each of its open file descriptors; it is useful for tracking down file descriptors
9497dd7cddfSDavid du Colombierleft open by network listeners, text editors that spawn commands, and the like:
9507dd7cddfSDavid du Colombier.P1
9517dd7cddfSDavid du Colombiervoid
9527dd7cddfSDavid du Colombieropenfiles(void)
9537dd7cddfSDavid du Colombier{
9547dd7cddfSDavid du Colombier	int i;
9557dd7cddfSDavid du Colombier	char buf[256];
9567dd7cddfSDavid du Colombier
9577dd7cddfSDavid du Colombier	for(i=0; i<NFD; i++)
9587dd7cddfSDavid du Colombier		if(fd2path(i, buf, sizeof buf) >= 0)
9597dd7cddfSDavid du Colombier			print("%d: %s\en", i, buf);
9607dd7cddfSDavid du Colombier}
9617dd7cddfSDavid du Colombier.P2
9627dd7cddfSDavid du Colombier.SH
9637dd7cddfSDavid du ColombierUses of good names
9647dd7cddfSDavid du Colombier.LP
9657dd7cddfSDavid du ColombierAlthough
9667dd7cddfSDavid du Colombier.CW pwd
9677dd7cddfSDavid du Colombierwas the motivation for getting names right, good file names are useful in many contexts
9687dd7cddfSDavid du Colombierand have become a key part of the Plan 9 programming environment.
9697dd7cddfSDavid du ColombierThe compilers record in the symbol table the full name of the source file, which makes
9707dd7cddfSDavid du Colombierit easy to track down the source of buggy, old software and also permits the
9717dd7cddfSDavid du Colombierimplementation of a program,
9727dd7cddfSDavid du Colombier.CW src ,
9737dd7cddfSDavid du Colombierto automate tracking it down.
9747dd7cddfSDavid du ColombierGiven the name of a program,
9757dd7cddfSDavid du Colombier.CW src
9767dd7cddfSDavid du Colombierreads its symbol table, extracts the file information,
9777dd7cddfSDavid du Colombierand triggers the editor to open a window on the program's
9787dd7cddfSDavid du Colombiersource for its
9797dd7cddfSDavid du Colombier.CW main
9807dd7cddfSDavid du Colombierroutine.
9817dd7cddfSDavid du ColombierNo guesswork, no heuristics.
9827dd7cddfSDavid du Colombier.LP
9837dd7cddfSDavid du ColombierThe
9847dd7cddfSDavid du Colombier.CW openfiles
9857dd7cddfSDavid du Colombierroutine was the inspiration for a new file in the
9867dd7cddfSDavid du Colombier.CW /proc
9877dd7cddfSDavid du Colombierfile system [Kill84].
9887dd7cddfSDavid du ColombierFor process
9897dd7cddfSDavid du Colombier.I n ,
9907dd7cddfSDavid du Colombierthe file
9917dd7cddfSDavid du Colombier.CW /proc/\f2n\fP/fd
9927dd7cddfSDavid du Colombieris a list of all its open files, including its working directory,
9937dd7cddfSDavid du Colombierwith associated information including its open status,
9947dd7cddfSDavid du ColombierI/O offset, unique id (analogous to i-number)
9957dd7cddfSDavid du Colombierand file name.
9967dd7cddfSDavid du ColombierHere is the contents of the
9977dd7cddfSDavid du Colombier.CW fd
9987dd7cddfSDavid du Colombierfile for a process in the window system on the machine being used to write this paper:
9997dd7cddfSDavid du Colombier.P1
10007dd7cddfSDavid du Colombier% cat /proc/125099/fd
10017dd7cddfSDavid du Colombier/usr/rob
10027dd7cddfSDavid du Colombier  0 r  M 5141 00000001.00000000        0 /mnt/term/dev/cons
10037dd7cddfSDavid du Colombier  1 w  M 5141 00000001.00000000       51 /mnt/term/dev/cons
10047dd7cddfSDavid du Colombier  2 w  M 5141 00000001.00000000       51 /mnt/term/dev/cons
10057dd7cddfSDavid du Colombier  3 r  M 5141 0000000b.00000000     1166 /dev/snarf
10067dd7cddfSDavid du Colombier  4 rw M 5141 0ffffffc.00000000      288 /dev/draw/new
10077dd7cddfSDavid du Colombier  5 rw M 5141 00000036.00000000  4266337 /dev/draw/3/data
10087dd7cddfSDavid du Colombier  6 r  M 5141 00000037.00000000        0 /dev/draw/3/refresh
10097dd7cddfSDavid du Colombier  7 r  c    0 00000004.00000000  6199848 /dev/bintime
10107dd7cddfSDavid du Colombier%
10117dd7cddfSDavid du Colombier.P2
10127dd7cddfSDavid du Colombier(The Linux implementation of
10137dd7cddfSDavid du Colombier.CW /proc
10147dd7cddfSDavid du Colombierprovides a related service by giving a directory in which each file-descriptor-numbered file is
10157dd7cddfSDavid du Colombiera symbolic link to the file itself.)
10167dd7cddfSDavid du ColombierWhen debugging errant systems software, such information can be valuable.
10177dd7cddfSDavid du Colombier.LP
10187dd7cddfSDavid du ColombierAnother motivation for getting names right was the need to extract from the system
10197dd7cddfSDavid du Colombieran accurate description of the mount table, so that a process's name space could be
10207dd7cddfSDavid du Colombierrecreated on another machine, in order to move (or simulate) a computing environment
10217dd7cddfSDavid du Colombieracross the network.
10227dd7cddfSDavid du ColombierOne program that does this is Plan 9's
10237dd7cddfSDavid du Colombier.CW cpu
10247dd7cddfSDavid du Colombiercommand, which recreates the local name space on a remote machine, typically a large
10257dd7cddfSDavid du Colombierfast multiprocessor.
10267dd7cddfSDavid du ColombierWithout accurate names, it was impossible to do the job right; now
10277dd7cddfSDavid du Colombier.CW /proc
10287dd7cddfSDavid du Colombierprovides a description of the name space of each process,
10297dd7cddfSDavid du Colombier.CW /proc/\f2n\fP/ns :
10307dd7cddfSDavid du Colombier.P1
10317dd7cddfSDavid du Colombier% cat /proc/125099/ns
10327dd7cddfSDavid du Colombierbind  / /
10337dd7cddfSDavid du Colombiermount -aC #s/boot /
10347dd7cddfSDavid du Colombierbind  #c /dev
10357dd7cddfSDavid du Colombierbind  #d /fd
10367dd7cddfSDavid du Colombierbind -c #e /env
10377dd7cddfSDavid du Colombierbind  #p /proc
10387dd7cddfSDavid du Colombierbind -c #s /srv
10397dd7cddfSDavid du Colombierbind  /386/bin /bin
10407dd7cddfSDavid du Colombierbind -a /rc/bin /bin
10417dd7cddfSDavid du Colombierbind  /net /net
10427dd7cddfSDavid du Colombierbind -a #l /net
10437dd7cddfSDavid du Colombiermount -a #s/cs /net
10447dd7cddfSDavid du Colombiermount -a #s/dns /net
10457dd7cddfSDavid du Colombierbind -a #D /net
10467dd7cddfSDavid du Colombiermount -c #s/boot /n/emelie
10477dd7cddfSDavid du Colombierbind -c /n/emelie/mail /mail
10487dd7cddfSDavid du Colombiermount -c /net/il/134/data /mnt/term
10497dd7cddfSDavid du Colombierbind -a /usr/rob/bin/rc /bin
10507dd7cddfSDavid du Colombierbind -a /usr/rob/bin/386 /bin
10517dd7cddfSDavid du Colombiermount  #s/boot /n/emelieother other
10527dd7cddfSDavid du Colombierbind -c /n/emelieother/rob /tmp
10537dd7cddfSDavid du Colombiermount  #s/boot /n/dump dump
10547dd7cddfSDavid du Colombierbind  /mnt/term/dev/cons /dev/cons
10557dd7cddfSDavid du Colombier\&...
10567dd7cddfSDavid du Colombiercd /usr/rob
10577dd7cddfSDavid du Colombier%
10587dd7cddfSDavid du Colombier.P2
10597dd7cddfSDavid du Colombier(The
10607dd7cddfSDavid du Colombier.CW #
10617dd7cddfSDavid du Colombiernotation identifies raw device drivers so they may be attached to the name space.)
10627dd7cddfSDavid du ColombierThe last line of the file gives the working directory of the process.
10637dd7cddfSDavid du ColombierThe format of this file is that used by a library routine,
10647dd7cddfSDavid du Colombier.CW newns ,
10657dd7cddfSDavid du Colombierwhich reads a textual description like this and reconstructs a name space.
10667dd7cddfSDavid du ColombierExcept for the need to quote
10677dd7cddfSDavid du Colombier.CW #
10687dd7cddfSDavid du Colombiercharacters, the output is also a shell script that invokes the user-level commands
10697dd7cddfSDavid du Colombier.CW bind
10707dd7cddfSDavid du Colombierand
10717dd7cddfSDavid du Colombier.CW mount ,
10727dd7cddfSDavid du Colombierwhich are just interfaces to the underlying system calls.
10737dd7cddfSDavid du ColombierHowever,
10747dd7cddfSDavid du Colombierfiles like
10757dd7cddfSDavid du Colombier.CW /net/il/134/data
10767dd7cddfSDavid du Colombierrepresent network connections; to find out where they point, so that the corresponding
10777dd7cddfSDavid du Colombiercalls can be reestablished for another process,
10787dd7cddfSDavid du Colombierthey must be examined in more detail using the network device files [PrWi93].  Another program,
10797dd7cddfSDavid du Colombier.CW ns ,
10807dd7cddfSDavid du Colombierdoes this; it reads the
10817dd7cddfSDavid du Colombier.CW /proc/\f2n\fP/ns
10827dd7cddfSDavid du Colombierfile, decodes the information, and interprets it, translating the network
10837dd7cddfSDavid du Colombieraddresses and quoting the names when required:
10847dd7cddfSDavid du Colombier.P1
10857dd7cddfSDavid du Colombier\&...
10867dd7cddfSDavid du Colombiermount -a '#s/dns' /net
10877dd7cddfSDavid du Colombier\&...
10887dd7cddfSDavid du Colombiermount -c il!135.104.3.100!12884 /mnt/term
10897dd7cddfSDavid du Colombier\&...
10907dd7cddfSDavid du Colombier.P2
10917dd7cddfSDavid du ColombierThese tools make it possible to capture an accurate description of a process's
10927dd7cddfSDavid du Colombiername space and recreate it elsewhere.
10937dd7cddfSDavid du ColombierAnd like the open file descriptor table,
10947dd7cddfSDavid du Colombierthey are a boon to debugging; it is always helpful to know
10957dd7cddfSDavid du Colombierexactly what resources a program is using.
10967dd7cddfSDavid du Colombier.SH
10977dd7cddfSDavid du ColombierAdapting to Unix
10987dd7cddfSDavid du Colombier.LP
10997dd7cddfSDavid du ColombierThis work was done for the Plan 9 operating system, which has the advantage that
11007dd7cddfSDavid du Colombierthe non-hierarchical aspects of the name space are all known to the kernel.
11017dd7cddfSDavid du ColombierIt should be possible, though, to adapt it to a Unix system.
11027dd7cddfSDavid du ColombierThe problem is that Unix has nothing corresponding precisely to a
11037dd7cddfSDavid du Colombier.CW Channel ,
11047dd7cddfSDavid du Colombierwhich in Plan 9 represents the unique result of evaluating a name.
11057dd7cddfSDavid du ColombierThe
11067dd7cddfSDavid du Colombier.CW vnode
11077dd7cddfSDavid du Colombierstructure is a shared structure that may represent a file
11087dd7cddfSDavid du Colombierknown by several names, while the
11097dd7cddfSDavid du Colombier.CW file
11107dd7cddfSDavid du Colombierstructure refers only to open files, but for example the current working
11117dd7cddfSDavid du Colombierdirectory of a process is not open.
11127dd7cddfSDavid du ColombierPossibilities to address this discrepancy include
11137dd7cddfSDavid du Colombierintroducing a
11147dd7cddfSDavid du Colombier.CW Channel -like
11157dd7cddfSDavid du Colombierstructure that connects a name and a
11167dd7cddfSDavid du Colombier.CW vnode ,
11177dd7cddfSDavid du Colombieror maintaining a separate per-process table that maps names to
11187dd7cddfSDavid du Colombier.CW vnodes ,
11197dd7cddfSDavid du Colombierdisambiguating using the techniques described here.
11207dd7cddfSDavid du ColombierIf it could be done
11217dd7cddfSDavid du Colombierthe result would be an implementation of
11227dd7cddfSDavid du Colombier.CW ..
11237dd7cddfSDavid du Colombierthat reduces the need for a built-in
11247dd7cddfSDavid du Colombier.CW pwd
11257dd7cddfSDavid du Colombierin the shell and offers a consistent, sensible interpretation of the `parent directory'.
11267dd7cddfSDavid du Colombier.LP
11277dd7cddfSDavid du ColombierWe have not done this adaptation, but we recommend that the Unix community try it.
11287dd7cddfSDavid du Colombier.SH
11297dd7cddfSDavid du ColombierConclusions
11307dd7cddfSDavid du Colombier.LP
11317dd7cddfSDavid du ColombierIt should be easy to discover a well-defined, absolute path name for every open file and
11327dd7cddfSDavid du Colombierdirectory in the system, even in the face of symbolic links and other non-hierarchical
11337dd7cddfSDavid du Colombierelements of the file name space.
11347dd7cddfSDavid du ColombierIn earlier versions of Plan 9, and all current versions of Unix,
11357dd7cddfSDavid du Colombiernames can instead be inconsistent and confusing.
11367dd7cddfSDavid du Colombier.LP
11377dd7cddfSDavid du ColombierThe Plan 9 operating system now maintains an accurate name for each file,
11387dd7cddfSDavid du Colombierusing inexpensive lexical operations coupled with local file system actions.
11397dd7cddfSDavid du ColombierAmbiguities are resolved by examining the names themselves;
11407dd7cddfSDavid du Colombiersince they reflect the path that was used to reach the file, they also reflect the path back,
11417dd7cddfSDavid du Colombierpermitting a dependable answer to be recovered even when stepping backwards through
11427dd7cddfSDavid du Colombiera multiply-named directory.
11437dd7cddfSDavid du Colombier.LP
11447dd7cddfSDavid du ColombierNames make sense again: they are sensible and consistent.
11457dd7cddfSDavid du ColombierNow that dependable names are available, system services can depend on them,
11467dd7cddfSDavid du Colombierand recent work in Plan 9 is doing just that.
11477dd7cddfSDavid du ColombierWe\(emthe community of Unix and Unix-like systems\(emshould have done this work a long time ago.
11487dd7cddfSDavid du Colombier.SH
11497dd7cddfSDavid du ColombierAcknowledgements
11507dd7cddfSDavid du Colombier.LP
11517dd7cddfSDavid du ColombierPhil Winterbottom devised the
11527dd7cddfSDavid du Colombier.CW ns
11537dd7cddfSDavid du Colombiercommand and the
11547dd7cddfSDavid du Colombier.CW fd
11557dd7cddfSDavid du Colombierand
11567dd7cddfSDavid du Colombier.CW ns
11577dd7cddfSDavid du Colombierfiles in
11587dd7cddfSDavid du Colombier.CW /proc ,
11597dd7cddfSDavid du Colombierbased on an earlier implementation of path name management that
11607dd7cddfSDavid du Colombierthe work in this paper replaces.
11617dd7cddfSDavid du ColombierRuss Cox wrote the final version of
11627dd7cddfSDavid du Colombier.CW cleanname
11637dd7cddfSDavid du Colombierand helped debug the code for reversing the mount table.
11647dd7cddfSDavid du ColombierKen Thompson, Dave Presotto, and Jim McKie offered encouragement and consultation.
11657dd7cddfSDavid du Colombier.SH
11667dd7cddfSDavid du ColombierReferences
11677dd7cddfSDavid du Colombier.LP
11687dd7cddfSDavid du Colombier[Field95]
11697dd7cddfSDavid du ColombierR. Fielding,
11707dd7cddfSDavid du Colombier``Relative Uniform Resource Locators'',
11717dd7cddfSDavid du Colombier.I "Network Working Group Request for Comments: 1808" ,
11727dd7cddfSDavid du ColombierJune, 1995.
11737dd7cddfSDavid du Colombier.LP
11747dd7cddfSDavid du Colombier[Kill84]
11757dd7cddfSDavid du ColombierT. J. Killian,
11767dd7cddfSDavid du Colombier``Processes as Files'',
11777dd7cddfSDavid du Colombier.I "Proceedings of the Summer 1984 USENIX Conference" ,
11787dd7cddfSDavid du ColombierSalt Lake City, 1984, pp. 203-207.
11797dd7cddfSDavid du Colombier.LP
11807dd7cddfSDavid du Colombier[Korn94]
11817dd7cddfSDavid du ColombierDavid G. Korn,
11827dd7cddfSDavid du Colombier``ksh: An Extensible High Level Language'',
11837dd7cddfSDavid du Colombier.I "Proceedings of the USENIX Very High Level Languages Symposium" ,
11847dd7cddfSDavid du ColombierSanta Fe, 1994, pp. 129-146.
11857dd7cddfSDavid du Colombier.LP
11867dd7cddfSDavid du Colombier[Korn00]
11877dd7cddfSDavid du ColombierDavid G. Korn,
11887dd7cddfSDavid du Colombierpersonal communication.
11897dd7cddfSDavid du Colombier.LP
11907dd7cddfSDavid du Colombier[PeMc95]
11917dd7cddfSDavid du ColombierJan-Simon Pendry and Marshall Kirk McKusick,
11927dd7cddfSDavid du Colombier``Union Mounts in 4.4BSD-Lite'',
11937dd7cddfSDavid du Colombier.I "Proceedings of the 1995 USENIX Conference" ,
11947dd7cddfSDavid du ColombierNew Orleans, 1995.
11957dd7cddfSDavid du Colombier.LP
11967dd7cddfSDavid du Colombier[Pike91]
11977dd7cddfSDavid du ColombierRob Pike,
11987dd7cddfSDavid du Colombier``8½, the Plan 9 Window System'',
11997dd7cddfSDavid du Colombier.I "Proceedings of the Summer 1991 USENIX Conference" ,
12007dd7cddfSDavid du ColombierNashville, 1991, pp. 257-265.
12017dd7cddfSDavid du Colombier.LP
12027dd7cddfSDavid du Colombier[Pike93]
12037dd7cddfSDavid du ColombierRob Pike, Dave Presotto, Ken Thompson, Howard Trickey, and Phil Winterbottom,
12047dd7cddfSDavid du Colombier``The Use of Name Spaces in Plan 9'',
12057dd7cddfSDavid du Colombier.I "Operating Systems Review" ,
12067dd7cddfSDavid du Colombier.B 27 ,
12077dd7cddfSDavid du Colombier2, April 1993, pp. 72-76.
12087dd7cddfSDavid du Colombier.LP
12097dd7cddfSDavid du Colombier[PrWi93]
12107dd7cddfSDavid du ColombierDave Presotto and Phil Winterbottom,
12117dd7cddfSDavid du Colombier``The Organization of Networks in Plan 9'',
12127dd7cddfSDavid du Colombier.I "Proceedings of the Winter 1993 USENIX Conference" ,
12137dd7cddfSDavid du ColombierSan Diego, 1993, pp. 43-50.
1214