Using the Application Program Interface


Using the ADSM X/Open API

This section describes, in a task-oriented fashion, how to use the X/Open Application Program Interface. You should be familiar with this section prior to designing or writing an application that uses the X/Open API.

ADSM's X/Open API supports the functions in XBSA's Data Movement function group. These functions include the following:
BSABeginTxn BSAGetNextQueryObject(1)
BSAChangeToken BSAGetObject
BSACreateObject BSAInit
BSADeleteObject BSAMarkObjectInactive
BSAEndData BSAQueryApiVersion
BSAEndTxn BSAQueryObject
BSAGetData BSASendData
BSAGetEnvironment BSATerminate

In addition, the X/Open API supports the following function:

* BSAResolveLifecycleGroup
	BSAResolveLifecycleGroup

See the X/Open Specification for detailed information on each function.
Note:The following functions are part of XBSA's Data Movement function group, but are not currently implemented in the X/Open API. Calls to these functions return the code BSA_RC_BAD_CALL_SEQUENCE.
	BSACreateObjectF	BSAGetObjectF	BSASetEnvironment

The API package that you receive includes a sample application. Look at the source code for the sample application to see examples of the X/Open API functions in context.

Maintaining Version Control in the API

All APIs have some form of version control, and X/Open is no exception. You must be sure the version of the X/Open API that you use in your application is compatible with the version of the API library that the end users have installed on their workstations.

The first API call issued when using the X/Open API should usually be BSAQueryApiVersion. This call does the following for the application client:

The X/Open API is designed to be upwardly compatible, so that applications written to older versions or releases of the API library will still operate correctly if the end user is running a newer version.

Determining the release of the API library is critical, because some releases may have different memory requirements and data structure definitions. Downward compatibility may be possible on a case-by-case basis, but it is not a design goal to be so. Downward compatibility, if a requirement, is the responsibility of the application client.

The API library and the Trusted Communication Agent module (dsmapitca) must be at the same level.

The BSAQueryApiVersion call returns the version of the API library installed on the end user's workstation. You can then compare the returned value with the version of the X/Open API that the application client was built with.

The version number of the application client's API is hard-coded in the compiled object code as a set of three constants:

   BSA_API_VERSION
   BSA_API_RELEASE
   BSA_API_LEVEL

These constants are defined in the header file custom.h. The application client's API version should usually be less than or equal to the API library installed on the user's system. Any other condition should be entered into with care.

The BSAQueryApiVersion call can be issued at any time, whether the API session has been initialized or not.

Starting and Terminating a Session

ADSM is a session-oriented product, and all activities must be performed within an ADSM session. To start a session, the application invokes the BSAInit call. This call must be performed prior to any other API call except BSAQueryApiVersion. The BSAInit function sets up a session with the ADSM server as indicated in the parameters passed in the call or defined in the options files.

Note that the application client can only register new nodes with an ADSM server if the server has closed registration. If a server has open registration, then any nodes that are already registered with the server will be accepted by the application. However, if a server has open registration and BSAInit tries to register a new node, then the return code BSA_AUTH_FAILURE is generated. Application designers should tell their customers about this requirement so that customers can configure their servers accordingly.

The ObjectOwner fields are particularly important to an ADSM session. BSAObjectOwner is used as the ADSM node name. AppObjectOwner contains the ADSM session owner name. The node name and password are used for session authentication with the ADSM server. The session owner name is used to determine which objects can be accessed during the session.

ADSM has two modes for handling passwords - Prompt and Generate. The mode is set in the PASSWORDACCESS option in the client options file. For Prompt mode, the node/owner/password must be supplied in the call to BSAInit. For Generate mode, the ADSM trusted agent decides on the node and owner name. The password is stored in a file.

If the user's dsm.sys file sets PASSWORDACCESS=Prompt, then the ADSM node and password (security token) must be supplied. The session owner can be whatever name you choose. An empty string for the session owner ([0]='\0') is used to mean the root owner. The application has control of the object owner values.

