void CDspVmAutoTaskManagerBase::Init()
{
	WRITE_TRACE( DBG_DEBUG, "Initializing %s manager", getManagerName() );

	QMultiHash<QString , SmartPtr<CVmConfiguration> > hashAllVms
		= CDspService::instance()->getVmDirHelper().getAllVmList();

	QMultiHash<QString , SmartPtr<CVmConfiguration> >::iterator it;
	for(it = hashAllVms.begin(); it != hashAllVms.end(); ++it)
	{
		SmartPtr<CVmConfiguration> pVmConfig = it.value();
		PRL_ASSERT(pVmConfig);

		if (isEnabled(pVmConfig, true))
		{
			PRL_RESULT res = tryToRegisterVm(pVmConfig, it.key());
			if (PRL_FAILED(res))
				WRITE_TRACE(DBG_FATAL,
					"Can't register VM %s in Auto-task Manager during starting dispetcher."
					"Error: 0x%x, (%s).",
					QSTR2UTF8(pVmConfig->getVmIdentification()->getVmUuid()),
					res, PRL_RESULT_TO_STRING(res) );
		}
	}

	m_bInitialized = true;
}
PRL_RESULT Task_VzManager::delete_env()
{
	PRL_RESULT res, ret;

	CProtoCommandPtr pCmd = CProtoSerializer::ParseCommand( getRequestPackage() );
	if (!pCmd->IsValid())
		return PRL_ERR_UNRECOGNIZED_REQUEST;

	CProtoVmDeleteCommand * pDeleteCmd = CProtoSerializer::CastToProtoCommand<CProtoVmDeleteCommand>(pCmd);
	QString sUuid = pDeleteCmd->GetVmUuid();

	VIRTUAL_MACHINE_STATE nState;
	res = getVzHelper()->getVzlibHelper().get_env_status(sUuid, nState);
	if (PRL_FAILED(res))
		return res;

	if (nState == VMS_MOUNTED) {
		res = get_op_helper()->umount_env(sUuid);
		if (PRL_FAILED(res))
			return res;
	}

	res = check_env_state(PVE::DspCmdDirVmDelete, sUuid);
	if (PRL_FAILED(res))
		return res;

	SmartPtr<CVmConfiguration> pConfig = getVzHelper()->getCtConfig(getClient(), sUuid);
	if (!pConfig)
		return PRL_ERR_VM_GET_CONFIG_FAILED;

	QString vm_uuid = pConfig->getVmIdentification()->getVmUuid();
	QString vm_name = pConfig->getVmIdentification()->getVmName();
	QString vm_home = pConfig->getVmIdentification()->getHomePath();

	CVmDirectory::TemporaryCatalogueItem vmInfo( vm_uuid, vm_home, vm_name);

	res = CDspService::instance()->getVmDirManager()
			.lockExclusiveVmParameters(m_sVzDirUuid, &vmInfo);
	if (PRL_SUCCEEDED(res)) {
		Backup::Device::Service(pConfig).teardown();

		res = get_op_helper()->delete_env(sUuid);
		if (PRL_SUCCEEDED(res)) {
			// FIXME: rollback operation
			ret = CDspService::instance()->getVmDirHelper()
					.deleteVmDirectoryItem(m_sVzDirUuid, vm_uuid);
			if (PRL_FAILED(ret) && ret != PRL_ERR_ENTRY_DOES_NOT_EXIST)
				WRITE_TRACE(DBG_FATAL, "Can't delete Container %s from VmDirectory by error: %s",
						QSTR2UTF8(vm_uuid), PRL_RESULT_TO_STRING(ret) );
		}

		// delete temporary registration
		CDspService::instance()->getVmDirManager()
			.unlockExclusiveVmParameters(m_sVzDirUuid, &vmInfo);
	}

	return res;
}
void Task_VzStateMonitor::processUnregisterEvt(const QString &sUuid)
{
	PRL_RESULT res;

	res = CDspService::instance()->getVmDirHelper().deleteVmDirectoryItem(m_sVzDirUuid, sUuid);
	if (PRL_FAILED(res))
		WRITE_TRACE(DBG_FATAL, ">>> Can't delete Ct %s from VmDirectory by error %#x, %s",
				QSTR2UTF8(sUuid), res, PRL_RESULT_TO_STRING( res) );
}
PRL_RESULT Task_VzManager::unregister_env()
{
	PRL_RESULT res, ret;

	CProtoCommandPtr cmd = CProtoSerializer::ParseCommand( getRequestPackage() );
	if ( ! cmd->IsValid() )
		return PRL_ERR_UNRECOGNIZED_REQUEST;

	QString uuid = cmd->GetVmUuid();

	// Check state
	res = check_env_state(PVE::DspCmdDirUnregVm, uuid);
	if (PRL_FAILED(res))
		return res;

	SmartPtr<CVmConfiguration> pConfig = getVzHelper()->getCtConfig(getClient(), uuid);
	if (!pConfig)
		return PRL_ERR_VM_GET_CONFIG_FAILED;

	QString vm_name = pConfig->getVmIdentification()->getVmName();
	QString vm_home = pConfig->getVmIdentification()->getHomePath();

	// Lock by vm_uuid/vm_name/vm_home triade
	CVmDirectory::TemporaryCatalogueItem vmInfo(uuid, vm_home, vm_name);
	res = CDspService::instance()->getVmDirManager()
			.lockExclusiveVmParameters(m_sVzDirUuid, &vmInfo);
	if (PRL_SUCCEEDED(res)) {
		res = get_op_helper()->unregister_env(uuid, 0);
		if (PRL_SUCCEEDED(res)) {
			Backup::Device::Service(pConfig).disable();

			ret = CDspService::instance()->getVmDirHelper()
						.deleteVmDirectoryItem(m_sVzDirUuid, uuid);
			if (PRL_FAILED(ret) && ret != PRL_ERR_ENTRY_DOES_NOT_EXIST)
				WRITE_TRACE(DBG_FATAL, "Can't delete Container %s from VmDirectory by error: %s",
						QSTR2UTF8(uuid), PRL_RESULT_TO_STRING(ret) );
		}
		// delete temporary registration
		CDspService::instance()->getVmDirManager()
			.unlockExclusiveVmParameters(m_sVzDirUuid, &vmInfo);
	}

	return res;
}
PRL_RESULT CDspDispConfigGuard::saveConfig( const QString& path, bool bNoSaveNetwork )
{
	CDspLockedPointer<CDispatcherConfig> pLockedDispConfig = getDispConfig();
	CDispNetworkPreferences*
		pNetwork = pLockedDispConfig->getDispatcherSettings()
						->getCommonPreferences()->getNetworkPreferences();
	CDispLockedOperationsList*
		pLockedOperationsList = pLockedDispConfig->getDispatcherSettings()->getCommonPreferences()
				->getLockedOperationsList();

	bool oldFlg = pNetwork->getNoSaveFlag();
	pNetwork->setNoSaveFlag( bNoSaveNetwork );

	// patch to not save operations with confirmation
	// #436109 ( we store this values in vmdirectory list to prevent deadlock in CDspAccessManager::checkAccess() )
	QList<PRL_ALLOWED_VM_COMMAND> confirmList = pLockedOperationsList->getLockedOperations();
	pLockedOperationsList->setLockedOperations( );

	CDispBackupSourcePreferences *pBackup = pLockedDispConfig->getDispatcherSettings()
						->getCommonPreferences()->getBackupSourcePreferences();
	pBackup->setSave(false);

	PRL_RESULT save_rc = pLockedDispConfig->saveToFile( path );

	pBackup->setSave(true);
	pNetwork->setNoSaveFlag( oldFlg );
	pLockedOperationsList->setLockedOperations( confirmList );

	if( PRL_FAILED(save_rc) )
	{
		WRITE_TRACE(DBG_FATAL, "Error %s on save dispatcher config. Reason: %ld: %s. path = '%s'"
			, PRL_RESULT_TO_STRING(save_rc)
			, Prl::GetLastError()
			, QSTR2UTF8( Prl::GetLastErrorAsString() )
			, QSTR2UTF8( path )
			);
		return PRL_ERR_DISP_CONFIG_WRITE_ERR;
	}

	return PRL_ERR_SUCCESS;
}
PRL_RESULT Task_MigrateCtSource::migrateStoppedCt()
{
	PRL_RESULT nRetCode = PRL_ERR_SUCCESS;
	int i;
	QList<QPair<QFileInfo, QString> > dList;
	QList<QPair<QFileInfo, QString> > fList;

	if ( !(m_nReservedFlags & PVM_DONT_COPY_VM) )
		/* get full directories and files lists for migration */
		if ((nRetCode = GetEntryLists(m_sVmHomePath, dList, fList)) != PRL_ERR_SUCCESS)
			return nRetCode;

	if (PRL_FAILED(nRetCode = SendStartRequest()))
		return nRetCode;

	/* calculate total transaction size */
	for (i = 0; i < fList.size(); ++i)
		m_nTotalSize += fList.at(i).first.size();

	m_pSender = SmartPtr<CVmFileListCopySender>(new CVmFileListCopySenderClient(m_pIoClient));
	m_pVmCopySource = SmartPtr<CVmFileListCopySource>(
			new CVmFileListCopySource(
				m_pSender.getImpl(),
				m_pVmConfig->getVmIdentification()->getVmUuid(),
				m_sVmHomePath,
				m_nTotalSize,
				getLastError(),
				m_nTimeout));
	m_pVmCopySource->SetRequest(getRequestPackage());
	m_pVmCopySource->SetVmDirectoryUuid(m_sVzDirUuid);
	m_pVmCopySource->SetProgressNotifySender(NotifyClientsWithProgress);

	nRetCode = m_pVmCopySource->Copy(dList, fList);
	if (PRL_FAILED(nRetCode))
		WRITE_TRACE(DBG_FATAL, "Error occurred while migration with code [%#x][%s]",
			nRetCode, PRL_RESULT_TO_STRING(nRetCode));

	return nRetCode;
}
bool SimpleServerWrapper::Logoff()
{
	m_isLocalAdminInited = false;

	SdkHandleWrap hJob(PrlSrv_Logoff(m_ServerHandle));
	if (PRL_SUCCEEDED(PrlJob_Wait(hJob, PRL_JOB_WAIT_TIMEOUT)))
	{
		PRL_RESULT nRetCode = PRL_ERR_UNINITIALIZED;
		if (PRL_SUCCEEDED(PrlJob_GetRetCode(hJob, &nRetCode)))
		{
			if (PRL_SUCCEEDED(nRetCode))
				return (true);
			else
				WRITE_TRACE(DBG_FATAL, "Logoff operation failed with retcode: 0x%.8X '%s'",\
					nRetCode, PRL_RESULT_TO_STRING(nRetCode));
		}
		else
			WRITE_TRACE(DBG_FATAL, "Failed to extract return code from the job object");
	}
	else
		WRITE_TRACE(DBG_FATAL, "Failed to wait logoff job");

	return (false);
}
void Task_VzStateMonitor::processConfigChangedEvt(const QString &sUuid)
{
	// Handle Name change
	CDspLockedPointer< CVmDirectoryItem >
		pVmDirItem = CDspService::instance()->getVmDirManager()
		.getVmDirItemByUuid(CDspVmDirManager::getVzDirectoryUuid(), sUuid );
	if (!pVmDirItem)
		return;

	SmartPtr<CVmConfiguration> pConfig = CDspService::instance()->getVzHelper()->
		getCtConfig(CDspClient::makeServiceUser(), sUuid);
	if (!pConfig)
		return;

	QString sNewName = pConfig->getVmIdentification()->getVmName();
	if (pVmDirItem->getVmName() != sNewName && !sNewName.isEmpty()) {
		pVmDirItem->setVmName(sNewName);
		PRL_RESULT ret = CDspService::instance()->getVmDirManager().
			updateVmDirItem(pVmDirItem);
		if (PRL_FAILED(ret) )
			WRITE_TRACE(DBG_FATAL, "Can't update Container %s VmCatalogue by error: %s",
					QSTR2UTF8(sUuid), PRL_RESULT_TO_STRING(ret));
	}
}
PRL_RESULT Task_MigrateCtTarget::run_body()
{
	PRL_RESULT nRetCode = PRL_ERR_SUCCESS;
	bool bConnected;
	QTimer *pTimer;
	CDispToDispCommandPtr pReply;
	SmartPtr<IOPackage> pPackage;
	IOSendJob::Handle hJob;

	if (operationIsCancelled()) {
		nRetCode = PRL_ERR_OPERATION_WAS_CANCELED;
		goto exit;
	}

	bConnected = QObject::connect(m_pParent,
		SIGNAL(onPackageReceived(
			const SmartPtr<CDspDispConnection> &,
			const QString &,
			const SmartPtr<IOPackage> &)),
		SLOT(handleStartPackage(
			const SmartPtr<CDspDispConnection> &,
			const QString &,
			const SmartPtr<IOPackage> &)),
		Qt::DirectConnection);
	PRL_ASSERT(bConnected);

	m_nReservedFlags |= PVM_CT_MIGRATE;
	pReply = CDispToDispProtoSerializer::CreateVmMigrateCheckPreconditionsReply(
		m_lstCheckPrecondsErrors, QStringList(), m_nReservedFlags);
	pPackage =
		DispatcherPackage::createInstance(
			pReply->GetCommandId(), pReply->GetCommand()->toString(), m_pCheckPackage);
	hJob = m_pCheckDispConnection->sendPackage(pPackage);
	if (!hJob.isValid()) {
		nRetCode = PRL_ERR_OPERATION_FAILED;
		goto exit;
	}

	/* set timer */
	pTimer = new QTimer();
	pTimer->setSingleShot(true);
	bConnected = QObject::connect(pTimer, SIGNAL(timeout()), SLOT(handleStartCommandTimeout()), Qt::DirectConnection);
	pTimer->start(VM_MIGRATE_START_CMD_WAIT_TIMEOUT);

	/* will wait StartMigration command */
	nRetCode = exec();
	pTimer->stop();
	if (bConnected)
		QObject::disconnect(pTimer, SIGNAL(timeout()), this, SLOT(handleStartCommandTimeout()));
	delete pTimer;

	QObject::disconnect(m_pParent,
		SIGNAL(onPackageReceived(
			const SmartPtr<CDspDispConnection> &,
			const QString &,
			const SmartPtr<IOPackage> &)),
		this,
		SLOT(handleStartPackage(
			const SmartPtr<CDspDispConnection> &,
			const QString &,
			const SmartPtr<IOPackage> &)));

	if (PRL_FAILED(nRetCode))
		goto exit;

	if (operationIsCancelled()) {
		nRetCode = PRL_ERR_OPERATION_WAS_CANCELED;
		goto exit;
	}

	if ( !(m_nReservedFlags & PVM_DONT_COPY_VM) ) {
		/* to create Vm bundle */
		if (!CFileHelper::WriteDirectory(m_sTargetVmHomePath, &getClient()->getAuthHelper())) {
			nRetCode = PRL_ERR_BACKUP_CANNOT_CREATE_DIRECTORY;
			CVmEvent *pEvent = getLastError();
			pEvent->setEventCode(nRetCode);
			pEvent->addEventParameter(
				new CVmEventParameter(PVE::String, m_sTargetVmHomePath, EVT_PARAM_MESSAGE_PARAM_0));
			WRITE_TRACE(DBG_FATAL, "[%s] Cannot create \"%s\" directory",
					__FUNCTION__, QSTR2UTF8(m_sTargetVmHomePath));
			goto exit;
		}
		/* set original permissions to Vm bundle (https://jira.sw.ru/browse/PSBM-8269) */
		if (m_nBundlePermissions) {
			QFile vmBundle(m_sTargetVmHomePath);
			if (!vmBundle.setPermissions((QFile::Permissions)m_nBundlePermissions)) {
				WRITE_TRACE(DBG_FATAL,
					"[%s] Cannot set permissions for Vm bundle \"%s\", will use default",
					__FUNCTION__, QSTR2UTF8(m_sTargetVmHomePath));
			}
		}
	}
	m_nSteps |= MIGRATE_STARTED;
	if ((m_nPrevVmState == VMS_RUNNING) || (m_nPrevVmState == VMS_PAUSED)) {
		nRetCode = PRL_ERR_VM_MIGRATE_UNSUITABLE_VM_STATE;
	} else {
		nRetCode = migrateStoppedVm();

		/* migration completed and connection state is indifferent for us
		   https://jira.sw.ru/browse/PSBM-8925 */
		QObject::disconnect(
			&CDspService::instance()->getIOServer(),
			SIGNAL(onClientDisconnected(IOSender::Handle)),
			this,
			SLOT(clientDisconnected(IOSender::Handle)));
	}

	if (PRL_FAILED(nRetCode))
		goto exit;

	/* rename conf file since source sent it with his origin ctid */
	if (m_nOriginCtid != m_nCtid) {
		QString srcPath = m_sTargetVmHomePath + QString("/%1.conf").arg(m_nOriginCtid);
		QString dstPath = m_sTargetVmHomePath + QString("/%1.conf").arg(m_nCtid);
		QFile::rename(srcPath, dstPath);
	}

	nRetCode = CVzHelper::dst_complete_migrate_env(m_sVmUuid, m_nCtid, m_nOriginCtid, &m_pOpaqueLock);
	if (PRL_FAILED(nRetCode)) {
		WRITE_TRACE(DBG_FATAL, "Can not compelete destination CT migration for ctid %u uuid %s",
			    m_nCtid,  QSTR2UTF8(m_sVmUuid));
		goto exit;
	}

	if (PVMT_CLONE_MODE & getRequestFlags())
		m_pVmConfig->getVmIdentification()->setSourceVmUuid(m_sOriginVmUuid);

	if (PVMT_CLONE_MODE & getRequestFlags()) {
		if ( PVMT_SWITCH_TEMPLATE & getRequestFlags() )
			m_pVmConfig->getVmSettings()->getVmCommonOptions()->setTemplate(
				!m_pVmConfig->getVmSettings()->getVmCommonOptions()->isTemplate() );

		Task_CloneVm::ResetNetSettings(m_pVmConfig);
	}

	/* do not fail since here - Ct already migrated */
	{
		QString sServerUuid = CDspService::instance()->getDispConfigGuard().getDispConfig()
			->getVmServerIdentification()->getServerUuid();
		QString sLastServerUuid = m_pVmConfig->getVmIdentification()->getServerUuid();
		m_pVmConfig->getVmIdentification()->setServerUuid(sServerUuid);
		m_pVmConfig->getVmIdentification()->setLastServerUuid(sLastServerUuid);
		SmartPtr<CVmConfiguration> pOldConfig = CDspService::instance()->getVzHelper()
			->getVzlibHelper().get_env_config(m_nCtid);
		if (pOldConfig == NULL) {
			WRITE_TRACE(DBG_FATAL, "Can't get config for CT %s [%d]", QSTR2UTF8(m_sVmUuid), m_nCtid);
		} else {
			get_op_helper().apply_env_config(m_pVmConfig, pOldConfig);
		}
	}

	// insert new item in user's VM Directory
	m_pVmConfig = CDspService::instance()->getVzHelper()->getVzlibHelper().get_env_config(m_nCtid);
	if (PRL_FAILED(CDspService::instance()->getVzHelper()->insertVmDirectoryItem(m_pVmConfig))) {
		WRITE_TRACE(DBG_FATAL, "Can't insert CT to VmDirectory by error %#x, %s",
			    nRetCode, PRL_RESULT_TO_STRING(nRetCode) );
	}

exit:
	setLastErrorCode(nRetCode);
	return nRetCode;
}
PRL_RESULT Task_MigrateCtSource::prepareTask()
{
	//https://bugzilla.sw.ru/show_bug.cgi?id=267152
	CAuthHelperImpersonateWrapper _impersonate( &getClient()->getAuthHelper() );

	PRL_RESULT nRetCode = PRL_ERR_SUCCESS;

	if (CDspService::instance()->isServerStopping())
	{
		WRITE_TRACE(DBG_FATAL, "Dispatcher shutdown is in progress - VM migrate rejected!");
		nRetCode = PRL_ERR_DISP_SHUTDOWN_IN_PROCESS;
		goto exit;
	}

	if (CDspService::instance()->getShellServiceHelper().isLocalAddress(m_sServerHostname)) {
		WRITE_TRACE(DBG_FATAL,
			"Host %s is a local host, migration is impossible", QSTR2UTF8(m_sServerHostname));
		nRetCode = PRL_ERR_VM_MIGRATE_TO_THE_SAME_NODE;
		goto exit;
	}

	/* will use Vz dir uuid for Vm */
	{
		CDspLockedPointer<CVmDirectory> pDir = CDspService::instance()->getVmDirManager().getVzDirectory();
		if (!pDir) {
			nRetCode = PRL_ERR_VM_UUID_NOT_FOUND;
			WRITE_TRACE(DBG_FATAL, "Couldn't to find VZ directiory UUID");
			goto exit;
		}
		m_sVzDirUuid = pDir->getUuid();

		nRetCode = CDspService::instance()->getVmDirHelper().registerExclusiveVmOperation(
			m_sVmUuid, m_sVzDirUuid, PVE::DspCmdDirVmMigrate, getClient());
		if ( PRL_FAILED(nRetCode) ) {
			WRITE_TRACE(DBG_FATAL, "[%s] registerExclusiveVmOperation failed. Reason: %#x (%s)",
				    __FUNCTION__, nRetCode, PRL_RESULT_TO_STRING(nRetCode));
			goto exit;
		}
		m_bExVmOperationRegistered = true;
	}

	m_pVmConfig = CDspService::instance()->getVzHelper()->getCtConfig(getClient(), m_sVmUuid);
	if (!m_pVmConfig.isValid()) {
		WRITE_TRACE(DBG_FATAL, "Can not load config for uuid %s", QSTR2UTF8(m_sVmUuid));
		goto exit;
	}
	m_sVmHomePath = m_pVmConfig->getVmIdentification()->getHomePath();
	m_nCtid = m_pVmConfig->getVmIdentification()->getEnvId();

	nRetCode = CDspService::instance()->getVzHelper()->getVzlibHelper().get_env_status(m_sVmUuid, m_nPrevVmState);
	if (PRL_FAILED(nRetCode)) {
		WRITE_TRACE(DBG_FATAL, "Can not get status for uuid %s", QSTR2UTF8(m_sVmUuid));
		goto exit;
	}

	if (m_nPrevVmState != VMS_STOPPED) {
		WRITE_TRACE(DBG_FATAL, "CT must be stopped for migration");
		nRetCode = PRL_ERR_VM_MIGRATE_UNSUITABLE_VM_STATE;
		goto exit;
	}

	nRetCode = CVzHelper::src_start_migrate_env(m_nCtid, &m_pOpaqueLock);
	if (PRL_FAILED(nRetCode)) {
		WRITE_TRACE(DBG_FATAL, "Can not start source CT migration for uuid %s", QSTR2UTF8(m_sVmUuid));
		goto exit;
	}

	{
		/* LOCK inside brackets */
		CDspLockedPointer<CDspHostInfo> lockedHostInfo = CDspService::instance()->getHostInfo();
		m_cHostInfo.fromString( lockedHostInfo->data()->toString() );
	}

	nRetCode = Connect(
		m_sServerHostname, m_nServerPort, m_sServerSessionUuid, QString(), QString(), m_nMigrationFlags);
	if (PRL_FAILED(nRetCode))
		goto exit;

exit:
	setLastErrorCode(nRetCode);
	return nRetCode;
}
PRL_RESULT Task_VzManager::editConfig()
{
	PRL_RESULT res;

	CProtoCommandPtr cmd = CProtoSerializer::ParseCommand( getRequestPackage() );
	if ( ! cmd->IsValid() )
		return PRL_ERR_UNRECOGNIZED_REQUEST;

	SmartPtr<CVmConfiguration> pConfig( new CVmConfiguration( cmd->GetFirstStrParam() ) );
	if( !IS_OPERATION_SUCCEEDED( pConfig->m_uiRcInit ) )
	{
		PRL_RESULT code = PRL_ERR_PARSE_VM_CONFIG;
		WRITE_TRACE(DBG_FATAL, "Error occurred while modification CT configuration: %s",
				PRL_RESULT_TO_STRING( code ) );
		return code;
	}
	QString sUuid = pConfig->getVmIdentification()->getVmUuid();
	SmartPtr<CVmConfiguration> pOldConfig = getVzHelper()->getCtConfig(getClient(), sUuid);
	if (!pOldConfig)
		return PRL_ERR_VM_GET_CONFIG_FAILED;

        QString oldname = pOldConfig->getVmIdentification()->getVmName();
        QString name = pConfig->getVmIdentification()->getVmName();

	QStringList lstFullItemIds;
	pConfig->diffDocuments(pOldConfig.getImpl(), lstFullItemIds);

	// Code below prohibits all other than Hdd and Network devices for Containers
	if (!lstFullItemIds.filter(QRegExp("Hardware\\.(?!Hdd|Network|Cpu|Memory)")).isEmpty())
		return PRL_ERR_ACTION_NOT_SUPPORTED_FOR_CT;
	// Handle the Firewall settings change on the running CT
	if (!lstFullItemIds.filter(QRegExp("\\.(?=Firewall\\.|MAC|NetAddress)")).isEmpty()) {
		VIRTUAL_MACHINE_STATE nState = VMS_UNKNOWN;
		PRL_RESULT res = getVzHelper()->getVzlibHelper().get_env_status(sUuid, nState);
		if (nState == VMS_RUNNING) {
			res = setupFirewall(pConfig);
			if (PRL_FAILED(res))
				return res;
		}
	}

	// Handle Name change
	if (oldname != name) {
		QString vm_uuid; // Skip uuid check
		QString vm_name = name;
		QString vm_home;

		// Lock the new name in the VmDirectory
		CVmDirectory::TemporaryCatalogueItem vmInfo( vm_uuid, vm_home, vm_name);
		res = checkAndLockRegisterParameters(&vmInfo);
		if (PRL_FAILED(res))
			return res;

		res = get_op_helper()->set_env_name(sUuid, name);
		if (PRL_SUCCEEDED(res)) {
			CDspLockedPointer< CVmDirectoryItem >
				pVmDirItem = CDspService::instance()->getVmDirManager()
				.getVmDirItemByUuid(m_sVzDirUuid, sUuid );

			if (!pVmDirItem) {
				WRITE_TRACE(DBG_FATAL, "Can't found VmDirItem by vmUuid = %s",
						QSTR2UTF8(sUuid));
			} else {
				pVmDirItem->setVmName(name);
				PRL_RESULT ret = CDspService::instance()->getVmDirManager().updateVmDirItem(pVmDirItem);
				if (PRL_FAILED(ret) )
					WRITE_TRACE(DBG_FATAL, "Can't update Container %s VmCatalogue by error: %s",
						QSTR2UTF8(sUuid), PRL_RESULT_TO_STRING(ret));
			}
		}

		// delete temporary registration
		CDspService::instance()->getVmDirManager()
			.unlockExclusiveVmParameters(&vmInfo);

		if (PRL_FAILED(res))
			return res;
	}

	// reset IP addresses for CT templates
	Task_EditVm::resetNetworkAddressesFromVmConfig(pConfig, pOldConfig);

	// update High Availability Cluster resource
	if (pConfig->getVmSettings()->getHighAvailability()->toString() !=
			pOldConfig->getVmSettings()->getHighAvailability()->toString()
		&& CFileHelper::isSharedFS(pConfig->getVmIdentification()->getHomePath())) {
		res = CDspService::instance()->getHaClusterHelper()->updateClusterResourceParams(
				sUuid,
				pOldConfig->getVmSettings()->getHighAvailability(),
				pConfig->getVmSettings()->getHighAvailability(),
				pConfig->getVmIdentification()->getHomePath(),
				PVT_CT);
		if (PRL_FAILED(res))
			return res;
	}

	CVmRemoteDisplay* oldD = pOldConfig->getVmSettings()->getVmRemoteDisplay();
	CVmRemoteDisplay* newD = pConfig->getVmSettings()->getVmRemoteDisplay();

	if (oldD->getPassword() != newD->getPassword()) {
		if (newD->getPassword().length() > PRL_VM_REMOTE_DISPLAY_MAX_PASS_LEN) {
			WRITE_TRACE(DBG_FATAL, "The specified remote display password is too long.");
			getLastError()->addEventParameter(
				new CVmEventParameter(
					PVE::UnsignedInt,
					QString::number(PRL_VM_REMOTE_DISPLAY_MAX_PASS_LEN),
					EVT_PARAM_MESSAGE_PARAM_0));

			return PRL_ERR_VMCONF_REMOTE_DISPLAY_PASSWORD_TOO_LONG;
		}
	}

	Backup::Device::Service service(pOldConfig);
	service.setContext(*this).setVmHome(pConfig->getVmIdentification()->getHomePath());
	Backup::Device::Details::Transition t = service.getTransition(pConfig);
	res = t.plant();
	if (PRL_FAILED(res))
		return res;

	res = get_op_helper()->apply_env_config(pConfig, pOldConfig, cmd->GetCommandFlags());
	if (PRL_FAILED(res))
		return res;

	res = t.remove();
	if (PRL_FAILED(res))
		return res;

	// Invalidate cache
	CDspService::instance()->getVzHelper()->getConfigCache().
		remove(pConfig->getVmIdentification()->getHomePath());

	res = changeVNCServerState(pOldConfig, pConfig, sUuid);
	if (PRL_FAILED(res))
		return res;

	// Handle memory limit change
	unsigned int newRamSize = pConfig->getVmHardwareList()->getMemory()->getRamSize();
	unsigned int oldRamSize = pOldConfig->getVmHardwareList()->getMemory()->getRamSize();
	if (newRamSize != oldRamSize) {
		VIRTUAL_MACHINE_STATE nState = VMS_UNKNOWN;
		PRL_RESULT res = getVzHelper()->getVzlibHelper().get_env_status(sUuid, nState);
		if (PRL_SUCCEEDED(res) && (nState == VMS_RUNNING))
			adjustReservedMemLimit((long long)newRamSize - oldRamSize);
	}

	QStringList lstAdd, lstDel;
	// Handle application templates
	QStringList newAppTemplates = pConfig->getCtSettings()->getAppTemplate();
	QStringList oldAppTemplates = pOldConfig->getCtSettings()->getAppTemplate();

	for (int i = 0; i < newAppTemplates.size(); i++) {
		if (newAppTemplates.at(i).startsWith('.'))
			newAppTemplates[i].remove(0, 1);
	}
	for (int i = 0; i < oldAppTemplates.size(); i++) {
		if (oldAppTemplates.at(i).startsWith('.'))
			oldAppTemplates[i].remove(0, 1);
	}

	if (newAppTemplates == oldAppTemplates)
		goto ok;

	foreach(QString str, newAppTemplates)
		if (!oldAppTemplates.contains(str))
			lstAdd.append(str);
	foreach(QString str, oldAppTemplates)
		if (!newAppTemplates.contains(str))
			lstDel.append(str);

	do {
		CVzTemplateHelper TmplHelper = getVzHelper()->getVzTemplateHelper();
		res = TmplHelper.remove_templates_env(sUuid, lstDel);
		if (PRL_FAILED(res))
			return res;

		res = TmplHelper.install_templates_env(sUuid, lstAdd);
	} while (0);

ok:
	if ( PRL_SUCCEEDED(res) ) {
		SmartPtr<CVmConfiguration> pNewConfig = getVzHelper()->getCtConfig(getClient(), sUuid);
		QStringList lstParams(pNewConfig ?
				pNewConfig->toString() : pConfig->toString());
		getResponseCmd()->SetParamsList( lstParams );

		sendEvent(PET_DSP_EVT_VM_CONFIG_CHANGED, sUuid);
	}

	return res;
}
Example #12
0
void Trace::finish(PRL_RESULT code_) const
{
	boost::property_tree::ptree t;
	t.put("result", PRL_RESULT_TO_STRING(code_));
	report(t);
}
PRL_RESULT Task_GetBackupTreeSource::prepareTask()
{
	PRL_RESULT ret = PRL_ERR_SUCCESS;
	try {
		if ((m_nFlags & (PBT_BACKUP_ID | PBT_CHAIN)) && m_sUuid.isEmpty()) {
			WRITE_TRACE(DBG_FATAL, "A backup UUID must be specified to get information "
								   "on a single backup or backup chain.");
			throw PRL_ERR_INVALID_PARAM;
		}
		if ((m_nFlags & PBT_BACKUP_ID) && (m_nFlags & PBT_CHAIN)) {
			WRITE_TRACE(DBG_FATAL, "The PBT_BACKUP_ID and PBT_CHAIN flags are mutually exclusive.");
			throw PRL_ERR_INVALID_PARAM;
		}
	} catch (PRL_RESULT code) {
		getLastError()->setEventCode(code);
		ret = code;
		WRITE_TRACE(DBG_FATAL, "An error occurred while preparing to get the backup tree [%#x][%s]",
			code, PRL_RESULT_TO_STRING(code));
	}

	return ret;
}