Thomas Vachuska
Committed by Gerrit Code Review

Fixed issue with leaking various switch-related collectors, e.g. port stats, met…

…ers, table stats, flow stats.

Change-Id: If46102708fa88cf5f251a18cb9ce09393fb95752
...@@ -180,6 +180,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -180,6 +180,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
180 controller.removeListener(listener); 180 controller.removeListener(listener);
181 providerRegistry.unregister(this); 181 providerRegistry.unregister(this);
182 collectors.values().forEach(PortStatsCollector::stop); 182 collectors.values().forEach(PortStatsCollector::stop);
183 + collectors.clear();
183 providerService = null; 184 providerService = null;
184 LOG.info("Stopped"); 185 LOG.info("Stopped");
185 } 186 }
...@@ -374,10 +375,9 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -374,10 +375,9 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
374 providerService.deviceConnected(did, description); 375 providerService.deviceConnected(did, description);
375 providerService.updatePorts(did, buildPortDescriptions(sw)); 376 providerService.updatePorts(did, buildPortDescriptions(sw));
376 377
377 - PortStatsCollector psc = 378 + PortStatsCollector psc = new PortStatsCollector(sw, portStatsPollFrequency);
378 - new PortStatsCollector(sw, portStatsPollFrequency); 379 + stopCollectorIfNeeded(collectors.put(dpid, psc));
379 psc.start(); 380 psc.start();
380 - collectors.put(dpid, psc);
381 381
382 //figure out race condition for collectors.remove() and collectors.put() 382 //figure out race condition for collectors.remove() and collectors.put()
383 if (controller.getSwitch(dpid) == null) { 383 if (controller.getSwitch(dpid) == null) {
...@@ -385,17 +385,19 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -385,17 +385,19 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
385 } 385 }
386 } 386 }
387 387
388 + private void stopCollectorIfNeeded(PortStatsCollector collector) {
389 + if (collector != null) {
390 + collector.stop();
391 + }
392 + }
393 +
388 @Override 394 @Override
389 public void switchRemoved(Dpid dpid) { 395 public void switchRemoved(Dpid dpid) {
390 if (providerService == null) { 396 if (providerService == null) {
391 return; 397 return;
392 } 398 }
393 providerService.deviceDisconnected(deviceId(uri(dpid))); 399 providerService.deviceDisconnected(deviceId(uri(dpid)));
394 - 400 + stopCollectorIfNeeded(collectors.remove(dpid));
395 - PortStatsCollector collector = collectors.remove(dpid);
396 - if (collector != null) {
397 - collector.stop();
398 - }
399 } 401 }
400 402
401 @Override 403 @Override
......
...@@ -31,7 +31,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -31,7 +31,7 @@ import static org.slf4j.LoggerFactory.getLogger;
31 /** 31 /**
32 * Collects flow statistics for the specified switch. 32 * Collects flow statistics for the specified switch.
33 */ 33 */
34 -class FlowStatsCollector { 34 +class FlowStatsCollector implements SwitchDataCollector {
35 35
36 private final Logger log = getLogger(getClass()); 36 private final Logger log = getLogger(getClass());
37 37
......
...@@ -55,7 +55,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -55,7 +55,7 @@ import static org.slf4j.LoggerFactory.getLogger;
55 /** 55 /**
56 * Efficiently and adaptively collects flow statistics for the specified switch. 56 * Efficiently and adaptively collects flow statistics for the specified switch.
57 */ 57 */
58 -public class NewAdaptiveFlowStatsCollector { 58 +public class NewAdaptiveFlowStatsCollector implements SwitchDataCollector {
59 private final Logger log = getLogger(getClass()); 59 private final Logger log = getLogger(getClass());
60 60
61 private static final String CHECK_AND_MOVE_LOG = 61 private static final String CHECK_AND_MOVE_LOG =
......
...@@ -131,7 +131,6 @@ public class OpenFlowRuleProvider extends AbstractProvider ...@@ -131,7 +131,6 @@ public class OpenFlowRuleProvider extends AbstractProvider
131 131
132 // NewAdaptiveFlowStatsCollector Set 132 // NewAdaptiveFlowStatsCollector Set
133 private final Map<Dpid, NewAdaptiveFlowStatsCollector> afsCollectors = Maps.newHashMap(); 133 private final Map<Dpid, NewAdaptiveFlowStatsCollector> afsCollectors = Maps.newHashMap();
134 - private final Map<Dpid, FlowStatsCollector> collectors = Maps.newHashMap();
135 private final Map<Dpid, TableStatisticsCollector> tableStatsCollectors = Maps.newHashMap(); 134 private final Map<Dpid, TableStatisticsCollector> tableStatsCollectors = Maps.newHashMap();
136 135
137 /** 136 /**
...@@ -142,7 +141,7 @@ public class OpenFlowRuleProvider extends AbstractProvider ...@@ -142,7 +141,7 @@ public class OpenFlowRuleProvider extends AbstractProvider
142 } 141 }
143 142
144 @Activate 143 @Activate
145 - public void activate(ComponentContext context) { 144 + protected void activate(ComponentContext context) {
146 cfgService.registerProperties(getClass()); 145 cfgService.registerProperties(getClass());
147 providerService = providerRegistry.register(this); 146 providerService = providerRegistry.register(this);
148 controller.addListener(listener); 147 controller.addListener(listener);
...@@ -159,7 +158,7 @@ public class OpenFlowRuleProvider extends AbstractProvider ...@@ -159,7 +158,7 @@ public class OpenFlowRuleProvider extends AbstractProvider
159 } 158 }
160 159
161 @Deactivate 160 @Deactivate
162 - public void deactivate(ComponentContext context) { 161 + protected void deactivate(ComponentContext context) {
163 cfgService.unregisterProperties(getClass(), false); 162 cfgService.unregisterProperties(getClass(), false);
164 stopCollectors(); 163 stopCollectors();
165 providerRegistry.unregister(this); 164 providerRegistry.unregister(this);
...@@ -169,7 +168,7 @@ public class OpenFlowRuleProvider extends AbstractProvider ...@@ -169,7 +168,7 @@ public class OpenFlowRuleProvider extends AbstractProvider
169 } 168 }
170 169
171 @Modified 170 @Modified
172 - public void modified(ComponentContext context) { 171 + protected void modified(ComponentContext context) {
173 Dictionary<?, ?> properties = context.getProperties(); 172 Dictionary<?, ?> properties = context.getProperties();
174 int newFlowPollFrequency; 173 int newFlowPollFrequency;
175 try { 174 try {
...@@ -223,15 +222,21 @@ public class OpenFlowRuleProvider extends AbstractProvider ...@@ -223,15 +222,21 @@ public class OpenFlowRuleProvider extends AbstractProvider
223 NewAdaptiveFlowStatsCollector fsc = 222 NewAdaptiveFlowStatsCollector fsc =
224 new NewAdaptiveFlowStatsCollector(driverService, sw, flowPollFrequency); 223 new NewAdaptiveFlowStatsCollector(driverService, sw, flowPollFrequency);
225 fsc.start(); 224 fsc.start();
226 - afsCollectors.put(new Dpid(sw.getId()), fsc); 225 + stopCollectorIfNeeded(afsCollectors.put(new Dpid(sw.getId()), fsc));
227 } else { 226 } else {
228 FlowStatsCollector fsc = new FlowStatsCollector(timer, sw, flowPollFrequency); 227 FlowStatsCollector fsc = new FlowStatsCollector(timer, sw, flowPollFrequency);
229 fsc.start(); 228 fsc.start();
230 - simpleCollectors.put(new Dpid(sw.getId()), fsc); 229 + stopCollectorIfNeeded(simpleCollectors.put(new Dpid(sw.getId()), fsc));
231 } 230 }
232 TableStatisticsCollector tsc = new TableStatisticsCollector(timer, sw, flowPollFrequency); 231 TableStatisticsCollector tsc = new TableStatisticsCollector(timer, sw, flowPollFrequency);
233 tsc.start(); 232 tsc.start();
234 - tableStatsCollectors.put(new Dpid(sw.getId()), tsc); 233 + stopCollectorIfNeeded(tableStatsCollectors.put(new Dpid(sw.getId()), tsc));
234 + }
235 +
236 + private void stopCollectorIfNeeded(SwitchDataCollector collector) {
237 + if (collector != null) {
238 + collector.stop();
239 + }
235 } 240 }
236 241
237 private void stopCollectors() { 242 private void stopCollectors() {
...@@ -398,29 +403,17 @@ public class OpenFlowRuleProvider extends AbstractProvider ...@@ -398,29 +403,17 @@ public class OpenFlowRuleProvider extends AbstractProvider
398 403
399 @Override 404 @Override
400 public void switchAdded(Dpid dpid) { 405 public void switchAdded(Dpid dpid) {
401 -
402 - OpenFlowSwitch sw = controller.getSwitch(dpid);
403 -
404 createCollector(controller.getSwitch(dpid)); 406 createCollector(controller.getSwitch(dpid));
405 } 407 }
406 408
407 @Override 409 @Override
408 public void switchRemoved(Dpid dpid) { 410 public void switchRemoved(Dpid dpid) {
409 if (adaptiveFlowSampling) { 411 if (adaptiveFlowSampling) {
410 - NewAdaptiveFlowStatsCollector collector = afsCollectors.remove(dpid); 412 + stopCollectorIfNeeded(afsCollectors.remove(dpid));
411 - if (collector != null) {
412 - collector.stop();
413 - }
414 } else { 413 } else {
415 - FlowStatsCollector collector = simpleCollectors.remove(dpid); 414 + stopCollectorIfNeeded(simpleCollectors.remove(dpid));
416 - if (collector != null) {
417 - collector.stop();
418 - }
419 - }
420 - TableStatisticsCollector tsc = tableStatsCollectors.remove(dpid);
421 - if (tsc != null) {
422 - tsc.stop();
423 } 415 }
416 + stopCollectorIfNeeded(tableStatsCollectors.remove(dpid));
424 } 417 }
425 418
426 @Override 419 @Override
......
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.provider.of.flow.impl;
18 +
19 +/**
20 + * Auxiliary abstraction.
21 + */
22 +interface SwitchDataCollector {
23 +
24 + /**
25 + * Starts the collector.
26 + */
27 + void start();
28 +
29 + /**
30 + * Stops the collector.
31 + */
32 + void stop();
33 +}
...\ No newline at end of file ...\ No newline at end of file
...@@ -29,7 +29,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -29,7 +29,7 @@ import static org.slf4j.LoggerFactory.getLogger;
29 /** 29 /**
30 * Collects Table statistics for the specified switch. 30 * Collects Table statistics for the specified switch.
31 */ 31 */
32 -class TableStatisticsCollector { 32 +class TableStatisticsCollector implements SwitchDataCollector {
33 33
34 private final Logger log = getLogger(getClass()); 34 private final Logger log = getLogger(getClass());
35 35
......
...@@ -363,10 +363,7 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv ...@@ -363,10 +363,7 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv
363 if (isGroupSupported(sw)) { 363 if (isGroupSupported(sw)) {
364 GroupStatsCollector gsc = new GroupStatsCollector(sw, POLL_INTERVAL); 364 GroupStatsCollector gsc = new GroupStatsCollector(sw, POLL_INTERVAL);
365 gsc.start(); 365 gsc.start();
366 - GroupStatsCollector prevGsc = collectors.put(dpid, gsc); 366 + stopCollectorIfNeeded(collectors.put(dpid, gsc));
367 - if (prevGsc != null) {
368 - prevGsc.stop();
369 - }
370 } 367 }
371 368
372 //figure out race condition 369 //figure out race condition
...@@ -377,7 +374,10 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv ...@@ -377,7 +374,10 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv
377 374
378 @Override 375 @Override
379 public void switchRemoved(Dpid dpid) { 376 public void switchRemoved(Dpid dpid) {
380 - GroupStatsCollector collector = collectors.remove(dpid); 377 + stopCollectorIfNeeded(collectors.remove(dpid));
378 + }
379 +
380 + private void stopCollectorIfNeeded(GroupStatsCollector collector) {
381 if (collector != null) { 381 if (collector != null) {
382 collector.stop(); 382 collector.stop();
383 } 383 }
......
...@@ -207,7 +207,13 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv ...@@ -207,7 +207,13 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv
207 if (isMeterSupported(sw)) { 207 if (isMeterSupported(sw)) {
208 MeterStatsCollector msc = new MeterStatsCollector(sw, POLL_INTERVAL); 208 MeterStatsCollector msc = new MeterStatsCollector(sw, POLL_INTERVAL);
209 msc.start(); 209 msc.start();
210 - collectors.put(new Dpid(sw.getId()), msc); 210 + stopCollectorIfNeeded(collectors.put(new Dpid(sw.getId()), msc));
211 + }
212 + }
213 +
214 + private void stopCollectorIfNeeded(MeterStatsCollector collector) {
215 + if (collector != null) {
216 + collector.stop();
211 } 217 }
212 } 218 }
213 219
...@@ -370,10 +376,7 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv ...@@ -370,10 +376,7 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv
370 376
371 @Override 377 @Override
372 public void switchRemoved(Dpid dpid) { 378 public void switchRemoved(Dpid dpid) {
373 - MeterStatsCollector msc = collectors.remove(dpid); 379 + stopCollectorIfNeeded(collectors.remove(dpid));
374 - if (msc != null) {
375 - msc.stop();
376 - }
377 } 380 }
378 381
379 @Override 382 @Override
......