cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From weiz...@apache.org
Subject [49/50] [abbrv] git commit: updated refs/heads/disk_io_throttling to 8b8a0d3
Date Mon, 10 Jun 2013 17:27:43 GMT
CLOUDSTACK-1301: VM Disk I/O Throttling on Bps/IOps


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

Branch: refs/heads/disk_io_throttling
Commit: 869a6b0ce305b70c4be72bd5d03866310c4313cc
Parents: 080bb76
Author: Wei Zhou <w.zhou@leaseweb.com>
Authored: Mon Jun 10 19:25:49 2013 +0200
Committer: Wei Zhou <w.zhou@leaseweb.com>
Committed: Mon Jun 10 19:25:49 2013 +0200

----------------------------------------------------------------------
 api/src/com/cloud/agent/api/to/VolumeTO.java    |  45 +++--
 api/src/com/cloud/offering/DiskOffering.java    |  22 ++-
 api/src/com/cloud/vm/DiskProfile.java           |  44 +++--
 .../org/apache/cloudstack/api/ApiConstants.java |   4 +
 .../admin/offering/CreateDiskOfferingCmd.java   |  33 +++-
 .../offering/CreateServiceOfferingCmd.java      |  30 +++-
 .../api/response/DiskOfferingResponse.java      |  34 ++--
 .../api/response/ServiceOfferingResponse.java   |  32 +++-
 .../cloudstack/api/response/VolumeResponse.java |  46 +++++-
 .../classes/resources/messages.properties       |   6 +-
 .../cloud/agent/api/AttachVolumeCommand.java    |  44 +++--
 .../src/com/cloud/storage/DiskOfferingVO.java   |  44 +++--
 .../kvm/resource/LibvirtComputingResource.java  |  34 ++--
 .../kvm/resource/LibvirtDomainXMLParser.java    |  26 ++-
 .../hypervisor/kvm/resource/LibvirtVMDef.java   |  39 +++--
 .../api/query/dao/DiskOfferingJoinDaoImpl.java  |   7 +-
 .../query/dao/ServiceOfferingJoinDaoImpl.java   |   6 +-
 .../cloud/api/query/dao/VolumeJoinDaoImpl.java  |   7 +-
 .../cloud/api/query/vo/DiskOfferingJoinVO.java  |  45 +++--
 .../api/query/vo/ServiceOfferingJoinVO.java     |  45 +++--
 .../com/cloud/api/query/vo/VolumeJoinVO.java    |  45 +++--
 server/src/com/cloud/configuration/Config.java  |   6 +-
 .../configuration/ConfigurationManager.java     |  14 +-
 .../configuration/ConfigurationManagerImpl.java |  43 +++--
 .../src/com/cloud/storage/StorageManager.java   |   8 +-
 .../com/cloud/storage/StorageManagerImpl.java   |  67 ++++++--
 .../com/cloud/storage/VolumeManagerImpl.java    |  67 ++++++--
 server/src/com/cloud/test/DatabaseConfig.java   |  34 +++-
 .../cloud/vpc/MockConfigurationManagerImpl.java |   6 +-
 setup/db/db/schema-410to420.sql                 |  38 +++--
 ui/dictionary.jsp                               |   6 +-
 ui/scripts/configuration.js                     | 163 +++++++++++++++----
 32 files changed, 808 insertions(+), 282 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/api/src/com/cloud/agent/api/to/VolumeTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/VolumeTO.java b/api/src/com/cloud/agent/api/to/VolumeTO.java
