Skip to content

Commit dbff797

Browse files
Srivastava, PiyushSrivastava, Piyush
authored andcommitted
removing the changes in iscsiadmadapter which were introduced for ontap as new adapter for ontap exist now
1 parent ee919af commit dbff797

1 file changed

Lines changed: 21 additions & 183 deletions

File tree

‎plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java‎

Lines changed: 21 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,9 @@
1616
// under the License.
1717
package com.cloud.hypervisor.kvm.storage;
1818

19-
import java.io.File;
20-
import java.io.FileWriter;
21-
import java.nio.file.Path;
2219
import java.util.HashMap;
2320
import java.util.List;
2421
import java.util.Map;
25-
import java.nio.file.Files;
26-
import java.nio.file.Paths;
2722

2823
import org.apache.cloudstack.utils.qemu.QemuImg;
2924
import org.apache.cloudstack.utils.qemu.QemuImg.PhysicalDiskFormat;
@@ -100,8 +95,14 @@ public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map<S
10095

10196
String result = iScsiAdmCmd.execute();
10297

103-
if (!handleNodeCreateResult(result, volumeUuid)) {
98+
if (result != null) {
99+
logger.debug("Failed to add iSCSI target " + volumeUuid);
100+
System.out.println("Failed to add iSCSI target " + volumeUuid);
101+
104102
return false;
103+
} else {
104+
logger.debug("Successfully added iSCSI target " + volumeUuid);
105+
System.out.println("Successfully added to iSCSI target " + volumeUuid);
105106
}
106107

107108
String chapInitiatorUsername = details.get(DiskTO.CHAP_INITIATOR_USERNAME);
@@ -122,26 +123,24 @@ public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map<S
122123
}
123124
}
124125

125-
final String host = pool.getSourceHost();
126-
final int port = pool.getSourcePort();
127-
final String iqn = getIqn(volumeUuid);
128-
129-
// Always try to login; treat benign outcomes as success (idempotent)
126+
// ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 --login
130127
iScsiAdmCmd = new Script(true, "iscsiadm", 0, logger);
128+
131129
iScsiAdmCmd.add("-m", "node");
132-
iScsiAdmCmd.add("-T", iqn);
133-
iScsiAdmCmd.add("-p", host + ":" + port);
130+
iScsiAdmCmd.add("-T", getIqn(volumeUuid));
131+
iScsiAdmCmd.add("-p", pool.getSourceHost() + ":" + pool.getSourcePort());
134132
iScsiAdmCmd.add("--login");
135133

136134
result = iScsiAdmCmd.execute();
137135

138-
if (!handleLoginResult(result, volumeUuid)) {
139-
return false;
140-
}
141-
142-
// If the session already existed, a newly mapped LUN won't be visible until a rescan.
143136
if (result != null) {
144-
rescanIscsiSessions(iqn, host, port);
137+
logger.debug("Failed to log in to iSCSI target " + volumeUuid);
138+
System.out.println("Failed to log in to iSCSI target " + volumeUuid);
139+
140+
return false;
141+
} else {
142+
logger.debug("Successfully logged in to iSCSI target " + volumeUuid);
143+
System.out.println("Successfully logged in to iSCSI target " + volumeUuid);
145144
}
146145

147146
// There appears to be a race condition where logging in to the iSCSI volume via iscsiadm
@@ -159,56 +158,6 @@ public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map<S
159158
return true;
160159
}
161160

