Skip to content

Commit e487b24

Browse files
committed
couple of bug fixes
1 parent 015b667 commit e487b24

7 files changed

Lines changed: 223 additions & 117 deletions

File tree

engine/schema/src/com/cloud/network/vpc/VpcVO.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ public boolean isDisplay() {
206206
@Override
207207
public IAMEntityType getEntityType() {
208208
return IAMEntityType.Vpc;
209+
}
209210

210211
@Override
211212
public boolean usesDistributedRouter() {

plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5284,15 +5284,17 @@ private Answer execute(OvsDestroyTunnelCommand cmd) {
52845284
public Answer execute(OvsVpcPhysicalTopologyConfigCommand cmd) {
52855285
Connection conn = getConnection();
52865286
try {
5287+
Network nw = findOrCreateTunnelNetwork(conn, cmd.getBridgeName());
5288+
String bridgeName = nw.getBridge(conn);;
52875289
String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge",
5288-
cmd.getBridgeName(), "config", cmd.getVpcConfigInJson());
5289-
if (result.equalsIgnoreCase("SUCCESS")) {
5290+
bridgeName, "config", cmd.getVpcConfigInJson(), "host-id", ((Long)cmd.getHostId()).toString());
5291+
if (result.startsWith("SUCCESS")) {
52905292
return new Answer(cmd, true, result);
52915293
} else {
52925294
return new Answer(cmd, false, result);
52935295
}
52945296
} catch (Exception e) {
5295-
s_logger.warn("caught exception while updating host with latest routing polcies", e);
5297+
s_logger.warn("caught exception while updating host with latest VPC topology", e);
52965298
return new Answer(cmd, false, e.getMessage());
52975299
}
52985300
}
@@ -5303,13 +5305,13 @@ public Answer execute(OvsVpcRoutingPolicyConfigCommand cmd) {
53035305
String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_routing_policies", "bridge",
53045306
cmd.getBridgeName(), "host-id", ((Long)cmd.getHostId()).toString(), "config",
53055307
cmd.getVpcConfigInJson());
5306-
if (result.equalsIgnoreCase("SUCCESS")) {
5308+
if (result.startsWith("SUCCESS")) {
53075309
return new Answer(cmd, true, result);
53085310
} else {
53095311
return new Answer(cmd, false, result);
53105312
}
53115313
} catch (Exception e) {
5312-
s_logger.warn("caught exception while updating host with latest VPC topology", e);
5314+
s_logger.warn("caught exception while updating host with latest routing policies", e);
53135315
return new Answer(cmd, false, e.getMessage());
53145316
}
53155317
}

plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,9 @@ public interface OvsNetworkTopologyGuru extends Manager {
5656
* get the list of all Vm id's in the network that are running on the host
5757
*/
5858
public List<Long> getActiveVmsInNetworkOnHost(long vpcId, long hostId);
59+
60+
/**
61+
* get the list of all Vpc id's in which, a VM has a nic in the network that is part of VPC
62+
*/
63+
public List<Long> getVpcIdsVmIsPartOf(long vmId);
5964
}

plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,22 @@ public List<Long> getActiveVmsInNetworkOnHost(long networkId, long hostId) {
187187
}
188188
return vmIds;
189189
}
190+
191+
@Override
192+
public List<Long> getVpcIdsVmIsPartOf(long vmId) {
193+
List<Long> vpcIds = new ArrayList<>();
194+
List<NicVO> nics = _nicDao.listByVmId(vmId);
195+
if (nics == null)
196+
return null;
197+
198+
for (Nic nic: nics) {
199+
Network network = _networkDao.findById(nic.getNetworkId());
200+
if (network != null && network.getTrafficType() == Networks.TrafficType.Guest && network.getVpcId() != null) {
201+
if (!vpcIds.contains(network.getVpcId())) {
202+
vpcIds.add(network.getVpcId());
203+
}
204+
}
205+
}
206+
return vpcIds;
207+
}
190208
}

plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java

Lines changed: 157 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import com.cloud.network.vpc.VpcManager;
3737
import com.cloud.network.vpc.VpcVO;
3838
import com.cloud.network.vpc.dao.NetworkACLDao;
39+
import com.cloud.vm.VMInstanceVO;
3940
import com.cloud.vm.dao.VMInstanceDao;
4041
import com.cloud.vm.Nic;
4142
import com.cloud.vm.NicVO;
@@ -80,13 +81,14 @@
8081
import com.cloud.utils.component.ManagerBase;
8182
import com.cloud.utils.concurrency.NamedThreadFactory;
8283
import com.cloud.utils.db.DB;
84+
import com.cloud.utils.fsm.StateListener;
8385
import com.cloud.utils.exception.CloudRuntimeException;
8486
import com.cloud.vm.dao.DomainRouterDao;
8587
import com.cloud.vm.dao.NicDao;
8688

8789
@Component
8890
@Local(value = {OvsTunnelManager.class})
89-
public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManager {
91+
public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManager, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualMachine> {
9092
public static final Logger s_logger = Logger.getLogger(OvsTunnelManagerImpl.class.getName());
9193

9294
// boolean _isEnabled;
@@ -133,7 +135,12 @@ public boolean configure(String name, Map<String, Object> params)
133135
_executorPool = Executors.newScheduledThreadPool(10, new NamedThreadFactory("OVS"));
134136
_cleanupExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("OVS-Cleanup"));
135137

138+
// register for network ACL updated for a VPC.
136139
_messageBus.subscribe("Network_ACL_Replaced", new NetworkAclEventsSubscriber());
140+
141+
// register for VM state transition updates
142+
VirtualMachine.State.getStateMachine().registerListener(this);
143+
137144
return true;
138145
}
139146

@@ -540,92 +547,6 @@ private String generateBridgeNameForVpc(long vpcId) {
540547
return "OVS-DR-VPC-Bridge" + vpcId;
541548
}
542549

543-
public boolean sendVpcTopologyChangeUpdate(OvsVpcPhysicalTopologyConfigCommand updateCmd, long hostId, String bridgeName) {
544-
try {
545-
s_logger.debug("Sending VPC topology update to the host " + hostId);
546-
updateCmd.setHostId(hostId);
547-
updateCmd.setBridgeName(bridgeName);
548-
Answer ans = _agentMgr.send(hostId, updateCmd);
549-
if (ans.getResult()) {
550-
s_logger.debug("Successfully updated the host " + hostId + " with latest VPC topology." );
551-
return true;
552-
} else {
553-
s_logger.debug("Failed to update the host " + hostId + " with latest VPC topology." );
554-
return false;
555-
}
556-
} catch (Exception e) {
557-
s_logger.debug("Failed to updated the host " + hostId + " with latest VPC topology." );
558-
return false;
559-
}
560-
}
561-
562-
OvsVpcPhysicalTopologyConfigCommand prepareVpcTopologyUpdate(long vpcId) {
563-
VpcVO vpc = _vpcDao.findById(vpcId);
564-
assert (vpc != null): "invalid vpc id";
565-
566-
List<? extends Network> vpcNetworks = _vpcMgr.getVpcNetworks(vpcId);
567-
List<Long> hostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
568-
List<Long> vmIds = _ovsNetworkToplogyGuru.getAllActiveVmsInVpc(vpcId);
569-
570-
List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<>();
571-
List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<>();
572-
List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<>();
573-
574-
for (Long hostId : hostIds) {
575-
HostVO hostDetails = _hostDao.findById(hostId);
576-
String remoteIp = null;
577-
for (Network network: vpcNetworks) {
578-
try {
579-
remoteIp = getGreEndpointIP(hostDetails, network);
580-
} catch (Exception e) {
581-
582-
}
583-
}
584-
OvsVpcPhysicalTopologyConfigCommand.Host host = new OvsVpcPhysicalTopologyConfigCommand.Host(hostId, remoteIp);
585-
hosts.add(host);
586-
}
587-
588-
for (Network network: vpcNetworks) {
589-
String key = network.getBroadcastUri().getAuthority();
590-
long gre_key;
591-
if (key.contains(".")) {
592-
String[] parts = key.split("\\.");
593-
gre_key = Long.parseLong(parts[1]);
594-
} else {
595-
try {
596-
gre_key = Long.parseLong(BroadcastDomainType.getValue(key));
597-
} catch (Exception e) {
598-
return null;
599-
}
600-
}
601-
NicVO nic = _nicDao.findByIp4AddressAndNetworkId(network.getGateway(), network.getId());
602-
OvsVpcPhysicalTopologyConfigCommand.Tier tier = new OvsVpcPhysicalTopologyConfigCommand.Tier(gre_key,
603-
network.getUuid(), network.getGateway(), nic.getMacAddress(), network.getCidr());
604-
tiers.add(tier);
605-
}
606-
607-
for (long vmId: vmIds) {
608-
VirtualMachine vmInstance = _vmInstanceDao.findById(vmId);
609-
List<OvsVpcPhysicalTopologyConfigCommand.Nic> vmNics = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Nic>();
610-
for (Nic vmNic :_nicDao.listByVmId(vmId)) {
611-
Network network = _networkDao.findById(vmNic.getNetworkId());
612-
if (network.getTrafficType() == TrafficType.Guest) {
613-
OvsVpcPhysicalTopologyConfigCommand.Nic nic = new OvsVpcPhysicalTopologyConfigCommand.Nic(
614-
vmNic.getIp4Address(), vmNic.getMacAddress(), ((Long)vmNic.getNetworkId()).toString());
615-
vmNics.add(nic);
616-
}
617-
}
618-
OvsVpcPhysicalTopologyConfigCommand.Vm vm = new OvsVpcPhysicalTopologyConfigCommand.Vm(
619-
vmInstance.getHostId(), vmNics.toArray(new OvsVpcPhysicalTopologyConfigCommand.Nic[vmNics.size()]));
620-
vms.add(vm);
621-
}
622-
return new OvsVpcPhysicalTopologyConfigCommand(
623-
hosts.toArray(new OvsVpcPhysicalTopologyConfigCommand.Host[hosts.size()]),
624-
tiers.toArray(new OvsVpcPhysicalTopologyConfigCommand.Tier[tiers.size()]),
625-
vms.toArray(new OvsVpcPhysicalTopologyConfigCommand.Vm[vms.size()]),
626-
vpc.getCidr());
627-
}
628-
629550
@DB
630551
protected void checkAndCreateVpcTunnelNetworks(Host host, long vpcId) {
631552

@@ -731,16 +652,158 @@ protected void checkAndCreateVpcTunnelNetworks(Host host, long vpcId) {
731652
s_logger.warn("Ovs Tunnel network created tunnel failed", e);
732653
}
733654
}
655+
}
656+
657+
@Override
658+
public boolean preStateTransitionEvent(VirtualMachine.State oldState,
659+
VirtualMachine.Event event, VirtualMachine.State newState,
660+
VirtualMachine vo, boolean status, Object opaque) {
661+
return true;
662+
}
663+
664+
@Override
665+
public boolean postStateTransitionEvent(VirtualMachine.State oldState, VirtualMachine.Event event,
666+
VirtualMachine.State newState, VirtualMachine vm,
667+
boolean status, Object opaque) {
668+
669+
if (!status) {
670+
return false;
671+
}
672+
673+
if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
674+
if (s_logger.isTraceEnabled()) {
675+
s_logger.trace("Security Group Mgr: handling start of vm id" + vm.getId());
676+
}
677+
handleVmStateChange((VMInstanceVO)vm);
678+
} else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
679+
if (s_logger.isTraceEnabled()) {
680+
s_logger.trace("Security Group Mgr: handling stop of vm id" + vm.getId());
681+
}
682+
handleVmStateChange((VMInstanceVO)vm);
683+
} else if (VirtualMachine.State.isVmMigrated(oldState, event, newState)) {
684+
if (s_logger.isTraceEnabled()) {
685+
s_logger.trace("Security Group Mgr: handling migration of vm id" + vm.getId());
686+
}
687+
handleVmStateChange((VMInstanceVO)vm);
688+
}
689+
690+
return true;
691+
}
692+
693+
public void handleVmStateChange(VMInstanceVO vm) {
694+
695+
// get the VPC's impacted with the VM start
696+
List<Long> vpcIds = _ovsNetworkToplogyGuru.getVpcIdsVmIsPartOf(vm.getId());
697+
if (vpcIds == null || vpcIds.isEmpty()) {
698+
return;
699+
}
700+
701+
for (Long vpcId: vpcIds) {
702+
VpcVO vpc = _vpcDao.findById(vpcId);
703+
if (vpc == null || !vpc.usesDistributedRouter()) {
704+
return;
705+
}
706+
707+
// get the list of hosts on which VPC spans (i.e hosts that need to be aware of VPC topology change update)
708+
List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
709+
String bridgeName=generateBridgeNameForVpc(vpcId);
734710

735-
OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate(vpcId);
736-
for (Long id: vpcSpannedHostIds) {
737-
if (!sendVpcTopologyChangeUpdate(topologyConfigCommand, id, bridgeName)) {
738-
s_logger.debug("Failed to send VPC topology change update to host : " + id + ". Moving on with rest of" +
739-
"the host update.");
711+
OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate(vpcId);
712+
for (Long id: vpcSpannedHostIds) {
713+
if (!sendVpcTopologyChangeUpdate(topologyConfigCommand, id, bridgeName)) {
714+
s_logger.debug("Failed to send VPC topology change update to host : " + id + ". Moving on " +
715+
"with rest of the host update.");
716+
}
717+
}
718+
}
719+
}
720+
721+
public boolean sendVpcTopologyChangeUpdate(OvsVpcPhysicalTopologyConfigCommand updateCmd, long hostId, String bridgeName) {
722+
try {
723+
s_logger.debug("Sending VPC topology update to the host " + hostId);
724+
updateCmd.setHostId(hostId);
725+
updateCmd.setBridgeName(bridgeName);
726+
Answer ans = _agentMgr.send(hostId, updateCmd);
727+
if (ans.getResult()) {
728+
s_logger.debug("Successfully updated the host " + hostId + " with latest VPC topology." );
729+
return true;
730+
} else {
731+
s_logger.debug("Failed to update the host " + hostId + " with latest VPC topology." );
732+
return false;
740733
}
734+
} catch (Exception e) {
735+
s_logger.debug("Failed to updated the host " + hostId + " with latest VPC topology." );
736+
return false;
741737
}
742738
}
743739

740+
OvsVpcPhysicalTopologyConfigCommand prepareVpcTopologyUpdate(long vpcId) {
741+
VpcVO vpc = _vpcDao.findById(vpcId);
742+
assert (vpc != null): "invalid vpc id";
743+
744+
List<? extends Network> vpcNetworks = _vpcMgr.getVpcNetworks(vpcId);
745+
List<Long> hostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
746+
List<Long> vmIds = _ovsNetworkToplogyGuru.getAllActiveVmsInVpc(vpcId);
747+
748+
List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<>();
749+
List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<>();
750+
List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<>();
751+
752+
for (Long hostId : hostIds) {
753+
HostVO hostDetails = _hostDao.findById(hostId);
754+
String remoteIp = null;
755+
for (Network network: vpcNetworks) {
756+
try {
757+
remoteIp = getGreEndpointIP(hostDetails, network);
758+
} catch (Exception e) {
759+
760+
}
761+
}
762+
OvsVpcPhysicalTopologyConfigCommand.Host host = new OvsVpcPhysicalTopologyConfigCommand.Host(hostId, remoteIp);
763+
hosts.add(host);
764+
}
765+
766+
for (Network network: vpcNetworks) {
767+
String key = network.getBroadcastUri().getAuthority();
768+
long gre_key;
769+
if (key.contains(".")) {
770+
String[] parts = key.split("\\.");
771+
gre_key = Long.parseLong(parts[1]);
772+
} else {
773+
try {
774+
gre_key = Long.parseLong(BroadcastDomainType.getValue(key));
775+
} catch (Exception e) {
776+
return null;
777+
}
778+
}
779+
NicVO nic = _nicDao.findByIp4AddressAndNetworkId(network.getGateway(), network.getId());
780+
OvsVpcPhysicalTopologyConfigCommand.Tier tier = new OvsVpcPhysicalTopologyConfigCommand.Tier(gre_key,
781+
network.getUuid(), network.getGateway(), nic.getMacAddress(), network.getCidr());
782+
tiers.add(tier);
783+
}
784+
785+
for (long vmId: vmIds) {
786+
VirtualMachine vmInstance = _vmInstanceDao.findById(vmId);
787+
List<OvsVpcPhysicalTopologyConfigCommand.Nic> vmNics = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Nic>();
788+
for (Nic vmNic :_nicDao.listByVmId(vmId)) {
789+
Network network = _networkDao.findById(vmNic.getNetworkId());
790+
if (network.getTrafficType() == TrafficType.Guest) {
791+
OvsVpcPhysicalTopologyConfigCommand.Nic nic = new OvsVpcPhysicalTopologyConfigCommand.Nic(
792+
vmNic.getIp4Address(), vmNic.getMacAddress(), network.getUuid());
793+
vmNics.add(nic);
794+
}
795+
}
796+
OvsVpcPhysicalTopologyConfigCommand.Vm vm = new OvsVpcPhysicalTopologyConfigCommand.Vm(
797+
vmInstance.getHostId(), vmNics.toArray(new OvsVpcPhysicalTopologyConfigCommand.Nic[vmNics.size()]));
798+
vms.add(vm);
799+
}
800+
return new OvsVpcPhysicalTopologyConfigCommand(
801+
hosts.toArray(new OvsVpcPhysicalTopologyConfigCommand.Host[hosts.size()]),
802+
tiers.toArray(new OvsVpcPhysicalTopologyConfigCommand.Tier[tiers.size()]),
803+
vms.toArray(new OvsVpcPhysicalTopologyConfigCommand.Vm[vms.size()]),
804+
vpc.getCidr());
805+
}
806+
744807
// Subscriber to ACL replace events. On acl replace event, if the vpc is enabled for distributed routing
745808
// send the ACL update to all the hosts on which VPC spans
746809
public class NetworkAclEventsSubscriber implements MessageSubscriber {
@@ -755,14 +818,14 @@ public void onPublishMessage(String senderAddress, String subject, Object args)
755818
for (Long id: vpcSpannedHostIds) {
756819
if (!sendVpcRoutingPolicyChangeUpdate(cmd, id, bridgeName)) {
757820
s_logger.debug("Failed to send VPC routing policy change update to host : " + id +
758-
". Moving on with rest of the host updates.");
821+
". But moving on with sending the host updates to the rest of the hosts.");
759822
}
760823
}
761824
}
762825
}
763826
}
764827

765-
OvsVpcRoutingPolicyConfigCommand prepareVpcRoutingPolicyUpdate(long vpcId) {
828+
private OvsVpcRoutingPolicyConfigCommand prepareVpcRoutingPolicyUpdate(long vpcId) {
766829
VpcVO vpc = _vpcDao.findById(vpcId);
767830
assert (vpc != null): "invalid vpc id";
768831
List<OvsVpcRoutingPolicyConfigCommand.Acl> acls = new ArrayList<>();

0 commit comments

Comments
 (0)