Skip to content

Commit 6ee6603

Browse files
rg9975GLOVER RENEsureshanaparti
authored
Updates to HPE-Primera and Pure FlashArray Drivers to use Host-based VLUN Assignments (apache#8889)
* Updates to change PUre and Primera to host-centric vlun assignments; various small bug fixes * update to add timestamp when deleting pure volumes to avoid future conflicts * update to migrate to properly check disk offering is valid for the target storage pool * Updates to change PUre and Primera to host-centric vlun assignments; various small bug fixes * update to add timestamp when deleting pure volumes to avoid future conflicts * update to migrate to properly check disk offering is valid for the target storage pool * improve error handling when copying volumes to add precision to which step failed * rename pure volume before delete to avoid conflicts if the same name is used before its expunged on the array * remove dead code in AdaptiveDataStoreLifeCycleImpl.java * Fix issues found in PR checks * fix session refresh TTL logic * updates from PR comments * logic to delete by path ONLY on supported OUI * fix to StorageSystemDataMotionStrategy compile error * change noisy debug message to trace message * fix double callback call in handleVolumeMigrationFromNonManagedStorageToManagedStorage * fix for flash array delete error * fix typo in StorageSystemDataMotionStrategy * change copyVolume to use writeback to speed up copy ops * remove returning PrimaryStorageDownloadAnswer when connectPhysicalDisk returns false during KVMStorageProcessor template copy * remove change to only set UUID on snapshot if it is a vmSnapshot * reverting change to UserVmManagerImpl.configureCustomRootDiskSize * add error checking/simplification per comments from @slavkap * Update engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java Co-authored-by: Suresh Kumar Anaparti <[email protected]> * address PR comments from @sureshanaparti --------- Co-authored-by: GLOVER RENE <[email protected]> Co-authored-by: Suresh Kumar Anaparti <[email protected]>
1 parent 42e7117 commit 6ee6603

File tree

36 files changed

+1162
-654
lines changed

36 files changed

+1162
-654
lines changed

Diff for: engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java

+4-5
Original file line numberDiff line numberDiff line change
@@ -1504,18 +1504,17 @@ public void prepareForMigration(VirtualMachineProfile vm, DeployDestination dest
15041504

15051505
for (VolumeVO vol : vols) {
15061506
VolumeInfo volumeInfo = volFactory.getVolume(vol.getId());
1507-
DataTO volTO = volumeInfo.getTO();
1508-
DiskTO disk = storageMgr.getDiskWithThrottling(volTO, vol.getVolumeType(), vol.getDeviceId(), vol.getPath(), vm.getServiceOfferingId(), vol.getDiskOfferingId());
15091507
DataStore dataStore = dataStoreMgr.getDataStore(vol.getPoolId(), DataStoreRole.Primary);
15101508

1511-
disk.setDetails(getDetails(volumeInfo, dataStore));
1512-
15131509
PrimaryDataStore primaryDataStore = (PrimaryDataStore)dataStore;
15141510
// This might impact other managed storages, enable requires access for migration in relevant datastore driver (currently enabled for PowerFlex storage pool only)
15151511
if (primaryDataStore.isManaged() && volService.requiresAccessForMigration(volumeInfo, dataStore)) {
15161512
volService.grantAccess(volFactory.getVolume(vol.getId()), dest.getHost(), dataStore);
15171513
}
1518-
1514+
// make sure this is done AFTER grantAccess, as grantAccess may change the volume's state
1515+
DataTO volTO = volumeInfo.getTO();
1516+
DiskTO disk = storageMgr.getDiskWithThrottling(volTO, vol.getVolumeType(), vol.getDeviceId(), vol.getPath(), vm.getServiceOfferingId(), vol.getDiskOfferingId());
1517+
disk.setDetails(getDetails(volumeInfo, dataStore));
15191518
vm.addDisk(disk);
15201519
}
15211520

Diff for: engine/storage/datamotion/src/main/java/org/apache/cloudstack/storage/motion/StorageSystemDataMotionStrategy.java

+193-114
Large diffs are not rendered by default.

Diff for: framework/spring/module/src/main/java/org/apache/cloudstack/spring/module/model/impl/DefaultModuleDefinitionSet.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,9 @@ public void with(ModuleDefinition def, Stack<ModuleDefinition> parents) {
101101
log.debug(String.format("Trying to obtain module [%s] context.", moduleDefinitionName));
102102
ApplicationContext context = getApplicationContext(moduleDefinitionName);
103103
try {
104-
if (context.containsBean("moduleStartup")) {
104+
if (context == null) {
105+
log.warn(String.format("Application context not found for module definition [%s]", moduleDefinitionName));
106+
} else if (context.containsBean("moduleStartup")) {
105107
Runnable runnable = context.getBean("moduleStartup", Runnable.class);
106108
log.info(String.format("Starting module [%s].", moduleDefinitionName));
107109
runnable.run();

Diff for: plugins/acl/dynamic-role-based/src/main/java/org/apache/cloudstack/acl/DynamicRoleBasedAPIAccessChecker.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@ public boolean checkAccess(Account account, String commandName) {
122122
}
123123

124124
if (accountRole.getRoleType() == RoleType.Admin && accountRole.getId() == RoleType.Admin.getId()) {
125-
LOGGER.info(String.format("Account [%s] is Root Admin or Domain Admin, all APIs are allowed.", account));
125+
if (LOGGER.isTraceEnabled()) {
126+
LOGGER.trace(String.format("Account [%s] is Root Admin or Domain Admin, all APIs are allowed.", account));
127+
}
126128
return true;
127129
}
128130

Diff for: plugins/acl/project-role-based/src/main/java/org/apache/cloudstack/acl/ProjectRoleBasedApiAccessChecker.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ public List<String> getApisAllowedToUser(Role role, User user, List<String> apiN
7676

7777
Project project = CallContext.current().getProject();
7878
if (project == null) {
79-
LOGGER.warn(String.format("Project is null, ProjectRoleBasedApiAccessChecker only applies to projects, returning APIs [%s] for user [%s] as allowed.", apiNames, user));
79+
if (LOGGER.isTraceEnabled()) {
80+
LOGGER.trace(String.format("Project is null, ProjectRoleBasedApiAccessChecker only applies to projects, returning APIs [%s] for user [%s] as allowed.", apiNames, user));
81+
}
8082
return apiNames;
8183
}
8284

@@ -114,8 +116,10 @@ public boolean checkAccess(User user, String apiCommandName) throws PermissionDe
114116

115117
Project project = CallContext.current().getProject();
116118
if (project == null) {
117-
LOGGER.warn(String.format("Project is null, ProjectRoleBasedApiAccessChecker only applies to projects, returning API [%s] for user [%s] as allowed.", apiCommandName,
119+
if (LOGGER.isTraceEnabled()) {
120+
LOGGER.trace(String.format("Project is null, ProjectRoleBasedApiAccessChecker only applies to projects, returning API [%s] for user [%s] as allowed.", apiCommandName,
118121
user));
122+
}
119123
return true;
120124
}
121125

Diff for: plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/wrapper/LibvirtMigrateVolumeCommandWrapper.java

+15-3
Original file line numberDiff line numberDiff line change
@@ -302,15 +302,27 @@ protected MigrateVolumeAnswer migrateRegularVolume(final MigrateVolumeCommand co
302302
(destVolumeObjectTO.getPath() != null ? destVolumeObjectTO.getPath() : UUID.randomUUID().toString());
303303

304304
try {
305-
storagePoolManager.connectPhysicalDisk(srcPrimaryDataStore.getPoolType(), srcPrimaryDataStore.getUuid(), srcPath, srcDetails);
305+
KVMStoragePool sourceStoragePool = storagePoolManager.getStoragePool(srcPrimaryDataStore.getPoolType(), srcPrimaryDataStore.getUuid());
306+
307+
if (!sourceStoragePool.connectPhysicalDisk(srcPath, srcDetails)) {
308+
return new MigrateVolumeAnswer(command, false, "Unable to connect source volume on hypervisor", srcPath);
309+
}
306310

307311
KVMPhysicalDisk srcPhysicalDisk = storagePoolManager.getPhysicalDisk(srcPrimaryDataStore.getPoolType(), srcPrimaryDataStore.getUuid(), srcPath);
312+
if (srcPhysicalDisk == null) {
313+
return new MigrateVolumeAnswer(command, false, "Unable to get handle to source volume on hypervisor", srcPath);
314+
}
308315

309316
KVMStoragePool destPrimaryStorage = storagePoolManager.getStoragePool(destPrimaryDataStore.getPoolType(), destPrimaryDataStore.getUuid());
310317

311-
storagePoolManager.connectPhysicalDisk(destPrimaryDataStore.getPoolType(), destPrimaryDataStore.getUuid(), destPath, destDetails);
318+
if (!destPrimaryStorage.connectPhysicalDisk(destPath, destDetails)) {
319+
return new MigrateVolumeAnswer(command, false, "Unable to connect destination volume on hypervisor", srcPath);
320+
}
312321

313-
storagePoolManager.copyPhysicalDisk(srcPhysicalDisk, destPath, destPrimaryStorage, command.getWaitInMillSeconds());
322+
KVMPhysicalDisk newDiskCopy = storagePoolManager.copyPhysicalDisk(srcPhysicalDisk, destPath, destPrimaryStorage, command.getWaitInMillSeconds());
323+
if (newDiskCopy == null) {
324+
return new MigrateVolumeAnswer(command, false, "Copy command failed to return handle to copied physical disk", destPath);
325+
}
314326
}
315327
catch (Exception ex) {
316328
return new MigrateVolumeAnswer(command, false, ex.getMessage(), null);

Diff for: plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/FiberChannelAdapter.java

+28
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,36 @@
1616
// under the License.
1717
package com.cloud.hypervisor.kvm.storage;
1818

19+
import java.net.InetAddress;
20+
import java.net.UnknownHostException;
21+
22+
import org.apache.log4j.Logger;
23+
1924
import com.cloud.storage.Storage;
2025
import com.cloud.utils.exception.CloudRuntimeException;
2126

2227
@StorageAdaptorInfo(storagePoolType=Storage.StoragePoolType.FiberChannel)
2328
public class FiberChannelAdapter extends MultipathSCSIAdapterBase {
29+
30+
private Logger LOGGER = Logger.getLogger(getClass());
31+
32+
private String hostname = null;
33+
private String hostnameFq = null;
34+
2435
public FiberChannelAdapter() {
2536
LOGGER.info("Loaded FiberChannelAdapter for StorageLayer");
37+
// get the hostname - we need this to compare to connid values
38+
try {
39+
InetAddress inetAddress = InetAddress.getLocalHost();
40+
hostname = inetAddress.getHostName(); // basic hostname
41+
if (hostname.indexOf(".") > 0) {
42+
hostname = hostname.substring(0, hostname.indexOf(".")); // strip off domain
43+
}
44+
hostnameFq = inetAddress.getCanonicalHostName(); // fully qualified hostname
45+
LOGGER.info("Loaded FiberChannelAdapter for StorageLayer on host [" + hostname + "]");
46+
} catch (UnknownHostException e) {
47+
LOGGER.error("Error getting hostname", e);
48+
}
2649
}
2750

2851
@Override
@@ -72,6 +95,11 @@ public AddressInfo parseAndValidatePath(String inPath) {
7295
address = value;
7396
} else if (key.equals("connid")) {
7497
connectionId = value;
98+
} else if (key.startsWith("connid.")) {
99+
String inHostname = key.substring(7);
100+
if (inHostname != null && (inHostname.equals(this.hostname) || inHostname.equals(this.hostnameFq))) {
101+
connectionId = value;
102+
}
75103
}
76104
}
77105
}

Diff for: plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/KVMStorageProcessor.java

+14-5
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ public Answer copyTemplateToPrimaryStorage(final CopyCommand cmd) {
268268

269269
Map<String, String> details = primaryStore.getDetails();
270270

271-
String path = details != null ? details.get("managedStoreTarget") : null;
271+
String path = derivePath(primaryStore, destData, details);
272272

273273
if (!storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), path, details)) {
274274
s_logger.warn("Failed to connect physical disk at path: " + path + ", in storage pool id: " + primaryStore.getUuid());
@@ -328,6 +328,16 @@ public Answer copyTemplateToPrimaryStorage(final CopyCommand cmd) {
328328
}
329329
}
330330

331+
private String derivePath(PrimaryDataStoreTO primaryStore, DataTO destData, Map<String, String> details) {
332+
String path = null;
333+
if (primaryStore.getPoolType() == StoragePoolType.FiberChannel) {
334+
path = destData.getPath();
335+
} else {
336+
path = details != null ? details.get("managedStoreTarget") : null;
337+
}
338+
return path;
339+
}
340+
331341
// this is much like PrimaryStorageDownloadCommand, but keeping it separate. copies template direct to root disk
332342
private KVMPhysicalDisk templateToPrimaryDownload(final String templateUrl, final KVMStoragePool primaryPool, final String volUuid, final Long size, final int timeout) {
333343
final int index = templateUrl.lastIndexOf("/");
@@ -407,7 +417,7 @@ public Answer cloneVolumeFromBaseTemplate(final CopyCommand cmd) {
407417
vol = templateToPrimaryDownload(templatePath, primaryPool, volume.getUuid(), volume.getSize(), cmd.getWaitInMillSeconds());
408418
} if (primaryPool.getType() == StoragePoolType.PowerFlex) {
409419
Map<String, String> details = primaryStore.getDetails();
410-
String path = details != null ? details.get("managedStoreTarget") : null;
420+
String path = derivePath(primaryStore, destData, details);
411421

412422
if (!storagePoolMgr.connectPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), templatePath, details)) {
413423
s_logger.warn("Failed to connect base template volume at path: " + templatePath + ", in storage pool id: " + primaryStore.getUuid());
@@ -1048,7 +1058,7 @@ public Answer backupSnapshot(final CopyCommand cmd) {
10481058
srcVolume.clearPassphrase();
10491059
if (isCreatedFromVmSnapshot) {
10501060
s_logger.debug("Ignoring removal of vm snapshot on primary as this snapshot is created from vm snapshot");
1051-
} else if (primaryPool.getType() != StoragePoolType.RBD) {
1061+
} else if (primaryPool != null && primaryPool.getType() != StoragePoolType.RBD) {
10521062
deleteSnapshotOnPrimary(cmd, snapshot, primaryPool);
10531063
}
10541064

@@ -2482,8 +2492,7 @@ public Answer copyVolumeFromPrimaryToPrimary(CopyCommand cmd) {
24822492
if (!storagePoolMgr.connectPhysicalDisk(destPrimaryStore.getPoolType(), destPrimaryStore.getUuid(), destVolumePath, destPrimaryStore.getDetails())) {
24832493
s_logger.warn("Failed to connect dest volume at path: " + destVolumePath + ", in storage pool id: " + destPrimaryStore.getUuid());
24842494
}
2485-
String managedStoreTarget = destPrimaryStore.getDetails() != null ? destPrimaryStore.getDetails().get("managedStoreTarget") : null;
2486-
destVolumeName = managedStoreTarget != null ? managedStoreTarget : destVolumePath;
2495+
destVolumeName = derivePath(destPrimaryStore, destData, destPrimaryStore.getDetails());
24872496
} else {
24882497
final String volumeName = UUID.randomUUID().toString();
24892498
destVolumeName = volumeName + "." + destFormat.getFileExtension();

0 commit comments

Comments
 (0)