Skip to content

Commit 6508e45

Browse files
Srivastava, PiyushSrivastava, Piyush
authored andcommitted
test iGroup host 1
1 parent 0977378 commit 6508e45

File tree

4 files changed

+65
-43
lines changed

4 files changed

+65
-43
lines changed

plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/driver/OntapPrimaryDatastoreDriver.java

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet
128128
s_logger.error("createAsync: Storage Pool not found for id: " + dataStore.getId());
129129
throw new CloudRuntimeException("createAsync: Storage Pool not found for id: " + dataStore.getId());
130130
}
131-
String storagePoolUuid = dataStore.getUuid();
132131

133132
Map<String, String> details = storagePoolDetailsDao.listDetailsKeyPairs(dataStore.getId());
134133

@@ -145,7 +144,6 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet
145144
volumeVO.setPoolId(storagePool.getId());
146145

147146
if (ProtocolType.ISCSI.name().equalsIgnoreCase(details.get(Constants.PROTOCOL))) {
148-
String svmName = details.get(Constants.SVM_NAME);
149147
String lunName = created != null && created.getLun() != null ? created.getLun().getName() : null;
150148
if (lunName == null) {
151149
throw new CloudRuntimeException("createAsync: Missing LUN name for volume " + volInfo.getId());
@@ -158,17 +156,17 @@ public void createAsync(DataStore dataStore, DataObject dataObject, AsyncComplet
158156
volumeVO.setFolder(created.getLun().getUuid());
159157
}
160158

161-
// Create LUN-to-igroup mapping and retrieve the assigned LUN ID
162-
UnifiedSANStrategy sanStrategy = (UnifiedSANStrategy) Utility.getStrategyByStoragePoolDetails(details);
163-
String accessGroupName = Utility.getIgroupName(svmName, storagePoolUuid);
164-
String lunNumber = sanStrategy.ensureLunMapped(svmName, lunName, accessGroupName);
159+
// DO NOT map LUN to igroup here - mapping will be done in grantAccess() to per-host igroup
160+
// This ensures each host only sees LUNs mapped to its specific igroup during discovery
161+
// For per-host igroups, LUN mapping happens when VM is actually attached to a host
162+
s_logger.info("createAsync: Created LUN [{}] for volume [{}]. LUN mapping will occur during grantAccess() to per-host igroup.",
163+
lunName, volumeVO.getId());
165164

166-
// Construct iSCSI path: /<iqn>/<lun_id> format for KVM/libvirt attachment
167-
String iscsiPath = Constants.SLASH + storagePool.getPath() + Constants.SLASH + lunNumber;
168-
volumeVO.set_iScsiName(iscsiPath);
169-
volumeVO.setPath(iscsiPath);
170-
s_logger.info("createAsync: Volume [{}] iSCSI path set to {}", volumeVO.getId(), iscsiPath);
171-
createCmdResult = new CreateCmdResult(null, new Answer(null, true, null));
165+
// Path will be set during grantAccess when LUN is mapped and we get the LUN ID
166+
// Return LUN name as identifier for CloudStack tracking
167+
volumeVO.set_iScsiName(null);
168+
volumeVO.setPath(null);
169+
createCmdResult = new CreateCmdResult(lunName, new Answer(null, true, null));
172170

173171
} else if (ProtocolType.NFS3.name().equalsIgnoreCase(details.get(Constants.PROTOCOL))) {
174172
createCmdResult = new CreateCmdResult(volInfo.getUuid(), new Answer(null, true, null));
@@ -319,16 +317,23 @@ public boolean grantAccess(DataObject dataObject, Host host, DataStore dataStore
319317
// Only retrieve LUN name for iSCSI volumes
320318
String cloudStackVolumeName = volumeDetailsDao.findDetail(volumeVO.getId(), Constants.LUN_DOT_NAME).getValue();
321319
UnifiedSANStrategy sanStrategy = (UnifiedSANStrategy) Utility.getStrategyByStoragePoolDetails(details);
322-
String accessGroupName = Utility.getIgroupName(svmName, storagePoolUuid);
323-
324-
// Verify host initiator is registered in the igroup before allowing access
325-
if (!sanStrategy.validateInitiatorInAccessGroup(host.getStorageUrl(), svmName, accessGroupName)) {
326-
throw new CloudRuntimeException("grantAccess: Host initiator [" + host.getStorageUrl() +
327-
"] is not present in iGroup [" + accessGroupName + "]");
320+
// Use per-host igroup for this host
321+
// Each host sees only LUNs mapped to its per-host igroup, reducing discovery time
322+
String perHostIgroupName = Utility.getPerHostIgroupName(svmName, storagePoolUuid, host.getName());
323+
s_logger.info("grantAccess: Mapping LUN to per-host igroup [{}] for host [{}]", perHostIgroupName, host.getName());
324+
325+
// Validate per-host igroup exists with the host's initiator
326+
if (!sanStrategy.validateInitiatorInAccessGroup(host.getStorageUrl(), svmName, perHostIgroupName)) {
327+
String errMsg = String.format("grantAccess: Per-host igroup [%s] does not exist or does not contain host initiator [%s]. " +
328+
"Per-host igroup must be created during host-pool attachment.",
329+
perHostIgroupName, host.getStorageUrl());
330+
s_logger.error(errMsg);
331+
throw new CloudRuntimeException(errMsg);
328332
}
329333

330-
// Create or retrieve existing LUN mapping
331-
String lunNumber = sanStrategy.ensureLunMapped(svmName, cloudStackVolumeName, accessGroupName);
334+
// Map LUN to the per-host igroup
335+
String lunNumber = sanStrategy.ensureLunMapped(svmName,cloudStackVolumeName, perHostIgroupName);
336+
s_logger.info("grantAccess: LUN [{}] mapped to per-host igroup [{}] with LUN ID [{}]", cloudStackVolumeName, perHostIgroupName, lunNumber);
332337

333338
// Update volume path if changed (e.g., after migration or re-mapping)
334339
String iscsiPath = Constants.SLASH + storagePool.getPath() + Constants.SLASH + lunNumber;
@@ -427,7 +432,9 @@ private void revokeAccessForVolume(StoragePoolVO storagePool, VolumeVO volumeVO,
427432
String storagePoolUuid = storagePool.getUuid();
428433

429434
if (ProtocolType.ISCSI.name().equalsIgnoreCase(details.get(Constants.PROTOCOL))) {
430-
String accessGroupName = Utility.getIgroupName(svmName, storagePoolUuid);
435+
// Use per-host igroup for unmapping
436+
String perHostIgroupName = Utility.getPerHostIgroupName(svmName, storagePoolUuid, host.getName());
437+
s_logger.info("revokeAccessForVolume: Using per-host igroup [{}] for host [{}]", perHostIgroupName, host.getName());
431438

432439
// Retrieve LUN name from volume details; if missing, volume may not have been fully created
433440
String lunName = volumeDetailsDao.findDetail(volumeVO.getId(), Constants.LUN_DOT_NAME) != null ?
@@ -444,29 +451,29 @@ private void revokeAccessForVolume(StoragePoolVO storagePool, VolumeVO volumeVO,
444451
return;
445452
}
446453

447-
// Verify igroup still exists on ONTAP
448-
AccessGroup accessGroup = getAccessGroupByName(storageStrategy, svmName, accessGroupName);
454+
// Verify per-host igroup still exists on ONTAP
455+
AccessGroup accessGroup = getAccessGroupByName(storageStrategy, svmName, perHostIgroupName);
449456
if (accessGroup == null || accessGroup.getIgroup() == null || accessGroup.getIgroup().getUuid() == null) {
450-
s_logger.warn("revokeAccessForVolume: iGroup [{}] not found on ONTAP, skipping revoke", accessGroupName);
457+
s_logger.warn("revokeAccessForVolume: Per-host iGroup [{}] not found on ONTAP, skipping revoke", perHostIgroupName);
451458
return;
452459
}
453460

454-
// Verify host initiator is in the igroup before attempting to remove mapping
461+
// Verify host initiator is in the per-host igroup before attempting to remove mapping
455462
SANStrategy sanStrategy = (UnifiedSANStrategy) storageStrategy;
456463
if (!sanStrategy.validateInitiatorInAccessGroup(host.getStorageUrl(), svmName, accessGroup.getIgroup().getName())) {
457-
s_logger.warn("revokeAccessForVolume: Initiator [{}] is not in iGroup [{}], skipping revoke",
458-
host.getStorageUrl(), accessGroupName);
464+
s_logger.warn("revokeAccessForVolume: Initiator [{}] is not in per-host iGroup [{}], skipping revoke",
465+
host.getStorageUrl(), perHostIgroupName);
459466
return;
460467
}
461468

462-
// Remove the LUN mapping from the igroup
469+
// Remove the LUN mapping from the per-host igroup
463470
Map<String, String> disableLogicalAccessMap = new HashMap<>();
464471
disableLogicalAccessMap.put(Constants.LUN_DOT_UUID, cloudStackVolume.getLun().getUuid());
465472
disableLogicalAccessMap.put(Constants.IGROUP_DOT_UUID, accessGroup.getIgroup().getUuid());
466473
storageStrategy.disableLogicalAccess(disableLogicalAccessMap);
467474

468-
s_logger.info("revokeAccessForVolume: Successfully revoked access to LUN [{}] for host [{}]",
469-
lunName, host.getName());
475+
s_logger.info("revokeAccessForVolume: Successfully revoked access to LUN [{}] from per-host igroup [{}] for host [{}]",
476+
lunName, perHostIgroupName, host.getName());
470477
}
471478
}
472479

plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,11 @@ public boolean attachCluster(DataStore dataStore, ClusterScope scope) {
304304
accessGroupRequest.setScope(scope);
305305
primaryStore.setDetails(details);// setting details as it does not come from cloudstack
306306
accessGroupRequest.setPrimaryDataStoreInfo(primaryStore);
307-
strategy.createAccessGroup(accessGroupRequest);
307+
// TODO for now skipping igroup creation for iscsi for testing igroup per host
308+
if(ProtocolType.NFS3.name().equalsIgnoreCase(details.get(Constants.PROTOCOL))){
309+
strategy.createAccessGroup(accessGroupRequest);
310+
}
311+
308312
} catch (Exception e) {
309313
s_logger.error("attachCluster: Failed to create access group on storage system for cluster: " + primaryStore.getClusterId() + ". Exception: " + e.getMessage());
310314
throw new CloudRuntimeException("attachCluster: Failed to create access group on storage system for cluster: " + primaryStore.getClusterId() + ". Exception: " + e.getMessage());

plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/UnifiedSANStrategy.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -585,18 +585,18 @@ public Map<String, String> getLogicalAccess(Map<String, String> values) {
585585
public String ensureLunMapped(String svmName, String lunName, String accessGroupName) {
586586
s_logger.info("ensureLunMapped: Ensuring LUN [{}] is mapped to igroup [{}] on SVM [{}]", lunName, accessGroupName, svmName);
587587

588-
// Check existing map first
589-
Map<String, String> getMap = Map.of(
590-
Constants.LUN_DOT_NAME, lunName,
591-
Constants.SVM_DOT_NAME, svmName,
592-
Constants.IGROUP_DOT_NAME, accessGroupName
593-
);
594-
Map<String, String> mapResp = getLogicalAccess(getMap);
595-
if (mapResp != null && mapResp.containsKey(Constants.LOGICAL_UNIT_NUMBER)) {
596-
String lunNumber = mapResp.get(Constants.LOGICAL_UNIT_NUMBER);
597-
s_logger.info("ensureLunMapped: Existing LunMap found for LUN [{}] in igroup [{}] with LUN number [{}]", lunName, accessGroupName, lunNumber);
598-
return lunNumber;
599-
}
588+
// // Check existing map first
589+
// Map<String, String> getMap = Map.of(
590+
// Constants.LUN_DOT_NAME, lunName,
591+
// Constants.SVM_DOT_NAME, svmName,
592+
// Constants.IGROUP_DOT_NAME, accessGroupName
593+
// );
594+
// Map<String, String> mapResp = getLogicalAccess(getMap);
595+
// if (mapResp != null && mapResp.containsKey(Constants.LOGICAL_UNIT_NUMBER)) {
596+
// String lunNumber = mapResp.get(Constants.LOGICAL_UNIT_NUMBER);
597+
// s_logger.info("ensureLunMapped: Existing LunMap found for LUN [{}] in igroup [{}] with LUN number [{}]", lunName, accessGroupName, lunNumber);
598+
// return lunNumber;
599+
// }
600600

601601
// Create if not exists
602602
Map<String, String> enableMap = Map.of(

plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/utils/Utility.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,17 @@ public static String getIgroupName(String svmName, String poolUuid) {
144144
return Constants.CS + Constants.UNDERSCORE + svmName + Constants.UNDERSCORE + poolUuid;
145145
}
146146

147+
/**
148+
* Generate per-host igroup name for improved iSCSI performance.
149+
* Each host gets its own igroup, so it only sees LUNs mapped to it.
150+
* Format: cs_svmName_poolUuid_hostName
151+
*/
152+
public static String getPerHostIgroupName(String svmName, String poolUuid, String hostName) {
153+
// Sanitize host name: remove domain, spaces, special chars
154+
String sanitizedHostName = hostName.split("\\.")[0].replaceAll("[^a-zA-Z0-9_-]", "_");
155+
return Constants.CS + Constants.UNDERSCORE + svmName + Constants.UNDERSCORE + poolUuid + Constants.UNDERSCORE + sanitizedHostName;
156+
}
157+
147158
public static String generateExportPolicyName(String svmName, String volumeName){
148159
return Constants.EXPORT + Constants.HYPHEN + svmName + Constants.HYPHEN + volumeName;
149160
}

0 commit comments

Comments
 (0)