bool SimpleServerWrapper::Login(char *sUserLogin, bool bUseNonInteractiveMode)
{
	SdkHandleWrap hJob;
	PRL_UINT32 nFlags = bUseNonInteractiveMode
		? PACF_NON_INTERACTIVE_MODE
		: 0;
	if (sUserLogin)
	{
		hJob.reset(PrlSrv_LoginEx(m_ServerHandle, TestConfig::getRemoteHostName(),	sUserLogin,
								TestConfig::getUserPassword(), NULL, 0, 0, PSL_HIGH_SECURITY, nFlags));
	}
	else
	{
		hJob.reset(PrlSrv_LoginLocalEx(m_ServerHandle, NULL, 0, PSL_HIGH_SECURITY, nFlags));
	}

	if (PRL_SUCCEEDED(PrlJob_Wait(hJob, PRL_JOB_WAIT_TIMEOUT)))
	{
		PRL_RESULT nRetCode;
		if (PRL_SUCCEEDED(PrlJob_GetRetCode(hJob, &nRetCode)))
		{
			if (!PRL_SUCCEEDED(nRetCode))
				WRITE_TRACE(DBG_FATAL, "Failed to login to server");
			else
				return (true);
		}
		else
			WRITE_TRACE(DBG_FATAL, "Failed to get job return code");
	}
	else
		WRITE_TRACE(DBG_FATAL, "Failed to wait server login async job");

	return (false);
}
bool SimpleServerWrapper::CreateTestVm(const SdkHandleWrap &hVm)
{
	if (PRL_INVALID_HANDLE != hVm)
		m_VmHandle = hVm;
	else
	{
		if (PRL_SUCCEEDED(PrlSrv_CreateVm(m_ServerHandle, m_VmHandle.GetHandlePtr())))
		{
			READ_VM_CONFIG_INTO_BUF
			if (PRL_SUCCEEDED(PrlVm_FromString(m_VmHandle, _config.toUtf8().data())))
			{
				if (PRL_FAILED(PrlVmCfg_SetName(m_VmHandle, QTest::currentTestFunction())))
				{
					WRITE_TRACE(DBG_FATAL, "Failed to apply VM name: '%s'", QTest::currentTestFunction());
					return (false);
				}
			}
			else
			{
				WRITE_TRACE(DBG_FATAL, "Couldn't to assign VM configuration");
				return (false);
			}
		}
		else
		{
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;
}
PRL_RESULT Task_VzManager::register_env()
{
	CProtoCommandPtr cmd = CProtoSerializer::ParseCommand( getRequestPackage() );
	if ( ! cmd->IsValid() )
		return PRL_ERR_UNRECOGNIZED_REQUEST;

	QString sPath = cmd->GetFirstStrParam();

	if (!QFileInfo(sPath).exists())
	{
		getLastError()->addEventParameter(new CVmEventParameter(
						PVE::String,
						sPath,
						EVT_PARAM_MESSAGE_PARAM_0 ));
		return PRL_ERR_DIRECTORY_DOES_NOT_EXIST;
	}
	SmartPtr<CVmConfiguration> pConfig;

	QString sUuid = cmd->GetVmUuid();
	if (cmd->GetCommandFlags() & PRVF_REGENERATE_VM_UUID)
		sUuid = Uuid::createUuid().toString();

	QString vm_uuid = sUuid;
	QString vm_name;
	QString vm_home = sPath + "/" + VMDIR_DEFAULT_VM_CONFIG_FILE;

	PRL_RESULT res;
	CVmDirectory::TemporaryCatalogueItem vmInfo( vm_uuid, vm_home, vm_name);
	// Lock
	res = checkAndLockRegisterParameters(&vmInfo);
	if (PRL_FAILED(res))
		return res;

	res = get_op_helper()->register_env(sPath, QString(), sUuid, cmd->GetCommandFlags(), pConfig);
	if (PRL_SUCCEEDED(res)) {
		res = getVzHelper()->insertVmDirectoryItem(pConfig);
		if (PRL_FAILED(res))
			get_op_helper()->unregister_env(
					pConfig->getVmIdentification()->getVmUuid(), 0);
	}
	// delete temporary registration
	CDspService::instance()->getVmDirManager()
		.unlockExclusiveVmParameters(&vmInfo);

	if (PRL_SUCCEEDED(res))
		getResponseCmd()->SetVmConfig(pConfig->toString());

	return res;
}
void Task_MigrateCtSource::finalizeTask()
{
	//https://bugzilla.sw.ru/show_bug.cgi?id=267152
	CAuthHelperImpersonateWrapper _impersonate( &getClient()->getAuthHelper() );
	SmartPtr<IOPackage> pPackage;

	Disconnect();

	if (PRL_SUCCEEDED(getLastErrorCode())) {
		CProtoCommandPtr pResponse =
			CProtoSerializer::CreateDspWsResponseCommand(getRequestPackage(), PRL_ERR_SUCCESS);
		getClient()->sendResponse(pResponse, getRequestPackage());
		/* We may not report error here since CT already live on destination */
		bool bDeleteSource = !(m_nMigrationFlags & PVMT_CLONE_MODE);
		PRL_RESULT nRetCode = CVzHelper::src_complete_migrate_env(m_nCtid, &m_pOpaqueLock, bDeleteSource);
		if (PRL_FAILED(nRetCode))
			WRITE_TRACE(DBG_FATAL, "Can not complete source CT migration for uuid %s", QSTR2UTF8(m_sVmUuid));
	} else {
		/* send response */
		CProtoCommandPtr pResponse =
			CProtoSerializer::CreateDspWsResponseCommand(getRequestPackage(), getLastErrorCode());
		CProtoCommandDspWsResponse *wsResponse =
			CProtoSerializer::CastToProtoCommand<CProtoCommandDspWsResponse>( pResponse );
		getLastError()->setEventCode(getLastErrorCode());
		wsResponse->SetError(getLastError()->toString());
		getClient()->sendResponse( pResponse, getRequestPackage() );

		getClient()->sendResponseError( getLastError(), getRequestPackage() );
	}

	if (m_bExVmOperationRegistered)
		CDspService::instance()->getVmDirHelper().unregisterExclusiveVmOperation(
				m_sVmUuid, m_sVzDirUuid, PVE::DspCmdDirVmMigrate, getClient());
}
PRL_RESULT Task_VzManager::create_env()
{
	CProtoCommandPtr cmd = CProtoSerializer::ParseCommand( getRequestPackage());
	if ( ! cmd->IsValid() )
		return PRL_ERR_UNRECOGNIZED_REQUEST;

	CProtoVmCreateCommand *pCmd = CProtoSerializer::CastToProtoCommand<CProtoVmCreateCommand>(cmd);
	if (!pCmd->IsValid())
		return PRL_ERR_UNRECOGNIZED_REQUEST;
	SmartPtr<CVmConfiguration> pConfig(new CVmConfiguration);
	pConfig->fromString(pCmd->GetVmConfig());

	QString sPath = pCmd->GetVmHomePath();
	if (!sPath.isEmpty() && !QDir::isAbsolutePath( sPath) ) {
		WRITE_TRACE(DBG_FATAL, "Invalid path '%s'", QSTR2UTF8(sPath));
		return PRL_ERR_VMDIR_PATH_IS_NOT_ABSOLUTE;
	}

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

	CVmDirectory::TemporaryCatalogueItem vmInfo( vm_uuid, vm_home, vm_name);
	// Lock
	PRL_RESULT res = checkAndLockRegisterParameters(&vmInfo);
	if (PRL_FAILED(res))
		return res;

	res = get_op_helper()->create_env(sPath, pConfig, pCmd->GetCommandFlags());
	if (PRL_SUCCEEDED(res)) {
		res = getVzHelper()->insertVmDirectoryItem(pConfig);
		if (PRL_FAILED(res))
			get_op_helper()->delete_env(
					pConfig->getVmIdentification()->getVmUuid());
	}
	// Unlock temporary registration
	CDspService::instance()->getVmDirManager()
		.unlockExclusiveVmParameters(&vmInfo);

	if (PRL_SUCCEEDED(res)) {
		getResponseCmd()->SetVmConfig(pConfig->toString());
		sendEvent(PET_DSP_EVT_VM_ADDED, vm_uuid);
	}

	return res;
}
SimpleServerWrapper::SimpleServerWrapper(char *sUserLogin, bool bUseNonInteractiveMode)
: m_bIsVmWasCreatedByThisInstance(false), m_isLocalAdminInited(false)
{
	if (PRL_SUCCEEDED(PrlSrv_Create(m_ServerHandle.GetHandlePtr())))
		Login(sUserLogin, bUseNonInteractiveMode);
	else
		WRITE_TRACE(DBG_FATAL, "Failed to create server handle");
}
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;
}
bool SimpleServerWrapper::IsConnected()
{
	PRL_BOOL bConnected = false;
	PRL_BOOL bIsConnectionLocal = false;
	if (PRL_SUCCEEDED(PrlSrv_IsConnected(m_ServerHandle, &bConnected, &bIsConnectionLocal)))
		return (bConnected);
	else
		WRITE_TRACE(DBG_FATAL, "Failed to get connected server sign");
	return (false);
}
/* Finalize task */
void Task_GetBackupTreeSource::finalizeTask()
{
	Disconnect();

	if (PRL_SUCCEEDED(getLastErrorCode())) {
		CProtoCommandPtr pResponse = CProtoSerializer::CreateDspWsResponseCommand(getRequestPackage(), PRL_ERR_SUCCESS);
		CProtoCommandDspWsResponse *pDspWsResponseCmd =
			CProtoSerializer::CastToProtoCommand<CProtoCommandDspWsResponse>(pResponse);
		pDspWsResponseCmd->SetBackupsTree(m_sBackupTree);

		getClient()->sendResponse( pResponse, getRequestPackage() );
	} else {
		getClient()->sendResponseError( getLastError(), getRequestPackage() );
	}
}
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);
}
PRL_RESULT Task_VzStateMonitor::run_body()
{
	// set initial states for all CTs
	QStringList uuids;
	{
		CDspLockedPointer<CVmDirectory>	d = CDspService::instance()->getVmDirManager().getVzDirectory();
		std::transform(d->m_lstVmDirectoryItems.begin(), d->m_lstVmDirectoryItems.end(),
			std::back_inserter(uuids), boost::bind(&CVmDirectoryItem::getVmUuid, _1));
	}
	CVzHelper& h = CDspService::instance()->getVzHelper()->getVzlibHelper();
	foreach(const QString& u, uuids)
	{
		VIRTUAL_MACHINE_STATE s = VMS_UNKNOWN;
		if (PRL_SUCCEEDED(h.get_env_status(u, s)) && s != VMS_UNKNOWN)
			processChangeCtState(u, s);
	}
void CVmMigrateTargetDisk::run()
{
	m_sem_init.release();
	m_result = PRL_ERR_SUCCESS;

	while (PRL_SUCCEEDED(m_result) && !(m_queue.empty() && m_wait))
	{
		DiskQueueElem_t data;
		if (m_queue.take(data, m_token))
			m_result = write_data(&data);
		else
			break;

		if (PRL_FAILED(m_result))
		{
			WRITE_TRACE(DBG_FATAL, "[Disk migration] Failed to write block to disk %s,\
					address %llu, size %u",
				qPrintable(Uuid::fromGuid(data.hdr.disk_id).toString()),
				data.hdr.lba, data.hdr.nsect);
			m_token.signal();
		}
	}
}
void Task_MigrateCtTarget::finalizeTask()
{
	IOSendJob::Handle hJob;
	SmartPtr<IOPackage> pPackage;

	// delete temporary registration
	if (m_nSteps & MIGRATE_VM_EXCL_PARAMS_LOCKED)
		CDspService::instance()->getVmDirManager().unlockExclusiveVmParameters(m_pVmInfo.getImpl());

	int nRetCode = getLastErrorCode();
	if (PRL_SUCCEEDED(nRetCode)) {
		if (m_pVm.getImpl()) {
			PRL_EVENT_TYPE evtType;
			/* restore Vm previous state */
			switch (m_nPrevVmState)
			{
			case VMS_RUNNING:
				evtType = PET_DSP_EVT_VM_STARTED;
				break;
			case VMS_STOPPED:
			default:
				evtType = PET_DSP_EVT_VM_STOPPED;
				break;
			}
			CVmEvent cStateEvent(evtType, m_sVmUuid, PIE_DISPATCHER);
			SmartPtr<IOPackage> pUpdateVmStatePkg =
				DispatcherPackage::createInstance( PVE::DspVmEvent, cStateEvent.toString());
			m_pVm->changeVmState(pUpdateVmStatePkg);
			CDspService::instance()->getClientManager().
				sendPackageToVmClients(pUpdateVmStatePkg, m_sVzDirUuid, m_sVmUuid);

			if (m_nPrevVmState == VMS_STOPPED) {
				CDspService::instance()->getVmDirHelper().unregisterExclusiveVmOperation(
					m_sVmUuid, m_sVzDirUuid, PVE::DspCmdDirVmMigrate, getClient());
				CDspVm::UnregisterVmObject(m_pVm);

			} else {
				/* lock running Vm (https://jira.sw.ru/browse/PSBM-7682) */
				/* will do it via initial Vm creation command
				   (https://jira.sw.ru/browse/PSBM-8222) */
				m_pVm->replaceInitDspCmd(PVE::DspCmdVmStart, getClient());
			}
		}

		/* notify source task about target task finish,
		   will send reply to check precondition request. https://jira.sw.ru/browse/PSBM-9596 */
		m_pCheckDispConnection->sendSimpleResponse(m_pCheckPackage, PRL_ERR_SUCCESS);

		/* migration initiator wait event from original Vm uuid */
		CVmEvent cEvent(PET_DSP_EVT_VM_MIGRATE_FINISHED, m_sOriginVmUuid, PIE_DISPATCHER);
		pPackage = DispatcherPackage::createInstance(PVE::DspVmEvent, cEvent.toString());
		CDspService::instance()->getClientManager().sendPackageToVmClients(pPackage, m_sVzDirUuid, m_sOriginVmUuid);
	}
	else
	{
		/* It is not possible to get Vm client list after deleteVmDirectoryItem(), and
		   sendPackageToVmClients() does not work. Get list right now and will use
		   sendPackageToClientList() call (https://jira.sw.ru/browse/PSBM-9159) */
		QList< SmartPtr<CDspClient> > clientList =
			CDspService::instance()->getClientManager().
				getSessionListByVm(m_sVzDirUuid, m_sVmUuid).values();

		if (operationIsCancelled())
			setLastErrorCode(PRL_ERR_OPERATION_WAS_CANCELED);

		/* if migration was not started, do not cleanup anything -
		   we can remove 'already existed Vm' */
		if (m_nSteps & MIGRATE_STARTED)
		{

			if (m_nSteps & MIGRATE_VM_APP_STARTED && m_pVm.getImpl())
			{
				/* stop Vm */
				CProtoCommandPtr pCmd =
					CProtoSerializer::CreateProtoVmCommandStop(m_sVmUuid, PSM_KILL, 0);
				pPackage = DispatcherPackage::createInstance( PVE::DspCmdVmStop, pCmd );
				m_pVm->stop(getClient(), pPackage, PSM_KILL, true);
				// Wait until VM stopped
				while (m_pVm->isConnected()) {
					if (operationIsCancelled() && CDspService::instance()->isServerStopping())
						break;
					QThread::msleep(1000);
				}
			}
			if (m_pVm.getImpl()) {
				CDspVm::UnregisterVmObject(m_pVm);
				m_pVm = SmartPtr<CDspVm>(0);
			}

			if (!CDspService::instance()->isServerStopping())
				CDspService::instance()->getVmConfigWatcher().unregisterVmToWatch(m_sTargetVmHomePath);
			if ( !(m_nReservedFlags & PVM_DONT_COPY_VM) ) {
				CFileHelper::ClearAndDeleteDir(m_sTargetVmHomePath);
			}

			// Unregister VM dir item
			CDspService::instance()->getVmDirHelper().deleteVmDirectoryItem(m_sVzDirUuid, m_sVmUuid);

			CVmEvent cDelEvent(PET_DSP_EVT_VM_DELETED, m_sVmUuid, PIE_DISPATCHER);
			SmartPtr<IOPackage> pDelPackage =
					DispatcherPackage::createInstance(PVE::DspVmEvent, cDelEvent.toString());
			CDspService::instance()->getClientManager().sendPackageToClientList(
					pDelPackage, clientList);
		}

		/* migration initiator wait event from original Vm uuid */
		CVmEvent cEvent(PET_DSP_EVT_VM_MIGRATE_CANCELLED, m_sOriginVmUuid, PIE_DISPATCHER);
		pPackage = DispatcherPackage::createInstance(PVE::DspVmEvent, cEvent.toString());
		CDspService::instance()->getClientManager().sendPackageToClientList(pPackage, clientList);

		if (m_pStartDispConnection.isValid())
			hJob = m_pStartDispConnection->sendResponseError(getLastError(), getRequestPackage());
		else
			hJob = m_pCheckDispConnection->sendResponseError(getLastError(), getRequestPackage());
		CDspService::instance()->getIOServer().waitForSend(hJob, m_nTimeout);
	}
}
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;
}
Exemple #16
0
static PRL_RESULT print_perfstats(PRL_HANDLE handle, const CmdParamData &param)
{
	(void)param;
	unsigned int param_count;
	PRL_RESULT ret = PrlEvent_GetParamsCount(handle, &param_count);
	if (PRL_FAILED(ret))
		return prl_err(ret, "PrlEvent_GetParamsCount returned the following error: %s",
				get_error_str(ret).c_str());

	if (!param_count)
		return PRL_ERR_SUCCESS;

	// Print VM uuid if necessary
	if (param.list_all) {
		char uuid[NORMALIZED_UUID_LEN + 1] = {0};
		PRL_UINT32 size = sizeof(uuid);
		PRL_HANDLE hVm;
		if (PRL_SUCCEEDED(PrlEvent_GetVm(handle, &hVm))) {
			PrlVmCfg_GetUuid(hVm, uuid, &size);
			PrlHandle_Free(hVm);
		}
		printf("%s\n", uuid);
	}
	for (unsigned int ndx = 0; ndx < param_count; ++ndx) {
		PrlHandle hPrm;
		ret = PrlEvent_GetParam(handle, ndx, hPrm.get_ptr());
		if (PRL_FAILED(ret))
			return prl_err(ret, "PrlEvent_GetParam returned the following error: %s",
					get_error_str(ret).c_str());

		char name_buff[1024];
		unsigned int len = sizeof(name_buff) - 1;
		ret = PrlEvtPrm_GetName(hPrm.get_handle(), name_buff, &len);
		if (PRL_FAILED(ret))
			return prl_err(ret, "PrlEvtPrm_GetName returned the following error: %s",
					get_error_str(ret).c_str());
		char val_buff[1024];
		len = sizeof(val_buff) - 1;
		val_buff[len] = 0;

		PRL_PARAM_FIELD_DATA_TYPE nFieldType = PFD_UNKNOWN;
		PrlEvtPrm_GetType(hPrm.get_handle(), &nFieldType);
		if (nFieldType == PFD_BINARY) {
			if (strncmp(name_buff, PRL_NET_CLASSFUL_TRAFFIC_PTRN, sizeof(PRL_NET_CLASSFUL_TRAFFIC_PTRN) - 1) == 0) {
				PRL_STAT_NET_TRAFFIC net_stat_buf;
				len = sizeof(PRL_STAT_NET_TRAFFIC);

				if (PrlEvtPrm_GetBuffer(hPrm.get_handle(), &net_stat_buf, &len) == 0) {

					for (unsigned int i = 0; i < PRL_TC_CLASS_MAX; i++)
						fprintf(stdout, "\t%20s %2d %20llu %10u %20llu %10u\n", name_buff, i,
								net_stat_buf.incoming[i], net_stat_buf.incoming_pkt[i],
								net_stat_buf.outgoing[i], net_stat_buf.outgoing_pkt[i]);
				}
			}
		} else {
			ret = PrlEvtPrm_ToString(hPrm.get_handle(), val_buff, &len);
			if (PRL_FAILED(ret))
				return prl_err(ret, "PrlEvtPrm_ToString returned the following error: %s",
						get_error_str(ret).c_str());

			fprintf(stdout, "\t%s:\t%s\n", name_buff, val_buff);
		}

	}

	return PRL_ERR_SUCCESS;
}
PRL_RESULT Task_VzManager::clone_env()
{
	PRL_RESULT res;

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

	CProtoVmCloneCommand *pCmd = CProtoSerializer::CastToProtoCommand<CProtoVmCloneCommand>(cmd);

	QString sUuid = pCmd->GetVmUuid();
	QString sNewHome = pCmd->GetVmHomePath();
	QString sNewName = pCmd->GetVmName();
	unsigned int nFlags = pCmd->GetCommandFlags();

	if (sNewName.isEmpty())
		return PRL_ERR_VM_NAME_IS_EMPTY;

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

	SmartPtr<CVmConfiguration> pConfig = getVzHelper()->getCtConfig(getClient(), sUuid);
	if (!pConfig)
	{
		WRITE_TRACE(DBG_FATAL, "Unable to find CT by uuid %s", QSTR2UTF8(sUuid));
		return PRL_ERR_VM_GET_CONFIG_FAILED;
	}

	SmartPtr<CVmConfiguration> pNewConfig(new CVmConfiguration);

	if (!pCmd->GetNewVmUuid().isEmpty())
		pNewConfig->getVmIdentification()->setVmUuid(pCmd->GetNewVmUuid());

	CVmDirectory::TemporaryCatalogueItem vmInfo(
			pNewConfig->getVmIdentification()->getVmUuid(),
			QString(),
			sNewName);

	res = checkAndLockRegisterParameters(&vmInfo);
	if (PRL_FAILED(res))
		return res;

	res = get_op_helper()->clone_env(pConfig, sNewHome, sNewName, nFlags, pNewConfig);
	if (PRL_SUCCEEDED(res)) {
		res = getVzHelper()->insertVmDirectoryItem(pNewConfig);
		if (PRL_FAILED(res))
			get_op_helper()->delete_env(
					pNewConfig->getVmIdentification()->getVmUuid());
	}
	// delete temporary registration
	CDspService::instance()->getVmDirManager()
		.unlockExclusiveVmParameters(&vmInfo);

	if (PRL_FAILED(res) || !pNewConfig.isValid())
		return res;

	SmartPtr<CVmConfiguration> pOldConfig(new CVmConfiguration(pNewConfig->toString()));

	bool isTemplate = (nFlags & PCVF_CLONE_TO_TEMPLATE);
	pNewConfig->getVmSettings()->getVmCommonOptions()->setTemplate(isTemplate);

	Task_CloneVm::ResetNetSettings(pNewConfig);
	Backup::Device::Dao(pNewConfig).deleteAll();

	get_op_helper()->apply_env_config(pNewConfig, pOldConfig, PVCF_DESTROY_HDD_BUNDLE);

	getResponseCmd()->SetVmConfig(pNewConfig->toString());
	{
	       CVmEvent event(PET_DSP_EVT_VM_ADDED,
			       pNewConfig->getVmIdentification()->getVmUuid(),
			       PIE_DISPATCHER);
	       SmartPtr<IOPackage> p = DispatcherPackage::createInstance(PVE::DspVmEvent, event);
	       CDspService::instance()->getClientManager().sendPackageToAllClients(p);
	}
	// Set some parameters in the response (see Task_CloneVm)
	CDspLockedPointer<CVmEvent> pParams = getTaskParameters();

	pParams->addEventParameter(
			new CVmEventParameter( PVE::String,
				pNewConfig->getVmIdentification()->getVmUuid(),
				EVT_PARAM_DISP_TASK_CLONE_VM_UUID ) );
	pParams->addEventParameter(
			new CVmEventParameter( PVE::String,
				pNewConfig->getVmIdentification()->getVmName(),
				EVT_PARAM_DISP_TASK_CLONE_NEW_VM_NAME ) );
	pParams->addEventParameter(
			new CVmEventParameter( PVE::String,
				pNewConfig->getVmIdentification()->getHomePath(),
				EVT_PARAM_DISP_TASK_CLONE_NEW_VM_ROOT_DIR ) );
	pParams->addEventParameter(
			new CVmEventParameter( PVE::Boolean,
				QString("%1").arg(isTemplate),
				EVT_PARAM_DISP_TASK_CLONE_AS_TEMPLATE ) );
	return PRL_ERR_SUCCESS;
}