diff --git a/api/src/com/cloud/vm/VirtualMachine.java b/api/src/com/cloud/vm/VirtualMachine.java index 0920b0b1f7f..d2632fc3fad 100755 --- a/api/src/com/cloud/vm/VirtualMachine.java +++ b/api/src/com/cloud/vm/VirtualMachine.java @@ -79,14 +79,12 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, StateObject s_fsm.addTransition(State.Stopped, VirtualMachine.Event.OperationFailed, State.Stopped); s_fsm.addTransition(State.Stopped, VirtualMachine.Event.ExpungeOperation, State.Expunging); s_fsm.addTransition(State.Stopped, VirtualMachine.Event.AgentReportShutdowned, State.Stopped); - s_fsm.addTransition(State.Stopped, VirtualMachine.Event.AgentReportMigrated, State.Stopped); s_fsm.addTransition(State.Starting, VirtualMachine.Event.OperationRetry, State.Starting); s_fsm.addTransition(State.Starting, VirtualMachine.Event.OperationSucceeded, State.Running); s_fsm.addTransition(State.Starting, VirtualMachine.Event.OperationFailed, State.Stopped); s_fsm.addTransition(State.Starting, VirtualMachine.Event.AgentReportRunning, State.Running); s_fsm.addTransition(State.Starting, VirtualMachine.Event.AgentReportStopped, State.Stopped); s_fsm.addTransition(State.Starting, VirtualMachine.Event.AgentReportShutdowned, State.Stopped); - s_fsm.addTransition(State.Starting, VirtualMachine.Event.AgentReportMigrated, State.Starting); s_fsm.addTransition(State.Destroyed, VirtualMachine.Event.RecoveryRequested, State.Stopped); s_fsm.addTransition(State.Destroyed, VirtualMachine.Event.ExpungeOperation, State.Expunging); s_fsm.addTransition(State.Running, VirtualMachine.Event.MigrationRequested, State.Migrating); @@ -107,7 +105,6 @@ public interface VirtualMachine extends RunningOn, ControlledEntity, StateObject s_fsm.addTransition(State.Stopping, VirtualMachine.Event.AgentReportStopped, State.Stopped); s_fsm.addTransition(State.Stopping, VirtualMachine.Event.StopRequested, State.Stopping); s_fsm.addTransition(State.Stopping, VirtualMachine.Event.AgentReportShutdowned, State.Stopped); - s_fsm.addTransition(State.Stopping, VirtualMachine.Event.AgentReportMigrated, State.Stopping); s_fsm.addTransition(State.Expunging, VirtualMachine.Event.OperationFailed, State.Expunging); s_fsm.addTransition(State.Expunging, VirtualMachine.Event.ExpungeOperation, State.Expunging); s_fsm.addTransition(State.Error, VirtualMachine.Event.DestroyRequested, State.Expunging); diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index 9d432f8d103..28746bfbdcd 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -73,10 +73,12 @@ + + diff --git a/core/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/core/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java index a16ed5561d4..7e77f6995fa 100644 --- a/core/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java +++ b/core/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java @@ -161,46 +161,61 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { boolean success = false; String snapshotBackupUuid = null; - VmwareContext context = hostService.getServiceContext(cmd); + VmwareContext context = hostService.getServiceContext(cmd); + VirtualMachineMO vmMo; + try { VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd); morDs = hyperHost.findDatastore(cmd.getPool().getUuid()); - - VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName()); - if (vmMo == null) { - if(s_logger.isDebugEnabled()) - s_logger.debug("Unable to find owner VM for BackupSnapshotCommand on host " + hyperHost.getHyperHostName() + ", will try within datacenter"); - - vmMo = hyperHost.findVmOnPeerHyperHost(cmd.getVmName()); - if(vmMo == null) { - dsMo = new DatastoreMO(hyperHost.getContext(), morDs); - // restrict VM name to 32 chars, (else snapshot descriptor file name will be truncated to 32 chars of vm name) - workerVMName = UUID.randomUUID().toString().replaceAll("-", ""); - // attach a volume to dummay wrapper VM for taking snapshot and exporting the VM for backup - if (!hyperHost.createBlankVm(workerVMName, 1, 512, 0, false, 4, 0, VirtualMachineGuestOsIdentifier._otherGuest.toString(), morDs, false)) { - String msg = "Unable to create worker VM to execute BackupSnapshotCommand"; - s_logger.error(msg); - throw new Exception(msg); - } - vmMo = hyperHost.findVmOnHyperHost(workerVMName); - if (vmMo == null) { - throw new Exception("Failed to find the newly create or relocated VM. vmName: " + workerVMName); - } - workerVm = vmMo; - - // attach volume to worker VM - String datastoreVolumePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumePath); - vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs); - snapshotUUID = UUID.randomUUID().toString(); - if (!vmMo.createSnapshot(snapshotUUID, "Snapshot taken for " + cmd.getSnapshotName(), false, false)) { - throw new Exception("Failed to take snapshot " + cmd.getSnapshotName() + " on vm: " + cmd.getVmName()); + try { + vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName()); + if (vmMo == null) { + if(s_logger.isDebugEnabled()) + s_logger.debug("Unable to find owner VM for BackupSnapshotCommand on host " + hyperHost.getHyperHostName() + ", will try within datacenter"); + + vmMo = hyperHost.findVmOnPeerHyperHost(cmd.getVmName()); + if(vmMo == null) { + dsMo = new DatastoreMO(hyperHost.getContext(), morDs); + + workerVMName = hostService.getWorkerName(context, cmd); + + // attach a volume to dummay wrapper VM for taking snapshot and exporting the VM for backup + if (!hyperHost.createBlankVm(workerVMName, 1, 512, 0, false, 4, 0, VirtualMachineGuestOsIdentifier._otherGuest.toString(), morDs, false)) { + String msg = "Unable to create worker VM to execute BackupSnapshotCommand"; + s_logger.error(msg); + throw new Exception(msg); + } + vmMo = hyperHost.findVmOnHyperHost(workerVMName); + if (vmMo == null) { + throw new Exception("Failed to find the newly create or relocated VM. vmName: " + workerVMName); + } + workerVm = vmMo; + + // attach volume to worker VM + String datastoreVolumePath = String.format("[%s] %s.vmdk", dsMo.getName(), volumePath); + vmMo.attachDisk(new String[] { datastoreVolumePath }, morDs); + snapshotUUID = UUID.randomUUID().toString(); + if (!vmMo.createSnapshot(snapshotUUID, "Snapshot taken for " + cmd.getSnapshotName(), false, false)) { + throw new Exception("Failed to take snapshot " + cmd.getSnapshotName() + " on vm: " + cmd.getVmName()); + } } - } - } else { - if (!vmMo.createSnapshot(snapshotUuid, "Snapshot taken for " + cmd.getSnapshotName(), false, false)) { - throw new Exception("Failed to take snapshot " + cmd.getSnapshotName() + " on vm: " + cmd.getVmName()); - } + } else { + if (!vmMo.createSnapshot(snapshotUuid, "Snapshot taken for " + cmd.getSnapshotName(), false, false)) { + throw new Exception("Failed to take snapshot " + cmd.getSnapshotName() + " on vm: " + cmd.getVmName()); + } + } + } finally { + try { + if (workerVm != null) { + // detach volume and destroy worker vm + workerVm.moveAllVmDiskFiles(dsMo, "", false); + workerVm.detachAllDisks(); + workerVm.destroy(); + } + } catch (Throwable e) { + s_logger.warn("Failed to destroy worker VM: " + workerVMName); + } } snapshotBackupUuid = backupSnapshotToSecondaryStorage(vmMo, accountId, @@ -224,17 +239,6 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager { details = "BackupSnapshotCommand exception: " + StringUtils.getExceptionStackInfo(e); return new BackupSnapshotAnswer(cmd, false, details, snapshotBackupUuid, true); - } finally { - try { - if (workerVm != null) { - // detach volume and destroy worker vm - workerVm.moveAllVmDiskFiles(dsMo, "", false); - workerVm.detachAllDisks(); - workerVm.destroy(); - } - } catch (Throwable e) { - s_logger.warn("Failed to destroy worker VM: " + workerVMName); - } } return new BackupSnapshotAnswer(cmd, success, details, snapshotBackupUuid, true); diff --git a/server/src/com/cloud/ha/VmwareFencer.java b/server/src/com/cloud/ha/VmwareFencer.java new file mode 100644 index 00000000000..d3e344579dc --- /dev/null +++ b/server/src/com/cloud/ha/VmwareFencer.java @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.ha; + +import java.util.Map; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import com.cloud.host.HostVO; +import com.cloud.vm.VMInstanceVO; + +@Local(value=FenceBuilder.class) +public class VmwareFencer implements FenceBuilder { + String _name; + + @Override + public Boolean fenceOff(VMInstanceVO vm, HostVO host) { + return null; + } + + public VmwareFencer() { + super(); + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + _name = name; + return true; + } + + @Override + public String getName() { + return _name; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } +} diff --git a/server/src/com/cloud/ha/VmwareInvestigator.java b/server/src/com/cloud/ha/VmwareInvestigator.java new file mode 100644 index 00000000000..8eb0995ef95 --- /dev/null +++ b/server/src/com/cloud/ha/VmwareInvestigator.java @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. + * + * This software is licensed under the GNU General Public License v3 or later. + * + * It is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +package com.cloud.ha; + +import javax.ejb.Local; + +import com.cloud.host.HostVO; +import com.cloud.host.Status; +import com.cloud.utils.component.AdapterBase; +import com.cloud.vm.VMInstanceVO; + +@Local(value=Investigator.class) +public class VmwareInvestigator extends AdapterBase implements Investigator { + protected VmwareInvestigator() { + } + + @Override + public Status isAgentAlive(HostVO agent) { + return null; + } + + @Override + public Boolean isVmAlive(VMInstanceVO vm, HostVO host) { + return null; + } +} diff --git a/server/src/com/cloud/hypervisor/vmware/VmwareManagerImpl.java b/server/src/com/cloud/hypervisor/vmware/VmwareManagerImpl.java index 3533002661e..511ce2e25ca 100755 --- a/server/src/com/cloud/hypervisor/vmware/VmwareManagerImpl.java +++ b/server/src/com/cloud/hypervisor/vmware/VmwareManagerImpl.java @@ -53,7 +53,6 @@ import com.cloud.hypervisor.vmware.mo.HostMO; import com.cloud.hypervisor.vmware.mo.HostVirtualNicType; import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper; import com.cloud.hypervisor.vmware.mo.TaskMO; -import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType; import com.cloud.hypervisor.vmware.mo.VmwareHostType; import com.cloud.hypervisor.vmware.resource.SshHelper; import com.cloud.hypervisor.vmware.util.VmwareContext; @@ -284,7 +283,7 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis @Override public String composeWorkerName() { - return "cloud.worker." + _clusterMgr.getManagementNodeId() + "." + _clusterMgr.getCurrentRunId() + "." + UUID.randomUUID().toString(); + return UUID.randomUUID().toString().replace("-", ""); } @Override diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index f5d8d3a19c9..a50739ff2e8 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1596,7 +1596,11 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene if(serverState == State.Running) { try { - if(hostId != vm.getHostId()) { + // + // we had a bug that sometimes VM may be at Running State but host_id is null, we will cover it here. + // means that when CloudStack DB lost of host information, we will heal it with the info reported from host + // + if(vm.getHostId() == null || hostId != vm.getHostId()) { if (s_logger.isDebugEnabled()) { s_logger.debug("detected host change when VM " + vm + " is at running state, VM could be live-migrated externally from host " + vm.getHostId() + " to host " + hostId);