162-
/**
163-
* Checks the result of an iscsiadm node-create command.
164-
* Returns true if the node was created or already exists, false on failure.
165-
*/
166-
boolean handleNodeCreateResult(String result, String volumeUuid) {
167-
if (result == null) {
168-
logger.debug("Successfully added iSCSI node for target {}", volumeUuid);
169-
return true;
170-
}
171-
String msg = result.toLowerCase();
172-
if (msg.contains("already exists") || msg.contains("database exists") || msg.contains("exists")) {
173-
logger.debug("iSCSI node already exists for target {}, proceeding", volumeUuid);
174-
return true;
175-
}
176-
logger.debug("Failed to add iSCSI node for target {}: {}", volumeUuid, result);
177-
return false;
178-
}
179-
180-
/**
181-
* Checks the result of an iscsiadm login command.
182-
* Returns true if the login succeeded or session already exists, false on failure.
183-
*/
184-
boolean handleLoginResult(String result, String volumeUuid) {
185-
if (result == null) {
186-
logger.debug("Successfully logged in to iSCSI target {}", volumeUuid);
187-
return true;
188-
}
189-
String msg = result.toLowerCase();
190-
if (msg.contains("already present") || msg.contains("already logged in") || msg.contains("session exists")) {
191-
logger.debug("iSCSI session already exists for target {}, proceeding", volumeUuid);
192-
return true;
193-
}
194-
logger.debug("Failed to log in to iSCSI target {}: {}", volumeUuid, result);
195-
return false;
196-
}
197-
198-
private void rescanIscsiSessions(String iqn, String host, int port) {
199-
Script rescanCmd = new Script(true, "iscsiadm", 0, logger);
200-
rescanCmd.add("-m", "node");
201-
rescanCmd.add("-T", iqn);
202-
rescanCmd.add("-p", host + ":" + port);
203-
rescanCmd.add("--rescan");
204-
String rescanResult = rescanCmd.execute();
205-
if (rescanResult != null) {
206-
logger.warn("iSCSI session rescan returned: {}", rescanResult);
207-
} else {
208-
logger.debug("iSCSI session rescan completed successfully for {}@{}:{}", iqn, host, port);
209-
}
210-
}
211-
212161
private void waitForDiskToBecomeAvailable(String volumeUuid, KVMStoragePool pool) {
213162
int numberOfTries = 10;
214163
int timeBetweenTries = 1000;
@@ -289,16 +238,6 @@ public KVMPhysicalDisk getPhysicalDisk(String volumeUuid, KVMStoragePool pool) {
289238
}
290239

291240
private long getDeviceSize(String deviceByPath) {
292-
try {
293-
if (!Files.exists(Paths.get(deviceByPath))) {
294-
logger.debug("Device by-path does not exist yet: " + deviceByPath);
295-
return 0L;
296-
}
297-
} catch (Exception ex) {
298-
// If FS check fails for any reason, fall back to blockdev call
299-
logger.error("Error fetching device size for {}", deviceByPath, ex);
300-
}
301-
302241
Script iScsiAdmCmd = new Script(true, "blockdev", 0, logger);
303242

304243
iScsiAdmCmd.add("--getsize64", deviceByPath);
@@ -341,96 +280,8 @@ private String getComponent(String path, int index) {
341280
return tmp[index].trim();
342281
}
343282

344-
/**
345-
* Check if there are other LUNs on the same iSCSI target (IQN) that are still
346-
* visible as block devices. This is needed because ONTAP uses a single IQN per
347-
* SVM — logging out of the target would kill ALL LUNs, not just the one being
348-
* disconnected.
349-
*
350-
* Checks /dev/disk/by-path/ for symlinks matching the same host:port + IQN but
351-
* with a different LUN number.
352-
*/
353-
private boolean hasOtherActiveLuns(String host, int port, String iqn, String lun) {
354-
String prefix = "ip-" + host + ":" + port + "-iscsi-" + iqn + "-lun-";
355-
File byPathDir = new File("/dev/disk/by-path");
356-
if (!byPathDir.exists() || !byPathDir.isDirectory()) {
357-
return false;
358-
}
359-
File[] entries = byPathDir.listFiles();
360-
if (entries == null) {
361-
return false;
362-
}
363-
for (File entry : entries) {
364-
String name = entry.getName();
365-
// Skip partition entries (e.g. lun-0-part1, lun-0-part2) — these are not
366-
// independent LUNs, they are partition symlinks for the same LUN disk.
367-
// Only count actual LUN entries (no "-part" suffix after the lun number).
368-
if (name.startsWith(prefix) && !name.equals(prefix + lun) && !name.contains("-part")) {
369-
logger.debug("Found other active LUN on same target: " + name);
370-
return true;
371-
}
372-
}
373-
return false;
374-
}
375-
376-
/**
377-
* Removes a single stale SCSI device from the kernel using the sysfs interface.
378-
*
379-
* When ONTAP unmaps a LUN from the host's igroup, the by-path symlink and the
380-
* underlying SCSI device (/dev/sdX) remain present in the kernel until explicitly
381-
* removed — the kernel does not auto-remove devices from live iSCSI sessions.
382-
*
383-
* This method resolves the by-path symlink to the real block device name (e.g. sdd),
384-
* then writes "1" to /sys/block/<dev>/device/delete — the standard Linux kernel SCSI
385-
* API for removing a single device without tearing down the entire iSCSI session.
386-
* Once the kernel processes the delete, it also removes the by-path symlink.
387-
*
388-
* This is used instead of iscsiadm --logout when other LUNs on the same IQN are still
389-
* active (ONTAP single-IQN-per-SVM model), since logout would tear down ALL LUNs.
390-
*/
391-
private void removeStaleScsiDevice(String host, int port, String iqn, String lun) {
392-
String byPath = getByPath(host, port, "/" + iqn + "/" + lun);
393-
Path byPathLink = Paths.get(byPath);
394-
if (!Files.exists(byPathLink)) {
395-
logger.debug("by-path entry for LUN " + lun + " already gone, nothing to remove");
396-
return;
397-
}
398-
try {
399-
Path realDevice = byPathLink.toRealPath();
400-
String devName = realDevice.getFileName().toString();
401-
File deleteFile = new File("/sys/block/" + devName + "/device/delete");
402-
if (!deleteFile.exists()) {
403-
logger.warn("sysfs delete entry not found for device " + devName + " — cannot remove stale SCSI device");
404-
return;
405-
}
406-
try (FileWriter fw = new FileWriter(deleteFile)) {
407-
fw.write("1");
408-
}
409-
logger.info("Removed stale SCSI device " + devName + " for LUN /" + iqn + "/" + lun + " via sysfs");
410-
} catch (Exception e) {
411-
logger.warn("Failed to remove stale SCSI device for LUN /" + iqn + "/" + lun + ": " + e.getMessage());
412-
}
413-
}
414-
415283
private boolean disconnectPhysicalDisk(String host, int port, String iqn, String lun) {
416-
// Check if other LUNs on the same IQN target are still in use.
417-
// ONTAP (and similar) uses a single IQN per SVM with multiple LUNs.
418-
// Doing iscsiadm --logout tears down the ENTIRE target session,
419-
// which would destroy access to ALL LUNs — not just the one being disconnected.
420-
if (hasOtherActiveLuns(host, port, iqn, lun)) {
421-
logger.info("Skipping iSCSI logout for /" + iqn + "/" + lun +
422-
" — other LUNs on the same target are still active. Removing stale SCSI device for this LUN only.");
423-
removeStaleScsiDevice(host, port, iqn, lun);
424-
// After removing this LUN's device, re-check: if no other LUNs remain active,
425-
// If it is the last one then must logout to clean up the iSCSI session entirely.
426-
if (hasOtherActiveLuns(host, port, iqn, lun)) {
427-
logger.info("Other LUNs still active after removing /" + iqn + "/" + lun + " — session kept alive.");
428-
return true;
429-
}
430-
logger.info("No more active LUNs on target after removing /" + iqn + "/" + lun + " — proceeding with iSCSI logout.");
431-
}
432-
433-
// No other LUNs active on this target — safe to logout and delete the node record.
284+
// use iscsiadm to log out of the iSCSI target and un-discover it
434285

435286
// ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 --logout
436287
Script iScsiAdmCmd = new Script(true, "iscsiadm", 0, logger);
@@ -536,8 +387,8 @@ public List<KVMPhysicalDisk> listPhysicalDisks(String storagePoolUuid, KVMStorag
536387

537388
@Override
538389
public KVMPhysicalDisk createDiskFromTemplate(KVMPhysicalDisk template, String name, PhysicalDiskFormat format,
539-
ProvisioningType provisioningType, long size,
540-
KVMStoragePool destPool, int timeout, byte[] passphrase) {
390+
ProvisioningType provisioningType, long size,
391+
KVMStoragePool destPool, int timeout, byte[] passphrase) {
541392
throw new UnsupportedOperationException("Creating a disk from a template is not yet supported for this configuration.");
542393
}
543394

@@ -571,19 +422,6 @@ public KVMPhysicalDisk copyPhysicalDisk(KVMPhysicalDisk srcDisk, String destVolu
571422
try {
572423
QemuImg q = new QemuImg(timeout);
573424
q.convert(srcFile, destFile);
574-
// Below fix is required when vendor depends on host based copy rather than storage CAN_CREATE_VOLUME_FROM_VOLUME capability
575-
// When host based template copy is triggered , small size template sits in RAM(depending on host memory and RAM) and copy is marked successful and by the time flush to storage is triggered
576-
// disconnectPhysicalDisk would disconnect the lun , hence template staying in RAM is not copied to storage lun. Below does flushing of data to storage and marking
577-
// copy as successful once flush is complete.
578-
Script flushCmd = new Script(true, "blockdev", 0, logger);
579-
flushCmd.add("--flushbufs", destDisk.getPath());
580-
String flushResult = flushCmd.execute();
581-
if (flushResult != null) {
582-
logger.warn("iSCSI copyPhysicalDisk: blockdev --flushbufs returned: {}", flushResult);
583-
}
584-
Script syncCmd = new Script(true, "sync", 0, logger);
585-
syncCmd.execute();
586-
logger.info("iSCSI copyPhysicalDisk: flush/sync completed ");
587425
} catch (QemuImgException | LibvirtException ex) {
588426
String msg = "Failed to copy data from " + srcDisk.getPath() + " to " +
589427
destDisk.getPath() + ". The error was the following: " + ex.getMessage();

0 commit comments

Comments
 (0)