// Copyright 2012 Citrix Systems, Inc. Licensed under the // Apache License, Version 2.0 (the "License"); you may not use this // file except in compliance with the License. Citrix Systems, Inc. // reserves all rights not expressly granted by the License. // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.ha; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.ejb.Local; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.PingTestCommand; import com.cloud.host.HostVO; import com.cloud.host.Status; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.network.NetworkManager; import com.cloud.network.Networks.TrafficType; import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.router.VirtualRouter; import com.cloud.utils.component.Inject; import com.cloud.vm.Nic; import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.UserVmDao; @Local(value={Investigator.class}) public class UserVmDomRInvestigator extends AbstractInvestigatorImpl { private static final Logger s_logger = Logger.getLogger(UserVmDomRInvestigator.class); private String _name = null; @Inject private final UserVmDao _userVmDao = null; @Inject private final AgentManager _agentMgr = null; @Inject private final NetworkManager _networkMgr = null; @Inject private final VirtualNetworkApplianceManager _vnaMgr = null; @Override public Boolean isVmAlive(VMInstanceVO vm, HostVO host) { if (vm.getType() != VirtualMachine.Type.User) { if (s_logger.isDebugEnabled()) { s_logger.debug("Not a User Vm, unable to determine state of " + vm + " returning null"); } return null; } if (s_logger.isDebugEnabled()) { s_logger.debug("testing if " + vm + " is alive"); } // to verify that the VM is alive, we ask the domR (router) to ping the VM (private IP) UserVmVO userVm = _userVmDao.findById(vm.getId()); List<? extends Nic> nics = _networkMgr.getNicsForTraffic(userVm.getId(), TrafficType.Guest); for (Nic nic : nics) { if (nic.getIp4Address() == null) { continue; } List<VirtualRouter> routers = _vnaMgr.getRoutersForNetwork(nic.getNetworkId()); if (routers == null || routers.isEmpty()) { if (s_logger.isDebugEnabled()) { s_logger.debug("Unable to find a router in network " + nic.getNetworkId() + " to ping " + vm); } continue; } Boolean result = null; for (VirtualRouter router : routers) { result = testUserVM(vm, nic, router); if (result != null) { break; } } if (result == null) { continue; } return result; } if (s_logger.isDebugEnabled()) { s_logger.debug("Returning null since we're unable to determine state of " + vm); } return null; } @Override public Status isAgentAlive(HostVO agent) { if (s_logger.isDebugEnabled()) { s_logger.debug("checking if agent (" + agent.getId() + ") is alive"); } if (agent.getPodId() == null) { return null; } List<Long> otherHosts = findHostByPod(agent.getPodId(), agent.getId()); for (Long hostId : otherHosts) { if (s_logger.isDebugEnabled()) { s_logger.debug("sending ping from (" + hostId + ") to agent's host ip address (" + agent.getPrivateIpAddress() + ")"); } Status hostState = testIpAddress(hostId, agent.getPrivateIpAddress()); if (hostState == null) { continue; } if (hostState == Status.Up) { if (s_logger.isDebugEnabled()) { s_logger.debug("ping from (" + hostId + ") to agent's host ip address (" + agent.getPrivateIpAddress() + ") successful, returning that agent is disconnected"); } return Status.Disconnected; // the computing host ip is ping-able, but the computing agent is down, report that the agent is disconnected } else if (hostState == Status.Down) { if (s_logger.isDebugEnabled()) { s_logger.debug("returning host state: " + hostState); } return hostState; } } // could not reach agent, could not reach agent's host, unclear what the problem is but it'll require more investigation... if (s_logger.isDebugEnabled()) { s_logger.debug("could not reach agent, could not reach agent's host, returning that we don't have enough information"); } return null; } @Override public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { _name = name; return true; } @Override public String getName() { return _name; } @Override public boolean start() { return true; } @Override public boolean stop() { return true; } private Boolean testUserVM(VMInstanceVO vm, Nic nic, VirtualRouter router) { String privateIp = nic.getIp4Address(); String routerPrivateIp = router.getPrivateIpAddress(); List<Long> otherHosts = new ArrayList<Long>(); if(vm.getHypervisorType() == HypervisorType.XenServer || vm.getHypervisorType() == HypervisorType.KVM){ otherHosts.add(router.getHostId()); }else{ otherHosts = findHostByPod(router.getPodIdToDeployIn(), null); } for (Long hostId : otherHosts) { try { Answer pingTestAnswer = _agentMgr.easySend(hostId, new PingTestCommand(routerPrivateIp, privateIp)); if (pingTestAnswer!=null && pingTestAnswer.getResult()) { if (s_logger.isDebugEnabled()) { s_logger.debug("user vm " + vm.getHostName() + " has been successfully pinged, returning that it is alive"); } return Boolean.TRUE; } } catch (Exception e) { if (s_logger.isDebugEnabled()) { s_logger.debug("Couldn't reach due to", e); } continue; } } if (s_logger.isDebugEnabled()) { s_logger.debug(vm + " could not be pinged, returning that it is unknown"); } return null; } }