/** * 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; }
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_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; }
/* 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; }
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; }
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; }