shill: Add device metrics registration for devices without link message.
Cellular devices may be created and registered without a preceding RTNL
link message.
BUG=chromium-os:38187
TEST=Restart modemmanager and make sure shill doesn't crash
Change-Id: I13697f53a007a5c4ff67106f980380db338fba64
Reviewed-on: https://gerrit.chromium.org/gerrit/41918
Reviewed-by: Ben Chan <benchan@chromium.org>
Commit-Queue: Thieu Le <thieule@chromium.org>
Tested-by: Thieu Le <thieule@chromium.org>
diff --git a/device_info.cc b/device_info.cc
index 75ab479..5cee01f 100644
--- a/device_info.cc
+++ b/device_info.cc
@@ -146,10 +146,15 @@
delayed_devices_.erase(device->interface_index());
CHECK(!GetDevice(device->interface_index()).get());
infos_[device->interface_index()].device = device;
+ if (metrics_->IsDeviceRegistered(device->interface_index(),
+ device->technology())) {
+ metrics_->NotifyDeviceInitialized(device->interface_index());
+ } else {
+ metrics_->RegisterDevice(device->interface_index(), device->technology());
+ }
if (Technology::IsPrimaryConnectivityTechnology(device->technology())) {
manager_->RegisterDevice(device);
}
- metrics_->NotifyDeviceInitialized(device->interface_index());
}
void DeviceInfo::DeregisterDevice(const DeviceRefPtr &device) {
diff --git a/metrics.cc b/metrics.cc
index bbbd150..0025305 100644
--- a/metrics.cc
+++ b/metrics.cc
@@ -581,8 +581,10 @@
void Metrics::RegisterDevice(int interface_index,
Technology::Identifier technology) {
+ SLOG(Metrics, 2) << __func__ << ": " << interface_index;
shared_ptr<DeviceMetrics> device_metrics(new DeviceMetrics);
devices_metrics_[interface_index] = device_metrics;
+ device_metrics->technology = technology;
string histogram = GetFullMetricName(kMetricTimeToInitializeMilliseconds,
technology);
device_metrics->initialization_timer.reset(
@@ -610,7 +612,19 @@
kMetricTimeToDisableMillisecondsNumBuckets));
}
+bool Metrics::IsDeviceRegistered(int interface_index,
+ Technology::Identifier technology) {
+ SLOG(Metrics, 2) << __func__ << ": interface index: " << interface_index
+ << ", technology: " << technology;
+ DeviceMetrics *device_metrics = GetDeviceMetrics(interface_index);
+ if (device_metrics == NULL)
+ return false;
+ // Make sure the device technologies match.
+ return (technology == device_metrics->technology);
+}
+
void Metrics::DeregisterDevice(int interface_index) {
+ SLOG(Metrics, 2) << __func__ << ": interface index: " << interface_index;
devices_metrics_.erase(interface_index);
}
@@ -705,11 +719,12 @@
kMetricNetworkServiceErrorsMax);
}
-Metrics::DeviceMetrics *Metrics::GetDeviceMetrics(int interface_index) {
- DeviceMetricsLookupMap::iterator it = devices_metrics_.find(interface_index);
+Metrics::DeviceMetrics *Metrics::GetDeviceMetrics(int interface_index) const {
+ DeviceMetricsLookupMap::const_iterator it =
+ devices_metrics_.find(interface_index);
if (it == devices_metrics_.end()) {
- SLOG(Metrics, 1) << "device " << interface_index << " not found";
- DCHECK(false);
+ SLOG(Metrics, 2) << __func__ << ": device " << interface_index
+ << " not found";
return NULL;
}
return it->second.get();
diff --git a/metrics.h b/metrics.h
index baa7613..9775692 100644
--- a/metrics.h
+++ b/metrics.h
@@ -331,6 +331,10 @@
void RegisterDevice(int interface_index,
Technology::Identifier technology);
+ // Checks to see if the device has already been registered.
+ bool IsDeviceRegistered(int interface_index,
+ Technology::Identifier technology);
+
// Deregisters the device from this class. All state transition timers
// will be removed.
void DeregisterDevice(int interface_index);
@@ -390,6 +394,7 @@
struct DeviceMetrics {
DeviceMetrics() {}
+ Technology::Identifier technology;
scoped_ptr<chromeos_metrics::TimerReporter> initialization_timer;
scoped_ptr<chromeos_metrics::TimerReporter> enable_timer;
scoped_ptr<chromeos_metrics::TimerReporter> disable_timer;
@@ -417,7 +422,7 @@
Service::ConnectState new_state);
void SendServiceFailure(const Service *service);
- DeviceMetrics *GetDeviceMetrics(int interface_index);
+ DeviceMetrics *GetDeviceMetrics (int interface_index) const;
// For unit test purposes.
void set_library(MetricsLibraryInterface *library);