Chapter 2. Common Implementation Issues

This chapter presents information you must know before implementing an LCP or DCP. Please read these sections whether you are implementing an LCP, a DCP, or both:

2.1. Booting OpenVault Components

Because it is composed of different modules working together, OpenVault booting is critical for correct operation. This section describes how OpenVault assembles itself, either at system boot time or when recovering from partial failure of the system.

The MLM server initiates a sequence to bootstrap a functioning OpenVault system. Each component boots independently, reading its own configuration file, which contains just enough information to initialize that particular component. Remaining information is derived from the state of a device, persistent storage, or from parameters compiled into a particular component. Configuration files vary greatly from component to component. The session initiation sequence is the same for all components, and allows a component to identify itself by name, type, and the language versions that it supports.

2.1.1. MLM Server Booting

The MLM server should be the first component to initialize itself. If the MLM server reboots, all LCP and DCP connections to it are lost. Procedure 2-1 describes the steps the MLM server takes during booting:

Procedure 2-1. Booting MLM Server

  1. Read its configuration file.

    The LCP or DCP developer does not need to be concerned about this file.

  2. Accept connections from booting DCPs and LCPs.

    The communications layer establishes TCP keepalive sockets. If the connection is lost, the MLM server tries to re-establish the connection every two minutes.

  3. Service other client connections and AAPI or CAPI requests.

    The MLM server accepts client connections as they arrive. AAPI and CAPI requests are fulfilled if the resources needed to service them are available.

    2.1.2. LCP and DCP Booting

    Each LCP and DCP must also initialize itself. For details on LCP booting, see Chapter 4, “Programming a Library Control Program (LCP)”. For details on DCP booting, see Chapter 6, “Programming a Drive Control Program (DCP)”.

    2.2. Persistent Storage

    The OpenVault persistent store is implemented as a database subsystem that resides in the MLM server. This is a multiuser, in-memory relational database subsystem whose clients are the modules that make up core OpenVault services. Each OpenVault module is linked with a C library to handle the following activities:

    • Constructing queries and other data update operations

    • Assembling and disassembling the data update structures

    One important OpenVault process is the Catalog Manager, which handles database startup and recovery, manages the on-disk transactional log file, and takes periodic snapshots of the database.

    The LCP or DCP developer does not need to be concerned about details of the OpenVault database. The MLM server handles database operations triggered by LCP and DCP events or by CAPI requests from client applications transparently. LCPs and DCPs interact with the persistent store through the ALI/R or ADI/R language.

    2.3. Communication Protocols

    The OpenVault interfaces ALI, ADI, CAPI, and AAPI are based on message passing. Only ASCII strings travel across the sockets. OpenVault client and control program processes communicate with the MLM server through TCP/IP sockets. The hello-welcome sequence establishes an IPC connection based on a TCP socket.

    Once an IPC connection has been established, the entity at either end of the connection may send and receive commands compatible with the negotiated language and version. The sender of a command generates a unique task ID for that command. The task ID is used in subsequent responses to that command. The sender may also use the task ID to cancel the original command or check command status.

    2.3.1. Version Negotiation Language

    To allow partial upgrades and peaceful coexistence of different language versions, OpenVault includes a session initiation facility to negotiate language version. When connecting to the MLM server, a client or control program announces which language it uses, and which versions of the language it understands. The MLM server then selects one version and tells the client which one to use for the current session.

    hello

    A client or control program uses the hello command to announce itself to the MLM server. The client includes in that command the name of the language it would like to speak, a list of the different language version numbers it supports, a name for itself as an application, and a name for a particular instance of that application. An LCP or DCP should use the OpenVault name of the device it controls as its application name.

    welcome

    After the client announcement, the MLM server responds with a welcome command, telling the client which version to use. This version is one that the client enumerated in the hello command. At this point, a session is established between the client and MLM server, implemented by an underlying TCP/IP connection.

    unwelcome

    The unwelcome command tells the client that none of the combinations of language and language version it provided are supported by this MLM server. After the external client has announced itself to the MLM server, the server may respond with an unwelcome command if the language name is unknown, or if none of the language versions supported by the client are supported by the server.

    LCP and DCP programmers working in the C language can use a library routine that encapsulates the hello and welcome exchange to establish a session. For an LCP, version negotiation is built into the ALIR_initiate_session() function. For a DCP, version negotiation is built into the ADIR_initiate_session() function.

    The OpenVault session is demarcated by version negotiation (hello and welcome) at the beginning, and close of session (goodbye) at the end.

    2.3.2. Authentication Requests

    Before a session can be established between the initiator and its recipient, authentication is needed. OpenVault employs public key session verification to provide a modicum of security while still avoiding export restrictions.

    As an example, assume that Alice represents the client that initiates communication with the MLM server (the client could be a DCP, LCP, or client application). Bob represents the MLM server. The authentication process begins with Alice sending her name to Bob. Bob replies by generating a 32-bit random number (R1) and sending it to Alice as a challenge. Upon receiving this number, Alice encrypts it with the key she shares with Bob and sends this value, along with another 32-bit random number she has generated herself (R2) to Bob. After checking to make sure that Alice has successfully encrypted R1, Bob then encrypts R2 and generates a third random number (R3). Bob now sends the encrypted R2 and R3 to Alice. Alice verifies that R2 has been properly encrypted and then decrypts R3 and stores it as the session key.

    Infrastructure developers do not need to be concerned about details of the OpenVault authentication method. The OpenVault transport layer handles authentication requests from client applications transparently.

    2.3.3. Command Phases

    A communication session between the MLM server and a client or control program employs a stylized sequence of phases. Since the interface is a full-duplex bidirectional peer-to-peer interface, this applies to both directions of a session. There are three phases:

    Command

    In this phase, the sender transmits the text of the command, plus a task ID it assigns to the command, to help track responses.

    Ack

    The receiver sends back an intermediate response indicating that it accepted a command with the given task ID. The receiver may send back an unacceptable response if the command was incorrectly constructed, in which case there is no data phase. The sender cannot transmit another command until it receives an accepted or unaccepted response.

    Data

    The receiver of the command sends back a final response, including the task ID, so as to identify the original command, a return value, which could be an indication of success or failure, and possibly some data.

    Associated ALI/R or ADI/R commands may intervene between transmission of a command and receipt of the corresponding final response.

    Since sessions are full-duplex, each endpoint must be prepared both to read and write on a session without blocking for either. For example, if the LCP is sending but the MLM server is not responding and its buffers are full, the LCP must still be prepared to accept incoming data from the MLM server. The only permitted blocking I/O operation is a select() call. This requirement helps reduce the likelihood of deadlocks.

    2.3.4. Protocol Layers

    Figure 2-1, shows OpenVault communication layers, which are described in this section.

    Figure 2-1. Communication Layers


    2.3.4.1. Semantic Layer

    The function of the semantic layer is the same for both ALI and ADI. It is responsible for the following tasks:

    • Implementation of ALI and ADI commands

    • Ack processing, synchronizing commands by ensuring that a command is not sent until an acknowledgment is received for the previous command

    • Ready state processing Section B.3.1 in Appendix B)

    • Response sequencing

      If an ALI or ADI command results in ALI/R or ADI/R commands being sent, in addition to the normal ALI/R or ADI/R responses for acknowledgment and final response, the intervening ALI/R or ADI/R commands should be sent in between the ack and final responses. For example, an activate enable command to a DCP usually results in the series ADIR_reponse for acknowledgment, ADIR_config, ADIR_ready, and finally ADIR_response for final response.

    • Detection and handling of device state changes

      This can range from full asynchronous notification by a device or device controller to a control program to periodic polling of a device by the control program to detect changes. With SCSI, the device raises a unit attention condition, and sends a unit attention notification piggy-backed on a response from the SCSI device, which indicates that some device state has changed. The control program can then send additional SCSI commands to determine what state has changed, and to clear the unit attention condition.

      When the control program detects state changes that affect the control program's ready state or configuration from the MLM server's point of view (for example, the library may have gone offline, or the library contents may have been altered if the library front door was detected to be opened and then closed), then the control program should update ready state and configuration information, as appropriate, and push the new ready state and configuration up to the MLM server.

    2.3.4.2. Parser and Generator Layer

    The parser and generator layer uses the POSIX compliant GNU utilities Bison and Flex, and is responsible for the following tasks:

    • Language version negotiation and session establishment

      The source files involved are ovsrc/include/hello.h and ovsrc/libs/hellor/*.

    • Converting commands between C data structures and ASCII representations

      The ALI source files involved are ovsrc/include/{ali,lcp}.h and ovsrc/libs/ali/*.

      The ADI source files involved are ovsrc/include/{adi,dcp}.h and ovsrc/libs/adi/*.

    2.3.4.3. Over-the-Wire ALI or ADI Layer

    The over-the-wire ALI and ALI/R or ADI and ADI/R layer employs nothing but ASCII strings, and is responsible for the following tasks:

    • Transitioning between command phases (command, ack, data)

    • Conforming to language conventions (the parser enforces this)

    2.3.4.4. OpenVault IPC Layer

    The OpenVault IPC layer is responsible for the following tasks:

    • Providing OpenVault interprocess communication between clients and the server

    • Implementing underlying session connections for OpenVault processes, including the packetization of over-the-wire ASCII commands

    • Authentication

    2.3.4.5. TCP/IP Socket Layer

    The TCP/IP socket layer employs standard networks to aid portability.

    2.3.5. Language Conventions

    All commands are designed so that the basic arguments of the command may be entered in any order. For example, these two commands are equivalent:

    mount slot["#12", "vol.001", "sideA"] drive["DLT2"];
    mount drive["DLT2"] slot["#12", "vol.001", "sideA"];

    OpenVault strings are composed of ASCII characters in the range 32 to 126 (decimal). Strings must be quoted with either a double-quote or single-quote (“ or `) as shown in Example 2-1. OpenVault considers these different quote characters to be identical.

    Example 2-1. Using Quote Characters in Strings

    To include either quote character in a string, precede it with backslash (\). To include a single backslash character in a string, put two backslash characters in a row:

    "This string contains a backslash \\ and a double quote \" character."

    Potential return value types depend on the command issued. In general, when a command is successful, the return value specification is the following:

    response success text [retValue(s)]

    When a command is unsuccessful, the error return value conforms to the following specification:

    response error errorSpec

    Boolean return values are predefined strings “true” and “false”.

    2.4. Convenience Routines for Developers

    The following modules are provided in the source code tree as an aid to LCP and DCP developers:

    • A generic linked list queue in ovsrc/src.GPL/server/include/queue.h

    • A command queuing facility and state machine in ovsrc/src.LGPL/include/cctxt.h and ovsrc/src.LGPL/common/cctxt.c 

    • Shared LCP or DCP data structures and functions in ovsrc/src.LGPL/include/[ld]cp_lib.h and ovsrc/src.BSD/[ld]cp/common/util.c 

      These are intended to provide a basic framework for developing DCPs and LCPs, and also reusable software for common control program operations such as ack, attribute, error, and ready-state processing. This framework will evolve.

    These modules, which are intended as a basic framework for DCP and LCP development, will evolve. They include reusable software for common control program operations such as ack, attribute, error, and ready-state processing.

    LCP and DCP templates are provided to enable developers to start coding. This source code is available as a freely downloadable package: http://www.sgi.com/software/opensource/openvault/

    2.5. Conformance Suites

    An LCP conformance suite is in ovsrc/src.GPL/conformance/lcp, and a DCP conformance suite is in ovsrc/src.GPL/conformance/dcp. Developers should test each LCP and DCP against a conformance suite to assure compliance with OpenVault specifications. Although there is no formal LCP or DCP certification program, this is the next best thing.

    Each conformance suite simulates the MLM server's interaction with an LCP or a DCP, and attempts to find certain logical errors in a control program, such as allowing ejection from an empty slot or unloading of an empty drive. See the respective README files for specific information about running an LCP or DCP conformance suite.