Skip to content

Commit fe0c976

Browse files
author
Mike Tutkowski
committed
CLOUDSTACK-6170 (VMware root-disk support for managed storage)
1 parent 412af7c commit fe0c976

File tree

9 files changed

+144
-23
lines changed

9 files changed

+144
-23
lines changed

core/src/org/apache/cloudstack/storage/to/PrimaryDataStoreTO.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
public class PrimaryDataStoreTO implements DataStoreTO {
2828
public static final String MANAGED = PrimaryDataStore.MANAGED;
2929
public static final String STORAGE_HOST = PrimaryDataStore.STORAGE_HOST;
30+
public static final String STORAGE_PORT = PrimaryDataStore.STORAGE_PORT;
3031
public static final String MANAGED_STORE_TARGET = PrimaryDataStore.MANAGED_STORE_TARGET;
3132
public static final String MANAGED_STORE_TARGET_ROOT_VOLUME = PrimaryDataStore.MANAGED_STORE_TARGET_ROOT_VOLUME;
3233
public static final String CHAP_INITIATOR_USERNAME = PrimaryDataStore.CHAP_INITIATOR_USERNAME;

engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/PrimaryDataStoreInfo.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
public interface PrimaryDataStoreInfo extends StoragePool {
3030
static final String MANAGED = "managed";
3131
static final String STORAGE_HOST= "storageHost";
32+
static final String STORAGE_PORT = "storagePort";
3233
static final String MANAGED_STORE_TARGET = "managedStoreTarget";
3334
static final String MANAGED_STORE_TARGET_ROOT_VOLUME = "managedStoreTargetRootVolume";
3435
static final String CHAP_INITIATOR_USERNAME = "chapInitiatorUsername";

engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,10 @@ protected Void managedCopyBaseImageCallback(AsyncCallbackDispatcher<VolumeServic
527527
TemplateObjectTO templateObjectTo = (TemplateObjectTO)answer.getNewData();
528528

529529
volume.setPath(templateObjectTo.getPath());
530-
volume.setFormat(templateObjectTo.getFormat());
530+
531+
if (templateObjectTo.getFormat() != null) {
532+
volume.setFormat(templateObjectTo.getFormat());
533+
}
531534

532535
volDao.update(volume.getId(), volume);
533536
}
@@ -682,6 +685,7 @@ public AsyncCallFuture<VolumeApiResult> createManagedStorageAndVolumeFromTemplat
682685

683686
details.put(PrimaryDataStore.MANAGED, Boolean.TRUE.toString());
684687
details.put(PrimaryDataStore.STORAGE_HOST, destPrimaryDataStore.getHostAddress());
688+
details.put(PrimaryDataStore.STORAGE_PORT, String.valueOf(destPrimaryDataStore.getPort()));
685689
// for managed storage, the storage repository (XenServer) or datastore (ESX) name is based off of the iScsiName property of a volume
686690
details.put(PrimaryDataStore.MANAGED_STORE_TARGET, volumeInfo.get_iScsiName());
687691
details.put(PrimaryDataStore.MANAGED_STORE_TARGET_ROOT_VOLUME, volumeInfo.getName());

plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareHostService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,14 @@ public interface VmwareHostService {
3333

3434
String getWorkerName(VmwareContext context, Command cmd, int workerSequence);
3535

36+
ManagedObjectReference prepareManagedDatastore(VmwareHypervisorHost hyperHost, String iScsiName,
37+
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
38+
String chapTargetUsername, String chapTargetSecret) throws Exception;
39+
3640
ManagedObjectReference prepareManagedStorage(VmwareHypervisorHost hyperHost, String iScsiName,
3741
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
3842
String chapTargetUsername, String chapTargetSecret, long size, Command cmd) throws Exception;
43+
3944
void handleDatastoreAndVmdkDetach(String iqn, String storageHost, int storagePort) throws Exception;
4045

4146
void removeManagedTargetsFromCluster(List<String> managedIqns) throws Exception;

plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1824,13 +1824,20 @@ private void tearDownVm(VirtualMachineMO vmMo) throws Exception{
18241824
vmMo.ensureScsiDeviceController();
18251825
}
18261826

1827+
@Override
1828+
public ManagedObjectReference prepareManagedDatastore(VmwareHypervisorHost hyperHost, String iScsiName,
1829+
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
1830+
String chapTargetUsername, String chapTargetSecret) throws Exception {
1831+
return getVmfsDatastore(hyperHost, VmwareResource.getDatastoreName(iScsiName), storageHost, storagePort,
1832+
VmwareResource.trimIqn(iScsiName), chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
1833+
}
1834+
18271835
@Override
18281836
public ManagedObjectReference prepareManagedStorage(VmwareHypervisorHost hyperHost, String iScsiName,
18291837
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
18301838
String chapTargetUsername, String chapTargetSecret, long size, Command cmd) throws Exception {
1831-
ManagedObjectReference morDs = getVmfsDatastore(hyperHost, VmwareResource.getDatastoreName(iScsiName),
1832-
storageHost, storagePort, VmwareResource.trimIqn(iScsiName), chapInitiatorUsername, chapInitiatorSecret,
1833-
chapTargetUsername, chapTargetSecret);
1839+
ManagedObjectReference morDs = prepareManagedDatastore(hyperHost, iScsiName, storageHost, storagePort,
1840+
chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
18341841

18351842
DatastoreMO dsMo = new DatastoreMO(getServiceContext(null), morDs);
18361843

@@ -1908,7 +1915,7 @@ private String[] syncDiskChain(DatacenterMO dcMo, VirtualMachineMO vmMo, Virtual
19081915

19091916
if (isManaged) {
19101917
if (volumeTO.getVolumeType() == Volume.Type.ROOT) {
1911-
datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, dsMo.getName());
1918+
datastoreDiskPath = VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmMo.getName(), dsMo, volumeTO.getName());
19121919
}
19131920
else {
19141921
datastoreDiskPath = dsMo.getDatastorePath(dsMo.getName() + ".vmdk");

plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareSecondaryStorageResourceHandler.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,13 @@ public String getMountPoint(String storageUrl) {
314314
return _resource.getRootDir(storageUrl);
315315
}
316316

317+
@Override
318+
public ManagedObjectReference prepareManagedDatastore(VmwareHypervisorHost hyperHost, String iScsiName,
319+
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,
320+
String chapTargetUsername, String chapTargetSecret) throws Exception {
321+
throw new OperationNotSupportedException();
322+
}
323+
317324
@Override
318325
public ManagedObjectReference prepareManagedStorage(VmwareHypervisorHost hyperHost, String iScsiName,
319326
String storageHost, int storagePort, String chapInitiatorUsername, String chapInitiatorSecret,

plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java

Lines changed: 96 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -188,52 +188,131 @@ public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) {
188188
DataTO srcData = cmd.getSrcTO();
189189
TemplateObjectTO template = (TemplateObjectTO)srcData;
190190
DataStoreTO srcStore = srcData.getDataStore();
191+
191192
if (!(srcStore instanceof NfsTO)) {
192193
return new CopyCmdAnswer("unsupported protocol");
193194
}
195+
194196
NfsTO nfsImageStore = (NfsTO)srcStore;
195197
DataTO destData = cmd.getDestTO();
196198
DataStoreTO destStore = destData.getDataStore();
197199
DataStoreTO primaryStore = destStore;
200+
198201
String secondaryStorageUrl = nfsImageStore.getUrl();
202+
199203
assert (secondaryStorageUrl != null);
200204

205+
boolean managed = false;
206+
String storageHost = null;
207+
int storagePort = Integer.MIN_VALUE;
208+
String managedStoragePoolName = null;
209+
String managedStoragePoolRootVolumeName = null;
210+
String chapInitiatorUsername = null;
211+
String chapInitiatorSecret = null;
212+
String chapTargetUsername = null;
213+
String chapTargetSecret = null;
214+
215+
if (destStore instanceof PrimaryDataStoreTO) {
216+
PrimaryDataStoreTO destPrimaryDataStoreTo = (PrimaryDataStoreTO)destStore;
217+
218+
Map<String, String> details = destPrimaryDataStoreTo.getDetails();
219+
220+
if (details != null) {
221+
managed = Boolean.parseBoolean(details.get(PrimaryDataStoreTO.MANAGED));
222+
223+
if (managed) {
224+
storageHost = details.get(PrimaryDataStoreTO.STORAGE_HOST);
225+
226+
try {
227+
storagePort = Integer.parseInt(details.get(PrimaryDataStoreTO.STORAGE_PORT));
228+
}
229+
catch (Exception ex) {
230+
storagePort = 3260;
231+
}
232+
233+
managedStoragePoolName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET);
234+
managedStoragePoolRootVolumeName = details.get(PrimaryDataStoreTO.MANAGED_STORE_TARGET_ROOT_VOLUME);
235+
chapInitiatorUsername = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_USERNAME);
236+
chapInitiatorSecret = details.get(PrimaryDataStoreTO.CHAP_INITIATOR_SECRET);
237+
chapTargetUsername = details.get(PrimaryDataStoreTO.CHAP_TARGET_USERNAME);
238+
chapTargetSecret = details.get(PrimaryDataStoreTO.CHAP_TARGET_SECRET);
239+
}
240+
}
241+
}
242+
201243
String templateUrl = secondaryStorageUrl + "/" + srcData.getPath();
202244

203245
Pair<String, String> templateInfo = VmwareStorageLayoutHelper.decodeTemplateRelativePathAndNameFromUrl(secondaryStorageUrl, templateUrl, template.getName());
204246

205247
VmwareContext context = hostService.getServiceContext(cmd);
248+
206249
try {
207250
VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, cmd);
208-
209-
String templateUuidName = deriveTemplateUuidOnHost(hyperHost, primaryStore.getUuid(), templateInfo.second());
210-
251+
String storageUuid = managed ? managedStoragePoolName : primaryStore.getUuid();
252+
String templateUuidName = deriveTemplateUuidOnHost(hyperHost, storageUuid, templateInfo.second());
211253
DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
212254
VirtualMachineMO templateMo = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templateUuidName), true);
255+
DatastoreMO dsMo = null;
213256

214257
if (templateMo == null) {
215-
if (s_logger.isInfoEnabled())
216-
s_logger.info("Template " + templateInfo.second() + " is not setup yet, setup template from secondary storage with uuid name: " + templateUuidName);
217-
ManagedObjectReference morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid());
258+
if (s_logger.isInfoEnabled()) {
259+
s_logger.info("Template " + templateInfo.second() + " is not setup yet. Set up template from secondary storage with uuid name: " + templateUuidName);
260+
}
261+
262+
final ManagedObjectReference morDs;
263+
264+
if (managed) {
265+
morDs = hostService.prepareManagedDatastore(hyperHost, managedStoragePoolName, storageHost, storagePort,
266+
chapInitiatorUsername, chapInitiatorSecret, chapTargetUsername, chapTargetSecret);
267+
}
268+
else {
269+
morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, storageUuid);
270+
}
271+
218272
assert (morDs != null);
219-
DatastoreMO primaryStorageDatastoreMo = new DatastoreMO(context, morDs);
220273

221-
copyTemplateFromSecondaryToPrimary(hyperHost, primaryStorageDatastoreMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(),
222-
templateUuidName);
274+
dsMo = new DatastoreMO(context, morDs);
275+
276+
copyTemplateFromSecondaryToPrimary(hyperHost, dsMo, secondaryStorageUrl, templateInfo.first(), templateInfo.second(),
277+
managed ? managedStoragePoolRootVolumeName : templateUuidName);
278+
279+
if (managed) {
280+
String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, managedStoragePoolRootVolumeName, managedStoragePoolRootVolumeName,
281+
VmwareStorageLayoutType.VMWARE, false);
282+
String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, null, managedStoragePoolRootVolumeName,
283+
VmwareStorageLayoutType.CLOUDSTACK_LEGACY, false);
284+
285+
dsMo.moveDatastoreFile(vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true);
286+
dsMo.moveDatastoreFile(vmwareLayoutFilePair[1], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[1], dcMo.getMor(), true);
287+
288+
String folderToDelete = dsMo.getDatastorePath(managedStoragePoolRootVolumeName, true);
289+
dsMo.deleteFolder(folderToDelete, dcMo.getMor());
290+
}
223291
} else {
224292
s_logger.info("Template " + templateInfo.second() + " has already been setup, skip the template setup process in primary storage");
225293
}
226294