If the user's dsm.sys file sets PASSWORDACCESS=Generate, then no value can be supplied for BSAObjOwner or AppObjOwner. These fields must be empty strings. The node name used will be the machine name and the session owner will be the login user's name. The security token field is ignored in this situation.

If an application passes node and/or session owner values when the mode is Generate, it gets the return code ADSM_RC_PSWD_GEN. In this case, if your application supports PASSWORDACCESS=Generate, BSAInit must be reissued with empty ObjectOwner fields. If your application requires PASSWORDACCESS=Prompt, then stop and tell the user to change the option in their dsm.sys file.

You should follow BSAInit with a call to BSAGetEnvironment to retrieve the actual node and owner used for the session. If dsm.sys has PASSWORDACCESS=Generate, these values will be node = hostname and owner = login user.

When using PASSWORDACCESS=Generate, the first ADSM session must be initiated by the root user. This is necessary to create the file where the password is stored.

Sessions are terminated by a BSATerminate call. This causes the X/Open API to close any connection with the ADSM server and free all resources associated with this session.
Note:Only one session can be active per invocation of the API. However, applications on UNIX platforms can circumvent this restriction by running with multiple processes, each process owning its own ADSM session.

Application Design Considerations

If the end user has set PASSWORDACCESS=Generate in the client options file, and is not the root user, then the Trusted Communication Agent (dsmapitca) child process is forked to manage the session with the ADSM server. The SIGCLD signal is used during termination. If PASSWORDACCESS=Prompt, no child process is used.

Session Security

ADSM, being a session-based system, has security components that allow applications to initialize sessions in a secure manner. These security measures prohibit unauthorized access to the server and help insure system integrity.

Every session that is started with the server has to go through a sign-on process. This sign-on process requires the use of a password that, when coupled with the node name of the client, insures proper authorization when connecting to the server. The application client is responsible for providing this password to the X/Open API for session initialization.

Passwords have expiration periods associated with them. Thus, if a BSAInit call fails with the password expired return code (BSA_RC_TOKEN_EXPIRED), the password must be updated before the session can be successfully established.

Only the root session owner can change the password. First, issue the BSAInit call with an empty string in the appObjectOwner field. Then, call BSAChangeToken to update the password.

Objects stored in the system also have ownerships associated with them. See the section "Identifying the Object" to understand how an application can take advantage of this to support multi-user applications. The application client is responsible for insuring that security and ownership rules are met once a session is initialized.

Determining the Session Parameters

After BSAInit has been called to start a session, the application can issue a call to BSAGetEnvironment to determine the parameters set for the session. BSAGetEnvironment returns such items as the node, owner, and server names used for the session, and the maximum number of objects that can be created in a single transaction.

The objectOwner.bsaObjectOwner field contains the ADSM node name. This corresponds to the BSAObjOwner field when PASSWORDACCESS is set to Prompt. When PASSWORDACCESS is Generate, this field contains the machine name.

The objectOwner.appObjectOwner field contains the ADSM owner name. This corresponds to the AppObjOwner field when PASSWORDACCESS is Prompt. When PASSWORDACCESS is Generate, this field contains the login name.

The calling application must allocate an array of ADSM_ENV_STRS elements with strings of size BSA_MAX_DESC for the environment output. The application must also allocate an array of character pointers with ADSM_ENV_STRS+1 elements. The extra element is for the NULL termination pointer.

   char *envP[ADSM_ENV_STRS+1];
   char envStrs[ADSM_ENV_STRS] [BSA_MAX_DESC];
   for (i=0; i<ADSM_ENV_STRS; i++)
     envP[i] = envStrs[i];
 
   envP[i] = NULL;
   rc = BSAGetEnvironment(bsaHandle, &objOwner, envP);

The format of the output is:

   envStrs[0] = "DSMSRVR=xxx"
   envStrs[1] = "MAXOBJ=xx"

where:

Associating a Management Class With Objects

One of the key features offered by ADSM is the use of policy (management classes) to define how objects are stored and managed in ADSM storage. A management class is associated with an object when the object is backed up or archived. This management class determines the following:

