コード例 #1
0
/**
 * Send the UDP message to be received by the daemon
 */
bool DynamicClientInitializer::sendUdpMessage ( int timeoutMsec )
{
    CommandNMS_INIT* cmdInit = new ( std::nothrow ) CommandNMS_INIT ( CONFIG_DISPATCHER_PROTOCOL, 7566 );
    if ( NULL == cmdInit )
    {
        LOG_ERR ( "Not enough memory to create the NMS_INIT command" );
        setLastErrorCode ( ErrorCodes::NOT_ENOUGH_MEMORY );
        return false;
    }

    if ( !udpSocket->send ( cmdInit ) ) // sending the broadcast message
    {
        LOG_ERR ( "UDP broadcast: sendto failed" + udpSocket->getError() );
        setLastErrorCode ( udpSocket->getErrorCode() );
        delete cmdInit;
        return false;
    }

    Thread::suspendCurrent ( 100 );

    if ( !udpSocket->setNonBlocking() )
    {
        LOG_ERR ( "Cannot set the UDP socket to non-blocking" );
        delete cmdInit;
        setLastErrorCode ( ErrorCodes::INTERNAL_ERROR );
        return false;
    }

    NetworkAddress naddrResponse;
    daemonFirstResponse = COMMAND_NOINIT;
    time_t startTime, nowTime;
    time ( &startTime );
    while ( true )
    {

        Thread::suspendCurrent ( 100 );

        string broadcastReply = udpSocket->receive ( &naddrResponse );
        if ( broadcastReply.length() > 0 )
        {
            if ( !udpSocket->close() )
            {
                LOG_ERR ( "Error while closing a socket" );
            }
            daemonFirstResponse = broadcastReply;
            delete cmdInit;
            return true;
        }
        else
        {
            time ( &nowTime );
            if ( nowTime - startTime >= timeoutMsec )
            {
                udpSocket->close();
                setLastErrorCode ( ErrorCodes::TIMEOUT );
                delete cmdInit;
                return false;
            }
        }
    }
    LOG_ERR ( "Reached to an invalid location in the code" );
    delete cmdInit;
    return false;
}
コード例 #2
0
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);
	}
}
コード例 #3
0
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;
}
コード例 #4
0
/* process VmMigrateCheckPreconditionsCommand */
PRL_RESULT Task_MigrateCtTarget::prepareTask()
{
	//https://bugzilla.sw.ru/show_bug.cgi?id=267152
	CAuthHelperImpersonateWrapper _impersonate( &getClient()->getAuthHelper() );

	PRL_RESULT nRetCode = PRL_ERR_SUCCESS;
	QString sVmDirPath;

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

	m_pVmConfig = SmartPtr<CVmConfiguration>(new CVmConfiguration(m_sVmConfig));
	if (PRL_FAILED(m_pVmConfig->m_uiRcInit)) {
		nRetCode = PRL_ERR_PARSE_VM_CONFIG;
		WRITE_TRACE(DBG_FATAL, "Wrong VM condiguration was received: [%s]", QSTR2UTF8(m_sVmConfig));
		goto exit;
	}
	m_sOriginVmUuid = m_pVmConfig->getVmIdentification()->getVmUuid();
	m_nCtid = m_nOriginCtid = m_pVmConfig->getVmIdentification()->getEnvId();
	m_sVmName = m_pVmConfig->getVmIdentification()->getVmName();

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

	if (m_nCtid != m_nOriginCtid)
		m_pVmConfig->getVmIdentification()->setEnvId(m_nCtid);

	{
		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();
	}
	m_sVmUuid = (PVMT_CLONE_MODE & getRequestFlags()) ? Uuid::createUuid().toString() : m_sOriginVmUuid;

	WRITE_TRACE(DBG_FATAL, "Start migrate origin CTID=%u to CTID=%u for uuid %s",
		    m_nOriginCtid, m_nCtid, QSTR2UTF8(m_sVmUuid));

	/*  to get target VM home directory path */
	if (!m_sVmDirPath.isEmpty())
		m_sTargetVmHomePath = m_sVmDirPath;
	else {
		m_sTargetVmHomePath = CVzHelper::getCtPrivatePath(m_nCtid);
	}
	m_sTargetVmHomePath = QFileInfo(m_sTargetVmHomePath).absoluteFilePath();
	m_sVmConfigPath = QString("%1/" VMDIR_DEFAULT_VM_CONFIG_FILE).arg(m_sTargetVmHomePath);

	/* lock Vm exclusive parameters */
	m_pVmInfo = SmartPtr<CVmDirectory::TemporaryCatalogueItem>(new CVmDirectory::TemporaryCatalogueItem(
			m_sVmUuid, m_sVmConfigPath, m_sVmName));

	nRetCode = CDspService::instance()->getVmDirManager()
			.checkAndLockNotExistsExclusiveVmParameters(QStringList(), m_pVmInfo.getImpl());
	if (PRL_FAILED(nRetCode))
	{
		switch (nRetCode)
		{
		case PRL_ERR_VM_ALREADY_REGISTERED_VM_UUID:
			WRITE_TRACE(DBG_FATAL, "UUID '%s' already registered", QSTR2UTF8(m_pVmInfo->vmUuid));
			getLastError()->addEventParameter(
				new CVmEventParameter( PVE::String, m_pVmInfo->vmUuid, EVT_PARAM_RETURN_PARAM_TOKEN));
			break;

		case PRL_ERR_VM_ALREADY_REGISTERED_VM_PATH:
			WRITE_TRACE(DBG_FATAL, "path '%s' already registered", QSTR2UTF8(m_pVmInfo->vmXmlPath));
			getLastError()->addEventParameter(
				new CVmEventParameter( PVE::String, m_pVmInfo->vmName, EVT_PARAM_MESSAGE_PARAM_0));
			getLastError()->addEventParameter(
				new CVmEventParameter( PVE::String, m_pVmInfo->vmXmlPath, EVT_PARAM_MESSAGE_PARAM_1));
			break;

		case PRL_ERR_VM_ALREADY_REGISTERED_VM_NAME:
			WRITE_TRACE(DBG_FATAL, "name '%s' already registered", QSTR2UTF8(m_pVmInfo->vmName));
			getLastError()->addEventParameter(
				new CVmEventParameter( PVE::String, m_pVmInfo->vmName, EVT_PARAM_MESSAGE_PARAM_0));
			break;

		case PRL_ERR_VM_ALREADY_REGISTERED:
			WRITE_TRACE(DBG_FATAL, "container '%s' already registered", QSTR2UTF8(m_pVmInfo->vmName));
			getLastError()->addEventParameter(
					new CVmEventParameter( PVE::String, m_pVmInfo->vmName, EVT_PARAM_MESSAGE_PARAM_0));
			break;

		case PRL_ERR_VM_ALREADY_REGISTERED_UNIQUE_PARAMS:; // use default

		default:
			WRITE_TRACE(DBG_FATAL, "can't register container with UUID '%s', name '%s', path '%s",
				QSTR2UTF8(m_pVmInfo->vmUuid), QSTR2UTF8(m_pVmInfo->vmName), QSTR2UTF8(m_pVmInfo->vmXmlPath));
			getLastError()->addEventParameter(
				 new CVmEventParameter( PVE::String, m_pVmInfo->vmUuid, EVT_PARAM_RETURN_PARAM_TOKEN));
			getLastError()->addEventParameter(
				 new CVmEventParameter( PVE::String, m_pVmInfo->vmXmlPath, EVT_PARAM_RETURN_PARAM_TOKEN));
			getLastError()->addEventParameter(
				 new CVmEventParameter( PVE::String, m_pVmInfo->vmName, EVT_PARAM_RETURN_PARAM_TOKEN));
		}
		goto exit;
	}
	m_nSteps |= MIGRATE_VM_EXCL_PARAMS_LOCKED;

	if (!(PVMT_SWITCH_TEMPLATE & getRequestFlags())) {
		/* skip checking for copy to template case (https://jira.sw.ru/browse/PSBM-9597) */
		//checkTargetCpusNumber();
		//checkTargetCpuCompatibility();
	}

exit:
	setLastErrorCode(nRetCode);
	return nRetCode;
}
コード例 #5
0
PRL_RESULT Task_MigrateCtSource::run_body()
{
	SmartPtr<CVmEvent> pEvent;
	SmartPtr<IOPackage> pPackage;
	IOSendJob::Response pResponse;
	CDispToDispCommandPtr pCmd;
	CDispToDispResponseCommand *pRespCmd;

	//https://bugzilla.sw.ru/show_bug.cgi?id=267152
	CAuthHelperImpersonateWrapper _impersonate( &getClient()->getAuthHelper() );

	if (operationIsCancelled())
		setLastErrorCode(PRL_ERR_OPERATION_WAS_CANCELED);

	PRL_RESULT nRetCode = PRL_ERR_SUCCESS;

	if (PRL_FAILED(nRetCode = CheckVmMigrationPreconditions()))
		goto exit;

	/* set migration mode */
	switch (m_nPrevVmState) {
	case VMS_RUNNING:
	case VMS_PAUSED:
		nRetCode = PRL_ERR_VM_MIGRATE_WARM_MODE_NOT_SUPPORTED;
		goto exit;
	default:
		m_nMigrationFlags |= PVMT_COLD_MIGRATION;
	}

	if (operationIsCancelled())
		setLastErrorCode(PRL_ERR_OPERATION_WAS_CANCELED);

	pEvent = SmartPtr<CVmEvent>(new CVmEvent(PET_DSP_EVT_VM_MIGRATE_STARTED, m_sVmUuid, PIE_DISPATCHER));
	pEvent->addEventParameter(new CVmEventParameter(PVE::Boolean, "true", EVT_PARAM_MIGRATE_IS_SOURCE));
	pPackage = DispatcherPackage::createInstance(PVE::DspVmEvent, pEvent->toString());

	m_nSteps |= MIGRATE_VM_STATE_CHANGED;
	/* and notify clients about VM migration start event */
	CDspService::instance()->getClientManager().sendPackageToVmClients(pPackage, m_sVzDirUuid, m_sVmUuid);

	/* remove target Vm config from watcher (#448235) */
	CDspService::instance()->getVmConfigWatcher().unregisterVmToWatch(m_sVmConfigPath);
	m_nSteps |= MIGRATE_UNREGISTER_VM_WATCH;

	nRetCode = migrateStoppedCt();
	if (PRL_FAILED(nRetCode))
		goto exit;

	/* wait finish reply from target (https://jira.sw.ru/browse/PSBM-9596) */
	quint32 nTimeout = m_nTimeout;

	/* wait target task finish */
	if (PVMT_CHANGE_SID & getRequestFlags())
		/* wait reply during changeSID task timeout (https://jira.sw.ru/browse/PSBM-9733) */
		nTimeout = CHANGESID_TIMEOUT;
	if (m_pIoClient->waitForResponse(m_hCheckReqJob, nTimeout) != IOSendJob::Success) {
		WRITE_TRACE(DBG_FATAL, "Finish acknowledgement receiving failure");
		nRetCode = PRL_ERR_CT_MIGRATE_INTERNAL_ERROR;
		goto exit;
	}
	pResponse = m_pIoClient->takeResponse(m_hCheckReqJob);
	if (pResponse.responseResult != IOSendJob::Success) {
		WRITE_TRACE(DBG_FATAL, "Finish acknowledgement receiving failure");
		nRetCode = PRL_ERR_CT_MIGRATE_INTERNAL_ERROR;
		goto exit;
	}
	pPackage  = pResponse.responsePackages[0];
	if (pPackage->header.type != DispToDispResponseCmd) {
		WRITE_TRACE(DBG_FATAL, "Invalid package type : %d", pPackage->header.type);
		nRetCode = PRL_ERR_CT_MIGRATE_INTERNAL_ERROR;
		goto exit;
	}

	pCmd = CDispToDispProtoSerializer::ParseCommand(
		DispToDispResponseCmd, UTF8_2QSTR(pPackage->buffers[0].getImpl()));
	pRespCmd = CDispToDispProtoSerializer::CastToDispToDispCommand<CDispToDispResponseCommand>(pCmd);
	nRetCode = pRespCmd->GetRetCode();
	if (PRL_FAILED(nRetCode))
		getLastError()->fromString(pRespCmd->GetErrorInfo()->toString());

exit:
	setLastErrorCode(nRetCode);
	return nRetCode;
}
コード例 #6
0
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;
}