Merge lp:~therve/landscape-client/network-plugin-reboot into lp:~landscape/landscape-client/trunk

Proposed by Thomas Herve
Status: Merged
Approved by: Kevin McDermott
Approved revision: 287
Merged at revision: 284
Proposed branch: lp:~therve/landscape-client/network-plugin-reboot
Merge into: lp:~landscape/landscape-client/trunk
Diff against target: 177 lines (+91/-8)
3 files modified
landscape/lib/network.py (+1/-1)
landscape/monitor/networkactivity.py (+26/-5)
landscape/monitor/tests/test_networkactivity.py (+64/-2)
To merge this branch: bzr merge lp:~therve/landscape-client/network-plugin-reboot
Reviewer Review Type Date Requested Status
Kevin McDermott (community) Approve
Jamu Kakar (community) Approve
Review via email: mp+32755@code.launchpad.net

Description of the change

The branch handles the rollovers of /proc/net/dev, hopefully.

Restarting was indeed not a problem, because we keep a memory safeguard. I'm still a little bit worried about the persist, but I guess it's fine.

To post a comment you must log in.
287. By Thomas Herve

Put back safeguard, handle packet rollover

Revision history for this message
Jamu Kakar (jkakar) wrote :

[1]

+ self._rolloverunit = pow(2, 64) if is_64() else pow(2, 32)

Please s/_rolloverunit/_rollover_unit/.

The change seems slightly odd to me, but I guess it's a step up from
what we have, +1!

review: Approve
Revision history for this message
Kevin McDermott (bigkevmcd) wrote :

I'd prefer _rollover_unit to be named something like _rollover_maxint or something, as it's essentially the MAXINT value for the platform...

Other than that, it's cool, subject to the kernel bugs we've seen...

+1

review: Approve
288. By Thomas Herve