How frequently objects are backed up
How many versions of the object are retained if backed up
How long to keep archive copies
Where the object is to be inserted in the storage hierarchy on the server

Management classes have two components: a backup copy group and an archive copy group.

A copy group is a set of attributes that define the management policies for an object that is being backed up or archived. Thus, if a backup operation is being performed, the attributes in the backup copy group apply. If an archive is being performed, the attributes in the archive copy group apply.

Because the use of policy is a critical component of ADSM, the API requires that all objects sent to the server first be assigned to a management class. There are two ways to do this:

Note that the backup or archive copy group in a particular management class can be empty or NULL. If an object is bound to the NULL backup copy group, then that object cannot be backed up. If an object is bound to the NULL archive copy group, the object cannot be archived.

The Transaction Model

All data sent to, received from, or deleted from ADSM storage by the X/Open API is done within the bounds of a transaction. This provides a high level of data integrity for the ADSM product, but it does impose some restrictions that an application client must take into consideration.

A transaction is initiated by a call to BSABeginTxn and ended by a call to BSAEndTxn.

A single transaction is an atomic action. Data sent or received within the bounds of a transaction is either all committed at the end of the transaction or all rolled back if the transaction ends prematurely.

ADSM supports the use of only a single operation type within a transaction. For example, you cannot perform both a send and a get operation within the bounds of a single transaction. The one exception is during a get operation, where you precede the get with a query operation.

Transactions can consist of either single objects or multiple objects. Smaller objects should be sent or received in a multiple object transaction. This greatly improves total system performance, because transaction overhead is decreased. The application client determines whether single or multiple transactions are appropriate.

All objects within a multiple object transaction must be sent to or received from the same copy destination. If you need to send an object to or receive it from a different destination than the previous object, you must end the current transaction and start a new one. Within the new transaction, you can send or receive the object to the new copy destination.

ADSM limits the number of objects that can be sent or received in a multiple object transaction. You can find this limit by calling BSAGetEnvironment and examining the MAXOBJ value.

The application client must keep track of the objects sent or received within a transaction in order to perform retry processing or error processing if the transaction is ended prematurely. A transaction can be halted at any time by either the server or the client. Thus, the application client must be prepared to handle sudden transaction ends that it did not initiate.

Querying the ADSM System

The X/Open API allows an application client to query an ADSM server for information on the records stored there. You can define a set of criteria that the records on the server must meet in order to be returned by the query. All query operations must be done within the bounds of a transaction (see "The Transaction Model").

A query operation consists of the following steps:

  1. Issue the BSABeginTxn call to initiate a transaction.

  2. Define the parameters of your query.

    Use the data fields in the QueryDescriptor structure to specify the parameters of your query. Start by setting the copyType field to backup, archive, or any, depending on whether you want to query only backup copies, only archive versions, or both.

    For all queries, you can specify an object name in the objName field, or use wildcard characters to identify a group of objects. For backup queries, use the status field to specify only active or inactive copies, or both. For archive queries, you can specify the description in the desc field and set the upper and lower bounds of the create and expiration times in the fields createTimeLB, createTimeUB, expireTimeLB, and expireTimeUB.

  3. Issue the BSAQueryObject call.

    To start the query operation, issue the BSAQueryObject call, passing in the QueryDescriptor structure. One of the following three codes is returned:

  4. Issue the BSAGetNextQueryObject call.

    If more than one object satisfied the query parameters, then a BSAGetNextQueryObjectcall must be issued to obtain each object after the first. The object descriptor for each object is added to the ObjectDescriptor structure.

    After each object is returned, check the return code. If the BSAGetNextQueryObject call returns the code BSA_RC_MORE_DATA, issue the BSAGetNextQueryObject call again. If there is no more data, go to the next step.

  5. Issue the BSAEndTxn call to end the transaction.

    When all query data has been retrieved or no further query data is desired, the BSAEndTxn call must be issued to end the transaction and terminate the query process. This causes the X/Open API to flush any remaining data from the query stream and release any resources utilized for the query.

Flow Chart

