Steven R. Breitstein
Bell Labs Innovations
600 Mountain Ave.
Murray Hill, NJ 07974
Inferno is a network operating system that provides a software infrastructure for distributed, network applications. Inferno allows any application, written in the Limbo programming language, to run across multiple platforms and networks under the Dis virtual machine. Inferno provides an elegant file-like interface to resources and services that allows the dynamic construction of a user name space. An Inferno application can access the resources and services in its name space even though they may be distributed throughout the network. The Styx component of Inferno provides transparent communications over a variety of networks with strong security capabilities built in.
The Inferno namespace operations provide a powerful set of features for delivering networked applications. They provide a simple programming model, network transparency, yet great flexibility in delivering resources to meet the many (sometimes conflicting) needs of diverse users. The result is simpler, smaller, less costly, more maintainable software.
The Inferno "namespace" is the hierarchy of file names available to a program. There are two things that make this a major feature of the Inferno system. First, Inferno represents many resources as files. Files are not just data; files may also be devices, network connections, and interfaces to services. So the (file) namespace actually represents a diverse resource space. Second, Inferno offers a unique set of operations to manage that namespace. These operations allow programmers and application developers to cope with complexity in today's networked environments.
Advantages of the Namespace
The traditional role of a file (data storage) is merely one of many file-based services in Inferno. Files are also interfaces to peripherals, to programs, to services, and to networks.
The file model is simple (open, read, and write) and known to all programmers. Representing so many resources by a common interface is a first step in controlling complexity. For certain naturally complex resources, Inferno provides interfaces as suites of related files, each individually simple to use. One example is IP device interface. That includes separate data, ctl (control), and status files. By convention, devices are controlled by simply writing a text string to the appropriate control file. For example, a connection can be established by writing "connect 18.104.22.168" to the control file.
Some system interfaces that traditionally require system calls are here provided via special files. This reduces the size of the operating system, another Inferno strength.
The local namespace can be extended by grafting on file trees from Inferno servers, thereby gaining access to resources from those machines. Once incorporated into the local namespace, use of the remote resources is indistinguishable from local resource use.
The namespace operations can be used to separate application issues from configuration issues. Resources can be made to appear where they are needed rather than having applications adapt to where resources can be found. Uncoupling the issues simplifies these problems.
The namespace can be personalized. Changes in the namespace can be either shared or restricted to individual users or even to individual programs. Thus, resources can be optimally positioned within the namespace for each situation rather than having to find compromises between the many (perhaps contradictory) needs of many applications.
Resources as Files, the Connection Server Example
A notable example of an important system service provided through a file interface is the connection server, a service that will translate a symbolic host name to a network address that can be used to establish a connection.
The protocol is to write the hostname of interest into the special file /net/cs, then read back the answer.
Figure 1 - Connection Server
The write request is detected by a daemon process that translates the name and stores the answer until the read request arrives. Multiple, interleaved requests are handled correctly. The daemon is a small, simple application program, not part of the kernel. In fact, the kernel itself uses the /net/cs file when it must translate a name to a network address.
The key namespace operations are mount and bind.
The mount operation adds a file tree from a server machine to the current namespace (see Figure 2). Once that file tree is attached, its members can be accessed in the same manner as local files (see Figure 3). Applications directed to use those files cannot detect that they are operating remotely. This is true even for fileC, a file that this server has mapped into its namespace from yet another server.
Network transparency is supported for all Inferno files, be they simple data, or devices, or daemon interfaces. Applications are networked without explicit network programming.
Inferno networking is more than simple client/server computing. The roles of "client" and "server" are relative to some set of shared resources. In general, application problems can be solved by having two or more machines cross mount resources from each other and have processes on each coordinate on using the combined resources.
Figure 2 - Client/Server View Before Mount
The bind operation maps one file name in the namespace to another. Consider first a simple example. Suppose an application is expecting to find a certain file, fileB, in directory, D, but the file actually resides in directory B. See Figure 3.
Figure 3 - View After Mount, Before Bind
The bind operation can be used to make fileB appear to reside in directory D. See Figure 4.
Note that fileB is still available from directory B. In this case, the original contents of directory D are obscured. Different bind options can be used to make D a union directory that has both the original contents and those from directory B. An example using that will be shown shortly.
Figure 4 - File View After Bind Operation
One implication of the above, simple example is that applications become simpler because they need not cope with a variety of configurations. They can be "hard-coded" to look for resources in certain directories. Ordinarily, this would be bad practice; however, in Inferno, there can be a separate set-up stage to provide the application with the needed file (possibly using mounts over the network) in the expected location.
Separating configuration issues from application concerns makes each task easier. This leads to better software that is less expensive to develop and maintain.
Namespace Customization, An Example
Another important facility of Inferno namespace operations is the ability to create "union" directories. That is, the ability to make several directories to appear as one. Member files of each contributing directory appear in the union. When contributing directories have file names in common, the file available from the union depends on the order of constructing the union.
One way this is used in Inferno is the management of commands available to the Inferno shell. The Inferno shell has no PATH variable. That is, it does not maintain a list of directories to be searched for commands. The Inferno shell is programmed to look for executable files in under a single hard coded directory, call it /bin. See Figure 5.
Figure 5 - Namespace Before Customization
When a user wants access to a command that does not exist in /bin, the user can bind the command into the designated place, /bin. If a user wants to use a customized version of a command already existing in /bin, the user can bind in the new command in a way so that the personal version takes precedence over the standard version. See Figure 6.
The Inferno system provides an operation to clone an existing namespace to obtain an independent copy. Changes in the copy do not influence those using the original.
Figure 6 - Namespace After Customization
Controlling Access to Resources
System security can be enhanced by namespace operations that shrink an existing namespace. A process can be restricted so that it can only access a limited set of files and, once restricted, the process can access no others.
This technique is usefully applied before starting a test program that requires a carefully controlled environment or before starting a suspicious program that might harm the local file system. The technique can also be applied on Inferno server systems to restrict the set of files available for mounting by clients.
Controlling access to resources by namespace restrictions is an adjunct to the control provided by file and directory permissions. For example, some application, say a mail reader program, to perform its basic function, might need a user's identity to access some of that user's files. Should satisfying that requirement imply that the program have the potential of accessing any of that user's files? By appropriately restricting the namespace, that need not be the case. The program can be restricted to a universe containing only the files it needs. The program's permission to access other files is irrelevant if pathnames to those other files cannot be defined.
Recall that files are representing all sorts of resources. By restricting the namespace the application's universe of resources is limited. Omitting the network interface means that it cannot make network calls. Omitting the interface to running programs means that the application cannot terminate other applications.