227295
TemplateObjectTO newTemplate = new TemplateObjectTO();
228-
newTemplate.setPath(templateUuidName);
296+
297+
if (managed) {
298+
String path = dsMo.getDatastorePath(managedStoragePoolRootVolumeName + ".vmdk");
299+
300+
newTemplate.setPath(path);
301+
}
302+
else {
303+
newTemplate.setPath(templateUuidName);
304+
}
305+
229306
return new CopyCmdAnswer(newTemplate);
230307
} catch (Throwable e) {
231308
if (e instanceof RemoteException) {
232309
hostService.invalidateServiceContext(context);
233310
}
234311

235312
String msg = "Unable to copy template to primary storage due to exception:" + VmwareHelper.getExceptionMessage(e);
313+
236314
s_logger.error(msg, e);
315+
237316
return new CopyCmdAnswer(msg);
238317
}
239318
}
@@ -1176,9 +1255,9 @@ private Answer attachVolume(Command cmd, DiskTO disk, boolean isAttach, boolean
11761255
Map<String, String> details = disk.getDetails();
11771256

11781257
morDs = hostService.prepareManagedStorage(hyperHost, iScsiName, storageHost, storagePort,
1179-
details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET),
1180-
details.get(DiskTO.CHAP_TARGET_USERNAME), details.get(DiskTO.CHAP_TARGET_SECRET),
1181-
volumeTO.getSize(), cmd);
1258+
details.get(DiskTO.CHAP_INITIATOR_USERNAME), details.get(DiskTO.CHAP_INITIATOR_SECRET),
1259+
details.get(DiskTO.CHAP_TARGET_USERNAME), details.get(DiskTO.CHAP_TARGET_SECRET),
1260+
volumeTO.getSize(), cmd);
11821261
}
11831262
else {
11841263
morDs = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, isManaged ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid());
@@ -1572,15 +1651,15 @@ private List<String> getManagedIqnsFromVirtualDisks(List<VirtualDisk> virtualDis
15721651
VirtualDiskFlatVer2BackingInfo backingInfo = (VirtualDiskFlatVer2BackingInfo)virtualDisk.getBacking();
15731652
String path = backingInfo.getFileName();
15741653

1575-
path = new DatastoreFile(path).getFileBaseName();
1576-
1577-
String search = "-";
1654+
String search = "[-";
15781655
int index = path.indexOf(search);
15791656

15801657
if (index > -1) {
15811658
path = path.substring(index + search.length());
15821659

1583-
index = path.lastIndexOf(search);
1660+
String search2 = "-0]";
1661+
1662+
index = path.lastIndexOf(search2);
15841663

15851664
if (index > -1) {
15861665
path = path.substring(0, index);

plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XenServerStorageProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,7 @@ public Answer copyTemplateToPrimaryStorage(CopyCommand cmd) {
911911
String chapInitiatorSecret = null;
912912

913913
if (destDataStoreTo instanceof PrimaryDataStoreTO) {
914-
PrimaryDataStoreTO destPrimaryDataStoreTo = (PrimaryDataStoreTO) destDataStoreTo;
914+
PrimaryDataStoreTO destPrimaryDataStoreTo = (PrimaryDataStoreTO)destDataStoreTo;
915915

916916
Map<String, String> details = destPrimaryDataStoreTo.getDetails();
917917

vmware-base/src/com/cloud/hypervisor/vmware/mo/DatastoreMO.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,23 @@ public String getDatastorePath(String relativePathWithoutDatastoreName, boolean
142142
return path;
143143
}
144144

145+
public boolean deleteFolder(String folder, ManagedObjectReference morDc) throws Exception {
146+
ManagedObjectReference morFileManager = _context.getServiceContent().getFileManager();
147+
ManagedObjectReference morTask = _context.getService().deleteDatastoreFileTask(morFileManager, folder, morDc);
148+
149+
boolean result = _context.getVimClient().waitForTask(morTask);
150+
151+
if (result) {
152+
_context.waitForTaskProgressDone(morTask);
153+
154+
return true;
155+
} else {
156+
s_logger.error("VMware deleteDatastoreFile_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
157+
}
158+
159+
return false;
160+
}
161+
145162
public boolean deleteFile(String path, ManagedObjectReference morDc, boolean testExistence) throws Exception {
146163
String datastoreName = getName();
147164
ManagedObjectReference morFileManager = _context.getServiceContent().getFileManager();

0 commit comments

Comments
 (0)