The flow chart for performing query operations is shown in Figure 48.

Figure 48. Flow Chart for Query Operations


REQTEXT


Sending Data to a Server

The X/Open API allows application clients to send data to ADSM server storage. Data can be either backed up or archived. All send operations must be done within the bounds of a transaction (see "The Transaction Model").

The backup component of the ADSM system supports multiple versions of named objects stored on the server. Thus, any object backed up to the server that has the same name as an object already stored on the server from that client is subject to version control. Objects are considered to be in active or inactive states on the server. The latest copy of an object on the server that has not been deactivated is in the active state. Any other object, whether it is an older version or a deactivated copy, is considered to be inactive. Different management criteria are assigned to active and inactive objects on the server as defined by the management class constructs.

The archive component of the ADSM system allows objects to be stored on the server with retention or expiration period controls instead of version control. Each object stored is considered to be unique, even though its name may be the same as an object already archived. This allows an application to archive the same object multiple times, but with different expiration times assigned to each copy of the object.

The value of the COMPRESSION option in the end user's dsm.sys file determines whether ADSM will compress the object during a send operation.

Some types of data (for example, data that is already compressed) may actually get bigger when processed with the compression algorithm. When this happens, the return code ADSM_RC_ERROR is generated and added to the ADSM error log (dsierror.log). If you recognize that this may happen, but want the send operation to continue anyway, tell the end users to specify the following option in their options file before the application runs:

   COMPRESSAlways Yes

A send operation consists of the following steps:

  1. Issue the BSABeginTxn call to initiate a transaction.

  2. Issue the BSAResolveLifecycleGroup call.

    This call is optional. Use it to associate a particular management class with an object that you are storing on the ADSM server. If you don't call BSAResolveLifecycleGroup, a management class is associated with the object during the call to BSACreateObject. For more information, see "Associating a Management Class With Objects".

  3. Issue the BSACreateObject call.

    The BSACreateObject call takes an ObjectDescriptor structure as an input parameter. This structure contains information about the object being stored, such as the object's name and whether it is being backed up or archived.

    The ObjectDescriptor.Owner.bsaObjectOwner value must match the value used on the BSAInit call. The ObjectDescriptor.Owner.appObjectOwner value must also match the one used on the BSAInit call, unless it was an empty string, signifying the session was started with the root owner. In this case the object owner can be any value.

    The sizes of the objInfo and desc fields in the ObjectDescriptor structure are set by ADSM. These sizes are determined by the constants ADSM_MAX_OBJINFO and ADSM_MAX_DESC in the custom.h header file.

    BSACreateObject can also send the first block of data to the ADSM server. If the object has more data, go to the next step. If there is no more data, go to step 5.

  4. Issue the BSASendData call.

    Repeat this call as many times as necessary until the entire object has been sent to the ADSM server.

  5. Issue the BSAEndData call.

    The BSAEndData call signifies there is no more data for a particular object.

  6. If you want to send more than one object to the ADSM server, repeat steps 3 through 5 for each object. Note that all objects sent within the same transaction must be for the same objectspaceName.

    ADSM limits the number of objects that can be sent in one transaction. The limit is determined by the constant MAXOBJ. You can get this value by calling BSAGetEnvironment.

  7. Issue the BSAEndTxn call to end the transaction.

Flow Chart

The flow chart for performing backup or archive operations within a transaction is shown in Figure 49.

Figure 49. Flow Chart for Backup and Archive Operations


REQTEXT


The key feature in this diagram is the loop between the following X/Open API calls from within a transaction:

BSACreateObject
BSASendData
BSAEndData

Receiving Data from a Server

The X/Open API allows application clients to receive data from ADSM storage using the restore and retrieve functions of the product. Restore accesses objects that have previously been backed up, and retrieve accesses objects that have previously been archived.

All restore and retrieve operations must be done within the bounds of a transaction (see "The Transaction Model").
Note:Only the API can restore or retrieve objects that have been backed up or archived with API calls.

