Chapter 2: Keymaster



2.1: Purpose


The keymaster is the daemon that provides services that could not be handled by the OSD library alone.



2.2: Services


2.2.1: Provide shared resource management

Shared resources are handled differently by different operating systems. For example, on UNIX and IPC resource persists until explicitly removed. However, on Windows NT an IPC resource is removed by the kernel when no handles to the resource exist. The keymaster is to provide persistent (UNIX style) and non-persistent (NT style) IPC resources on any operating system.

2.2.2: Provide system information services

System information such as system load or which processes are alive is to be provided by the keymaster. Even though the abstraction layer library could handle most of this, the overhead in obtaining some information on some operating systems is high (therefore the keymaster could provide information caching). Also, the keymaster provides a remotely locatable process from which system information for remote machine can be obtained. Finally, there are some types of system data which cannot be provided by the abstraction library (for example, on Windows NT there is no obtainable 'load'. However, the process queue length can be obtained so the 'load' can be generated by a thread in the keymaster averaging process queue length over time).

2.2.3: Provide kernel extensions

Objects which do not even exist on some operating systems can be provided by the keymaster. For example, an application could use a semaphore (or mutex or whatever) to lock on every object in a container type instead of locking the whole container. However, UNIX semaphores are available in a limited number available on any particular OS. The keymaster could provide an indefinite number of blocking objects (semaphores, mutexes, or whatever) by making use of its serialized access (a single UDP port).



2.3: Shared Resource Management

Interaction with the keymaster is based on an instruction set of simple commands. Complex tasks are accomplished through a series of these instructions.


In order to provide shared resource management, the keymaster must keep track of the particular OS resources and the processes with handles to the resources.



2.3.1: Context Objects

Internally, the keymaster represents OS resources it is managing as a linked list of 'context' objects. A context object has a 'key' associated with it. With this 'key' a process can identify which context, hence which OS resource, it is referring to. In addition the the keymaster assigned 'key', and OS resource context also has an operating system 'os_key' associated with it.



2.3.2: Process Objects

Internally, the keymaster represents processes as a linked list of process objects. In order to open a handle to a context a process must be registered with the keymaster. The first process object in the process object linked list is for the keymaster itself.



2.3.3: Associate Objects

Processes are associated with contexts through associate objects. If a process has a handle to a context, then in the keymaster the process object points to an associate object which is also pointed to by the appropriate context object. Therefore, each process object and each context object has a linked list of associate objects which together form a sparse matrix. Associate objects have a reference count. If the reference count for an associate object drops to zero, the associate object is removed.

In this example sparse matrix process objects are labeled A-F and context objects are labeled 1-6. Associate object will be referred to by the appropriate letter-number combination (such as C2). Process object A is the process object for the keymaster itself.


It is through this data structure that keymaster consistency is maintained. When a process is removed, it whole column in the matrix is removed. When a context is explicitly destroyed the whole row for the context is removed.



2.3.4: Resource Persistence

As far as the keymaster is concerned, all context objects are non-persistent. If a context object has no associate objects associated to it, it is removed. In the above example if process B sent a close handle instruction for context 5, context 5 would be removed since it would no longer have any process associated with it.


Persistence (as far as a process using the keymaster is concerned) is achieved by associating a context with the keymaster process object. Therefore, if no process besides the keymaster is associated with the context, and the keymaster process is associated with it, the context still persists (such as context 4 in the example matrix). Since the open context instruction and the open handle instruction are separate, the keymaster is associated with any newly opened context (otherwise a context would be removed as soon as it was opened because no association would exist). Therefore, contexts are persistent by default. The decrement keymaster handle instruction decrements the count of the keymaster association thereby providing the means to make a context non-persistent.



2.3.5: Handles and Keys

Unfortunately, the words 'handle' and 'key' are overloaded when talking about the keymaster and abstraction layer. In attempt to make things clearer the different handles/keys are enumerated here.




2.3.5.1: Universal Key

The universal key is defined by the keymaster and is used to identify context objects. A user of the abstraction layer does have access to universal keys.




2.3.5.2: Operating System Key

The operating system key (os_key) is an operating system dependent entity with which processes identify a system resources. A user of the abstraction layer does not see operating system keys. However, the abstraction layer itself uses operating system keys to locate actual shared resources.


In UNIX operating system keys are of type key_t (an int). In Windows NT operating system keys are names (strings).




2.3.5.3: Keymaster Handle

A keymaster handle is an associate object , or more specificly a counted reference in an associate object.




2.3.5.4: Operating System Handle

The operating system handle is what a process uses to interact with with the OS resources through system calls. These are also hidden from the user of the abstraction layer. In UNIX the operating system handle is a descriptor, in Windows NT it is of type HANDLE.



2.3.6: Creating and Using Shared Resources

The keymaster uses what is essentially a finite state machine to configure create resource objects. A keymaster client sends a sequence of instruction that build the state of a context and then create it.



2.4: System Information Services



2.4.1: Queries

There are two basic types of queries. Keymaster information queries and system information queries.




2.4.1.1: Keymaster Information

All keys of some type can be obtained through the instruction. The status of a context can be obtained with the status instruction.

2.4.1.2: System Information

Particular items of system data such as load or free swap space can be obtained through the GKDATA instruction.



2.4.2: Mailboxes

Mailboxes provide a way for client processes to register to be notified by the keymaster when particular events happen. For example, the Harness srvr registers to be notified whenever a keymaster client process (which all harness processes are) dies ungracefully, allowing srvr to clean its data structures when this happens.


A mailbox is simply another type of context with a data element specifying which types of events to send mail for. Every process associated with the mailbox is sent a message when the specified event happens.



2.5: Implementation


2.5.1: The Universal Key

The universal key is make up of two 16 bit fields, the user field and the system field. The user field is specified by the process requesting a new context and the system field is specified by the keymaster. This gives applications the ability to group resources using the user field of the key.



2.5.2: The Instruction Set

An instruction is made up of three fields as follows