Ovirt

【Ovirt 笔记】资源信息状态刷新实现分析与整理(2)(持续更

2018-10-08  本文已影响2人  58bc06151329

文前说明

作为码农中的一员,需要不断的学习,我工作之余将一些分析总结和学习笔记写成博客与大家一起交流,也希望采用这种方式记录自己的学习之旅。

本文仅供学习交流使用,侵权必删。
不用于商业目的,转载请注明出处。

分析整理的版本为 Ovirt 3.4.5Ovirt 4.2.3 版本。

紧接前文 【Ovirt 笔记】资源信息状态刷新实现分析与整理(1)(持续更新)

4. 虚拟机

if (xmlRpcStruct.containsKey(VdsProperties.vm_guid)) {
            vm.setId(new Guid((String) xmlRpcStruct.get(VdsProperties.vm_guid)));
        }
        if (xmlRpcStruct.containsKey(VdsProperties.session)) {
            String session = (String) xmlRpcStruct.get(VdsProperties.session);
            try {
                vm.setSession(SessionState.valueOf(session));
            } catch (Exception e) {
                log.errorFormat("vm session value illegal : {0}", session);
            }
        }
        if (xmlRpcStruct.containsKey(VdsProperties.kvmEnable)) {
            vm.setKvmEnable(Boolean.parseBoolean((String) xmlRpcStruct.get(VdsProperties.kvmEnable)));
        }
......
@OnTimerMethodAnnotation("poll")
public void poll() {
        if (isMonitoringNeeded(vdsManager.getStatus())) {
            VmsListFetcher fetcher = new VmsStatisticsFetcher(vdsManager);

            long fetchTime = System.nanoTime();
            if (fetcher.fetch()) {
                getVmsMonitoring().perform(fetcher.getChangedVms(), fetchTime, vdsManager, true);
                Stream<VdsmVm> vdsmVmsToMonitor = filterVmsToDevicesMonitoring(fetcher.getChangedVms());
                processDevices(vdsmVmsToMonitor, fetchTime);
            } else {
                log.info("Failed to fetch vms info for host '{}' - skipping VMs monitoring.", vdsManager.getVdsName());
            }
        }
}

4.1 状态说明

虚拟机状态 说明 版本
Unassigned 未指派的 -1 3.4.5/4.2.3
Down 关机 0 3.4.5/4.2.3
Up 开机 1 3.4.5/4.2.3
PoweringUp 正在开机 2 3.4.5/4.2.3
Paused 暂停 4 3.4.5/4.2.3
MigratingFrom 迁移出 5 3.4.5/4.2.3
MigratingTo 迁移入 6 3.4.5/4.2.3
Unknown 未知 7 3.4.5/4.2.3
NotResponding 没有响应 8 3.4.5/4.2.3
WaitForLaunch 等待 9 3.4.5/4.2.3
RebootInProgress 重启过程中 10 3.4.5/4.2.3
SavingState 保存状态 11 3.4.5/4.2.3
RestoringState 恢复状态 12 3.4.5/4.2.3
Suspended 挂起 13 3.4.5/4.2.3
ImageIllegal 镜像损坏 14 3.4.5/4.2.3
ImageLocked 镜像锁定 15 3.4.5/4.2.3
PoweringDown 正在关机 16 3.4.5/4.2.3
PreparingForHibernate 准备进入暂停 17 3.4.5

4.1.1 Unassigned

4.1.2 Down

void addVmDynamic() {
        VmDynamic tempVar = new VmDynamic();
        tempVar.setId(getVmId());
        tempVar.setStatus(VMStatus.Down);
        tempVar.setVmHost("");
        tempVar.setVmIp("");
        tempVar.setVmFQDN("");
        tempVar.setDisplayType(getParameters().getVmStaticData().getDefaultDisplayType());
        tempVar.setLastStopTime(new Date());
        VmDynamic vmDynamic = tempVar;
        DbFacade.getInstance().getVmDynamicDao().save(vmDynamic);
        getCompensationContext().snapshotNewEntity(vmDynamic);
}
private void unlockEntities() {
        // Assumption - this is last DB change of command, no need for compensation here
        getSnapshotDao().updateStatus(sourceSnapshotId, SnapshotStatus.OK);
        getVmDynamicDao().updateStatus(getVmId(), VMStatus.Down);
}
for (VM vm : vms) {
            if (vm.isAutoStartup()) {
                autoStartVmIdsToRerun.add(vm.getId());
            }
            VDSReturnValue returnValue = Backend
                    .getInstance()
                    .getResourceManager()
                    .RunVdsCommand(VDSCommandType.SetVmStatus,
                            new SetVmStatusVDSCommandParameters(vm.getId(), VMStatus.Down, VmExitStatus.Error));
            // Write that this VM was shut down by host reboot or manual fence
            if (returnValue != null && returnValue.getSucceeded()) {
                LogSettingVmToDown(getVds().getId(), vm.getId());
            }

            Backend.getInstance().runInternalAction(VdcActionType.ProcessDownVm,
                    new IdParameters(vm.getId()),
                    ExecutionHandler.createDefaultContexForTasks(getExecutionContext()));
}
protected void restartVdsVms() {
        List<Guid> autoStartVmIdsToRerun = new ArrayList<>();
        // restart all running vms of a failed vds.
        for (VM vm : mVmList) {
            destroyVmOnDestination(vm);
            VDSReturnValue returnValue = Backend
                    .getInstance()
                    .getResourceManager()
                    .RunVdsCommand(VDSCommandType.SetVmStatus,
                            new SetVmStatusVDSCommandParameters(vm.getId(), VMStatus.Down, VmExitStatus.Error));
            // Write that this VM was shut down by host reboot or manual fence
            if (returnValue != null && returnValue.getSucceeded()) {
                LogSettingVmToDown(getVds().getId(), vm.getId());
            }
            setVmId(vm.getId());
            setVmName(vm.getName());
            setVm(vm);
            Backend.getInstance().runInternalAction(VdcActionType.ProcessDownVm,
                    new IdParameters(vm.getId()),
                    ExecutionHandler.createDefaultContexForTasks(getExecutionContext()));

            // Handle highly available VMs
            if (vm.isAutoStartup()) {
                autoStartVmIdsToRerun.add(vm.getId());
            }
        }
        if (!autoStartVmIdsToRerun.isEmpty()) {
            AutoStartVmsRunner.getInstance().addVmsToRun(autoStartVmIdsToRerun);
        }
        setVm(null);
        setVmId(Guid.Empty);
        setVmName(null);
}
@Override
protected void endVmCommand() {
        setCommandShouldBeLogged(false);
        if (getVm() != null) {
            getVm().setStatus(VMStatus.Down);
            getVm().setHibernationVolHandle(null);
            getVmDynamicDao().update(getVm().getDynamicData());
        } else {
            log.warn("StopVmCommandBase::EndVmCommand: Vm is null - not performing full endAction");
        }
        setSucceeded(true);
}
public static void unLockVm(VM vm) {
        Backend.getInstance()
                .getResourceManager()
                .RunVdsCommand(VDSCommandType.SetVmStatus,
                        new SetVmStatusVDSCommandParameters(vm.getId(), VMStatus.Down));
        vm.setStatus(VMStatus.Down);
}
private void clearVm(VM vm, VmExitStatus exitStatus, String exitMessage) {
        if (vm.getStatus() != VMStatus.MigratingFrom) {
            // we must check that vm.getStatus() != VMStatus.Down because if it was set to down
            // the exit status and message were set, and we don't want to override them here.
            // we will add it to _vmDynamicToSave though because it might been removed from it in #updateRepository
            if (vm.getStatus() != VMStatus.Suspended && vm.getStatus() != VMStatus.Down) {
                ResourceManager.getInstance().InternalSetVmStatus(vm, VMStatus.Down, exitStatus, exitMessage);
            }
            addVmDynamicToList(vm.getDynamicData());
            addVmStatisticsToList(vm.getStatisticsData());
            addVmInterfaceStatisticsToList(vm.getInterfaces());
            if (!ResourceManager.getInstance().IsVmInAsyncRunningList(vm.getId())) {
                _vmsMovedToDown.add(vm.getId());
            }
        }
}
@Override
protected VmDynamic createVmDynamic() {
        VmDynamic vmDynamic = super.createVmDynamic();
        vmDynamic.setStatus(VMStatus.Down);
        return vmDynamic;
}
if (getVdsId().equals(curVm.getRunOnVds())) {
            ResourceManager.getInstance().InternalSetVmStatus(curVm, parameters.getGracefully() ? VMStatus.PoweringDown : VMStatus.Down);
}

4.1.3 Up

if (getVm().getRunOnVds() != null) {
                getVm().setHibernationVolHandle(null);
                getVm().setStatus(VMStatus.Up);

                Backend.getInstance()
                        .getResourceManager()
                        .RunVdsCommand(
                                VDSCommandType.UpdateVmDynamicData,
                                new UpdateVmDynamicDataVDSCommandParameters(
                                        new Guid(getVm().getRunOnVds().toString()), getVm().getDynamicData()));
                setSucceeded(true);
}
decreasePendingVms();
setSucceeded(true);
setActionReturnValue(VMStatus.Up);
private static VMStatus convertToVmStatus(String statusName) {
        VMStatus status = VMStatus.Unassigned;

        // TODO: The following condition should deleted as soon as we drop compatibility with 3.3 since "Running" state
        // will be replaced "Up" state and "Unknown" will exist no more. The "Up" state will be processed by
        // EnumUtils as other states below.
        if ("Running".equals(statusName) || "Unknown".equals(statusName)) {
            status = VMStatus.Up;
        }
        else if ("Migration Source".equals(statusName)) {
            status = VMStatus.MigratingFrom;
        }
        else if ("Migration Destination".equals(statusName)) {
            status = VMStatus.MigratingTo;
        } else {
            try {
                statusName = statusName.replace(" ", "");
                status = EnumUtils.valueOf(VMStatus.class, statusName, true);
            } catch (Exception e) {
                log.errorFormat("Vm status: {0} illegal", statusName);
            }
        }
        return status;
}

4.1.4 PoweringUp

if (vdsReturnValue.getSucceeded()) {
            resourceManager.addAsyncRunningVm(getParameters().getVmId());
            getVDSReturnValue().setReturnValue(VMStatus.PoweringUp);
......

4.1.5 Paused

4.1.6 MigratingFrom

ResourceManager.getInstance().AddAsyncRunningVm(getParameters().getVmId());
ResourceManager.getInstance().InternalSetVmStatus(vm, VMStatus.MigratingFrom);
vm.setMigratingToVds(getParameters().getDstVdsId());
getVmDynamicDAO().update(vm.getDynamicData());
getVDSReturnValue().setReturnValue(VMStatus.MigratingFrom);

4.1.7 MigratingTo

// when the destination VDS is NonResponsive put the VM to Uknown like the rest of its VMs, else MigratingTo
        VMStatus newVmStatus =
                (VDSStatus.NonResponsive == getDbFacade().getVdsDao().get(destinationHostId).getStatus())
                        ? VMStatus.Unknown
                        : VMStatus.MigratingTo;

        // handing over the VM to the DST by marking it running on it. it will now be its SRC host.
        vmToRemove.setRunOnVds(destinationHostId);

        log.infoFormat("Handing over VM {0} {1} to Host {2}. Setting VM to status {3}",
                vmToRemove.getName(),
                vmToRemove.getId(),
                destinationHostId,
                newVmStatus);

        // if the DST host goes unresponsive it will take care all MigratingTo and unknown VMs
        ResourceManager.getInstance().InternalSetVmStatus(vmToRemove, newVmStatus);
......
private void handOverVm() {
        Guid dstHostId = dbVm.getMigratingToVds();
        // when the destination VDS is NonResponsive put the VM to Unknown like the rest of its VMs
        VMStatus newVmStatus = isVdsNonResponsive(dstHostId) ? VMStatus.Unknown : VMStatus.MigratingTo;
        dbVm.setRunOnVds(dstHostId);
        logVmHandOver(dstHostId, newVmStatus);
        resourceManager.internalSetVmStatus(dbVm, newVmStatus);
        saveDynamic(dbVm);
}
else if ("Migration Source".equals(statusName)) {
            status = VMStatus.MigratingFrom;
        }
else if ("Migration Destination".equals(statusName)) {
        status = VMStatus.MigratingTo;
......
case VdsProperties.MIGRATION_SOURCE:
            return VMStatus.MigratingFrom;
case VdsProperties.MIGRATION_DESTINATION:
            return VMStatus.MigratingTo;

4.1.8 Unknown

4.1.8.1 设置为没有响应状态(3.4.5)。

for (VM vm : getVmList()) {
     destroyVmOnDestination(vm);
     Backend.getInstance().getResourceManager().RunVdsCommand(VDSCommandType.SetVmStatus, new SetVmStatusVDSCommandParameters(vm.getId(), VMStatus.Unknown));
     // log VM transition to unknown status
     AuditLogableBase logable = new AuditLogableBase();
     logable.setVmId(vm.getId());
     AuditLogDirector.log(logable, AuditLogType.VM_SET_TO_UNKNOWN_STATUS);
}
private VdcReturnValueBase executeVdsFenceAction(final Guid vdsId, String sessionId, FenceActionType fenceAction, VdcActionType action) {
        FenceVdsActionParameters params = new FenceVdsActionParameters(vdsId, fenceAction);
        params.setParentCommand(VdcActionType.RestartVds);
        params.setSessionId(sessionId);
        // If Host was in Maintenance, and was restarted manually , it should preserve its status after reboot
        if (getParameters().getParentCommand() != VdcActionType.VdsNotRespondingTreatment && getVds().getStatus() == VDSStatus.Maintenance) {
            params.setChangeHostToMaintenanceOnStart(true);
        }
        return Backend.getInstance().runInternalAction(action, params, getContext());
}
if (MonitoringStrategyFactory.getMonitoringStrategyForVds(vds).isPowerManagementSupported() && shouldExecRealFencing) {
      Backend.getInstance().runInternalAction(VdcActionType.VdsNotRespondingTreatment, new FenceVdsActionParameters(vds.getId(), FenceActionType.Restart), ExecutionHandler.createInternalJobContext());
}

4.1.9 NotResponding

// engine
if (xmlRpcStruct.containsKey(VdsProperties.monitorResponse)) {
            int response = Integer.parseInt(xmlRpcStruct.get(VdsProperties.monitorResponse).toString());
            if (response < 0) {
                vm.setStatus(VMStatus.NotResponding);
            }
}
# vdsm
if self._vmStats:
                decStats = self._vmStats.get()
                if (not self.isMigrating()
                    and decStats['statsAge'] >
                        config.getint('vars', 'vm_command_timeout')):
                    stats['monitorResponse'] = '-1'
......

4.1.10 WaitForLaunch

4.1.11 RebootInProgress

4.1.12 SavingState

private void changeVmStatusToSavingState() {
        TransactionSupport.executeInNewTransaction(
                new TransactionMethod<Object>() {
                    @Override
                    public Object runInTransaction() {
                        VmDynamic vmDynamic = DbFacade.getInstance().getVmDynamicDao().get(getParameters().getVmId());
                        vmDynamic.setStatus(VMStatus.SavingState);
                        _vdsManager.updateVmDynamic(vmDynamic);
                        return null;
                    }
                });
}

4.1.14 RestoringState

4.1.15 Suspended

// when going to suspend, delete vm from cache later
if (status == VMStatus.SavingState) {
     ResourceManager.getInstance().InternalSetVmStatus(vmTo, VMStatus.Suspended);
}
switch (dbVm.getStatus()) {
        case SavingState:
            resourceManager.internalSetVmStatus(dbVm, VMStatus.Suspended);
            clearVm(vdsmVm.getVmDynamic().getExitStatus(),
                    vdsmVm.getVmDynamic().getExitMessage(),
                    vdsmVm.getVmDynamic().getExitReason());
            resourceManager.removeAsyncRunningVm(dbVm.getId());
            auditVmSuspended();
            break;

4.1.16 ImageIllegal

4.1.17 ImageLocked

private void addVmDynamic() {
        VmDynamic tempVar = new VmDynamic();
        tempVar.setId(getVmId());
        tempVar.setStatus(VMStatus.ImageLocked);
        tempVar.setVmHost("");
        tempVar.setVmIp("");
        tempVar.setVmFQDN("");
        tempVar.setLastStopTime(new Date());
        tempVar.setAppList(getParameters().getVm().getDynamicData().getAppList());
        getVmDynamicDAO().save(tempVar);
        getCompensationContext().snapshotNewEntity(tempVar);
}
protected VmDynamic createVmDynamic() {
        VmDynamic vmDynamic = new VmDynamic();
        vmDynamic.setId(getVmId());
        vmDynamic.setStatus(VMStatus.ImageLocked);
        vmDynamic.setVmHost("");
        vmDynamic.setIp("");
        vmDynamic.setFqdn("");
        vmDynamic.setLastStopTime(new Date());
        vmDynamic.setAppList(getParameters().getVm().getAppList());
        return vmDynamic;
}
private boolean stopSuspendedVm() {
        // Set the Vm to null, for getting the recent VM from the DB, instead from the cache.
        setVm(null);
        final VMStatus vmStatus = getVm().getStatus();

        // Check whether stop VM procedure didn't started yet (Status is not imageLocked), by another transaction.
        if (vmStatus == VMStatus.ImageLocked) {
            return false;
        }

        // Set the VM to image locked to decrease race condition.
        updateVmStatus(VMStatus.ImageLocked);

        if (!removeVmHibernationVolumes()) {
            updateVmStatus(vmStatus);
            return false;
        }
        return true;
}

4.1.17.1 对虚拟机磁盘加锁

public static void lockVm(Guid vmId) {
        Backend.getInstance()
                .getResourceManager()
                .RunVdsCommand(VDSCommandType.SetVmStatus,
                        new SetVmStatusVDSCommandParameters(vmId, VMStatus.ImageLocked));
}
protected boolean addVmImages() {
        if (vmDisksSource.getDiskTemplateMap().size() > 0) {
            if (getVm().getStatus() != VMStatus.Down) {
                log.error("Cannot add images. VM is not Down");
                throw new VdcBLLException(VdcBllErrors.IRS_IMAGE_STATUS_ILLEGAL);
            }
            VmHandler.lockVm(getVmId());
......
protected void lockVM() {
        vmHandler.lockVm(getVmId());
}
protected void lockVmWithCompensationIfNeeded() {
        log.infoFormat("Locking VM(id = {0}) {1} compensation.", getVmId(), isInternalExecution() ? "without" : "with");

        if (isInternalExecution()) {
            VmHandler.checkStatusAndLockVm(getVmId());
        } else {
            VmHandler.checkStatusAndLockVm(getVmId(), getCompensationContext());
        }
}
VmHandler.lockVm(getParameters().getVmStaticData().getId());
private void processImages() {
        TransactionSupport.executeInNewTransaction(new TransactionMethod<Void>() {

            @Override
            public Void runInTransaction() {
                addVmImagesAndSnapshots();
                updateSnapshotsFromExport();
                moveOrCopyAllImageGroups();
                VmDeviceUtils.addImportedDevices(getVm().getStaticData(), getParameters().isImportAsNewEntity());
                VmHandler.lockVm(getVm().getId());
                if (getParameters().isImportAsNewEntity()) {
                    getParameters().setVm(getVm());
                    setVmId(getVm().getId());
                }
                return null;

            }
        });
}
@Override
    protected boolean addVmImages() {
        if (getVmTemplate().getDiskTemplateMap().size() > 0) {
            if (getVm().getStatus() != VMStatus.Down) {
                log.error("Cannot add images. VM is not Down");
                throw new VdcBLLException(VdcBllErrors.IRS_IMAGE_STATUS_ILLEGAL);
            }
            VmHandler.lockVm(getVm().getDynamicData(), getCompensationContext());
......
@Override
protected void lockVM() {
      vmHandler.lockVm(getVm().getDynamicData(), getCompensationContext());
}
if (isVmInDb) {
            VmDynamic vmDynamic = DbFacade.getInstance().getVmDynamicDao().get(getVmId());
            if (vmDynamic.getStatus() != VMStatus.Down) {
                throw new VdcBLLException(VdcBllErrors.IRS_IMAGE_STATUS_ILLEGAL);
            }

            VmHandler.lockVm(vmDynamic, getCompensationContext());
}
VmHandler.lockVm(getVm().getDynamicData(), getCompensationContext());
if (getVm().getStatus() != VMStatus.ImageLocked) {
       VmHandler.lockVm(getVm().getDynamicData(), getCompensationContext());
}
freeLock();
setSucceeded(removeVm());
if (!filteredImages.isEmpty()) {
            VmHandler.lockVm(getVm().getDynamicData(), getCompensationContext());
......

4.1.18 PoweringDown

if (getVdsId().equals(curVm.getRunOnVds())) {
            ResourceManager.getInstance().InternalSetVmStatus(curVm, parameters.getGracefully() ? VMStatus.PoweringDown : VMStatus.Down);
}
private void changeStatus(VmDynamic curVm) {
        // do the state transition only if that VM is really running on SRC
        if (getParameters().getVdsId().equals(curVm.getRunOnVds())) {
            resourceManager.internalSetVmStatus(curVm, VMStatus.PoweringDown);
        }
}

4.1.19 PreparingForHibernate

getCompensationContext().snapshotEntityStatus(getVm().getDynamicData());

// Set the VM to SavingState to lock the VM,to avoid situation of multi VM hibernation.
getVm().setStatus(VMStatus.PreparingForHibernate);
Backend.getInstance().getResourceManager().RunVdsCommand(VDSCommandType.UpdateVmDynamicData, new UpdateVmDynamicDataVDSCommandParameters(getVdsId(), getVm().getDynamicData()));
getCompensationContext().stateChanged();
} else if (props.contains("status") && vmToUpdate.argvalue.getDynamicData().getStatus() == VMStatus.PreparingForHibernate) {
       vmNewDynamicData.setStatus(VMStatus.PreparingForHibernate);
       props.remove("status");
}
上一篇下一篇

猜你喜欢

热点阅读