Skip to content

Commit 09cec4b

Browse files
committed
vpc/server: Fix network statistics for vpc
This contains 3 main changes (1) add NETWORK_STATS_ethX for all nics with public ips in VPC VRs (current: NETWORK_STATS_eth1) (2) DO NOT create records in user_statistics for each VPC tier (only one record per public nic per VPC VR) (3) send NetworkUsageCommand before unplugging a NIC with public IPs from VPC VR
1 parent 9c6b02f commit 09cec4b

7 files changed

Lines changed: 61 additions & 109 deletions

File tree

api/src/main/java/com/cloud/network/VirtualNetworkApplianceService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.cloud.exception.ResourceUnavailableException;
2727
import com.cloud.network.router.VirtualRouter;
2828
import com.cloud.user.Account;
29+
import com.cloud.vm.Nic;
2930

3031
public interface VirtualNetworkApplianceService {
3132
/**
@@ -74,4 +75,6 @@ public interface VirtualNetworkApplianceService {
7475
* @return
7576
*/
7677
boolean performRouterHealthChecks(long routerId);
78+
79+
<T extends VirtualRouter> void collectNetworkStatistics(T router, Nic nic);
7780
}

engine/schema/src/main/java/com/cloud/vm/dao/DomainRouterDaoImpl.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -384,12 +384,14 @@ public void addRouterToGuestNetwork(final VirtualRouter router, final Network gu
384384
final RouterNetworkVO routerNtwkMap = new RouterNetworkVO(router.getId(), guestNetwork.getId(), guestNetwork.getGuestType());
385385
_routerNetworkDao.persist(routerNtwkMap);
386386
//2) create user stats entry for the network
387-
UserStatisticsVO stats =
388-
_userStatsDao.findBy(router.getAccountId(), router.getDataCenterId(), guestNetwork.getId(), null, router.getId(), router.getType().toString());
389-
if (stats == null) {
390-
stats =
391-
new UserStatisticsVO(router.getAccountId(), router.getDataCenterId(), null, router.getId(), router.getType().toString(), guestNetwork.getId());
392-
_userStatsDao.persist(stats);
387+
if (router.getVpcId() == null) {
388+
UserStatisticsVO stats =
389+
_userStatsDao.findBy(router.getAccountId(), router.getDataCenterId(), guestNetwork.getId(), null, router.getId(), router.getType().toString());
390+
if (stats == null) {
391+
stats =
392+
new UserStatisticsVO(router.getAccountId(), router.getDataCenterId(), null, router.getId(), router.getType().toString(), guestNetwork.getId());
393+
_userStatsDao.persist(stats);
394+
}
393395
}
394396
txn.commit();
395397
}

server/src/main/java/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java

Lines changed: 18 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -729,100 +729,7 @@ protected void runInContext() {
729729
s_logger.debug("Found " + routers.size() + " running routers. ");
730730

731731
for (final DomainRouterVO router : routers) {
732-
final String privateIP = router.getPrivateIpAddress();
733-
734-
if (privateIP != null) {
735-
final boolean forVpc = router.getVpcId() != null;
736-
final List<? extends Nic> routerNics = _nicDao.listByVmId(router.getId());
737-
for (final Nic routerNic : routerNics) {
738-
final Network network = _networkModel.getNetwork(routerNic.getNetworkId());
739-
// Send network usage command for public nic in VPC VR
740-
// Send network usage command for isolated guest nic of non) VPC VR
741-
742-
//[TODO] Avoiding the NPE now, but I have to find out what is going on with the network. - Wilder Rodrigues
743-
if (network == null) {
744-
s_logger.error("Could not find a network with ID => " + routerNic.getNetworkId() + ". It might be a problem!");
745-
continue;
746-
}
747-
if (forVpc && network.getTrafficType() == TrafficType.Public || !forVpc && network.getTrafficType() == TrafficType.Guest
748-
&& network.getGuestType() == Network.GuestType.Isolated) {
749-
final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), forVpc, routerNic.getIPv4Address());
750-
final String routerType = router.getType().toString();
751-
final UserStatisticsVO previousStats = _userStatsDao.findBy(router.getAccountId(), router.getDataCenterId(), network.getId(),
752-
forVpc ? routerNic.getIPv4Address() : null, router.getId(), routerType);
753-
NetworkUsageAnswer answer = null;
754-
try {
755-
answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd);
756-
} catch (final Exception e) {
757-
s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId(), e);
758-
continue;
759-
}
760-
761-
if (answer != null) {
762-
if (!answer.getResult()) {
763-
s_logger.warn("Error while collecting network stats from router: " + router.getInstanceName() + " from host: " + router.getHostId()
764-
+ "; details: " + answer.getDetails());
765-
continue;
766-
}
767-
try {
768-
if (answer.getBytesReceived() == 0 && answer.getBytesSent() == 0) {
769-
s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics");
770-
continue;
771-
}
772-
final NetworkUsageAnswer answerFinal = answer;
773-
Transaction.execute(new TransactionCallbackNoReturn() {
774-
@Override
775-
public void doInTransactionWithoutResult(final TransactionStatus status) {
776-
final UserStatisticsVO stats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterId(), network.getId(),
777-
forVpc ? routerNic.getIPv4Address() : null, router.getId(), routerType);
778-
if (stats == null) {
779-
s_logger.warn("unable to find stats for account: " + router.getAccountId());
780-
return;
781-
}
782-
783-
if (previousStats != null
784-
&& (previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived() || previousStats.getCurrentBytesSent() != stats
785-
.getCurrentBytesSent())) {
786-
s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + "Ignoring current answer. Router: "
787-
+ answerFinal.getRouterName() + " Rcvd: " + answerFinal.getBytesReceived() + "Sent: " + answerFinal.getBytesSent());
788-
return;
789-
}
790-
791-
if (stats.getCurrentBytesReceived() > answerFinal.getBytesReceived()) {
792-
if (s_logger.isDebugEnabled()) {
793-
s_logger.debug("Received # of bytes that's less than the last one. "
794-
+ "Assuming something went wrong and persisting it. Router: " + answerFinal.getRouterName() + " Reported: "
795-
+ answerFinal.getBytesReceived() + " Stored: " + stats.getCurrentBytesReceived());
796-
}
797-
stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived());
798-
}
799-
stats.setCurrentBytesReceived(answerFinal.getBytesReceived());
800-
if (stats.getCurrentBytesSent() > answerFinal.getBytesSent()) {
801-
if (s_logger.isDebugEnabled()) {
802-
s_logger.debug("Received # of bytes that's less than the last one. "
803-
+ "Assuming something went wrong and persisting it. Router: " + answerFinal.getRouterName() + " Reported: "
804-
+ answerFinal.getBytesSent() + " Stored: " + stats.getCurrentBytesSent());
805-
}
806-
stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent());
807-
}
808-
stats.setCurrentBytesSent(answerFinal.getBytesSent());
809-
if (!_dailyOrHourly) {
810-
// update agg bytes
811-
stats.setAggBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent());
812-
stats.setAggBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived());
813-
}
814-
_userStatsDao.update(stats.getId(), stats);
815-
}
816-
});
817-
818-
} catch (final Exception e) {
819-
s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + " Rx: " + answer.getBytesReceived() + "; Tx: "
820-
+ answer.getBytesSent());
821-
}
822-
}
823-
}
824-
}
825-
}
732+
collectNetworkStatistics(router, null);
826733
}
827734
} catch (final Exception e) {
828735
s_logger.warn("Error while collecting network stats", e);
@@ -3053,6 +2960,11 @@ public void prepareStop(final VirtualMachineProfile profile) {
30532960
// Collect network usage before stopping Vm
30542961

30552962
final DomainRouterVO router = _routerDao.findById(profile.getVirtualMachine().getId());
2963+
collectNetworkStatistics(router, null);
2964+
}
2965+
2966+
@Override
2967+
public <T extends VirtualRouter> void collectNetworkStatistics(final T router, final Nic nic) {
30562968
if (router == null) {
30572969
return;
30582970
}
@@ -3061,12 +2973,23 @@ public void prepareStop(final VirtualMachineProfile profile) {
30612973

30622974
if (privateIP != null) {
30632975
final boolean forVpc = router.getVpcId() != null;
3064-
final List<? extends Nic> routerNics = _nicDao.listByVmId(router.getId());
2976+
List<Nic> routerNics = new ArrayList<Nic>();
2977+
if (nic != null) {
2978+
routerNics.add(nic);
2979+
} else {
2980+
routerNics.addAll(_nicDao.listByVmId(router.getId()));
2981+
}
30652982
for (final Nic routerNic : routerNics) {
30662983
final Network network = _networkModel.getNetwork(routerNic.getNetworkId());
30672984
// Send network usage command for public nic in VPC VR
30682985
// Send network usage command for isolated guest nic of non VPC
30692986
// VR
2987+
2988+
//[TODO] Avoiding the NPE now, but I have to find out what is going on with the network. - Wilder Rodrigues
2989+
if (network == null) {
2990+
s_logger.error("Could not find a network with ID => " + routerNic.getNetworkId() + ". It might be a problem!");
2991+
continue;
2992+
}
30702993
if (forVpc && network.getTrafficType() == TrafficType.Public || !forVpc && network.getTrafficType() == TrafficType.Guest
30712994
&& network.getGuestType() == Network.GuestType.Isolated) {
30722995
final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), forVpc, routerNic.getIPv4Address());

server/src/main/java/com/cloud/network/rules/NicPlugInOutRules.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import com.cloud.network.Networks.BroadcastDomainType;
3939
import com.cloud.network.Networks.IsolationType;
4040
import com.cloud.network.PublicIpAddress;
41+
import com.cloud.network.VpcVirtualNetworkApplianceService;
4142
import com.cloud.network.router.VirtualRouter;
4243
import com.cloud.network.vpc.VpcManager;
4344
import com.cloud.network.vpc.VpcVO;
@@ -75,8 +76,17 @@ public boolean accept(final NetworkTopologyVisitor visitor, final VirtualRouter
7576

7677
NetworkModel networkModel = visitor.getVirtualNetworkApplianceFactory().getNetworkModel();
7778
VirtualMachineManager itMgr = visitor.getVirtualNetworkApplianceFactory().getItMgr();
79+
NicDao nicDao = visitor.getVirtualNetworkApplianceFactory().getNicDao();
80+
VpcVirtualNetworkApplianceService routerService = visitor.getVirtualNetworkApplianceFactory().getRouterService();
81+
7882
// 1) Unplug the nics
7983
for (Entry<String, PublicIpAddress> entry : nicsToUnplug.entrySet()) {
84+
PublicIpAddress ip = entry.getValue();
85+
NicVO nic = nicDao.findByIp4AddressAndNetworkIdAndInstanceId(ip.getNetworkId(), _router.getId(), ip.getAddress().addr());
86+
if (nic != null) {
87+
s_logger.info("Collect network statistics for nic " + nic + " from router " + _router);
88+
routerService.collectNetworkStatistics(_router, nic);
89+
}
8090
Network publicNtwk = null;
8191
try {
8292
publicNtwk = networkModel.getNetwork(entry.getValue().getNetworkId());
@@ -215,4 +225,4 @@ private Pair<Map<String, PublicIpAddress>, Map<String, PublicIpAddress>> getNics
215225

216226
return nicsToChange;
217227
}
218-
}
228+
}

server/src/main/java/com/cloud/network/rules/VirtualNetworkApplianceFactory.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.cloud.dc.dao.VlanDao;
2727
import com.cloud.network.IpAddressManager;
2828
import com.cloud.network.NetworkModel;
29+
import com.cloud.network.VpcVirtualNetworkApplianceService;
2930
import com.cloud.network.dao.IPAddressDao;
3031
import com.cloud.network.dao.LoadBalancerDao;
3132
import com.cloud.network.dao.NetworkDao;
@@ -91,6 +92,9 @@ public class VirtualNetworkApplianceFactory {
9192
@Inject
9293
private NicProfileHelper _nicProfileHelper;
9394

95+
@Inject
96+
private VpcVirtualNetworkApplianceService _routerService;
97+
9498
public NetworkModel getNetworkModel() {
9599
return _networkModel;
96100
}
@@ -174,4 +178,8 @@ public NetworkHelper getNetworkHelper() {
174178
public NicProfileHelper getNicProfileHelper() {
175179
return _nicProfileHelper;
176180
}
177-
}
181+
182+
public VpcVirtualNetworkApplianceService getRouterService() {
183+
return _routerService;
184+
}
185+
}

server/src/test/java/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import com.cloud.user.User;
4242
import com.cloud.utils.component.ManagerBase;
4343
import com.cloud.vm.DomainRouterVO;
44+
import com.cloud.vm.Nic;
4445
import com.cloud.vm.VirtualMachineProfile;
4546

4647
@Component
@@ -280,4 +281,10 @@ public boolean startSite2SiteVpn(DomainRouterVO router) throws ResourceUnavailab
280281
// TODO Auto-generated method stub
281282
return false;
282283
}
283-
}
284+
285+
@Override
286+
public <T extends VirtualRouter> void collectNetworkStatistics(T router, Nic nic) {
287+
// TODO Auto-generated method stub
288+
return;
289+
}
290+
}

systemvm/debian/opt/cloud/bin/cs/CsAddress.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -471,11 +471,6 @@ def fw_vpcrouter(self):
471471
"-A PREROUTING -m state --state NEW -i %s -s %s ! -d %s/32 -j ACL_OUTBOUND_%s" %
472472
(self.dev, guestNetworkCidr, self.address['gateway'], self.dev)])
473473

