PRL_RESULT CDspVmAutoTaskManagerBase::unregisterVm(const CVmIdent& vmIdent, bool bEditVmConfig, const SmartPtr<CDspClient>& pClient) { WRITE_TRACE( DBG_DEBUG, "Unregistering VM '%s' from %s manager", QSTR2UTF8( vmIdent.first ), getManagerName() ); // Clear settings { CDspLockedPointer<QSettings> pQSettings = CDspService::instance()->getQSettings(); QString qsGroup = getSettingsGroupKey(vmIdent); pQSettings->remove(qsGroup); } { QMutexLocker locker(&m_lockVmIdents); if ( ! m_mapVmIdents.contains(vmIdent) ) return PRL_ERR_SUCCESS; // Stop timer emit killVmTimerSignal(m_mapVmIdents.value(vmIdent).iTimerId); // TODO: Check running task for this VM. Cancel it ? // Unregister VM m_mapVmIdents.remove(vmIdent); } return finalizeUnregistration( vmIdent, pClient, bEditVmConfig ); }
PRL_RESULT Task_ChangeSID::save_config(SmartPtr<CVmConfiguration> &pVmConfig) { PRL_RESULT ret; CDspLockedPointer< CVmDirectoryItem > pVmDirItem = CDspService::instance()->getVmDirManager() .getVmDirItemByUuid(getClient()->getVmDirectoryUuid(), getVmUuid()); if (!pVmDirItem) return PRL_ERR_VM_UUID_NOT_FOUND; ret = CDspService::instance()->getVmConfigManager().saveConfig(pVmConfig, pVmDirItem->getVmHome(), getClient(), true, true); if (PRL_FAILED(ret)) { WRITE_TRACE(DBG_FATAL, "Unable to save configuration of the VM to file %s. Reason: %ld: %s", pVmConfig->getOutFileName().toUtf8().data(), Prl::GetLastError(), QSTR2UTF8( Prl::GetLastErrorAsString()) ); return ret; } return PRL_ERR_SUCCESS; }
QString CDspDispConfigGuard::getDispUserByUuidAsString( const QString& userUuid ) { CDspLockedPointer<CDispUser> pUser = getDispUserByUuid( userUuid ); QString sUserProfile; if (pUser.getPtr()) sUserProfile = pUser->toString(); return sUserProfile; }
// check if addition vm state was changed and post event if changed void CDspTaskHelper::checkVmAdditionState( bool bExcludeThisForSearch ) { if( !providedAdditionState() || !getClient() ) return; if( getVmUuid().isEmpty() ) return; VIRTUAL_MACHINE_ADDITION_STATE state = CDspVm::getVmAdditionState( getVmUuid(), getClient()->getVmDirectoryUuid(), bExcludeThisForSearch ? this : NULL ); CDspLockedPointer<CDspVmStateSender> pLockedVmStateSender = CDspService::instance()->getVmStateSender(); if( pLockedVmStateSender ) pLockedVmStateSender->onVmAdditionStateChanged( state, getVmUuid(), getClient()->getVmDirectoryUuid() ); }
PRL_RESULT CDspDispConfigGuard::saveConfig( const QString& path, bool bNoSaveNetwork ) { CDspLockedPointer<CDispatcherConfig> pLockedDispConfig = getDispConfig(); CDispNetworkPreferences* pNetwork = pLockedDispConfig->getDispatcherSettings() ->getCommonPreferences()->getNetworkPreferences(); CDispLockedOperationsList* pLockedOperationsList = pLockedDispConfig->getDispatcherSettings()->getCommonPreferences() ->getLockedOperationsList(); bool oldFlg = pNetwork->getNoSaveFlag(); pNetwork->setNoSaveFlag( bNoSaveNetwork ); // patch to not save operations with confirmation // #436109 ( we store this values in vmdirectory list to prevent deadlock in CDspAccessManager::checkAccess() ) QList<PRL_ALLOWED_VM_COMMAND> confirmList = pLockedOperationsList->getLockedOperations(); pLockedOperationsList->setLockedOperations( ); CDispBackupSourcePreferences *pBackup = pLockedDispConfig->getDispatcherSettings() ->getCommonPreferences()->getBackupSourcePreferences(); pBackup->setSave(false); PRL_RESULT save_rc = pLockedDispConfig->saveToFile( path ); pBackup->setSave(true); pNetwork->setNoSaveFlag( oldFlg ); pLockedOperationsList->setLockedOperations( confirmList ); if( PRL_FAILED(save_rc) ) { WRITE_TRACE(DBG_FATAL, "Error %s on save dispatcher config. Reason: %ld: %s. path = '%s'" , PRL_RESULT_TO_STRING(save_rc) , Prl::GetLastError() , QSTR2UTF8( Prl::GetLastErrorAsString() ) , QSTR2UTF8( path ) ); return PRL_ERR_DISP_CONFIG_WRITE_ERR; } return PRL_ERR_SUCCESS; }
void Task_VzStateMonitor::processConfigChangedEvt(const QString &sUuid) { // Handle Name change CDspLockedPointer< CVmDirectoryItem > pVmDirItem = CDspService::instance()->getVmDirManager() .getVmDirItemByUuid(CDspVmDirManager::getVzDirectoryUuid(), sUuid ); if (!pVmDirItem) return; SmartPtr<CVmConfiguration> pConfig = CDspService::instance()->getVzHelper()-> getCtConfig(CDspClient::makeServiceUser(), sUuid); if (!pConfig) return; QString sNewName = pConfig->getVmIdentification()->getVmName(); if (pVmDirItem->getVmName() != sNewName && !sNewName.isEmpty()) { pVmDirItem->setVmName(sNewName); 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)); } }
void CDspVmAutoTaskManagerBase::timerEvent(QTimerEvent* te) { if (!IsInitialized()) { WRITE_TRACE( DBG_WARNING, "Timer event on unitialized %s manager", getManagerName() ); return; } // Looking for proper VM ident. bool bRestartTimer = false; TimerInfo timerInfo; CVmIdent vmIdent; { QMutexLocker locker(&m_lockVmIdents); QMap<CVmIdent, TimerInfo >::iterator it; for(it = m_mapVmIdents.begin(); it != m_mapVmIdents.end(); ++it) { timerInfo = it.value(); if (timerInfo.iTimerId == te->timerId()) break; } if ( it == m_mapVmIdents.end() || timerInfo.bTaskInUse) return; vmIdent = it.key(); bRestartTimer = (timerInfo.iPeriod != timerInfo.iOriginalPeriod); if (bRestartTimer) { emit killVmTimerSignal(timerInfo.iTimerId); m_mapVmIdents.remove(vmIdent); } } if (bRestartTimer) { emit startVmTimerSignal(vmIdent, timerInfo.iOriginalPeriod, timerInfo.iOriginalPeriod); } // Store timestamp { CDspLockedPointer<QSettings> pQSettings = CDspService::instance()->getQSettings(); QString qsGroup = getSettingsGroupKey(vmIdent); pQSettings->beginGroup(qsGroup); pQSettings->setValue(getSettingsKeyTimestamp(), QVariant(QDateTime::currentDateTime())); pQSettings->endGroup(); } // Get client QHash< IOSender::Handle, SmartPtr<CDspClient> > hashClients = CDspService::instance()->getClientManager().getSessionListByVm( vmIdent.second, vmIdent.first, CDspAccessManager::VmAccessRights::makeModeRWX() ); if ( hashClients.empty() ) { WRITE_TRACE(DBG_FATAL, "No clients connect to VM %s with required permissions", QSTR2UTF8(vmIdent.first) ); return; } // Start auto task if ( ! updateTaskState(vmIdent, true) ) return; // Fake client SmartPtr<CDspClient> pClient( new CDspClient(IOSender::Handle()) ); pClient->getAuthHelper().AuthUserBySelfProcessOwner(); pClient->setVmDirectoryUuid(vmIdent.second); startTask( pClient, vmIdent ); }
PRL_RESULT CDspVmAutoTaskManagerBase::tryToRegisterVm(const SmartPtr<CVmConfiguration>& pVmConfig, const QString& qsVmDirUuid, int iRecommendedNextTime) { if ( ! pVmConfig ) return PRL_ERR_FAILURE; CVmIdent vmIdent = MakeVmIdent(pVmConfig->getVmIdentification()->getVmUuid(), qsVmDirUuid); // Fake client (calling at starting dispatcher from Init()) SmartPtr<CDspClient> pClient( new CDspClient(IOSender::Handle()) ); pClient->getAuthHelper().AuthUserBySelfProcessOwner(); pClient->setVmDirectoryUuid(vmIdent.second); PRL_RESULT res = prepareRegistration( vmIdent, pClient ); if ( PRL_FAILED( res ) ) return res; if ( !isEnabled( pVmConfig, false ) ) return unregisterVm(vmIdent); // Check period int iPeriod; res = getPeriod( pVmConfig, iPeriod ); if ( PRL_FAILED( res ) ) return res; // Register VM and start timer { QMutexLocker locker(&m_lockVmIdents); if (m_mapVmIdents.contains(vmIdent)) { TimerInfo timerInfo = m_mapVmIdents.value(vmIdent); if ( timerInfo.bAutoTask ) { int iOldPeriod = timerInfo.iPeriod; if (iOldPeriod && iOldPeriod != iPeriod) { emit killVmTimerSignal(timerInfo.iTimerId); m_mapVmIdents.remove(vmIdent); } else { return PRL_ERR_SUCCESS; } } } } // Check timestamp QDateTime dtNow = QDateTime::currentDateTime(); QDateTime dtTimestamp; { CDspLockedPointer<QSettings> pQSettings = CDspService::instance()->getQSettings(); QString qsGroup = getSettingsGroupKey(vmIdent); pQSettings->beginGroup(qsGroup); QString qsKeyTimeStamp = getSettingsKeyTimestamp(); dtTimestamp = pQSettings->value(qsKeyTimeStamp, QVariant(dtNow)).toDateTime(); if ( ! pQSettings->contains(qsKeyTimeStamp) ) pQSettings->setValue(qsKeyTimeStamp, QVariant(dtNow)); pQSettings->endGroup(); } int iOriginalPeriod = iPeriod; int iSkippedInterval = dtTimestamp.secsTo( dtNow ); if ( iSkippedInterval > 0 ) { iPeriod = (iSkippedInterval > iPeriod ? 0 : iPeriod - iSkippedInterval); } if ( iRecommendedNextTime ) iPeriod = qMin(iPeriod, iRecommendedNextTime); WRITE_TRACE( DBG_FATAL, "%s manager: register VM %s with period %d (%d)", getManagerName(), QSTR2UTF8( pVmConfig->getVmIdentification()->getVmName() ), iPeriod, iOriginalPeriod ); emit startVmTimerSignal(vmIdent, iPeriod, iOriginalPeriod); return PRL_ERR_SUCCESS; }
/* 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::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; }
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; }
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; }