Skip to content

VMs stuck in Stopping state due to NPE at org.apache.cloudstack.network.topology.BasicNetworkVisitor.visit(BasicNetworkVisitor.java:201) #3497

Description

@server24

Bug Report

After upgrading from 4.11.2.0 to 4.11.3.0 every operation that requires deleting an entry in a basic network seems to fail due to a NPE and therefore the VMs are stuck in Stopping state.

Possibly caused by commit b2b99ca regarding server/src/main/java/org/apache/cloudstack/network/topology/BasicNetworkTopology.java (but this is just my guess)

CloudStack version 4.11.3.0
with Basic Networking

How to reproduce: Create a VM and then try to stop or destroy it. The procedure will not complete and the VM stays in "Stopping" state. In the CloudStack Mgm Server the following error message is shown:

2019-07-16 13:37:52,781 DEBUG [o.a.c.n.t.BasicNetworkTopology] (AgentManager-Handler-2:null) (logid:) REMOVING DHCP ENTRY RULE
2019-07-16 13:37:52,781 DEBUG [o.a.c.n.t.BasicNetworkTopology] (AgentManager-Handler-2:null) (logid:) Applying dhcp entry in network Ntwk[212|Guest|6]
2019-07-16 13:37:52,784 ERROR [o.a.c.f.m.MessageDispatcher] (AgentManager-Handler-2:null) (logid:) Unexpected exception when calling com.cloud.vm.ClusteredVirtualMachineManagerImpl.HandlePowerStateReport
java.lang.reflect.InvocationTargetException
        at sun.reflect.GeneratedMethodAccessor77.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.cloudstack.framework.messagebus.MessageDispatcher.dispatch(MessageDispatcher.java:75)
        at org.apache.cloudstack.framework.messagebus.MessageDispatcher.onPublishMessage(MessageDispatcher.java:45)
        at org.apache.cloudstack.framework.messagebus.MessageBusBase$SubscriptionNode.notifySubscribers(MessageBusBase.java:441)
        at org.apache.cloudstack.framework.messagebus.MessageBusBase.publish(MessageBusBase.java:178)
        at com.cloud.vm.VirtualMachinePowerStateSyncImpl.processReport(VirtualMachinePowerStateSyncImpl.java:147)
        at com.cloud.vm.VirtualMachinePowerStateSyncImpl.processHostVmStatePingReport(VirtualMachinePowerStateSyncImpl.java:68)
        at com.cloud.vm.VirtualMachineManagerImpl.processCommands(VirtualMachineManagerImpl.java:3071)
        at com.cloud.agent.manager.AgentManagerImpl.handleCommands(AgentManagerImpl.java:317)
        at com.cloud.agent.manager.AgentManagerImpl$AgentHandler.processRequest(AgentManagerImpl.java:1296)
        at com.cloud.agent.manager.AgentManagerImpl$AgentHandler.doTask(AgentManagerImpl.java:1383)
        at com.cloud.agent.manager.ClusteredAgentManagerImpl$ClusteredAgentHandler.doTask(ClusteredAgentManagerImpl.java:712)
        at com.cloud.utils.nio.Task.call(Task.java:83)
        at com.cloud.utils.nio.Task.call(Task.java:29)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
        at org.apache.cloudstack.network.topology.BasicNetworkVisitor.visit(BasicNetworkVisitor.java:201)
        at com.cloud.network.rules.DhcpEntryRules.accept(DhcpEntryRules.java:64)
        at org.apache.cloudstack.network.topology.BasicNetworkTopology.applyRules(BasicNetworkTopology.java:390)
        ... 27 more
