Please enter search query.
Search <book_title>...
Veritas NetBackup™ DataStore SDK Programmer's Guide for XBSA 1.1.0
Last Published:
2021-01-01
Product(s):
NetBackup (9.0.0.1, 9.0)
- Introduction to NetBackup XBSA
- How to set up the SDK
- Using the NetBackup XBSA interface
- NetBackup XBSA data structures
- NetBackup XBSA environment
- XBSA sessions and transactions
- Creating a NetBackup XBSA application
- How to build an XBSA application
- How to run a NetBackup XBSA application
- API reference
- Function calls
- Function specifications
- Type definitions
- Process flow and troubleshooting
- How to use the sample files
- Support and updates
- Appendix A. Register authorized locations
Multiple object restore example
Here is an example of a multiple object restore. Examples of BSAQueryObject and BSAGetObject are included elsewhere in this document, so this example bypasses some of the error handling associated with those calls.
BSA_Handle BsaHandle; BSA_ObjectOwner BsaObjectOwner; BSA_SecurityToken *security_tokenPtr; BSA_DataBlock32 *data_block; BSA_QueryDescriptor *query_desc; BSA_ObjectDescriptor *object_desc; BSA_ObjectDescriptor *object_desc_current; NBBSA_DESCRIPT_LIST *object_list = NULL; NBBSA_DESCRIPT_LIST *object_list_current; BSA_UInt32 EnvBufSz = 512; BSA_UInt32 Size; char *envx[3]; char EnvBuf[512]; char ErrorString[512]; char msg[1024]; char *restore_location; int total_bytes = 0; int status; . . BSAInit(&BsaHandle, security_tokenPtr, &BsaObjectOwner, envx); . . BSABeginTxn(BsaHandle); /* Populate the query descriptor of the object to be searched for. */ query_desc = (BSA_QueryDescriptor *)malloc(sizeof(BSA_QueryDescriptor)); object_desc = (BSA_ObjectDescriptor *)malloc(sizeof(BSA_ObjectDescriptor)); data_block = (BSA_DataBlock32 *)malloc(sizeof(BSA_DataBlock32)); query_desc->copyType = BSA_CopyType_BACKUP; query_desc->objectType = BSA_ObjectType_FILE; query_desc->objectStatus = BSA_ObjectStatus_MOST_RECENT; strcpy(query_desc->objectOwner.bsa_ObjectOwner, "BSA Client"); strcpy(query_desc->objectOwner.app_ObjectOwner, "BSA App"); strcpy(query_desc->objectName.pathName, "/xbsa/sample/object1"); strcpy(query_desc->objectName.objectSpaceName, ""); /* Search for an object matching the query criteria. */ status = BSAQueryObject(BsaHandle, query_desc, object_desc); if (status != BSA_RC_SUCCESS) { /* handle error condition */ } /* Start building the objectList by adding the object descriptor to the list. */ status = NBBSAAddToMultiObjectRestoreList(BsaHandle, &object_list, object_desc); if (status != BSA_RC_SUCCESS) { Size = 512; NBBSAGetErrorString(status, &Size, ErrorString); sprintf(msg, "ERROR: NBBSAAddToMultiObjectRestoreList() failed with error: %s", ErrorString); NBBSALogMsg(BsaHandle, ERROR, msg, " Multiple Object Restore"); BSATerminate(BsaHandle); exit(status); } /* Search for a second object. */ strcpy(query_desc->objectName.pathName, "/xbsa/sample/object2"); status = BSAQueryObject(BsaHandle, query_desc, object_desc); if (status != BSA_RC_SUCCESS) { /* handle error condition */ } /* Add the second object descriptor to the objectList. */ status = NBBSAAddToMultiObjectRestoreList(BsaHandle, &object_list, object_desc); if (status != BSA_RC_SUCCESS) { Size = 512; NBBSAGetErrorString(status, &Size, ErrorString); sprintf(msg, "ERROR: NBBSAAddToMultiObjectRestoreList() failed with error: %s", ErrorString); NBBSALogMsg(BsaHandle, ERROR, msg, " Multiple Object Restore"); BSATerminate(BsaHandle); exit(status); } /* Start the multiple object restore by passing in the object list. The object list * will be evaluated and the restore job will be started. */ status = NBBSAGetMultipleObjects(BsaHandle, object_list); if (status != BSA_RC_SUCCESS) { Size = 512; NBBSAGetErrorString(status, &Size, ErrorString); sprintf(msg, "ERROR: NBBSAGetMultipleObjects () failed with error: %s", ErrorString); NBBSALogMsg(BsaHandle, ERROR, msg, "Multiple Object Restore"); BSATerminate(BsaHandle); exit(status); } /* Create a pointer to the object list in order to keep track of the current object * being restored. A list created by the application could also be used. * Point the object descriptor at the first object */ object_list_current = object_list; object_desc_current = object_list_current->Descriptor; /* Get the first object. */ status = BSAGetObject(BsaHandle, object_desc_current, data_block); if (status != BSA_RC_SUCCESS) { /* handle error condition */ } restore_location = (char *)malloc((EnvBufSz + 1) * sizeof(char)); memset(restore_location, 0x00, EnvBufSz + 1); data_block->bufferLen = EnvBufSz; data_block->bufferPtr = EnvBuf; memset(data_block->bufferPtr, 0x00, EnvBufSz); /* Read data until the end of data. */ while ((status = BSAGetData(BsaHandle, data_block)) == BSA_RC_SUCCESS) { /* Move the retrieved data to where it is to be restored to and * * reset the data_block buffer. */ memcpy(restore_location, data_block->bufferPtr, data_block->numBytes); total_bytes += data_block->numBytes; memset(restore_location, 0x00, EnvBufSz + 1); memset(data_block->bufferPtr, 0x00, EnvBufSz); } if (status == BSA_RC_NO_MORE_DATA) { memcpy(restore_location, data_block->bufferPtr, data_block->numBytes); total_bytes += data_block->numBytes; printf("Total bytes retrieved: %d\n", total_bytes); } else { /* handle error condition */ } /* Done retrieving data for the first object. */ status = BSAEndData(BsaHandle); if (status != BSA_RC_SUCCESS) { /* handle error condition */ } /* Set the object descriptor to the next object in the list. */ object_list_current = object_list_current->next; if (object_list_current == NULL) { /* handle end of objects condition */ } object_desc_current = object_list_current->Descriptor; if (object_desc_current == NULL) { /* handle error condition */ } /* Get the next object. */ status = BSAGetObject(BsaHandle, object_desc_current, data_block); if (status != BSA_RC_SUCCESS) { /* handle error condition */ } restore_location = (char *)malloc((EnvBufSz + 1) * sizeof(char)); memset(restore_location, 0x00, EnvBufSz + 1); data_block->bufferLen = EnvBufSz; data_block->bufferPtr = EnvBuf; memset(data_block->bufferPtr, 0x00, EnvBufSz); /* Read data until the end of data. */ while ((status = BSAGetData(BsaHandle, data_block)) == BSA_RC_SUCCESS) { /* Move the retrieved data to where it is to be restored to and * * reset the data_block buffer. */ memcpy(restore_location, data_block->bufferPtr, data_block->numBytes); total_bytes += data_block->numBytes; memset(restore_location, 0x00, EnvBufSz + 1); memset(data_block->bufferPtr, 0x00, EnvBufSz); } if (status == BSA_RC_NO_MORE_DATA) { memcpy(restore_location, data_block->bufferPtr, data_block->numBytes); total_bytes += data_block->numBytes; printf("Total bytes retrieved: %d\n", total_bytes); } else { /* handle error condition */ } /* Done retrieving data for the second object. */ status = BSAEndData(BsaHandle); if (status != BSA_RC_SUCCESS) { /* handle error condition */ } /* End the multiple object restore transaction. Set any references to objects * in the object list to NULL as the memory associated to the list has been freed. */ status = NBBSAEndGetMultipleObjects(BsaHandle, BSA_Vote_COMMIT, object_list); if (status != BSA_RC_SUCCESS) { Size = 512; NBBSAGetErrorString(status, &Size, ErrorString); sprintf(msg, "ERROR: NBBSAEndGetMultipleObjects() failed with error: %s", ErrorString); NBBSALogMsg(BsaHandle, ERROR, msg, "Multiple Object Restore"); BSATerminate(BsaHandle); exit(status); } object_list_current = NULL; object_desc_current = NULL; /* End the restore transaction. BSA_Vote_COMMIT and BSA_Vote_ABORT are * equivalent as there is nothing to commit or abort for a restore transaction. */ status = BSAEndTxn(BsaHandle, BSA_Vote_COMMIT); if (status != BSA_RC_SUCCESS) { Size = 512; NBBSAGetErrorString(status, &Size, ErrorString); sprintf(msg, "ERROR: BSAEndTxn() failed with error: %s", ErrorString); NBBSALogMsg(BsaHandle, ERROR, msg, " Multiple Object Restore"); BSATerminate(BsaHandle); exit(status); }