From f528fdfdb6e0b04c275711a3625f49c765731d13 Mon Sep 17 00:00:00 2001 From: "Gupta, Surya" Date: Thu, 6 Aug 2026 22:34:06 +0530 Subject: [PATCH 1/6] [CSTACKEX-233] Subsequent VM Creation is failing for ISCSI Storage Pool on Oracle Linux --- .../kvm/storage/IscsiAdmStorageAdaptor.java | 61 +++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java index 495ae45a2896..d8ed59a4e66a 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java @@ -47,6 +47,9 @@ public class IscsiAdmStorageAdaptor implements StorageAdaptor { private static final Map MapStorageUuidToStoragePool = new HashMap<>(); + /** iscsiadm's ISCSI_ERR_NO_OBJS_FOUND: returned by "-m session" when no session is established. */ + private static final int ISCSI_ERR_NO_OBJS_FOUND = 21; + @Override public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, StoragePoolType storagePoolType, Map details, boolean isPrimaryStorage) { IscsiAdmStoragePool storagePool = new IscsiAdmStoragePool(uuid, host, port, storagePoolType, this); @@ -126,6 +129,8 @@ public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map null). + final boolean sessionPreExisted = sessionAlreadyActive || (result != null); + + if (sessionPreExisted) { + logger.info("sessionPreExisted : performing rescan explicitely"); rescanIscsiSessions(iqn, host, port); } @@ -156,6 +164,11 @@ public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map Date: Fri, 7 Aug 2026 16:13:02 +0530 Subject: [PATCH 2/6] [CSTACKEX-233] Added session exists error code check --- .../kvm/storage/IscsiAdmStorageAdaptor.java | 47 +++++++++++-------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java index d8ed59a4e66a..a20fce08833d 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java @@ -50,6 +50,9 @@ public class IscsiAdmStorageAdaptor implements StorageAdaptor { /** iscsiadm's ISCSI_ERR_NO_OBJS_FOUND: returned by "-m session" when no session is established. */ private static final int ISCSI_ERR_NO_OBJS_FOUND = 21; + /** iscsiadm's ISCSI_ERR_SESS_EXISTS: returned by "--login" when the session is already logged in (e.g. Ubuntu). */ + private static final int ISCSI_SESSION_EXISTS_CODE = 15; + @Override public KVMStoragePool createStoragePool(String uuid, String host, int port, String path, String userInfo, StoragePoolType storagePoolType, Map details, boolean isPrimaryStorage) { IscsiAdmStoragePool storagePool = new IscsiAdmStoragePool(uuid, host, port, storagePoolType, this); @@ -93,12 +96,16 @@ public KVMPhysicalDisk createPhysicalDisk(String volumeUuid, KVMStoragePool pool @Override public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map details, boolean isVMMigrate) { + final String host = pool.getSourceHost(); + final int port = pool.getSourcePort(); + final String iqn = getIqn(volumeUuid); + // ex. sudo iscsiadm -m node -T iqn.2012-03.com.test:volume1 -p 192.168.233.10:3260 -o new Script iScsiAdmCmd = new Script(true, "iscsiadm", 0, logger); iScsiAdmCmd.add("-m", "node"); - iScsiAdmCmd.add("-T", getIqn(volumeUuid)); - iScsiAdmCmd.add("-p", pool.getSourceHost() + ":" + pool.getSourcePort()); + iScsiAdmCmd.add("-T", iqn); + iScsiAdmCmd.add("-p", host + ":" + port); iScsiAdmCmd.add("-o", "new"); String result = iScsiAdmCmd.execute(); @@ -125,13 +132,11 @@ public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map null). - final boolean sessionPreExisted = sessionAlreadyActive || (result != null); - + // Newly mapped LUNs on an existing session are invisible until rescan. + // Prefer the pre-login session check (required on Oracle, where re-login exits 0). + // Also treat ISCSI_ERR_SESS_EXISTS as a hint (Ubuntu). if (sessionPreExisted) { - logger.info("sessionPreExisted : performing rescan explicitely"); + logger.debug("iSCSI session for target {} at {}:{} pre-existed, performing rescan", iqn, host, port); rescanIscsiSessions(iqn, host, port); } @@ -192,16 +198,19 @@ boolean handleNodeCreateResult(String result, String volumeUuid) { /** * Checks the result of an iscsiadm login command. - * Returns true if the login succeeded or session already exists, false on failure. + * Returns true if the session already existed (pre-check and/or ISCSI_ERR_SESS_EXISTS) + * or login succeeded with no error output, false on failure. + * + * sessionPreExisted must be checked first: on Ubuntu, re-login exits 15 with a non-null + * error message that would otherwise be treated as failure. */ - boolean handleLoginResult(String result, String volumeUuid) { - if (result == null) { - logger.debug("Successfully logged in to iSCSI target {}", volumeUuid); + boolean handleLoginResult(String result, boolean sessionPreExisted, String volumeUuid) { + if (sessionPreExisted) { + logger.debug("iSCSI session already active for target {}", volumeUuid); return true; } - String msg = result.toLowerCase(); - if (msg.contains("already present") || msg.contains("already logged in") || msg.contains("session exists")) { - logger.debug("iSCSI session already exists for target {}, proceeding", volumeUuid); + if (result == null) { + logger.debug("Successfully logged in to iSCSI target {}", volumeUuid); return true; } logger.debug("Failed to log in to iSCSI target {}: {}", volumeUuid, result); From 0271cef1abf4c800177c33493bbb27f502dcead9 Mon Sep 17 00:00:00 2001 From: "Gupta, Surya" Date: Wed, 12 Aug 2026 00:14:26 +0530 Subject: [PATCH 3/6] [CSTACKEX-233] Review Comments --- .../kvm/storage/IscsiAdmStorageAdaptor.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java index a20fce08833d..dfce3ade5ac8 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java @@ -150,7 +150,8 @@ public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map Date: Mon, 17 Aug 2026 23:31:41 +0530 Subject: [PATCH 4/6] [CSTACKEX-233] Address Review Comments --- .../kvm/storage/IscsiAdmStorageAdaptor.java | 76 +++++++++---------- 1 file changed, 34 insertions(+), 42 deletions(-) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java index dfce3ade5ac8..109c54189e21 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java @@ -132,33 +132,12 @@ public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map 0) { + while ((deviceSize = getPhysicalDisk(volumeUuid, pool).getSize()) == 0 && numberOfTries > 0) { numberOfTries--; try { Thread.sleep(timeBetweenTries); - } catch (Exception ex) { - // don't do anything + } catch (InterruptedException ex) { + logger.warn("Interrupted while waiting for iSCSI device {} to become available", volumeUuid, ex); + return false; } } + + return deviceSize > 0; } private void waitForDiskToBecomeUnavailable(String host, int port, String iqn, String lun) { From f87fdc0a8c8d33f9a8c0e749f351a3dc8952e8f9 Mon Sep 17 00:00:00 2001 From: "Gupta, Surya" Date: Thu, 20 Aug 2026 01:24:43 +0530 Subject: [PATCH 5/6] [CSTACKEX-233] Address Review Comments --- .../hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java index 109c54189e21..7813747e1a11 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java @@ -148,6 +148,9 @@ public boolean connectPhysicalDisk(String volumeUuid, KVMStoragePool pool, Map Date: Thu, 20 Aug 2026 14:11:52 +0530 Subject: [PATCH 6/6] [CSTACKEX-233] Added comment for \n split --- .../cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java index 7813747e1a11..3ec7407d1098 100644 --- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java +++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/storage/IscsiAdmStorageAdaptor.java @@ -236,6 +236,9 @@ private boolean isIscsiSessionActive(String iqn, String host, int port) { if (StringUtils.isBlank(sessions)) { return false; } + // AllLinesParser uses BufferedReader.readLine() (strips \n, \r\n, and \r) and then + // appends "\n" after each session. split("\n") depends on that separator to walk + // one session per line when multiple sessions are listed. for (String line : sessions.split("\n")) { if (line.contains(iqn) && line.contains(host)) { return true;