2019-07-16 13:37:52,784 WARN  [c.c.a.m.AgentManagerImpl] (AgentManager-Handler-2:null) (logid:) Caught:
java.lang.RuntimeException: InvocationTargetException when invoking event handler for subject: vm.powerstate
        at org.apache.cloudstack.framework.messagebus.MessageDispatcher.dispatch(MessageDispatcher.java:84)
        at org.apache.cloudstack.framework.messagebus.MessageDispatcher.onPublishMessage(MessageDispatcher.java:45)
        at org.apache.cloudstack.framework.messagebus.MessageBusBase$SubscriptionNode.notifySubscribers(MessageBusBase.java:441)
        at org.apache.cloudstack.framework.messagebus.MessageBusBase.publish(MessageBusBase.java:178)
        at com.cloud.vm.VirtualMachinePowerStateSyncImpl.processReport(VirtualMachinePowerStateSyncImpl.java:147)
        at com.cloud.vm.VirtualMachinePowerStateSyncImpl.processHostVmStatePingReport(VirtualMachinePowerStateSyncImpl.java:68)
        at com.cloud.vm.VirtualMachineManagerImpl.processCommands(VirtualMachineManagerImpl.java:3071)
        at com.cloud.agent.manager.AgentManagerImpl.handleCommands(AgentManagerImpl.java:317)
        at com.cloud.agent.manager.AgentManagerImpl$AgentHandler.processRequest(AgentManagerImpl.java:1296)
        at com.cloud.agent.manager.AgentManagerImpl$AgentHandler.doTask(AgentManagerImpl.java:1383)
        at com.cloud.agent.manager.ClusteredAgentManagerImpl$ClusteredAgentHandler.doTask(ClusteredAgentManagerImpl.java:712)
        at com.cloud.utils.nio.Task.call(Task.java:83)
        at com.cloud.utils.nio.Task.call(Task.java:29)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)


Already tried recreating the VR, cleaning and restarting the network etc., but it makes no difference.

The problems first appeared after upgrading from CloudStack 4.11.2 to 4.11.3.

