shill: Device: Add receive / transmit byte count properties
Create "RecieveByteCount" and "TransmitByteCount" properties for
Devices, which increment persistently across shill instances. Also
create a "ResetByteCount" method on Devices to set these counters
back to zero.
BUG=chromium-os:31584
TEST=New unit tests; list-devices on a real machine. Restart shill,
and ensure byte counts are persisted to disk. Write a "reset-counters"
test script and ensure that this resets the counters and the on-disk
values are set to 0 as well.
Change-Id: I8d285310d153e1e219ef523528b575e2c600de01
Reviewed-on: https://gerrit.chromium.org/gerrit/27300
Reviewed-by: Ben Chan <benchan@chromium.org>
Commit-Ready: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/device.cc b/device.cc
index 9eda4df..db0616f 100644
--- a/device.cc
+++ b/device.cc
@@ -62,12 +62,14 @@
const char Device::kIPFlagReversePathFilterEnabled[] = "1";
// static
const char Device::kIPFlagReversePathFilterLooseMode[] = "2";
-
// static
const char Device::kStoragePowered[] = "Powered";
-
// static
const char Device::kStorageIPConfigs[] = "IPConfigs";
+// static
+const char Device::kStorageReceiveByteCount[] = "ReceiveByteCount";
+// static
+const char Device::kStorageTransmitByteCount[] = "TransmitByteCount";
Device::Device(ControlInterface *control_interface,
EventDispatcher *dispatcher,
@@ -96,6 +98,8 @@
weak_ptr_factory_.GetWeakPtr())),
technology_(technology),
portal_attempts_to_online_(0),
+ receive_byte_offset_(0),
+ transmit_byte_offset_(0),
dhcp_provider_(DHCPProvider::GetInstance()),
rtnl_handler_(RTNLHandler::GetInstance()) {
store_.RegisterConstString(flimflam::kAddressProperty, &hardware_address_);
@@ -140,6 +144,16 @@
// flimflam::kScanningProperty: Registered in WiFi, Cellular
// flimflam::kScanIntervalProperty: Registered in WiFi, Cellular
+
+ if (manager_ && manager_->device_info()) { // Unit tests may not have these.
+ manager_->device_info()->GetByteCounts(
+ interface_index_, &receive_byte_offset_, &transmit_byte_offset_);
+ HelpRegisterConstDerivedUint64(shill::kReceiveByteCountProperty,
+ &Device::GetReceiveByteCount);
+ HelpRegisterConstDerivedUint64(shill::kTransmitByteCountProperty,
+ &Device::GetTransmitByteCount);
+ }
+
LOG(INFO) << "Device created: " << link_name_
<< " index " << interface_index_;
}
@@ -267,7 +281,23 @@
}
enabled_persistent_ = true;
storage->GetBool(id, kStoragePowered, &enabled_persistent_);
- // TODO(cmasone): What does it mean to load an IPConfig identifier??
+ uint64 rx_byte_count = 0, tx_byte_count = 0;
+
+ manager_->device_info()->GetByteCounts(
+ interface_index_, &rx_byte_count, &tx_byte_count);
+ // If there is a byte-count present in the profile, the return value
+ // of Device::Get*ByteCount() should be the this stored value plus
+ // whatever additional bytes we receive since time-of-load. We
+ // accomplish this by the subtractions below, which can validly
+ // roll over "negative" in the subtractions below and in Get*ByteCount.
+ uint64 profile_byte_count;
+ if (storage->GetUint64(id, kStorageReceiveByteCount, &profile_byte_count)) {
+ receive_byte_offset_ = rx_byte_count - profile_byte_count;
+ }
+ if (storage->GetUint64(id, kStorageTransmitByteCount, &profile_byte_count)) {
+ transmit_byte_offset_ = tx_byte_count - profile_byte_count;
+ }
+
return true;
}
@@ -283,6 +313,8 @@
ipconfig_->Save(storage, suffix);
storage->SetString(id, kStorageIPConfigs, SerializeIPConfigs(suffix));
}
+ storage->SetUint64(id, kStorageReceiveByteCount, GetReceiveByteCount(NULL));
+ storage->SetUint64(id, kStorageTransmitByteCount, GetTransmitByteCount(NULL));
return true;
}
@@ -346,6 +378,15 @@
new CustomAccessor<Device, RpcIdentifiers>(this, get, NULL)));
}
+void Device::HelpRegisterConstDerivedUint64(
+ const string &name,
+ uint64(Device::*get)(Error *)) {
+ store_.RegisterDerivedUint64(
+ name,
+ Uint64Accessor(
+ new CustomAccessor<Device, uint64>(this, get, NULL)));
+}
+
void Device::ConfigureStaticIPTask() {
SLOG(Device, 2) << __func__ << " selected_service " << selected_service_.get()
<< " ipconfig " << ipconfig_.get();
@@ -514,6 +555,12 @@
return true;
}
+void Device::ResetByteCounters() {
+ manager_->device_info()->GetByteCounts(
+ interface_index_, &receive_byte_offset_, &transmit_byte_offset_);
+ manager_->UpdateDevice(this);
+}
+
bool Device::RestartPortalDetection() {
StopPortalDetection();
return StartPortalDetection();
@@ -701,6 +748,20 @@
return adaptor_->GetRpcConnectionIdentifier();
}
+uint64 Device::GetReceiveByteCount(Error */*error*/) {
+ uint64 rx_byte_count = 0, tx_byte_count = 0;
+ manager_->device_info()->GetByteCounts(
+ interface_index_, &rx_byte_count, &tx_byte_count);
+ return rx_byte_count - receive_byte_offset_;
+}
+
+uint64 Device::GetTransmitByteCount(Error */*error*/) {
+ uint64 rx_byte_count = 0, tx_byte_count = 0;
+ manager_->device_info()->GetByteCounts(
+ interface_index_, &rx_byte_count, &tx_byte_count);
+ return tx_byte_count - transmit_byte_offset_;
+}
+
bool Device::IsUnderlyingDeviceEnabled() const {
return false;
}