Skip to content

Commit 3773ff0

Browse files
author
Mike Tutkowski
committed
Update to volume-resize logic
1 parent 1436ce6 commit 3773ff0

5 files changed

Lines changed: 98 additions & 20 deletions

File tree

plugins/hypervisors/xenserver/src/com/cloud/hypervisor/xenserver/resource/CitrixResourceBase.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,7 +1928,6 @@ protected VDI prepareManagedStorage(Connection conn, Map<String, String> details
19281928
Long volumeSize = Long.parseLong(details.get(DiskTO.VOLUME_SIZE));
19291929

19301930
if (vdi == null) {
1931-
19321931
vdi = createVdi(sr, vdiNameLabel, volumeSize);
19331932
} else {
19341933
// if VDI is not null, it must have already been created, so check whether a resize of the volume was performed
@@ -1939,7 +1938,7 @@ protected VDI prepareManagedStorage(Connection conn, Map<String, String> details
19391938
long vdiVirtualSize = vdi.getVirtualSize(conn);
19401939

19411940
if (vdiVirtualSize != volumeSize) {
1942-
s_logger.info("resizing the datadisk(vdi) from vdiVirtualsize :"+ vdiVirtualSize + "to volumeSize :" + volumeSize);
1941+
s_logger.info("resizing the data disk (vdi) from vdiVirtualsize: "+ vdiVirtualSize + " to volumeSize: " + volumeSize);
19431942

19441943
try {
19451944
vdi.resize(conn, volumeSize);

plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/driver/SolidFirePrimaryDataStoreDriver.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,8 @@ public void resize(DataObject dataObject, AsyncCompletionCallback<CreateCmdResul
420420

421421
verifySufficientIopsForStoragePool(storagePoolId, volumeInfo.getId(), payload.newMinIops);
422422

423-
SolidFireUtil.modifySolidFireVolume(sfConnection, sfVolumeId, sfVolume.getTotalSize(), payload.newMinIops, payload.newMaxIops,
424-
getDefaultBurstIops(storagePoolId, payload.newMaxIops));
423+
SolidFireUtil.modifySolidFireVolume(sfConnection, sfVolumeId, sfVolume.getTotalSize(), NumberFormat.getInstance().format(payload.newSize),
424+
payload.newMinIops, payload.newMaxIops, getDefaultBurstIops(storagePoolId, payload.newMaxIops));
425425

426426
VolumeVO volume = _volumeDao.findById(volumeInfo.getId());
427427

plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/lifecycle/SolidFireSharedPrimaryDataStoreLifeCycle.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ public void updateStoragePool(StoragePool storagePool, Map<String, String> detai
621621
}
622622
}
623623

624-
SolidFireUtil.modifySolidFireVolume(sfConnection, getVolumeId(storagePool.getId()), size, minIops, maxIops, burstIops);
624+
SolidFireUtil.modifySolidFireVolume(sfConnection, getVolumeId(storagePool.getId()), size, null, minIops, maxIops, burstIops);
625625

626626
SolidFireUtil.updateCsDbWithSolidFireIopsInfo(storagePool.getId(), _primaryDataStoreDao, _storagePoolDetailsDao, minIops, maxIops, burstIops);
627627
}

plugins/storage/volume/solidfire/src/org/apache/cloudstack/storage/datastore/util/SolidFireUtil.java

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -467,11 +467,14 @@ public static long createSolidFireVolume(SolidFireConnection sfConnection, Strin
467467
return volumeCreateResult.result.volumeID;
468468
}
469469

470-
public static void modifySolidFireVolume(SolidFireConnection sfConnection, long volumeId, long totalSize, long minIops, long maxIops, long burstIops)
470+
public static void modifySolidFireVolume(SolidFireConnection sfConnection, long volumeId, long totalSize, String strCloudStackVolumeSize,
471+
long minIops, long maxIops, long burstIops)
471472
{
472473
final Gson gson = new GsonBuilder().create();
473474

474-
VolumeToModify volumeToModify = new VolumeToModify(volumeId, totalSize, minIops, maxIops, burstIops);
475+
Object volumeToModify = strCloudStackVolumeSize != null && strCloudStackVolumeSize.trim().length() > 0 ?
476+
new VolumeToModifyWithCloudStackVolumeSize(volumeId, totalSize, strCloudStackVolumeSize, minIops, maxIops, burstIops) :
477+
new VolumeToModify(volumeId, totalSize, minIops, maxIops, burstIops);
475478

476479
String strVolumeToModifyJson = gson.toJson(volumeToModify);
477480

@@ -947,8 +950,8 @@ private static final class VolumeToCreateParams {
947950
private final long accountID;
948951
private final long totalSize;
949952
private final boolean enable512e;
950-
private final VolumeToCreateParamsQoS qos;
951953
private final VolumeToCreateParamsAttributes attributes;
954+
private final VolumeToCreateParamsQoS qos;
952955

953956
private VolumeToCreateParams(final String strVolumeName, final long lAccountId, final long lTotalSize, final boolean bEnable512e,
954957
final String strCloudStackVolumeSize, final long lMinIOPS, final long lMaxIOPS, final long lBurstIOPS) {
@@ -1024,6 +1027,57 @@ private VolumeToCreateParamsQoS(final long lMinIOPS, final long lMaxIOPS, final
10241027
}
10251028
}
10261029

1030+
@SuppressWarnings("unused")
1031+
private static final class VolumeToModifyWithCloudStackVolumeSize
1032+
{
1033+
private final String method = "ModifyVolume";
1034+
private final VolumeToModifyParams params;
1035+
1036+
private VolumeToModifyWithCloudStackVolumeSize(final long lVolumeId, final long lTotalSize, final String strCloudStackVolumeSize,
1037+
final long lMinIOPS, final long lMaxIOPS, final long lBurstIOPS)
1038+
{
1039+
params = new VolumeToModifyParams(lVolumeId, lTotalSize, strCloudStackVolumeSize, lMinIOPS, lMaxIOPS, lBurstIOPS);
1040+
}
1041+
1042+
private static final class VolumeToModifyParams
1043+
{
1044+
private final long volumeID;
1045+
private final long totalSize;
1046+
private final VolumeToModifyParamsAttributes attributes;
1047+
private final VolumeToModifyParamsQoS qos;
1048+
1049+
private VolumeToModifyParams(final long lVolumeId, final long lTotalSize, String strCloudStackVolumeSize, final long lMinIOPS, final long lMaxIOPS, final long lBurstIOPS)
1050+
{
1051+
volumeID = lVolumeId;
1052+
1053+
totalSize = lTotalSize;
1054+
1055+
attributes = new VolumeToModifyParamsAttributes(strCloudStackVolumeSize);
1056+
qos = new VolumeToModifyParamsQoS(lMinIOPS, lMaxIOPS, lBurstIOPS);
1057+
}
1058+
}
1059+
1060+
private static final class VolumeToModifyParamsAttributes {
1061+
private final String CloudStackVolumeSize;
1062+
1063+
private VolumeToModifyParamsAttributes(final String strCloudStackVolumeSize) {
1064+
CloudStackVolumeSize = strCloudStackVolumeSize;
1065+
}
1066+
}
1067+
1068+
private static final class VolumeToModifyParamsQoS {
1069+
private final long minIOPS;
1070+
private final long maxIOPS;
1071+
private final long burstIOPS;
1072+
1073+
private VolumeToModifyParamsQoS(final long lMinIOPS, final long lMaxIOPS, final long lBurstIOPS) {
1074+
minIOPS = lMinIOPS;
1075+
maxIOPS = lMaxIOPS;
1076+
burstIOPS = lBurstIOPS;
1077+
}
1078+
}
1079+
}
1080+
10271081
@SuppressWarnings("unused")
10281082
private static final class VolumeToModify
10291083
{

server/src/com/cloud/storage/VolumeApiServiceImpl.java

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ public VolumeVO resizeVolume(ResizeVolumeCmd cmd) throws ResourceAllocationExcep
851851
}
852852
}
853853

854-
// Note: The storage plug-in in question should perform validation on the IOPS to check if a sufficient number of IOPS are available to perform
854+
// Note: The storage plug-in in question should perform validation on the IOPS to check if a sufficient number of IOPS is available to perform
855855
// the requested change
856856

857857
/* If this volume has never been beyond allocated state, short circuit everything and simply update the database. */
@@ -970,9 +970,21 @@ private VolumeVO orchestrateResizeVolume(long volumeId, long currentSize, long n
970970
hosts = new long[] {userVm.getLastHostId()};
971971
}
972972

973+
final String errorMsg = "The VM must be stopped or the disk detached in order to resize with the XenServer Hypervisor.";
974+
975+
StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
976+
977+
if (storagePool.isManaged() && storagePool.getHypervisor() == HypervisorType.Any && hosts != null && hosts.length > 0) {
978+
HostVO host = this._hostDao.findById(hosts[0]);
979+
980+
if (currentSize != newSize && host.getHypervisorType() == HypervisorType.XenServer && !userVm.getState().equals(State.Stopped)) {
981+
throw new InvalidParameterValueException(errorMsg);
982+
}
983+
}
984+
973985
/* Xen only works offline, SR does not support VDI.resizeOnline */
974986
if (currentSize != newSize && _volsDao.getHypervisorType(volume.getId()) == HypervisorType.XenServer && !userVm.getState().equals(State.Stopped)) {
975-
throw new InvalidParameterValueException("VM must be stopped or disk detached in order to resize with the Xen HV");
987+
throw new InvalidParameterValueException(errorMsg);
976988
}
977989
}
978990

@@ -982,8 +994,30 @@ private VolumeVO orchestrateResizeVolume(long volumeId, long currentSize, long n
982994
VolumeInfo vol = volFactory.getVolume(volume.getId());
983995
vol.addPayload(payload);
984996

997+
StoragePoolVO storagePool = _storagePoolDao.findById(vol.getPoolId());
998+
999+
// managed storage is designed in such a way that the storage plug-in does not
1000+
// talk to the hypervisor layer; as such, if the storage is managed and the
1001+
// current and new sizes are different, then CloudStack (i.e. not a storage plug-in)
1002+
// needs to tell the hypervisor to resize the disk
1003+
if (storagePool.isManaged() && currentSize != newSize) {
1004+
if (hosts != null && hosts.length > 0) {
1005+
volService.resizeVolumeOnHypervisor(volumeId, newSize, hosts[0], instanceName);
1006+
}
1007+
1008+
volume.setSize(newSize);
1009+
1010+
_volsDao.update(volume.getId(), volume);
1011+
}
1012+
1013+
// this call to resize has a different impact depending on whether the
1014+
// underlying primary storage is managed or not
1015+
// if managed, this is the chance for the plug-in to change IOPS value, if applicable
1016+
// if not managed, this is the chance for the plug-in to talk to the hypervisor layer
1017+
// to change the size of the disk
9851018
AsyncCallFuture<VolumeApiResult> future = volService.resize(vol);
9861019
VolumeApiResult result = future.get();
1020+
9871021
if (result.isFailed()) {
9881022
s_logger.warn("Failed to resize the volume " + volume);
9891023
String details = "";
@@ -995,19 +1029,10 @@ private VolumeVO orchestrateResizeVolume(long volumeId, long currentSize, long n
9951029

9961030
volume = _volsDao.findById(volume.getId());
9971031

998-
StoragePoolVO storagePool = _storagePoolDao.findById(vol.getPoolId());
999-
1000-
if (currentSize != newSize && storagePool.isManaged()) {
1001-
if (hosts != null && hosts.length > 0) {
1002-
volService.resizeVolumeOnHypervisor(volumeId, newSize, hosts[0], instanceName);
1003-
}
1004-
1005-
volume.setSize(newSize);
1006-
}
1007-
10081032
if (newDiskOfferingId != null) {
10091033
volume.setDiskOfferingId(newDiskOfferingId);
10101034
}
1035+
10111036
_volsDao.update(volume.getId(), volume);
10121037
// Log usage event for volumes belonging user VM's only
10131038
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_RESIZE, volume.getAccountId(), volume.getDataCenterId(), volume.getId(), volume.getName(),

0 commit comments

Comments
 (0)