PRL_RESULT Task_GetBackupTreeSource::run_body() { //https://bugzilla.sw.ru/show_bug.cgi?id=267152 CAuthHelperImpersonateWrapper _impersonate( &getClient()->getAuthHelper() ); PRL_RESULT nRetCode = PRL_ERR_SUCCESS; QFileInfoList excludeList; QFileInfoList dirList; QFileInfoList fileList; if (PRL_FAILED(nRetCode = connect())) goto exit; if (PRL_FAILED(nRetCode = GetBackupTreeRequest(m_sUuid, m_sBackupTree))) goto exit; exit: setLastErrorCode(nRetCode); return nRetCode; }
PRL_RESULT CDspHaClusterHelper::moveToClusterResource(const QString & sName, const QString & sRemoteNode) { QProcess proc; QStringList args; args += SHAMAN_CMD_TO; args += getResourcePrefix() + sName; args += sRemoteNode; PRL_RESULT res = runHaman(args, proc); if (PRL_FAILED(res)) WRITE_TRACE(DBG_FATAL, "cluster resource '%s' removing error", QSTR2UTF8(sName)); return res; }
PRL_RESULT Task_MigrateCtSource::migrateStoppedCt() { PRL_RESULT nRetCode = PRL_ERR_SUCCESS; int i; QList<QPair<QFileInfo, QString> > dList; QList<QPair<QFileInfo, QString> > fList; if ( !(m_nReservedFlags & PVM_DONT_COPY_VM) ) /* get full directories and files lists for migration */ if ((nRetCode = GetEntryLists(m_sVmHomePath, dList, fList)) != PRL_ERR_SUCCESS) return nRetCode; if (PRL_FAILED(nRetCode = SendStartRequest())) return nRetCode; /* calculate total transaction size */ for (i = 0; i < fList.size(); ++i) m_nTotalSize += fList.at(i).first.size(); m_pSender = SmartPtr<CVmFileListCopySender>(new CVmFileListCopySenderClient(m_pIoClient)); m_pVmCopySource = SmartPtr<CVmFileListCopySource>( new CVmFileListCopySource( m_pSender.getImpl(), m_pVmConfig->getVmIdentification()->getVmUuid(), m_sVmHomePath, m_nTotalSize, getLastError(), m_nTimeout)); m_pVmCopySource->SetRequest(getRequestPackage()); m_pVmCopySource->SetVmDirectoryUuid(m_sVzDirUuid); m_pVmCopySource->SetProgressNotifySender(NotifyClientsWithProgress); nRetCode = m_pVmCopySource->Copy(dList, fList); if (PRL_FAILED(nRetCode)) WRITE_TRACE(DBG_FATAL, "Error occurred while migration with code [%#x][%s]", nRetCode, PRL_RESULT_TO_STRING(nRetCode)); return nRetCode; }
PRL_RESULT CDspHaClusterHelper::removeClusterResource(const QString & sName, bool removeFromAllNodes) { QProcess proc; QStringList args; args += removeFromAllNodes ? SHAMAN_CMD_DEL_EVERYWHERE : SHAMAN_CMD_DEL; args += getResourcePrefix() + sName; WRITE_TRACE(DBG_FATAL, "%s removing resource %s", removeFromAllNodes ? "recursively" : "", QSTR2UTF8(sName)); PRL_RESULT res = runHaman(args, proc); if (PRL_FAILED(res)) WRITE_TRACE(DBG_FATAL, "cluster resource '%s' removing error", QSTR2UTF8(sName)); return res; }
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; }
PRL_RESULT Task_VzManager::umount_env() { CProtoCommandPtr cmd = CProtoSerializer::ParseCommand( getRequestPackage()); if ( ! cmd->IsValid() ) return PRL_ERR_FAILURE; PRL_RESULT res; QString sUuid = cmd->GetVmUuid(); res = check_env_state(PVE::DspCmdVmUmount, sUuid); if (PRL_FAILED(res)) return res; return get_op_helper()->umount_env(sUuid); }
PRL_RESULT Task_VzManager::checkAndLockRegisterParameters( CVmDirectory::TemporaryCatalogueItem *pVmInfo) { PRL_RESULT lockResult = CDspService::instance()->getVmDirManager() .checkAndLockNotExistsExclusiveVmParameters(QStringList(), pVmInfo); if (PRL_FAILED( lockResult)) { switch (lockResult) { case PRL_ERR_VM_ALREADY_REGISTERED_VM_UUID: getLastError()->addEventParameter( new CVmEventParameter( PVE::String, pVmInfo->vmUuid, EVT_PARAM_RETURN_PARAM_TOKEN)); break; case PRL_ERR_VM_ALREADY_REGISTERED_VM_PATH: getLastError()->addEventParameter( new CVmEventParameter( PVE::String, pVmInfo->vmName, EVT_PARAM_MESSAGE_PARAM_0)); getLastError()->addEventParameter( new CVmEventParameter( PVE::String, pVmInfo->vmXmlPath, EVT_PARAM_MESSAGE_PARAM_1)); break; case PRL_ERR_VM_ALREADY_REGISTERED_VM_NAME: getLastError()->addEventParameter( new CVmEventParameter( PVE::String, pVmInfo->vmName, EVT_PARAM_MESSAGE_PARAM_0)); break; case PRL_ERR_VM_ALREADY_REGISTERED: getLastError()->addEventParameter( new CVmEventParameter( PVE::String, pVmInfo->vmName, EVT_PARAM_MESSAGE_PARAM_0)); break; case PRL_ERR_VM_ALREADY_REGISTERED_UNIQUE_PARAMS:; // use default default: getLastError()->addEventParameter( new CVmEventParameter( PVE::String, pVmInfo->vmUuid, EVT_PARAM_RETURN_PARAM_TOKEN)); getLastError()->addEventParameter( new CVmEventParameter( PVE::String, pVmInfo->vmXmlPath, EVT_PARAM_RETURN_PARAM_TOKEN)); getLastError()->addEventParameter( new CVmEventParameter( PVE::String, pVmInfo->vmName, EVT_PARAM_RETURN_PARAM_TOKEN)); } return lockResult; } 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; }
PRL_RESULT Task_VzManager::setupFirewall(SmartPtr<CVmConfiguration> &pConfig) { CFirewallHelper fw(pConfig); PRL_RESULT ret = fw.Execute(); if (PRL_FAILED(ret)) { if ( ret == PRL_ERR_FIREWALL_TOOL_EXECUTED_WITH_ERROR ) { getLastError()->setEventType( PET_DSP_EVT_ERROR_MESSAGE ); getLastError()->addEventParameter( new CVmEventParameter( PVE::String, fw.GetErrorMessage(), EVT_PARAM_DETAIL_DESCRIPTION ) ); } return ret; } return PRL_ERR_SUCCESS; }
PRL_RESULT Task_VzManager::resume_env() { CProtoCommandPtr pCmd = CProtoSerializer::ParseCommand( getRequestPackage() ); if (!pCmd->IsValid()) return PRL_ERR_UNRECOGNIZED_REQUEST; PRL_RESULT res; QString sUuid = pCmd->GetVmUuid(); res = check_env_state(PVE::DspCmdVmResume, sUuid); if (PRL_FAILED(res)) return res; SmartPtr<CVmConfiguration> pConfig = getVzHelper()->getCtConfig(getClient(), sUuid); if (!pConfig) return PRL_ERR_VM_GET_CONFIG_FAILED; Backup::Device::Service(pConfig).setContext(*this).enable(); return get_op_helper()->resume_env(sUuid, pCmd->GetCommandFlags()); }
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; }
PRL_RESULT Task_VzManager::suspend_env() { CProtoCommandPtr pCmd = CProtoSerializer::ParseCommand( getRequestPackage() ); if (!pCmd->IsValid()) return PRL_ERR_UNRECOGNIZED_REQUEST; PRL_RESULT res; QString sUuid = pCmd->GetVmUuid(); res = check_env_state(PVE::DspCmdVmSuspend, sUuid); if (PRL_FAILED(res)) return res; res = get_op_helper()->suspend_env(sUuid); SmartPtr<CVmConfiguration> pConfig = getVzHelper()->getCtConfig(getClient(), sUuid); if (pConfig.isValid()) Backup::Device::Service(pConfig).disable(); return res; }
PRL_RESULT Task_GetBackupTreeTarget::addDisks(T& entry, const VmItem& vm, const QString& uuid, unsigned number) { QString path = QString("%1/%2/%3").arg(getBackupDirectory()).arg(vm.getUuid()).arg(uuid); if (number == PRL_BASE_BACKUP_NUMBER) path = QString("%1/" PRL_BASE_BACKUP_DIRECTORY).arg(path); else path = QString("%1/%2").arg(path).arg(number); QScopedPointer<CBackupDisks> list(new (std::nothrow) CBackupDisks); if (!list) return PRL_ERR_OUT_OF_MEMORY; SmartPtr<CVmConfiguration> conf; PRL_RESULT res = loadVeConfig(uuid, path, vm.getVmType(), conf); if (PRL_FAILED(res)) return res; conf->setRelativePath(); /* XXX: empty home doesn't work here, so generate some random cookie */ QString home("/" + Uuid::createUuid().toString()); Backup::Product::Model p(Backup::Object::Model(conf), home); Backup::Product::componentList_type archives; if (BACKUP_PROTO_V4 <= vm.getVersion()) { p.setSuffix(::Backup::Suffix(number, 0)()); archives = p.getVmTibs(); } else if (vm.getVmType() == PVBT_VM) archives = p.getVmTibs(); else archives = p.getCtTibs(); foreach(const Backup::Product::component_type& a, archives) { CBackupDisk *b = new (std::nothrow) CBackupDisk; if (!b) return PRL_ERR_OUT_OF_MEMORY; b->setName(a.second.fileName()); QFileInfo fi(a.first.getImage()); /* use relative paths for disks that reside in the VM home directory */ b->setOriginalPath(fi.dir() == home ? fi.fileName() : fi.filePath()); b->setSize(a.first.getDevice().getSize() << 20); list->m_lstBackupDisks << b; }
PRL_RESULT CDspHaClusterHelper::getHaClusterID(QString & sHaClusterID) { QStringList args; QProcess proc; args += SHAMAN_CMD_INFO; PRL_RESULT res = runHaman(args, proc); if (PRL_FAILED(res)) { WRITE_TRACE(DBG_FATAL, "can not get cluster info"); return res; } QList<QByteArray> lstOut = proc.readAllStandardOutput().split('\n'); QByteArray token = "ID :"; foreach(QByteArray entry, lstOut) { if (entry.startsWith(token)) { sHaClusterID = QString(entry.right(entry.size() - token.size()).trimmed()); break; } } return PRL_ERR_SUCCESS; }
void CVmMigrateTargetDisk::run() { m_sem_init.release(); m_result = PRL_ERR_SUCCESS; while (PRL_SUCCEEDED(m_result) && !(m_queue.empty() && m_wait)) { DiskQueueElem_t data; if (m_queue.take(data, m_token)) m_result = write_data(&data); else break; if (PRL_FAILED(m_result)) { WRITE_TRACE(DBG_FATAL, "[Disk migration] Failed to write block to disk %s,\ address %llu, size %u", qPrintable(Uuid::fromGuid(data.hdr.disk_id).toString()), data.hdr.lba, data.hdr.nsect); m_token.signal(); } } }
PRL_RESULT Task_VzManager::restart_env() { CProtoCommandPtr pCmd = CProtoSerializer::ParseCommand( getRequestPackage() ); if (!pCmd->IsValid()) return PRL_ERR_UNRECOGNIZED_REQUEST; if (CDspService::instance()->isServerStopping()) return PRL_ERR_DISP_SHUTDOWN_IN_PROCESS; QString sUuid = pCmd->GetVmUuid(); SmartPtr<CVmConfiguration> pConfig = getVzHelper()->getCtConfig(getClient(), sUuid); if (!pConfig) return PRL_ERR_VM_GET_CONFIG_FAILED; if (pConfig->getVmSettings()->getVmCommonOptions()->isTemplate()) return PRL_ERR_CANT_TO_START_VM_TEMPLATE; PRL_RESULT res = get_op_helper()->restart_env(sUuid); if (PRL_FAILED(res)) return res; 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)); } }
static PRL_RESULT perfstats_callback(PRL_HANDLE handle, void *user_data, PRL_EVENT_TYPE process_type) { PrlHandle clean(handle); PRL_RESULT ret; PRL_EVENT_TYPE e_type; const CmdParamData ¶m = *(const CmdParamData*)user_data; ret = PrlEvent_GetType(handle, &e_type); if (PRL_FAILED(ret)) { prl_log(L_DEBUG, "Warning! PrlSrv_Logoff failed: %s", get_error_str(ret).c_str()); return PRL_ERR_SUCCESS; } if (e_type != process_type) return PRL_ERR_SUCCESS; print_perfstats(handle, param); if (s_evt) s_evt->Signal(); return PRL_ERR_SUCCESS; }
static PRL_RESULT print_perfstats(PRL_HANDLE handle, const CmdParamData ¶m) { (void)param; unsigned int param_count; PRL_RESULT ret = PrlEvent_GetParamsCount(handle, ¶m_count); if (PRL_FAILED(ret)) return prl_err(ret, "PrlEvent_GetParamsCount returned the following error: %s", get_error_str(ret).c_str()); if (!param_count) return PRL_ERR_SUCCESS; // Print VM uuid if necessary if (param.list_all) { char uuid[NORMALIZED_UUID_LEN + 1] = {0}; PRL_UINT32 size = sizeof(uuid); PRL_HANDLE hVm; if (PRL_SUCCEEDED(PrlEvent_GetVm(handle, &hVm))) { PrlVmCfg_GetUuid(hVm, uuid, &size); PrlHandle_Free(hVm); } printf("%s\n", uuid); } for (unsigned int ndx = 0; ndx < param_count; ++ndx) { PrlHandle hPrm; ret = PrlEvent_GetParam(handle, ndx, hPrm.get_ptr()); if (PRL_FAILED(ret)) return prl_err(ret, "PrlEvent_GetParam returned the following error: %s", get_error_str(ret).c_str()); char name_buff[1024]; unsigned int len = sizeof(name_buff) - 1; ret = PrlEvtPrm_GetName(hPrm.get_handle(), name_buff, &len); if (PRL_FAILED(ret)) return prl_err(ret, "PrlEvtPrm_GetName returned the following error: %s", get_error_str(ret).c_str()); char val_buff[1024]; len = sizeof(val_buff) - 1; val_buff[len] = 0; PRL_PARAM_FIELD_DATA_TYPE nFieldType = PFD_UNKNOWN; PrlEvtPrm_GetType(hPrm.get_handle(), &nFieldType); if (nFieldType == PFD_BINARY) { if (strncmp(name_buff, PRL_NET_CLASSFUL_TRAFFIC_PTRN, sizeof(PRL_NET_CLASSFUL_TRAFFIC_PTRN) - 1) == 0) { PRL_STAT_NET_TRAFFIC net_stat_buf; len = sizeof(PRL_STAT_NET_TRAFFIC); if (PrlEvtPrm_GetBuffer(hPrm.get_handle(), &net_stat_buf, &len) == 0) { for (unsigned int i = 0; i < PRL_TC_CLASS_MAX; i++) fprintf(stdout, "\t%20s %2d %20llu %10u %20llu %10u\n", name_buff, i, net_stat_buf.incoming[i], net_stat_buf.incoming_pkt[i], net_stat_buf.outgoing[i], net_stat_buf.outgoing_pkt[i]); } } } else { ret = PrlEvtPrm_ToString(hPrm.get_handle(), val_buff, &len); if (PRL_FAILED(ret)) return prl_err(ret, "PrlEvtPrm_ToString returned the following error: %s", get_error_str(ret).c_str()); fprintf(stdout, "\t%s:\t%s\n", name_buff, val_buff); } } return PRL_ERR_SUCCESS; }
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; }
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; }
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; }
int PrlSrv::print_statistics(const CmdParamData ¶m, PrlVm *vm) { PRL_RESULT ret; std::string err; if (param.list_all && !vm) { ret = update_vm_list(param.vmtype); if (PRL_FAILED(ret)) return ret; } if (!param.statistics.loop) s_evt = new CEventSyncObject(); const PrlHook *hHook = get_cleanup_ctx().register_hook(call_exit, NULL); if (param.action == SrvPerfStatsAction) { ret = PrlSrv_RegEventHandler(get_handle(), &perfstats_srv_callback, (void*)¶m); if (PRL_FAILED(ret)) return prl_err(ret, "PrlSrv_RegEventHandler returned the following error: %s", get_error_str(ret).c_str()); PrlHandle hJob(PrlSrv_SubscribeToPerfStats(get_handle(), param.statistics.filter.c_str())); if (PRL_FAILED(get_job_retcode_predefined(hJob.get_handle(), err))) return prl_err(ret, "PrlSrv_SubscribeToPerfStats returned the following error: %s", err.c_str()); } if (param.action == VmPerfStatsAction || param.list_all) { for (PrlVmList::iterator it = m_VmList.begin(), end = m_VmList.end(); it != end; ++it) { if (!param.list_all && (*it) != vm) continue; ret = PrlVm_RegEventHandler((*it)->get_handle(), &perfstats_vm_callback, (void*)¶m); if (PRL_FAILED(ret)) return prl_err(ret, "PrlVm_RegEventHandler returned the following error: %s", get_error_str(ret).c_str()); PrlHandle hJob(PrlVm_SubscribeToPerfStats((*it)->get_handle(), param.statistics.filter.c_str())); if (PRL_FAILED(get_job_retcode_predefined(hJob.get_handle(), err))) return prl_err(ret, "PrlVm_SubscribeToPerfStats returned the following error: %s", err.c_str()); if (s_evt) { s_evt->Wait(10000); s_evt->Reset(); PrlVm_UnregEventHandler((*it)->get_handle(), &perfstats_vm_callback, (void*)¶m); PrlHandle j(PrlVm_UnsubscribeFromPerfStats((*it)->get_handle())); get_job_retcode_predefined(j.get_handle(), err); } } } if (param.statistics.loop) { int ch = 0 ; while (ch!=0x0A && ch!=0x0D && ch!=0x03) { ch = _getch(); } fprintf(stdout, "\n"); } get_cleanup_ctx().unregister_hook(hHook); if (param.action == SrvPerfStatsAction) PrlSrv_UnregEventHandler(get_handle(), &perfstats_srv_callback, NULL); return 0; }
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; }
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; }