Skip to content

CSTACKEX-127: Primary storage-pool is getting created even if desired data LIFs are not reachable#76

Open
sandeeplocharla wants to merge 1 commit into
mainfrom
feature/CSTACKEX-127
Open

CSTACKEX-127: Primary storage-pool is getting created even if desired data LIFs are not reachable#76
sandeeplocharla wants to merge 1 commit into
mainfrom
feature/CSTACKEX-127

Conversation

@sandeeplocharla

@sandeeplocharla sandeeplocharla commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Choosing IpInterface based on its status and affinity to the chosen aggregate

Description

This PR...

  1. Fixed an issue in picking an unavailable IP while creating the storage pool.
  2. When CloudStack creates an ONTAP primary storage pool, it now picks the best available network interface (LIF) using a priority-based selection:
    • Best case: Uses a LIF homed on the same node as the storage aggregate — optimal I/O, no warning
    • Degraded case: All home-node LIFs are down but a failover LIF is running on that node — pool is created, admin is warned
    • Fallback case: No LIF at all on the aggregate's node, pool is created using a LIF from a different node, admin is warned with a latency note
    • Failure case: No usable LIF anywhere, pool creation fails with a clear error

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)
  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Enhancement (improves an existing feature and functionality)
  • Cleanup (Code refactoring and cleanup, that may add test cases)
  • Build/CI
  • Test (unit or integration test code)

Feature/Enhancement Scale or Bug Severity

Feature/Enhancement Scale

  • Major
  • Minor

Bug Severity

  • BLOCKER
  • Critical
  • Major
  • Minor
  • Trivial

Screenshots (if appropriate):

How Has This Been Tested?

Note: The following images have been captured for NFS3, the same would be the case for iSCSI.

Screenshot 2026-07-08 at 6 55 32 AM

Clearly, by the virtue of free space available, the plugin would choose sti246_vsim_ocvs040d_aggr1 by default.

Scenario-1 [pool_P1]: Happy path; No LIFs were down.
Screenshot 2026-07-07 at 10 26 34 PM
Screenshot 2026-07-07 at 10 26 49 PM
Screenshot 2026-07-07 at 10 27 48 PM
The first best available LIF with current node and home node matching with the chosen node has been picked.

Scenario-2 [pool_P2_1]: LIFs on 040d node were down; with one LIF whose current node: 040d, while its home node: 040c
Screenshot 2026-07-07 at 10 28 38 PM
Screenshot 2026-07-07 at 10 28 50 PM
Screenshot 2026-07-07 at 11 05 22 PM
Screenshot 2026-07-07 at 11 05 43 PM

Scenario-3 [pool_P3]: None of the 040d node LIFs are UP. First best available LIF is picked from 040c.
Screenshot 2026-07-07 at 11 07 00 PM
Screenshot 2026-07-07 at 11 07 22 PM
Screenshot 2026-07-07 at 11 08 30 PM
Screenshot 2026-07-07 at 11 08 54 PM

@sandeeplocharla sandeeplocharla self-assigned this Jul 8, 2026
Copilot AI review requested due to automatic review settings July 8, 2026 01:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the ONTAP primary storage workflow to select a reachable/usable data LIF based on operational status and node affinity (aggregate home node vs. failover vs. cross-node fallback), and surfaces warnings via pool details/alerts when selection is degraded.

Changes:

  • Adds node-aware, status-aware LIF selection in StorageStrategy.getNetworkInterface() and returns both the chosen LIF IP + an optional warning.
  • Captures the chosen aggregate’s node during volume creation to bias LIF selection toward optimal locality.
  • Updates lifecycle + tests to handle the new (lifIp, warning) result and emits storage alerts when degraded selection occurs.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/service/StorageStrategyTest.java Expands unit tests for LIF status and node-affinity tiers; avoids mocking issues on newer JDKs.
plugins/storage/volume/ontap/src/test/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycleTest.java Updates mocks for new Pair<String,String> LIF return type and scope behavior.
plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/utils/OntapStorageUtils.java Adds helper to send storage alerts for degraded LIF selection.
plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/utils/OntapStorageConstants.java Adds constants for aggregate node/space fields and LIF state/location/warning keys.
plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/service/StorageStrategy.java Implements tiered LIF selection and tracks chosenAggregateNode from aggregate selection.
plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/lifecycle/OntapPrimaryDatastoreLifecycle.java Persists selected LIF + warning and emits an alert during pool initialization.
plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/feign/model/IpInterface.java Extends model with state, enabled, and location to support selection logic.
plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/feign/model/Aggregate.java Extends model with node and setters needed for reading/constructing detailed aggregate info.
plugins/storage/volume/ontap/src/main/java/org/apache/cloudstack/storage/feign/client/AggregateFeignClient.java Adds @QueryMap to request specific aggregate fields (node/space/state).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +159 to +165
Pair<String, String> lifResult;
try {
lifResult = storageStrategy.getNetworkInterface();
} catch (Exception e) {
logger.error("Exception occurred while retrieving network interface for pool: " + storagePoolName, e);
throw new CloudRuntimeException("Failed to retrieve Data LIF from ONTAP: " + e.getMessage(), e);
}
Comment on lines +275 to +277
if (aggrChosen.getNode() != null) {
this.chosenAggregateNode = aggrChosen.getNode().getName();
}
Comment on lines +500 to +506
for (IpInterface iface : response.getRecords()) {
if (!Boolean.TRUE.equals(iface.getEnabled()) || !OntapStorageConstants.LIF_STATE_UP.equals(iface.getState())) {
continue;
}
if (!isIPv4Address(iface.getIp().getAddress())) {
continue;
}
Comment on lines +549 to 552
} catch (Exception e) {
logger.error("Exception while retrieving network interfaces: ", e);
throw new CloudRuntimeException("Failed to retrieve network interfaces: " + e.getMessage());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants