Return-Path: X-Original-To: apmail-cloudstack-commits-archive@www.apache.org Delivered-To: apmail-cloudstack-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id B72F2101AF for ; Wed, 4 Sep 2013 22:42:16 +0000 (UTC) Received: (qmail 43700 invoked by uid 500); 4 Sep 2013 22:42:11 -0000 Delivered-To: apmail-cloudstack-commits-archive@cloudstack.apache.org Received: (qmail 43645 invoked by uid 500); 4 Sep 2013 22:42:11 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 43249 invoked by uid 99); 4 Sep 2013 22:42:11 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 04 Sep 2013 22:42:11 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 1FAA5900830; Wed, 4 Sep 2013 22:42:11 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: kelveny@apache.org To: commits@cloudstack.apache.org Date: Wed, 04 Sep 2013 22:42:27 -0000 Message-Id: <009575ac804842e5857b0ad6c2de8456@git.apache.org> In-Reply-To: <2120af6f82154b6dad8445eadc5c6cc2@git.apache.org> References: <2120af6f82154b6dad8445eadc5c6cc2@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [18/27] git commit: updated refs/heads/master to ae23144 CLOUDSTACK-4585: make run-time datastore folder migration, VM snapshot, bug in root disk controller type carried from previous version work under upgrade situation Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/ae231444 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/ae231444 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/ae231444 Branch: refs/heads/master Commit: ae231444bc885ee5e9a5d4bb3003bef651c849d6 Parents: e81e75c Author: Kelven Yang Authored: Sun Sep 1 07:14:27 2013 -0700 Committer: Kelven Yang Committed: Wed Sep 4 14:49:46 2013 -0700 ---------------------------------------------------------------------- .../com/cloud/upgrade/dao/Upgrade410to420.java | 2 +- .../vmware/resource/VmwareResource.java | 146 +++++++++++-------- .../resource/VmwareStorageLayoutHelper.java | 4 +- .../hypervisor/vmware/mo/VirtualMachineMO.java | 20 ++- .../hypervisor/vmware/util/VmwareHelper.java | 50 ++++--- 5 files changed, 136 insertions(+), 86 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae231444/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java ---------------------------------------------------------------------- diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java index 2afca0b..9ca7f54 100755 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade410to420.java @@ -727,7 +727,7 @@ public class Upgrade410to420 implements DbUpgrade { pstmt.close(); } else { if (hypervisorsListInUse.contains(hypervisorAndTemplateName.getKey())){ - throw new CloudRuntimeException("4.2.0 " + hypervisorAndTemplateName.getKey() + " SystemVm template not found. Cannot upgrade system Vms"); + // throw new CloudRuntimeException("4.2.0 " + hypervisorAndTemplateName.getKey() + " SystemVm template not found. Cannot upgrade system Vms"); } else { s_logger.warn("4.2.0 " + hypervisorAndTemplateName.getKey() + " SystemVm template not found. " + hypervisorAndTemplateName.getKey() + " hypervisor is not used, so not failing upgrade"); // Update the latest template URLs for corresponding hypervisor http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae231444/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index a548ceb..450c5f0 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -2807,7 +2807,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (vol.getType() == Volume.Type.ISO) continue; - controllerKey = getDiskController(vol, vmSpec, ideControllerKey, scsiControllerKey); + VirtualMachineDiskInfo matchingExistingDisk = getMatchingExistingDisk(diskInfoBuilder, vol); + controllerKey = getDiskController(matchingExistingDisk, vol, vmSpec, ideControllerKey, scsiControllerKey); VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData(); PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore(); @@ -2816,19 +2817,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa VirtualDevice device; String[] diskChain = syncDiskChain(dcMo, vmMo, vmSpec, - vol, diskInfoBuilder, - dataStoresDetails, - (controllerKey == ideControllerKey) ? true : false, - 0, // currently only support bus 0 - (controllerKey == ideControllerKey) ? ideUnitNumber : scsiUnitNumber); + vol, matchingExistingDisk, + dataStoresDetails); - device = VmwareHelper.prepareDiskDevice(vmMo, controllerKey, + device = VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, diskChain, volumeDsDetails.first(), (controllerKey == ideControllerKey) ? ideUnitNumber++ : scsiUnitNumber++, i + 1); deviceConfigSpecArray[i].setDevice(device); - deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD); + deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD); if(s_logger.isDebugEnabled()) s_logger.debug("Prepare volume at new device " + _gson.toJson(device)); @@ -2951,55 +2949,37 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa // return the finalized disk chain for startup, from top to bottom private String[] syncDiskChain(DatacenterMO dcMo, VirtualMachineMO vmMo, VirtualMachineTO vmSpec, - DiskTO vol, VirtualMachineDiskInfoBuilder diskInfoBuilder, - HashMap> dataStoresDetails, - boolean ideController, int deviceBusNumber, int deviceUnitNumber) throws Exception { + DiskTO vol, VirtualMachineDiskInfo diskInfo, + HashMap> dataStoresDetails + ) throws Exception { VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData(); PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO)volumeTO.getDataStore(); - String deviceBusName; - if(ideController) - deviceBusName = String.format("ide%d:%d", deviceBusNumber, deviceUnitNumber); - else - deviceBusName = String.format("scsi%d:%d", deviceBusNumber, deviceUnitNumber); - Pair volumeDsDetails = dataStoresDetails.get(primaryStore.getUuid()); if(volumeDsDetails == null) throw new Exception("Primary datastore " + primaryStore.getUuid() + " is not mounted on host."); DatastoreMO dsMo = volumeDsDetails.second(); // we will honor vCenter's meta if it exists - if(diskInfoBuilder != null && diskInfoBuilder.getDiskCount() > 0) { - // we will always on-disk info from vCenter in this case - VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByDeviceBusName(deviceBusName); - if(diskInfo != null) { - if(s_logger.isInfoEnabled()) - s_logger.info("Volume " + volumeTO.getId() + " does not seem to exist on datastore. use on-disk chain: " + - _gson.toJson(diskInfo)); - - return diskInfo.getDiskChain(); - } else { - s_logger.warn("Volume " + volumeTO.getId() + " does not seem to exist on datastore. on-disk may be out of sync as well. disk device info: " + deviceBusName); - } - } + if(diskInfo != null) { + // to deal with run-time upgrade to maintain the new datastore folder structure + String disks[] = diskInfo.getDiskChain(); + for(int i = 0; i < disks.length; i++) { + DatastoreFile file = new DatastoreFile(disks[i]); + if(file.getDir() != null && file.getDir().isEmpty()) { + s_logger.info("Perform run-time datastore folder upgrade. sync " + disks[i] + " to VM folder"); + disks[i] = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder( + dcMo, vmMo.getName(), dsMo, file.getFileBaseName()); + } + } + return disks; + } String datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder( dcMo, vmMo.getName(), dsMo, volumeTO.getPath()); if(!dsMo.fileExists(datastoreDiskPath)) { - if(s_logger.isInfoEnabled()) - s_logger.info("Volume " + volumeTO.getId() + " does not seem to exist on datastore, out of sync? path: " + datastoreDiskPath); - - // last resort, try chain info stored in DB - if(volumeTO.getChainInfo() != null) { - VirtualMachineDiskInfo diskInfo = _gson.fromJson(volumeTO.getChainInfo(), VirtualMachineDiskInfo.class); - if(diskInfo != null) { - s_logger.info("Use chain info from DB: " + volumeTO.getChainInfo()); - return diskInfo.getDiskChain(); - } - - throw new Exception("Volume " + volumeTO.getId() + " does not seem to exist on datastore. Broken disk chain"); - } + s_logger.warn("Volume " + volumeTO.getId() + " does not seem to exist on datastore, out of sync? path: " + datastoreDiskPath); } return new String[] { datastoreDiskPath }; @@ -3209,21 +3189,80 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } - private static int getDiskController(DiskTO vol, VirtualMachineTO vmSpec, int ideControllerKey, int scsiControllerKey) { + private VirtualMachineDiskInfo getMatchingExistingDisk(VirtualMachineDiskInfoBuilder diskInfoBuilder, DiskTO vol) { + if(diskInfoBuilder != null) { + VolumeObjectTO volume = (VolumeObjectTO)vol.getData(); + + VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(volume.getPath()); + if(diskInfo != null) { + s_logger.info("Found existing disk info from volume path: " + volume.getPath()); + return diskInfo; + } else { + String chainInfo = volume.getChainInfo(); + if(chainInfo != null) { + VirtualMachineDiskInfo infoInChain = _gson.fromJson(chainInfo, VirtualMachineDiskInfo.class); + if(infoInChain != null) { + String[] disks = infoInChain.getDiskChain(); + if(disks.length > 0) { + for(String diskPath : disks) { + DatastoreFile file = new DatastoreFile(diskPath); + diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(file.getFileBaseName()); + if(diskInfo != null) { + s_logger.info("Found existing disk from chain info: " + diskPath); + return diskInfo; + } + } + } + + if(diskInfo == null) { + diskInfo = diskInfoBuilder.getDiskInfoByDeviceBusName(infoInChain.getDiskDeviceBusName()); + if(diskInfo != null) { + s_logger.info("Found existing disk from from chain device bus information: " + infoInChain.getDiskDeviceBusName()); + return diskInfo; + } + } + } + } + } + } + + return null; + } + + private int getDiskController(VirtualMachineDiskInfo matchingExistingDisk, DiskTO vol, + VirtualMachineTO vmSpec, int ideControllerKey, int scsiControllerKey) { + int controllerKey; + if(matchingExistingDisk != null) { + s_logger.info("Chose disk controller based on existing information: " + matchingExistingDisk.getDiskDeviceBusName()); + if(matchingExistingDisk.getDiskDeviceBusName().startsWith("ide")) + return ideControllerKey; + else + return scsiControllerKey; + } if(vol.getType() == Volume.Type.ROOT) { - if(vmSpec.getDetails() != null && vmSpec.getDetails().get(VmDetailConstants.ROOK_DISK_CONTROLLER) != null) + Map vmDetails = vmSpec.getDetails(); + if(vmDetails != null && vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER) != null) { - if(vmSpec.getDetails().get(VmDetailConstants.ROOK_DISK_CONTROLLER).equalsIgnoreCase("scsi")) + if(vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER).equalsIgnoreCase("scsi")) { + s_logger.info("Chose disk controller for vol " + vol.getType() + " -> scsi, based on root disk controller settings: " + + vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER)); controllerKey = scsiControllerKey; - else + } + else { + s_logger.info("Chose disk controller for vol " + vol.getType() + " -> ide, based on root disk controller settings: " + + vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER)); controllerKey = ideControllerKey; + } } else { + s_logger.info("Chose disk controller for vol " + vol.getType() + " -> scsi. due to null root disk controller setting"); controllerKey = scsiControllerKey; } + } else { // DATA volume always use SCSI device + s_logger.info("Chose disk controller for vol " + vol.getType() + " -> scsi"); controllerKey = scsiControllerKey; } @@ -3234,9 +3273,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa int ideControllerKey, int scsiControllerKey) throws Exception { VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder(); - int controllerKey; - int ideUnitNumber = 1; // we always count in IDE device first - int scsiUnitNumber = 0; for(DiskTO vol: sortedDisks) { if (vol.getType() == Volume.Type.ISO) @@ -3244,15 +3280,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa VolumeObjectTO volumeTO = (VolumeObjectTO)vol.getData(); - controllerKey = getDiskController(vol, vmSpec, ideControllerKey, scsiControllerKey); - - String deviceBusName; - if(controllerKey == ideControllerKey) - deviceBusName = String.format("ide%d:%d", 0, ideUnitNumber++); - else - deviceBusName = String.format("scsi%d:%d", 0, scsiUnitNumber++); - - VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByDeviceBusName(deviceBusName); + VirtualMachineDiskInfo diskInfo = getMatchingExistingDisk(diskInfoBuilder, vol); assert(diskInfo != null); String[] diskChain = diskInfo.getDiskChain(); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae231444/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageLayoutHelper.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageLayoutHelper.java b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageLayoutHelper.java index 20544df..24b13c8 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageLayoutHelper.java +++ b/plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageLayoutHelper.java @@ -109,10 +109,10 @@ public class VmwareStorageLayoutHelper { String[] vmdkFullCloneModePair = getVmdkFilePairDatastorePath(ds, vmName, vmdkName, VmwareStorageLayoutType.VMWARE, false); - if(!ds.fileExists(vmdkLinkedCloneModeLegacyPair[0])) { + if(!ds.fileExists(vmdkLinkedCloneModeLegacyPair[0]) && !ds.fileExists(vmdkLinkedCloneModePair[0])) { // To protect against inconsistency caused by non-atomic datastore file management, detached disk may // be left over in its previous owner VM. We will do a fixup synchronization here by moving it to root - // again + // again. // syncVolumeToRootFolder(dcMo, ds, vmdkName); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae231444/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java ---------------------------------------------------------------------- diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java index 3512af5..fcf2e5f 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/VirtualMachineMO.java @@ -988,7 +988,7 @@ public class VirtualMachineMO extends BaseMO { s_logger.trace("vCenter API trace - attachDisk(). target MOR: " + _mor.getValue() + ", vmdkDatastorePath: " + new Gson().toJson(vmdkDatastorePathChain) + ", datastore: " + morDs.getValue()); - VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, getScsiDeviceControllerKey(), + VirtualDevice newDisk = VmwareHelper.prepareDiskDevice(this, null, getScsiDeviceControllerKey(), vmdkDatastorePathChain, morDs, -1, 1); VirtualMachineConfigSpec reConfigSpec = new VirtualMachineConfigSpec(); VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec(); @@ -1573,7 +1573,7 @@ public class VirtualMachineMO extends BaseMO { VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec(); VirtualDeviceConfigSpec deviceConfigSpec = new VirtualDeviceConfigSpec(); - VirtualDevice device = VmwareHelper.prepareDiskDevice(clonedVmMo, -1, disks, morDs, -1, 1); + VirtualDevice device = VmwareHelper.prepareDiskDevice(clonedVmMo, null, -1, disks, morDs, -1, 1); deviceConfigSpec.setDevice(device); deviceConfigSpec.setOperation(VirtualDeviceConfigSpecOperation.ADD); @@ -1841,6 +1841,22 @@ public class VirtualMachineMO extends BaseMO { return null; } + public VirtualDisk getDiskDeviceByDeviceBusName(String deviceBusName) throws Exception { + List devices = (List)_context.getVimClient().getDynamicProperty(_mor, "config.hardware.device"); + + if(devices != null && devices.size() > 0) { + for(VirtualDevice device : devices) { + if(device instanceof VirtualDisk) { + String deviceNumbering = getDeviceBusName(devices, device); + if(deviceNumbering.equals(deviceBusName)) + return (VirtualDisk)device; + } + } + } + + return null; + } + public VirtualMachineDiskInfoBuilder getDiskInfoBuilder() throws Exception { VirtualMachineDiskInfoBuilder builder = new VirtualMachineDiskInfoBuilder(); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ae231444/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java ---------------------------------------------------------------------- diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java index e545c8e..bcf9f14 100644 --- a/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/util/VmwareHelper.java @@ -264,18 +264,40 @@ public class VmwareHelper { } // vmdkDatastorePath: [datastore name] vmdkFilePath - public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, int controllerKey, String vmdkDatastorePathChain[], + public static VirtualDevice prepareDiskDevice(VirtualMachineMO vmMo, VirtualDisk device, int controllerKey, String vmdkDatastorePathChain[], ManagedObjectReference morDs, int deviceNumber, int contextNumber) throws Exception { assert(vmdkDatastorePathChain != null); assert(vmdkDatastorePathChain.length >= 1); - VirtualDisk disk = new VirtualDisk(); - - VirtualDiskFlatVer2BackingInfo backingInfo = new VirtualDiskFlatVer2BackingInfo(); - backingInfo.setDatastore(morDs); + VirtualDisk disk; + VirtualDiskFlatVer2BackingInfo backingInfo; + if(device != null) { + disk = device; + backingInfo = (VirtualDiskFlatVer2BackingInfo)disk.getBacking(); + } else { + disk = new VirtualDisk(); + backingInfo = new VirtualDiskFlatVer2BackingInfo(); + backingInfo.setDatastore(morDs); + backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value()); + disk.setBacking(backingInfo); + + if(controllerKey < 0) + controllerKey = vmMo.getIDEDeviceControllerKey(); + if(deviceNumber < 0) + deviceNumber = vmMo.getNextDeviceNumber(controllerKey); + + disk.setControllerKey(controllerKey); + disk.setKey(-contextNumber); + disk.setUnitNumber(deviceNumber); + + VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo(); + connectInfo.setConnected(true); + connectInfo.setStartConnected(true); + disk.setConnectable(connectInfo); + } + backingInfo.setFileName(vmdkDatastorePathChain[0]); - backingInfo.setDiskMode(VirtualDiskMode.PERSISTENT.value()); if(vmdkDatastorePathChain.length > 1) { String[] parentDisks = new String[vmdkDatastorePathChain.length - 1]; for(int i = 0; i < vmdkDatastorePathChain.length - 1; i++) @@ -284,22 +306,6 @@ public class VmwareHelper { setParentBackingInfo(backingInfo, morDs, parentDisks); } - disk.setBacking(backingInfo); - - if(controllerKey < 0) - controllerKey = vmMo.getIDEDeviceControllerKey(); - if(deviceNumber < 0) - deviceNumber = vmMo.getNextDeviceNumber(controllerKey); - - disk.setControllerKey(controllerKey); - disk.setKey(-contextNumber); - disk.setUnitNumber(deviceNumber); - - VirtualDeviceConnectInfo connectInfo = new VirtualDeviceConnectInfo(); - connectInfo.setConnected(true); - connectInfo.setStartConnected(true); - disk.setConnectable(connectInfo); - return disk; }