Creates a data set handle for the data set that is to be restored.
#include <smsutapi.h> #include <smstsapi.h> CCODE NWSMTSOpenDataSetForRestore ( UINT32 connection, UINT32 parentHandle, NWSM_DATA_SET_NAME_LIST *newDataSetName, UINT32 mode, UINT32 *dataSetHandle);
(IN) Specifies the connection information returned by NWSMTSConnectToTargetService or NWSMTSConnectToTargetServicEx.
(IN) Specifies the data set handle returned by NWSMTSOpenDataSetForRestore.
(IN) Points to the data set's new name and location.
(IN) Specifies the open modes to apply.
(OUT) Points to a data set handle to use when calling NWSMTSWriteDataSet, NWSMTSCloseDataSet, and NWSMTSSetArchiveStatus.
See Section 9.3, Target Service Return Values for more information.
The following table lists the return values associated with the function.
To build newDataSetName the “Data Set Name Functions” listed in Storage Management Services Library can be used.
NWSMTSOpenDataSetForRestore validates the data set handle (if it has access to the data) and renames or moves the data set to a new location.
NWSMTSOpenDataSetForRestore requires that the combination of parentHandle, newDataSetName, and the path information contained in the data set's data form a fully qualified path. If parentHandle is used, the path information in newDataSetName and in the data set's data is ignored (except the terminal node). If newDataSetName is used, the path information in the data set's data is ignored.
If the original name of the data set is to be kept, newDataSetName must be set to NULL.
If a parent is not needed, the engine must set parentHandle to zero. If parent handles are used, the handles must remain open until all subordinate data sets are restored.
parentHandle is like a pointer to a location in the file system tree. It is used to restore immediate children and parents (subdirectories) of the parent referenced by the handle. Parent handles are used when Target Services has a hierarchical file system and supports the use of parent handles. For example, NDS is a Target Service with a hierarchical file system that does not support the use of parent handles.
NOTE:NWSMTSGetUnsupportedOptions must be called to see if the TSA supports renaming and moving of data set during a restore session.
newDataSetName must contain a fully qualified path if parentHandle is zero. If parentHandle is used, only the terminal node in newDataSetName is used.
NOTE:The data set's path information will automatically be placed into the data set's data by the TSA.
The following table shows when and how to use newDataSetName, parentHandle, and the path information contained in the data set data. The newDataSetName column indicates the contents of the data set name parameter and what portion of it is used. The parentHandle column indicates if a parent handle is passed to the function and if it points to a new location. The third column indicates the contents of the path information in the data set's data and how much of it is used. The first seven rows are used if the data set is renamed or moved. The last four rows are used if the data set's original name is used and newDataSetName is NULL. In rows five and six, parentHandle points to a new location. In rows nine and ten, it points to the data set's original location.
The open modes are used by NWSMTSWriteDataSet to determine how to write the data set (see Section 9.2, Target Services Generic Open Mode Values).
NWSMTSCloseDataSet, NWSMTSOpenDataSetForRestore, NWSMTSSetRestoreOptions, NWSMTSWriteDataSet
/*This example uses a log file built by the engine from information of a previous backup session to restore the data sets. The log file is used to get the names of the data set, find out if it is a parent, and build the path to the data set and contains the information from the NWSM_SCAN_INFORMATION and NWSM_DATA_SET_NAME_LIST structures. All parents were backed up with full paths and children were backed with no path information. All children of a parent were backed up before the next parent was scanned. Only one data set existed per transfer buffer.*/ #include <smsutapi.h> #include <smstsapi.h> UINT32 parentHandle = 0, mode = NWSM_OVERWRITE_DATA_SET, dataSetHandle, maxTransferBufferSize, transferBufferSize; /* For more informationabout maxTransferBufferSize and transferBufferDataOffset see NWSMSDSessionOpenForWriting in Storage Management Services Device Interface. */ NWBOOLEAN checkCRC = TRUE, dontCheckSelectionList = TRUE; BUFFERPTR transferBuffer; NWSM_RECORD_HEADER_INFO recordHeaderInfo = {0}; /* Connect to a TSA and Target Service. */ /* Build the lists to display to the user for selection including getting information about the Target Service type, unsupported options, name space information, primary resource list, open modes, scan types, and selection type. See NWSMSTGetTargetServiceType, NWSMTSGetUnsupportedOptions, NWSMTSListSupportedNameSpaces, NWSMTSListTSResources, NWSMTSGetOpenModeOptionString, NWSMTSGetTargetScanTypeString, and NWSMTSGetTargetSelectionTypeStr.*/ /* Connect to SMS DI. Subjugate a device and media, and mount the media. See document Storage Device API. */ /* Have the user choose a session to restore. After the log is chosen and opened, match the media information in the log file against the one on the media to verify that we have the correct session. */ /* Rewind the media, match the session information against the one on the media, and open the session for reading by using NWSMSDMediaPosition and NWSMSDSessionOpenForReading. maxTransferBufferSize and transferBufferDataOffset is set by the last function. */ /* Display the lists previously built to the user for selection and specification. After the selections are made, package the user's restore selections into selectionList and notify the TSA what data sets to restore by calling NWSMTSSetRestoreOptions. mode is set during this user interaction. */ NWSMTSSetRestoreOptions(connection, checkCRC, dontCheckSelectionList, selectionList); /* Retrieve the selected data sets and restore them. */ while(1) { /* Check if the first data set in the log file is to be restored. First, from the information in the log construct a full path for a data set by using NWSMPutFirstName and NWSMPutNextName. The full path is put into newDataSetName. isParent is set from the parentFlag field of the scan information kept in the log file. */ if(no more data sets) break; if (NWSMTSIsDataSetExcluded(connection, isParent, newDataSetName) == NWSMTS_DATA_SET_EXCLUDED) cntinue; /* We found a data set to restore. Move the media to the data set's address, as indicated by the log file, and read the transfer buffer from the media. NWSMSDMediaPosition and NWSMSDSessionReadData can be used. */ if (no transfer buffers) break; /*Set up transfer buffer information. */ transferBuffer = Transfer Buffer from the media; transferBuffer += transferBufferDataOffset; /* Point to the Data Set Header or Subheader. */ transferBufferSize = maxTransferBufferSize - transferBufferDataOffset; /* Extract the SIDF data from the transfer buffer. Only one SIDF data set per transfer buffer exists and each data set wholly occupies one transfer buffer. First, move the transfer buffer pointer to the first record. */ while (transferBufferSize) /* While there is data in the Transfer Buffer. */ { /*Get the next data set header or subheader from the Transfer Buffer. */ NWSMGetRecordHeaderOnly(&transferBuffer, &transferBufferSize, &recordHeaderInfo); /* If we have a record or subrecord, get the data from the Transfer Buffer. Notice that the second part of the if statement will be true if we have gone through the loop more than once (NWSMGetDataSetInfo sets recordHeaderInfo.dataSetInfoRetrieved to DATA_SET_INFO_SPANNED). */ if ((recordHeaderInfo.dataSetInfoRetrieved == DATA_SET_INFO_NOT_STARTED) || (recordHeaderInfo.dataSetInfoRetrieved == DATA_SET_INFO_SPANNED)) NWSMGetDataSetInfo(&tranferBuffer, &transferBufferSize, &recordHeaderInfo); if (!transferBufferSize) break; /* All data retrieved from current Transfer Buffer. Break and get the next Transfer Buffer. */ if (recordHeaderInfo.dataSetInfoRetrieved == DATA_SET_INFO_COMPLETE) { /* Data in recordHeaderInof.dataSetName and recordHeaderInfo.scanInformation can now be used. */ /* Restore the data set. Because of the way the data sets were backed up, we need to use the parent handle to restore children. No parent handles are needed for parents, because they contain full path information. */ if (recordHeaderInfo.scanInformation->parentFlag) { if (parentHandle) /* Close existing parent handle. */ NWSMTSCloseDataSet(connection, &parentHandle); NWSMTSOpenDataSetForRestore(connection, 0, NULL, mode, &parentHandle); dataSetHandle = 0; } else /* We have a child. */ { NWSMTSOpenDataSetForRestore(connection, parentHandle, NULL, mode, &dataSetHandle); } /* Now write the data to Target Service. */ NWSMTSWriteDataSet(connection, dataSetHandle ? dataSetHandle : parentHandle, recordHeaderInfo.recordSize, transferBuffer); /* Close the data set. */ NWSMTSCloseDataSet(connection, &dataSetHandle); } /* end if DATA_SET_INFO_COMPLETE */ /* Update the buffer's information. */ transferBuffer += recordHeaderInfo.recordSize; transferBufferSize -= recordHeaderInfo.recordSize; } /* end while(transferBufferSize) */ } /* end while(1) */ free(recordHeaderInfo.scanInformation); free(recordHeaderInfo.dataSetName);