PEG_METHOD_EXIT();
}
+////////////////////////////////////////////////////////////////////////////////
+//
+// _beginInstanceTransaction()
+//
+// Creates rollback files to allow an incomplete transaction to be voided.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+void _beginInstanceTransaction(
+ const String& indexFilePath,
+ const String& dataFilePath)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "_beginInstanceTransaction");
+
+ //
+ // Begin the transaction (an incomplete transaction will cause
+ // a rollback the next time an instance-oriented routine is invoked).
+ //
+
+ if (!InstanceIndexFile::beginTransaction(indexFilePath))
+ {
+ PEG_METHOD_EXIT();
+ throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
+ MessageLoaderParms("Repository.CIMRepository.BEGIN_FAILED",
+ "begin failed"));
+ }
+
+ if (!InstanceDataFile::beginTransaction(dataFilePath))
+ {
+ PEG_METHOD_EXIT();
+ throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
+ MessageLoaderParms("Repository.CIMRepository.BEGIN_FAILED",
+ "begin failed"));
+ }
+
+ PEG_METHOD_EXIT();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// _commitInstanceTransaction()
+//
+// Removes the rollback files to complete the transaction.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+void _commitInstanceTransaction(
+ const String& indexFilePath,
+ const String& dataFilePath)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "_commitInstanceTransaction");
+
+ //
+ // Commit the transaction by removing the rollback files.
+ //
+
+ if (!InstanceIndexFile::commitTransaction(indexFilePath))
+ {
+ PEG_METHOD_EXIT();
+ throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
+ MessageLoaderParms("Repository.CIMRepository.COMMIT_FAILED",
+ "commit failed"));
+ }
+
+ if (!InstanceDataFile::commitTransaction(dataFilePath))
+ {
+ PEG_METHOD_EXIT();
+ throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
+ MessageLoaderParms("Repository.CIMRepository.COMMIT_FAILED",
+ "commit failed"));
+ }
+
+ PEG_METHOD_EXIT();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// _rollbackInstanceTransaction()
+//
+// Restores instance index and data files to void an incomplete operation.
+// If there are no rollback files, this method has no effect.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+void _rollbackInstanceTransaction(
+ const String& indexFilePath,
+ const String& dataFilePath)
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY, "_rollbackInstanceTransaction");
+
+ if (!InstanceIndexFile::rollbackTransaction(indexFilePath))
+ {
+ PEG_METHOD_EXIT();
+ throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
+ MessageLoaderParms("Repository.CIMRepository.ROLLBACK_FAILED",
+ "rollback failed"));
+ }
+
+ if (!InstanceDataFile::rollbackTransaction(dataFilePath))
+ {
+ PEG_METHOD_EXIT();
+ throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
+ MessageLoaderParms(
+ "Repository.CIMRepository.ROLLBACK_FAILED",
+ "rollback failed"));
+ }
+
+ PEG_METHOD_EXIT();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// InstanceTransactionHandler
+//
+// This class is used to manage a repository instance transaction. The
+// transaction is started when the class is instantiated, committed when
+// the complete() method is called, and rolled back if the destructor is
+// called without a prior call to complete().
+//
+// The appropriate repository write locks must be owned while an
+// InstanceTransactionHandler instance exists.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+class InstanceTransactionHandler
+{
+public:
+ InstanceTransactionHandler(
+ const String& indexFilePath,
+ const String& dataFilePath)
+ : _indexFilePath(indexFilePath),
+ _dataFilePath(dataFilePath),
+ _isComplete(false)
+ {
+ _rollbackInstanceTransaction(_indexFilePath, _dataFilePath);
+ _beginInstanceTransaction(_indexFilePath, _dataFilePath);
+ }
+
+ ~InstanceTransactionHandler()
+ {
+ if (!_isComplete)
+ {
+ _rollbackInstanceTransaction(_indexFilePath, _dataFilePath);
+ }
+ }
+
+ void complete()
+ {
+ _commitInstanceTransaction(_indexFilePath, _dataFilePath);
+ _isComplete = true;
+ }
+
+private:
+ String _indexFilePath;
+ String _dataFilePath;
+ Boolean _isComplete;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// CIMRepository::_rollbackIncompleteTransactions()
+//
+// Searches for incomplete instance transactions for all classes in all
+// namespaces. Restores instance index and data files to void an
+// incomplete operation. If no incomplete instance transactions are
+// outstanding, this method has no effect.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+void CIMRepository::_rollbackIncompleteTransactions()
+{
+ PEG_METHOD_ENTER(TRC_REPOSITORY,
+ "CIMRepository::_rollbackIncompleteTransactions");
+
+ WriteLock lock(_lock);
+
+ Array<CIMNamespaceName> namespaceNames;
+ _nameSpaceManager.getNameSpaceNames(namespaceNames);
+
+ for (Uint32 i = 0; i < namespaceNames.size(); i++)
+ {
+ Array<CIMName> classNames;
+ _nameSpaceManager.getSubClassNames(
+ namespaceNames[i], CIMName(), true, classNames);
+
+ for (Uint32 j = 0; j < classNames.size(); j++)
+ {
+ //
+ // Get paths of index and data files:
+ //
+
+ String indexFilePath = _getInstanceIndexFilePath(
+ namespaceNames[i], classNames[j]);
+
+ String dataFilePath = _getInstanceDataFilePath(
+ namespaceNames[i], classNames[j]);
+
+ //
+ // Attempt rollback (if there are no rollback files, this will
+ // have no effect). This code is here to rollback uncommitted
+ // changes left over from last time an instance-oriented function
+ // was called.
+ //
+
+ _rollbackInstanceTransaction(indexFilePath, dataFilePath);
+ }
+ }
+
+ PEG_METHOD_EXIT();
+}
+
////////////////////////////////////////////////////////////////////////////////
//
// CIMRepository
_isDefaultInstanceProvider = (ConfigManager::getInstance()->getCurrentValue(
"repositoryIsDefaultInstanceProvider") == "true");
+ _rollbackIncompleteTransactions();
+
PEG_METHOD_EXIT();
}
_isDefaultInstanceProvider = (ConfigManager::getInstance()->getCurrentValue(
"repositoryIsDefaultInstanceProvider") == "true");
+ _rollbackIncompleteTransactions();
+
PEG_METHOD_EXIT();
}
nameSpace, instanceName.getClassName());
//
- // Attempt rollback (if there are no rollback files, this will have no
- // effect). This code is here to rollback uncommitted changes left over
- // from last time an instance-oriented function was called.
+ // Perform the operation in a transaction scope to enable rollback on
+ // failure.
//
- if (!InstanceIndexFile::rollbackTransaction(indexFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "rollback failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.ROLLBACK_FAILED",
- "rollback failed"));
- //l10n end
- }
-
- if (!InstanceDataFile::rollbackTransaction(dataFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "rollback failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.ROLLBACK_FAILED",
- "rollback failed"));
- //l10n end
- }
+ InstanceTransactionHandler transaction(indexFilePath, dataFilePath);
//
// Lookup instance from the index file (raise error if not found).
throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
}
- //
- // Begin the transaction (any return prior to commit will cause
- // a rollback next time an instance-oriented routine is invoked).
- //
-
- if (!InstanceIndexFile::beginTransaction(indexFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "begin failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.BEGIN_FAILED",
- "begin failed"));
- //l10n end
- }
-
- if (!InstanceDataFile::beginTransaction(dataFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "begin failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.BEGIN_FAILED",
- "begin failed"));
- //l10n end
- }
-
//
// Remove entry from index file.
//
//l10n end
}
- //
- // Commit the transaction:
- //
-
- if (!InstanceIndexFile::commitTransaction(indexFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "commit failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.COMMIT_FAILED",
- "commit failed"));
- //l10n end
- }
-
- if (!InstanceDataFile::commitTransaction(dataFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "commit failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.COMMIT_FAILED",
- "commit failed"));
- //l10n end
- }
+ transaction.complete();
//
// Compact the index and data files if the free count max was
String errMessage;
- //
- // Get paths to data and index files:
- //
-
- String dataFilePath = _getInstanceDataFilePath(
- nameSpace, newInstance.getClassName());
-
- String indexFilePath = _getInstanceIndexFilePath(
- nameSpace, newInstance.getClassName());
-
- //
- // Attempt rollback (if there are no rollback files, this will have no
- // effect). This code is here to rollback uncommitted changes left over
- // from last time an instance-oriented function was called.
- //
-
- if (!InstanceIndexFile::rollbackTransaction(indexFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "rollback failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.ROLLBACK_FAILED",
- "rollback failed"));
- //l10n end
- }
-
- if (!InstanceDataFile::rollbackTransaction(dataFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "rollback failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms(
- "Repository.CIMRepository.ROLLBACK_FAILED",
- "rollback failed"));
- //l10n end
- }
-
//
// Resolve the instance. Looks up class and fills out properties but
// not the qualifiers.
_createAssocInstEntries(nameSpace, cimClass, cimInstance, instanceName);
//
- // Begin the transaction (any return prior to commit will cause
- // a rollback next time an instance-oriented routine is invoked).
+ // Get paths to data and index files:
//
- if (!InstanceIndexFile::beginTransaction(indexFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "begin failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.BEGIN_FAILED",
- "begin failed"));
- //l10n end
- }
+ String dataFilePath = _getInstanceDataFilePath(
+ nameSpace, newInstance.getClassName());
- if (!InstanceDataFile::beginTransaction(dataFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "begin failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.BEGIN_FAILED",
- "begin failed"));
- //l10n end
- }
+ String indexFilePath = _getInstanceIndexFilePath(
+ nameSpace, newInstance.getClassName());
+
+ //
+ // Perform the operation in a transaction scope to enable rollback on
+ // failure.
+ //
+
+ InstanceTransactionHandler transaction(indexFilePath, dataFilePath);
//
// Save instance to file:
//l10n end
}
- //
- // Commit the changes:
- //
-
- if (!InstanceIndexFile::commitTransaction(indexFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "commit failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.COMMIT_FAILED",
- "commit failed"));
- //l10n end
- }
-
- if (!InstanceDataFile::commitTransaction(dataFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "commit failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.COMMIT_FAILED",
- "commit failed"));
- //l10n end
- }
+ transaction.complete();
Resolver::resolveInstance (cimInstance, _context, nameSpace, cimClass,
true);
WriteLock lock(_lock);
- //
- // Get paths of index and data files:
- //
-
- const CIMInstance& instance = modifiedInstance;
-
- String indexFilePath = _getInstanceIndexFilePath(
- nameSpace, instance.getClassName());
-
- String dataFilePath = _getInstanceDataFilePath(
- nameSpace, instance.getClassName());
-
- //
- // First attempt rollback:
- //
-
- if (!InstanceIndexFile::rollbackTransaction(indexFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "rollback failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.ROLLBACK_FAILED",
- "rollback failed"));
- //l10n end
- }
-
- if (!InstanceDataFile::rollbackTransaction(dataFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "rollback failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.ROLLBACK_FAILED",
- "rollback failed"));
- //l10n end
- }
-
- //
- // Begin the transaction:
- //
-
- if (!InstanceIndexFile::beginTransaction(indexFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "begin failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.BEGIN_FAILED",
- "begin failed"));
- //l10n end
- }
-
- if (!InstanceDataFile::beginTransaction(dataFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "begin failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.BEGIN_FAILED",
- "begin failed"));
- //l10n end
- }
-
//
// Do this:
//
//l10n end
}
+ //
+ // Get paths of index and data files:
+ //
+
+ String indexFilePath = _getInstanceIndexFilePath(
+ nameSpace, modifiedInstance.getClassName());
+
+ String dataFilePath = _getInstanceDataFilePath(
+ nameSpace, modifiedInstance.getClassName());
+
+ //
+ // Look up the specified instance
+ //
+
Uint32 oldSize;
Uint32 oldIndex;
Uint32 newSize;
throw PEGASUS_CIM_EXCEPTION(CIM_ERR_NOT_FOUND, instanceName.toString());
}
+ //
+ // Perform the operation in a transaction scope to enable rollback on
+ // failure.
+ //
+
+ InstanceTransactionHandler transaction(indexFilePath, dataFilePath);
+
//
// Modify the data file:
//
//l10n end
}
- //
- // Commit the transaction:
- //
-
- if (!InstanceIndexFile::commitTransaction(indexFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "commit failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.COMMIT_FAILED",
- "commit failed"));
- //l10n end
- }
-
- if (!InstanceDataFile::commitTransaction(dataFilePath))
- {
- PEG_METHOD_EXIT();
- //l10n
- //throw PEGASUS_CIM_EXCEPTION(CIM_ERR_FAILED, "commit failed");
- throw PEGASUS_CIM_EXCEPTION_L(CIM_ERR_FAILED,
- MessageLoaderParms("Repository.CIMRepository.COMMIT_FAILED",
- "commit failed"));
- //l10n end
- }
+ transaction.complete();
//
// Compact the index and data files if the free count max was