The Client Application Programming Interface (CAPI) and Administrative Application Programming Interface (AAPI) are languages that OpenVault client and administrative programs use to communicate with the MLM server. CAPI commands are a subset of AAPI commands, which are more powerful.
CAPI and AAPI are based on message passing. OpenVault client and administrative programs communicate with the MLM server through TCP/IP sockets. Only ASCII strings travel across these sockets. The hello-welcome command sequence establishes an IPC connection based on a 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. In some releases, the sender may also use the task ID to cancel the command or to obtain command status.
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 administrative program announces which language it uses, and which versions of the language it understands. The MLM server selects one version and says which one to use for the current session.
The OpenVault session is demarcated by version negotiation (hello and welcome or possibly unwelcome) at the beginning, and close of session (goodbye) at the end.
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. 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.
Application 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.
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, phase sequencing applies to both directions of a session. The phases are as follows:
Associated CAPI/R or AAPI/R commands may intervene between transmission of a command and receipt of the corresponding final response.
Because 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 application is sending but the MLM server is not responding and its buffers are full, the application must remain ready to accept incoming data from the server. The only permitted blocking I/O operation is a select() function call. This requirement helps reduce the likelihood of deadlocks.
Figure 2-1 shows OpenVault communication layers, which are described in this section.
The function of the semantic layer is the same for CAPI and AAPI. It is responsible for the following:
Implementation of CAPI and AAPI commands
Ack processing--synchronizing commands by ensuring that a command is not sent until an acknowledgment is received for the previous command
Response sequencing
Detection and handling of device state changes
The parser and generator layer uses the POSIX compliant GNU utilities bison and flex, and is responsible for the following:
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 source files involved are ovsrc/include/capi.h and ovsrc/libs/{capi,capir}/*.
The over-the-wire CAPI and CAPI/R layer employs nothing but ASCII strings, and is responsible for the following:
Transitioning between command phases (command, ack, data)
Conforming to language conventions (the parser enforces this)
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"] task["1"]; mount drive["DLT2"] slot["#12", "vol.001", "sideA"] task["1"]; |
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 `). 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 task success text [retValue(s)] |
When a command is unsuccessful, the error return value conforms to the following specification:
response task error errorSpec |
Boolean return values are the predefined strings “true” and “false”.
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:
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 OpenVault applications programmer does not need to be concerned about details of the OpenVault database. The MLM server handles database operations triggered by hardware events or by CAPI requests from client applications transparently. Client applications interact with the persistent store through the CAPI language.
CAPI and AAPI use a hybrid of an object attribute interface and procedural commands to accomplish tasks required in a media management system.
The command-response format is semi-asynchronous. After submitting each command, the application waits for the server to acknowledge receiving the command, but need not wait for results before sending the next command. CAPI communications libraries can also work synchronously if this makes implementation more convenient.
During a session, the client sends a command with task ID, and waits for the MLM server to acknowledge receipt of that command. Some time later the MLM server sends the client a response to the command, including the original task ID. The client application can thus determine which response goes with which command. Example 2-2 shows this arrangement (arrows indicate command direction):
Example 2-2. CAPI/AAPI Command Sequence
The client application sends a command to the MLM server:
→ mount task["1"] match [streq(VOLUME."VolumeName" "v1")]; |
The MLM server sends an acknowledgment:
← response task["1"] accepted; |
Some time later, MLM sends a response to the original command:
← response task["1"] success; |
Because the application can determine which response came from the execution of each individual command, the sequence could look something more like this:
→ mount task["1"] match [streq(VOLUME."VolumeName" "v1")]; ← response task["1"] accepted; → attribute task["a43"] match [streq(VOLUME."VolumeName" "v1")] set[VOLUME."Color" "green"]; ← response task["a43"] accepted; ← response task["a43"] success; ← response task["1"] success; |
In this example, the client sent a second command before the first command completed. In fact, the second command completed before the first.
OpenVault defines 27 types of objects that comprise a media environment. Table 2-1, provides a complete list of object types known to OpenVault, the predefined attributes for each object, and a short description of the object type. Applications can add more attributes to any given instance of an object, and can modify the values of most predefined attributes, but may not remove a predefined attribute.
Object Type and | Predefined Attributes | Object Description |
---|---|---|
AI | AIKey AIName ApplicationName Entity | An instance of an application. Holds the security key as well as language and version information for the point-to-point communication link relating to this AI. Used as a storage location for attribute name/value data. For applications, the SELF meta-object resolves to a particular AI. |
APPLICATION | ApplicationName Language | An application. Used as a storage location for attribute name/value data. Declares the language used (either “AAPI” or “CAPI”). For applications, the PARENT meta-object resolves to a particular APPLICATION. |
BAY | BayAccessible BayName LCPName | A physical region of a robot. This is the only specifier of locality or adjacency that is exposed, or indeed known to OpenVault, for slots and drives within a robot. This exists both for efficiency and administrability. |
CARTRIDGE | ApplicationName CartridgeGroupName CartridgeID CartridgeNumberMounts CartridgeNumberVolumes CartridgePCL CartridgeState CartridgeTimeCreated CartridgeTimeMountedLast CartridgeTimeMountedTotal CartridgeTypeName LibraryName | A physical cartridge, for example a DLT cartridge or a 3480 cartridge. A cartridge contains media, which is physically organized into one or more sides. Each side is logically organized as one or more partitions. |
CARTRIDGEGROUP | CartridgeGroupName CartridgeGroupPriority | Data for one of the two permissions-related parts of OpenVault. The other is the DriveGroup abstraction. Each cartridge is in exactly one cartridge group. |
CARTRIDGE GROUP APPLICATION | ApplicationName CartridgeGroupApplicationPriority CartridgeGroupName | Data for one of the two permissions-related parts of OpenVault. The other is the DriveGroup abstraction. Each Cartridge Group Application object shows the relationship between one application and one cartridge group. If and only if there exists a cartridge group application object referencing both the application and the cartridge group, an application can allocate volumes on cartridges in that cartridge group. |
CARTRIDGETYPE | CartridgeTypeMediaLength CartridgeTypeMediaType CartridgeTypeName CartridgeTypeNumberSides SlotTypeName | Particular type of cartridge. This includes the cartridge's media type, media length, number of sides (for a tape, this is always 1), and the name of the type of slot into which this cartridge fits. |
CONNECTION | ConnectionClientHost ConnectionClientPort ConnectionID ConnectionTimeCreated ConnectionTimeLastActive Entity SessionID | Every time a client (an LCP, DCP, CAPI or AAPI client) connects to MLM, the server creates a CONNECTION object that uniquely defines the connection. This object allows request responses to be returned to the requestor, and allows the OpenVault administrator a better view of the running system. |
DCP | DCPHost DCPKey DCPName DCPStateHard DCPStateSoft DriveName Entity | For a drive to function, at least one DCP object is required for that drive. More than one DCP can be used per drive in fault-tolerant configurations. |
Capability DCPCAPABILITY | DCPCapabilityName DCPName | Tag attached to a particular set of simultaneously available capabilities of a drive, as exposed by a particular DCP. For example, in the OpenVault sample source, the EXB-8505 DCP encodes the capabilities {“norewind” “variable_block” “compression”} under the tag named nrvc. |
Capability String DCPCAPABILITYSTRING | DCPCapabilityName DCPCapabilityStringName DCPName | One of these objects for each of the strings listed above in DCPCAPABILITY. Each DCPCAPABILITY can be thought of as a container that holds some number of DCPCAPABILITYSTRING objects. |
DRIVE | BayName CartridgePCL DCPName DriveBroken DriveGroupName DriveLibraryAccessible DriveLibraryOccupied DriveName DriveOnline DriveStateHard DriveStateSoft DriveTimeCreated DriveTimeLastMounted DriveTimeMountedTotal LibraryName
| A device to access the contents of a piece of media. DRIVE refers to the drive, and not to the DCP that controls it. For example, a tape drive, magneto-optical drive, CDROM drive, and so forth. This object is in a one-to-one relationship with the physical pieces of hardware. |
DRIVEGROUP | DriveGroupName DriveGroupUnloadTime | Data for one of the two permissions-related parts of OpenVault. The other is the cartridge group abstraction. Each drive is in exactly one drive group. |
DRIVE GROUP APPLICATION | ApplicationName DriveGroupApplicationPriority DriveGroupApplicationUnloadTime DriveGroupName | Data for one of the two permissions-related parts of OpenVault. The other is the cartridge group abstraction. Each drive is in exactly one drive group. Each Drive Group Application object shows the relationship between one application and one drive group. If and only if there exists a drive group application object referencing both the application and the drive group, an application can mount volumes in drives belonging to that drive group. |
LCP | Entity LCPHost LCPName LCPStateHard LCPStateSoft LibraryName | For a library to function, at least one LCP object is required for that library. More than one LCP can be used per library in certain fault-tolerant configurations. |
LIBRARY | LCPName LibraryBroken LibraryName LibraryOnline LibraryStateHard LibraryStateSoft | This refers to the library, and not the LCP that controls it. A library can be automated (a robotic tape changer) or manual (a person changing tapes). |
MOUNTLOGICAL | ApplicationName DCPCapabilityName DCPName DriveName MountLogicalHandle MountLogicalTimeWhenMounted PartitionName VolumeName | Stored information about a particular logical mount. One MOUNTLOGICAL object is created by MLM for each drive access handle that is returned as the result of a CAPI or AAPI mount request. The object is destroyed during the processing of a CAPI or AAPI unmount request. |
MOUNTPHYSICAL | CartridgeID CartridgePCL DriveName LibraryName MountPhysicalState MountPhysicalTimeWhenMounted SideNumber SlotName | Stored information about a particular physical mount. MLM creates one such object when a cartridge is inserted into a drive, and deletes it when that cartridge is removed. |
PARTITION | CartridgeID PartitionAllocatable PartitionBitFormat PartitionName PartitionNumberMounts PartitionSignature PartitionSize PartitionTimeCreated PartitionTimeMountedLast PartitionTimeMountedTotal SideNumber | A logical subrange of a side. Some tape technologies support multiple partitions per side. For example, a filesystem resides in a disk partition. |
REQUEST | RequestAcceptances RequestID RequestInitiatorSessionID RequestRequest RequestResponderSessionID RequestResponse RequestState RequestTimeAccepted RequestTimeClosed
RequestTimeCreated RequestType | LCPs, DCPs, and CAPI/AAPI clients may request actions by the OpenVault operator. Each request command causes the creation of a REQUEST object in MLM. When the original requestor receives its results, the REQUEST object is deleted. |
SESSION | ApplicationName Language SessionAttached SessionClientHost SessionClientPort SessionID SessionTimeCreated SessionTimeLastActive | Every time a CAPI or AAPI client makes a recognized (authorized) connection to MLM, the server creates a SESSION object. The session name (SessionID) ties the client to other objects in MLM. When a CAPI or AAPI client sends the goodbye command, its session object is destroyed. When a CAPI or AAPI client sends the detach command, its SESSION lives on, but its CONNECTION is destroyed. The session object can be reattached to the client if the client sends an attach command upon reconnection. |
SIDE | CartridgeID SideNumber SideNumberMounts SideTimeCreated SideTimeMountedLast SideTimeMountedTotal | SIDE objects are created automatically at cartridge-creation time. When a cartridge object is created, one of the fields required is CartridgeTypeName. From the CARTRIDGETYPE object, MLM determines the number of sides to make, and creates them. Sides exist as objects so that partitions can be attached to them. |
SLOT | BayName CartridgeID CartridgePCL LCPName SlotAccessible SlotName SlotOccupied SlotTypeName | A position in the library that can hold a cartridge. It may contain a cartridge or it may be empty. |
SLOTCONFIG | BayName LCPName SlotConfigNumberFree SlotConfigNumberTotal SlotTypeName | One or more SLOTCONFIG objects must be declared for each SlotTypeName of each BAY that an LCP declares within a LIBRARY. Each of these objects stores the total number of slots and also the number of free slots of that particular slot type. |
SLOTTYPE | SlotTypeName | The family of SLOTTYPE objects defines the registry of valid slot types that may be used in SlotTypeName fields in various other object types. |
SYSTEM | Administrator | Stored e-mail address of the system administrator, and all the attribute/value pairs that the administrator has attached as annotations to the system as a whole. There is only one SYSTEM object in MLM. |
VOLUME | ApplicationName CartridgeID PartitionName SideNumber VolumeName VolumeNumberMounts VolumeTimeCreated VolumeTimeMountedLast VolumeTimeMountedTotal | An application's view of a partition. There can be zero, one, or many volumes that map to a particular partition. If zero, then no CAPI application can mount that partition. Since AAPI applications can mount partitions and sides as well as volumes, this restriction does not apply. If only one volume exists for a given partition, the partition is owned by a particular application; if more than one volume exists for a given partition, it is shared by several applications. |
The show and attribute commands are used to query the state of an object's attributes and set them, respectively.
Each object has various attributes that either describe its current state or control its behavior. An example of a state attribute is “SlotOccupied”--true if there is a cartridge in the slot and false if there is none. An example of behavior controlling attribute is “LibraryOnline”--if set to false, MLM does not use that library even if everything it requires is available and functioning perfectly (this is an administrative disable switch).
See the OpenVault Infrastructure Programmer's Guide for more information about library and drive hardware and control programs.
OpenVault objects are all related to each other. Some relationships are physical, such as those between cartridges, sides, partitions, and those between libraries, bays, and slots. Some relationships are logical, such as the connection between applications, volumes, and partitions. The system administrator must understand these relationships in order to administer the OpenVault environment effectively.
In addition to objects and their attributes, an administrative application can directly cause some operations to occur. For example, an application can eject a cartridge from a library into an operator's hand.
There is a set of commands in the AAPI language that implement those operations. The objects and the attributes that control them are still active and will influence exactly what happens when one of the operation-oriented commands is executed. For example, the current value of any drive group attributes on the drives in the system will affect an AAPI mount command by influencing which drives are candidates for the mount.
The OpenVault security model is based on both applications and the limitations of the interface to which that application has access. A normal client application has access only to the CAPI interface, with the limitations in control that implies: no visibility of volume namespaces for other applications, read-only access to drive or library attributes, no ability to directly create or destroy objects, and so on. An administrative application has access to the much more powerful AAPI language, implying: read-write access to attributes on any object in the system, and the ability to create and destroy objects.
CAPI client applications are protected from each other, but all AAPI applications share complete access to the entire system. It is expected that in Release 1 of OpenVault only trusted applications will be granted access to the AAPI interface.
AAPI and CAPI commands fall into three basic groupings: session management, device control, and database manipulation.
attach reconnects to a previously established session.
detach disconnects from a session but leaves it running.
goodbye ends a session with the MLM server.
hello initiates a session with the MLM server.
eject pushes a cartridge out of a library into the operator's hand (AAPI only).
inject allows the operator to insert a cartridge into a library (AAPI only).
mount tells the MLM server to provide data access to a volume.
move relocates a cartridge from one slot in a library to another (AAPI only).
reject informs the MLM server that it mounted the wrong volume.
unmount says that volumes are no longer needed for data access.
allocate associates volume names with a cartridge group (AAPI only).
attribute sets attribute-value pairs associated with OpenVault volumes.
create establishes an object in the persistent store (AAPI only).
deallocate disassociates volume names with a cartridge group (AAPI only).
delete removes an object from the persistent store (AAPI only).
forget deletes volumes from the list known to the MLM server (AAPI only).
rename declares a new name for a volume.
show displays information about OpenVault volumes.
The OpenVault character set for strings includes all 7-bit ASCII characters in the decimal value range 32 to 126 (hex 20 to 7E).
Strings must be quoted with either a double-quote (") or single-quote (`) character. OpenVault treats the single quote and double quote characters as identical. To include a double quote or single quote in a string, precede it with a backslash (\). To include one backslash character in a string, put two backslash characters in your string (\\).
All commands are designed so that constituent elements may be entered in any order.
In the syntax summaries below, words in fixed-space font indicate commands, filenames, routines, path names, signals, messages, signals, messages, and programming language structures. Words in italics represent variable entries and words or concepts being defined. Braces enclose optional portions of a command or directive line where order does not matter. Inside braces, vertical bars indicate a choice of only one element. Ellipses (...) indicate that a preceding element can be repeated.
This section describes the AAPI and CAPI commands for session management.
The attach command may reconnect to an earlier session.
The detach command may relinquish a session connection.
The goodbye command severs the connection from an application to the MLM server. The syntax is as follows:
goodbye task["taskID"]; |
Example 2-3 shows the application closing a session, and two possible responses from the MLM server:
→ goodbye task ['1234']; ← response whichtask ['1234'] accepted; ← response whichtask ['1234'] success; |
The hello command initiates a connection from a client or administrative application to the MLM server. The syntax is as follows:
hello { client["cli"] instance ["inst"]language["lang"] versions ["vers"] } |
MLM returns a hello response, either welcome or unwelcome. The syntax is as follows:
welcome version "ver" ; unwelcome { error ["errNum"] | text["errText"] } ... ; |
Example 2-4 shows the MLM server agreeing to talk version 1.1 of AAPI:
→ hello client ['admin'] instance ['fred'] language ['AAPI'] versions ['1.0' '1.1']; ← welcome version ['1.1']; |
Example 2-5 shows the MLM server unwilling to talk version 1.2 or 1.7 of AAPI:
Example 2-5. unwelcome Response
→ hello client ['admin'] instance ['jane'] language ['AAPI'] versions ['1.2' '1.7']; ← unwelcome error ['EBADVERSION'] text ['No Version Supported']; |
This section describes AAPI and CAPI commands for controlling cartridge movement.
The eject command is used by an administrative application when it wants to have a media cartridge pushed out of a library into a human's hand. The syntax is as follows:
eject { task [taskID] match [matchSpec(s)] order [orderSpec(s)] number [number(s)] report [reportSpec] reportMode [modeName]}; |
The match operator must resolve to a library.
Example 2-6 asks the alexandria library to eject the cartridge in slot 24:
Example 2-6. Ejecting a Cartridge
eject match [and( strEQ (LIBRARY."LibraryName" "alexandria") strEQ (SLOT."SlotName" "slot 24"))] task["0"]; |
The inject command is used by an administrative application when it wants to allow the human operator to insert a cartridge into a library. The syntax is as follows:
inject { task [taskID] match [matchSpec(s)] order [orderSpec(s)] number [number(s)] report [reportSpec] reportMode [modeName]}; |
The match operator must resolve to a library.
Example 2-7 requests the alexandria library to accept a new cartridge:
Example 2-7. Injecting a New Cartridge
inject match [strEQ(LIBRARY."LibraryName" "alexandria")] task["0"]; |
The mount command provides data access to one or more volumes, partitions, or sides. Things to be mounted may be explicitly enumerated or may be implicitly declared by a match operator. The syntax is as follows:
mount { mountMode [mountMode] volname [volNameSpec ...] task [taskID] match [matchSpec(s)] order [orderSpec(s)] number [number(s)] report [reportSpec] reportMode [modeName]}; |
See “Semantics of Common Syntactic Elements”, for information about the match, order, number, and report operators.
Table 2-2 lists the tokens that specify different mount modes.
Token | Description |
---|---|
audio | Mount point allows playing audio data from media (often unimplemented). |
compression | Attempts compression of the data stream. |
fixed | Blocks on the media are a fixed size. |
readonly | The mount point allows reading of the media. |
readwrite | The mount point allows writing of the media. |
rewind | Rewinds the media on close of the mount point. |
status | A status-only mount point is also created (in a directory created for the session). |
variable | Blocks on the media are variable sized. |
The following default applies only to the mount command:
mountMode ["read" "write"] |
The following defaults apply to all commands containing a number or reportMode clause:
number [FIRST..LAST] reportMode [value] |
Whether volumes are explicitly or implicitly enumerated, any number of volumes may be specified for mounting. Some volumes must be mounted read-only, others read-write, or an application can specify a preference, if mount mode is not volume dependent.
Example 2-8 mounts volume myVolume-003 for reading and writing:
Example 2-8. Mounting Explicitly Enumerated Volume
mount mountMode ["read" "write"] volname ["myVolume-003"] task["0"]; |
Example 2-9 mounts the first available DLT volume that is less than 60% full for reading and writing (note that percentFull is a user-defined token):
Example 2-9. Mounting Implicitly Enumerated Volume
mount mountMode ["read" "write"] number [FIRST] match [and( strEq (CARTRIDGE."CartridgeTypeName" "DLT") numLe (VOLUME."percentFull" "60")) task["0"]]; |
The move command is used by an administrative application when it wants to have a cartridge moved from one library slot to another. The syntax is as follows:
move { fromslot [slotID] fromPCL [PCL] toslot [slotID] task [taskID] match [matchSpec(s)] order [orderSpec(s)] number [number(s)] report [reportSpec] reportMode [modeName]}; |
Example 2-10 moves the cartridge labeled AB1234 from slot 12 to slot 24 in the library named alexandria if all these objects exist:
Example 2-10. Moving a Cartridge
move match [strEQ(LIBRARY."LibraryName" "alexandria")] fromslot ["slot 12"] fromPCL["AB1234"] toslot["slot 24"] task["0"]; |
![]() | Note: The reject command is not supported in the OpenVault releases 1.x. |
Implemented but currently disabled, this allowed applications to refuse acceptance of OpenVault-assigned volumes. It is unclear whether this should be allowed.
When an application is done accessing a partition, side, or volume, it can use the unmount command to free the drive for use by another application. The unmount command must specify currently mounted volumes, either by enumerating volumes to be unmounted, or by means of a match operation. The thing to be unmounted must be mounted when this command is given. The syntax is as follows:
unmount { volname [volNameSpec ...] task [taskID] match [matchSpec(s)] order [orderSpec(s)] number [number(s)] report [reportSpec] reportMode [modeName]}; |
The unmount command does not immediately unload media--delay is affected by the default unload time specified as drive group attribute (DriveGroupUnloadTime).
Example 2-11 unmounts volume myVolume-003:
Example 2-12 unmounts the two volumes in pool servers that are nearest to full capacity (note that all these VOLUME attributes are user-defined tokens):
Example 2-12. Unmounting Implicitly Enumerated Volume
unmount number[2] order [numHiLo(VOLUME."percentFull")] match [and ( strEq (VOLUME."allFull" "true") strEq (VOLUME."pool" "servers")) task["0"]]; |
This section describes the AAPI and CAPI commands for handling persistent storage.
Unprivileged applications may obtain ownership of cartridges and create new volumes on those cartridges by using the allocate command. When a volume is created, it immediately takes its place next to all other volumes owned by that application. No other non-privileged application can see the new volume or allocate a volume on the same cartridge. The syntax is as follows:
allocate { volname [volNameSpec] ... task [taskID] match [matchSpec(s)] order [orderSpec(s)] number [number(s)] report [reportSpec] reportMode [modeName]}; |
In Example 2-13, OpenVault allocates any convenient volume as the first named Servers:
An administrative application may modify the values of object attributes in OpenVault. The attribute command modifies behavior-controlling object attributes, thus permitting administrative control of the MLM server. The syntax is as follows:
attribute { volname [volNameSpec] ... task [taskID] match [matchSpec(s)] order [=orderSpec(s)]= number [=number(s)]= set [setSpec(s)] unset [unsetSpec(s)] report [reportSpec] reportMode [modeName]}; |
Applications can also use the attribute command to attach or remove non-system-defined attribute-value pairs from objects in the system.
When using the attribute command, the list of objects to operate on is primarily specified using the match element. There are additional elements that can be used to order the list of objects and even to restrict that list to a certain subset.
An application may disassociate attributes that it has associated with an object in exactly the same way it associated them, except that it will use the unset rather than the set operator. Set and unset operators may be freely mixed, but a single attribute command may not contain more than one set or unset operator referencing the same attribute.
![]() | Note: System-defined attributes may not be disassociated from an object. Any attempt to do so returns an error. Example 2-14 and Example 2-15 show how you can use the attribute command. |
Example 2-14. Modifying Values of Object Attributes 1
attribute match [strEQ( VOLUME."VolumeName" "vol001")] set [VOLUME."PartitionName" "PART 2"] task ["0"]; |
Example 2-15. Modifying Values of Object Attributes 2
attribute match [and (strEQ(SLOT."SlotName" "Slot 1") strEQ(SLOT."BayName" BAY."BayName")] set [SLOT."SlotOccupied" "true"] report [BAY."BayName"] task ["0"]; |
Administrative applications may create new objects. Once an object has been created, it immediately takes its place next to all other objects of that type. The syntax is as follows:
create type [tableNameSpec] { set [setSpec] ... task [taskID] match [matchSpec(s)] order [orderSpec(s)] number [number(s)] report [reportSpec] reportMode [modeName]}; |
The application must specify all required attributes for the type of object being created, or the MLM server returns failure. The application may specify additional attributes and values beyond those required.
In Example 2-16, the administrative application creates an object of type LIBRARY named alexandria in group physics but not currently online:
create type [LIBRARY] set [LIBRARY."LibraryName" "alexandria"] set [LIBRARY."Group" "physics"] set [LIBRARY."Online" "false"] task["0"]; |
Applications may delete volumes that they own. The volume immediately disappears-- there is neither a grace period nor an undo operation. Lacking a volume name, that portion of the cartridge is no longer available to the application for mount operations. Non-privileged applications can delete only volumes that they own, but they can do so at any time and with no restrictions. The syntax is as follows:
deallocate { volname [volNameSpec] ... task [taskID] match [matchSpec(s)] order [orderSpec(s)] number [number(s)] report [reportSpec] reportMode [modeName]}; |
In Example 2-17, OpenVault deallocates the volume named Servers.001:
Administrative applications may delete existing objects by using the delete command. Deleted objects disappear immediately--there is neither a grace period nor an undo operation. The syntax is as follows:
delete type [tableNameSpec] { task [taskID] match [matchSpec(s)] order [orderSpec(s)] number [number(s)] report [reportSpec] reportMode [modeName]}; |
Permission to delete an object is subject to the internal consistency constraints of MLM. If the object is still in use or being referenced by other objects, then the delete operation fails. For example, a LIBRARY object may not be deleted until all DRIVE objects for that library have been deleted.
In Example 2-18, the administrative application deletes the LIBRARY object named alexandria previously created:
Example 2-18. Deleting an Object
delete type [LIBRARY] match [strEQ(LIBRARY."LibraryName" "alexandria")] task["0"]; |
An administrative application may delete volumes from the list known to the MLM server, using the forget command. The volumes cannot be in use by any application. The syntax is as follows:
forget { volname [volNameSpec] ... task [taskID] match [matchSpec(s)] ordermm [orderSpec(s)] number [number(s)] reportm [reportSpec] reportModem [modeName]}; |
In Example 2-19, the lack of an application name might cause the MLM server to delete database information for several volumes from different applications:
Example 2-19. Deleting a Volume 1
forget match [strEQ(VOLUME."VolumeName", "servers.001")] task["0"]; |
Example 2-20 is more limiting and thus more realistic:
Example 2-20. Deleting a Volume 2
forget match [and (strEq (APPLICATION."ApplicationName" "deadApp") strEq (CARTRIDGE."CartridgeTypeName" "8mm-112m"))] task["0"]; |
Client applications may rename their own volumes, while administrative applications may rename any volumes, using the rename command. The syntax is as follows:
rename { volname [volNameSpec] volnewname [volNameSpec] task [taskID] match [matchSpec(s)] order [orderSpec(s)] number [number(s)] report [reportSpec] reportMode [modeName]}; |
Because Example 2-21 contains no match component, this command renames all volumes of that name, no matter which application owns the volumes.
The show command displays data from the OpenVault environment to application users, often in ways not directly supported by the MLM server. The syntax is as follows:
show { volname [volNameSpec] ... task [taskID] match [matchSpec(s)] order [orderSpec(s)] number [number(s)] report [reportSpec] reportMode [modeName]}; |
The application may use the match operator to select objects to be operated on, the order operator to specify that the results of the command be ordered in some manner, the number operator to specify that only certain numbers of records be returned, the report operator to specify attributes of the selected objects to be returned, and the reportMode operator to specify how the results should be formatted.
![]() | Caution: Things can change in MLM between show commands or between a show command and a command intended to act on the information returned by show. |
In Example 2-22, OpenVault reports about all drives known to the MLM server:
In Example 2-23, the MLM server selects bay 1 in the library named alexandria, sorts the slot names in ascending order, and reports the names of the first four:
Example 2-23. Showing Slot Names
show match [and (strEQ (LIBRARY."BayName" "bay 1") strEq (LIBRARY."LibraryName" "alexandria"))] order [strLoHi (SLOT."SlotName")] number [1..4] report [SLOT."SlotName"] reportMode [nameValue] task["0"]; |
Several syntactic elements are common to many AAPI and CAPI commands, including match, order, number, report, reportMode, and others. The meaning of each of these elements is constant no matter what the command.
The syntax elements described in the sections below are evaluated in the following order:
Start with the whole object name space as the working set.
Restrict the working set to objects with specified attributes using the match operator.
Sort the working set on values of specified attributes using the order operator.
Select specified ordinal elements from the working set using the number operator.
Display attributes of objects that remain in the working set using the report operator. The reportMode operator influences the report output format.
The sections below provide a description of common AAPI and CAPI syntax elements.
An attribute may be interpolated by referring to its object type and field name. This syntax is used in combination with the match and order operators. The object type is chosen from a predefined list; see Table 2-1. The field name may be predefined or user defined. The object type is all uppercase, while the field name is enclosed in quotes:
OBJECTTYPE."fieldname" |
Example 2-24 reports the physical cartridge labels of all the volumes named servers.001, from all applications shows all on the servers.001 volume:
Example 2-24. Reporting Physical Cartridge Labels
show volname ["servers.001"] report[CARTRIDGE."CartridgePCL"]; |
Example 2-25 reports the name of the library containing the physics1 drive:
Example 2-25. Reporting a Library Name
show match [strEQ(DRIVE."DriveName" "physics1")] report [LIBRARY."LibraryName"]; |
The volname operator restricts the set of volumes to which a command is applied. It is shorthand for a much more complicated match statement as shown in Example 2-26.
Example 2-26. volname to match Comparison
The volname operator is given a list of volume names:
volname ["servers.001" "servers.002" "servers.003" ] |
The following match statement is equivalent to this volname statement.
match [ or( strEQ (VOLUME."VolumeName" "servers.001") strEQ (VOLUME."VolumeName" "servers.002") strEQ (VOLUME."VolumeName" "servers.003") )]; |
![]() | Note: If the volname operator is given, it is illegal to supply a match operator also. |
The match operator restricts the set of objects to which a command is applied. Restriction is accomplished by applying various functions to specified object attributes in order to determine true or false status, which in turn determines membership or exclusion from the working set. As an example, suppose the current working set of volumes and attributes is shown in Table 2-3:
Table 2-3. Current Working Set 1 of Volumes and Attributes
Volume | Group Attribute | Handler Attribute |
---|---|---|
"vol1" | Group="Servers" | Handler="Marge" |
"vol2" | Group="Clients" | Handler="Sam" |
"vol3" | Group="Servers" | Handler="Bill" |
"vol4" | Group="Clients" | Handler="Marge" |
With that working set, Example 2-27 shows the match statement returns vol3 as its result (the Ne in strNe means not equal to):
Roughly translated, the match statement would read: “Find volumes where the Group attribute is set to Servers and the Handler attribute is not set to Marge.” After evaluation, only the volume named vol3 and related objects remain in the working set.
The order operator sorts the set of objects in the working set. It is useful in cases where the application wants to optimize its activities as much as possible.
As an example, suppose the current working set of volumes and attributes is shown in Table 2-4:
Table 2-4. Current Working Set 2 of Volumes and Attributes
Volume | Attribute |
---|---|
“vol1” | percentFull=”40” |
“vol2” | percentFull=”31” |
“vol3” | percentFull=”93” |
“vol4” | percentFull=”11” |
With that working set, this order statement returns vol3 vol1 vol2 vol4 as its result:
order [numHiLo(VOLUME."percentFull")]; |
The number operator declares which elements in the current working set are reported. The elements given after number specify ordinal numbers of items in the work list for further operation. It is possible to specify both single items and ranges of items.
A range is specified by numbers separated by two periods (..) and includes elements at each end of the range. The additional tokens FIRST and LAST refer to the initial and final elements of the work list. Negative numbers are offsets from the end of the work list.
The specification number [1 3 5] means that the first, third, and fifth items from the ordered work list should be used. Specifications number [2..4] and number [2 3 4] are identical. The specification number [FIRST..3 7..-8 -3..LAST] is equivalent to number [1 2 3 7 8 9 14 15 16] if there are 16 elements in the working set.
As an example, suppose the current working set of volumes and attributes is shown in Table 2-5:
Table 2-5. Current Working Set 3 of Volumes and Attributes
Volume | Group Attribute | Handler Attribute |
---|---|---|
"vol1" | Group="Servers" | Handler="Marge" |
"vol2" | Group="Clients" | Handler="Sam" |
"vol3" | Group="Servers" | Handler="Bill" |
"vol4" | Group="Clients" | Handler="Marge" |
Example 2-28 shows the output that is produced by the number and report statements using this working set:
number[2 4] report [VOLUME."group" VOLUME."VolumeName" VOLUME."handler"] text ["Clients" "vol2" "Sam"] text ["Clients" "vol4" "Marge"] |
The report operator declares attributes or attribute values that are to be returned by the current command.
The reportMode operator declares whether the report contains only the “name” of each reported attribute, only the “value” of each attribute, or both (specified as “nameValue”).
As an example, suppose the current working set of volumes and attributes is shown in Table 2-6:
Table 2-6. Current Working Set 4 of Volumes and Attributes
Volume | Group Attribute | Handler Attribute |
---|---|---|
"vol1" | Group="Servers" | Handler="Marge" |
"vol2" | Group="Clients" | Handler="Sam" |
"vol3" | Group="Servers" | Handler="Bill" |
"vol4" | Group="Clients" | Handler="Marge" |
Example 2-29 shows the output produced a report statement and that working set:
report [VOLUME."group" VOLUME."VolumeName" VOLUME."handler"] text ["Servers" "vol1" "Marge"] text ["Clients" "vol2" "Sam"] text ["Servers" "vol3" "Bill"] text ["Clients" "vol4" "Marge"] |
Example 2-30 shows the output produced when a reportMode statement is added:
Example 2-30. reportMode Usage
reportMode [nameValue] text[ text [VOLUME."group" "Servers"] text [VOLUME."VolumeName" "vol1"] text [VOLUME."handler" "Marge"]] text[ text [VOLUME."group" "Clients"] text [VOLUME."VolumeName" "vol2"] text [VOLUME."handler" "Sam"] ] text[ text [VOLUME."group" "Servers"] text [VOLUME."VolumeName" "vol3"] text [VOLUME."handler" "Bill"]] text[ text [VOLUME."group" "Clients"] text [VOLUME."VolumeName" "vol4"] text [VOLUME."handler" "Marge"]] |
The text operator is a general container for lists of character strings or object references. In some contexts, such as the use of this operator in the rename command, the number of and content of strings that can be enclosed by the text operator may be constrained. But usually, command responses are encapsulated in one or more text statements.
Example 2-31 shows use of the text operator in a reject command:
The functions described in this section operate in the context of the CAPI or AAPI match operator. For each possible combination of objects in the system, an expression made up of field references (OBJECT."field") can be evaluated in combination with the following functions. If the expression returns false, the object is not included in the working set for the enclosing operation of the match operator. All functions return either true or false.
isAttr (nameSpec) | |||||||||||||||||
Returns true if the attribute nameSpec is defined on this object, otherwise returns false. | |||||||||||||||||
noAttr (nameSpec) | |||||||||||||||||
Returns false if the attribute nameSpec is defined on this object, otherwise returns true. | |||||||||||||||||
regex ((regExpr) expression) | |||||||||||||||||
Returns true if regular expression regExpr matches expression, otherwise returns false. For regular expression rules, see the regcmp(3G) man page. | |||||||||||||||||
strXX (expression1 expression2) | |||||||||||||||||
Returns true if the defined relationship between the values denoted by expression1 and expression2 is true; otherwise returns false.
Table 2-7. String Comparison Suffixes
| |||||||||||||||||
numXX (value1 value2) | |||||||||||||||||
Returns true if the defined relationship between the values denoted by value1 and value2 is true, otherwise returns false.
| |||||||||||||||||
and (expression ...) | |||||||||||||||||
Returns true if all expressions are true, or false if any expression is false. | |||||||||||||||||
or (expression ...) | |||||||||||||||||
Returns true if any expression is true, or false if all listed expressions are false. |
Example 2-32 and Example 2-33 illustrate AAPI command usage:
Example 2-32. Showing Volume Names
This show command returns the volume names of all volumes that have an attribute called VolumeNumberMounts with a numeric value greater that 10:
show match [ numGt (VOLUME."VolumeNumberMounts" "10")] report [VOLUME."VolumeName"] task ["0"]; |
Example 2-33. Setting an Attribute
This attribute command sets or creates an attribute named CartridgeGroupName with a value of CART 4 on all volumes that have an attribute named CartridgeNumberMounts with numeric value greater than 10 and an attribute named LibraryName with a lib1 value:
attribute match [and (numGt (CARTRIDGE."CartridgeNumberMounts" "10)) strEQ (CARTRIDGE."LibraryName" "Lib1"))] set [ nameValue[CARTRIDGE."CartridgeGroupName" "CART 4"]] task ["0"]; |