示例#1
0
//
// Remove the unit device ID from the list
//
BOOL
CNdasLogicalDevice::RemoveUnitDevice(CNdasUnitDevice& unitDevice)
{
	ximeta::CAutoLock autolock(this);
	DWORD ldSequence = unitDevice.GetLDSequence();

	_ASSERTE(ldSequence < m_logicalDeviceGroup.nUnitDevices);
	if (ldSequence >= m_logicalDeviceGroup.nUnitDevices) {
		DBGPRT_ERR(_FT("Invalid sequence (%d) of the unit device.\n"), ldSequence);
		return FALSE;
	}

	_ASSERTE(&unitDevice == m_pUnitDevices[ldSequence]);
	if (&unitDevice != m_pUnitDevices[ldSequence]) {
		DBGPRT_ERR(_FT("Unit device in sequence (%d) is not occupied.\n"), ldSequence);
		return FALSE;
	}

	m_pUnitDevices[ldSequence]->Release();
	m_pUnitDevices[ldSequence] = NULL;

	//
	// Workaround for Fault-tolerant Mode
	// -> Even if the logical device is incomplete,
	//    Mounted Logical Device Location should be intact
	//    if it is mounted
	//
	if (NDAS_LOGICALDEVICE_STATUS_MOUNT_PENDING == GetStatus() ||
		NDAS_LOGICALDEVICE_STATUS_MOUNTED == GetStatus() ||
		NDAS_LOGICALDEVICE_STATUS_UNMOUNT_PENDING == GetStatus()) 
	{
		--m_nUnitDeviceInstances;
		return TRUE;
	}

	if (IsComplete()) {
		CNdasLogicalDeviceManager* pLdm = pGetNdasLogicalDeviceManager();
		pLdm->UnregisterNdasScsiLocation(m_NdasScsiLocation);
	}

	--m_nUnitDeviceInstances;

	//
	// Deallocation NDAS SCSI Location when the fist unit device is removed
	//
	if (0 == ldSequence) {
		cpDeallocateNdasScsiLocation();
	}

	//
	// Publish Event
	//
	CNdasEventPublisher* pEventPublisher = pGetNdasEventPublisher();
	(VOID) pEventPublisher->LogicalDeviceRelationChanged(m_logicalDeviceId);

	//
	// Set Device Error
	//
	SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_MISSING_MEMBER);

	return TRUE;
}
示例#2
0
//
// Set the unit device ID at a sequence 
// to a unit device member ID list
//
BOOL 
CNdasLogicalDevice::AddUnitDevice(CNdasUnitDevice& unitDevice)
{
	ximeta::CAutoLock autolock(this);
	BOOL fSuccess;

	DWORD ldSequence = unitDevice.GetLDSequence();

	_ASSERTE(ldSequence < m_logicalDeviceGroup.nUnitDevices);
	if (ldSequence >= m_logicalDeviceGroup.nUnitDevices) {
		DBGPRT_ERR(_FT("Invalid sequence (%d) of the unit device.\n"), ldSequence);
		return FALSE;
	}

	_ASSERTE(NULL == m_pUnitDevices[ldSequence]);
	if (NULL != m_pUnitDevices[ldSequence]) {
		DBGPRT_ERR(_FT("Sequence (%d) is already occupied.\n"), ldSequence);
		return FALSE;
	}

	_ASSERTE(NULL == m_pUnitDevices[ldSequence]);
	m_pUnitDevices[ldSequence] = &unitDevice;
	m_pUnitDevices[ldSequence]->AddRef();
	++m_nUnitDeviceInstances;

	_ASSERTE(
		m_nUnitDeviceInstances >= 0 && 
		m_nUnitDeviceInstances <= GetUnitDeviceCount()
		);

	if (m_nUnitDeviceInstances < GetUnitDeviceCount()) {
		SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_MISSING_MEMBER);
	} else {
		SetLastDeviceError(NDAS_LOGICALDEVICE_ERROR_NONE);
	}

	//
	// Allocate NDAS SCSI Location when the first unit device is
	// available
	//
	if (0 == ldSequence) {
		cpAllocateNdasScsiLocation();
	}

	if (IsComplete()) {
		CNdasLogicalDeviceManager* pLdm = pGetNdasLogicalDeviceManager();
		pLdm->RegisterNdasScsiLocation(m_NdasScsiLocation, *this);
	}

	if (IsComplete()) 
	{
		//
		// Reconciliation Support
		//
		BOOL bAlive, bAdapterError;
		fSuccess = ::LsBusCtlQueryNodeAlive(
			m_NdasScsiLocation.SlotNo, 
			&bAlive, 
			&bAdapterError);

		//
		// Reconciliation
		//
		if (fSuccess && bAlive)
		{
			ReconcileFromNdasBus();
		}
	}
	else if (IsComplete() && m_fMountOnReady) 
	{
		//
		// Boot-time Plug In Support
		//

		if ((m_mountOnReadyAccess & GetAllowingAccess()) == 
			m_mountOnReadyAccess)
		{

			(VOID) PlugIn(m_mountOnReadyAccess);

		} else if ((GENERIC_READ & GetAllowingAccess()) && 
			m_fReducedMountOnReadyAccess) 
		{

			(VOID) PlugIn(GENERIC_READ);

		}
	}

	DBGPRT_INFO(_FT("Added %s to Logical Device %s\n"), unitDevice.ToString(), this->ToString());

	CNdasEventPublisher* pEventPublisher = pGetNdasEventPublisher();
	(VOID) pEventPublisher->LogicalDeviceRelationChanged(m_logicalDeviceId);

	return TRUE;
}