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
- Instruction Opcode (8 bits)
- Universal Key (32 bits)
- Argument (ARG_SIZE bytes)