474-
self.fw.append(["", "front", "-A NETWORK_STATS_%s -i %s -d %s" %
475-
("eth1", "eth1", guestNetworkCidr)])
476-
self.fw.append(["", "front", "-A NETWORK_STATS_%s -o %s -s %s" %
477-
("eth1", "eth1", guestNetworkCidr)])
478-
479474
if self.address["source_nat"]:
480475
self.fw.append(["nat", "front",
481476
"-A POSTROUTING -o %s -j SNAT --to-source %s" %
@@ -490,6 +485,10 @@ def fw_vpcrouter(self):
490485
["mangle", "", "-A VPN_STATS_%s -i %s -m mark --mark 0x524/0xffffffff" % (self.dev, self.dev)])
491486
self.fw.append(
492487
["", "front", "-A FORWARD -j NETWORK_STATS_%s" % self.dev])
488+
self.fw.append(
489+
["", "front", "-A NETWORK_STATS_%s -s %s -o %s" % (self.dev, self.cl.get_vpccidr(), self.dev)])
490+
self.fw.append(
491+
["", "front", "-A NETWORK_STATS_%s -d %s -i %s" % (self.dev, self.cl.get_vpccidr(), self.dev)])
493492

494493
self.fw.append(["", "front", "-A FORWARD -j NETWORK_STATS"])
495494
self.fw.append(["", "front", "-A INPUT -j NETWORK_STATS"])

0 commit comments

Comments
 (0)