Activity

  1. server24 commented on Jul 17, 2019

    @server24
    Author

    Line 201 of BasicNetworkVisitor.java in CS 4.11.3 is:
    if (router.getPodIdToDeployIn().longValue() == destination.getPod().getId()) {

    in this method:

        @Override
        public boolean visit(final DhcpEntryRules dhcp) throws ResourceUnavailableException {
            final VirtualRouter router = dhcp.getRouter();
    
            final Commands commands = new Commands(Command.OnError.Stop);
            final NicVO nicVo = dhcp.getNicVo();
            final UserVmVO userVM = dhcp.getUserVM();
            final DeployDestination destination = dhcp.getDestination();
            final boolean remove = dhcp.isRemove();
    
            **if (router.getPodIdToDeployIn().longValue() == destination.getPod().getId()) {**
                _commandSetupHelper.createDhcpEntryCommand(router, userVM, nicVo, remove, commands);
    
                return _networkGeneralHelper.sendCommandsToRouter(router, commands);
            }
            return true;
        }
    

    This works fine in advanced network, but seems to fail with a basic network; also all tests in the relative merge pull seem to be done with advanced networking only.

  2. server24 commented on Jul 17, 2019

    @server24
    Author

    I have attached jdb and the problem seems to be that destination is NULL, specifically that dhcp.getDestination() returns NULL. From the debugger:

    Breakpoint hit: "thread=API-Job-Executor-1", org.apache.cloudstack.network.topology.BasicNetworkVisitor.visit(), line=193 bci=0
    
    API-Job-Executor-1[1] list
    Source file not found: BasicNetworkVisitor.java
    API-Job-Executor-1[1] locals
    Method arguments:
    dhcp = instance of com.cloud.network.rules.DhcpEntryRules(id=11576)
    Local variables:
    API-Job-Executor-1[1] print dhcp
     dhcp = "com.cloud.network.rules.DhcpEntryRules@725a95d4"
    API-Job-Executor-1[1] print dhcp.getNicVo()
     dhcp.getNicVo() = "Nic[862-609-9f0f0a12-c397-4735-84b2-a6222a929e1a-84.33.37.153]"
    API-Job-Executor-1[1] print dhcp.getUserVM()
     dhcp.getUserVM() = "VM[User|i-9-609-VM]"
    API-Job-Executor-1[1] print dhcp.getDestination()
     dhcp.getDestination() = null
    API-Job-Executor-1[1] print dhcp.isRemove()
     dhcp.isRemove() = true
    

    So no destination is specified and this is causing the NPE. Hope this helps.

  3. server24 commented on Jul 17, 2019

    @server24
    Author

    Just one more thing: it will always be NULL when invoked from removeDhcpEntry in the BasicNetworkTopology-class, line 461:

    final DhcpEntryRules dhcpRules = new DhcpEntryRules(network, nic, profile, null);

    The same calls happens in the AdvancedNetworkTopology-class BTW, but in the AdvancedNetworkVisitor-class destination is not used and not compared, so it works there.

    Why is destination needed in Basic Networking?

  4. added this to the 4.13.0.0 milestone on Jul 17, 2019
  5. yadvr commented on Jul 17, 2019

    @yadvr
    Member

    Can you have a look @nvazquez, or cc @shwstppr @anuragaw ?

  6. server24 commented on Jul 17, 2019

    @server24
    Author

    You probably want to add the destination parameter to removeDhcpEntry in server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java, e. g.:

        @Override
        public boolean removeDhcpEntry(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest,
    			final VirtualRouter virtualRouter) throws ResourceUnavailableException {
    			
            s_logger.debug("REMOVING DHCP ENTRY RULE");
    
            final String typeString = "dhcp entry";
            final Long podId = profile.getVirtualMachine().getPodIdToDeployIn();
            boolean isPodLevelException = false;
    
            if (podId != null && profile.getVirtualMachine().getType() == VirtualMachine.Type.User && network.getTrafficType() == TrafficType.Guest
                    && network.getGuestType() == Network.GuestType.Shared) {
                isPodLevelException = true;
            }
    
            final boolean failWhenDisconnect = false;
    
            final DhcpEntryRules dhcpRules = new DhcpEntryRules(network, nic, profile, dest);
            dhcpRules.setRemove(true);
    
            return applyRules(network, virtualRouter, typeString, isPodLevelException, podId, failWhenDisconnect, new RuleApplierWrapper<RuleApplier>(dhcpRules));
        }
    
    

    But that is the obvious choice (e.g. compared to applyDhcpEntry), so there must be something that prevented this trivial solution from being implemented.

  7. nvazquez commented on Jul 18, 2019

    @nvazquez
    Contributor

    @server24 please find a PR fixing the issue referenced above

  8. server24 commented on Jul 18, 2019

    @server24
    Author

    Is this PR really fixing the issue? Your original patch was born out of the idea that DHCP entries where left in the VR when it should not.

    Now with your patch you are basically avoiding the command being executed, but that means it would fall back to the old behaviour before your patch in Basic Networking. Wouldn't it make sense to change it to something like this:

    @Override
    public boolean visit(final DhcpEntryRules dhcp) throws ResourceUnavailableException {
        final VirtualRouter router = dhcp.getRouter();
    
        final Commands commands = new Commands(Command.OnError.Stop);
        final NicVO nicVo = dhcp.getNicVo();
        final UserVmVO userVM = dhcp.getUserVM();
        final DeployDestination destination = dhcp.getDestination();
        final boolean remove = dhcp.isRemove();
    
        // If we are just removing something, no destination is necessary; we always need the router:
        if (router != null &&
                (remove || (destination != null &&
                                        destination.getPod() != null && router.getPodIdToDeployIn() != null &&
                                        router.getPodIdToDeployIn().longValue() == destination.getPod().getId()))) {
            _commandSetupHelper.createDhcpEntryCommand(router, userVM, nicVo, remove, commands);
    
            return _networkGeneralHelper.sendCommandsToRouter(router, commands);
        }
        return true;
    }
    

    So that if remove is TRUE it does not check for destination at all?

  9. added a commit that references this issue on Jul 23, 2019
    281148d
  10. incubatec commented on Jul 23, 2019

    @incubatec

    @server24 please find a PR fixing the issue referenced above

    works perfectly, thx!

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions