CLOUDSTACK-6928: fix issue disk I/O throttling not applied

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/976b3b7d
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/976b3b7d
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/976b3b7d

Branch: refs/heads/4.8
Commit: 976b3b7df4fda3e51a9e32ca00729caacec3983e
Parents: 7a0b37a
Author: Wei Zhou <w.z...@tech.leaseweb.com>
Authored: Tue Feb 9 12:55:41 2016 +0100
Committer: Wei Zhou <w.z...@tech.leaseweb.com>
Committed: Thu May 19 11:26:43 2016 +0200

----------------------------------------------------------------------
 .../src/com/cloud/storage/StorageManager.java   | 137 +++++++++++++++++++
 .../orchestration/VolumeOrchestrator.java       |  20 ++-
 .../kvm/storage/KVMStorageProcessor.java        |  21 ++-
 .../src/com/cloud/storage/StorageManager.java   | 128 -----------------
 .../com/cloud/storage/StorageManagerImpl.java   |  53 ++++++-
 .../com/cloud/storage/VolumeApiServiceImpl.java |   5 +-
 6 files changed, 221 insertions(+), 143 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/976b3b7d/engine/components-api/src/com/cloud/storage/StorageManager.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/com/cloud/storage/StorageManager.java 
b/engine/components-api/src/com/cloud/storage/StorageManager.java
new file mode 100644
index 0000000..aa6c0ce
--- /dev/null
+++ b/engine/components-api/src/com/cloud/storage/StorageManager.java
@@ -0,0 +1,137 @@
+// 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.math.BigDecimal;
+import java.util.List;
+
+import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
+import 
org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
+import com.cloud.agent.manager.Commands;
+import com.cloud.capacity.CapacityVO;
+import com.cloud.exception.ConnectionException;
+import com.cloud.exception.StorageConflictException;
+import com.cloud.exception.StorageUnavailableException;
+import com.cloud.host.Host;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.utils.Pair;
+import com.cloud.vm.DiskProfile;
+import com.cloud.vm.VMInstanceVO;
+
+public interface StorageManager extends StorageService {
+    static final ConfigKey<Integer> StorageCleanupInterval = new 
ConfigKey<Integer>(Integer.class, "storage.cleanup.interval", "Advanced", 
"86400",
+            "The interval (in seconds) to wait before running the storage 
cleanup thread.", false, ConfigKey.Scope.Global, null);
+    static final ConfigKey<Integer> StorageCleanupDelay = new 
ConfigKey<Integer>(Integer.class, "storage.cleanup.delay", "Advanced", "86400",
+            "Determines how long (in seconds) to wait before actually 
expunging destroyed volumes. The default value = the default value of 
storage.cleanup.interval.", false, ConfigKey.Scope.Global, null);
+    static final ConfigKey<Boolean> StorageCleanupEnabled = new 
ConfigKey<Boolean>(Boolean.class, "storage.cleanup.enabled", "Advanced", "true",
+            "Enables/disables the storage cleanup thread.", false, 
ConfigKey.Scope.Global, null);
+
+    /**
+     * Returns a comma separated list of tags for the specified storage pool
+     * @param poolId
+     * @return comma separated list of tags
+     */
+    public String getStoragePoolTags(long poolId);
+
+    Answer sendToPool(long poolId, Command cmd) throws 
StorageUnavailableException;
+
+    Answer sendToPool(StoragePool pool, Command cmd) throws 
StorageUnavailableException;
+
+    Answer[] sendToPool(long poolId, Commands cmd) throws 
StorageUnavailableException;
+
+    Answer[] sendToPool(StoragePool pool, Commands cmds) throws 
StorageUnavailableException;
+
+    Pair<Long, Answer[]> sendToPool(StoragePool pool, long[] 
hostIdsToTryFirst, List<Long> hostIdsToAvoid, Commands cmds) throws 
StorageUnavailableException;
+
+    Pair<Long, Answer> sendToPool(StoragePool pool, long[] hostIdsToTryFirst, 
List<Long> hostIdsToAvoid, Command cmd) throws StorageUnavailableException;
+
+    /**
+     * Checks if a host has running VMs that are using its local storage pool.
+     * @return true if local storage is active on the host
+     */
+    boolean isLocalStorageActiveOnHost(Long hostId);
+
+    /**
+     * Cleans up storage pools by removing unused templates.
+     * @param recurring - true if this cleanup is part of a recurring garbage 
collection thread
+     */
+    void cleanupStorage(boolean recurring);
+
+    String getPrimaryStorageNameLabel(VolumeVO volume);
+
+    void createCapacityEntry(StoragePoolVO storagePool, short capacityType, 
long allocated);
+
+    Answer sendToPool(StoragePool pool, long[] hostIdsToTryFirst, Command cmd) 
throws StorageUnavailableException;
+
+    CapacityVO getSecondaryStorageUsedStats(Long hostId, Long zoneId);
+
+    CapacityVO getStoragePoolUsedStats(Long poolId, Long clusterId, Long 
podId, Long zoneId);
+
+    List<StoragePoolVO> ListByDataCenterHypervisor(long datacenterId, 
HypervisorType type);
+
+    List<VMInstanceVO> listByStoragePool(long storagePoolId);
+
+    StoragePoolVO findLocalStorageOnHost(long hostId);
+
+    Host updateSecondaryStorage(long secStorageId, String newUrl);
+
+    List<Long> getUpHostsInPool(long poolId);
+
+    void cleanupSecondaryStorage(boolean recurring);
+
+    HypervisorType getHypervisorTypeFromFormat(ImageFormat format);
+
+    boolean storagePoolHasEnoughIops(List<Volume> volume, StoragePool pool);
+
+    boolean storagePoolHasEnoughSpace(List<Volume> volume, StoragePool pool);
+
+    boolean registerHostListener(String providerUuid, HypervisorHostListener 
listener);
+
+    void connectHostToSharedPool(long hostId, long poolId) throws 
StorageUnavailableException, StorageConflictException;
+
+    void createCapacityEntry(long poolId);
+
+    DataStore createLocalStorage(Host host, StoragePoolInfo poolInfo) throws 
ConnectionException;
+
+    BigDecimal getStorageOverProvisioningFactor(Long dcId);
+
+    Long getDiskBytesReadRate(ServiceOffering offering, DiskOffering 
diskOffering);
+
+    Long getDiskBytesWriteRate(ServiceOffering offering, DiskOffering 
diskOffering);
+
+    Long getDiskIopsReadRate(ServiceOffering offering, DiskOffering 
diskOffering);
+
+    Long getDiskIopsWriteRate(ServiceOffering offering, DiskOffering 
diskOffering);
+
+    void cleanupDownloadUrls();
+
+    void setDiskProfileThrottling(DiskProfile dskCh, ServiceOffering offering, 
DiskOffering diskOffering);
+
+    DiskTO getDiskWithThrottling(DataTO volTO, Volume.Type volumeType, long 
deviceId, String path, long offeringId, long diskOfferingId);
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/976b3b7d/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
----------------------------------------------------------------------
diff --git 
a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
 
b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
index d407bb1..8de6bd2 100644
--- 
a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
+++ 
b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java
@@ -94,6 +94,7 @@ import com.cloud.storage.ScopeType;
 import com.cloud.storage.Snapshot;
 import com.cloud.storage.Storage;
 import com.cloud.storage.Storage.ImageFormat;
+import com.cloud.storage.StorageManager;
 import com.cloud.storage.StoragePool;
 import com.cloud.storage.VMTemplateStorageResourceAssoc;
 import com.cloud.storage.Volume;
@@ -175,6 +176,8 @@ public class VolumeOrchestrator extends ManagerBase 
implements VolumeOrchestrati
     protected AsyncJobManager _jobMgr;
     @Inject
     ClusterManager clusterManager;
+    @Inject
+    StorageManager storageMgr;
 
     private final StateMachine2<Volume.State, Volume.Event, Volume> 
_volStateMachine;
     protected List<StoragePoolAllocator> _storagePoolAllocators;
@@ -207,10 +210,11 @@ public class VolumeOrchestrator extends ManagerBase 
implements VolumeOrchestrati
 
         // Find a destination storage pool with the specified criteria
         DiskOffering diskOffering = _entityMgr.findById(DiskOffering.class, 
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);
+        storageMgr.setDiskProfileThrottling(dskCh, null, diskOffering);
+
         DataCenter destPoolDataCenter = _entityMgr.findById(DataCenter.class, 
destPoolDcId);
         Pod destPoolPod = _entityMgr.findById(Pod.class, destPoolPodId);
 
@@ -458,6 +462,8 @@ public class VolumeOrchestrator extends ManagerBase 
implements VolumeOrchestrati
         final HashSet<StoragePool> avoidPools = new 
HashSet<StoragePool>(avoids);
         DiskProfile dskCh = createDiskCharacteristics(volume, template, dc, 
diskOffering);
         dskCh.setHyperType(vm.getHypervisorType());
+        storageMgr.setDiskProfileThrottling(dskCh, null, diskOffering);
+
         // Find a suitable storage to create volume on
         StoragePool destPool = findStoragePool(dskCh, dc, pod, clusterId, 
null, vm, avoidPools);
         DataStore destStore = dataStoreMgr.getDataStore(destPool.getId(), 
DataStoreRole.Primary);
@@ -490,8 +496,10 @@ public class VolumeOrchestrator extends ManagerBase 
implements VolumeOrchestrati
         DiskProfile dskCh = null;
         if (volume.getVolumeType() == Type.ROOT && Storage.ImageFormat.ISO != 
template.getFormat()) {
             dskCh = createDiskCharacteristics(volume, template, dc, offering);
+            storageMgr.setDiskProfileThrottling(dskCh, offering, diskOffering);
         } else {
             dskCh = createDiskCharacteristics(volume, template, dc, 
diskOffering);
+            storageMgr.setDiskProfileThrottling(dskCh, null, diskOffering);
         }
 
         if (diskOffering != null && diskOffering.isCustomized()) {
@@ -1054,9 +1062,10 @@ public class VolumeOrchestrator extends ManagerBase 
implements VolumeOrchestrati
         }
 
         for (VolumeVO vol : vols) {
-            DataTO volTO = volFactory.getVolume(vol.getId()).getTO();
-            DiskTO disk = new DiskTO(volTO, vol.getDeviceId(), vol.getPath(), 
vol.getVolumeType());
             VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
+            DataTO volTO = volumeInfo.getTO();
+            DiskTO disk = storageMgr.getDiskWithThrottling(volTO, 
vol.getVolumeType(), vol.getDeviceId(), vol.getPath(),
+                    vm.getServiceOfferingId(), vol.getDiskOfferingId());
             DataStore dataStore = dataStoreMgr.getDataStore(vol.getPoolId(), 
DataStoreRole.Primary);
 
             disk.setDetails(getDetails(volumeInfo, dataStore));
@@ -1337,9 +1346,10 @@ public class VolumeOrchestrator extends ManagerBase 
implements VolumeOrchestrati
                 pool = 
(StoragePool)dataStoreMgr.getDataStore(result.second().getId(), 
DataStoreRole.Primary);
                 vol = result.first();
             }
-            DataTO volumeTO = volFactory.getVolume(vol.getId()).getTO();
-            DiskTO disk = new DiskTO(volumeTO, vol.getDeviceId(), 
vol.getPath(), vol.getVolumeType());
             VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
+            DataTO volTO = volumeInfo.getTO();
+            DiskTO disk = storageMgr.getDiskWithThrottling(volTO, 
vol.getVolumeType(), vol.getDeviceId(), vol.getPath(),
+                    vm.getServiceOfferingId(), vol.getDiskOfferingId());
             DataStore dataStore = dataStoreMgr.getDataStore(vol.getPoolId(), 
DataStoreRole.Primary);
 
             disk.setDetails(getDetails(volumeInfo, dataStore));

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/976b3b7d/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
 
b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
index 51931db..749cbd8 100644
--- 
a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
+++ 
b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java
@@ -944,8 +944,8 @@ public class KVMStorageProcessor implements 
StorageProcessor {
         return null;
     }
 
-    protected synchronized String attachOrDetachDisk(final Connect conn, final 
boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final 
int devId, final String serial) throws LibvirtException,
-    InternalErrorException {
+    protected synchronized String attachOrDetachDisk(final Connect conn, final 
boolean attach, final String vmName, final KVMPhysicalDisk attachingDisk, final 
int devId, final String serial,
+            final Long bytesReadRate, final Long bytesWriteRate, final Long 
iopsReadRate, final Long iopsWriteRate) throws LibvirtException, 
InternalErrorException {
         List<DiskDef> disks = null;
         Domain dm = null;
         DiskDef diskdef = null;
@@ -1006,6 +1006,19 @@ public class KVMStorageProcessor implements 
StorageProcessor {
                 } else if (attachingDisk.getFormat() == 
PhysicalDiskFormat.RAW) {
                     diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId, 
DiskDef.DiskBus.VIRTIO);
                 }
+
+                if ((bytesReadRate != null) && (bytesReadRate > 0)) {
+                    diskdef.setBytesReadRate(bytesReadRate);
+                }
+                if ((bytesWriteRate != null) && (bytesWriteRate > 0)) {
+                    diskdef.setBytesWriteRate(bytesWriteRate);
+                }
+                if ((iopsReadRate != null) && (iopsReadRate > 0)) {
+                    diskdef.setIopsReadRate(iopsReadRate);
+                }
+                if ((iopsWriteRate != null) && (iopsWriteRate > 0)) {
+                    diskdef.setIopsWriteRate(iopsWriteRate);
+                }
             }
 
             final String xml = diskdef.toString();
@@ -1031,7 +1044,7 @@ public class KVMStorageProcessor implements 
StorageProcessor {
 
             final KVMPhysicalDisk phyDisk = 
storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), 
primaryStore.getUuid(), vol.getPath());
 
-            attachOrDetachDisk(conn, true, vmName, phyDisk, 
disk.getDiskSeq().intValue(), serial);
+            attachOrDetachDisk(conn, true, vmName, phyDisk, 
disk.getDiskSeq().intValue(), serial, vol.getBytesReadRate(), 
vol.getBytesWriteRate(), vol.getIopsReadRate(), vol.getIopsWriteRate());
 
             return new AttachAnswer(disk);
         } catch (final LibvirtException e) {
@@ -1056,7 +1069,7 @@ public class KVMStorageProcessor implements 
StorageProcessor {
 
             final KVMPhysicalDisk phyDisk = 
storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), 
primaryStore.getUuid(), vol.getPath());
 
-            attachOrDetachDisk(conn, false, vmName, phyDisk, 
disk.getDiskSeq().intValue(), serial);
+            attachOrDetachDisk(conn, false, vmName, phyDisk, 
disk.getDiskSeq().intValue(), serial, vol.getBytesReadRate(), 
vol.getBytesWriteRate(), vol.getIopsReadRate(), vol.getIopsWriteRate());
 
             storagePoolMgr.disconnectPhysicalDisk(primaryStore.getPoolType(), 
primaryStore.getUuid(), vol.getPath());
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/976b3b7d/server/src/com/cloud/storage/StorageManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/StorageManager.java 
b/server/src/com/cloud/storage/StorageManager.java
deleted file mode 100644
index a399a08..0000000
--- a/server/src/com/cloud/storage/StorageManager.java
+++ /dev/null
@@ -1,128 +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.math.BigDecimal;
-import java.util.List;
-
-import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
-import 
org.apache.cloudstack.engine.subsystem.api.storage.HypervisorHostListener;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.StoragePoolInfo;
-import com.cloud.agent.manager.Commands;
-import com.cloud.capacity.CapacityVO;
-import com.cloud.exception.ConnectionException;
-import com.cloud.exception.StorageConflictException;
-import com.cloud.exception.StorageUnavailableException;
-import com.cloud.host.Host;
-import com.cloud.hypervisor.Hypervisor.HypervisorType;
-import com.cloud.service.ServiceOfferingVO;
-import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.utils.Pair;
-import com.cloud.vm.VMInstanceVO;
-
-public interface StorageManager extends StorageService {
-    static final ConfigKey<Integer> StorageCleanupInterval = new 
ConfigKey<Integer>(Integer.class, "storage.cleanup.interval", "Advanced", 
"86400",
-            "The interval (in seconds) to wait before running the storage 
cleanup thread.", false, ConfigKey.Scope.Global, null);
-    static final ConfigKey<Integer> StorageCleanupDelay = new 
ConfigKey<Integer>(Integer.class, "storage.cleanup.delay", "Advanced", "86400",
-            "Determines how long (in seconds) to wait before actually 
expunging destroyed volumes. The default value = the default value of 
storage.cleanup.interval.", false, ConfigKey.Scope.Global, null);
-    static final ConfigKey<Boolean> StorageCleanupEnabled = new 
ConfigKey<Boolean>(Boolean.class, "storage.cleanup.enabled", "Advanced", "true",
-            "Enables/disables the storage cleanup thread.", false, 
ConfigKey.Scope.Global, null);
-
-    /**
-     * Returns a comma separated list of tags for the specified storage pool
-     * @param poolId
-     * @return comma separated list of tags
-     */
-    public String getStoragePoolTags(long poolId);
-
-    Answer sendToPool(long poolId, Command cmd) throws 
StorageUnavailableException;
-
-    Answer sendToPool(StoragePool pool, Command cmd) throws 
StorageUnavailableException;
-
-    Answer[] sendToPool(long poolId, Commands cmd) throws 
StorageUnavailableException;
-
-    Answer[] sendToPool(StoragePool pool, Commands cmds) throws 
StorageUnavailableException;
-
-    Pair<Long, Answer[]> sendToPool(StoragePool pool, long[] 
hostIdsToTryFirst, List<Long> hostIdsToAvoid, Commands cmds) throws 
StorageUnavailableException;
-
-    Pair<Long, Answer> sendToPool(StoragePool pool, long[] hostIdsToTryFirst, 
List<Long> hostIdsToAvoid, Command cmd) throws StorageUnavailableException;
-
-    /**
-     * Checks if a host has running VMs that are using its local storage pool.
-     * @return true if local storage is active on the host
-     */
-    boolean isLocalStorageActiveOnHost(Long hostId);
-
-    /**
-     * Cleans up storage pools by removing unused templates.
-     * @param recurring - true if this cleanup is part of a recurring garbage 
collection thread
-     */
-    void cleanupStorage(boolean recurring);
-
-    String getPrimaryStorageNameLabel(VolumeVO volume);
-
-    void createCapacityEntry(StoragePoolVO storagePool, short capacityType, 
long allocated);
-
-    Answer sendToPool(StoragePool pool, long[] hostIdsToTryFirst, Command cmd) 
throws StorageUnavailableException;
-
-    CapacityVO getSecondaryStorageUsedStats(Long hostId, Long zoneId);
-
-    CapacityVO getStoragePoolUsedStats(Long poolId, Long clusterId, Long 
podId, Long zoneId);
-
-    List<StoragePoolVO> ListByDataCenterHypervisor(long datacenterId, 
HypervisorType type);
-
-    List<VMInstanceVO> listByStoragePool(long storagePoolId);
-
-    StoragePoolVO findLocalStorageOnHost(long hostId);
-
-    Host updateSecondaryStorage(long secStorageId, String newUrl);
-
-    List<Long> getUpHostsInPool(long poolId);
-
-    void cleanupSecondaryStorage(boolean recurring);
-
-    HypervisorType getHypervisorTypeFromFormat(ImageFormat format);
-
-    boolean storagePoolHasEnoughIops(List<Volume> volume, StoragePool pool);
-
-    boolean storagePoolHasEnoughSpace(List<Volume> volume, StoragePool pool);
-
-    boolean registerHostListener(String providerUuid, HypervisorHostListener 
listener);
-
-    void connectHostToSharedPool(long hostId, long poolId) throws 
StorageUnavailableException, StorageConflictException;
-
-    void createCapacityEntry(long poolId);
-
-    DataStore createLocalStorage(Host host, StoragePoolInfo poolInfo) throws 
ConnectionException;
-
-    BigDecimal getStorageOverProvisioningFactor(Long dcId);
-
-    Long getDiskBytesReadRate(ServiceOfferingVO offering, DiskOfferingVO 
diskOffering);
-
-    Long getDiskBytesWriteRate(ServiceOfferingVO offering, DiskOfferingVO 
diskOffering);
-
-    Long getDiskIopsReadRate(ServiceOfferingVO offering, DiskOfferingVO 
diskOffering);
-
-    Long getDiskIopsWriteRate(ServiceOfferingVO offering, DiskOfferingVO 
diskOffering);
-
-    void cleanupDownloadUrls();
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/976b3b7d/server/src/com/cloud/storage/StorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java 
b/server/src/com/cloud/storage/StorageManagerImpl.java
index 3d7146e..97a4db6 100644
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@ -95,11 +95,14 @@ 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 org.apache.cloudstack.storage.to.VolumeObjectTO;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
 import com.cloud.agent.api.StoragePoolInfo;
+import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DiskTO;
 import com.cloud.agent.manager.Commands;
 import com.cloud.api.ApiDBUtils;
 import com.cloud.api.query.dao.TemplateJoinDao;
@@ -138,13 +141,14 @@ import com.cloud.host.Status;
 import com.cloud.host.dao.HostDao;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.hypervisor.HypervisorGuruManager;
+import com.cloud.offering.DiskOffering;
+import com.cloud.offering.ServiceOffering;
 import com.cloud.org.Grouping;
 import com.cloud.org.Grouping.AllocationState;
 import com.cloud.resource.ResourceState;
 import com.cloud.server.ConfigurationServer;
 import com.cloud.server.ManagementServer;
 import com.cloud.server.StatsCollector;
-import com.cloud.service.ServiceOfferingVO;
 import com.cloud.storage.Storage.ImageFormat;
 import com.cloud.storage.Storage.StoragePoolType;
 import com.cloud.storage.Volume.Type;
@@ -173,6 +177,7 @@ import com.cloud.utils.component.ComponentContext;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;
+import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.db.GenericSearchBuilder;
 import com.cloud.utils.db.GlobalLock;
 import com.cloud.utils.db.JoinBuilder;
@@ -185,6 +190,7 @@ import com.cloud.utils.db.TransactionCallbackNoReturn;
 import com.cloud.utils.db.TransactionLegacy;
 import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.vm.DiskProfile;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.dao.VMInstanceDao;
@@ -280,6 +286,8 @@ public class StorageManagerImpl extends ManagerBase 
implements StorageManager, C
     private DiskOfferingDao _diskOfferingDao;
     @Inject
     ResourceLimitService _resourceLimitMgr;
+    @Inject
+    EntityManager _entityMgr;
 
     protected List<StoragePoolDiscoverer> _discoverers;
 
@@ -2237,7 +2245,7 @@ public class StorageManagerImpl extends ManagerBase 
implements StorageManager, C
 
     // get bytesReadRate from service_offering, disk_offering and 
vm.disk.throttling.bytes_read_rate
     @Override
-    public Long getDiskBytesReadRate(ServiceOfferingVO offering, 
DiskOfferingVO diskOffering) {
+    public Long getDiskBytesReadRate(final ServiceOffering offering, final 
DiskOffering diskOffering) {
         if ((offering != null) && (offering.getBytesReadRate() != null) && 
(offering.getBytesReadRate() > 0)) {
             return offering.getBytesReadRate();
         } else if ((diskOffering != null) && (diskOffering.getBytesReadRate() 
!= null) && (diskOffering.getBytesReadRate() > 0)) {
@@ -2253,7 +2261,7 @@ public class StorageManagerImpl extends ManagerBase 
implements StorageManager, C
 
     // get bytesWriteRate from service_offering, disk_offering and 
vm.disk.throttling.bytes_write_rate
     @Override
-    public Long getDiskBytesWriteRate(ServiceOfferingVO offering, 
DiskOfferingVO diskOffering) {
+    public Long getDiskBytesWriteRate(final ServiceOffering offering, final 
DiskOffering diskOffering) {
         if ((offering != null) && (offering.getBytesWriteRate() != null) && 
(offering.getBytesWriteRate() > 0)) {
             return offering.getBytesWriteRate();
         } else if ((diskOffering != null) && (diskOffering.getBytesWriteRate() 
!= null) && (diskOffering.getBytesWriteRate() > 0)) {
@@ -2269,7 +2277,7 @@ public class StorageManagerImpl extends ManagerBase 
implements StorageManager, C
 
     // get iopsReadRate from service_offering, disk_offering and 
vm.disk.throttling.iops_read_rate
     @Override
-    public Long getDiskIopsReadRate(ServiceOfferingVO offering, DiskOfferingVO 
diskOffering) {
+    public Long getDiskIopsReadRate(final ServiceOffering offering, final 
DiskOffering diskOffering) {
         if ((offering != null) && (offering.getIopsReadRate() != null) && 
(offering.getIopsReadRate() > 0)) {
             return offering.getIopsReadRate();
         } else if ((diskOffering != null) && (diskOffering.getIopsReadRate() 
!= null) && (diskOffering.getIopsReadRate() > 0)) {
@@ -2285,7 +2293,7 @@ public class StorageManagerImpl extends ManagerBase 
implements StorageManager, C
 
     // get iopsWriteRate from service_offering, disk_offering and 
vm.disk.throttling.iops_write_rate
     @Override
-    public Long getDiskIopsWriteRate(ServiceOfferingVO offering, 
DiskOfferingVO diskOffering) {
+    public Long getDiskIopsWriteRate(final ServiceOffering offering, final 
DiskOffering diskOffering) {
         if ((offering != null) && (offering.getIopsWriteRate() != null) && 
(offering.getIopsWriteRate() > 0)) {
             return offering.getIopsWriteRate();
         } else if ((diskOffering != null) && (diskOffering.getIopsWriteRate() 
!= null) && (diskOffering.getIopsWriteRate() > 0)) {
@@ -2308,4 +2316,39 @@ public class StorageManagerImpl extends ManagerBase 
implements StorageManager, C
     public ConfigKey<?>[] getConfigKeys() {
         return new ConfigKey<?>[] {StorageCleanupInterval, 
StorageCleanupDelay, StorageCleanupEnabled};
     }
+
+    @Override
+    public void setDiskProfileThrottling(DiskProfile dskCh, final 
ServiceOffering offering, final DiskOffering diskOffering) {
+        dskCh.setBytesReadRate(getDiskBytesReadRate(offering, diskOffering));
+        dskCh.setBytesWriteRate(getDiskBytesWriteRate(offering, diskOffering));
+        dskCh.setIopsReadRate(getDiskIopsReadRate(offering, diskOffering));
+        dskCh.setIopsWriteRate(getDiskIopsWriteRate(offering, diskOffering));
+    }
+
+    @Override
+    public DiskTO getDiskWithThrottling(final DataTO volTO, final Volume.Type 
volumeType, final long deviceId, final String path, final long offeringId, 
final long diskOfferingId) {
+        DiskTO disk = null;
+        if (volTO != null && volTO instanceof VolumeObjectTO) {
+            VolumeObjectTO volumeTO = (VolumeObjectTO) volTO;
+            ServiceOffering offering = 
_entityMgr.findById(ServiceOffering.class, offeringId);
+            DiskOffering diskOffering = 
_entityMgr.findById(DiskOffering.class, diskOfferingId);
+            if (volumeType == Volume.Type.ROOT) {
+                setVolumeObjectTOThrottling(volumeTO, offering, diskOffering);
+            } else {
+                setVolumeObjectTOThrottling(volumeTO, null, diskOffering);
+            }
+            disk = new DiskTO(volumeTO, deviceId, path, volumeType);
+        } else {
+            disk = new DiskTO(volTO, deviceId, path, volumeType);
+        }
+        return disk;
+    }
+
+    private void setVolumeObjectTOThrottling(VolumeObjectTO volumeTO, final 
ServiceOffering offering, final DiskOffering diskOffering) {
+        volumeTO.setBytesReadRate(getDiskBytesReadRate(offering, 
diskOffering));
+        volumeTO.setBytesWriteRate(getDiskBytesWriteRate(offering, 
diskOffering));
+        volumeTO.setIopsReadRate(getDiskIopsReadRate(offering, diskOffering));
+        volumeTO.setIopsWriteRate(getDiskIopsWriteRate(offering, 
diskOffering));
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/976b3b7d/server/src/com/cloud/storage/VolumeApiServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java 
b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
index 4c3de3e..9243503 100644
--- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java
@@ -251,6 +251,8 @@ public class VolumeApiServiceImpl extends ManagerBase 
implements VolumeApiServic
     @Inject
     UserVmManager _userVmMgr;
     protected Gson _gson;
+    @Inject
+    StorageManager storageMgr;
 
     private List<StoragePoolAllocator> _storagePoolAllocators;
 
@@ -2479,7 +2481,8 @@ public class VolumeApiServiceImpl extends ManagerBase 
implements VolumeApiServic
 
             deviceId = getDeviceId(vm.getId(), deviceId);
 
-            DiskTO disk = new DiskTO(volTO, deviceId, 
volumeToAttach.getPath(), volumeToAttach.getVolumeType());
+            DiskTO disk = storageMgr.getDiskWithThrottling(volTO, 
volumeToAttach.getVolumeType(), deviceId, volumeToAttach.getPath(),
+                    vm.getServiceOfferingId(), 
volumeToAttach.getDiskOfferingId());
 
             AttachCommand cmd = new AttachCommand(disk, vm.getInstanceName());
 

Reply via email to