Fix NPE during VM setup for pvlan#12781
Conversation
|
@blueorangutan package |
|
@sureshanaparti 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. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## 4.22 #12781 +/- ##
============================================
- Coverage 17.61% 17.61% -0.01%
+ Complexity 15664 15663 -1
============================================
Files 5917 5917
Lines 531402 531408 +6
Branches 64971 64973 +2
============================================
Hits 93596 93596
- Misses 427252 427258 +6
Partials 10554 10554
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Fixes a NullPointerException during VM pvlan setup by guarding against missing NIC broadcast URI (and missing host).
Changes:
- Add null checks for
NicProfile/getBroadCastUri()before accessing URI scheme. - Compare pvlan scheme safely using a local
schemevariable and constant-first equals. - Add a host existence check (with a warning) before issuing the pvlan setup command.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| if (nic == null || nic.getBroadCastUri() == null) { | ||
| return false; | ||
| } | ||
|
|
||
| String scheme = nic.getBroadCastUri().getScheme(); | ||
| if (!"pvlan".equals(scheme)) { |
There was a problem hiding this comment.
Returning false here makes the failure mode indistinguishable from the non-pvlan path (scheme != pvlan). Consider logging (at least debug/warn) why pvlan setup is being skipped (null NIC vs null broadcast URI) so future incidents are diagnosable.
| if (nic == null || nic.getBroadCastUri() == null) { | |
| return false; | |
| } | |
| String scheme = nic.getBroadCastUri().getScheme(); | |
| if (!"pvlan".equals(scheme)) { | |
| if (nic == null) { | |
| logger.debug("Skipping PVLAN setup on host {} because NIC profile is null", hostId); | |
| return false; | |
| } | |
| if (nic.getBroadCastUri() == null) { | |
| logger.debug("Skipping PVLAN setup on host {} for NIC with MAC {} because broadcast URI is null", hostId, nic.getMacAddress()); | |
| return false; | |
| } | |
| String scheme = nic.getBroadCastUri().getScheme(); | |
| if (!"pvlan".equals(scheme)) { | |
| logger.debug("Skipping PVLAN setup on host {} for NIC with MAC {} because broadcast URI scheme is '{}'", hostId, nic.getMacAddress(), scheme); |
| Network network = _networkDao.findById(nic.getNetworkId()); | ||
| Host host = _hostDao.findById(hostId); | ||
| if (host == null) { | ||
| logger.warn("Host with id {} doesn't exist", hostId); | ||
| return false; | ||
| } |
There was a problem hiding this comment.
The network lookup is performed even when hostId is invalid and the method returns early. Consider fetching/validating host before calling _networkDao.findById(...) to avoid unnecessary DAO work in this error path.
| Network network = _networkDao.findById(nic.getNetworkId()); | |
| Host host = _hostDao.findById(hostId); | |
| if (host == null) { | |
| logger.warn("Host with id {} doesn't exist", hostId); | |
| return false; | |
| } | |
| Host host = _hostDao.findById(hostId); | |
| if (host == null) { | |
| logger.warn("Host with id {} doesn't exist", hostId); | |
| return false; | |
| } | |
| Network network = _networkDao.findById(nic.getNetworkId()); |
| Network network = _networkDao.findById(nic.getNetworkId()); | ||
| Host host = _hostDao.findById(hostId); | ||
| if (host == null) { | ||
| logger.warn("Host with id {} doesn't exist", hostId); |
There was a problem hiding this comment.
Consider changing the log message to avoid the contraction "doesn't" (e.g., "does not exist") for consistency and formality in logs.
| logger.warn("Host with id {} doesn't exist", hostId); | |
| logger.warn("Host with id {} does not exist", hostId); |
|
Packaging result [SF]: ✖️ el8 ✖️ el9 ✔️ debian ✖️ suse15. SL-JID 17068 |
Description
This PR fixes NPE issue during VM setup for pvlan.
ERROR [c.c.v.VmWorkJobDispatcher] (Work-Job-Executor-5:[ctx-36c8ede2, job-51933/job-51934]) (logid:aad07025) Unable to complete AsyncJob {"accountId":2,"cmd":"com.cloud.vm.VmWorkMigrate","cmdInfo":"rO0ABXNyABpjb20uY2xvdWQudm0uVm1Xb3JrTWlncmF0ZRdxQXtPtzYqAgAGSgAJc3JjSG9zdElkTAAJY2x1c3RlcklkdAAQTGphdmEvbGFuZy9Mb25nO0wABmhvc3RJZHEAfgABTAAFcG9kSWRxAH4AAUwAB3N0b3JhZ2V0AA9MamF2YS91dGlsL01hcDtMAAZ6b25lSWRxAH4AAXhyABNjb20uY2xvdWQudm0uVm1Xb3Jrn5m2VvAlZ2sCAARKAAlhY2NvdW50SWRKAAZ1c2VySWRKAAR2bUlkTAALaGFuZGxlck5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cAAAAAAAAAACAAAAAAAAAFMAAAAAAAAAMHQAGVZpcnR1YWxNYWNoaW5lTWFuYWdlckltcGwAAAAAAAAAEXNyAA5qYXZhLmxhbmcuTG9uZzuL5JDMjyPfAgABSgAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAAAAAAAA3NxAH4ABwAAAAAAAAATc3EAfgAHAAAAAAAAAAFwcQB-AAs","cmdVersion":0,"completeMsid":null,"created":"Mon Feb 16 15:40:04 EST 2026","id":51934,"initMsid":90520733277145,"instanceId":null,"instanceType":null,"lastPolled":null,"lastUpdated":null,"processStatus":0,"removed":null,"result":null,"resultCode":0,"status":"IN_PROGRESS","userId":83,"uuid":"c3826ec3-3793-453c-bd0b-a79cbfbda7fe"}, job origin: 51933 java.lang.NullPointerException: Cannot invoke "java.net.URI.getScheme()" because the return value of "com.cloud.vm.NicProfile.getBroadCastUri()" is null at com.cloud.vm.UserVmManagerImpl.setupVmForPvlan(UserVmManagerImpl.java:5390) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:569) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) at jdk.proxy3/jdk.proxy3.$Proxy219.setupVmForPvlan(Unknown Source) at org.apache.cloudstack.engine.orchestration.NetworkOrchestrator.prepareNicForMigration(NetworkOrchestrator.java:2278) at com.cloud.vm.VirtualMachineManagerImpl.migrate(VirtualMachineManagerImpl.java:3100) at com.cloud.vm.VirtualMachineManagerImpl.orchestrateMigrate(VirtualMachineManagerImpl.java:3052) at com.cloud.vm.VirtualMachineManagerImpl.orchestrateMigrate(VirtualMachineManagerImpl.java:5978)Types of changes
Feature/Enhancement Scale or Bug Severity
Feature/Enhancement Scale
Bug Severity
Screenshots (if appropriate):
How Has This Been Tested?
How did you try to break this feature and the system with this change?