1 /* 2 * Copyright (C) 2016 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 _STORAGED_H_ 18 #define _STORAGED_H_ 19 20 #include <semaphore.h> 21 #include <stdint.h> 22 #include <time.h> 23 24 #include <queue> 25 #include <string> 26 #include <unordered_map> 27 #include <vector> 28 29 #include <utils/Mutex.h> 30 31 #include <aidl/android/hardware/health/IHealth.h> 32 #include <android/hardware/health/2.0/IHealth.h> 33 34 #define FRIEND_TEST(test_case_name, test_name) \ 35 friend class test_case_name##_##test_name##_Test 36 37 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 38 39 #define IS_ALIGNED(x, align) (!((x) & ((align) - 1))) 40 #define ROUND_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1)) 41 42 #define SECTOR_SIZE ( 512 ) 43 #define SEC_TO_MSEC ( 1000 ) 44 #define MSEC_TO_USEC ( 1000 ) 45 #define USEC_TO_NSEC ( 1000 ) 46 #define SEC_TO_USEC ( 1000000 ) 47 #define HOUR_TO_SEC ( 3600 ) 48 #define DAY_TO_SEC ( 3600 * 24 ) 49 #define WEEK_TO_DAYS ( 7 ) 50 #define YEAR_TO_WEEKS ( 52 ) 51 52 #include "storaged_diskstats.h" 53 #include "storaged_info.h" 54 #include "storaged_uid_monitor.h" 55 #include "storaged.pb.h" 56 #include "uid_info.h" 57 58 using namespace std; 59 using namespace android; 60 61 // Periodic chores intervals in seconds 62 #define DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT ( 60 ) 63 #define DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH ( 3600 ) 64 #define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO ( 3600 ) 65 #define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_LIMIT ( 300 ) 66 #define DEFAULT_PERIODIC_CHORES_INTERVAL_FLUSH_PROTO ( 3600 ) 67 68 // UID IO threshold in bytes 69 #define DEFAULT_PERIODIC_CHORES_UID_IO_THRESHOLD ( 1024 * 1024 * 1024ULL ) 70 71 class storaged_t; 72 73 struct storaged_config { 74 int periodic_chores_interval_unit; 75 int periodic_chores_interval_disk_stats_publish; 76 int periodic_chores_interval_uid_io; 77 int periodic_chores_interval_flush_proto; 78 int event_time_check_usec; // check how much cputime spent in event loop 79 }; 80 81 struct HealthServicePair { 82 std::shared_ptr<aidl::android::hardware::health::IHealth> aidl_health; 83 android::sp<android::hardware::health::V2_0::IHealth> hidl_health; 84 static HealthServicePair get(); 85 }; 86 87 class hidl_health_death_recipient : public android::hardware::hidl_death_recipient { 88 public: hidl_health_death_recipient(const android::sp<android::hardware::health::V2_0::IHealth> & health)89 hidl_health_death_recipient(const android::sp<android::hardware::health::V2_0::IHealth>& health) 90 : mHealth(health) {} 91 void serviceDied(uint64_t cookie, const wp<::android::hidl::base::V1_0::IBase>& who); 92 93 private: 94 android::sp<android::hardware::health::V2_0::IHealth> mHealth; 95 }; 96 97 class storaged_t : public RefBase { 98 private: 99 time_t mTimer; 100 storaged_config mConfig; 101 unique_ptr<disk_stats_monitor> mDsm; 102 uid_monitor mUidm; 103 time_t mStarttime; 104 std::shared_ptr<aidl::android::hardware::health::IHealth> health; 105 sp<android::hardware::hidl_death_recipient> hidl_death_recp; 106 ndk::ScopedAIBinder_DeathRecipient aidl_death_recp; 107 shared_ptr<aidl::android::hardware::health::IHealthInfoCallback> aidl_health_callback; 108 unique_ptr<storage_info_t> storage_info; 109 static const uint32_t current_version; 110 Mutex proto_lock; 111 unordered_map<userid_t, bool> proto_loaded; 112 void load_proto(userid_t user_id); 113 char* prepare_proto(userid_t user_id, StoragedProto* proto); 114 void flush_proto(userid_t user_id, StoragedProto* proto); 115 void flush_proto_data(userid_t user_id, const char* data, ssize_t size); proto_path(userid_t user_id)116 string proto_path(userid_t user_id) { 117 return string("/data/misc_ce/") + to_string(user_id) + 118 "/storaged/storaged.proto"; 119 } 120 void init_health_service(); 121 122 public: 123 storaged_t(void); 124 void init(void); 125 void event(void); 126 void event_checked(void); pause(void)127 void pause(void) { 128 sleep(mConfig.periodic_chores_interval_unit); 129 } 130 get_starttime(void)131 time_t get_starttime(void) { 132 return mStarttime; 133 } 134 get_uids(void)135 unordered_map<uint32_t, uid_info> get_uids(void) { 136 return mUidm.get_uid_io_stats(); 137 } 138 get_perf_history(void)139 vector<int> get_perf_history(void) { 140 return storage_info->get_perf_history(); 141 } 142 get_recent_perf(void)143 uint32_t get_recent_perf(void) { return storage_info->get_recent_perf(); } 144 get_uid_records(double hours,uint64_t threshold,bool force_report)145 map<uint64_t, struct uid_records> get_uid_records( 146 double hours, uint64_t threshold, bool force_report) { 147 return mUidm.dump(hours, threshold, force_report); 148 } 149 update_uid_io_interval(int interval)150 void update_uid_io_interval(int interval) { 151 if (interval >= DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_LIMIT) { 152 mConfig.periodic_chores_interval_uid_io = interval; 153 } 154 } 155 156 void add_user_ce(userid_t user_id); 157 void remove_user_ce(userid_t user_id); 158 159 void report_storage_info(); 160 161 void flush_protos(unordered_map<int, StoragedProto>* protos); 162 }; 163 164 // Eventlog tag 165 // The content must match the definition in EventLogTags.logtags 166 #define EVENTLOGTAG_DISKSTATS ( 2732 ) 167 #define EVENTLOGTAG_EMMCINFO ( 2733 ) 168 #define EVENTLOGTAG_UID_IO_ALERT ( 2734 ) 169 170 #endif /* _STORAGED_H_ */ 171