1 /* 2 * Copyright (c) 2020, The Android Open Source Project 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 #ifndef CPP_WATCHDOG_SERVER_SRC_IOOVERUSEMONITOR_H_ 18 #define CPP_WATCHDOG_SERVER_SRC_IOOVERUSEMONITOR_H_ 19 20 #include "IoOveruseConfigs.h" 21 #include "PackageInfoResolver.h" 22 #include "ProcStat.h" 23 #include "UidStatsCollector.h" 24 #include "WatchdogPerfService.h" 25 26 #include <android-base/result.h> 27 #include <android-base/stringprintf.h> 28 #include <android/automotive/watchdog/BnResourceOveruseListener.h> 29 #include <android/automotive/watchdog/PerStateBytes.h> 30 #include <android/automotive/watchdog/internal/ComponentType.h> 31 #include <android/automotive/watchdog/internal/IoOveruseConfiguration.h> 32 #include <android/automotive/watchdog/internal/PackageInfo.h> 33 #include <android/automotive/watchdog/internal/PackageIoOveruseStats.h> 34 #include <cutils/multiuser.h> 35 #include <utils/Mutex.h> 36 37 #include <time.h> 38 39 #include <ostream> 40 #include <string> 41 #include <unordered_map> 42 #include <unordered_set> 43 #include <vector> 44 45 namespace android { 46 namespace automotive { 47 namespace watchdog { 48 49 // Number of periodically monitored stats to cache in memory. 50 constexpr int32_t kDefaultPeriodicMonitorBufferSize = 360; 51 // Dumpsys flags. 52 constexpr const char* kResetResourceOveruseStatsFlag = "--reset_resource_overuse_stats"; 53 54 // Forward declaration for testing use only. 55 namespace internal { 56 57 class IoOveruseMonitorPeer; 58 59 } // namespace internal 60 61 // Used only in tests. 62 std::tuple<int64_t, int64_t> calculateStartAndDuration(const time_t& currentTime); 63 64 /** 65 * IIoOveruseMonitor interface defines the methods that the I/O overuse monitoring module 66 * should implement. 67 */ 68 class IIoOveruseMonitor : virtual public IDataProcessorInterface { 69 public: 70 // Returns whether or not the monitor is initialized. 71 virtual bool isInitialized() const = 0; 72 73 // Dumps the help text. 74 virtual bool dumpHelpText(int fd) const = 0; 75 76 // Below API is from internal/ICarWatchdog.aidl. Please refer to the AIDL for description. 77 virtual android::base::Result<void> updateResourceOveruseConfigurations( 78 const std::vector< 79 android::automotive::watchdog::internal::ResourceOveruseConfiguration>& 80 configs) = 0; 81 virtual android::base::Result<void> getResourceOveruseConfigurations( 82 std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>* 83 configs) const = 0; 84 85 // Below methods support APIs from ICarWatchdog.aidl. Please refer to the AIDL for description. 86 virtual android::base::Result<void> addIoOveruseListener( 87 const sp<IResourceOveruseListener>& listener) = 0; 88 89 virtual android::base::Result<void> removeIoOveruseListener( 90 const sp<IResourceOveruseListener>& listener) = 0; 91 92 virtual android::base::Result<void> getIoOveruseStats(IoOveruseStats* ioOveruseStats) const = 0; 93 94 virtual android::base::Result<void> resetIoOveruseStats( 95 const std::vector<std::string>& packageNames) = 0; 96 97 // Removes stats for the given user from the internal cache. 98 virtual void removeStatsForUser(userid_t userId) = 0; 99 }; 100 101 class IoOveruseMonitor final : public IIoOveruseMonitor { 102 public: 103 explicit IoOveruseMonitor(const android::sp<IWatchdogServiceHelper>& watchdogServiceHelper); 104 ~IoOveruseMonitor()105 ~IoOveruseMonitor() { terminate(); } 106 isInitialized()107 bool isInitialized() const override { 108 std::shared_lock readLock(mRwMutex); 109 return isInitializedLocked(); 110 } 111 112 // Below methods implement IDataProcessorInterface. name()113 std::string name() const override { return "IoOveruseMonitor"; } 114 friend std::ostream& operator<<(std::ostream& os, const IoOveruseMonitor& monitor); 115 android::base::Result<void> onBoottimeCollection( 116 [[maybe_unused]] time_t time, 117 [[maybe_unused]] const android::wp<UidStatsCollectorInterface>& uidStatsCollector, 118 [[maybe_unused]] const android::wp<ProcStat>& procStat) override { 119 // No I/O overuse monitoring during boot-time. 120 return {}; 121 } 122 123 android::base::Result<void> onPeriodicCollection( 124 time_t time, SystemState systemState, 125 const android::wp<UidStatsCollectorInterface>& uidStatsCollector, 126 const android::wp<ProcStat>& procStat) override; 127 128 android::base::Result<void> onCustomCollection( 129 time_t time, SystemState systemState, 130 const std::unordered_set<std::string>& filterPackages, 131 const android::wp<UidStatsCollectorInterface>& uidStatsCollector, 132 const android::wp<ProcStat>& procStat) override; 133 134 android::base::Result<void> onPeriodicMonitor( 135 time_t time, const android::wp<IProcDiskStatsInterface>& procDiskStats, 136 const std::function<void()>& alertHandler) override; 137 138 android::base::Result<void> onDump(int fd) const override; 139 140 bool dumpHelpText(int fd) const override; 141 142 android::base::Result<void> onCustomCollectionDump([[maybe_unused]] int fd) override { 143 // No special processing for custom collection. Thus no custom collection dump. 144 return {}; 145 } 146 147 // Below methods implement AIDL interfaces. 148 android::base::Result<void> updateResourceOveruseConfigurations( 149 const std::vector< 150 android::automotive::watchdog::internal::ResourceOveruseConfiguration>& configs) 151 override; 152 153 android::base::Result<void> getResourceOveruseConfigurations( 154 std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>* 155 configs) const override; 156 157 android::base::Result<void> addIoOveruseListener( 158 const sp<IResourceOveruseListener>& listener) override; 159 160 android::base::Result<void> removeIoOveruseListener( 161 const sp<IResourceOveruseListener>& listener) override; 162 163 android::base::Result<void> getIoOveruseStats(IoOveruseStats* ioOveruseStats) const override; 164 165 android::base::Result<void> resetIoOveruseStats( 166 const std::vector<std::string>& packageName) override; 167 168 void removeStatsForUser(userid_t userId) override; 169 170 protected: 171 android::base::Result<void> init(); 172 173 void terminate(); 174 175 private: 176 struct WrittenBytesSnapshot { 177 double pollDurationInSecs; 178 uint64_t bytesInKib; 179 }; 180 181 struct UserPackageIoUsage { 182 UserPackageIoUsage(const android::automotive::watchdog::internal::PackageInfo& packageInfo, 183 const UidIoStats& uidIoStats, const bool isGarageModeActive); 184 android::automotive::watchdog::internal::PackageInfo packageInfo = {}; 185 PerStateBytes writtenBytes = {}; 186 PerStateBytes forgivenWriteBytes = {}; 187 int totalOveruses = 0; 188 bool isPackageWarned = false; 189 uint64_t lastSyncedWrittenBytes = 0; 190 191 UserPackageIoUsage& operator+=(const UserPackageIoUsage& r); 192 UserPackageIoUsage& operator+=( 193 const android::automotive::watchdog::internal::IoUsageStats& r); 194 195 const std::string id() const; 196 void resetStats(); 197 }; 198 199 class BinderDeathRecipient final : public android::IBinder::DeathRecipient { 200 public: BinderDeathRecipient(const android::sp<IoOveruseMonitor> & service)201 explicit BinderDeathRecipient(const android::sp<IoOveruseMonitor>& service) : 202 mService(service) {} 203 binderDied(const android::wp<android::IBinder> & who)204 void binderDied(const android::wp<android::IBinder>& who) override { 205 mService->handleBinderDeath(who); 206 } 207 208 private: 209 android::sp<IoOveruseMonitor> mService; 210 }; 211 212 private: isInitializedLocked()213 bool isInitializedLocked() const { return mIoOveruseConfigs != nullptr; } 214 215 void syncTodayIoUsageStatsLocked(); 216 217 void notifyNativePackagesLocked(const std::unordered_map<uid_t, IoOveruseStats>& statsByUid); 218 219 void handleBinderDeath(const wp<IBinder>& who); 220 221 using ListenersByUidMap = std::unordered_map<uid_t, android::sp<IResourceOveruseListener>>; 222 using Processor = std::function<void(ListenersByUidMap&, ListenersByUidMap::const_iterator)>; 223 bool findListenerAndProcessLocked(const sp<IBinder>& binder, const Processor& processor); 224 225 /** 226 * Writes in-memory configs to disk asynchronously if configs are not written after latest 227 * update. 228 */ 229 void writeConfigsToDiskAsyncLocked(); 230 231 // Local IPackageInfoResolver instance. Useful to mock in tests. 232 sp<IPackageInfoResolver> mPackageInfoResolver; 233 // Minimum written bytes to sync the stats with the Watchdog service. 234 double mMinSyncWrittenBytes; 235 android::sp<IWatchdogServiceHelper> mWatchdogServiceHelper; 236 237 // Makes sure only one collection is running at any given time. 238 mutable std::shared_mutex mRwMutex; 239 240 // Indicates whether or not today's I/O usage stats, that were collected during previous boot, 241 // are read from CarService because CarService persists these stats in database across reboot. 242 bool mDidReadTodayPrevBootStats GUARDED_BY(mRwMutex); 243 244 // Summary of configs available for all the components and system-wide overuse alert thresholds. 245 sp<IIoOveruseConfigs> mIoOveruseConfigs GUARDED_BY(mRwMutex); 246 247 /** 248 * Delta of system-wide written kib across all disks from the last |mPeriodicMonitorBufferSize| 249 * polls along with the polling duration. 250 */ 251 std::vector<WrittenBytesSnapshot> mSystemWideWrittenBytes GUARDED_BY(mRwMutex); 252 size_t mPeriodicMonitorBufferSize GUARDED_BY(mRwMutex); 253 time_t mLastSystemWideIoMonitorTime GUARDED_BY(mRwMutex); 254 255 // Cache of I/O usage stats from previous boot that happened today. Key is a unique ID with 256 // the format `packageName:userId`. 257 std::unordered_map<std::string, android::automotive::watchdog::internal::IoUsageStats> 258 mPrevBootIoUsageStatsById GUARDED_BY(mRwMutex); 259 260 // Cache of per user package I/O usage. Key is a unique ID with the format `packageName:userId`. 261 std::unordered_map<std::string, UserPackageIoUsage> mUserPackageDailyIoUsageById 262 GUARDED_BY(mRwMutex); 263 double mIoOveruseWarnPercentage GUARDED_BY(mRwMutex); 264 time_t mLastUserPackageIoMonitorTime GUARDED_BY(mRwMutex); 265 std::vector<android::automotive::watchdog::internal::PackageIoOveruseStats> 266 mLatestIoOveruseStats; 267 268 ListenersByUidMap mOveruseListenersByUid GUARDED_BY(mRwMutex); 269 android::sp<BinderDeathRecipient> mBinderDeathRecipient; 270 271 friend class WatchdogPerfService; 272 273 // For unit tests. 274 friend class internal::IoOveruseMonitorPeer; 275 }; 276 277 } // namespace watchdog 278 } // namespace automotive 279 } // namespace android 280 281 #endif // CPP_WATCHDOG_SERVER_SRC_IOOVERUSEMONITOR_H_ 282