Implement logic in CarStorageMonitoringManager to detect the cost (in terms of disk I/O) of the previous shutdown
ext4 and f2fs offer lifetime_write_kbytes files via sysfs that let userspace discover the amount of data
written to each individual partition throughout its lifetime.
Using this information, we execute this algorithm:
- when CarService goes down, store lifetime_write_kbytes info for all mounted partitions;
- at the next boot, calculate lifetime_write_kbytes for all mounted partitions again;
- for every partition that existed at both shutdown and reboot, calculate the difference of the written amount;
- add up those deltas: this is the total amount of writes since CarService went down;
- take the aggregate UID I/O activity, and add up all bytes written to disk inferred from there: this is the cost of getting where we are;
- subtract this aggregate from the previously computed total delta: this is a fair approximation of the cost of shutdown
Test: tests in carservice_test and carservice_unit_test
Bug: 32512551
Change-Id: Ia791eaa1fdb4bf026c1760e2bd333c30a413721f
Fixes: 72236603
diff --git a/car-lib/api/system-current.txt b/car-lib/api/system-current.txt
index 16fb2d0..8ef43fd 100644
--- a/car-lib/api/system-current.txt
+++ b/car-lib/api/system-current.txt
@@ -750,6 +750,7 @@
method public java.util.List<android.car.storagemonitoring.IoStatsEntry> getBootIoStats() throws android.car.CarNotConnectedException;
method public java.util.List<android.car.storagemonitoring.IoStats> getIoStatsDeltas() throws android.car.CarNotConnectedException;
method public int getPreEolIndicatorStatus() throws android.car.CarNotConnectedException;
+ method public long getShutdownDiskWriteAmount() throws android.car.CarNotConnectedException;
method public android.car.storagemonitoring.WearEstimate getWearEstimate() throws android.car.CarNotConnectedException;
method public java.util.List<android.car.storagemonitoring.WearEstimateChange> getWearEstimateHistory() throws android.car.CarNotConnectedException;
method public void registerListener(android.car.storagemonitoring.CarStorageMonitoringManager.IoStatsListener) throws android.car.CarNotConnectedException;
@@ -759,6 +760,7 @@
field public static final int PRE_EOL_INFO_UNKNOWN = 0; // 0x0
field public static final int PRE_EOL_INFO_URGENT = 3; // 0x3
field public static final int PRE_EOL_INFO_WARNING = 2; // 0x2
+ field public static final long SHUTDOWN_COST_INFO_MISSING = -1L; // 0xffffffffffffffffL
}
public static abstract interface CarStorageMonitoringManager.IoStatsListener {
@@ -811,6 +813,19 @@
field public final long fsyncCalls;
}
+ public class LifetimeWriteInfo implements android.os.Parcelable {
+ ctor public LifetimeWriteInfo(java.lang.String, java.lang.String, long);
+ ctor public LifetimeWriteInfo(android.os.Parcel);
+ ctor public LifetimeWriteInfo(org.json.JSONObject) throws org.json.JSONException;
+ method public int describeContents();
+ method public void writeToJson(android.util.JsonWriter) throws java.io.IOException;
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.car.storagemonitoring.IoStats> CREATOR;
+ field public final java.lang.String fstype;
+ field public final java.lang.String partition;
+ field public final long writtenBytes;
+ }
+
public final class UidIoRecord {
ctor public UidIoRecord(int, long, long, long, long, long, long, long, long, long, long);
field public final long background_fsync;