From cc7dc5e6be875a3f5708f5b176c7cf9d82d39d69 Mon Sep 17 00:00:00 2001 From: Kelven Yang Date: Fri, 3 Dec 2010 11:34:22 -0800 Subject: [PATCH] Persist disk chain info when we detach a volume, check disk chain info when we attach a volume, this is required when snapshot operations are involved in vwmare --- .../computing/LibvirtComputingResource.java | 2 +- api/src/com/cloud/agent/api/to/VolumeTO.java | 9 ++++++++- api/src/com/cloud/storage/Volume.java | 2 ++ console-proxy/.classpath | 2 +- console-viewer/.classpath | 2 +- core/.classpath | 1 - .../cloud/agent/api/AttachVolumeAnswer.java | 10 ++++++++++ .../cloud/agent/api/AttachVolumeCommand.java | 8 +++++++- .../agent/api/storage/DestroyCommand.java | 3 ++- .../xen/resource/CitrixResourceBase.java | 2 +- core/src/com/cloud/storage/VolumeVO.java | 13 ++++++++++++- .../src/com/cloud/vm/UserVmManagerImpl.java | 19 ++++++++++++------- setup/db/create-schema.sql | 1 + 13 files changed, 58 insertions(+), 16 deletions(-) diff --git a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java index e803bff99e8..dfff26ca6c5 100644 --- a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java +++ b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java @@ -1338,7 +1338,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv vol = primaryPool.storageVolCreateXML(volDef.toString(), 0); } - VolumeTO volume = new VolumeTO(cmd.getVolumeId(), dskch.getType(), getStorageResourceType(), pool.getType(), pool.getPath(), vol.getName(),vol.getKey(), disksize); + VolumeTO volume = new VolumeTO(cmd.getVolumeId(), dskch.getType(), getStorageResourceType(), pool.getType(), pool.getPath(), vol.getName(),vol.getKey(), disksize, null); return new CreateAnswer(cmd, volume); } catch (LibvirtException e) { diff --git a/api/src/com/cloud/agent/api/to/VolumeTO.java b/api/src/com/cloud/agent/api/to/VolumeTO.java index 60dfe9eaf2b..5b0f6299720 100644 --- a/api/src/com/cloud/agent/api/to/VolumeTO.java +++ b/api/src/com/cloud/agent/api/to/VolumeTO.java @@ -37,8 +37,9 @@ public class VolumeTO { private StoragePoolType storagePoolType; private long poolId; private int deviceId; + private String chainInfo; - public VolumeTO(long id, Volume.VolumeType type, Storage.StorageResourceType resourceType, StoragePoolType poolType, String name, String mountPoint, String path, long size) { + public VolumeTO(long id, Volume.VolumeType type, Storage.StorageResourceType resourceType, StoragePoolType poolType, String name, String mountPoint, String path, long size, String chainInfo) { this.id = id; this.name= name; this.path = path; @@ -47,6 +48,7 @@ public class VolumeTO { this.resourceType = resourceType; this.storagePoolType = poolType; this.mountPoint = mountPoint; + this.chainInfo = chainInfo; } public VolumeTO(Volume volume, StoragePool pool) { @@ -58,6 +60,7 @@ public class VolumeTO { this.resourceType = volume.getStorageResourceType(); this.storagePoolType = pool.getPoolType(); this.mountPoint = volume.getFolder(); + this.chainInfo = volume.getChainInfo(); } @@ -97,6 +100,10 @@ public class VolumeTO { return storagePoolType; } + public String getChainInfo() { + return chainInfo; + } + @Override public String toString() { return new StringBuilder("Vol[").append(id).append("|").append(type).append("|").append(path).append("|").append(size).append("]").toString(); diff --git a/api/src/com/cloud/storage/Volume.java b/api/src/com/cloud/storage/Volume.java index 330b2820bb4..49447543832 100755 --- a/api/src/com/cloud/storage/Volume.java +++ b/api/src/com/cloud/storage/Volume.java @@ -161,4 +161,6 @@ public interface Volume extends ControlledEntity, BasedOn { boolean getDestroyed(); long getDiskOfferingId(); + + String getChainInfo(); } diff --git a/console-proxy/.classpath b/console-proxy/.classpath index 5a34eae6642..521b7a55fa9 100644 --- a/console-proxy/.classpath +++ b/console-proxy/.classpath @@ -4,6 +4,6 @@ - + diff --git a/console-viewer/.classpath b/console-viewer/.classpath index e8a8d8c0a84..170f58a8bbb 100644 --- a/console-viewer/.classpath +++ b/console-viewer/.classpath @@ -2,6 +2,6 @@ - + diff --git a/core/.classpath b/core/.classpath index 6f23bda4ba2..4fbdcf5ff6e 100644 --- a/core/.classpath +++ b/core/.classpath @@ -1,7 +1,6 @@ - diff --git a/core/src/com/cloud/agent/api/AttachVolumeAnswer.java b/core/src/com/cloud/agent/api/AttachVolumeAnswer.java index 22b84b268b2..999942bdd61 100644 --- a/core/src/com/cloud/agent/api/AttachVolumeAnswer.java +++ b/core/src/com/cloud/agent/api/AttachVolumeAnswer.java @@ -20,6 +20,7 @@ package com.cloud.agent.api; public class AttachVolumeAnswer extends Answer { private Long deviceId; + private String chainInfo; protected AttachVolumeAnswer() { @@ -40,10 +41,19 @@ public class AttachVolumeAnswer extends Answer { super(cmd); this.deviceId = null; } + /** * @return the deviceId */ public Long getDeviceId() { return deviceId; } + + public void setChainInfo(String chainInfo) { + this.chainInfo = chainInfo; + } + + public String getChainInfo() { + return chainInfo; + } } diff --git a/core/src/com/cloud/agent/api/AttachVolumeCommand.java b/core/src/com/cloud/agent/api/AttachVolumeCommand.java index 0ac47dd7e2e..3029ed0fda2 100644 --- a/core/src/com/cloud/agent/api/AttachVolumeCommand.java +++ b/core/src/com/cloud/agent/api/AttachVolumeCommand.java @@ -30,11 +30,12 @@ public class AttachVolumeCommand extends Command { String volumePath; String volumeName; Long deviceId; + String chainInfo; protected AttachVolumeCommand() { } - public AttachVolumeCommand(boolean attach, String vmName, StoragePoolType pooltype, String volumeFolder, String volumePath, String volumeName, Long deviceId) { + public AttachVolumeCommand(boolean attach, String vmName, StoragePoolType pooltype, String volumeFolder, String volumePath, String volumeName, Long deviceId, String chainInfo) { this.attach = attach; this.vmName = vmName; this.pooltype = pooltype; @@ -42,6 +43,7 @@ public class AttachVolumeCommand extends Command { this.volumePath = volumePath; this.volumeName = volumeName; this.deviceId = deviceId; + this.chainInfo = chainInfo; } @Override @@ -92,4 +94,8 @@ public class AttachVolumeCommand extends Command { public void setPoolUuid(String poolUuid) { this.poolUuid = poolUuid; } + + public String getChainInfo() { + return chainInfo; + } } diff --git a/core/src/com/cloud/agent/api/storage/DestroyCommand.java b/core/src/com/cloud/agent/api/storage/DestroyCommand.java index e7cdaec433f..703ae2ef8e9 100755 --- a/core/src/com/cloud/agent/api/storage/DestroyCommand.java +++ b/core/src/com/cloud/agent/api/storage/DestroyCommand.java @@ -37,7 +37,8 @@ public class DestroyCommand extends StorageCommand { } public DestroyCommand(StoragePoolVO pool, VMTemplateStoragePoolVO templatePoolRef) { - volume = new VolumeTO(templatePoolRef.getId(), null, Storage.StorageResourceType.STORAGE_POOL, pool.getPoolType(), null, pool.getPath(), templatePoolRef.getInstallPath(), templatePoolRef.getTemplateSize()); + volume = new VolumeTO(templatePoolRef.getId(), null, Storage.StorageResourceType.STORAGE_POOL, pool.getPoolType(), null, + pool.getPath(), templatePoolRef.getInstallPath(), templatePoolRef.getTemplateSize(), null); } public VolumeTO getVolume() { diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 8a230c23844..ad03c1676bd 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -4710,7 +4710,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR s_logger.debug("Succesfully created VDI for " + cmd + ". Uuid = " + vdir.uuid); VolumeTO vol = new VolumeTO(cmd.getVolumeId(), dskch.getType(), Storage.StorageResourceType.STORAGE_POOL, pool.getType(), vdir.nameLabel, pool.getPath(), vdir.uuid, - vdir.virtualSize); + vdir.virtualSize, null); return new CreateAnswer(cmd, vol); } catch (Exception e) { s_logger.warn("Unable to create volume; Pool=" + pool + "; Disk: " + dskch, e); diff --git a/core/src/com/cloud/storage/VolumeVO.java b/core/src/com/cloud/storage/VolumeVO.java index d3b02e0f95e..380dceaf119 100755 --- a/core/src/com/cloud/storage/VolumeVO.java +++ b/core/src/com/cloud/storage/VolumeVO.java @@ -160,6 +160,9 @@ public class VolumeVO implements Volume { @Column(name="source_id") Long sourceId; + @Column(name="chain_info") + String chainInfo; + /** * Constructor for data disk. * @param type @@ -559,5 +562,13 @@ public class VolumeVO implements Volume { public void setAttached(Date attached){ this.attached = attached; } - + + @Override + public String getChainInfo() { + return this.chainInfo; + } + + public void setChainInfo(String chainInfo) { + this.chainInfo = chainInfo; + } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 6cef007d250..6b456504978 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -561,7 +561,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualM if (sendCommand) { StoragePoolVO volumePool = _storagePoolDao.findById(volume.getPoolId()); - AttachVolumeCommand cmd = new AttachVolumeCommand(true, vm.getInstanceName(), volume.getPoolType(), volume.getFolder(), volume.getPath(), volume.getName(), deviceId); + AttachVolumeCommand cmd = new AttachVolumeCommand(true, vm.getInstanceName(), volume.getPoolType(), volume.getFolder(), volume.getPath(), volume.getName(), deviceId, volume.getChainInfo()); cmd.setPoolUuid(volumePool.getUuid()); try { @@ -694,7 +694,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualM Answer answer = null; if (sendCommand) { - AttachVolumeCommand cmd = new AttachVolumeCommand(false, vm.getInstanceName(), volume.getPoolType(), volume.getFolder(), volume.getPath(), volume.getName(), cmmd.getDeviceId() != null ? cmmd.getDeviceId() : volume.getDeviceId()); + AttachVolumeCommand cmd = new AttachVolumeCommand(false, vm.getInstanceName(), volume.getPoolType(), volume.getFolder(), volume.getPath(), volume.getName(), + cmmd.getDeviceId() != null ? cmmd.getDeviceId() : volume.getDeviceId(), volume.getChainInfo()); StoragePoolVO volumePool = _storagePoolDao.findById(volume.getPoolId()); cmd.setPoolUuid(volumePool.getUuid()); @@ -715,11 +716,15 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, VirtualM if (!sendCommand || (answer != null && answer.getResult())) { // Mark the volume as detached _volsDao.detachVolume(volume.getId()); - if(!vm.getHostName().equals(vm.getDisplayName())) { - event.setDescription("Volume: " +volume.getName()+ " successfully detached from VM: "+vm.getHostName()+"("+vm.getDisplayName()+")"); - } else { - event.setDescription("Volume: " +volume.getName()+ " successfully detached from VM: "+vm.getHostName()); - } + if(answer != null && answer instanceof AttachVolumeAnswer) { + volume.setChainInfo(((AttachVolumeAnswer)answer).getChainInfo()); + _volsDao.update(volume.getId(), volume); + } + + if(!vm.getHostName().equals(vm.getDisplayName())) + event.setDescription("Volume: " +volume.getName()+ " successfully detached from VM: "+vm.getHostName()+"("+vm.getDisplayName()+")"); + else + event.setDescription("Volume: " +volume.getName()+ " successfully detached from VM: "+vm.getHostName()); event.setLevel(EventVO.LEVEL_INFO); _eventDao.persist(event); diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 625bd4c07b6..eda390a0c11 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -322,6 +322,7 @@ CREATE TABLE `cloud`.`volumes` ( `state` varchar(32) COMMENT 'State machine', `source_id` bigint unsigned COMMENT 'id for the source', `source_type` varchar(32) COMMENT 'source from which the volume is created -- snapshot, diskoffering, template, blank', + `chain_info` text COMMENT 'save possible disk chain info in primary storage', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;