| /* | |
| * Copyright (C) 2016 The Android Open Source Project | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| #ifndef _STORAGED_H_ | |
| #define _STORAGED_H_ | |
| #include <semaphore.h> | |
| #include <stdint.h> | |
| #include <time.h> | |
| #include <queue> | |
| #include <string> | |
| #include <unordered_map> | |
| #include <vector> | |
| #include <utils/Mutex.h> | |
| #include <android/hardware/health/2.0/IHealth.h> | |
| #define FRIEND_TEST(test_case_name, test_name) \ | |
| friend class test_case_name##_##test_name##_Test | |
| #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | |
| #define IS_ALIGNED(x, align) (!((x) & ((align) - 1))) | |
| #define ROUND_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1)) | |
| #define SECTOR_SIZE ( 512 ) | |
| #define SEC_TO_MSEC ( 1000 ) | |
| #define MSEC_TO_USEC ( 1000 ) | |
| #define USEC_TO_NSEC ( 1000 ) | |
| #define SEC_TO_USEC ( 1000000 ) | |
| #define HOUR_TO_SEC ( 3600 ) | |
| #define DAY_TO_SEC ( 3600 * 24 ) | |
| #define WEEK_TO_DAYS ( 7 ) | |
| #define YEAR_TO_WEEKS ( 52 ) | |
| #include "storaged_diskstats.h" | |
| #include "storaged_info.h" | |
| #include "storaged_uid_monitor.h" | |
| #include "storaged.pb.h" | |
| #include "uid_info.h" | |
| using namespace std; | |
| using namespace android; | |
| // Periodic chores intervals in seconds | |
| #define DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT ( 60 ) | |
| #define DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH ( 3600 ) | |
| #define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO ( 3600 ) | |
| #define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_LIMIT ( 300 ) | |
| #define DEFAULT_PERIODIC_CHORES_INTERVAL_FLUSH_PROTO ( 3600 ) | |
| // UID IO threshold in bytes | |
| #define DEFAULT_PERIODIC_CHORES_UID_IO_THRESHOLD ( 1024 * 1024 * 1024ULL ) | |
| struct storaged_config { | |
| int periodic_chores_interval_unit; | |
| int periodic_chores_interval_disk_stats_publish; | |
| int periodic_chores_interval_uid_io; | |
| int periodic_chores_interval_flush_proto; | |
| int event_time_check_usec; // check how much cputime spent in event loop | |
| }; | |
| class storaged_t : public android::hardware::health::V2_0::IHealthInfoCallback, | |
| public android::hardware::hidl_death_recipient { | |
| private: | |
| time_t mTimer; | |
| storaged_config mConfig; | |
| unique_ptr<disk_stats_monitor> mDsm; | |
| uid_monitor mUidm; | |
| time_t mStarttime; | |
| sp<android::hardware::health::V2_0::IHealth> health; | |
| unique_ptr<storage_info_t> storage_info; | |
| static const uint32_t current_version; | |
| unordered_map<userid_t, bool> proto_loaded; | |
| void load_proto(userid_t user_id); | |
| char* prepare_proto(userid_t user_id, StoragedProto* proto); | |
| void flush_proto(userid_t user_id, StoragedProto* proto); | |
| void flush_proto_data(userid_t user_id, const char* data, ssize_t size); | |
| string proto_path(userid_t user_id) { | |
| return string("/data/misc_ce/") + to_string(user_id) + | |
| "/storaged/storaged.proto"; | |
| } | |
| void init_health_service(); | |
| public: | |
| storaged_t(void); | |
| void init(void); | |
| void event(void); | |
| void event_checked(void); | |
| void pause(void) { | |
| sleep(mConfig.periodic_chores_interval_unit); | |
| } | |
| time_t get_starttime(void) { | |
| return mStarttime; | |
| } | |
| unordered_map<uint32_t, uid_info> get_uids(void) { | |
| return mUidm.get_uid_io_stats(); | |
| } | |
| vector<int> get_perf_history(void) { | |
| return storage_info->get_perf_history(); | |
| } | |
| uint32_t get_recent_perf(void) { return storage_info->get_recent_perf(); } | |
| map<uint64_t, struct uid_records> get_uid_records( | |
| double hours, uint64_t threshold, bool force_report) { | |
| return mUidm.dump(hours, threshold, force_report); | |
| } | |
| void update_uid_io_interval(int interval) { | |
| if (interval >= DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_LIMIT) { | |
| mConfig.periodic_chores_interval_uid_io = interval; | |
| } | |
| } | |
| void add_user_ce(userid_t user_id); | |
| void remove_user_ce(userid_t user_id); | |
| virtual ::android::hardware::Return<void> healthInfoChanged( | |
| const ::android::hardware::health::V2_0::HealthInfo& info); | |
| void serviceDied(uint64_t cookie, const wp<::android::hidl::base::V1_0::IBase>& who); | |
| void report_storage_info(); | |
| void flush_protos(unordered_map<int, StoragedProto>* protos); | |
| }; | |
| // Eventlog tag | |
| // The content must match the definition in EventLogTags.logtags | |
| #define EVENTLOGTAG_DISKSTATS ( 2732 ) | |
| #define EVENTLOGTAG_EMMCINFO ( 2733 ) | |
| #define EVENTLOGTAG_UID_IO_ALERT ( 2734 ) | |
| #endif /* _STORAGED_H_ */ |