index 8b3a6be..b95aa1d 100644
--- a/api/src/com/cloud/agent/api/to/VolumeTO.java
+++ b/api/src/com/cloud/agent/api/to/VolumeTO.java
@@ -37,8 +37,10 @@ public class VolumeTO implements InternalIdentity {
     private long deviceId;
     private String chainInfo;
     private String guestOsType;
-    private long bytesRate;
-    private long iopsRate;
+    private long bytesReadRate;
+    private long bytesWriteRate;
+    private long iopsReadRate;
+    private long iopsWriteRate;
 
     public VolumeTO(long id, Volume.Type type, StoragePoolType poolType, String poolUuid, String name, String mountPoint, String path, long size, String chainInfo) {
         this.id = id;
@@ -136,19 +138,36 @@ public class VolumeTO implements InternalIdentity {
         return new StringBuilder("Vol[").append(id).append("|").append(type).append("|").append(path).append("|").append(size).append("]").toString();
     }
     
-    public void setBytesRate(long bytesRate) {
-        this.bytesRate = bytesRate;
+    public void setBytesReadRate(long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
     }
-    
-    public long getBytesRate() {
-        return bytesRate;
+
+    public long getBytesReadRate() {
+        return bytesReadRate;
     }
-    
-    public void setIopsRate(long iopsRate) {
-        this.iopsRate = iopsRate;
+
+    public void setBytesWriteRate(long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
     }
-    
-    public long getIopsRate() {
-        return iopsRate;
+
+    public long getBytesWriteRate() {
+        return bytesWriteRate;
+    }
+
+    public void setIopsReadRate(long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
     }
+
+    public long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    public void setIopsWriteRate(long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
+    }
+
+    public long getIopsWriteRate() {
+        return iopsWriteRate;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/api/src/com/cloud/offering/DiskOffering.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/offering/DiskOffering.java b/api/src/com/cloud/offering/DiskOffering.java
index 1618db9..0c119fc 100644
--- a/api/src/com/cloud/offering/DiskOffering.java
+++ b/api/src/com/cloud/offering/DiskOffering.java
@@ -53,11 +53,19 @@ public interface DiskOffering extends InfrastructureEntity, Identity, InternalId
 
     void setDiskSize(long diskSize);
     
-    void setBytesRate(long bytesRate);
-    
-    long getBytesRate();
-    
-    void setIopsRate(long iopsRate);
-    
-    long getIopsRate();
+    void setBytesReadRate(long bytesReadRate);
+
+    long getBytesReadRate();
+
+    void setBytesWriteRate(long bytesWriteRate);
+
+    long getBytesWriteRate();
+
+    void setIopsReadRate(long iopsReadRate);
+
+    long getIopsReadRate();
+
+    void setIopsWriteRate(long iopsWriteRate);
+
+    long getIopsWriteRate();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/api/src/com/cloud/vm/DiskProfile.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/vm/DiskProfile.java b/api/src/com/cloud/vm/DiskProfile.java
index 2c77006..90fb71e 100644
--- a/api/src/com/cloud/vm/DiskProfile.java
+++ b/api/src/com/cloud/vm/DiskProfile.java
@@ -35,8 +35,10 @@ public class DiskProfile {
     private Long templateId;
     private long volumeId;
     private String path;
-    private long bytesRate;
-    private long iopsRate;
+    private long bytesReadRate;
+    private long bytesWriteRate;
+    private long iopsReadRate;
+    private long iopsWriteRate;
 
     private HypervisorType hyperType;
 
@@ -157,19 +159,35 @@ public class DiskProfile {
     	this.size = size;
     }
     
-    public void setBytesRate(long bytesRate) {
-        this.bytesRate = bytesRate;
+    public void setBytesReadRate(long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
     }
-    
-    public long getBytesRate() {
-        return bytesRate;
+
+    public long getBytesReadRate() {
+        return bytesReadRate;
     }
-    
-    public void setIopsRate(long iopsRate) {
-        this.iopsRate = iopsRate;
+
+    public void setBytesWriteRate(long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
     }
-    
-    public long getIopsRate() {
-        return iopsRate;
+
+    public long getBytesWriteRate() {
+        return bytesWriteRate;
+    }
+
+    public void setIopsReadRate(long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
+    }
+
+    public long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    public void setIopsWriteRate(long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
+    }
+
+    public long getIopsWriteRate() {
+        return iopsWriteRate;
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index ab1402c..1704ca3 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -31,6 +31,8 @@ public class ApiConstants {
     public static final String BOOTABLE = "bootable";
     public static final String BIND_DN = "binddn";
     public static final String BIND_PASSWORD = "bindpass";
+    public static final String BYTES_READ_RATE = "bytesreadrate";
+    public static final String BYTES_WRITE_RATE = "byteswriterate";
     public static final String CATEGORY = "category";
     public static final String CERTIFICATE = "certificate";
     public static final String PRIVATE_KEY = "privatekey";
@@ -104,6 +106,8 @@ public class ApiConstants {
     public static final String INTERNAL_DNS1 = "internaldns1";
     public static final String INTERNAL_DNS2 = "internaldns2";
     public static final String INTERVAL_TYPE = "intervaltype";
+    public static final String IOPS_READ_RATE = "iopsreadrate";
+    public static final String IOPS_WRITE_RATE = "iopswriterate";
     public static final String IP_ADDRESS = "ipaddress";
     public static final String IP6_ADDRESS = "ip6address";
     public static final String IP_ADDRESS_ID = "ipaddressid";

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
index 848d158..47ec365 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateDiskOfferingCmd.java
@@ -62,11 +62,17 @@ public class CreateDiskOfferingCmd extends BaseCmd {
     @Parameter(name=ApiConstants.STORAGE_TYPE, type=CommandType.STRING, description="the storage type of the disk offering. Values are local and shared.")
     private String storageType = ServiceOffering.StorageType.shared.toString();
     
-    @Parameter(name="bytesRate", type=CommandType.LONG, required=false, description="bytes rate of the disk offering")
-    private Long bytesRate;
+    @Parameter(name=ApiConstants.BYTES_READ_RATE, type=CommandType.LONG, required=false, description="bytes read rate of the disk offering")
+    private Long bytesReadRate;
 
-    @Parameter(name="iopsRate", type=CommandType.LONG, required=false, description="io requests rate of the disk offering")
-    private Long iopsRate;
+    @Parameter(name=ApiConstants.BYTES_WRITE_RATE, type=CommandType.LONG, required=false, description="bytes write rate of the disk offering")
+    private Long bytesWriteRate;
+
+    @Parameter(name=ApiConstants.IOPS_READ_RATE, type=CommandType.LONG, required=false, description="io requests read rate of the disk offering")
+    private Long iopsReadRate;
+
+    @Parameter(name=ApiConstants.IOPS_WRITE_RATE, type=CommandType.LONG, required=false, description="io requests write rate of the disk offering")
+    private Long iopsWriteRate;
 
     @Parameter(name=ApiConstants.DISPLAY_OFFERING, type=CommandType.BOOLEAN, description="an optional field, whether to display the offering to the end user or not.")
     private Boolean displayOffering;
@@ -99,12 +105,21 @@ public class CreateDiskOfferingCmd extends BaseCmd {
         return domainId;
     }
     
-    public Long getBytesRate() {
-        return bytesRate;
+    public long getBytesReadRate() {
+        return bytesReadRate;
+        //return (bytesReadRate == null) || (bytesReadRate < 0) ? 0 : bytesReadRate;
     }
-    
-    public Long getIopsRate() {
-        return iopsRate;
+
+    public long getBytesWriteRate() {
+        return (bytesWriteRate == null) || (bytesWriteRate < 0) ? 0 : bytesWriteRate;
+    }
+
+    public long getIopsReadRate() {
+        return (iopsReadRate == null) || (iopsReadRate < 0) ? 0 : iopsReadRate;
+    }
+
+    public long getIopsWriteRate() {
+        return (iopsWriteRate == null) || (iopsWriteRate < 0) ? 0 : iopsWriteRate;
     }
 
     public String getStorageType() {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
index 28f1a68..6efac46 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
@@ -93,11 +93,17 @@ public class CreateServiceOfferingCmd extends BaseCmd {
     @Parameter(name = ApiConstants.SERVICE_OFFERING_DETAILS, type = CommandType.MAP, description = "details for planner, used to store specific parameters")
     private Map<String, String> details;
 
-    @Parameter(name="bytesRate", type=CommandType.LONG, required=false, description="bytes rate of the disk offering")
-    private Long bytesRate;
+    @Parameter(name=ApiConstants.BYTES_READ_RATE, type=CommandType.LONG, required=false, description="bytes read rate of the disk offering")
+    private Long bytesReadRate;
 
-    @Parameter(name="iopsRate", type=CommandType.LONG, required=false, description="io requests rate of the disk offering")
-    private Long iopsRate;
+    @Parameter(name=ApiConstants.BYTES_WRITE_RATE, type=CommandType.LONG, required=false, description="bytes write rate of the disk offering")
+    private Long bytesWriteRate;
+
+    @Parameter(name=ApiConstants.IOPS_READ_RATE, type=CommandType.LONG, required=false, description="io requests read rate of the disk offering")
+    private Long iopsReadRate;
+
+    @Parameter(name=ApiConstants.IOPS_WRITE_RATE, type=CommandType.LONG, required=false, description="io requests write rate of the disk offering")
+    private Long iopsWriteRate;
 
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
@@ -177,12 +183,20 @@ public class CreateServiceOfferingCmd extends BaseCmd {
         return params;
     }
 
-    public long getBytesRate() {
-       return bytesRate;
+    public long getBytesReadRate() {
+        return (bytesReadRate == null) || (bytesReadRate < 0) ? 0 : bytesReadRate;
+    }
+
+    public long getBytesWriteRate() {
+        return (bytesWriteRate == null) || (bytesWriteRate < 0) ? 0 : bytesWriteRate;
+    }
+
+    public long getIopsReadRate() {
+        return (iopsReadRate == null) || (iopsReadRate < 0) ? 0 : iopsReadRate;
     }
 
-    public long getIopsRate() {
-        return iopsRate;
+    public long getIopsWriteRate() {
+        return (iopsWriteRate == null) || (iopsWriteRate < 0) ? 0 : iopsWriteRate;
     }
 
     /////////////////////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java
index 8d4bec3..9cd2918 100644
--- a/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/DiskOfferingResponse.java
@@ -58,11 +58,17 @@ public class DiskOfferingResponse extends BaseResponse {
     @SerializedName("storagetype") @Param(description="the storage type for this disk offering")
     private String storageType;
     
-    @SerializedName("diskBytesRate") @Param(description="bytes rate of the disk offering")
-    private Long bytesRate;
+    @SerializedName("diskBytesReadRate") @Param(description="bytes read rate of the disk offering")
+    private Long bytesReadRate;
 
-    @SerializedName("diskIORate") @Param(description="io requests rate of the disk offering")
-    private Long iopsRate;
+    @SerializedName("diskBytesWriteRate") @Param(description="bytes write rate of the disk offering")
+    private Long bytesWriteRate;
+
+    @SerializedName("diskIopsReadRate") @Param(description="io requests read rate of the disk offering")
+    private Long iopsReadRate;
+
+    @SerializedName("diskIopsWriteRate") @Param(description="io requests write rate of the disk offering")
+    private Long iopsWriteRate;
 
     @SerializedName("displayoffering") @Param(description="whether to display the offering to the end user or not.")
     private Boolean displayOffering;
@@ -155,12 +161,20 @@ public class DiskOfferingResponse extends BaseResponse {
     public void setStorageType(String storageType) {
         this.storageType = storageType;
     }
-    
-    public void setBytesRate(long bytesRate) {
-        this.bytesRate = bytesRate;
+
+    public void setBytesReadRate(long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
     }
-    
-    public void setIopsRate(long iopsRate) {
-        this.iopsRate = iopsRate;
+
+    public void setBytesWriteRate(long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
+    }
+
+    public void setIopsReadRate(long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
     }
+
+    public void setIopsWriteRate(long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
+    }    
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
index b98fd4d..a56e91a 100644
--- a/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/ServiceOfferingResponse.java
@@ -87,11 +87,17 @@ public class ServiceOfferingResponse extends BaseResponse {
     @SerializedName(ApiConstants.NETWORKRATE) @Param(description="data transfer rate in megabits per second allowed.")
     private Integer networkRate;
     
-    @SerializedName("diskBytesRate") @Param(description="bytes rate of the service offering")
-    private Long bytesRate;
+    @SerializedName("diskBytesReadRate") @Param(description="bytes read rate of the service offering")
+    private Long bytesReadRate;
 
-    @SerializedName("diskIORate") @Param(description="io requests rate of the service offering")
-    private Long iopsRate;
+    @SerializedName("diskBytesWriteRate") @Param(description="bytes write rate of the service offering")
+    private Long bytesWriteRate;
+
+    @SerializedName("diskIopsReadRate") @Param(description="io requests read rate of the service offering")
+    private Long iopsReadRate;
+
+    @SerializedName("diskIopsWriteRate") @Param(description="io requests write rate of the service offering")
+    private Long iopsWriteRate;
 
     @SerializedName(ApiConstants.DEPLOYMENT_PLANNER) @Param(description="deployment strategy used to deploy VM.")
     private String deploymentPlanner;
@@ -255,11 +261,19 @@ public class ServiceOfferingResponse extends BaseResponse {
         this.isVolatile = isVolatile;
     }
     
-    public void setBytesRate(long bytesRate) {
-        this.bytesRate = bytesRate;
+    public void setBytesReadRate(long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
     }
-    
-    public void setIopsRate(long iopsRate) {
-        this.iopsRate = iopsRate;
+
+    public void setBytesWriteRate(long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
+    }
+
+    public void setIopsReadRate(long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
+    }
+
+    public void setIopsWriteRate(long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
index 8e38d85..dab5b3e 100644
--- a/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/VolumeResponse.java
@@ -110,11 +110,17 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity
     @Param(description = "shared or local storage")
     private String storageType;
 
-    @SerializedName("diskBytesRate") @Param(description="bytes rate of the disk offering")
-    private Long bytesRate;
+    @SerializedName("diskBytesReadRate") @Param(description="bytes read rate of the disk volume")
+    private Long bytesReadRate;
 
-    @SerializedName("diskIORate") @Param(description="io requests rate of the disk offering")
-    private Long iopsRate;
+    @SerializedName("diskBytesWriteRate") @Param(description="bytes write rate of the disk volume")
+    private Long bytesWriteRate;
+
+    @SerializedName("diskIopsReadRate") @Param(description="io requests read rate of the disk volume")
+    private Long iopsReadRate;
+
+    @SerializedName("diskIopsWriteRate") @Param(description="io requests write rate of the disk volume")
+    private Long iopsWriteRate;
 
     @SerializedName(ApiConstants.HYPERVISOR)
     @Param(description = "Hypervisor the volume belongs to")
@@ -264,12 +270,36 @@ public class VolumeResponse extends BaseResponse implements ControlledViewEntity
         this.storageType = storageType;
     }
 
-    public void setBytesRate(long bytesRate) {
-        this.bytesRate = bytesRate;
+    public void setBytesReadRate(long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
+    }
+
+    public long getBytesReadRate() {
+        return bytesReadRate;
+    }
+
+    public void setBytesWriteRate(long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
+    }
+
+    public long getBytesWriteRate() {
+        return bytesWriteRate;
+    }
+
+    public void setIopsReadRate(long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
+    }
+
+    public long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    public void setIopsWriteRate(long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
     }
 
-    public void setIopsRate(long iopsRate) {
-        this.iopsRate = iopsRate;
+    public long getIopsWriteRate() {
+        return iopsWriteRate;
     }
 
     public void setHypervisor(String hypervisor) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/client/WEB-INF/classes/resources/messages.properties
----------------------------------------------------------------------
diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties
index d0ead0e..a0a36c8 100644
--- a/client/WEB-INF/classes/resources/messages.properties
+++ b/client/WEB-INF/classes/resources/messages.properties
@@ -466,8 +466,10 @@ label.disable.vpn=Disable VPN
 label.disabled=Disabled
 label.disabling.vpn.access=Disabling VPN Access
 label.disk.allocated=Disk Allocated
-label.disk.bytes.rate=Disk Rate (BPS)
-label.disk.iops.rate=Disk Rate (IOPS)
+label.disk.bytes.read.rate=Disk Read Rate (BPS)
+label.disk.bytes.write.rate=Disk Write Rate (BPS)
+label.disk.iops.read.rate=Disk Read Rate (IOPS)
+label.disk.iops.write.rate=Disk Write Rate (IOPS)
 label.disk.offering=Disk Offering
 label.disk.read.bytes=Disk Read (Bytes)
 label.disk.read.io=Disk Read (IO)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/core/src/com/cloud/agent/api/AttachVolumeCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/AttachVolumeCommand.java b/core/src/com/cloud/agent/api/AttachVolumeCommand.java
index 101c254..74480cc 100644
--- a/core/src/com/cloud/agent/api/AttachVolumeCommand.java
+++ b/core/src/com/cloud/agent/api/AttachVolumeCommand.java
@@ -29,8 +29,10 @@ public class AttachVolumeCommand extends Command {
 	String volumeName;
 	Long deviceId;
 	String chainInfo;
-    long bytesRate;
-    long iopsRate;
+    long bytesReadRate;
+    long bytesWriteRate;
+    long iopsReadRate;
+    long iopsWriteRate;
 
 	protected AttachVolumeCommand() {
 	}
@@ -99,19 +101,35 @@ public class AttachVolumeCommand extends Command {
     	return chainInfo;
     }
     
-    public void setBytesRate(long bytesRate) {
-        this.bytesRate = bytesRate;
+    public void setBytesReadRate(long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
     }
-    
-    public long getBytesRate() {
-        return bytesRate;
+
+    public long getBytesReadRate() {
+        return bytesReadRate;
     }
-    
-    public void setIopsRate(long iopsRate) {
-        this.iopsRate = iopsRate;
+
+    public void setBytesWriteRate(long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
     }
-    
-    public long getIopsRate() {
-        return iopsRate;
+
+    public long getBytesWriteRate() {
+        return bytesWriteRate;
+    }
+
+    public void setIopsReadRate(long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
+    }
+
+    public long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    public void setIopsWriteRate(long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
+    }
+
+    public long getIopsWriteRate() {
+        return iopsWriteRate;
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/engine/schema/src/com/cloud/storage/DiskOfferingVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java
index 239ddb0..16e11af 100755
--- a/engine/schema/src/com/cloud/storage/DiskOfferingVO.java
+++ b/engine/schema/src/com/cloud/storage/DiskOfferingVO.java
@@ -100,12 +100,17 @@ public class DiskOfferingVO implements DiskOffering {
     @Column(name="sort_key")
     int sortKey;
     
-    @Column(name="bytes_rate")
-    long bytesRate;
+    @Column(name="bytes_read_rate")
+    long bytesReadRate;
 
-    @Column(name="iops_rate")
-    long iopsRate;
+    @Column(name="bytes_write_rate")
+    long bytesWriteRate;
 
+    @Column(name="iops_read_rate")
+    long iopsReadRate;
+
+    @Column(name="iops_write_rate")
+    long iopsWriteRate;
 
     @Column(name="display_offering")
     boolean displayOffering;
@@ -335,20 +340,35 @@ public class DiskOfferingVO implements DiskOffering {
         this.displayOffering = displayOffering;
     }
 
-    public void setBytesRate(long bytesRate) {
-       this.bytesRate = bytesRate;
+    public void setBytesReadRate(long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
+    }
+
+    public long getBytesReadRate() {
+        return bytesReadRate;
+    }
+
+    public void setBytesWriteRate(long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
+    }
+
+    public long getBytesWriteRate() {
+        return bytesWriteRate;
     }
 
-    public long getBytesRate() {
-       return bytesRate;
+    public void setIopsReadRate(long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
     }
 
-    public void setIopsRate(long iopsRate) {
-        this.iopsRate = iopsRate;
+    public long getIopsReadRate() {
+        return iopsReadRate;
     }
 
-    public long getIopsRate() {
-        return iopsRate;
+    public void setIopsWriteRate(long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
     }
 
+    public long getIopsWriteRate() {
+        return iopsWriteRate;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 05882d4..690c15f 100755
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -1411,8 +1411,10 @@ ServerResource {
             VolumeTO volume = new VolumeTO(cmd.getVolumeId(), dskch.getType(),
                     pool.getType(), pool.getUuid(), pool.getPath(),
                     vol.getName(), vol.getName(), disksize, null);
-            volume.setBytesRate(dskch.getBytesRate());
-            volume.setIopsRate(dskch.getIopsRate());
+            volume.setBytesReadRate(dskch.getBytesReadRate());
+            volume.setBytesWriteRate(dskch.getBytesWriteRate());
+            volume.setIopsReadRate(dskch.getIopsReadRate());
+            volume.setIopsWriteRate(dskch.getIopsWriteRate());
             return new CreateAnswer(cmd, volume);
         } catch (CloudRuntimeException e) {
             s_logger.debug("Failed to create volume: " + e.toString());
@@ -2628,7 +2630,7 @@ ServerResource {
                     cmd.getPoolUuid());
             KVMPhysicalDisk disk = primary.getPhysicalDisk(cmd.getVolumePath());
             attachOrDetachDisk(conn, cmd.getAttach(), cmd.getVmName(), disk,
-                    cmd.getDeviceId().intValue(), cmd.getBytesRate(), cmd.getIopsRate());
+                    cmd.getDeviceId().intValue(), cmd.getBytesReadRate(), cmd.getBytesWriteRate(), cmd.getIopsReadRate(), cmd.getIopsWriteRate());
         } catch (LibvirtException e) {
             return new AttachVolumeAnswer(cmd, e.toString());
         } catch (InternalErrorException e) {
@@ -3497,10 +3499,14 @@ ServerResource {
 
             }
             
-            if (volume.getBytesRate() > 0)
-                disk.setBytesRate(volume.getBytesRate());
-            if (volume.getIopsRate() > 0)
-                disk.setIopsRate(volume.getIopsRate());
+            if (volume.getBytesReadRate() > 0)
+                disk.setBytesReadRate(volume.getBytesReadRate());
+            if (volume.getBytesWriteRate() > 0)
+                disk.setBytesWriteRate(volume.getBytesWriteRate());
+            if (volume.getIopsReadRate() > 0)
+                disk.setIopsReadRate(volume.getIopsReadRate());
+            if (volume.getIopsWriteRate() > 0)
+                disk.setIopsWriteRate(volume.getIopsWriteRate());
 
             vm.getDevices().addDevice(disk);
         }
@@ -3635,7 +3641,7 @@ ServerResource {
 
     protected synchronized String attachOrDetachDisk(Connect conn,
             boolean attach, String vmName, KVMPhysicalDisk attachingDisk,
-            int devId, long bytesRate, long iopsRate) throws LibvirtException, InternalErrorException {
+            int devId, long bytesReadRate, long bytesWriteRate, long iopsReadRate, long iopsWriteRate) throws LibvirtException, InternalErrorException {
         List<DiskDef> disks = null;
         Domain dm = null;
         DiskDef diskdef = null;
@@ -3675,10 +3681,14 @@ ServerResource {
                     diskdef.defBlockBasedDisk(attachingDisk.getPath(), devId,
                             DiskDef.diskBus.VIRTIO);
                 }
-                if (bytesRate > 0)
-                    diskdef.setBytesRate(bytesRate);
-                if (iopsRate > 0)
-                    diskdef.setIopsRate(iopsRate);
+                if (bytesReadRate > 0)
+                    diskdef.setBytesReadRate(bytesReadRate);
+                if (bytesWriteRate > 0)
+                    diskdef.setBytesWriteRate(bytesWriteRate);
+                if (iopsReadRate > 0)
+                    diskdef.setIopsReadRate(iopsReadRate);
+                if (iopsWriteRate > 0)
+                    diskdef.setIopsWriteRate(iopsWriteRate);
             }
 
             String xml = diskdef.toString();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
index cccdc39..c364cd4 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtDomainXMLParser.java
@@ -108,15 +108,25 @@ public class LibvirtDomainXMLParser {
                 
                 NodeList iotune = disk.getElementsByTagName("iotune");
                 if ((iotune != null) && (iotune.getLength() !=0)) {
-                    String bytesRateStr = getTagValue("total_bytes_sec", (Element)iotune.item(0));
-                    if (bytesRateStr != null) {
-                        Long bytesRate = Long.parseLong(bytesRateStr);
-                        def.setBytesRate(bytesRate);
+                    String bytesReadRateStr = getTagValue("read_bytes_sec", (Element)iotune.item(0));
+                    if (bytesReadRateStr != null) {
+                        Long bytesReadRate = Long.parseLong(bytesReadRateStr);
+                        def.setBytesReadRate(bytesReadRate);
                     }
-                    String iopsRateStr = getTagValue("total_iops_sec", (Element)iotune.item(0));
-                    if (iopsRateStr != null) {
-                        Long iopsRate = Long.parseLong(iopsRateStr);
-                        def.setIopsRate(iopsRate);
+                    String bytesWriteRateStr = getTagValue("write_bytes_sec", (Element)iotune.item(0));
+                    if (bytesWriteRateStr != null) {
+                        Long bytesWriteRate = Long.parseLong(bytesWriteRateStr);
+                        def.setBytesWriteRate(bytesWriteRate);
+                    }
+                    String iopsReadRateStr = getTagValue("read_iops_sec", (Element)iotune.item(0));
+                    if (iopsReadRateStr != null) {
+                        Long iopsReadRate = Long.parseLong(iopsReadRateStr);
+                        def.setIopsReadRate(iopsReadRate);
+                    }
+                    String iopsWriteRateStr = getTagValue("write_iops_sec", (Element)iotune.item(0));
+                    if (iopsWriteRateStr != null) {
+                        Long iopsWriteRate = Long.parseLong(iopsWriteRateStr);
+                        def.setIopsWriteRate(iopsWriteRate);
                     }
                 }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
index 2959821..a347fee 100644
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtVMDef.java
@@ -441,8 +441,10 @@ public class LibvirtVMDef {
         private boolean _readonly = false;
         private boolean _shareable = false;
         private boolean _deferAttach = false;
-        private Long _bytesRate;
-        private Long _iopsRate;
+        private Long _bytesReadRate;
+        private Long _bytesWriteRate;
+        private Long _iopsReadRate;
+        private Long _iopsWriteRate;
 
         public void setDeviceType(deviceType deviceType) {
             _deviceType = deviceType;
@@ -588,12 +590,20 @@ public class LibvirtVMDef {
             return suffix - 'a';
         }
         
-        public void setBytesRate(Long bytesRate) {
-            _bytesRate = bytesRate;
+        public void setBytesReadRate(long bytesReadRate) {
+            _bytesReadRate = bytesReadRate;
         }
-        
-        public void setIopsRate(Long iopsRate) {
-            _iopsRate = iopsRate;
+
+        public void setBytesWriteRate(long bytesWriteRate) {
+            _bytesWriteRate = bytesWriteRate;
+        }
+
+        public void setIopsReadRate(long iopsReadRate) {
+            _iopsReadRate = iopsReadRate;
+        }
+
+        public void setIopsWriteRate(long iopsWriteRate) {
+            _iopsWriteRate = iopsWriteRate;
         }
 
         @Override
@@ -643,7 +653,8 @@ public class LibvirtVMDef {
             String libvirtVersion = Script.runSimpleBashScript("virsh version |grep API | awk '{print $4}'");
             String qemuVersion = Script.runSimpleBashScript("virsh version |grep hypervisor | awk '{print $4}'");
             if ((_deviceType != deviceType.CDROM) && (libvirtVersion != null) && (qemuVersion != null) 
-                    && (((_bytesRate != null) && (_bytesRate > 0)) || ((_iopsRate != null) && (_iopsRate > 0)))) { // not CDROM, from libvirt 0.9.8 and QEMU 1.1.0
+                    && (((_bytesReadRate != null) && (_bytesReadRate > 0)) || ((_bytesWriteRate != null) && (_bytesWriteRate > 0))
+                    || ((_iopsReadRate != null) && (_iopsReadRate > 0)) || ((_iopsWriteRate != null) && (_iopsWriteRate > 0)) )) { // not CDROM, from libvirt 0.9.8 and QEMU 1.1.0
                 String[] libvirtVersions = libvirtVersion.split("\\.");
                 String[] qemuVersions = qemuVersion.split("\\.");
                 if (((libvirtVersions != null) && (libvirtVersions.length == 3) && ((Integer.valueOf(libvirtVersions[0]) > 0)
@@ -653,10 +664,14 @@ public class LibvirtVMDef {
                         || ((Integer.valueOf(qemuVersions[0]) == 1) && (Integer.valueOf(qemuVersions[1]) > 1))
                         || ((Integer.valueOf(qemuVersions[0]) == 1) && (Integer.valueOf(qemuVersions[1]) == 1) && (Integer.valueOf(qemuVersions[1]) >= 0))))) {
                     diskBuilder.append("<iotune>\n");
-                    if ((_bytesRate != null) && (_bytesRate > 0))
-                        diskBuilder.append("<total_bytes_sec>" + _bytesRate + "</total_bytes_sec>\n");
-                    if ((_iopsRate != null) && (_iopsRate > 0))
-                        diskBuilder.append("<total_iops_sec>" + _iopsRate + "</total_iops_sec>\n");
+                    if ((_bytesReadRate != null) && (_bytesReadRate > 0))
+                        diskBuilder.append("<read_bytes_sec>" + _bytesReadRate + "</read_bytes_sec>\n");
+                    if ((_bytesWriteRate != null) && (_bytesWriteRate > 0))
+                        diskBuilder.append("<write_bytes_sec>" + _bytesWriteRate + "</write_bytes_sec>\n");
+                    if ((_iopsReadRate != null) && (_iopsReadRate > 0))
+                        diskBuilder.append("<read_iops_sec>" + _iopsReadRate + "</read_iops_sec>\n");
+                    if ((_iopsWriteRate != null) && (_iopsWriteRate > 0))
+                        diskBuilder.append("<write_iops_sec>" + _iopsWriteRate + "</write_iops_sec>\n");
                     diskBuilder.append("</iotune>\n");
                 }
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java
index bfae58b..7022ee6 100644
--- a/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java
+++ b/server/src/com/cloud/api/query/dao/DiskOfferingJoinDaoImpl.java
@@ -75,9 +75,12 @@ public class DiskOfferingJoinDaoImpl extends GenericDaoBase<DiskOfferingJoinVO,
         diskOfferingResponse.setTags(offering.getTags());
         diskOfferingResponse.setCustomized(offering.isCustomized());
         diskOfferingResponse.setStorageType(offering.isUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared.toString());
+        diskOfferingResponse.setBytesReadRate(offering.getBytesReadRate());
+        diskOfferingResponse.setBytesWriteRate(offering.getBytesWriteRate());
+        diskOfferingResponse.setIopsReadRate(offering.getIopsReadRate());
+        diskOfferingResponse.setIopsWriteRate(offering.getIopsWriteRate());
         diskOfferingResponse.setObjectName("diskoffering");
-        diskOfferingResponse.setBytesRate(offering.getBytesRate());
-        diskOfferingResponse.setIopsRate(offering.getIopsRate());
+
         return diskOfferingResponse;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
index ec67175..6f6e277 100644
--- a/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
+++ b/server/src/com/cloud/api/query/dao/ServiceOfferingJoinDaoImpl.java
@@ -75,9 +75,11 @@ public class ServiceOfferingJoinDaoImpl extends GenericDaoBase<ServiceOfferingJo
         offeringResponse.setNetworkRate(offering.getRateMbps());
         offeringResponse.setHostTag(offering.getHostTag());
         offeringResponse.setDeploymentPlanner(offering.getDeploymentPlanner());
+        offeringResponse.setBytesReadRate(offering.getBytesReadRate());
+        offeringResponse.setBytesWriteRate(offering.getBytesWriteRate());
+        offeringResponse.setIopsReadRate(offering.getIopsReadRate());
+        offeringResponse.setIopsWriteRate(offering.getIopsWriteRate());
         offeringResponse.setObjectName("serviceoffering");
-        offeringResponse.setBytesRate(offering.getBytesRate());
-        offeringResponse.setIopsRate(offering.getIopsRate());
 
         return offeringResponse;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
index e65f78a..453e82e 100644
--- a/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
+++ b/server/src/com/cloud/api/query/dao/VolumeJoinDaoImpl.java
@@ -160,8 +160,11 @@ public class VolumeJoinDaoImpl extends GenericDaoBase<VolumeJoinVO, Long> implem
             }
             volResponse.setStorageType(volume.isUseLocalStorage() ? ServiceOffering.StorageType.local.toString() : ServiceOffering.StorageType.shared
                     .toString());
-            volResponse.setBytesRate(volume.getBytesRate());
-            volResponse.setIopsRate(volume.getIopsRate());
+            volResponse.setBytesReadRate(volume.getBytesReadRate());
+            volResponse.setBytesWriteRate(volume.getBytesReadRate());
+            volResponse.setIopsReadRate(volume.getIopsWriteRate());
+            volResponse.setIopsWriteRate(volume.getIopsWriteRate());
+
         }
         Long poolId = volume.getPoolId();
         String poolName = (poolId == null) ? "none" : volume.getPoolName();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java b/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java
index c44c171..baebc48 100644
--- a/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java
+++ b/server/src/com/cloud/api/query/vo/DiskOfferingJoinVO.java
@@ -64,11 +64,17 @@ public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity,
     @Column(name="sort_key")
     int sortKey;
 
-    @Column(name="bytes_rate")
-    long bytesRate;
+    @Column(name="bytes_read_rate")
+    long bytesReadRate;
 
-    @Column(name="iops_rate")
-    long iopsRate;
+    @Column(name="bytes_write_rate")
+    long bytesWriteRate;
+
+    @Column(name="iops_read_rate")
+    long iopsReadRate;
+
+    @Column(name="iops_write_rate")
+    long iopsWriteRate;
 
     @Column(name="type")
     Type type;
@@ -245,21 +251,36 @@ public class DiskOfferingJoinVO extends BaseViewVO implements InternalIdentity,
         this.type = type;
     }
 
-    public void setBytesRate(long bytesRate) {
-       this.bytesRate = bytesRate;
+    public void setBytesReadRate(long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
     }
 
-    public long getBytesRate() {
-       return bytesRate;
+    public long getBytesReadRate() {
+        return bytesReadRate;
     }
 
-    public void setIopsRate(long iopsRate) {
-        this.iopsRate = iopsRate;
+    public void setBytesWriteRate(long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
     }
 
-    public long getIopsRate() {
-        return iopsRate;
+    public long getBytesWriteRate() {
+        return bytesWriteRate;
     }
 
+    public void setIopsReadRate(long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
+    }
+
+    public long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    public void setIopsWriteRate(long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
+    }
+
+    public long getIopsWriteRate() {
+        return iopsWriteRate;
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java b/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java
index 89c665e..4011c6a 100644
--- a/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java
+++ b/server/src/com/cloud/api/query/vo/ServiceOfferingJoinVO.java
@@ -90,11 +90,17 @@ public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentit
     @Column(name="sort_key")
     int sortKey;
 
-    @Column(name="bytes_rate")
-    long bytesRate;
+    @Column(name="bytes_read_rate")
+    long bytesReadRate;
 
-    @Column(name="iops_rate")
-    long iopsRate;
+    @Column(name="bytes_write_rate")
+    long bytesWriteRate;
+
+    @Column(name="iops_read_rate")
+    long iopsReadRate;
+
+    @Column(name="iops_write_rate")
+    long iopsWriteRate;
 
     @Column(name=GenericDao.CREATED_COLUMN)
     private Date created;
@@ -334,20 +340,35 @@ public class ServiceOfferingJoinVO extends BaseViewVO implements InternalIdentit
         this.volatileVm = volatileVm;
     }
 
-    public void setBytesRate(long bytesRate) {
-        this.bytesRate = bytesRate;
+    public void setBytesReadRate(long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
     }
 
-    public long getBytesRate() {
-        return bytesRate;
+    public long getBytesReadRate() {
+        return bytesReadRate;
     }
 
-    public void setIopsRate(long iopsRate) {
-        this.iopsRate = iopsRate;
+    public void setBytesWriteRate(long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
     }
 
-    public long getIopsRate() {
-        return iopsRate;
+    public long getBytesWriteRate() {
+        return bytesWriteRate;
     }
 
+    public void setIopsReadRate(long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
+    }
+
+    public long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    public void setIopsWriteRate(long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
+    }
+
+    public long getIopsWriteRate() {
+        return iopsWriteRate;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/server/src/com/cloud/api/query/vo/VolumeJoinVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java
index 5831659..7aeb0b3 100644
--- a/server/src/com/cloud/api/query/vo/VolumeJoinVO.java
+++ b/server/src/com/cloud/api/query/vo/VolumeJoinVO.java
@@ -184,11 +184,17 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity {
     @Column(name="use_local_storage")
     private boolean useLocalStorage;
 
-    @Column(name="bytes_rate")
-    long bytesRate;
+    @Column(name="bytes_read_rate")
+    long bytesReadRate;
 
-    @Column(name="iops_rate")
-    long iopsRate;
+    @Column(name="bytes_write_rate")
+    long bytesWriteRate;
+
+    @Column(name="iops_read_rate")
+    long iopsReadRate;
+
+    @Column(name="iops_write_rate")
+    long iopsWriteRate;
 
     @Column(name="pool_id")
     private long poolId;
@@ -748,22 +754,37 @@ public class VolumeJoinVO extends BaseViewVO implements ControlledViewEntity {
     }
 
 
-    public void setBytesRate(long bytesRate) {
-       this.bytesRate = bytesRate;
+    public void setBytesReadRate(long bytesReadRate) {
+        this.bytesReadRate = bytesReadRate;
     }
 
-    public long getBytesRate() {
-       return bytesRate;
+    public long getBytesReadRate() {
+        return bytesReadRate;
     }
 
-    public void setIopsRate(long iopsRate) {
-        this.iopsRate = iopsRate;
+    public void setBytesWriteRate(long bytesWriteRate) {
+        this.bytesWriteRate = bytesWriteRate;
     }
 
-    public long getIopsRate() {
-        return iopsRate;
+    public long getBytesWriteRate() {
+        return bytesWriteRate;
     }
 
+    public void setIopsReadRate(long iopsReadRate) {
+        this.iopsReadRate = iopsReadRate;
+    }
+
+    public long getIopsReadRate() {
+        return iopsReadRate;
+    }
+
+    public void setIopsWriteRate(long iopsWriteRate) {
+        this.iopsWriteRate = iopsWriteRate;
+    }
+
+    public long getIopsWriteRate() {
+        return iopsWriteRate;
+    }
 
     public long getPoolId() {
         return poolId;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/server/src/com/cloud/configuration/Config.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java
index d822ae2..7a2127a 100755
--- a/server/src/com/cloud/configuration/Config.java
+++ b/server/src/com/cloud/configuration/Config.java
@@ -232,8 +232,10 @@ public enum Config {
 	VmDiskStatsInterval("Advanced", ManagementServer.class, Integer.class, "vm.disk.stats.interval", "0", "Interval (in seconds) to report vm disk statistics.", null),
 	VmTransitionWaitInterval("Advanced", ManagementServer.class, Integer.class, "vm.tranisition.wait.interval", "3600", "Time (in seconds) to wait before taking over a VM in transition state", null),
 	VmDestroyForcestop("Advanced", ManagementServer.class, Boolean.class, "vm.destroy.forcestop", "false", "On destroy, force-stop takes this value ", null),
-        VmDiskThrottlingIORate("Advanced", ManagementServer.class, Integer.class, "vm.disk.throttling.iops_rate", "0", "Default disk I/O rate in requests per second allowed in User vm's disk.", null),
-        VmDiskThrottlingBytesRate("Advanced", ManagementServer.class, Integer.class, "vm.disk.throttling.bytes_rate", "0", "Default disk I/O rate in bytes per second allowed in User vm's disk.", null),
+        VmDiskThrottlingIopsReadRate("Advanced", ManagementServer.class, Integer.class, "vm.disk.throttling.iops_read_rate", "0", "Default disk I/O read rate in requests per second allowed in User vm's disk.", null),
+        VmDiskThrottlingIopsWriteRate("Advanced", ManagementServer.class, Integer.class, "vm.disk.throttling.iops_write_rate", "0", "Default disk I/O writerate in requests per second allowed in User vm's disk.", null),
+        VmDiskThrottlingBytesReadRate("Advanced", ManagementServer.class, Integer.class, "vm.disk.throttling.bytes_read_rate", "0", "Default disk I/O read rate in bytes per second allowed in User vm's disk.", null),
+        VmDiskThrottlingBytesWriteRate("Advanced", ManagementServer.class, Integer.class, "vm.disk.throttling.bytes_write_rate", "0", "Default disk I/O writerate in bytes per second allowed in User vm's disk.", null),
 
 	ControlCidr("Advanced", ManagementServer.class, String.class, "control.cidr", "169.254.0.0/16", "Changes the cidr for the control network traffic.  Defaults to using link local.  Must be unique within pods", null),
 	ControlGateway("Advanced", ManagementServer.class, String.class, "control.gateway", "169.254.0.1", "gateway for the control network traffic", null),

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/server/src/com/cloud/configuration/ConfigurationManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManager.java b/server/src/com/cloud/configuration/ConfigurationManager.java
index 975fad1..93cadfa 100755
--- a/server/src/com/cloud/configuration/ConfigurationManager.java
+++ b/server/src/com/cloud/configuration/ConfigurationManager.java
@@ -81,10 +81,15 @@ public interface ConfigurationManager extends ConfigurationService, Manager {
      * @param useVirtualNetwork
      * @param deploymentPlanner
      * @param details
+     * @param bytesReadRate
+     * @param bytesWriteRate
+     * @param iopsReadRate
+     * @param iopsWriteRate
      * @return ID
      */
     ServiceOfferingVO createServiceOffering(long userId, boolean isSystem, VirtualMachine.Type vm_typeType, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired,
-            boolean offerHA, boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate, String deploymentPlanner, Map<String, String> details, Long bytesRate, Long iopsRate);
+            boolean offerHA, boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate, String deploymentPlanner, Map<String, String> details,
+            Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate);
 
     /**
      * Creates a new disk offering
@@ -97,9 +102,14 @@ public interface ConfigurationManager extends ConfigurationService, Manager {
      * @param isCustomized
      * @param localStorageRequired
      * @param isDisplayOfferingEnabled
+     * @param bytesReadRate
+     * @param bytesWriteRate
+     * @param iopsReadRate
+     * @param iopsWriteRate
      * @return newly created disk offering
      */
-    DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled, Long bytesRate, Long iopsRate);
+    DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled,
+            Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate);
 
     /**
      * Creates a new pod

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index 0bfd286..e5dbf3a 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -2032,7 +2032,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
                 cpuNumber.intValue(), memory.intValue(), cpuSpeed.intValue(), cmd.getDisplayText(),
                 localStorageRequired, offerHA, limitCpuUse, volatileVm, cmd.getTags(), cmd.getDomainId(),
                 cmd.getHostTag(), cmd.getNetworkRate(), cmd.getDeploymentPlanner(), cmd.getDetails(),
-                cmd.getBytesRate(), cmd.getIopsRate());
+                cmd.getBytesReadRate(), cmd.getBytesWriteRate(), cmd.getIopsReadRate(), cmd.getIopsWriteRate());
     }
 
     @Override
@@ -2040,15 +2040,19 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
     public ServiceOfferingVO createServiceOffering(long userId, boolean isSystem, VirtualMachine.Type vm_type,
             String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired,
             boolean offerHA, boolean limitResourceUse, boolean volatileVm,  String tags, Long domainId, String hostTag,
-            Integer networkRate, String deploymentPlanner, Map<String, String> details, Long bytesRate, Long iopsRate) {
+            Integer networkRate, String deploymentPlanner, Map<String, String> details, Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) {
         tags = cleanupTags(tags);
         ServiceOfferingVO offering = new ServiceOfferingVO(name, cpu, ramSize, speed, networkRate, null, offerHA, limitResourceUse, volatileVm, displayText, localStorageRequired, false, tags, isSystem, vm_type,
                 domainId, hostTag, deploymentPlanner);
 
-        if ((bytesRate != null) && (bytesRate > 0))
-            offering.setBytesRate(bytesRate);
-        if ((iopsRate != null) && (iopsRate > 0))
-            offering.setIopsRate(iopsRate);
+        if (bytesReadRate != null && (bytesReadRate > 0))
+            offering.setBytesReadRate(bytesReadRate);
+        if (bytesWriteRate != null && (bytesWriteRate > 0))
+            offering.setBytesWriteRate(bytesWriteRate);
+        if (iopsReadRate != null && (iopsReadRate > 0))
+            offering.setIopsReadRate(iopsReadRate);
+        if (iopsWriteRate != null && (iopsWriteRate > 0))
+            offering.setIopsWriteRate(iopsWriteRate);
 
         if ((offering = _serviceOfferingDao.persist(offering)) != null) {
             if (details != null) {
@@ -2135,7 +2139,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_DISK_OFFERING_CREATE, eventDescription = "creating disk offering")
-    public DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled, Long bytesRate, Long iopsRate) {
+    public DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled,
+            Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) {
         long diskSize = 0;// special case for custom disk offerings
         if (numGibibytes != null && (numGibibytes <= 0)) {
             throw new InvalidParameterValueException("Please specify a disk size of at least 1 Gb.");
@@ -2155,10 +2160,18 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
         DiskOfferingVO newDiskOffering = new DiskOfferingVO(domainId, name, description, diskSize, tags, isCustomized);
         newDiskOffering.setUseLocalStorage(localStorageRequired);
         newDiskOffering.setDisplayOffering(isDisplayOfferingEnabled);
-        if (bytesRate != null && (bytesRate > 0))
-            newDiskOffering.setBytesRate(bytesRate);
-        if (iopsRate != null && (iopsRate > 0))
-            newDiskOffering.setIopsRate(iopsRate);
+
+        if (bytesReadRate != null && (bytesReadRate > 0))
+            newDiskOffering.setBytesReadRate(bytesReadRate);
+        if (bytesWriteRate != null && (bytesWriteRate > 0))
+            newDiskOffering.setBytesWriteRate(bytesWriteRate);
+        if (iopsReadRate != null && (iopsReadRate > 0))
+            newDiskOffering.setIopsReadRate(iopsReadRate);
+        if (iopsWriteRate != null && (iopsWriteRate > 0))
+            newDiskOffering.setIopsWriteRate(iopsWriteRate);
+	s_logger.warn("bytesReadRate =" + bytesReadRate);
+	s_logger.warn("newDiskOffering.getBytesReadRate" + newDiskOffering.getBytesReadRate());
+
         UserContext.current().setEventDetails("Disk offering id=" + newDiskOffering.getId());
         DiskOfferingVO offering = _diskOfferingDao.persist(newDiskOffering);
         if (offering != null) {
@@ -2199,9 +2212,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
             }
         }
 
-        Long bytesRate = cmd.getBytesRate();
-        Long iopsRate = cmd.getIopsRate();
-        return createDiskOffering(domainId, name, description, numGibibytes, tags, isCustomized, localStorageRequired, isDisplayOfferingEnabled, bytesRate, iopsRate);
+        Long bytesReadRate = cmd.getBytesReadRate();
+        Long bytesWriteRate = cmd.getBytesWriteRate();
+        Long iopsReadRate = cmd.getIopsReadRate();
+        Long iopsWriteRate = cmd.getIopsWriteRate();
+        return createDiskOffering(domainId, name, description, numGibibytes, tags, isCustomized, localStorageRequired, isDisplayOfferingEnabled, bytesReadRate, bytesWriteRate, iopsReadRate, iopsWriteRate);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/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
index 7f5b3ff..29c7ebc 100755
--- a/server/src/com/cloud/storage/StorageManager.java
+++ b/server/src/com/cloud/storage/StorageManager.java
@@ -125,7 +125,11 @@ public interface StorageManager extends StorageService {
 
     BigDecimal getStorageOverProvisioningFactor(Long dcId);
 
-    Long getDiskBytesRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering);
+    Long getDiskBytesReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering);
 
-    Long getDiskIORate(ServiceOfferingVO offering, DiskOfferingVO diskOffering);
+    Long getDiskBytesWriteRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering);
+
+    Long getDiskIopsReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering);
+
+    Long getDiskIopsWriteRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/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 cdfc19a..b905d9e 100755
--- a/server/src/com/cloud/storage/StorageManagerImpl.java
+++ b/server/src/com/cloud/storage/StorageManagerImpl.java
@@ -1885,36 +1885,67 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
         return null;
     }
 
-    // get bytesRate from disk_offering and vm.disk.throttling.bytes_rate
+    // get bytesReadRate from service_offering, disk_offering and vm.disk.throttling.bytes_read_rate
     @Override
-    public Long getDiskBytesRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) {
-        if ((offering != null) && (offering.getBytesRate() > 0)) {
-            return offering.getBytesRate();
-        } else if ((diskOffering != null) && (diskOffering.getBytesRate() > 0)) {
-            return diskOffering.getBytesRate();
+    public Long getDiskBytesReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) {
+        if ((offering != null) && (offering.getBytesReadRate() > 0)) {
+            return offering.getBytesReadRate();
+        } else if ((diskOffering != null) && (diskOffering.getBytesReadRate() > 0)) {
+            return diskOffering.getBytesReadRate();
         } else {
-            Long bytesRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingBytesRate.key()));
-            if (bytesRate > 0)  {
-                return bytesRate;
+            Long bytesReadRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingBytesReadRate.key()));
+            if ((bytesReadRate > 0) && ((offering == null) || (! offering.getSystemUse()))) {
+                return bytesReadRate;
             }
         }
         return 0L;
     }
 
-    // get iopsRate from disk_offering and vm.disk.throttling.io_rate
+    // get bytesWriteRate from service_offering, disk_offering and vm.disk.throttling.bytes_write_rate
     @Override
-    public Long getDiskIORate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) {
-        if ((offering != null) && (offering.getIopsRate() > 0)) {
-            return offering.getIopsRate();
-        } else if ((diskOffering != null) && (diskOffering.getIopsRate() > 0)) {
-            return diskOffering.getIopsRate();
+    public Long getDiskBytesWriteRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) {
+        if ((offering != null) && (offering.getBytesWriteRate() > 0)) {
+            return offering.getBytesWriteRate();
+        } else if ((diskOffering != null) && (diskOffering.getBytesWriteRate() > 0)) {
+            return diskOffering.getBytesWriteRate();
         } else {
-            Long iopsRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIORate.key()));
-            if (iopsRate > 0)  {
-                return iopsRate;
+            Long bytesWriteRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingBytesWriteRate.key()));
+            if ((bytesWriteRate > 0) && ((offering == null) || (! offering.getSystemUse())))  {
+                return bytesWriteRate;
             }
         }
         return 0L;
     }
 
+    // get iopsReadRate from service_offering, disk_offering and vm.disk.throttling.iops_read_rate
+    @Override
+    public Long getDiskIopsReadRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) {
+        if ((offering != null) && (offering.getIopsReadRate() > 0)) {
+            return offering.getIopsReadRate();
+        } else if ((diskOffering != null) && (diskOffering.getIopsReadRate() > 0)) {
+            return diskOffering.getIopsReadRate();
+        } else {
+            Long iopsReadRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIopsReadRate.key()));
+            if ((iopsReadRate > 0) && ((offering == null) || (! offering.getSystemUse())))  {
+                return iopsReadRate;
+            }
+        }
+        return 0L;
+    }
+
+    // get iopsWriteRate from service_offering, disk_offering and vm.disk.throttling.iops_write_rate
+    @Override
+    public Long getDiskIopsWriteRate(ServiceOfferingVO offering, DiskOfferingVO diskOffering) {
+        if ((offering != null) && (offering.getIopsWriteRate() > 0)) {
+            return offering.getIopsWriteRate();
+        } else if ((diskOffering != null) && (diskOffering.getIopsWriteRate() > 0)) {
+            return diskOffering.getIopsWriteRate();
+        } else {
+            Long iopsWriteRate = Long.parseLong(_configDao.getValue(Config.VmDiskThrottlingIopsWriteRate.key()));
+            if ((iopsWriteRate > 0) && ((offering == null) || (! offering.getSystemUse())))  {
+                return iopsWriteRate;
+            }
+        }
+        return 0L;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/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
index 63f3254..f3c94ab 100644
--- a/server/src/com/cloud/storage/VolumeManagerImpl.java
+++ b/server/src/com/cloud/storage/VolumeManagerImpl.java
@@ -337,8 +337,10 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
                 diskOffering.getUseLocalStorage(),
                 diskOffering.isRecreatable(), null);
         dskCh.setHyperType(dataDiskHyperType);
-        dskCh.setBytesRate(storageMgr.getDiskBytesRate(null, diskOffering));
-        dskCh.setIopsRate(storageMgr.getDiskIORate(null, diskOffering));
+        dskCh.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering));
+        dskCh.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering));
+        dskCh.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering));
+        dskCh.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering));
 
         DataCenterVO destPoolDataCenter = _dcDao.findById(destPoolDcId);
         HostPodVO destPoolPod = _podDao.findById(destPoolPodId);
@@ -515,8 +517,10 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
         DataCenterVO dc = _dcDao.findById(volume.getDataCenterId());
         DiskProfile dskCh = new DiskProfile(volume, diskOffering,
                 snapshot.getHypervisorType());
-        dskCh.setBytesRate(storageMgr.getDiskBytesRate(null, diskOffering));
-        dskCh.setIopsRate(storageMgr.getDiskIORate(null, diskOffering));
+        dskCh.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering));
+        dskCh.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering));
+        dskCh.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering));
+        dskCh.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering));
 
         // Determine what pod to store the volume in
         while ((pod = _resourceMgr.findPod(null, null, dc, account.getId(),
@@ -617,8 +621,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
         DiskProfile dskCh = createDiskCharacteristics(volume, template, dc,
                 diskOffering);
         dskCh.setHyperType(vm.getHypervisorType());
-        dskCh.setBytesRate(storageMgr.getDiskBytesRate(offering, diskOffering));
-        dskCh.setIopsRate(storageMgr.getDiskIORate(offering, diskOffering));
+        dskCh.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering));
+        dskCh.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering));
+        dskCh.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering));
+        dskCh.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering));
+
         // Find a suitable storage to create volume on
         StoragePool destPool = storageMgr.findStoragePool(dskCh, dc, pod,
                 clusterId, null, vm, avoidPools);
@@ -657,15 +664,21 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
         if (volume.getVolumeType() == Type.ROOT
                 && Storage.ImageFormat.ISO != template.getFormat()) {
             dskCh = createDiskCharacteristics(volume, template, dc, offering);
+            dskCh.setBytesReadRate(storageMgr.getDiskBytesReadRate(offering, diskOffering));
+            dskCh.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(offering, diskOffering));
+            dskCh.setIopsReadRate(storageMgr.getDiskIopsReadRate(offering, diskOffering));
+            dskCh.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(offering, diskOffering));
         } else {
             dskCh = createDiskCharacteristics(volume, template, dc,
                     diskOffering);
+            dskCh.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering));
+            dskCh.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering));
+            dskCh.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering));
+            dskCh.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering));
         }
 
         dskCh.setHyperType(hyperType);
-        dskCh.setBytesRate(storageMgr.getDiskBytesRate(offering, diskOffering));
-        dskCh.setIopsRate(storageMgr.getDiskIORate(offering, diskOffering));
-        
+ 
         final HashSet<StoragePool> avoidPools = new HashSet<StoragePool>(
                 avoids);
 
@@ -1555,6 +1568,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
                     volume.getFolder(), volume.getPath(), volume.getName(),
                     deviceId, volume.getChainInfo());
             cmd.setPoolUuid(volumePool.getUuid());
+            DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
+            cmd.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering));
+            cmd.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering));
+            cmd.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering));
+            cmd.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering));
 
             try {
                 answer = (AttachVolumeAnswer) _agentMgr.send(hostId, cmd);
@@ -1915,6 +1933,11 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
             StoragePoolVO volumePool = _storagePoolDao.findById(volume
                     .getPoolId());
             cmd.setPoolUuid(volumePool.getUuid());
+            DiskOfferingVO diskOffering = _diskOfferingDao.findById(volume.getDiskOfferingId());
+            cmd.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering));
+            cmd.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering));
+            cmd.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering));
+            cmd.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering));
 
             // Collect vm disk statistics from host before stopping Vm
             _userVmMgr.collectVmDiskStatistics(vm);
@@ -2245,8 +2268,17 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
             ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId());
             DiskOfferingVO diskOffering = _diskOfferingDao.findById(vol.getDiskOfferingId());
             VolumeTO newVolume = new VolumeTO(vol, pool);
-            newVolume.setBytesRate(storageMgr.getDiskBytesRate(offering, diskOffering));
-            newVolume.setIopsRate(storageMgr.getDiskIORate(offering, diskOffering));
+            if (vol.getVolumeType() == Type.ROOT) {
+                newVolume.setBytesReadRate(storageMgr.getDiskBytesReadRate(offering, diskOffering));
+                newVolume.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(offering, diskOffering));
+                newVolume.setIopsReadRate(storageMgr.getDiskIopsReadRate(offering, diskOffering));
+                newVolume.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(offering, diskOffering));
+            } else {
+                newVolume.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering));
+                newVolume.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering));
+                newVolume.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering));
+                newVolume.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering));
+            }
             vm.addDisk(newVolume);
         }
 
@@ -2480,8 +2512,17 @@ public class VolumeManagerImpl extends ManagerBase implements VolumeManager {
             ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId());
             DiskOfferingVO diskOffering = _diskOfferingDao.findById(vol.getDiskOfferingId());
             VolumeTO newVolume = new VolumeTO(vol, pool);
-            newVolume.setBytesRate(storageMgr.getDiskBytesRate(offering, diskOffering));
-            newVolume.setIopsRate(storageMgr.getDiskIORate(offering, diskOffering));
+            if (vol.getVolumeType() == Type.ROOT) {
+                newVolume.setBytesReadRate(storageMgr.getDiskBytesReadRate(offering, diskOffering));
+                newVolume.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(offering, diskOffering));
+                newVolume.setIopsReadRate(storageMgr.getDiskIopsReadRate(offering, diskOffering));
+                newVolume.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(offering, diskOffering));
+            } else {
+                newVolume.setBytesReadRate(storageMgr.getDiskBytesReadRate(null, diskOffering));
+                newVolume.setBytesWriteRate(storageMgr.getDiskBytesWriteRate(null, diskOffering));
+                newVolume.setIopsReadRate(storageMgr.getDiskIopsReadRate(null, diskOffering));
+                newVolume.setIopsWriteRate(storageMgr.getDiskIopsWriteRate(null, diskOffering));
+            }
             vm.addDisk(newVolume);
         }
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/server/src/com/cloud/test/DatabaseConfig.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/test/DatabaseConfig.java b/server/src/com/cloud/test/DatabaseConfig.java
index 16829f8..54e41f4 100755
--- a/server/src/com/cloud/test/DatabaseConfig.java
+++ b/server/src/com/cloud/test/DatabaseConfig.java
@@ -918,6 +918,20 @@ public class DatabaseConfig {
         }
 
         ServiceOfferingVO serviceOffering = new ServiceOfferingVO(name, cpu, ramSize, speed, null, null, ha, displayText, useLocalStorage, false, null, false, null, false);
+
+        Long bytesReadRate = Long.parseLong(_currentObjectParams.get("bytesReadRate"));
+        if (bytesReadRate != null && (bytesReadRate > 0))
+            serviceOffering.setBytesReadRate(bytesReadRate);
+        Long bytesWriteRate = Long.parseLong(_currentObjectParams.get("bytesWriteRate"));
+        if (bytesWriteRate != null && (bytesWriteRate > 0))
+            serviceOffering.setBytesWriteRate(bytesWriteRate);
+        Long iopsReadRate = Long.parseLong(_currentObjectParams.get("iopsReadRate"));
+        if (iopsReadRate != null && (iopsReadRate > 0))
+            serviceOffering.setIopsReadRate(iopsReadRate);
+        Long iopsWriteRate = Long.parseLong(_currentObjectParams.get("iopsWriteRate"));
+        if (iopsWriteRate != null && (iopsWriteRate > 0))
+            serviceOffering.setIopsWriteRate(iopsWriteRate);
+
         ServiceOfferingDaoImpl dao = ComponentContext.inject(ServiceOfferingDaoImpl.class);
         try {
             dao.persist(serviceOffering);
@@ -967,12 +981,20 @@ public class DatabaseConfig {
         }
         DiskOfferingVO diskOffering = new DiskOfferingVO(domainId, name, displayText, diskSpace , tags, false);
         diskOffering.setUseLocalStorage(local);
-        Long bytesRate = Long.parseLong(_currentObjectParams.get("bytesRate"));
-        if (bytesRate != null && (bytesRate > 0))
-            diskOffering.setBytesRate(bytesRate);
-        Long iopsRate = Long.parseLong(_currentObjectParams.get("iopsRate"));
-        if (iopsRate != null && (iopsRate > 0))
-            diskOffering.setIopsRate(iopsRate);
+
+        Long bytesReadRate = Long.parseLong(_currentObjectParams.get("bytesReadRate"));
+        if (bytesReadRate != null && (bytesReadRate > 0))
+            diskOffering.setBytesReadRate(bytesReadRate);
+        Long bytesWriteRate = Long.parseLong(_currentObjectParams.get("bytesWriteRate"));
+        if (bytesWriteRate != null && (bytesWriteRate > 0))
+            diskOffering.setBytesWriteRate(bytesWriteRate);
+        Long iopsReadRate = Long.parseLong(_currentObjectParams.get("iopsReadRate"));
+        if (iopsReadRate != null && (iopsReadRate > 0))
+            diskOffering.setIopsReadRate(iopsReadRate);
+        Long iopsWriteRate = Long.parseLong(_currentObjectParams.get("iopsWriteRate"));
+        if (iopsWriteRate != null && (iopsWriteRate > 0))
+            diskOffering.setIopsWriteRate(iopsWriteRate);
+
         DiskOfferingDaoImpl offering = ComponentContext.inject(DiskOfferingDaoImpl.class);
         try {
             offering.persist(diskOffering);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
index 686040b..6e3d187 100755
--- a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
@@ -489,7 +489,8 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu
      */
     @Override
     public ServiceOfferingVO createServiceOffering(long userId, boolean isSystem, Type vm_typeType, String name, int cpu, int ramSize, int speed, String displayText, boolean localStorageRequired, boolean offerHA,
-            boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate, String deploymentPlanner, Map<String, String> details, Long bytesRate, Long iopsRate) {
+            boolean limitResourceUse, boolean volatileVm, String tags, Long domainId, String hostTag, Integer networkRate, String deploymentPlanner, Map<String, String> details,
+            Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) {
         // TODO Auto-generated method stub
         return null;
     }
@@ -654,7 +655,8 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu
      * @see com.cloud.configuration.ConfigurationManager#createDiskOffering(java.lang.Long, java.lang.String, java.lang.String, java.lang.Long, java.lang.String, boolean, boolean, boolean)
      */
     @Override
-    public DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled, Long bytesRate, Long iopsRate) {
+    public DiskOfferingVO createDiskOffering(Long domainId, String name, String description, Long numGibibytes, String tags, boolean isCustomized, boolean localStorageRequired, boolean isDisplayOfferingEnabled,
+            Long bytesReadRate, Long bytesWriteRate, Long iopsReadRate, Long iopsWriteRate) {
         // TODO Auto-generated method stub
         return null;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/setup/db/db/schema-410to420.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql
index a59cf1c..2e52296 100644
--- a/setup/db/db/schema-410to420.sql
+++ b/setup/db/db/schema-410to420.sql
@@ -290,9 +290,13 @@ ALTER TABLE `cloud`.`nics` ADD COLUMN `display_nic` tinyint(1) NOT NULL DEFAULT
 
 ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `display_offering` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Should disk offering be displayed to the end user';
 
-ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `bytes_rate` bigint(20) unsigned DEFAULT 0;
+ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `bytes_read_rate` bigint(20) unsigned DEFAULT 0;
 
-ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `iops_rate` bigint(20) unsigned DEFAULT 0;
+ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `bytes_write_rate` bigint(20) unsigned DEFAULT 0;
+
+ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `iops_read_rate` bigint(20) unsigned DEFAULT 0;
+
+ALTER TABLE `cloud`.`disk_offering` ADD COLUMN `iops_write_rate` bigint(20) unsigned DEFAULT 0;
 
 CREATE TABLE `cloud`.`volume_details` (
   `id` bigint unsigned NOT NULL auto_increment,
@@ -766,8 +770,10 @@ CREATE VIEW `cloud`.`volume_view` AS
         disk_offering.display_text disk_offering_display_text,
         disk_offering.use_local_storage,
         disk_offering.system_use,
-        disk_offering.bytes_rate,
-        disk_offering.iops_rate,
+        disk_offering.bytes_read_rate,
+        disk_offering.bytes_write_rate,
+        disk_offering.iops_read_rate,
+        disk_offering.iops_write_rate,
         storage_pool.id pool_id,
         storage_pool.uuid pool_uuid,
         storage_pool.name pool_name,
@@ -1076,8 +1082,10 @@ CREATE VIEW `cloud`.`service_offering_view` AS
         disk_offering.removed,
         disk_offering.use_local_storage,
         disk_offering.system_use,
-        disk_offering.bytes_rate,
-        disk_offering.iops_rate,
+        disk_offering.bytes_read_rate,
+        disk_offering.bytes_write_rate,
+        disk_offering.iops_read_rate,
+        disk_offering.iops_write_rate,
         service_offering.cpu,
         service_offering.speed,
         service_offering.ram_size,
@@ -1384,8 +1392,10 @@ CREATE VIEW `cloud`.`disk_offering_view` AS
         disk_offering.removed,
         disk_offering.use_local_storage,
         disk_offering.system_use,
-        disk_offering.bytes_rate,
-        disk_offering.iops_rate,
+        disk_offering.bytes_read_rate,
+        disk_offering.bytes_write_rate,
+        disk_offering.iops_read_rate,
+        disk_offering.iops_write_rate,
         disk_offering.sort_key,
         disk_offering.type,
 	disk_offering.display_offering,
@@ -1626,8 +1636,10 @@ CREATE VIEW `cloud`.`volume_view` AS
         disk_offering.display_text disk_offering_display_text,
         disk_offering.use_local_storage,
         disk_offering.system_use,
-        disk_offering.bytes_rate,
-        disk_offering.iops_rate,
+        disk_offering.bytes_read_rate,
+        disk_offering.bytes_write_rate,
+        disk_offering.iops_read_rate,
+        disk_offering.iops_write_rate,
         storage_pool.id pool_id,
         storage_pool.uuid pool_uuid,
         storage_pool.name pool_name,
@@ -1858,8 +1870,10 @@ CREATE TABLE `cloud_usage`.`usage_vm_disk` (
 ) ENGINE=InnoDB CHARSET=utf8;
 
 INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.stats.interval', 0, 'Interval (in seconds) to report vm disk statistics.');
-INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.iops_rate', 0, 'Default disk I/O rate in requests per second allowed in User vm\'s disk. ');
-INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.bytes_rate', 0, 'Default disk I/O rate in bytes per second allowed in User vm\'s disk. ');
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.iops_read_rate', 0, 'Default disk I/O read rate in requests per second allowed in User vm\'s disk. ');
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.iops_write_rate', 0, 'Default disk I/O write rate in requests per second allowed in User vm\'s disk. ');
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.bytes_read_rate', 0, 'Default disk I/O read rate in bytes per second allowed in User vm\'s disk. ');
+INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'management-server', 'vm.disk.throttling.bytes_write_rate', 0, 'Default disk I/O write rate in bytes per second allowed in User vm\'s disk. ');
 
 -- Re-enable foreign key checking, at the end of the upgrade path
 SET foreign_key_checks = 1;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/869a6b0c/ui/dictionary.jsp
----------------------------------------------------------------------
diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp
index dd24aa2..7809cdb 100644
--- a/ui/dictionary.jsp
+++ b/ui/dictionary.jsp
@@ -472,8 +472,10 @@ dictionary = {
 'label.disable.vpn': '<fmt:message key="label.disable.vpn" />',
 'label.disabling.vpn.access': '<fmt:message key="label.disabling.vpn.access" />',
 'label.disk.allocated': '<fmt:message key="label.disk.allocated" />',
-'label.disk.bytes.rate': '<fmt:message key="label.disk.bytes.rate" />',
-'label.disk.iops.rate': '<fmt:message key="label.disk.iops.rate" />',
+'label.disk.bytes.read.rate': '<fmt:message key="label.disk.bytes.read.rate" />',
+'label.disk.bytes.write.rate': '<fmt:message key="label.disk.bytes.write.rate" />',
+'label.disk.iops.write.rate': '<fmt:message key="label.disk.iops.write.rate" />',
+'label.disk.iops.read.rate': '<fmt:message key="label.disk.iops.read.rate" />',
 'label.disk.read.bytes': '<fmt:message key="label.disk.read.bytes" />',
 'label.disk.read.io': '<fmt:message key="label.disk.read.io" />',
 'label.disk.offering': '<fmt:message key="label.disk.offering" />',


Mime
View raw message