Skip to content

retry NIC IP allocation instead of NPE when the allocating - #14038

Open
rootnomad wants to merge 2 commits into
apache:4.20from
rootnomad:fix/nic-allocation-race-npe
Open

rootnomad wants to merge 2 commits into
apache:4.20from
rootnomad:fix/nic-allocation-race-npe

Conversation

@rootnomad

@rootnomad rootnomad commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Description

checkForRaceAndAllocateNic dereferenced the requested NicProfile when a
concurrent deploy had already taken the IP (persistNicAfterRaceCheck returned
null). When the deploy passes no requested profile, requested is null, so the
losing thread threw a NullPointerException instead of nulling the IP and
retrying.

The null-requested path is the internal deploys that allocate a NIC without a
profile: Basic zone reallocate, and the control and management NICs on routers
and system VMs. User VM deploys build a NicProfile even when no IP is asked, so
they already retried correctly.

Null-guard the requested profile so a lost race retries the allocation.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)

Feature/Enhancement Scale or Bug Severity

Bug Severity

  • Minor

How Has This Been Tested?

Added a unit test that simulates losing the allocation race with no explicit IP
requested and asserts the allocation is retried rather than throwing a
NullPointerException. Also built the standard packages and deployed on a KVM
advanced zone.

@DaanHoogland DaanHoogland left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@nagaboinaramgopal can you see if this is applicable to older LTS branches?

@rootnomad
rootnomad force-pushed the fix/nic-allocation-race-npe branch from 82d4eb1 to d0fc3c2 Compare September 2, 2026 23:10
@rootnomad

Copy link
Copy Markdown
Contributor Author

Thanks @DaanHoogland . I removed the inline comment, the null-guard reads clearly on its own. And on the LTS question: the same deref of a possibly-null requested profile in checkForRaceAndAllocateNic is present on 4.19, 4.20 and 4.22, so this applies to all of them. Happy to open backport PRs once this merges, or to retarget to the oldest branch and let it merge forward, whichever you prefer.

@DaanHoogland

Copy link
Copy Markdown
Contributor

Thanks @DaanHoogland . I removed the inline comment, the null-guard reads clearly on its own. And on the LTS question: the same deref of a possibly-null requested profile in checkForRaceAndAllocateNic is present on 4.19, 4.20 and 4.22, so this applies to all of them. Happy to open backport PRs once this merges, or to retarget to the oldest branch and let it merge forward, whichever you prefer.

We have the custom to put fixes on the oldest open LTS branch (until january that will be 4.20) and than merge it forwards to newer LTS branches and main. So rebasing this (and some of your other contribution) on 4.20 would be great, thanks.

@rootnomad

Copy link
Copy Markdown
Contributor Author

Thanks @DaanHoogland . I removed the inline comment, the null-guard reads clearly on its own. And on the LTS question: the same deref of a possibly-null requested profile in checkForRaceAndAllocateNic is present on 4.19, 4.20 and 4.22, so this applies to all of them. Happy to open backport PRs once this merges, or to retarget to the oldest branch and let it merge forward, whichever you prefer.

We have the custom to put fixes on the oldest open LTS branch (until january that will be 4.20) and than merge it forwards to newer LTS branches and main. So rebasing this (and some of your other contribution) on 4.20 would be great, thanks.

Sounds good, thanks for explaining the workflow. I'll rebase this onto 4.20 and update the base, and do the same for my other bug-fix PRs so they merge forward. The two feature PRs (HA capacity reserve, event-driven DRS) I'll leave targeting main.

@DaanHoogland

Copy link
Copy Markdown
Contributor

Thanks @DaanHoogland . I removed the inline comment, the null-guard reads clearly on its own. And on the LTS question: the same deref of a possibly-null requested profile in checkForRaceAndAllocateNic is present on 4.19, 4.20 and 4.22, so this applies to all of them. Happy to open backport PRs once this merges, or to retarget to the oldest branch and let it merge forward, whichever you prefer.

We have the custom to put fixes on the oldest open LTS branch (until january that will be 4.20) and than merge it forwards to newer LTS branches and main. So rebasing this (and some of your other contribution) on 4.20 would be great, thanks.

Sounds good, thanks for explaining the workflow. I'll rebase this onto 4.20 and update the base, and do the same for my other bug-fix PRs so they merge forward. The two feature PRs (HA capacity reserve, event-driven DRS) I'll leave targeting main.

thanks, and welcome to the community ;)

…ce is lost

checkForRaceAndAllocateNic dereferenced the requested NicProfile when a
concurrent deploy had already taken the IP (persistNicAfterRaceCheck returned
null). On the common path the user requests no explicit IP, so requested is
null and the loser threw a NullPointerException instead of nulling the IP and
retrying. This defeats the ipv4AllocationRaceCheck retry for exactly the case
it exists for (bulk/autoscale/CKS deploys onto one network). Null-guard the
requested profile so the allocation is retried.
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch.

@rootnomad
rootnomad changed the base branch from main to 4.20 September 3, 2026 17:54
@DaanHoogland

Copy link
Copy Markdown
Contributor

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@DaanHoogland a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✖️ debian ✔️ suse15. SL-JID 19094

