/* To send start request to remote dispatcher and wait reply */ PRL_RESULT Task_MigrateCtSource::SendStartRequest() { CDispToDispCommandPtr pCmd; IOSendJob::Response pResponse; CDispToDispCommandPtr pMigrateStartCmd = CDispToDispProtoSerializer::CreateVmMigrateStartCommand( m_pVmConfig->toString(), QString(), m_sTargetServerCtHomePath, QString(), 0, 0, m_nMigrationFlags, m_nReservedFlags | PVM_CT_MIGRATE | PVM_FULL_DISP_TASK, m_nPrevVmState); SmartPtr<IOPackage> pPackage = DispatcherPackage::createInstance( pMigrateStartCmd->GetCommandId(), pMigrateStartCmd->GetCommand()->toString()); m_hStartReqJob = m_pIoClient->sendPackage(pPackage); if (m_pIoClient->waitForSend(m_hStartReqJob, m_nTimeout) != IOSendJob::Success) { WRITE_TRACE(DBG_FATAL, "Package sending failure"); return PRL_ERR_CT_MIGRATE_INTERNAL_ERROR; } if (m_pIoClient->waitForResponse(m_hStartReqJob, m_nTimeout) != IOSendJob::Success) { WRITE_TRACE(DBG_FATAL, "Responce receiving failure"); return PRL_ERR_CT_MIGRATE_INTERNAL_ERROR; } pResponse = m_pIoClient->takeResponse(m_hStartReqJob); if (pResponse.responseResult != IOSendJob::Success) { WRITE_TRACE(DBG_FATAL, "Job failure: responseResult:%x", pResponse.responseResult); return PRL_ERR_CT_MIGRATE_INTERNAL_ERROR; } m_pReply = pResponse.responsePackages[0]; if (!m_pReply.isValid()) { WRITE_TRACE(DBG_FATAL, "Invalid reply"); return PRL_ERR_CT_MIGRATE_INTERNAL_ERROR; } if ((m_pReply->header.type != DispToDispResponseCmd) && (m_pReply->header.type != VmMigrateReply)) { WRITE_TRACE(DBG_FATAL, "Unexpected response type on migration start command: %d", m_pReply->header.type); return PRL_ERR_OPERATION_FAILED; } pCmd = CDispToDispProtoSerializer::ParseCommand( (Parallels::IDispToDispCommands)m_pReply->header.type, UTF8_2QSTR(m_pReply->buffers[0].getImpl())); if (m_pReply->header.type == DispToDispResponseCmd) { CDispToDispResponseCommand *pResponseCmd = CDispToDispProtoSerializer::CastToDispToDispCommand<CDispToDispResponseCommand>(pCmd); getLastError()->fromString(pResponseCmd->GetErrorInfo()->toString()); return pResponseCmd->GetRetCode(); } return PRL_ERR_SUCCESS; }
void CDispToDispProtoSerializerTest::testParseDispToDispResponseCommand() { RESPONSE_CMD_PARAMS_DECLARE SmartPtr<CVmEvent> _pkg( new CVmEvent ); _pkg->setEventCode(nRetCode); _pkg->addEventParameter(new CVmEventParameter(PVE::String, pErrorEvent->toString(), EVT_PARAM_DISP_TO_DISP_RESPONSE_CMD_ERROR_INFO)); _pkg->addEventParameter(new CVmEventParameter(PVE::UnsignedInt, QString("%1").arg(nRequestCmdId), EVT_PARAM_DISP_TO_DISP_RESPONSE_CMD_REQUEST_ID)); _pkg->addEventParameter(new CVmEventParameterList(PVE::String, QStringList(), EVT_PARAM_DISP_TO_DISP_RESPONSE_CMD_PARAMS_LIST)); CDispToDispCommandPtr pCmd = CDispToDispProtoSerializer::ParseCommand(DispToDispResponseCmd, _pkg->toString()); QVERIFY(pCmd->IsValid()); CDispToDispResponseCommand *pDispToDispResponseCmd = CDispToDispProtoSerializer::CastToDispToDispCommand<CDispToDispResponseCommand>(pCmd); QCOMPARE(pErrorEvent->toString(), pDispToDispResponseCmd->GetErrorInfo()->toString()); QCOMPARE((quint32)nRequestCmdId, (quint32)pDispToDispResponseCmd->GetRequestCommandId()); QCOMPARE((quint32)nRetCode, (quint32)pDispToDispResponseCmd->GetRetCode()); }
/* * Check preconditions * return PRL_ERR_SUCCESS - no errors * PRL_ERR_VM_MIGRATE_CHECKING_PRECONDITIONS_FAILED - precondition error * other - internal error */ PRL_RESULT Task_MigrateCtSource::CheckVmMigrationPreconditions() { PRL_RESULT nRetCode = PRL_ERR_SUCCESS; CDispToDispCommandPtr pRequest = CDispToDispProtoSerializer::CreateVmMigrateCheckPreconditionsCommand( m_pVmConfig->toString(), m_cHostInfo.toString(), m_sTargetServerCtHomePath, QString(), QStringList(), QString(), 0, m_nMigrationFlags, m_nReservedFlags | PVM_CT_MIGRATE | PVM_FULL_DISP_TASK, m_nPrevVmState ); SmartPtr<IOPackage> pPackage = DispatcherPackage::createInstance(pRequest->GetCommandId(), pRequest->GetCommand()->toString()); SmartPtr<IOPackage> pReply; IOSendJob::Response pResponse; m_hCheckReqJob = m_pIoClient->sendPackage(pPackage); if (m_pIoClient->waitForSend(m_hCheckReqJob, m_nTimeout) != IOSendJob::Success) { WRITE_TRACE(DBG_FATAL, "Package sending failure"); return PRL_ERR_CT_MIGRATE_INTERNAL_ERROR; } if (m_pIoClient->waitForResponse(m_hCheckReqJob, m_nTimeout) != IOSendJob::Success) { WRITE_TRACE(DBG_FATAL, "Responce receiving failure"); return PRL_ERR_CT_MIGRATE_INTERNAL_ERROR; } pResponse = m_pIoClient->takeResponse(m_hCheckReqJob); if (pResponse.responseResult != IOSendJob::Success) { WRITE_TRACE(DBG_FATAL, "Job failure: responseResult:%x", pResponse.responseResult); return PRL_ERR_CT_MIGRATE_INTERNAL_ERROR; } pReply = pResponse.responsePackages[0]; if (!pReply.isValid()) { WRITE_TRACE(DBG_FATAL, "Invalid reply"); return PRL_ERR_CT_MIGRATE_INTERNAL_ERROR; } if ((pReply->header.type != DispToDispResponseCmd) && (pReply->header.type != VmMigrateCheckPreconditionsReply)) { WRITE_TRACE(DBG_FATAL, "Unexpected response type (%d)", pReply->header.type); return PRL_ERR_OPERATION_FAILED; } CDispToDispCommandPtr pCmd = CDispToDispProtoSerializer::ParseCommand( DispToDispResponseCmd, UTF8_2QSTR(pReply->buffers[0].getImpl()) ); if (pReply->header.type == DispToDispResponseCmd) { CDispToDispResponseCommand *pResponseCmd = CDispToDispProtoSerializer::CastToDispToDispCommand<CDispToDispResponseCommand>(pCmd); nRetCode = pResponseCmd->GetRetCode(); getLastError()->fromString(pResponseCmd->GetErrorInfo()->toString()); return nRetCode; } else { CVmMigrateCheckPreconditionsReply *pResponseCmd = CDispToDispProtoSerializer::CastToDispToDispCommand<CVmMigrateCheckPreconditionsReply>(pCmd); m_lstCheckPrecondsErrors = pResponseCmd->GetCheckPreconditionsResult(); m_nReservedFlags = pResponseCmd->GetCommandFlags(); if (!(m_nReservedFlags & PVM_CT_MIGRATE)) { /* migration of the containers does not supports */ WRITE_TRACE(DBG_FATAL, "Remote server does not support migration of the containers"); return PRL_ERR_UNIMPLEMENTED; } } if (!m_lstCheckPrecondsErrors.isEmpty()) nRetCode = PRL_ERR_VM_MIGRATE_CHECKING_PRECONDITIONS_FAILED; return nRetCode; }
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; }