Once a session is established with the ADSM server, use the following procedure to restore or retrieve data:

  1. Issue the BSABeginTxn call to initiate a transaction.

  2. Issue the BSAQueryObject call to query the ADSM server for backup or archive data. (This step can be performed outside the transaction.)

    Before beginning a restore or retrieve operation, you query the ADSM server to determine what objects can be received from storage. To issue the query, first fill in the applicable fields in the QueryDescriptor structure with the desired search parameters. Then issue the BSAQueryObject call with the QueryDescriptor.

    If the session was initialized with a NULL owner name, the owner field need not be specified. If the session was initialized with an explicit owner name, then only objects that explicitly have that owner name associated with them are returned.

    The query returns all information in an ObjectDescriptor structure. Different information is returned depending on whether the object was originally backed up or archived. For instance, a query on backup objects returns information on whether an object is active or inactive, while a query on archive objects returns information such as the object descriptions.

    All queries return all information that was originally stored with the object, plus the following:

    copyid
    The copyid provides an 8-byte number that uniquely identifies this object for this node in ADSM storage. Use this ID to request a specific object from storage for restore or retrieve processing.

    restoreOrder
    The restoreOrder provides a mechanism for receiving objects from ADSM storage in the most efficient manner possible. Sort the objects to be restored on this value to insure that tapes are mounted only once and are read from front to back.

    You must retain some or all of the query information for later processing. Retain the copyid and restoreOrder fields because they are needed for the actual restore operation. You must also retain any other information needed to properly open a data file or identify a destination.

  3. Determine the objects to be restored or retrieved from the server.

    Once the backup or archive query has been performed, the application client must determine which objects, if any, are to be restored or retrieved.

  4. If more than one object is selected, sort the objects on the restore order field.

    Once the objects to restore or retrieve are selected, they must be sorted in ascending order (low to high) by the restoreOrder field. This sorting is critical to the performance of the restore operation. Sorting the objects on the restoreOrder field means that the data is read from the server in the most efficient order. Thus, all data on disk is restored first, followed by data on media classes that require volume mounts (such as tape). The restoreOrder field also insures that data on tape is read in order with processing starting at the front of a tape and progressing towards the end.

    Properly sorting on the restoreOrder field means that duplicate tape mounts and unnecessary tape rewinds do not occur.

  5. Issue the BSAGetObject call.

    The BSAGetObject call uses the copyType and copyid fields of the ObjectDescriptor to begin obtaining the first object from the system. The call begins a restore or retrieve operation by identifying the object being requested from the data stream.

    BSAGetObject obtains the first block of data associated with the object. If the object has more data, go to the next step. If the return code is BSA_RC_NO_MORE_DATA, go to step 7.

  6. Issue the BSAGetData call.

    Repeat this call as many times as necessary until the entire object has been received from the ADSM server.

  7. Issue the BSAEndData call.

    The BSAEndData call signifies there is no more data for a particular object.

  8. If you want to receive more than one object from the ADSM server, repeat steps 5 through 7 for each object.

  9. Issue the BSAEndTxn call to end the transaction.

    After all data for all requested objects has been received, the BSAEndTxn call must be issued. You can also use this call to discard any remaining data in the restore stream for objects not yet received.

Flow Chart

The flow chart for performing restore or retrieve operations is shown in Figure 50.

Figure 50. Flow Chart for Restore and Retrieve Operations


REQTEXT


Deleting Objects from the Server

X/Open API applications can issue calls to either delete objects that have been archived or deactivate objects that have been backed up. The former is dependent on the node authorization given when the node was registered by an ADSM administrator. Administrators can specify whether nodes can delete archive objects.

The BSADeleteObject call is used for deleting archive objects and the BSAMarkObjectInactive call is used for deactivating backup objects.

When deleting an archive object, the object is marked in ADSM storage for deletion when the system next performs its object expiration cycle. Once an archive object is deleted from the server, it cannot be retrieved.

When deactivating a backup object on the ADSM server, the object moves from an active state to an inactive state. These states have different retention policies associated with them based on the management class assigned.

