package org.ovirt.engine.core.vdsbroker;
import java.util.concurrent.locks.ReentrantLock;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import org.ovirt.engine.core.common.businessentities.OriginType;
import org.ovirt.engine.core.common.businessentities.VmDynamic;
import org.ovirt.engine.core.common.businessentities.VmStatic;
import org.ovirt.engine.core.common.businessentities.VmStatistics;
import org.ovirt.engine.core.common.businessentities.network.VmNetworkStatistics;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.compat.Version;
import org.ovirt.engine.core.dao.ClusterDao;
import org.ovirt.engine.core.dao.VmDynamicDao;
import org.ovirt.engine.core.dao.VmStaticDao;
import org.ovirt.engine.core.dao.VmStatisticsDao;
import org.ovirt.engine.core.dao.network.VmNetworkStatisticsDao;
import org.ovirt.engine.core.vdsbroker.monitoring.VdsmVm;
public class VmManager {
private final Guid vmId;
///// Static fields ///////
private String name;
private OriginType origin;
private boolean autoStart;
private int memSizeMb;
private int minAllocatedMem;
private int numOfCpus;
private Version clusterCompatibilityVersion;
private Guid leaseStorageDomainId;
private final ReentrantLock lock;
private Long vmDataChangedTime;
/** how long to wait for a response for power-off operation, in nanoseconds */
private long powerOffTimeout;
private int convertOperationProgress;
private String convertOperationDescription;
private Guid convertProxyHostId;
private Double lastStatusEventTimestamp;
private Guid lastStatusEventReporterId;
private VmStatistics statistics;
private boolean coldReboot;
@Inject
private VmDynamicDao vmDynamicDao;
@Inject
private VmStatisticsDao vmStatisticsDao;
@Inject
private VmNetworkStatisticsDao vmNetworkStatisticsDao;
@Inject
private VmStaticDao vmStaticDao;
@Inject
private ClusterDao clusterDao;
VmManager(Guid vmId) {
this.vmId = vmId;
lock = new ReentrantLock();
convertOperationProgress = -1;
statistics = new VmStatistics(vmId);
}
@PostConstruct
public void init() {
setPowerOffTimeout(System.nanoTime());
VmStatic vmStatic = vmStaticDao.get(vmId);
// vmStatic is null for externally managed VMs
if (vmStatic != null) {
updateStaticFields(vmStatic);
}
}
private void updateStaticFields(VmStatic vmStatic) {
name = vmStatic.getName();
origin = vmStatic.getOrigin();
autoStart = vmStatic.isAutoStartup();
memSizeMb = vmStatic.getMemSizeMb();
minAllocatedMem = vmStatic.getMinAllocatedMem();
numOfCpus = vmStatic.getNumOfCpus();
clusterCompatibilityVersion = clusterDao.get(vmStatic.getClusterId()).getCompatibilityVersion();
leaseStorageDomainId = vmStatic.getLeaseStorageDomainId();
}
public void lock() {
lock.lock();
}
public void unlock() {
lock.unlock();
}
public boolean trylock() {
return lock.tryLock();
}
public void update(VmDynamic dynamic) {
vmDynamicDao.update(dynamic);
}
public void update(VmStatistics statistics) {
vmStatisticsDao.update(statistics);
setStatistics(statistics);
}
public void update(VmNetworkStatistics networkStatistics) {
vmNetworkStatisticsDao.update(networkStatistics);
}
public void update(VmStatic vmStatic) {
vmStaticDao.update(vmStatic);
updateStaticFields(vmStatic);
}
public int getConvertOperationProgress() {
return convertOperationProgress;
}
public String getConvertOperationDescription() {
return convertOperationDescription;
}
public void updateConvertOperation(String description, int progress) {
this.convertOperationDescription = description;
this.convertOperationProgress = progress;
}
public void setConvertProxyHostId(Guid convertProxyHostId) {
this.convertProxyHostId = convertProxyHostId;
}
public Guid getConvertProxyHostId() {
return convertProxyHostId;
}
public Long getVmDataChangedTime () {
return vmDataChangedTime;
}
/**
* set the changed time of the vm data to the current System.nanoTime()
* nanoTime should be used as it is more accurate and monotonic,
*
* in general this should be called while holding the manager lock
*/
public final void updateVmDataChangedTime() {
vmDataChangedTime = System.nanoTime();
}
/**
* Check whether the given data is the latest we got from the given host
* @param vdsmVm - the data received
* @param vdsId - the host that sent the data
* @return false if newer data was already processed, true otherwise
*/
public boolean isLatestData(VdsmVm vdsmVm, Guid vdsId) {
if (vdsmVm == null) {
// VM disappeared from VDSM, we need to have monitoring cycle
return true;
}
Double statusEventTimestamp = vdsmVm.getTimestamp();
if (!vdsId.equals(lastStatusEventReporterId) || lastStatusEventTimestamp <= statusEventTimestamp) {
lastStatusEventTimestamp = statusEventTimestamp;
lastStatusEventReporterId = vdsId;
return true;
}
return false;
}
void clearLastStatusEventStampIfFromVds(Guid vdsId) {
if (vdsId.equals(lastStatusEventReporterId)) {
lastStatusEventReporterId = null;
}
}
public boolean isColdReboot() {
return coldReboot;
}
public void setColdReboot(boolean coldReboot) {
this.coldReboot = coldReboot;
}
public VmStatistics getStatistics() {
return statistics;
}
public void setStatistics(VmStatistics statistics) {
this.statistics = statistics;
}
public String getName() {
return name;
}
public OriginType getOrigin() {
return origin;
}
public boolean isAutoStart() {
return autoStart;
}
public int getMemSizeMb() {
return memSizeMb;
}
public int getMinAllocatedMem() {
return minAllocatedMem;
}
public int getNumOfCpus() {
return numOfCpus;
}
public void setClusterCompatibilityVersion(Version version) {
this.clusterCompatibilityVersion = version;
}
public Version getClusterCompatibilityVersion() {
return clusterCompatibilityVersion;
}
public Guid getLeaseStorageDomainId() {
return leaseStorageDomainId;
}
public long getPowerOffTimeout() {
return powerOffTimeout;
}
public long setPowerOffTimeout(long powerOffTimeout) {
long result = this.powerOffTimeout;
this.powerOffTimeout = powerOffTimeout;
return result;
}
}