From b55e7a5bf4f2483f5a68fc5ca5de8b27a19e505b Mon Sep 17 00:00:00 2001 From: Edison Su Date: Tue, 18 Jan 2011 12:34:20 -0500 Subject: [PATCH] bug 8032: for xen pv guest, if an iso is attached, then only when the iso's guest os type is equal to vm's os type, we boot from iso. status 8032: resolved fixed --- api/src/com/cloud/agent/api/to/VolumeTO.java | 20 ++++++++++++++ .../xen/resource/CitrixResourceBase.java | 27 +++++++++++++------ .../src/com/cloud/vm/UserVmManagerImpl.java | 4 ++- .../cloud/vm/VirtualMachineManagerImpl.java | 5 ++-- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/api/src/com/cloud/agent/api/to/VolumeTO.java b/api/src/com/cloud/agent/api/to/VolumeTO.java index 096169e4c6a..7cda2e5659a 100644 --- a/api/src/com/cloud/agent/api/to/VolumeTO.java +++ b/api/src/com/cloud/agent/api/to/VolumeTO.java @@ -37,6 +37,7 @@ public class VolumeTO { private String storagePoolUuid; private long deviceId; private String chainInfo; + private String guestOsType; public VolumeTO(long id, Volume.VolumeType type, Storage.StorageResourceType resourceType, StoragePoolType poolType, String poolUuid, String name, String mountPoint, String path, long size, String chainInfo) { @@ -52,6 +53,21 @@ public class VolumeTO { this.chainInfo = chainInfo; } + public VolumeTO(long id, Volume.VolumeType type, Storage.StorageResourceType resourceType, StoragePoolType poolType, + String poolUuid, String name, String mountPoint, String path, long size, String chainInfo, String guestOsType) { + this.id = id; + this.name= name; + this.path = path; + this.size = size; + this.type = type; + this.resourceType = resourceType; + this.storagePoolType = poolType; + this.storagePoolUuid = poolUuid; + this.mountPoint = mountPoint; + this.chainInfo = chainInfo; + this.guestOsType = guestOsType; + } + public VolumeTO(Volume volume, StoragePool pool) { this.id = volume.getId(); this.name = volume.getName(); @@ -115,6 +131,10 @@ public class VolumeTO { return chainInfo; } + public String getOsType() { + return guestOsType; + } + @Override public String toString() { return new StringBuilder("Vol[").append(id).append("|").append(type).append("|").append(path).append("|").append(size).append("]").toString(); diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 0d8f42a1435..dcabd6d5cdf 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -172,6 +172,7 @@ import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.StorageLayer; import com.cloud.storage.StoragePoolVO; +import com.cloud.storage.Volume; import com.cloud.storage.Volume.VolumeType; import com.cloud.storage.VolumeVO; import com.cloud.storage.resource.StoragePoolResource; @@ -741,18 +742,28 @@ public abstract class CitrixResourceBase implements ServerResource { if (!(guestOsTypeName.startsWith("Windows") || guestOsTypeName.startsWith("Citrix") || guestOsTypeName.startsWith("Other"))) { if (vmSpec.getBootloader() == BootloaderType.CD) { - vm.setPVBootloader(conn, "eliloader"); - Map otherConfig = vm.getOtherConfig(conn); - otherConfig.put( "install-repository", "cdrom"); - vm.setOtherConfig(conn, otherConfig); + VolumeTO [] disks = vmSpec.getDisks(); + for (VolumeTO disk : disks) { + if (disk.getType() == Volume.VolumeType.ISO && disk.getOsType() != null) { + String isoGuestOsName = getGuestOsType(disk.getOsType(), vmSpec.getBootloader() == BootloaderType.CD); + if (!isoGuestOsName.equals(guestOsTypeName)) { + vmSpec.setBootloader(BootloaderType.PyGrub); + } + } + } + } + if (vmSpec.getBootloader() == BootloaderType.CD) { + vm.setPVBootloader(conn, "eliloader"); + Map otherConfig = vm.getOtherConfig(conn); + otherConfig.put( "install-repository", "cdrom"); + vm.setOtherConfig(conn, otherConfig); } else if (vmSpec.getBootloader() == BootloaderType.PyGrub ){ - vm.setPVBootloader(conn, "pygrub"); + vm.setPVBootloader(conn, "pygrub"); } else { - vm.destroy(conn); - throw new CloudRuntimeException("Unable to handle boot loader type: " + vmSpec.getBootloader()); + vm.destroy(conn); + throw new CloudRuntimeException("Unable to handle boot loader type: " + vmSpec.getBootloader()); } } - return vm; } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 132aa54e7e2..7bec239d1b8 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2419,8 +2419,10 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager isoPath = isoPathPair.first(); } profile.setBootLoaderType(BootloaderType.CD); + GuestOSVO guestOS = _guestOSDao.findById(template.getGuestOSId()); VolumeTO iso = new VolumeTO(profile.getId(), Volume.VolumeType.ISO, StorageResourceType.STORAGE_POOL, StoragePoolType.ISO, null, template.getName(), null, isoPath, - 0, null); + 0, null, guestOS.getDisplayName()); + iso.setDeviceId(3); profile.addDisk(iso); vo.setIsoId(template.getId()); diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index d6d8aff61e7..3e02076b226 100644 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -558,7 +558,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { VMTemplateVO template = _templateDao.findById(vm.getTemplateId()); DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), vm.getPodId(), null, null); HypervisorGuru hvGuru = _hvGurus.get(vm.getHypervisorType()); - VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, null, params); try { @@ -567,7 +566,9 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager { ExcludeList avoids = new ExcludeList(); int retry = _retry; while (retry-- != 0) { // It's != so that it can match -1. - + //Note: need to re-intialize vmProfile in every re-try, or you will got a lot of duplicate disks and nics. + VirtualMachineProfileImpl vmProfile = new VirtualMachineProfileImpl(vm, template, offering, null, params); + DeployDestination dest = null; for (DeploymentPlanner planner : _planners) { dest = planner.plan(vmProfile, plan, avoids);