Note that a call to BSAMarkObjectInactive affects all objects with the same objType and the same name.

A call to BSADeleteObject or to BSAMarkObjectInactive is always issued within the bounds of a transaction. The flow charts in Figure 51 show how a call to BSADeleteObject or BSAMarkObjectInactive is preceded by a call to BSABeginTxn and followed by a call to BSAEndTxn.

Figure 51. Flow Charts for Delete Archive (left) and Deactivate Backup (right) Operations


REQTEXT


Identifying the Object

The ADSM server can be viewed as an object storage server whose main goal is to efficiently store and retrieve named objects. The server has two main storage areas to meet this requirement:

Each object stored on the server has a name associated with it. The client controls the following key components of the name:

Object space name
Pathname
Object type

When making decisions about naming objects for an application, keep in mind that it may be necessary to externalize the full object names to the end user. Specifically, the end user may need to specify the object in an Include or Exclude statement when the application is run.

Object Space Name

One of the most critical components of the name is the object space name. This name can be viewed as the name of a file system or disk drive, or any other high-level qualifier that groups related data together. ADSM uses the object space to identify the file system or disk drive the data is located on. Thus, actions can be performed on all entities within an object space with relative ease, such as querying all objects within a specified object space.

The ADSM server also has administrative commands to query the object spaces on a given node in ADSM storage, and delete them if necessary. Thus, all data stored by the application client must have an object space name associated with it. Choose the name carefully to group like data together in the system.

An application client should choose different object space names than the file system names a backup-archive client would use, in order to avoid possible interference. The application client should publish its object space names, so that end users can identify the objects for Include and Exclude statements, if necessary.

Pathnames

Another component of the object name is the pathname. The pathname consists of the directory path the object belongs in, and the actual name of the object in that directory path. When the object space name and pathname are concatenated, they must form a syntactically correct name on the operating system the client is running on. The name does not have to exist as an object on the system or bear any relation to the actual data on the local file system, but the name must meet the standard naming rules in order to be properly processed for management classes.

Object Type

The object type identifies the object as either a file or a directory. A file is an object that contains both attributes and binary data. A directory is an object that contains only attributes.

ADSM also accepts the value BSAObjectType_DATABASE, but treats it as BSAObjectType_FILE.

Example

The following example demonstrates what the application client would code on a UNIX platform:

   /myobjspace/pathname

Setting the Owner Name

Each object has an owner name associated with it. The rules governing what objects can be accessed depend on what owner name is used when a session is initialized. This object owner value can be used to control access to the object.

If a session is initialized with an empty string for the owner, that session owner is treated with session (or root) authority. This session can perform any action on any object owned by this node regardless of the actual owner of that object. The session owner is set during the call to BSAInit in the AppObjectOwner field of the ObjectOwner structure.

If a session is initialized with a specific owner name, the session can only perform actions on objects that have that owner name associated with them. Thus, backups or archives into the system all must have this owner name associated with them. Also, any queries performed only return values that have this owner name associated with them. The object owner value is set during the BSACreateObject call in the Owner field of the ObjectDescriptor structure.

Figure 52 summarizes the conditions under which a user has access to an object.

Figure 52. Summary of user access to objects
Session owner Object owner User access?
" " (empty string) (root, system owner) " " (empty string) Yes
" " (empty string) (root, system owner) specific name Yes
specific name " " (empty string) No
specific name same name Yes
specific name different name No

Determining Size Limits

Certain data structures or fields in the X/Open API have size limitations. These structures are often names or other text fields that cannot exceed a predetermined length. Examples of fields with such limits are:

Archive description
Copy group destination
Copy group name
Object information size
Object owner name
Path name length
Password

These limits are defined as constants within the header files custom.h and xbsa.h. Any storage allocation should be based on these constants instead of hard-coded numbers. Refer to the header files for further information and a list of the current constants.


Footnotes:

(1) In the X/Open Specification, BSAGetNextQueryObject was accidentally omitted from the list of functions in XBSA's Data Movement function group.


[ Top of Page | Previous Page | Next Page | Table of Contents | Index ]