@Part( lowlevel, root "text" ) @Section(V-System Low-Level Naming)@Label(lowlevel) V-System naming is structured as three levels: IPC, service, and object. In this section, we discuss the low-level names used for these entities. Because V is built on a message-based distributed kernel, IPC is the most basic level. @Subsection(IPC Naming) Communication in V takes place between processes, with senders of data specifying the recipient as a process, as opposed to a port or mailbox. @Foot(Alternatively, one can think of a process as having exactly one mailbox which is permanently associated with that process.) Similarly, the sender of data is identified to the receiver by its process identifier. A V process identifier (or @i[pid]) is a 32-bit value that uniquely identifies a process within one V domain. @Foot(A process identifier is spatially unique, but not unique in time, as it may be reused at some point after the process it currently names is terminated. We attempt to maximize the time before reuse.) A @i[V domain] is a set of logical hosts running the distributed V kernel, usually machines connected by one local network, over which kernel operations are transparent with respect to machine boundaries. A V domain is basically one V-System installation. Process identifiers are structured as two 16-bit subfields: @i[logical host] and @i[local process identifier], as shown in Figure 2. @presspicture( file="pid.fig", height="0.25 inches") @Center(@b(Figure 2:) Process Identifier Subfields) The logical host field is mapped to a particular host address and the local pid is mapped to a process on the machine at that address. This structuring provides an efficient means of locating a process. It also allows each logical host within a V domain to independently generate unique process identifiers without danger of conflict. Finally, one can efficiently determine from a process identifier whether the named process is local or remote, an important issue for some servers. Process identifiers are the only absolute names in a V domain. All other names are relative to either a process identifier, typically the identifier of a server process implementing a service, or a ``logical process identifier'' for a service, as described below. @Subsection(Service Naming) V-System services include storage, printing, time, context management, virtual graphics terminals, program loading, and exception handling, among others. Most V-System services are provided by dedicated server processes. To name the @i[service] (as opposed to the process that implements the service), the kernel supports a simple naming facility that allows processes to register as providing a particular service, and allows client processes to determine the process identifier of a registered server. @Example{SetPid(service, pid, scope)} registers the process specified by @i[pid] as providing the specified service within the given scope. @i[Scope] is one of ``local'' to this machine, ``remote'' or ``both local and remote.'' We have found it important to distinguish between simple local servers and remotely-available ``public'' servers, and even to allow both simultaneously for the same service. @Example{pid = GetPid(service, scope)} returns the process identifier, or @i[pid], of a process registered as providing the particular service within the specified scope. In response to a @p[GetPid], the kernel checks its local table and, if that fails and the scope is not @i[local], broadcasts to query other kernels on the network. Using this mechanism, programs are written in terms of services, and the binding of service to server process occurs at time of use. With simple services like time, the client typically translates from service to real server pid on each operation. With file access, the pid for a server process is acquired when the file is opened and used subsequently without remapping from the service name. This avoids the extra overhead of an indirection from service to process on every communication, as arises in a system using ports or mailboxes. It does, however, complicate rebinding when a server fails, although this presumably rare event can then be handled without imposing overhead on normal operation. A service naming mechanism separate from process naming is required because a process identifier can only identify the process currently implementing the service, and not the service itself. The process may change while the service remains essentially the same. For instance, if a storage server is recreated after a crash with a different process identifier, it is still the same service from the client's point of view, even though now implemented by a different process. @comment(** Is the follow paragraph needed at all? --TPM) An alternative design for service naming is to make a distinguished name server ``well-known'' and use it to name all other services. This design can still be implemented using our kernel, but the @p[SetPid]-@p[GetPid] mechanism would still be needed to obtain the name server's pid, since the use of even one ``fixed'' process identifier with the V kernel does not suit its design, i.e., process identifiers are always allocated randomly. @Subsection(Object Naming) In general, many services consist of implementations of one or more types of @i[objects] (in the data abstraction sense), with the operations associated with the service being the operations on these objects, i.e., the server is an abstract data type manager. There are basically two categories of server objects with respect to naming: temporary and permanent. Temporary objects typically only exist during the execution of the program that requested their creation. A temporary object is named by a short, numeric identifier (low-level name) generated by the server when the object is created. The identifier need not be chosen by the user because it is only used internally by the program and the server. A temporary object is uniquely specified by the server pid, type of object, and object identifier. Normally, the type of object is derived from the type of the request message, as specified by the operation code. In V, temporary objects are named using short (16-bit) numeric identifiers, called @i[object instance identifiers]. Servers attempt to maximize the time before reusing a temporary object identifier after the object has been destroyed. Permanent objects typically exist beyond the execution of the program that created them. Thus, the name of the object must be stored in a file or remembered by the user. Therefore, permanent objects are named by users or applications for their convenience. A permanent V object is named using a high-level @i[character string name]. Character-string naming is discussed in the next section.