PRL_RESULT Task_GetBackupTreeTarget::run_body() { //https://bugzilla.sw.ru/show_bug.cgi?id=267152 CAuthHelperImpersonateWrapper _impersonate( &getClient()->getAuthHelper() ); PRL_RESULT nRetCode = PRL_ERR_SUCCESS; QString msg; CDispToDispCommandPtr pReply; SmartPtr<IOPackage> pPackage; getBackupTree(msg); pReply = CDispToDispProtoSerializer::CreateGetBackupTreeReply(msg); pPackage = DispatcherPackage::createInstance( pReply->GetCommandId(), pReply->GetCommand()->toString(), getRequestPackage()); IOSendJob::Handle hJob = m_pDispConnection->sendPackage(pPackage); if (CDspService::instance()->getIOServer().waitForSend(hJob, m_nTimeout) != IOSendJob::Success) { WRITE_TRACE(DBG_FATAL, "Package sending failure"); setLastErrorCode(PRL_ERR_BACKUP_INTERNAL_PROTO_ERROR); return PRL_ERR_BACKUP_INTERNAL_PROTO_ERROR; } return nRetCode; }
/* 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; }
PRL_RESULT Task_MigrateCtTarget::migrateStoppedVm() { PRL_RESULT nRetCode = PRL_ERR_SUCCESS; CDispToDispCommandPtr pReply; SmartPtr<IOPackage> pPackage; m_pSender = SmartPtr<CVmFileListCopySender>(new CVmFileListCopySenderServer( CDspService::instance()->getIOServer(), m_pStartDispConnection->GetConnectionHandle())); /* CVmFileListCopyTarget will use Vm uuid in progress messages for clients, so will use original Vm uuid */ m_pVmMigrateTarget = SmartPtr<CVmFileListCopyTarget>( new CVmFileListCopyTarget(m_pSender.getImpl(), m_sOriginVmUuid, m_sTargetVmHomePath, NULL, m_nTimeout)); // Connect to handle traffic report package bool bConnected = QObject::connect( m_pStartDispConnection.getImpl(), SIGNAL(onPackageReceived(IOSender::Handle, const SmartPtr<IOPackage>)), SLOT(handlePackage(IOSender::Handle, const SmartPtr<IOPackage>)), Qt::DirectConnection ); PRL_ASSERT(bConnected); // set empty string for default path pReply = CDispToDispProtoSerializer::CreateVmMigrateReply(QString()); pPackage = DispatcherPackage::createInstance( pReply->GetCommandId(), pReply->GetCommand()->toString(), m_pStartPackage); m_pStartDispConnection->sendPackage(pPackage); nRetCode = QThread::exec(); QObject::disconnect( m_pStartDispConnection.getImpl(), SIGNAL(onPackageReceived(IOSender::Handle, const SmartPtr<IOPackage>)), this, SLOT(handlePackage(IOSender::Handle, const SmartPtr<IOPackage>))); if (PRL_FAILED(nRetCode)) return nRetCode; return PRL_ERR_SUCCESS; }
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; }
/* * 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; }