@DaanHoogland DaanHoogland added this to the 4.20.4 milestone Sep 4, 2026
@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✖️ el8 ✖️ el9 ✖️ debian ✖️ suse15. SL-JID 19122

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✖️ debian ✔️ suse15. SL-JID 19127

Fold the requested-IPv4 throw and the address reset under a single requested != null guard instead of repeating the check on both branches.
@codecov

codecov Bot commented Sep 8, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 16.35%. Comparing base (2cd8c5e) to head (75e8a0f).
⚠️ Report is 23 commits behind head on 4.20.

Files with missing lines Patch % Lines
...tack/engine/orchestration/NetworkOrchestrator.java 0.00% 4 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff            @@
##               4.20   #14038   +/-   ##
=========================================
  Coverage     16.34%   16.35%           
- Complexity    13574    13579    +5     
=========================================
  Files          5669     5669           
  Lines        501368   501406   +38     
  Branches      60903    60908    +5     
=========================================
+ Hits          81964    81996   +32     
+ Misses       410219   410214    -5     
- Partials       9185     9196   +11     
Flag Coverage Δ
uitests 4.14% <ø> (-0.01%) ⬇️
unittests 17.21% <0.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✖️ debian ✔️ suse15. SL-JID 19145

@DaanHoogland DaanHoogland changed the title engine: retry NIC IP allocation instead of NPE when the allocation ra… retry NIC IP allocation instead of NPE when the allocation ra… Sep 8, 2026
@DaanHoogland

Copy link
Copy Markdown
Contributor

@blueorangutan test

@DaanHoogland DaanHoogland left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

clgtm

@DaanHoogland

Copy link
Copy Markdown
Contributor

generic hardening, I think smoke tests should be enough for this one, cc @sureshanaparti , can you do a quick review?

@DaanHoogland DaanHoogland moved this from Backlog to In progress in CloudStack Testing Sep 8, 2026
@DaanHoogland DaanHoogland changed the title retry NIC IP allocation instead of NPE when the allocation ra… retry NIC IP allocation instead of NPE when the allocating Sep 8, 2026
@nvazquez

nvazquez commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

@blueorangutan package

@blueorangutan

Copy link
Copy Markdown

@nvazquez a [SL] Jenkins job has been kicked to build packages. It will be bundled with KVM, XenServer and VMware SystemVM templates. I'll keep you posted as I make progress.

@nvazquez nvazquez left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code LGTM

@blueorangutan

Copy link
Copy Markdown

Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 19152

@nvazquez

nvazquez commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

@blueorangutan test

@blueorangutan

Copy link
Copy Markdown

@nvazquez a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests

@blueorangutan

Copy link
Copy Markdown

[SF] Trillian test result (tid-16931)
Environment: kvm-ol8 (x2), zone: Advanced Networking with Mgmt server ol8
Total time taken: 54600 seconds
Marvin logs: https://github.com/blueorangutan/acs-prs/releases/download/trillian/pr14038-t16931-kvm-ol8.zip
Smoke tests completed. 140 look OK, 1 have errors, 0 did not run
Only failed and skipped tests results shown below:

Test Result Time (s) Test File
test_02_list_cpvm_vm Failure 0.05 test_ssvm.py
test_04_cpvm_internals Failure 0.05 test_ssvm.py

@DaanHoogland DaanHoogland assigned sudo87 and unassigned DaanHoogland Sep 10, 2026

@sudo87 sudo87 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

lgtm

@sudo87 sudo87 moved this from In progress to In review in CloudStack Testing Sep 11, 2026
@rootnomad

Copy link
Copy Markdown
Contributor Author

Thank you @DaanHoogland, @nvazquez and @sudo87 for the reviews, and for running the smoke tests. Please let me know if anything else is needed from my side for 4.20.4.

@DaanHoogland

Copy link
Copy Markdown
Contributor

lgtm

@sudo87 , am i correct to understand, you did test this? (can you expand a little?)

@sudo87

sudo87 commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

@DaanHoogland my bad, should have used "clgtm". I didn't test it.

throw new InsufficientVirtualNetworkCapacityException("Unable to acquire requested Guest IP address " + requested.getRequestedIPv4() + " for network " + network, DataCenter.class, dcVo.getId());
} else {
requested.setIPv4Address(null);
if (requested != null) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

which deploy path sends no nic profile here? user vm deploys always build one even when no ip is asked, so i think its routers or system vms and not bulk or cks deploys

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good question, thanks @Damans227. The null requested comes from allocate(): when a network is handed in with an empty profile list, the loop adds a single null entry and calls allocateNic(null, ...). You're right that normal user-vm deploys build a NicProfile and don't reach it; the path that does is reallocate() in Basic zones and the other internal add-network flows that pass no profile. Before the fix, losing the allocation race there dereferenced the null requested and threw NPE; the guard makes it retry the same as the non-null case.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

makes sense, so its the basic zone reallocate plus the control and management nics on routers and system vms. can we update the description too? it still says bulk deploys, autoscale and cks hit this

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point, thanks. Updated the description to drop the bulk/autoscale/cks examples, since those are user VMs that build a profile. It now says the null-requested path is the internal deploys that pass no profile: basic-zone reallocate and the control and management NICs on routers and system VMs.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

that covers it, thanks

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

6 participants