cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ahu...@apache.org
Subject [04/11] Moved volume related code into cloud-engine-orchestration
Date Tue, 13 Aug 2013 04:09:36 GMT
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/de2bd96d/server/src/com/cloud/storage/VolumeManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeManagerImpl.java b/server/src/com/cloud/storage/VolumeManagerImpl.java
deleted file mode 100644
index 5c0ec66..0000000
--- a/server/src/com/cloud/storage/VolumeManagerImpl.java
+++ /dev/null
@@ -1,2861 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.cloud.storage;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ExecutionException;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import com.cloud.utils.DateUtil;
-import com.cloud.utils.EnumUtils;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.UriUtils;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
-import org.apache.cloudstack.api.BaseCmd;
-import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.UpdateVolumeCmd;
-import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreProviderManager;
-import org.apache.cloudstack.engine.subsystem.api.storage.HostScope;
-import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.Scope;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService;
-import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
-import org.apache.cloudstack.framework.async.AsyncCallFuture;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.jobs.AsyncJob;
-import org.apache.cloudstack.framework.jobs.AsyncJobExecutionContext;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
-import org.apache.cloudstack.storage.command.AttachAnswer;
-import org.apache.cloudstack.storage.command.AttachCommand;
-import org.apache.cloudstack.storage.command.CommandResult;
-import org.apache.cloudstack.storage.command.DettachCommand;
-import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
-import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
-import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
-
-import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.to.DataTO;
-import com.cloud.agent.api.to.DiskTO;
-import com.cloud.agent.api.to.VirtualMachineTO;
-import com.cloud.alert.AlertManager;
-import com.cloud.api.ApiDBUtils;
-import com.cloud.capacity.CapacityManager;
-import com.cloud.capacity.dao.CapacityDao;
-import com.cloud.configuration.Config;
-import com.cloud.configuration.ConfigurationManager;
-import com.cloud.configuration.Resource.ResourceType;
-import com.cloud.consoleproxy.ConsoleProxyManager;
-import com.cloud.dc.ClusterVO;
-import com.cloud.dc.DataCenter;
-import com.cloud.dc.DataCenterVO;
-import com.cloud.dc.HostPodVO;
-import com.cloud.dc.Pod;
-import com.cloud.dc.dao.ClusterDao;
-import com.cloud.dc.dao.DataCenterDao;
-import com.cloud.dc.dao.HostPodDao;
-import com.cloud.deploy.DeployDestination;
-import com.cloud.domain.Domain;
-import com.cloud.domain.dao.DomainDao;
-import com.cloud.event.ActionEvent;
-import com.cloud.event.EventTypes;
-import com.cloud.event.UsageEventUtils;
-import com.cloud.event.dao.EventDao;
-import com.cloud.exception.ConcurrentOperationException;
-import com.cloud.exception.InsufficientStorageCapacityException;
-import com.cloud.exception.InvalidParameterValueException;
-import com.cloud.exception.PermissionDeniedException;
-import com.cloud.exception.ResourceAllocationException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.host.HostVO;
-import com.cloud.host.dao.HostDao;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.hypervisor.HypervisorCapabilitiesVO;
-import com.cloud.hypervisor.HypervisorGuruManager;
-import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
-import com.cloud.network.NetworkModel;
-import com.cloud.org.Grouping;
-import com.cloud.resource.ResourceManager;
-import com.cloud.server.ManagementServer;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.service.dao.ServiceOfferingDao;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.storage.Volume.Type;
-import com.cloud.storage.dao.DiskOfferingDao;
-import com.cloud.storage.dao.SnapshotDao;
-import com.cloud.storage.dao.SnapshotPolicyDao;
-import com.cloud.storage.dao.StoragePoolHostDao;
-import com.cloud.storage.dao.StoragePoolWorkDao;
-import com.cloud.storage.dao.UploadDao;
-import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.storage.dao.VMTemplatePoolDao;
-import com.cloud.storage.dao.VolumeDao;
-import com.cloud.storage.dao.VolumeDetailsDao;
-import com.cloud.storage.download.DownloadMonitor;
-import com.cloud.storage.secondary.SecondaryStorageVmManager;
-import com.cloud.storage.snapshot.SnapshotApiService;
-import com.cloud.storage.snapshot.SnapshotManager;
-import com.cloud.storage.snapshot.SnapshotScheduler;
-import com.cloud.storage.upload.UploadMonitor;
-import com.cloud.tags.dao.ResourceTagDao;
-import com.cloud.template.TemplateManager;
-import com.cloud.user.Account;
-import com.cloud.user.AccountManager;
-import com.cloud.user.ResourceLimitService;
-import com.cloud.user.VmDiskStatisticsVO;
-import com.cloud.user.dao.AccountDao;
-import com.cloud.user.dao.UserDao;
-import com.cloud.user.dao.VmDiskStatisticsDao;
-import com.cloud.uservm.UserVm;
-import com.cloud.utils.EnumUtils;
-import com.cloud.utils.NumbersUtil;
-import com.cloud.utils.Pair;
-import com.cloud.utils.UriUtils;
-import com.cloud.utils.component.ManagerBase;
-import com.cloud.utils.db.DB;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.utils.fsm.NoTransitionException;
-import com.cloud.utils.fsm.StateMachine2;
-import com.cloud.vm.DiskProfile;
-import com.cloud.vm.UserVmManager;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineManager;
-import com.cloud.vm.VirtualMachineProfile;
-import com.cloud.vm.dao.ConsoleProxyDao;
-import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.dao.SecondaryStorageVmDao;
-import com.cloud.vm.dao.UserVmDao;
-import com.cloud.vm.dao.VMInstanceDao;
-import com.cloud.vm.snapshot.VMSnapshotVO;
-import com.cloud.vm.snapshot.dao.VMSnapshotDao;
-
-@Component
-public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
-    private static final Logger s_logger = Logger
-            .getLogger(VolumeManagerImpl.class);
-    @Inject
-    protected UserVmManager _userVmMgr;
-    @Inject
-    protected AgentManager _agentMgr;
-    @Inject
-    protected TemplateManager _tmpltMgr;
-    @Inject
-    protected AsyncJobManager _asyncMgr;
-    @Inject
-    protected SnapshotManager _snapshotMgr;
-    @Inject
-    protected SnapshotScheduler _snapshotScheduler;
-    @Inject
-    protected AccountManager _accountMgr;
-    @Inject
-    protected ConfigurationManager _configMgr;
-    @Inject
-    protected ConsoleProxyManager _consoleProxyMgr;
-    @Inject
-    protected SecondaryStorageVmManager _secStorageMgr;
-    @Inject
-    protected NetworkModel _networkMgr;
-    @Inject
-    protected ServiceOfferingDao _serviceOfferingDao;
-    @Inject
-    protected VolumeDao _volsDao;
-    @Inject
-    protected HostDao _hostDao;
-    @Inject
-    protected ConsoleProxyDao _consoleProxyDao;
-    @Inject
-    protected SnapshotDao _snapshotDao;
-    @Inject
-    protected SnapshotManager _snapMgr;
-    @Inject
-    protected SnapshotPolicyDao _snapshotPolicyDao;
-    @Inject
-    protected StoragePoolHostDao _storagePoolHostDao;
-    @Inject
-    StoragePoolDetailsDao storagePoolDetailsDao;
-    @Inject
-    protected AlertManager _alertMgr;
-    @Inject
-    protected TemplateDataStoreDao _vmTemplateStoreDao = null;
-    @Inject
-    protected VMTemplatePoolDao _vmTemplatePoolDao = null;
-    @Inject
-    protected VMTemplateDao _vmTemplateDao = null;
-    @Inject
-    protected StoragePoolHostDao _poolHostDao = null;
-    @Inject
-    protected UserVmDao _userVmDao;
-    @Inject
-    VolumeDataStoreDao _volumeStoreDao;
-    @Inject
-    protected VMInstanceDao _vmInstanceDao;
-    @Inject
-    protected PrimaryDataStoreDao _storagePoolDao = null;
-    @Inject
-    protected CapacityDao _capacityDao;
-    @Inject
-    protected CapacityManager _capacityMgr;
-    @Inject
-    protected DiskOfferingDao _diskOfferingDao;
-    @Inject
-    protected AccountDao _accountDao;
-    @Inject
-    protected EventDao _eventDao = null;
-    @Inject
-    protected DataCenterDao _dcDao = null;
-    @Inject
-    protected HostPodDao _podDao = null;
-    @Inject
-    protected VMTemplateDao _templateDao;
-    @Inject
-    protected ServiceOfferingDao _offeringDao;
-    @Inject
-    protected DomainDao _domainDao;
-    @Inject
-    protected UserDao _userDao;
-    @Inject
-    protected ClusterDao _clusterDao;
-    @Inject
-    protected VirtualMachineManager _vmMgr;
-    @Inject
-    protected DomainRouterDao _domrDao;
-    @Inject
-    protected SecondaryStorageVmDao _secStrgDao;
-    @Inject
-    protected StoragePoolWorkDao _storagePoolWorkDao;
-    @Inject
-    protected HypervisorGuruManager _hvGuruMgr;
-    @Inject
-    protected VolumeDao _volumeDao;
-    @Inject
-    protected OCFS2Manager _ocfs2Mgr;
-    @Inject
-    protected ResourceLimitService _resourceLimitMgr;
-    @Inject
-    protected SecondaryStorageVmManager _ssvmMgr;
-    @Inject
-    protected ResourceManager _resourceMgr;
-    @Inject
-    protected DownloadMonitor _downloadMonitor;
-    @Inject
-    protected ResourceTagDao _resourceTagDao;
-    @Inject
-    protected VmDiskStatisticsDao _vmDiskStatsDao;
-    @Inject
-    protected VMSnapshotDao _vmSnapshotDao;
-    @Inject
-    protected List<StoragePoolAllocator> _storagePoolAllocators;
-    @Inject
-    ConfigurationDao _configDao;
-    @Inject
-    VolumeDetailsDao _volDetailDao;
-    @Inject
-    ManagementServer _msServer;
-    @Inject
-    DataStoreManager dataStoreMgr;
-    @Inject
-    DataStoreProviderManager dataStoreProviderMgr;
-    @Inject
-    VolumeService volService;
-    @Inject
-    VolumeDataFactory volFactory;
-    @Inject
-    TemplateDataFactory tmplFactory;
-    @Inject
-    SnapshotDataFactory snapshotFactory;
-    @Inject
-    SnapshotApiService snapshotMgr;
-    @Inject
-    UploadMonitor _uploadMonitor;
-    @Inject
-    UploadDao _uploadDao;
-
-    private int _copyvolumewait;
-    @Inject
-    protected HypervisorCapabilitiesDao _hypervisorCapabilitiesDao;
-    private final StateMachine2<Volume.State, Volume.Event, Volume> _volStateMachine;
-    @Inject
-    StorageManager storageMgr;
-    private int _customDiskOfferingMinSize = 1;
-    private final int _customDiskOfferingMaxSize = 1024;
-    private long _maxVolumeSizeInGb;
-    private boolean _recreateSystemVmEnabled;
-
-    public VolumeManagerImpl() {
-        _volStateMachine = Volume.State.getStateMachine();
-    }
-
-    @Override
-    public VolumeInfo moveVolume(VolumeInfo volume, long destPoolDcId,
-            Long destPoolPodId, Long destPoolClusterId,
-            HypervisorType dataDiskHyperType)
-                    throws ConcurrentOperationException {
-
-        // Find a destination storage pool with the specified criteria
-        DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume
-                .getDiskOfferingId());
-        DiskProfile dskCh = new DiskProfile(volume.getId(),
-                volume.getVolumeType(), volume.getName(), diskOffering.getId(),
-                diskOffering.getDiskSize(), diskOffering.getTagsArray(),
-                diskOffering.getUseLocalStorage(),
-                diskOffering.isRecreatable(), null);
-        dskCh.setHyperType(dataDiskHyperType);
-        DataCenterVO destPoolDataCenter = _dcDao.findById(destPoolDcId);
-        HostPodVO destPoolPod = _podDao.findById(destPoolPodId);
-
-        StoragePool destPool = storageMgr.findStoragePool(dskCh,
-                destPoolDataCenter, destPoolPod, destPoolClusterId, null, null,
-                new HashSet<StoragePool>());
-
-        if (destPool == null) {
-            throw new CloudRuntimeException(
-                    "Failed to find a storage pool with enough capacity to move the volume to.");
-        }
-
-        Volume newVol = migrateVolume(volume, destPool);
-        return volFactory.getVolume(newVol.getId());
-    }
-
-    /*
-     * Upload the volume to secondary storage.
-     */
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPLOAD, eventDescription = "uploading volume", async = true)
-    public VolumeVO uploadVolume(UploadVolumeCmd cmd)
-            throws ResourceAllocationException {
-        Account caller = CallContext.current().getCallingAccount();
-        long ownerId = cmd.getEntityOwnerId();
-        Account owner = _accountDao.findById(ownerId);
-        Long zoneId = cmd.getZoneId();
-        String volumeName = cmd.getVolumeName();
-        String url = cmd.getUrl();
-        String format = cmd.getFormat();
-        String imageStoreUuid = cmd.getImageStoreUuid();
-        DataStore store = _tmpltMgr.getImageStore(imageStoreUuid, zoneId);
-
-        validateVolume(caller, ownerId, zoneId, volumeName, url, format);
-
-        VolumeVO volume = persistVolume(owner, zoneId, volumeName,
-                url, cmd.getFormat());
-
-        VolumeInfo vol = volFactory.getVolume(volume.getId());
-
-        RegisterVolumePayload payload = new RegisterVolumePayload(cmd.getUrl(), cmd.getChecksum(),
-                cmd.getFormat());
-        vol.addPayload(payload);
-
-        volService.registerVolume(vol, store);
-        return volume;
-    }
-
-    private boolean validateVolume(Account caller, long ownerId, Long zoneId,
-            String volumeName, String url, String format)
-                    throws ResourceAllocationException {
-
-        // permission check
-        _accountMgr.checkAccess(caller, null, true,
-                _accountMgr.getActiveAccountById(ownerId));
-
-        // Check that the resource limit for volumes won't be exceeded
-        _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId),
-                ResourceType.volume);
-
-        // Verify that zone exists
-        DataCenterVO zone = _dcDao.findById(zoneId);
-        if (zone == null) {
-            throw new InvalidParameterValueException(
-                    "Unable to find zone by id " + zoneId);
-        }
-
-        // Check if zone is disabled
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState()
-                && !_accountMgr.isRootAdmin(caller.getType())) {
-            throw new PermissionDeniedException(
-                    "Cannot perform this operation, Zone is currently disabled: "
-                            + zoneId);
-        }
-
-        if (url.toLowerCase().contains("file://")) {
-            throw new InvalidParameterValueException(
-                    "File:// type urls are currently unsupported");
-        }
-
-        ImageFormat imgfmt = ImageFormat.valueOf(format.toUpperCase());
-        if (imgfmt == null) {
-            throw new IllegalArgumentException("Image format is incorrect "
-                    + format + ". Supported formats are "
-                    + EnumUtils.listValues(ImageFormat.values()));
-        }
-
-        String userSpecifiedName = volumeName;
-        if (userSpecifiedName == null) {
-            userSpecifiedName = getRandomVolumeName();
-        }
-        if ((!url.toLowerCase().endsWith("vhd"))
-                && (!url.toLowerCase().endsWith("vhd.zip"))
-                && (!url.toLowerCase().endsWith("vhd.bz2"))
-                && (!url.toLowerCase().endsWith("vhd.gz"))
-                && (!url.toLowerCase().endsWith("qcow2"))
-                && (!url.toLowerCase().endsWith("qcow2.zip"))
-                && (!url.toLowerCase().endsWith("qcow2.bz2"))
-                && (!url.toLowerCase().endsWith("qcow2.gz"))
-                && (!url.toLowerCase().endsWith("ova"))
-                && (!url.toLowerCase().endsWith("ova.zip"))
-                && (!url.toLowerCase().endsWith("ova.bz2"))
-                && (!url.toLowerCase().endsWith("ova.gz"))
-                && (!url.toLowerCase().endsWith("img"))
-                && (!url.toLowerCase().endsWith("raw"))) {
-            throw new InvalidParameterValueException("Please specify a valid "
-                    + format.toLowerCase());
-        }
-
-        if ((format.equalsIgnoreCase("vhd") && (!url.toLowerCase().endsWith(
-                ".vhd")
-                && !url.toLowerCase().endsWith("vhd.zip")
-                && !url.toLowerCase().endsWith("vhd.bz2") && !url.toLowerCase()
-                .endsWith("vhd.gz")))
-                || (format.equalsIgnoreCase("qcow2") && (!url.toLowerCase()
-                        .endsWith(".qcow2")
-                        && !url.toLowerCase().endsWith("qcow2.zip")
-                        && !url.toLowerCase().endsWith("qcow2.bz2") && !url
-                        .toLowerCase().endsWith("qcow2.gz")))
-                        || (format.equalsIgnoreCase("ova") && (!url.toLowerCase()
-                                .endsWith(".ova")
-                                && !url.toLowerCase().endsWith("ova.zip")
-                                && !url.toLowerCase().endsWith("ova.bz2") && !url
-                                .toLowerCase().endsWith("ova.gz")))
-                                || (format.equalsIgnoreCase("raw") && (!url.toLowerCase()
-                                        .endsWith(".img") && !url.toLowerCase().endsWith("raw")))) {
-            throw new InvalidParameterValueException(
-                    "Please specify a valid URL. URL:" + url
-                    + " is an invalid for the format "
-                    + format.toLowerCase());
-        }
-        UriUtils.validateUrl(url);
-
-        // Check that the resource limit for secondary storage won't be exceeded
-        _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.secondary_storage,
-                UriUtils.getRemoteSize(url));
-
-        return false;
-    }
-
-    @Override
-    public VolumeVO allocateDuplicateVolume(VolumeVO oldVol, Long templateId) {
-        VolumeVO newVol = new VolumeVO(oldVol.getVolumeType(),
-                oldVol.getName(), oldVol.getDataCenterId(),
-                oldVol.getDomainId(), oldVol.getAccountId(),
-                oldVol.getDiskOfferingId(), oldVol.getSize(),
-                oldVol.getMinIops(), oldVol.getMaxIops(), oldVol.get_iScsiName());
-        if (templateId != null) {
-            newVol.setTemplateId(templateId);
-        } else {
-            newVol.setTemplateId(oldVol.getTemplateId());
-        }
-        newVol.setDeviceId(oldVol.getDeviceId());
-        newVol.setInstanceId(oldVol.getInstanceId());
-        newVol.setRecreatable(oldVol.isRecreatable());
-        newVol.setFormat(oldVol.getFormat());
-        return _volsDao.persist(newVol);
-    }
-
-    @DB
-    protected VolumeInfo createVolumeFromSnapshot(VolumeVO volume,
-            SnapshotVO snapshot) throws StorageUnavailableException {
-        Account account = _accountDao.findById(volume.getAccountId());
-
-        final HashSet<StoragePool> poolsToAvoid = new HashSet<StoragePool>();
-        StoragePool pool = null;
-
-        Set<Long> podsToAvoid = new HashSet<Long>();
-        Pair<Pod, Long> pod = null;
-
-        DiskOfferingVO diskOffering = _diskOfferingDao
-                .findByIdIncludingRemoved(volume.getDiskOfferingId());
-        DataCenterVO dc = _dcDao.findById(volume.getDataCenterId());
-        DiskProfile dskCh = new DiskProfile(volume, diskOffering,
-                snapshot.getHypervisorType());
-
-        // Determine what pod to store the volume in
-        while ((pod = _resourceMgr.findPod(null, null, dc, account.getId(), podsToAvoid)) != null) {
-            podsToAvoid.add(pod.first().getId());
-            // Determine what storage pool to store the volume in
-            while ((pool = storageMgr.findStoragePool(dskCh, dc, pod.first(), null, null,
-                    null, poolsToAvoid)) != null) {
-                break;
-            }
-        }
-
-        if (pool == null) {
-            String msg = "There are no available storage pools to store the volume in";
-            s_logger.info(msg);
-            throw new StorageUnavailableException(msg, -1);
-        }
-
-        VolumeInfo vol = volFactory.getVolume(volume.getId());
-        DataStore store = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
-        SnapshotInfo snapInfo = snapshotFactory.getSnapshot(snapshot.getId(), DataStoreRole.Image);
-        AsyncCallFuture<VolumeApiResult> future = volService.createVolumeFromSnapshot(vol, store, snapInfo);
-        try {
-            VolumeApiResult result = future.get();
-            if (result.isFailed()) {
-                s_logger.debug("Failed to create volume from snapshot:" + result.getResult());
-                throw new CloudRuntimeException("Failed to create volume from snapshot:" + result.getResult());
-            }
-            return result.getVolume();
-        } catch (InterruptedException e) {
-            s_logger.debug("Failed to create volume from snapshot", e);
-            throw new CloudRuntimeException("Failed to create volume from snapshot", e);
-        } catch (ExecutionException e) {
-            s_logger.debug("Failed to create volume from snapshot", e);
-            throw new CloudRuntimeException("Failed to create volume from snapshot", e);
-        }
-
-    }
-
-    protected DiskProfile createDiskCharacteristics(VolumeInfo volume,
-            VMTemplateVO template, DataCenterVO dc, DiskOfferingVO diskOffering) {
-        if (volume.getVolumeType() == Type.ROOT
-                && Storage.ImageFormat.ISO != template.getFormat()) {
-            TemplateDataStoreVO ss = _vmTemplateStoreDao.findByTemplateZoneDownloadStatus(template.getId(), dc.getId(),
-                    VMTemplateStorageResourceAssoc.Status.DOWNLOADED);
-            if (ss == null) {
-                throw new CloudRuntimeException("Template "
-                        + template.getName()
-                        + " has not been completely downloaded to zone "
-                        + dc.getId());
-            }
-
-            return new DiskProfile(volume.getId(), volume.getVolumeType(),
-                    volume.getName(), diskOffering.getId(), ss.getSize(),
-                    diskOffering.getTagsArray(),
-                    diskOffering.getUseLocalStorage(),
-                    diskOffering.isRecreatable(),
-                    Storage.ImageFormat.ISO != template.getFormat() ? template
-                            .getId() : null);
-        } else {
-            return new DiskProfile(volume.getId(), volume.getVolumeType(),
-                    volume.getName(), diskOffering.getId(),
-                    diskOffering.getDiskSize(), diskOffering.getTagsArray(),
-                    diskOffering.getUseLocalStorage(),
-                    diskOffering.isRecreatable(), null);
-        }
-    }
-
-    protected VolumeVO createVolumeFromSnapshot(VolumeVO volume, long snapshotId) throws StorageUnavailableException {
-        VolumeInfo createdVolume = null;
-        SnapshotVO snapshot = _snapshotDao.findById(snapshotId);
-        createdVolume = createVolumeFromSnapshot(volume,
-                snapshot);
-
-        UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, createdVolume.getAccountId(), createdVolume.getDataCenterId(), createdVolume.getId(),
-                createdVolume.getName(), createdVolume.getDiskOfferingId(), null, createdVolume.getSize(), Volume.class.getName(), createdVolume.getUuid());
-
-        return _volsDao.findById(createdVolume.getId());
-    }
-
-    @DB
-    public VolumeInfo copyVolumeFromSecToPrimary(VolumeInfo volume,
-            VMInstanceVO vm, VMTemplateVO template, DataCenterVO dc,
-            HostPodVO pod, Long clusterId, ServiceOfferingVO offering,
-            DiskOfferingVO diskOffering, List<StoragePool> avoids,
-            long size, HypervisorType hyperType) throws NoTransitionException {
-
-        final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(
-                avoids);
-        DiskProfile dskCh = createDiskCharacteristics(volume, template, dc,
-                diskOffering);
-        dskCh.setHyperType(vm.getHypervisorType());
-        // Find a suitable storage to create volume on
-        StoragePool destPool = storageMgr.findStoragePool(dskCh, dc, pod,
-                clusterId, null, vm, avoidPools);
-        DataStore destStore = dataStoreMgr.getDataStore(destPool.getId(), DataStoreRole.Primary);
-        AsyncCallFuture<VolumeApiResult> future = volService.copyVolume(volume, destStore);
-
-        try {
-            VolumeApiResult result = future.get();
-            if (result.isFailed()) {
-                s_logger.debug("copy volume failed: " + result.getResult());
-                throw new CloudRuntimeException("copy volume failed: " + result.getResult());
-            }
-            return result.getVolume();
-        } catch (InterruptedException e) {
-            s_logger.debug("Failed to copy volume: " + volume.getId(), e);
-            throw new CloudRuntimeException("Failed to copy volume", e);
-        } catch (ExecutionException e) {
-            s_logger.debug("Failed to copy volume: " + volume.getId(), e);
-            throw new CloudRuntimeException("Failed to copy volume", e);
-        }
-    }
-
-    @DB
-    public VolumeInfo createVolume(VolumeInfo volume, VMInstanceVO vm,
-            VMTemplateVO template, DataCenterVO dc, HostPodVO pod,
-            Long clusterId, ServiceOfferingVO offering,
-            DiskOfferingVO diskOffering, List<StoragePool> avoids,
-            long size, HypervisorType hyperType) {
-        StoragePool pool = null;
-
-        if (diskOffering != null && diskOffering.isCustomized()) {
-            diskOffering.setDiskSize(size);
-        }
-
-        DiskProfile dskCh = null;
-        if (volume.getVolumeType() == Type.ROOT
-                && Storage.ImageFormat.ISO != template.getFormat()) {
-            dskCh = createDiskCharacteristics(volume, template, dc, offering);
-        } else {
-            dskCh = createDiskCharacteristics(volume, template, dc,
-                    diskOffering);
-        }
-
-        dskCh.setHyperType(hyperType);
-
-        final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(
-                avoids);
-
-        pool = storageMgr.findStoragePool(dskCh, dc, pod, clusterId, vm.getHostId(),
-                vm, avoidPools);
-        if (pool == null) {
-            s_logger.warn("Unable to find storage pool when create volume "
-                    + volume.getName());
-            throw new CloudRuntimeException("Unable to find storage pool when create volume" + volume.getName());
-        }
-
-        if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Trying to create " + volume + " on " + pool);
-        }
-        DataStore store = dataStoreMgr.getDataStore(pool.getId(), DataStoreRole.Primary);
-        AsyncCallFuture<VolumeApiResult> future = null;
-        boolean isNotCreatedFromTemplate = volume.getTemplateId() == null ? true : false;
-        if (isNotCreatedFromTemplate) {
-            future = volService.createVolumeAsync(volume, store);
-        } else {
-            TemplateInfo templ = tmplFactory.getTemplate(template.getId(), DataStoreRole.Image);
-            future = volService.createVolumeFromTemplateAsync(volume, store.getId(), templ);
-        }
-        try {
-            VolumeApiResult result = future.get();
-            if (result.isFailed()) {
-                s_logger.debug("create volume failed: " + result.getResult());
-                throw new CloudRuntimeException("create volume failed:" + result.getResult());
-            }
-
-            return result.getVolume();
-        } catch (InterruptedException e) {
-            s_logger.error("create volume failed", e);
-            throw new CloudRuntimeException("create volume failed", e);
-        } catch (ExecutionException e) {
-            s_logger.error("create volume failed", e);
-            throw new CloudRuntimeException("create volume failed", e);
-        }
-
-    }
-
-    public String getRandomVolumeName() {
-        return UUID.randomUUID().toString();
-    }
-
-    private VolumeVO persistVolume(Account owner, Long zoneId,
-            String volumeName, String url, String format) {
-
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-
-        VolumeVO volume = new VolumeVO(volumeName, zoneId, -1, -1, -1,
-                new Long(-1), null, null, 0, Volume.Type.DATADISK);
-        volume.setPoolId(null);
-        volume.setDataCenterId(zoneId);
-        volume.setPodId(null);
-        volume.setAccountId(owner.getAccountId());
-        volume.setDomainId(owner.getDomainId());
-        long diskOfferingId = _diskOfferingDao.findByUniqueName(
-                "Cloud.com-Custom").getId();
-        volume.setDiskOfferingId(diskOfferingId);
-        // volume.setSize(size);
-        volume.setInstanceId(null);
-        volume.setUpdated(new Date());
-        volume.setDomainId((owner == null) ? Domain.ROOT_DOMAIN : owner
-                .getDomainId());
-        volume.setFormat(ImageFormat.valueOf(format));
-        volume = _volsDao.persist(volume);
-        CallContext.current().setEventDetails("Volume Id: " + volume.getId());
-
-        // Increment resource count during allocation; if actual creation fails,
-        // decrement it
-        _resourceLimitMgr.incrementResourceCount(volume.getAccountId(),
-                ResourceType.volume);
-        _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage,
-                UriUtils.getRemoteSize(url));
-
-        txn.commit();
-        return volume;
-    }
-
-    @Override
-    public boolean volumeOnSharedStoragePool(VolumeVO volume) {
-        Long poolId = volume.getPoolId();
-        if (poolId == null) {
-            return false;
-        } else {
-            StoragePoolVO pool = _storagePoolDao.findById(poolId);
-
-            if (pool == null) {
-                return false;
-            } else {
-                return (pool.getScope() == ScopeType.HOST) ? false : true;
-            }
-        }
-    }
-
-    @Override
-    public boolean volumeInactive(Volume volume) {
-        Long vmId = volume.getInstanceId();
-        if (vmId != null) {
-            UserVm vm = _userVmDao.findById(vmId);
-            if (vm == null) {
-                return true;
-            }
-            State state = vm.getState();
-            if (state.equals(State.Stopped) || state.equals(State.Destroyed)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public String getVmNameOnVolume(Volume volume) {
-        Long vmId = volume.getInstanceId();
-        if (vmId != null) {
-            VMInstanceVO vm = _vmInstanceDao.findById(vmId);
-
-            if (vm == null) {
-                return null;
-            }
-            return vm.getInstanceName();
-        }
-        return null;
-    }
-
-    /*
-     * Just allocate a volume in the database, don't send the createvolume cmd
-     * to hypervisor. The volume will be finally created only when it's attached
-     * to a VM.
-     */
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", create = true)
-    public VolumeVO allocVolume(CreateVolumeCmd cmd)
-            throws ResourceAllocationException {
-        // FIXME: some of the scheduled event stuff might be missing here...
-        Account caller = CallContext.current().getCallingAccount();
-
-        long ownerId = cmd.getEntityOwnerId();
-        Boolean displayVolumeEnabled = cmd.getDisplayVolume();
-
-        // permission check
-        _accountMgr.checkAccess(caller, null, true,
-                _accountMgr.getActiveAccountById(ownerId));
-
-        // Check that the resource limit for volumes won't be exceeded
-        _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId),
-                ResourceType.volume);
-
-        Long zoneId = cmd.getZoneId();
-        Long diskOfferingId = null;
-        DiskOfferingVO diskOffering = null;
-        Long size = null;
-        Long minIops = null;
-        Long maxIops = null;
-        // Volume VO used for extracting the source template id
-        VolumeVO parentVolume = null;
-
-        // validate input parameters before creating the volume
-        if ((cmd.getSnapshotId() == null && cmd.getDiskOfferingId() == null)
-                || (cmd.getSnapshotId() != null && cmd.getDiskOfferingId() != null)) {
-            throw new InvalidParameterValueException(
-                    "Either disk Offering Id or snapshot Id must be passed whilst creating volume");
-        }
-
-        if (cmd.getSnapshotId() == null) {// create a new volume
-
-            diskOfferingId = cmd.getDiskOfferingId();
-            size = cmd.getSize();
-            Long sizeInGB = size;
-            if (size != null) {
-                if (size > 0) {
-                    size = size * 1024 * 1024 * 1024; // user specify size in GB
-                } else {
-                    throw new InvalidParameterValueException(
-                            "Disk size must be larger than 0");
-                }
-            }
-
-            // Check that the the disk offering is specified
-            diskOffering = _diskOfferingDao.findById(diskOfferingId);
-            if ((diskOffering == null) || diskOffering.getRemoved() != null
-                    || !DiskOfferingVO.Type.Disk.equals(diskOffering.getType())) {
-                throw new InvalidParameterValueException(
-                        "Please specify a valid disk offering.");
-            }
-
-            if (diskOffering.isCustomized()) {
-                if (size == null) {
-                    throw new InvalidParameterValueException(
-                            "This disk offering requires a custom size specified");
-                }
-                if ((sizeInGB < _customDiskOfferingMinSize)
-                        || (sizeInGB > _customDiskOfferingMaxSize)) {
-                    throw new InvalidParameterValueException("Volume size: "
-                            + sizeInGB + "GB is out of allowed range. Max: "
-                            + _customDiskOfferingMaxSize + " Min:"
-                            + _customDiskOfferingMinSize);
-                }
-            }
-
-            if (!diskOffering.isCustomized() && size != null) {
-                throw new InvalidParameterValueException(
-                        "This disk offering does not allow custom size");
-            }
-
-            if (diskOffering.getDomainId() == null) {
-                // do nothing as offering is public
-            } else {
-                _configMgr.checkDiskOfferingAccess(caller, diskOffering);
-            }
-
-            if (diskOffering.getDiskSize() > 0) {
-                size = diskOffering.getDiskSize();
-            }
-
-            Boolean isCustomizedIops = diskOffering.isCustomizedIops();
-
-            if (isCustomizedIops != null) {
-                if (isCustomizedIops) {
-                    minIops = cmd.getMinIops();
-                    maxIops = cmd.getMaxIops();
-
-                    if (minIops == null && maxIops == null) {
-                        minIops = 0L;
-                        maxIops = 0L;
-                    }
-                    else {
-                        if (minIops == null || minIops <= 0) {
-                            throw new InvalidParameterValueException("The min IOPS must be greater than 0.");
-                        }
-
-                        if (maxIops == null) {
-                            maxIops = 0L;
-                        }
-
-                        if (minIops > maxIops) {
-                            throw new InvalidParameterValueException("The min IOPS must be less than or equal to the max IOPS.");
-                        }
-                    }
-                }
-                else {
-                    minIops = diskOffering.getMinIops();
-                    maxIops = diskOffering.getMaxIops();
-                }
-            }
-
-            if (!validateVolumeSizeRange(size)) {// convert size from mb to gb
-                // for validation
-                throw new InvalidParameterValueException(
-                        "Invalid size for custom volume creation: " + size
-                        + " ,max volume size is:" + _maxVolumeSizeInGb);
-            }
-        } else { // create volume from snapshot
-            Long snapshotId = cmd.getSnapshotId();
-            SnapshotVO snapshotCheck = _snapshotDao.findById(snapshotId);
-            if (snapshotCheck == null) {
-                throw new InvalidParameterValueException(
-                        "unable to find a snapshot with id " + snapshotId);
-            }
-
-            if (snapshotCheck.getState() != Snapshot.State.BackedUp) {
-                throw new InvalidParameterValueException("Snapshot id="
-                        + snapshotId + " is not in " + Snapshot.State.BackedUp
-                        + " state yet and can't be used for volume creation");
-            }
-            parentVolume = _volsDao.findByIdIncludingRemoved(snapshotCheck.getVolumeId());
-
-            diskOfferingId = snapshotCheck.getDiskOfferingId();
-            diskOffering = _diskOfferingDao.findById(diskOfferingId);
-            zoneId = snapshotCheck.getDataCenterId();
-            size = snapshotCheck.getSize(); // ; disk offering is used for tags
-            // purposes
-
-            // check snapshot permissions
-            _accountMgr.checkAccess(caller, null, true, snapshotCheck);
-        }
-
-        if(displayVolumeEnabled == null){
-            displayVolumeEnabled = true;
-        } else{
-            if(!_accountMgr.isRootAdmin(caller.getType())){
-                throw new PermissionDeniedException( "Cannot update parameter displayvolume, only admin permitted ");
-            }
-        }
-
-        // Check that the resource limit for primary storage won't be exceeded
-        _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(ownerId), ResourceType.primary_storage,
-                new Long(size));
-
-        // Verify that zone exists
-        DataCenterVO zone = _dcDao.findById(zoneId);
-        if (zone == null) {
-            throw new InvalidParameterValueException(
-                    "Unable to find zone by id " + zoneId);
-        }
-
-        // Check if zone is disabled
-        if (Grouping.AllocationState.Disabled == zone.getAllocationState()
-                && !_accountMgr.isRootAdmin(caller.getType())) {
-            throw new PermissionDeniedException(
-                    "Cannot perform this operation, Zone is currently disabled: "
-                            + zoneId);
-        }
-
-        // If local storage is disabled then creation of volume with local disk
-        // offering not allowed
-        if (!zone.isLocalStorageEnabled() && diskOffering.getUseLocalStorage()) {
-            throw new InvalidParameterValueException(
-                    "Zone is not configured to use local storage but volume's disk offering "
-                            + diskOffering.getName() + " uses it");
-        }
-
-        String userSpecifiedName = cmd.getVolumeName();
-        if (userSpecifiedName == null) {
-            userSpecifiedName = getRandomVolumeName();
-        }
-
-        Transaction txn = Transaction.currentTxn();
-        txn.start();
-
-        VolumeVO volume = new VolumeVO(userSpecifiedName, -1, -1, -1, -1,
-                new Long(-1), null, null, 0, Volume.Type.DATADISK);
-        volume.setPoolId(null);
-        volume.setDataCenterId(zoneId);
-        volume.setPodId(null);
-        volume.setAccountId(ownerId);
-        volume.setDomainId(((caller == null) ? Domain.ROOT_DOMAIN : caller
-                .getDomainId()));
-        volume.setDiskOfferingId(diskOfferingId);
-        volume.setSize(size);
-        volume.setMinIops(minIops);
-        volume.setMaxIops(maxIops);
-        volume.setInstanceId(null);
-        volume.setUpdated(new Date());
-        volume.setDomainId((caller == null) ? Domain.ROOT_DOMAIN : caller
-                .getDomainId());
-        volume.setDisplayVolume(displayVolumeEnabled);
-        if (parentVolume != null) {
-            volume.setTemplateId(parentVolume.getTemplateId());
-            volume.setFormat(parentVolume.getFormat());
-        }  else {
-            volume.setTemplateId(null);
-        }
-
-        volume = _volsDao.persist(volume);
-        if (cmd.getSnapshotId() == null) {
-            // for volume created from snapshot, create usage event after volume creation
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(), diskOfferingId,
-                    null, size, Volume.class.getName(), volume.getUuid());
-        }
-
-        CallContext.current().setEventDetails("Volume Id: " + volume.getId());
-
-        // Increment resource count during allocation; if actual creation fails,
-        // decrement it
-        _resourceLimitMgr.incrementResourceCount(volume.getAccountId(),
-                ResourceType.volume);
-        _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage,
-                new Long(volume.getSize()));
-
-        txn.commit();
-
-        return volume;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", async = true)
-    public VolumeVO createVolume(CreateVolumeCmd cmd) {
-        VolumeVO volume = _volsDao.findById(cmd.getEntityId());
-        boolean created = true;
-
-        try {
-            if (cmd.getSnapshotId() != null) {
-                volume = createVolumeFromSnapshot(volume, cmd.getSnapshotId());
-                if (volume.getState() != Volume.State.Ready) {
-                    created = false;
-                }
-            }
-            return volume;
-        } catch(Exception e) {
-            created = false;
-            s_logger.debug("Failed to create volume: " + volume.getId(), e);
-            return null;
-        } finally {
-            if (!created) {
-                s_logger.trace("Decrementing volume resource count for account id="
-                        + volume.getAccountId()
-                        + " as volume failed to create on the backend");
-                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(),
-                        ResourceType.volume);
-                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage,
-                        new Long(volume.getSize()));
-            }
-        }
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_RESIZE, eventDescription = "resizing volume", async = true)
-    public VolumeVO resizeVolume(ResizeVolumeCmd cmd)
-            throws ResourceAllocationException {
-        Long newSize = null;
-        boolean shrinkOk = cmd.getShrinkOk();
-
-        VolumeVO volume = _volsDao.findById(cmd.getEntityId());
-        if (volume == null) {
-            throw new InvalidParameterValueException("No such volume");
-        }
-
-        DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume
-                .getDiskOfferingId());
-        DiskOfferingVO newDiskOffering = null;
-
-        newDiskOffering = _diskOfferingDao.findById(cmd.getNewDiskOfferingId());
-
-        /*
-         * Volumes with no hypervisor have never been assigned, and can be
-         * resized by recreating. perhaps in the future we can just update the
-         * db entry for the volume
-         */
-        if (_volsDao.getHypervisorType(volume.getId()) == HypervisorType.None) {
-            throw new InvalidParameterValueException(
-                    "Can't resize a volume that has never been attached, not sure which hypervisor type. Recreate volume to resize.");
-        }
-
-        /* Only works for KVM/Xen for now */
-        if (_volsDao.getHypervisorType(volume.getId()) != HypervisorType.KVM
-                && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.XenServer
-                && _volsDao.getHypervisorType(volume.getId()) != HypervisorType.VMware) {
-            throw new InvalidParameterValueException(
-                    "Cloudstack currently only supports volumes marked as KVM or XenServer hypervisor for resize");
-        }
-
-
-        if (volume.getState() != Volume.State.Ready) {
-            throw new InvalidParameterValueException(
-                    "Volume should be in ready state before attempting a resize");
-        }
-
-        if (!volume.getVolumeType().equals(Volume.Type.DATADISK)) {
-            throw new InvalidParameterValueException(
-                    "Can only resize DATA volumes");
-        }
-
-        /*
-         * figure out whether or not a new disk offering or size parameter is
-         * required, get the correct size value
-         */
-        if (newDiskOffering == null) {
-            if (diskOffering.isCustomized()) {
-                newSize = cmd.getSize();
-
-                if (newSize == null) {
-                    throw new InvalidParameterValueException(
-                            "new offering is of custom size, need to specify a size");
-                }
-
-                newSize = (newSize << 30);
-            } else {
-                throw new InvalidParameterValueException("current offering"
-                        + volume.getDiskOfferingId()
-                        + " cannot be resized, need to specify a disk offering");
-            }
-        } else {
-
-            if (newDiskOffering.getRemoved() != null
-                    || !DiskOfferingVO.Type.Disk.equals(newDiskOffering
-                            .getType())) {
-                throw new InvalidParameterValueException(
-                        "Disk offering ID is missing or invalid");
-            }
-
-            if (diskOffering.getTags() != null) {
-                if (!newDiskOffering.getTags().equals(diskOffering.getTags())) {
-                    throw new InvalidParameterValueException(
-                            "Tags on new and old disk offerings must match");
-                }
-            } else if (newDiskOffering.getTags() != null) {
-                throw new InvalidParameterValueException(
-                        "There are no tags on current disk offering, new disk offering needs to have no tags");
-            }
-
-            if (newDiskOffering.getDomainId() == null) {
-                // do nothing as offering is public
-            } else {
-                _configMgr.checkDiskOfferingAccess(CallContext.current()
-                        .getCallingAccount(), newDiskOffering);
-            }
-
-            if (newDiskOffering.isCustomized()) {
-                newSize = cmd.getSize();
-
-                if (newSize == null) {
-                    throw new InvalidParameterValueException(
-                            "new offering is of custom size, need to specify a size");
-                }
-
-                newSize = (newSize << 30);
-            } else {
-                newSize = newDiskOffering.getDiskSize();
-            }
-        }
-
-        if (newSize == null) {
-            throw new InvalidParameterValueException(
-                    "could not detect a size parameter or fetch one from the diskofferingid parameter");
-        }
-
-        if (!validateVolumeSizeRange(newSize)) {
-            throw new InvalidParameterValueException(
-                    "Requested size out of range");
-        }
-
-        /* does the caller have the authority to act on this volume? */
-        _accountMgr.checkAccess(CallContext.current().getCallingAccount(), null, true,
-                volume);
-
-        UserVmVO userVm = _userVmDao.findById(volume.getInstanceId());
-
-        long currentSize = volume.getSize();
-
-        /*
-         * lets make certain they (think they) know what they're doing if they
-         * want to shrink, by forcing them to provide the shrinkok parameter.
-         * This will be checked again at the hypervisor level where we can see
-         * the actual disk size
-         */
-        if (currentSize > newSize && !shrinkOk) {
-            throw new InvalidParameterValueException(
-                    "Going from existing size of "
-                            + currentSize
-                            + " to size of "
-                            + newSize
-                            + " would shrink the volume, need to sign off by supplying the shrinkok parameter with value of true");
-        }
-
-        if (!shrinkOk) {
-            /* Check resource limit for this account on primary storage resource */
-            _resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()),
-                    ResourceType.primary_storage, new Long(newSize - currentSize));
-        }
-
-        /*
-         * get a list of hosts to send the commands to, try the system the
-         * associated vm is running on first, then the last known place it ran.
-         * If not attached to a userVm, we pass 'none' and resizevolume.sh is ok
-         * with that since it only needs the vm name to live resize
-         */
-        long[] hosts = null;
-        String instanceName = "none";
-        if (userVm != null) {
-            instanceName = userVm.getInstanceName();
-            if (userVm.getHostId() != null) {
-                hosts = new long[] { userVm.getHostId() };
-            } else if (userVm.getLastHostId() != null) {
-                hosts = new long[] { userVm.getLastHostId() };
-            }
-
-            /* Xen only works offline, SR does not support VDI.resizeOnline */
-            if (_volsDao.getHypervisorType(volume.getId()) == HypervisorType.XenServer
-                    && !userVm.getState().equals(State.Stopped)) {
-                throw new InvalidParameterValueException(
-                        "VM must be stopped or disk detached in order to resize with the Xen HV");
-            }
-        }
-
-        ResizeVolumePayload payload = new ResizeVolumePayload(newSize, shrinkOk, instanceName, hosts);
-
-        try {
-            VolumeInfo vol = volFactory.getVolume(volume.getId());
-            vol.addPayload(payload);
-
-            AsyncCallFuture<VolumeApiResult> future = volService.resize(vol);
-            VolumeApiResult result = future.get();
-            if (result.isFailed()) {
-                s_logger.warn("Failed to resize the volume " + volume);
-                return null;
-            }
-            
-            volume = _volsDao.findById(volume.getId());
-
-            if (newDiskOffering != null) {
-                volume.setDiskOfferingId(cmd.getNewDiskOfferingId());
-            }
-            _volsDao.update(volume.getId(), volume);
-            // Log usage event for volumes belonging user VM's only
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
-                    volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(), volume.getUuid());
-
-            /* Update resource count for the account on primary storage resource */
-            if (!shrinkOk) {
-                _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.primary_storage,
-                        new Long(newSize - currentSize));
-            } else {
-                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage,
-                        new Long(currentSize - newSize));
-            }
-            return volume;
-        } catch (InterruptedException e) {
-            s_logger.warn("failed get resize volume result", e);
-        } catch (ExecutionException e) {
-            s_logger.warn("failed get resize volume result", e);
-        } catch (Exception e) {
-            s_logger.warn("failed get resize volume result", e);
-        }
-
-        return null;
-    }
-
-    @Override
-    @DB
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DELETE, eventDescription = "deleting volume")
-    public boolean deleteVolume(long volumeId, Account caller)
-            throws ConcurrentOperationException {
-
-        VolumeVO volume = _volsDao.findById(volumeId);
-        if (volume == null) {
-            throw new InvalidParameterValueException(
-                    "Unable to aquire volume with ID: " + volumeId);
-        }
-
-        if (!_snapshotMgr.canOperateOnVolume(volume)) {
-            throw new InvalidParameterValueException(
-                    "There are snapshot creating on it, Unable to delete the volume");
-        }
-
-        _accountMgr.checkAccess(caller, null, true, volume);
-
-        if (volume.getInstanceId() != null) {
-            throw new InvalidParameterValueException(
-                    "Please specify a volume that is not attached to any VM.");
-        }
-
-        if (volume.getState() == Volume.State.UploadOp) {
-            VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(volume
-                    .getId());
-            if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) {
-                throw new InvalidParameterValueException(
-                        "Please specify a volume that is not uploading");
-            }
-        }
-
-        try {
-            if (volume.getState() != Volume.State.Destroy && volume.getState() != Volume.State.Expunging && volume.getState() != Volume.State.Expunging) {
-                Long instanceId = volume.getInstanceId();
-                if (!volService.destroyVolume(volume.getId())) {
-                    return false;
-                }
-
-                VMInstanceVO vmInstance = _vmInstanceDao.findById(instanceId);
-                if (instanceId == null
-                        || (vmInstance.getType().equals(VirtualMachine.Type.User))) {
-                    // Decrement the resource count for volumes and primary storage belonging user VM's only
-                    _resourceLimitMgr.decrementResourceCount(volume.getAccountId(),
-                            ResourceType.volume);
-                    /* If volume is in primary storage, decrement primary storage count else decrement secondary
-                     storage count (in case of upload volume). */
-                    if (volume.getFolder() != null || volume.getPath() != null || volume.getState() == Volume.State.Allocated) {
-                        _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.primary_storage,
-                                new Long(volume.getSize()));
-                    } else {
-                        _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(),
-                                ResourceType.secondary_storage.getOrdinal());
-                    }
-
-                    // Log usage event for volumes belonging user VM's only
-                    UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),
-                            Volume.class.getName(), volume.getUuid());
-                }
-            }
-            // Mark volume as removed if volume has not been created on primary or secondary
-            if (volume.getState() == Volume.State.Allocated) {
-                _volsDao.remove(volumeId);
-                stateTransitTo(volume, Volume.Event.DestroyRequested);
-                return true;
-            }
-            // expunge volume from primary if volume is on primary
-            VolumeInfo volOnPrimary = volFactory.getVolume(volume.getId(), DataStoreRole.Primary);
-            if (volOnPrimary != null) {
-                s_logger.info("Expunging volume " + volume.getId() + " from primary data store");
-                AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volOnPrimary);
-                future.get();
-            }
-            // expunge volume from secondary if volume is on image store
-            VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image);
-            if (volOnSecondary != null) {
-                s_logger.info("Expunging volume " + volume.getId() + " from secondary data store");
-                AsyncCallFuture<VolumeApiResult> future2 = volService.expungeVolumeAsync(volOnSecondary);
-                future2.get();
-            }
-        } catch (Exception e) {
-            s_logger.warn("Failed to expunge volume:", e);
-            return false;
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean validateVolumeSizeRange(long size) {
-        if (size < 0 || (size > 0 && size < (1024 * 1024 * 1024))) {
-            throw new InvalidParameterValueException(
-                    "Please specify a size of at least 1 Gb.");
-        } else if (size > (_maxVolumeSizeInGb * 1024 * 1024 * 1024)) {
-            throw new InvalidParameterValueException("volume size " + size
-                    + ", but the maximum size allowed is " + _maxVolumeSizeInGb
-                    + " Gb.");
-        }
-
-        return true;
-    }
-
-    protected DiskProfile toDiskProfile(VolumeVO vol, DiskOfferingVO offering) {
-        return new DiskProfile(vol.getId(), vol.getVolumeType(), vol.getName(),
-                offering.getId(), vol.getSize(), offering.getTagsArray(),
-                offering.getUseLocalStorage(), offering.isRecreatable(),
-                vol.getTemplateId());
-    }
-
-    @Override
-    public DiskProfile allocateRawVolume(Type type,
-            String name, DiskOfferingVO offering, Long size, VMInstanceVO vm, VMTemplateVO template, Account owner) {
-        Long isoId=null;
-        if (size == null) {
-            size = offering.getDiskSize();
-        } else {
-            size = (size * 1024 * 1024 * 1024);
-        }
-        VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterId(),
-                owner.getDomainId(), owner.getId(), offering.getId(), size,
-                offering.getMinIops(), offering.getMaxIops(), null);
-        if (vm != null) {
-            vol.setInstanceId(vm.getId());
-        }
-
-        if (type.equals(Type.ROOT)) {
-            vol.setDeviceId(0l);
-        } else {
-            vol.setDeviceId(1l);
-        }
-        if (template.getFormat() == ImageFormat.ISO) {
-            vol.setIsoId(template.getId());
-        }
-
-        vol.setFormat(getSupportedImageFormatForCluster(vm.getHypervisorType()));
-        vol = _volsDao.persist(vol);
-
-        // Save usage event and update resource count for user vm volumes
-        if (vm instanceof UserVm) {
-
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size,
-                    Volume.class.getName(), vol.getUuid());
-
-            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(),
-                    ResourceType.volume);
-            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage,
-                    new Long(vol.getSize()));
-        }
-        return toDiskProfile(vol, offering);
-    }
-
-    @Override
-    public  DiskProfile allocateTemplatedVolume(
-            Type type, String name, DiskOfferingVO offering,
-            VMTemplateVO template, VMInstanceVO vm, Account owner) {
-        assert (template.getFormat() != ImageFormat.ISO) : "ISO is not a template really....";
-
-        Long size = _tmpltMgr.getTemplateSize(template.getId(), vm.getDataCenterId());
-
-        VolumeVO vol = new VolumeVO(type, name, vm.getDataCenterId(),
-                owner.getDomainId(), owner.getId(), offering.getId(), size,
-                offering.getMinIops(), offering.getMaxIops(), null);
-        vol.setFormat(getSupportedImageFormatForCluster(template.getHypervisorType()));
-        if (vm != null) {
-            vol.setInstanceId(vm.getId());
-        }
-        vol.setTemplateId(template.getId());
-
-        if (type.equals(Type.ROOT)) {
-            vol.setDeviceId(0l);
-            if (!vm.getType().equals(VirtualMachine.Type.User)) {
-                vol.setRecreatable(true);
-            }
-        } else {
-            vol.setDeviceId(1l);
-        }
-
-        vol = _volsDao.persist(vol);
-
-        // Create event and update resource count for volumes if vm is a user vm
-        if (vm instanceof UserVm) {
-
-            Long offeringId = null;
-
-            if (offering.getType() == DiskOfferingVO.Type.Disk) {
-                offeringId = offering.getId();
-            }
-
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offeringId, null, size,
-                    Volume.class.getName(), vol.getUuid());
-
-            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(),
-                    ResourceType.volume);
-            _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage,
-                    new Long(vol.getSize()));
-        }
-        return toDiskProfile(vol, offering);
-    }
-
-    private  ImageFormat getSupportedImageFormatForCluster(HypervisorType hyperType) {
-        if (hyperType == HypervisorType.XenServer) {
-            return ImageFormat.VHD;
-        } else if (hyperType == HypervisorType.KVM) {
-            return ImageFormat.QCOW2;
-        } else if (hyperType == HypervisorType.VMware) {
-            return ImageFormat.OVA;
-        } else if (hyperType == HypervisorType.Ovm) {
-            return ImageFormat.RAW;
-        } else {
-            return null;
-        }
-    }
-
-    private VolumeInfo copyVolume(StoragePoolVO rootDiskPool
-            , VolumeInfo volume, VMInstanceVO vm, VMTemplateVO rootDiskTmplt, DataCenterVO dcVO,
-            HostPodVO pod, DiskOfferingVO diskVO, ServiceOfferingVO svo, HypervisorType rootDiskHyperType) throws NoTransitionException {
-
-        if (!volume
-                .getFormat()
-                .equals(
-                        getSupportedImageFormatForCluster(rootDiskHyperType))) {
-            throw new InvalidParameterValueException(
-                    "Failed to attach volume to VM since volumes format "
-                            + volume.getFormat()
-                            .getFileExtension()
-                            + " is not compatible with the vm hypervisor type");
-        }
-
-        VolumeInfo volumeOnPrimary = copyVolumeFromSecToPrimary(volume,
-                vm, rootDiskTmplt, dcVO, pod,
-                rootDiskPool.getClusterId(), svo, diskVO,
-                new ArrayList<StoragePool>(),
-                volume.getSize(), rootDiskHyperType);
-
-        return volumeOnPrimary;
-    }
-
-    private VolumeInfo createVolumeOnPrimaryStorage(VMInstanceVO vm, VolumeVO rootVolumeOfVm, VolumeInfo volume, HypervisorType rootDiskHyperType) throws NoTransitionException {
-        VMTemplateVO rootDiskTmplt = _templateDao.findById(vm
-                .getTemplateId());
-        DataCenterVO dcVO = _dcDao.findById(vm
-                .getDataCenterId());
-        HostPodVO pod = _podDao.findById(vm.getPodIdToDeployIn());
-        StoragePoolVO rootDiskPool = _storagePoolDao
-                .findById(rootVolumeOfVm.getPoolId());
-        ServiceOfferingVO svo = _serviceOfferingDao.findById(vm
-                .getServiceOfferingId());
-        DiskOfferingVO diskVO = _diskOfferingDao.findById(volume
-                .getDiskOfferingId());
-        Long clusterId = (rootDiskPool == null ? null : rootDiskPool
-                .getClusterId());
-
-        VolumeInfo vol = null;
-        if (volume.getState() == Volume.State.Allocated) {
-            vol = createVolume(volume, vm,
-                    rootDiskTmplt, dcVO, pod, clusterId, svo, diskVO,
-                    new ArrayList<StoragePool>(), volume.getSize(),
-                    rootDiskHyperType);
-        } else if (volume.getState() == Volume.State.Uploaded) {
-            vol = copyVolume(rootDiskPool
-                    , volume, vm, rootDiskTmplt,  dcVO,
-                    pod,  diskVO,  svo,  rootDiskHyperType);
-            if (vol != null) {
-                // Moving of Volume is successful, decrement the volume resource count from secondary for an account and increment it into primary storage under same account.
-                _resourceLimitMgr.decrementResourceCount(volume.getAccountId(),
-                        ResourceType.secondary_storage, new Long(volume.getSize()));
-                _resourceLimitMgr.incrementResourceCount(volume.getAccountId(),
-                        ResourceType.primary_storage, new Long(volume.getSize()));
-            }
-        }
-
-        VolumeVO volVO = _volsDao.findById(vol.getId());
-        volVO.setFormat(getSupportedImageFormatForCluster(rootDiskHyperType));
-        _volsDao.update(volVO.getId(), volVO);
-        return volFactory.getVolume(volVO.getId());
-    }
-
-    private boolean needMoveVolume(VolumeVO rootVolumeOfVm, VolumeInfo volume) {
-        if (rootVolumeOfVm.getPoolId() == null || volume.getPoolId() == null) {
-            return false;
-        }
-
-        DataStore storeForRootVol = dataStoreMgr.getPrimaryDataStore(rootVolumeOfVm.getPoolId());
-        DataStore storeForDataVol = dataStoreMgr.getPrimaryDataStore(volume.getPoolId());
-
-        Scope storeForRootStoreScope = storeForRootVol.getScope();
-        if (storeForRootStoreScope == null) {
-            throw new CloudRuntimeException("Can't get scope of data store: " + storeForRootVol.getId());
-        }
-
-        Scope storeForDataStoreScope = storeForDataVol.getScope();
-        if (storeForDataStoreScope == null) {
-            throw new CloudRuntimeException("Can't get scope of data store: " + storeForDataVol.getId());
-        }
-
-        if (storeForDataStoreScope.getScopeType() == ScopeType.ZONE) {
-            return false;
-        }
-
-        if (storeForRootStoreScope.getScopeType() != storeForDataStoreScope.getScopeType()) {
-            if (storeForDataStoreScope.getScopeType() == ScopeType.CLUSTER && storeForRootStoreScope.getScopeType() == ScopeType.HOST) {
-                HostScope hs = (HostScope)storeForRootStoreScope;
-                if (storeForDataStoreScope.getScopeId().equals(hs.getClusterId())) {
-                    return false;
-                }
-            }
-            if (storeForRootStoreScope.getScopeType() == ScopeType.CLUSTER && storeForDataStoreScope.getScopeType() == ScopeType.HOST) {
-                HostScope hs = (HostScope)storeForDataStoreScope;
-                if (storeForRootStoreScope.getScopeId().equals(hs.getClusterId())) {
-                    return false;
-                }
-            }
-            throw new CloudRuntimeException("Can't move volume between scope: " + storeForDataStoreScope.getScopeType() + " and " + storeForRootStoreScope.getScopeType());
-        }
-
-        return !storeForRootStoreScope.isSameScope(storeForDataStoreScope);
-    }
-
-    private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, Long deviceId) {
-        String errorMsg = "Failed to attach volume: " + volumeToAttach.getName()
-                + " to VM: " + vm.getHostName();
-        boolean sendCommand = (vm.getState() == State.Running);
-        AttachAnswer answer = null;
-        Long hostId = vm.getHostId();
-        if (hostId == null) {
-            hostId = vm.getLastHostId();
-            HostVO host = _hostDao.findById(hostId);
-            if (host != null
-                    && host.getHypervisorType() == HypervisorType.VMware) {
-                sendCommand = true;
-            }
-        }
-
-        StoragePoolVO volumeToAttachStoragePool = null;
-
-        if (sendCommand) {
-            volumeToAttachStoragePool = _storagePoolDao.findById(volumeToAttach.getPoolId());
-            long storagePoolId = volumeToAttachStoragePool.getId();
-
-            DataTO volTO = volFactory.getVolume(volumeToAttach.getId()).getTO();
-            DiskTO disk = new DiskTO(volTO, deviceId, null, volumeToAttach.getVolumeType());
-
-            AttachCommand cmd = new AttachCommand(disk, vm.getInstanceName());
-
-            cmd.setManaged(volumeToAttachStoragePool.isManaged());
-
-            cmd.setStorageHost(volumeToAttachStoragePool.getHostAddress());
-            cmd.setStoragePort(volumeToAttachStoragePool.getPort());
-
-            cmd.set_iScsiName(volumeToAttach.get_iScsiName());
-
-            VolumeInfo volumeInfo = volFactory.getVolume(volumeToAttach.getId());
-            DataStore dataStore = dataStoreMgr.getDataStore(storagePoolId, DataStoreRole.Primary);
-            ChapInfo chapInfo = volService.getChapInfo(volumeInfo, dataStore);
-
-            if (chapInfo != null) {
-                cmd.setChapInitiatorUsername(chapInfo.getInitiatorUsername());
-                cmd.setChapInitiatorPassword(chapInfo.getInitiatorSecret());
-                cmd.setChapTargetUsername(chapInfo.getTargetUsername());
-                cmd.setChapTargetPassword(chapInfo.getTargetSecret());
-            }
-
-            try {
-                answer = (AttachAnswer)_agentMgr.send(hostId, cmd);
-            } catch (Exception e) {
-                throw new CloudRuntimeException(errorMsg + " due to: "
-                        + e.getMessage());
-            }
-        }
-
-        if (!sendCommand || (answer != null && answer.getResult())) {
-            // Mark the volume as attached
-            if (sendCommand) {
-                DiskTO disk = answer.getDisk();
-                _volsDao.attachVolume(volumeToAttach.getId(), vm.getId(),
-                        disk.getDiskSeq());
-
-                volumeToAttach = _volsDao.findById(volumeToAttach.getId());
-
-                if (volumeToAttachStoragePool.isManaged() &&
-                        volumeToAttach.getPath() == null) {
-                    volumeToAttach.setPath(answer.getDisk().getVdiUuid());
-
-                    _volsDao.update(volumeToAttach.getId(), volumeToAttach);
-                }
-            } else {
-                _volsDao.attachVolume(volumeToAttach.getId(), vm.getId(), deviceId);
-            }
-
-            // insert record for disk I/O statistics
-            VmDiskStatisticsVO diskstats = _vmDiskStatsDao.findBy(vm.getAccountId(), vm.getDataCenterId(),vm.getId(), volumeToAttach.getId());
-            if (diskstats == null) {
-                diskstats = new VmDiskStatisticsVO(vm.getAccountId(), vm.getDataCenterId(),vm.getId(), volumeToAttach.getId());
-                _vmDiskStatsDao.persist(diskstats);
-            }
-
-            return _volsDao.findById(volumeToAttach.getId());
-        } else {
-            if (answer != null) {
-                String details = answer.getDetails();
-                if (details != null && !details.isEmpty()) {
-                    errorMsg += "; " + details;
-                }
-            }
-            throw new CloudRuntimeException(errorMsg);
-        }
-    }
-
-    private int getMaxDataVolumesSupported(UserVmVO vm) {
-        Long hostId = vm.getHostId();
-        if (hostId == null) {
-            hostId = vm.getLastHostId();
-        }
-        HostVO host = _hostDao.findById(hostId);
-        Integer maxDataVolumesSupported = null;
-        if (host != null) {
-            _hostDao.loadDetails(host);
-            maxDataVolumesSupported = _hypervisorCapabilitiesDao
-                    .getMaxDataVolumesLimit(host.getHypervisorType(),
-                            host.getDetail("product_version"));
-        }
-        if (maxDataVolumesSupported == null) {
-            maxDataVolumesSupported = 6; // 6 data disks by default if nothing
-            // is specified in
-            // 'hypervisor_capabilities' table
-        }
-
-        return maxDataVolumesSupported.intValue();
-    }
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_ATTACH, eventDescription = "attaching volume", async = true)
-    public Volume attachVolumeToVM(AttachVolumeCmd command) {
-        Long vmId = command.getVirtualMachineId();
-        Long volumeId = command.getId();
-        Long deviceId = command.getDeviceId();
-        Account caller = CallContext.current().getCallingAccount();
-
-        // Check that the volume ID is valid
-        VolumeInfo volume = volFactory.getVolume(volumeId);
-        // Check that the volume is a data volume
-        if (volume == null || volume.getVolumeType() != Volume.Type.DATADISK) {
-            throw new InvalidParameterValueException(
-                    "Please specify a valid data volume.");
-        }
-
-        // Check that the volume is not currently attached to any VM
-        if (volume.getInstanceId() != null) {
-            throw new InvalidParameterValueException(
-                    "Please specify a volume that is not attached to any VM.");
-        }
-
-        // Check that the volume is not destroyed
-        if (volume.getState() == Volume.State.Destroy) {
-            throw new InvalidParameterValueException(
-                    "Please specify a volume that is not destroyed.");
-        }
-
-        // Check that the virtual machine ID is valid and it's a user vm
-        UserVmVO vm = _userVmDao.findById(vmId);
-        if (vm == null || vm.getType() != VirtualMachine.Type.User) {
-            throw new InvalidParameterValueException(
-                    "Please specify a valid User VM.");
-        }
-
-        // Check that the VM is in the correct state
-        if (vm.getState() != State.Running && vm.getState() != State.Stopped) {
-            throw new InvalidParameterValueException(
-                    "Please specify a VM that is either running or stopped.");
-        }
-
-        // Check that the device ID is valid
-        if (deviceId != null) {
-            if (deviceId.longValue() == 0) {
-                throw new InvalidParameterValueException(
-                        "deviceId can't be 0, which is used by Root device");
-            }
-        }
-
-        // Check that the number of data volumes attached to VM is less than
-        // that supported by hypervisor
-        List<VolumeVO> existingDataVolumes = _volsDao.findByInstanceAndType(
-                vmId, Volume.Type.DATADISK);
-        int maxDataVolumesSupported = getMaxDataVolumesSupported(vm);
-        if (existingDataVolumes.size() >= maxDataVolumesSupported) {
-            throw new InvalidParameterValueException(
-                    "The specified VM already has the maximum number of data disks ("
-                            + maxDataVolumesSupported
-                            + "). Please specify another VM.");
-        }
-
-        // Check that the VM and the volume are in the same zone
-        if (vm.getDataCenterId() != volume.getDataCenterId()) {
-            throw new InvalidParameterValueException(
-                    "Please specify a VM that is in the same zone as the volume.");
-        }
-
-        // If local storage is disabled then attaching a volume with local disk
-        // offering not allowed
-        DataCenterVO dataCenter = _dcDao.findById(volume.getDataCenterId());
-        if (!dataCenter.isLocalStorageEnabled()) {
-            DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume
-                    .getDiskOfferingId());
-            if (diskOffering.getUseLocalStorage()) {
-                throw new InvalidParameterValueException(
-                        "Zone is not configured to use local storage but volume's disk offering "
-                                + diskOffering.getName() + " uses it");
-            }
-        }
-
-        // if target VM has associated VM snapshots
-        List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
-        if(vmSnapshots.size() > 0){
-            throw new InvalidParameterValueException(
-                    "Unable to attach volume, please specify a VM that does not have VM snapshots");
-        }
-
-        // permission check
-        _accountMgr.checkAccess(caller, null, true, volume, vm);
-
-        if (!(Volume.State.Allocated.equals(volume.getState())
-                || Volume.State.Ready.equals(volume.getState()) || Volume.State.Uploaded
-                .equals(volume.getState()))) {
-            throw new InvalidParameterValueException(
-                    "Volume state must be in Allocated, Ready or in Uploaded state");
-        }
-
-        VolumeVO rootVolumeOfVm = null;
-        List<VolumeVO> rootVolumesOfVm = _volsDao.findByInstanceAndType(vmId,
-                Volume.Type.ROOT);
-        if (rootVolumesOfVm.size() != 1) {
-            throw new CloudRuntimeException(
-                    "The VM "
-                            + vm.getHostName()
-                            + " has more than one ROOT volume and is in an invalid state.");
-        } else {
-            rootVolumeOfVm = rootVolumesOfVm.get(0);
-        }
-
-        HypervisorType rootDiskHyperType = vm.getHypervisorType();
-
-        HypervisorType dataDiskHyperType = _volsDao.getHypervisorType(volume
-                .getId());
-        if (dataDiskHyperType != HypervisorType.None
-                && rootDiskHyperType != dataDiskHyperType) {
-            throw new InvalidParameterValueException(
-                    "Can't attach a volume created by: " + dataDiskHyperType
-                    + " to a " + rootDiskHyperType + " vm");
-        }
-
-
-        deviceId = getDeviceId(vmId, deviceId);
-        VolumeInfo volumeOnPrimaryStorage = volume;
-
-        // Check if volume is stored on secondary storage
-        boolean isVolumeOnSec = false;
-        VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image);
-        if (volOnSecondary != null) {
-            isVolumeOnSec = true;
-            if(volOnSecondary.getState() != Volume.State.Uploaded) {
-                throw new InvalidParameterValueException("Volume is not uploaded yet. Please try this operation once the volume is uploaded");
-            }
-        }
-        
-        boolean createVolumeOnBackend = true;
-        if (rootVolumeOfVm.getState() == Volume.State.Allocated) {
-            createVolumeOnBackend = false;
-            if(isVolumeOnSec) {
-                throw new CloudRuntimeException("Cant attach uploaded volume to the vm which is not created. Please start it and then retry");
-            }
-        }
-
-        // Create volume on the backend only when VM's root volume is allocated
-        if (createVolumeOnBackend) {
-            if (volume.getState().equals(Volume.State.Allocated)
-                    || volume.getState() == Volume.State.Uploaded) {
-                try {
-                    volumeOnPrimaryStorage = createVolumeOnPrimaryStorage(vm, rootVolumeOfVm, volume, rootDiskHyperType);
-                } catch (NoTransitionException e) {
-                    s_logger.debug("Failed to create volume on primary storage", e);
-                    throw new CloudRuntimeException("Failed to create volume on primary storage", e);
-                }
-            }
-
-            // reload the volume from db
-            volumeOnPrimaryStorage = volFactory.getVolume(volumeOnPrimaryStorage.getId());
-            boolean moveVolumeNeeded = needMoveVolume(rootVolumeOfVm, volumeOnPrimaryStorage);
-
-            if (moveVolumeNeeded) {
-                PrimaryDataStoreInfo primaryStore = (PrimaryDataStoreInfo)volumeOnPrimaryStorage.getDataStore();
-                if (primaryStore.isLocal()) {
-                    throw new CloudRuntimeException(
-                            "Failed to attach local data volume "
-                                    + volume.getName()
-                                    + " to VM "
-                                    + vm.getDisplayName()
-                                    + " as migration of local data volume is not allowed");
-                }
-                StoragePoolVO vmRootVolumePool = _storagePoolDao
-                        .findById(rootVolumeOfVm.getPoolId());
-
-                try {
-                    volumeOnPrimaryStorage = moveVolume(volumeOnPrimaryStorage,
-                            vmRootVolumePool.getDataCenterId(),
-                            vmRootVolumePool.getPodId(),
-                            vmRootVolumePool.getClusterId(),
-                            dataDiskHyperType);
-                } catch (ConcurrentOperationException e) {
-                    s_logger.debug("move volume failed", e);
-                    throw new CloudRuntimeException("move volume failed", e);
-                }
-            }
-        }
-
-
-        AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-               
-        if (asyncExecutionContext != null) {
-            AsyncJob job = asyncExecutionContext.getJob();
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Trying to attaching volume " + volumeId
-                        + " to vm instance:" + vm.getId()
-                        + ", update async job-" + job.getId()
-                        + " progress status");
-            }
-
-            _asyncMgr.updateAsyncJobAttachment(job.getId(), "volume", volumeId);
-            _asyncMgr.updateAsyncJobStatus(job.getId(), BaseCmd.PROGRESS_INSTANCE_CREATED, Long.toString(volumeId));
-        }
-
-        VolumeVO newVol = _volumeDao.findById(volumeOnPrimaryStorage.getId());
-        newVol = sendAttachVolumeCommand(vm, newVol, deviceId);
-        return newVol;
-    }
-
-    @Override
-    public Volume updateVolume(UpdateVolumeCmd cmd){
-        Long volumeId = cmd.getId();
-        String path = cmd.getPath();
-
-        if(path == null){
-            throw new InvalidParameterValueException("Failed to update the volume as path was null");
-        }
-
-        VolumeVO volume = ApiDBUtils.findVolumeById(volumeId);
-        volume.setPath(path);
-        _volumeDao.update(volumeId, volume);
-
-        return volume;
-    }
-
-
-    @Override
-    @ActionEvent(eventType = EventTypes.EVENT_VOLUME_DETACH, eventDescription = "detaching volume", async = true)
-    public Volume detachVolumeFromVM(DetachVolumeCmd cmmd) {
-        Account caller = CallContext.current().getCallingAccount();
-        if ((cmmd.getId() == null && cmmd.getDeviceId() == null && cmmd
-                .getVirtualMachineId() == null)
-                || (cmmd.getId() != null && (cmmd.getDeviceId() != null || cmmd
-                .getVirtualMachineId() != null))
-                || (cmmd.getId() == null && (cmmd.getDeviceId() == null || cmmd
-                .getVirtualMachineId() == null))) {
-            throw new InvalidParameterValueException(
-                    "Please provide either a volume id, or a tuple(device id, instance id)");
-        }
-
-        Long volumeId = cmmd.getId();
-        VolumeVO volume = null;
-
-        if (volumeId != null) {
-            volume = _volsDao.findById(volumeId);
-        } else {
-            volume = _volsDao.findByInstanceAndDeviceId(
-                    cmmd.getVirtualMachineId(), cmmd.getDeviceId()).get(0);
-        }
-
-        Long vmId = null;
-
-        if (cmmd.getVirtualMachineId() == null) {
-            vmId = volume.getInstanceId();
-        } else {
-            vmId = cmmd.getVirtualMachineId();
-        }
-
-        // Check that the volume ID is valid
-        if (volume == null) {
-            throw new InvalidParameterValueException(
-                    "Unable to find volume with ID: " + volumeId);
-        }
-
-        // Permissions check
-        _accountMgr.checkAccess(caller, null, true, volume);
-
-        // Check that the volume is a data volume
-        if (volume.getVolumeType() != Volume.Type.DATADISK) {
-            throw new InvalidParameterValueException(
-                    "Please specify a data volume.");
-        }
-
-        // Check that the volume is currently attached to a VM
-        if (vmId == null) {
-            throw new InvalidParameterValueException(
-                    "The specified volume is not attached to a VM.");
-        }
-
-        // Check that the VM is in the correct state
-        UserVmVO vm = _userVmDao.findById(vmId);
-        if (vm.getState() != State.Running && vm.getState() != State.Stopped
-                && vm.getState() != State.Destroyed) {
-            throw new InvalidParameterValueException(
-                    "Please specify a VM that is either running or stopped.");
-        }
-
-        AsyncJobExecutionContext asyncExecutionContext = AsyncJobExecutionContext.getCurrentExecutionContext();
-        if (asyncExecutionContext != null) {
-            AsyncJob job = asyncExecutionContext.getJob();
-
-            if (s_logger.isInfoEnabled()) {
-                s_logger.info("Trying to attaching volume " + volumeId
-                        + "to vm instance:" + vm.getId()
-                        + ", update async job-" + job.getId()
-                        + " progress status");
-            }
-
-            _asyncMgr.updateAsyncJobAttachment(job.getId(), "volume", volumeId);
-            _asyncMgr.updateAsyncJobStatus(job.getId(), BaseCmd.PROGRESS_INSTANCE_CREATED, volumeId.toString());
-        }
-
-        String errorMsg = "Failed to detach volume: " + volume.getName()
-                + " from VM: " + vm.getHostName();
-        boolean sendCommand = (vm

<TRUNCATED>

Mime
View raw message