PRL_RESULT CDspHaClusterHelper::updateClusterResourceParams(const QString & sName, CVmHighAvailability *oldHa, CVmHighAvailability *newHa, const QString & newPath, PRL_VM_TYPE vmType) { QProcess proc; QStringList args; QString cmd; PRL_ASSERT(oldHa); PRL_ASSERT(newHa); if (newHa->isEnabled() != oldHa->isEnabled()) cmd = newHa->isEnabled() ? SHAMAN_CMD_ADD : SHAMAN_CMD_DEL; else if (newHa->getPriority() != oldHa->getPriority()) { cmd = SHAMAN_CMD_SET; } else { /* HA options are not changed */ return PRL_ERR_SUCCESS; } /* * Don't run shaman if HA is disabled in VM config and the command line * doesn't contain '--ha-enable yes'. */ if ((newHa->isEnabled() == oldHa->isEnabled()) && !newHa->isEnabled()) return PRL_ERR_SUCCESS; args += cmd; args += getResourcePrefix(vmType) + sName; if (cmd != SHAMAN_CMD_DEL) { /* * Specify all parameters from the config when doing 'shaman add'. * This is needed e.g. when registering an already existing VM - newly * created cluster resource for this VM should contain all actual * HA parameter values. */ if ((newHa->getPriority() != oldHa->getPriority()) || (cmd == SHAMAN_CMD_ADD)) { args += QString("--path"); args += newPath; args += QString("--prio"); args += QString("%1").arg(newHa->getPriority()); } } PRL_RESULT res = runHaman(args, proc); if (PRL_FAILED(res)) WRITE_TRACE(DBG_FATAL, "cluster resource '%s' registration error", QSTR2UTF8(sName)); return res; }
void CDspVmAutoTaskManagerBase::Init() { WRITE_TRACE( DBG_DEBUG, "Initializing %s manager", getManagerName() ); QMultiHash<QString , SmartPtr<CVmConfiguration> > hashAllVms = CDspService::instance()->getVmDirHelper().getAllVmList(); QMultiHash<QString , SmartPtr<CVmConfiguration> >::iterator it; for(it = hashAllVms.begin(); it != hashAllVms.end(); ++it) { SmartPtr<CVmConfiguration> pVmConfig = it.value(); PRL_ASSERT(pVmConfig); if (isEnabled(pVmConfig, true)) { PRL_RESULT res = tryToRegisterVm(pVmConfig, it.key()); if (PRL_FAILED(res)) WRITE_TRACE(DBG_FATAL, "Can't register VM %s in Auto-task Manager during starting dispetcher." "Error: 0x%x, (%s).", QSTR2UTF8(pVmConfig->getVmIdentification()->getVmUuid()), res, PRL_RESULT_TO_STRING(res) ); } } m_bInitialized = true; }
Task_MigrateCtSource::Task_MigrateCtSource( const SmartPtr<CDspClient>& client, const CProtoCommandPtr cmd, const SmartPtr<IOPackage>& p) : CDspTaskHelper(client, p), Task_DispToDispConnHelper(getLastError()), m_pVmConfig(new CVmConfiguration()), m_bNewVmInstance(false), m_nSteps(0), m_nTotalSize(0), m_pOpaqueLock(NULL) { CProtoVmMigrateCommand *pCmd = CProtoSerializer::CastToProtoCommand<CProtoVmMigrateCommand>(cmd); PRL_ASSERT(pCmd->IsValid()); m_sVmUuid = pCmd->GetVmUuid(); m_sServerHostname = pCmd->GetTargetServerHostname(); m_nServerPort = pCmd->GetTargetServerPort(); if (m_nServerPort == 0) m_nServerPort = CDspService::getDefaultListenPort(); m_sServerSessionUuid = pCmd->GetTargetServerSessionUuid(); m_sTargetServerCtHomePath = pCmd->GetTargetServerVmHomePath(); m_nMigrationFlags = pCmd->GetMigrationFlags(); m_nReservedFlags = pCmd->GetReservedFlags(); m_bExVmOperationRegistered = false; }
void Task_MigrateCtTarget::handlePackage(IOSender::Handle h, const SmartPtr<IOPackage> p) { PRL_RESULT nRetCode; bool bExit; PRL_ASSERT(m_pVmMigrateTarget.getImpl()); // #439777 to protect call handler for destroying object WaiterTillHandlerUsingObject::AutoUnlock lock( m_waiter ); if( !lock.isLocked() ) return; if (h != m_pStartDispConnection->GetConnectionHandle()) return; if (IS_FILE_COPY_PACKAGE(p->header.type)) { nRetCode = m_pVmMigrateTarget->handlePackage(p, &bExit); if (bExit) QThread::exit(nRetCode); } else if (p->header.type == VmMigrateCancelCmd) { WRITE_TRACE(DBG_DEBUG, "Migration was cancelled"); QThread::exit(PRL_ERR_OPERATION_WAS_CANCELED); } else { WRITE_TRACE(DBG_FATAL, "Invalid package type %d, ignored", p->header.type); } }
PRL_RESULT CDspHaClusterHelper::addClusterResource(const QString & sName, const CVmHighAvailability *ha, const QString & sPath) { PRL_ASSERT(ha); if (!ha->isEnabled()) return PRL_ERR_SUCCESS; // handle only VM on shared FS - nfs, gfs, gfs2, pcs if (!CFileHelper::isSharedFS(sPath)) return PRL_ERR_SUCCESS; QProcess proc; QStringList args; args += SHAMAN_CMD_ADD; args += getResourcePrefix() + sName; args += QString("--prio"); args += QString("%1").arg(ha->getPriority()); args += QString("--path"); args += sPath; args += QString("--force"); PRL_RESULT res = runHaman(args, proc); if (PRL_FAILED(res)) WRITE_TRACE(DBG_FATAL, "cluster resource '%s' registration error", QSTR2UTF8(sName)); return res; }
void CDspIOCtClientHandler::handleFromDispatcherPackage ( const SmartPtr<CDspHandler>&, const IOSender::Handle&, const SmartPtr<IOPackage>& ) { // Never should be called for this handler PRL_ASSERT(0); }
void Task_EventLoopBase::cancelOperation( SmartPtr<CDspClient> user, const SmartPtr<IOPackage>& pkg) { bool invoked = true; invoked &= QMetaObject::invokeMethod(this, "taskCancel", Qt::QueuedConnection); PRL_ASSERT(invoked); CDspTaskHelper::cancelOperation(user, pkg); }
PRL_RESULT Task_EventLoopBase::run_body() { bool invoked = true; invoked &= QMetaObject::invokeMethod(this, "onFirstEvent", Qt::QueuedConnection); PRL_ASSERT(invoked); QThread::exec(); return getLastErrorCode(); }
/** * Class constructor */ CDspHwMonitorHandler::CDspHwMonitorHandler( QObject * parent ) : QThread (parent), m_hResetEvent(INVALID_HANDLE_VALUE), m_FinalizationMutex(QMutex::Recursive) { g_pHwMonitorHandler = this; /* Event to stop HWMonitor */ m_hResetEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); if (m_hResetEvent == INVALID_HANDLE_VALUE) WRITE_TRACE(DBG_FATAL, "Failed to create StopEvent"); PRL_ASSERT(m_hResetEvent != INVALID_HANDLE_VALUE); }
PRL_RESULT Task_SyncVmsUptime::run_body() { quint32 nTimeout = CDspService::instance()->getDispConfigGuard().getDispWorkSpacePrefs()->getVmUptimeSyncTimeoutInMinutes(); if ( ! nTimeout ) { WRITE_TRACE(DBG_FATAL, "Synchronization up time task was not started due to timeout is zero !"); return (PRL_ERR_SUCCESS); } SmartPtr<QTimer> pTimer(new QTimer); bool bConnected = connect(pTimer.getImpl(), SIGNAL(timeout()), SLOT(onTimeoutEvent())); PRL_ASSERT(bConnected); pTimer->start(nTimeout*60*1000); exec(); return (PRL_ERR_SUCCESS); }
PRL_RESULT CDspHaClusterHelper::renameClusterResource(const QString & oldName, CVmHighAvailability *oldHa, const QString & newName, const QString & newPath) { PRL_ASSERT(oldHa); if (!oldHa->isEnabled()) return PRL_ERR_SUCCESS; PRL_RESULT res = addClusterResource(newName, oldHa, newPath); if (PRL_FAILED(res)) return res; /* Ignore errors on remove, can't do anything with them. */ removeClusterResource(oldName); 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; }
Task_MigrateCtTarget::Task_MigrateCtTarget( const QObject *parent, const SmartPtr<CDspDispConnection> &pDispConnection, CDispToDispCommandPtr pCmd, const SmartPtr<IOPackage> &p) : CDspTaskHelper(pDispConnection->getUserSession(), p), Task_DispToDispConnHelper(getLastError()), m_pParent(parent), m_pCheckDispConnection(pDispConnection), m_pCheckPackage(p), m_cDstHostInfo(CDspService::instance()->getHostInfo()->data()), m_pOpaqueLock(NULL), m_nSteps(0), m_nBundlePermissions(0), m_nConfigPermissions(0) { CVmMigrateCheckPreconditionsCommand * pCheckCmd = CDispToDispProtoSerializer::CastToDispToDispCommand<CVmMigrateCheckPreconditionsCommand>(pCmd); m_hConnHandle = pDispConnection->GetConnectionHandle(); m_nMigrationFlags = pCheckCmd->GetMigrationFlags(); m_nReservedFlags = pCheckCmd->GetReservedFlags(); m_nVersion = pCheckCmd->GetVersion(); m_sVmConfig = pCheckCmd->GetVmConfig(); m_nPrevVmState = pCheckCmd->GetVmPrevState(); m_sVmDirPath = pCheckCmd->GetTargetVmHomePath(); m_sSrcHostInfo = pCheckCmd->GetSourceHostHardwareInfo(); /* initialize all vars from pCheckCmd - after exit from constructor package buffer will invalid */ bool bConnected = QObject::connect( &CDspService::instance()->getIOServer(), SIGNAL(onClientDisconnected(IOSender::Handle)), SLOT(clientDisconnected(IOSender::Handle)), Qt::DirectConnection); PRL_ASSERT(bConnected); }
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; }
PRL_RESULT Mixin_CreateVmSupport::setDefaultVmPermissions( SmartPtr<CDspClient> pUser, QString vmPathToConfig, bool bKeepOthersPermissions ) { PRL_ASSERT( pUser ); PRL_ASSERT( ! vmPathToConfig.isEmpty() ); if( ! pUser || vmPathToConfig.isEmpty() ) return PRL_ERR_INVALID_ARG; // FIXME: isFsSupportPermsAndOwner() should be moved near setFullAccessRightsToVm() and united with it. { //https://bugzilla.sw.ru/show_bug.cgi?id=267152 CAuthHelperImpersonateWrapper _impersonate( &pUser->getAuthHelper() ); // # https://bugzilla.sw.ru/show_bug.cgi?id=112901 // https://jira.sw.ru/browse/PSBM-9040 if( !CFileHelper::isFsSupportPermsAndOwner( vmPathToConfig ) ) { WRITE_TRACE(DBG_FATAL, "File system does not support permissions. Setting default Vm permission will be ignored. (path=%s)" , QSTR2UTF8( vmPathToConfig ) ); return PRL_ERR_SUCCESS; } } // get vm directory path // To prevent stupid errors see https://bugzilla.sw.ru/show_bug.cgi?id=483700 for more details PRL_ASSERT(QFileInfo( vmPathToConfig ).isFile()); QString strVmDirPath; if ( QFileInfo( vmPathToConfig ).isFile() ) strVmDirPath = CFileHelper::GetFileRoot( vmPathToConfig ); else { strVmDirPath = vmPathToConfig; vmPathToConfig = QString("%1/%2").arg(strVmDirPath).arg(VMDIR_DEFAULT_VM_CONFIG_FILE); } if ( !CDspAccessManager::setOwner( strVmDirPath, &pUser->getAuthHelper(), true ) ) { WRITE_TRACE(DBG_FATAL, "Can't change owner to vm dir files [%s]. error=[%s]" , QSTR2UTF8( strVmDirPath ) , QSTR2UTF8( Prl::GetLastErrorAsString() ) ); return PRL_ERR_CANT_CHANGE_OWNER_OF_FILE; } ////////////////////////////////////////////////////////////////////////// // set default access rigths ////////////////////////////////////////////////////////////////////////// CVmDirectoryItem vmDirItem; vmDirItem.setVmHome( vmPathToConfig ); PRL_SEC_AM ownerAccess = CDspAccessManager::VmAccessRights::makeModeRWX() ; PRL_SEC_AM otherAccess = CDspAccessManager::VmAccessRights::makeModeNO_ACCESS() ; PRL_RESULT err = CDspService::instance()->getAccessManager() .setFullAccessRightsToVm( pUser, &vmDirItem, &ownerAccess, // Do not change others permissions during registration at desktop mode // https://bugzilla.sw.ru/show_bug.cgi?id=120191 ! bKeepOthersPermissions ? &otherAccess : NULL ); if( PRL_FAILED( err ) ) { WRITE_TRACE(DBG_FATAL, "Can't change permission to vm dir files [%s]. error=[%s]" , QSTR2UTF8( strVmDirPath ) , QSTR2UTF8( Prl::GetLastErrorAsString() ) ); return PRL_ERR_CANT_CHANGE_FILE_PERMISSIONS; } return PRL_ERR_SUCCESS; }