Rename rollover variable.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'landscape/lib/network.py'
--- landscape/lib/network.py 2010-07-23 08:08:41 +0000
+++ landscape/lib/network.py 2010-08-18 08:45:58 +0000
@@ -6,7 +6,7 @@
6import socket6import socket
7import struct7import struct
88
9__all__ = ["get_active_device_info", "get_network_traffic"]9__all__ = ["get_active_device_info", "get_network_traffic", "is_64"]
1010
11# from header /usr/include/bits/ioctls.h11# from header /usr/include/bits/ioctls.h
12SIOCGIFCONF = 0x891212SIOCGIFCONF = 0x8912
1313
=== modified file 'landscape/monitor/networkactivity.py'
--- landscape/monitor/networkactivity.py 2010-06-11 09:12:51 +0000
+++ landscape/monitor/networkactivity.py 2010-08-18 08:45:58 +0000
@@ -5,7 +5,7 @@
55
6import time6import time
77
8from landscape.lib.network import get_network_traffic8from landscape.lib.network import get_network_traffic, is_64
9from landscape.accumulate import Accumulator9from landscape.accumulate import Accumulator
1010
11from landscape.monitor.plugin import MonitorPlugin11from landscape.monitor.plugin import MonitorPlugin
@@ -28,6 +28,7 @@
28 # our last traffic sample for calculating a traffic delta28 # our last traffic sample for calculating a traffic delta
29 self._last_activity = {}29 self._last_activity = {}
30 self._create_time = create_time30 self._create_time = create_time
31 self._rollover_maxint = pow(2, 64) if is_64() else pow(2, 32)
3132
32 def register(self, registry):33 def register(self, registry):
33 super(NetworkActivity, self).register(registry)34 super(NetworkActivity, self).register(registry)
@@ -61,14 +62,34 @@
61 for interface in new_traffic:62 for interface in new_traffic:
62 traffic = new_traffic[interface]63 traffic = new_traffic[interface]
63 if interface in self._last_activity:64 if interface in self._last_activity:
64 previous_out, previous_in = self._last_activity[interface]65 (previous_out, previous_in, previous_packet_out,
66 previous_packet_in) = self._last_activity[interface]
65 delta_out = traffic["send_bytes"] - previous_out67 delta_out = traffic["send_bytes"] - previous_out
66 delta_in = traffic["recv_bytes"] - previous_in68 delta_in = traffic["recv_bytes"] - previous_in
67 if not delta_out and not delta_in:69 if not delta_out and not delta_in:
68 continue70 continue
71 if delta_out < 0:
72 delta_out += self._rollover_maxint
73 if delta_in < 0:
74 delta_in += self._rollover_maxint
75 packets_delta_out = (
76 traffic["send_packets"] - previous_packet_out)
77 if packets_delta_out < 0:
78 packets_delta_out += self._rollover_maxint
79 # 28 bytes is the minimum packet size, roughly
80 if packets_delta_out * 28 > delta_out:
81 delta_out += self._rollover_maxint
82 packets_delta_in = (
83 traffic["recv_packets"] - previous_packet_in)
84 if packets_delta_in < 0:
85 packets_delta_in += self._rollover_maxint
86 if packets_delta_in * 28 > delta_in:
87 delta_in += self._rollover_maxint
88
69 yield interface, delta_out, delta_in89 yield interface, delta_out, delta_in
70 self._last_activity[interface] = (90 self._last_activity[interface] = (
71 traffic["send_bytes"], traffic["recv_bytes"])91 traffic["send_bytes"], traffic["recv_bytes"],
92 traffic["send_packets"], traffic["recv_packets"])
7293
73 def run(self):94 def run(self):
74 """95 """
@@ -79,10 +100,10 @@
79 new_traffic = get_network_traffic(self._source_file)100 new_traffic = get_network_traffic(self._source_file)
80 for interface, delta_out, delta_in in self._traffic_delta(new_traffic):101 for interface, delta_out, delta_in in self._traffic_delta(new_traffic):
81 out_step_data = self._accumulate(102 out_step_data = self._accumulate(
82 new_timestamp, delta_out, "delta-out-%s"%interface)103 new_timestamp, delta_out, "delta-out-%s" % interface)
83104
84 in_step_data = self._accumulate(105 in_step_data = self._accumulate(
85 new_timestamp, delta_in, "delta-in-%s"%interface)106 new_timestamp, delta_in, "delta-in-%s" % interface)
86107
87 # there's only data when we cross a step boundary108 # there's only data when we cross a step boundary
88 if not (in_step_data and out_step_data):109 if not (in_step_data and out_step_data):
89110
=== modified file 'landscape/monitor/tests/test_networkactivity.py'
--- landscape/monitor/tests/test_networkactivity.py 2010-06-11 09:12:51 +0000
+++ landscape/monitor/tests/test_networkactivity.py 2010-08-18 08:45:58 +0000
@@ -10,7 +10,7 @@
10 stats_template = """\10 stats_template = """\
11Inter-| Receive | Transmit11Inter-| Receive | Transmit
12 face |bytes packets compressed multicast|bytes packets errs drop fifo12 face |bytes packets compressed multicast|bytes packets errs drop fifo
13 lo:%(lo_in)d 0 0 0 %(lo_out)d 3321049 0 0 013 lo:%(lo_in)d %(lo_in_p)d 0 0 %(lo_out)d %(lo_out_p)d 0 0 0
14 eth0: %(eth0_in)d 12539 0 62 %(eth0_out)d 12579 0 0 014 eth0: %(eth0_in)d 12539 0 62 %(eth0_out)d 12579 0 0 0
15 %(extra)s15 %(extra)s
16"""16"""
@@ -29,10 +29,12 @@
29 super(NetworkActivityTest, self).tearDown()29 super(NetworkActivityTest, self).tearDown()
3030
31 def write_activity(self, lo_in=0, lo_out=0, eth0_in=0, eth0_out=0,31 def write_activity(self, lo_in=0, lo_out=0, eth0_in=0, eth0_out=0,
32 extra="", **kw):32 extra="", lo_in_p=0, lo_out_p=0, **kw):
33 kw.update(dict(33 kw.update(dict(
34 lo_in = lo_in,34 lo_in = lo_in,
35 lo_out = lo_out,35 lo_out = lo_out,
36 lo_in_p = lo_in_p,
37 lo_out_p = lo_out_p,
36 eth0_in = eth0_in,38 eth0_in = eth0_in,
37 eth0_out = eth0_out,39 eth0_out = eth0_out,
38 extra=extra))40 extra=extra))
@@ -80,6 +82,66 @@
80 [(300, 10, 99)])82 [(300, 10, 99)])
81 self.assertNotIn("eth0", message["activities"])83 self.assertNotIn("eth0", message["activities"])
8284
85 def test_proc_rollover(self):
86 """
87 If /proc/net/dev rollovers, the network plugin handles the value and
88 gives a positive value instead.
89 """
90 self.plugin._rollover_maxint = 10000
91 self.write_activity(lo_in=2000, lo_out=1900)
92 self.plugin.run()
93 self.reactor.advance(self.monitor.step_size)
94 self.write_activity(lo_in=1010, lo_out=999)
95 self.plugin.run()
96 message = self.plugin.create_message()
97 self.assertTrue(message)
98 self.assertTrue("type" in message)
99 self.assertEquals(message["type"], "network-activity")
100 self.assertEquals(message["activities"]["lo"],
101 [(300, 9010, 9099)])
102 self.assertNotIn("eth0", message["activities"])
103
104 def test_proc_huge_rollover(self):
105 """
106 If /proc/net/dev rollovers *and* that we pass the previous measured
107 value (so, more than 4GB in 30 seconds on 32 bits), we use the number
108 of packets to check if the number makes sense. It doesn't solve
109 everything, but it helps in some cases.
110 """
111 self.plugin._rollover_maxint = 10000
112 self.write_activity(lo_in=2000, lo_out=1900)
113 self.plugin.run()
114 self.reactor.advance(self.monitor.step_size)
115 self.write_activity(lo_in=3000, lo_out=1999, lo_in_p=100, lo_out_p=50)
116 self.plugin.run()
117 message = self.plugin.create_message()
118 self.assertTrue(message)
119 self.assertTrue("type" in message)
120 self.assertEquals(message["type"], "network-activity")
121 self.assertEquals(message["activities"]["lo"],
122 [(300, 11000, 10099)])
123 self.assertNotIn("eth0", message["activities"])
124
125 def test_proc_huge_packets_rollover(self):
126 """
127 The value of packets can rollover, too, even if it's unlikely at the
128 same time as bytes, let's handle the case.
129 """
130 self.plugin._rollover_maxint = 10000
131 self.write_activity(lo_in=2000, lo_out=1900, lo_in_p=600, lo_out_p=500)
132 self.plugin.run()
133 self.reactor.advance(self.monitor.step_size)
134 self.write_activity(lo_in=3000, lo_out=1999, lo_in_p=500, lo_out_p=200)
135 self.plugin.run()
136 message = self.plugin.create_message()
137 self.assertTrue(message)
138 self.assertTrue("type" in message)
139 self.assertEquals(message["type"], "network-activity")
140 self.assertEquals(message["activities"]["lo"],
141 [(300, 11000, 10099)])
142 self.assertNotIn("eth0", message["activities"])
143
144
83 def test_no_message_without_traffic_delta(self):145 def test_no_message_without_traffic_delta(self):
84 """146 """
85 If no traffic delta is detected between runs, no message will be147 If no traffic delta is detected between runs, no message will be

Subscribers

People subscribed via source and target branches

to all changes: