diff options
author | Jin Qian | 2017-01-23 16:38:47 -0600 |
---|---|---|
committer | Jin Qian | 2017-01-24 16:45:50 -0600 |
commit | 3790f5bfafc52ca881b9350b922ffe94e6a537bb (patch) | |
tree | 8fd65e9b42e125a02fe07bf6c5ac73e7f53d7e14 /storaged | |
parent | bcd6e3b9d92b2eea3b054372c9adf00a1e6235bc (diff) | |
download | platform-system-core-3790f5bfafc52ca881b9350b922ffe94e6a537bb.tar.gz platform-system-core-3790f5bfafc52ca881b9350b922ffe94e6a537bb.tar.xz platform-system-core-3790f5bfafc52ca881b9350b922ffe94e6a537bb.zip |
storaged: replace cmd arguments with properties
Add properties to control event intervals.
Add a property to check time spent in event loop.
Bug: 34612341
Bug: 34198239
Change-Id: I01f64c84e17153377ece7ae530be106e3f55287e
Diffstat (limited to 'storaged')
-rw-r--r-- | storaged/README.properties | 6 | ||||
-rw-r--r-- | storaged/include/storaged.h | 25 | ||||
-rw-r--r-- | storaged/include/storaged_uid_monitor.h | 5 | ||||
-rw-r--r-- | storaged/main.cpp | 77 | ||||
-rw-r--r-- | storaged/storaged.cpp | 47 | ||||
-rw-r--r-- | storaged/storaged_uid_monitor.cpp | 4 | ||||
-rw-r--r-- | storaged/storaged_utils.cpp | 5 |
7 files changed, 67 insertions, 102 deletions
diff --git a/storaged/README.properties b/storaged/README.properties new file mode 100644 index 000000000..70e6026f0 --- /dev/null +++ b/storaged/README.properties | |||
@@ -0,0 +1,6 @@ | |||
1 | ro.storaged.event.interval # interval storaged scans for IO stats, in seconds | ||
2 | ro.storaged.event.perf_check # check for time spent in event loop, in microseconds | ||
3 | ro.storaged.disk_stats_pub # interval storaged publish disk stats, in seconds | ||
4 | ro.storaged.emmc_info_pub # interval storaged publish emmc info, in seconds | ||
5 | ro.storaged.uid_io.interval # interval storaged checks Per UID IO usage, in seconds | ||
6 | ro.storaged.uid_io.threshold # Per UID IO usage limit, in bytes | ||
diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h index 7fa9958bd..d3e6b7140 100644 --- a/storaged/include/storaged.h +++ b/storaged/include/storaged.h | |||
@@ -40,6 +40,12 @@ friend class test_case_name##_##test_name##_Test | |||
40 | #define debuginfo(...) | 40 | #define debuginfo(...) |
41 | #endif | 41 | #endif |
42 | 42 | ||
43 | #define SECTOR_SIZE ( 512 ) | ||
44 | #define SEC_TO_MSEC ( 1000 ) | ||
45 | #define MSEC_TO_USEC ( 1000 ) | ||
46 | #define USEC_TO_NSEC ( 1000 ) | ||
47 | #define SEC_TO_USEC ( 1000000 ) | ||
48 | |||
43 | // number of attributes diskstats has | 49 | // number of attributes diskstats has |
44 | #define DISK_STATS_SIZE ( 11 ) | 50 | #define DISK_STATS_SIZE ( 11 ) |
45 | // maximum size limit of a stats file | 51 | // maximum size limit of a stats file |
@@ -266,7 +272,10 @@ public: | |||
266 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT ( 60 ) | 272 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT ( 60 ) |
267 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH ( 3600 ) | 273 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH ( 3600 ) |
268 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_EMMC_INFO_PUBLISH ( 86400 ) | 274 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_EMMC_INFO_PUBLISH ( 86400 ) |
269 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_ALERT ( 3600 ) | 275 | #define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO ( 3600 ) |
276 | |||
277 | // UID IO threshold in bytes | ||
278 | #define DEFAULT_PERIODIC_CHORES_UID_IO_THRESHOLD ( 1024 * 1024 * 1024ULL ) | ||
270 | 279 | ||
271 | struct storaged_config { | 280 | struct storaged_config { |
272 | int periodic_chores_interval_unit; | 281 | int periodic_chores_interval_unit; |
@@ -277,6 +286,7 @@ struct storaged_config { | |||
277 | bool proc_uid_io_available; // whether uid_io is accessible | 286 | bool proc_uid_io_available; // whether uid_io is accessible |
278 | bool emmc_available; // whether eMMC est_csd file is readable | 287 | bool emmc_available; // whether eMMC est_csd file is readable |
279 | bool diskstats_available; // whether diskstats is accessible | 288 | bool diskstats_available; // whether diskstats is accessible |
289 | int event_time_check_usec; // check how much cputime spent in event loop | ||
280 | }; | 290 | }; |
281 | 291 | ||
282 | class storaged_t { | 292 | class storaged_t { |
@@ -293,21 +303,10 @@ public: | |||
293 | storaged_t(void); | 303 | storaged_t(void); |
294 | ~storaged_t() {} | 304 | ~storaged_t() {} |
295 | void event(void); | 305 | void event(void); |
306 | void event_checked(void); | ||
296 | void pause(void) { | 307 | void pause(void) { |
297 | sleep(mConfig.periodic_chores_interval_unit); | 308 | sleep(mConfig.periodic_chores_interval_unit); |
298 | } | 309 | } |
299 | void set_unit_interval(int unit) { | ||
300 | mConfig.periodic_chores_interval_unit = unit; | ||
301 | } | ||
302 | void set_diskstats_interval(int disk_stats) { | ||
303 | mConfig.periodic_chores_interval_disk_stats_publish = disk_stats; | ||
304 | } | ||
305 | void set_emmc_interval(int emmc_info) { | ||
306 | mConfig.periodic_chores_interval_emmc_info_publish = emmc_info; | ||
307 | } | ||
308 | void set_uid_io_interval(int uid_io) { | ||
309 | mUidm.set_periodic_chores_interval(uid_io); | ||
310 | } | ||
311 | std::vector<struct task_info> get_tasks(void) { | 310 | std::vector<struct task_info> get_tasks(void) { |
312 | // There could be a race when get_tasks() and the main thread is updating at the same time | 311 | // There could be a race when get_tasks() and the main thread is updating at the same time |
313 | // While update_running_tasks() is updating the critical sections at the end of the function | 312 | // While update_running_tasks() is updating the critical sections at the end of the function |
diff --git a/storaged/include/storaged_uid_monitor.h b/storaged/include/storaged_uid_monitor.h index eceb7fd34..9f95c5188 100644 --- a/storaged/include/storaged_uid_monitor.h +++ b/storaged/include/storaged_uid_monitor.h | |||
@@ -46,11 +46,12 @@ class uid_monitor { | |||
46 | private: | 46 | private: |
47 | std::unordered_map<uint32_t, struct uid_info> last_uids; | 47 | std::unordered_map<uint32_t, struct uid_info> last_uids; |
48 | void set_last_uids(std::unordered_map<uint32_t, struct uid_info>&& uids, uint64_t ts); | 48 | void set_last_uids(std::unordered_map<uint32_t, struct uid_info>&& uids, uint64_t ts); |
49 | int interval; // monitor interval in seconds | 49 | int interval; // monitor interval in seconds |
50 | int threshold; // monitor threshold in bytes | ||
50 | uint64_t last_report_ts; // timestamp of last report in nsec | 51 | uint64_t last_report_ts; // timestamp of last report in nsec |
51 | public: | 52 | public: |
52 | uid_monitor(); | 53 | uid_monitor(); |
53 | void set_periodic_chores_interval(int t) { interval = t; } | 54 | void set_periodic_chores_params(int intvl, int thold) { interval = intvl; threshold = thold; } |
54 | int get_periodic_chores_interval() { return interval; } | 55 | int get_periodic_chores_interval() { return interval; } |
55 | std::unordered_map<uint32_t, struct uid_info> get_uids(); | 56 | std::unordered_map<uint32_t, struct uid_info> get_uids(); |
56 | void report(); | 57 | void report(); |
diff --git a/storaged/main.cpp b/storaged/main.cpp index 915157493..c7f3dff5c 100644 --- a/storaged/main.cpp +++ b/storaged/main.cpp | |||
@@ -96,7 +96,7 @@ void* storaged_main(void* s) { | |||
96 | LOG_TO(SYSTEM, INFO) << "storaged: Start"; | 96 | LOG_TO(SYSTEM, INFO) << "storaged: Start"; |
97 | 97 | ||
98 | for (;;) { | 98 | for (;;) { |
99 | storaged->event(); | 99 | storaged->event_checked(); |
100 | storaged->pause(); | 100 | storaged->pause(); |
101 | } | 101 | } |
102 | return NULL; | 102 | return NULL; |
@@ -107,10 +107,6 @@ static void help_message(void) { | |||
107 | printf(" -d --dump Dump task I/O usage to stdout\n"); | 107 | printf(" -d --dump Dump task I/O usage to stdout\n"); |
108 | printf(" -u --uid Dump uid I/O usage to stdout\n"); | 108 | printf(" -u --uid Dump uid I/O usage to stdout\n"); |
109 | printf(" -s --start Start storaged (default)\n"); | 109 | printf(" -s --start Start storaged (default)\n"); |
110 | printf(" --emmc=INTERVAL Set publish interval of emmc lifetime information (in days)\n"); | ||
111 | printf(" --diskstats=INTERVAL Set publish interval of diskstats (in hours)\n"); | ||
112 | printf(" --uidio=INTERVAL Set publish interval of uid io (in hours)\n"); | ||
113 | printf(" --unit=INTERVAL Set storaged's refresh interval (in seconds)\n"); | ||
114 | fflush(stdout); | 110 | fflush(stdout); |
115 | } | 111 | } |
116 | 112 | ||
@@ -121,11 +117,6 @@ int main(int argc, char** argv) { | |||
121 | int flag_main_service = 0; | 117 | int flag_main_service = 0; |
122 | int flag_dump_task = 0; | 118 | int flag_dump_task = 0; |
123 | int flag_dump_uid = 0; | 119 | int flag_dump_uid = 0; |
124 | int flag_config = 0; | ||
125 | int unit_interval = DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT; | ||
126 | int diskstats_interval = DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH; | ||
127 | int emmc_interval = DEFAULT_PERIODIC_CHORES_INTERVAL_EMMC_INFO_PUBLISH; | ||
128 | int uid_io_interval = DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_ALERT; | ||
129 | int fd_emmc = -1; | 120 | int fd_emmc = -1; |
130 | int opt; | 121 | int opt; |
131 | 122 | ||
@@ -136,11 +127,7 @@ int main(int argc, char** argv) { | |||
136 | {"kill", no_argument, 0, 'k'}, | 127 | {"kill", no_argument, 0, 'k'}, |
137 | {"dump", no_argument, 0, 'd'}, | 128 | {"dump", no_argument, 0, 'd'}, |
138 | {"uid", no_argument, 0, 'u'}, | 129 | {"uid", no_argument, 0, 'u'}, |
139 | {"help", no_argument, 0, 'h'}, | 130 | {"help", no_argument, 0, 'h'} |
140 | {"unit", required_argument, 0, 0 }, | ||
141 | {"diskstats", required_argument, 0, 0 }, | ||
142 | {"emmc", required_argument, 0, 0 }, | ||
143 | {"uidio", required_argument, 0, 0 } | ||
144 | }; | 131 | }; |
145 | opt = getopt_long(argc, argv, ":skdhu0", long_options, &opt_idx); | 132 | opt = getopt_long(argc, argv, ":skdhu0", long_options, &opt_idx); |
146 | if (opt == -1) { | 133 | if (opt == -1) { |
@@ -148,53 +135,6 @@ int main(int argc, char** argv) { | |||
148 | } | 135 | } |
149 | 136 | ||
150 | switch (opt) { | 137 | switch (opt) { |
151 | case 0: | ||
152 | printf("option %s", long_options[opt_idx].name); | ||
153 | if (optarg) { | ||
154 | printf(" with arg %s", optarg); | ||
155 | if (strcmp(long_options[opt_idx].name, "unit") == 0) { | ||
156 | unit_interval = atoi(optarg); | ||
157 | if (unit_interval == 0) { | ||
158 | fprintf(stderr, "Invalid argument. Option %s requires an integer argument greater than 0.\n", | ||
159 | long_options[opt_idx].name); | ||
160 | help_message(); | ||
161 | return -1; | ||
162 | } | ||
163 | } else if (strcmp(long_options[opt_idx].name, "diskstats") == 0) { | ||
164 | diskstats_interval = atoi(optarg) * HOUR_TO_SEC; | ||
165 | if (diskstats_interval == 0) { | ||
166 | fprintf(stderr, "Invalid argument. Option %s requires an integer argument greater than 0.\n", | ||
167 | long_options[opt_idx].name); | ||
168 | help_message(); | ||
169 | return -1; | ||
170 | } | ||
171 | |||
172 | } else if (strcmp(long_options[opt_idx].name, "emmc") == 0) { | ||
173 | emmc_interval = atoi(optarg) * DAY_TO_SEC; | ||
174 | if (emmc_interval == 0) { | ||
175 | fprintf(stderr, "Invalid argument. Option %s requires an integer argument greater than 0.\n", | ||
176 | long_options[opt_idx].name); | ||
177 | help_message(); | ||
178 | return -1; | ||
179 | } | ||
180 | } else if (strcmp(long_options[opt_idx].name, "uidio") == 0) { | ||
181 | uid_io_interval = atoi(optarg) * HOUR_TO_SEC; | ||
182 | if (uid_io_interval == 0) { | ||
183 | fprintf(stderr, "Invalid argument. Option %s requires an integer argument greater than 0.\n", | ||
184 | long_options[opt_idx].name); | ||
185 | help_message(); | ||
186 | return -1; | ||
187 | } | ||
188 | } | ||
189 | flag_config = 1; | ||
190 | } else { | ||
191 | fprintf(stderr, "Invalid argument. Option %s requires an argument.\n", | ||
192 | long_options[opt_idx].name); | ||
193 | help_message(); | ||
194 | return -1; | ||
195 | } | ||
196 | printf("\n"); | ||
197 | break; | ||
198 | case 's': | 138 | case 's': |
199 | flag_main_service = 1; | 139 | flag_main_service = 1; |
200 | break; | 140 | break; |
@@ -225,12 +165,6 @@ int main(int argc, char** argv) { | |||
225 | return -1; | 165 | return -1; |
226 | } | 166 | } |
227 | 167 | ||
228 | if (flag_config && flag_dump_task) { | ||
229 | fprintf(stderr, "Invalid arguments. Cannot set configs in \'dump\' option.\n"); | ||
230 | help_message(); | ||
231 | return -1; | ||
232 | } | ||
233 | |||
234 | if (flag_main_service) { // start main thread | 168 | if (flag_main_service) { // start main thread |
235 | static const char mmc0_ext_csd[] = "/d/mmc0/mmc0:0001/ext_csd"; | 169 | static const char mmc0_ext_csd[] = "/d/mmc0/mmc0:0001/ext_csd"; |
236 | fd_emmc = android_get_control_file(mmc0_ext_csd); | 170 | fd_emmc = android_get_control_file(mmc0_ext_csd); |
@@ -243,13 +177,6 @@ int main(int argc, char** argv) { | |||
243 | 177 | ||
244 | storaged.set_privileged_fds(fd_emmc); | 178 | storaged.set_privileged_fds(fd_emmc); |
245 | 179 | ||
246 | if (flag_config) { | ||
247 | storaged.set_unit_interval(unit_interval); | ||
248 | storaged.set_diskstats_interval(diskstats_interval); | ||
249 | storaged.set_emmc_interval(emmc_interval); | ||
250 | storaged.set_uid_io_interval(uid_io_interval); | ||
251 | } | ||
252 | |||
253 | // Start the main thread of storaged | 180 | // Start the main thread of storaged |
254 | pthread_t storaged_main_thread; | 181 | pthread_t storaged_main_thread; |
255 | errno = pthread_create(&storaged_main_thread, NULL, storaged_main, &storaged); | 182 | errno = pthread_create(&storaged_main_thread, NULL, storaged_main, &storaged); |
diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp index 0c53f4482..1950c217a 100644 --- a/storaged/storaged.cpp +++ b/storaged/storaged.cpp | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <unistd.h> | 21 | #include <unistd.h> |
22 | 22 | ||
23 | #include <android-base/logging.h> | 23 | #include <android-base/logging.h> |
24 | #include <cutils/properties.h> | ||
24 | 25 | ||
25 | #include <storaged.h> | 26 | #include <storaged.h> |
26 | #include <storaged_utils.h> | 27 | #include <storaged_utils.h> |
@@ -176,10 +177,21 @@ storaged_t::storaged_t(void) { | |||
176 | 177 | ||
177 | mConfig.proc_uid_io_available = (access(UID_IO_STATS_PATH, R_OK) == 0); | 178 | mConfig.proc_uid_io_available = (access(UID_IO_STATS_PATH, R_OK) == 0); |
178 | 179 | ||
179 | mConfig.periodic_chores_interval_unit = DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT; | 180 | mConfig.periodic_chores_interval_unit = |
180 | mConfig.periodic_chores_interval_disk_stats_publish = DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH; | 181 | property_get_int32("ro.storaged.event.interval", DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT); |
181 | mConfig.periodic_chores_interval_emmc_info_publish = DEFAULT_PERIODIC_CHORES_INTERVAL_EMMC_INFO_PUBLISH; | 182 | |
182 | mUidm.set_periodic_chores_interval(DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_ALERT); | 183 | mConfig.event_time_check_usec = |
184 | property_get_int32("ro.storaged.event.perf_check", 0); | ||
185 | |||
186 | mConfig.periodic_chores_interval_disk_stats_publish = | ||
187 | property_get_int32("ro.storaged.disk_stats_pub", DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH); | ||
188 | |||
189 | mConfig.periodic_chores_interval_emmc_info_publish = | ||
190 | property_get_int32("ro.storaged.emmc_info_pub", DEFAULT_PERIODIC_CHORES_INTERVAL_EMMC_INFO_PUBLISH); | ||
191 | |||
192 | mUidm.set_periodic_chores_params( | ||
193 | property_get_int32("ro.storaged.uid_io.interval", DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO), | ||
194 | property_get_int32("ro.storaged.uid_io.threshold", DEFAULT_PERIODIC_CHORES_UID_IO_THRESHOLD)); | ||
183 | 195 | ||
184 | mStarttime = time(NULL); | 196 | mStarttime = time(NULL); |
185 | } | 197 | } |
@@ -212,3 +224,30 @@ void storaged_t::event(void) { | |||
212 | 224 | ||
213 | mTimer += mConfig.periodic_chores_interval_unit; | 225 | mTimer += mConfig.periodic_chores_interval_unit; |
214 | } | 226 | } |
227 | |||
228 | void storaged_t::event_checked(void) { | ||
229 | struct timespec start_ts, end_ts; | ||
230 | bool check_time = true; | ||
231 | |||
232 | if (mConfig.event_time_check_usec && | ||
233 | clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_ts) < 0) { | ||
234 | check_time = false; | ||
235 | PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed"; | ||
236 | } | ||
237 | |||
238 | event(); | ||
239 | |||
240 | if (mConfig.event_time_check_usec) { | ||
241 | if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_ts) < 0) { | ||
242 | PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed"; | ||
243 | return; | ||
244 | } | ||
245 | int64_t cost = (end_ts.tv_sec - start_ts.tv_sec) * SEC_TO_USEC + | ||
246 | (end_ts.tv_nsec - start_ts.tv_nsec) / USEC_TO_NSEC; | ||
247 | if (cost > mConfig.event_time_check_usec) { | ||
248 | LOG_TO(SYSTEM, ERROR) | ||
249 | << "event loop spent " << cost << " usec, threshold " | ||
250 | << mConfig.event_time_check_usec << " usec"; | ||
251 | } | ||
252 | } | ||
253 | } | ||
diff --git a/storaged/storaged_uid_monitor.cpp b/storaged/storaged_uid_monitor.cpp index 4105dae8f..2a84a0c40 100644 --- a/storaged/storaged_uid_monitor.cpp +++ b/storaged/storaged_uid_monitor.cpp | |||
@@ -33,8 +33,6 @@ | |||
33 | #include "storaged.h" | 33 | #include "storaged.h" |
34 | #include "storaged_uid_monitor.h" | 34 | #include "storaged_uid_monitor.h" |
35 | 35 | ||
36 | static const uint64_t io_alert_threshold = 1024 * 1024 * 1024; // 1GB | ||
37 | |||
38 | using namespace android; | 36 | using namespace android; |
39 | using namespace android::base; | 37 | using namespace android::base; |
40 | 38 | ||
@@ -116,7 +114,7 @@ void uid_monitor::report() | |||
116 | 114 | ||
117 | uint64_t curr_ts = ts.tv_sec * NS_PER_SEC + ts.tv_nsec; | 115 | uint64_t curr_ts = ts.tv_sec * NS_PER_SEC + ts.tv_nsec; |
118 | uint64_t ts_delta = curr_ts - last_report_ts; | 116 | uint64_t ts_delta = curr_ts - last_report_ts; |
119 | uint64_t adjusted_threshold = io_alert_threshold * ((double)ts_delta / interval / NS_PER_SEC); | 117 | uint64_t adjusted_threshold = threshold * ((double)ts_delta / interval / NS_PER_SEC); |
120 | 118 | ||
121 | std::unordered_map<uint32_t, struct uid_info> uids = get_uids(); | 119 | std::unordered_map<uint32_t, struct uid_info> uids = get_uids(); |
122 | if (uids.empty()) { | 120 | if (uids.empty()) { |
diff --git a/storaged/storaged_utils.cpp b/storaged/storaged_utils.cpp index 6e4ddb66c..1dcd0ffcf 100644 --- a/storaged/storaged_utils.cpp +++ b/storaged/storaged_utils.cpp | |||
@@ -41,11 +41,6 @@ | |||
41 | #include <storaged.h> | 41 | #include <storaged.h> |
42 | #include <storaged_utils.h> | 42 | #include <storaged_utils.h> |
43 | 43 | ||
44 | #define SECTOR_SIZE ( 512 ) | ||
45 | #define SEC_TO_MSEC ( 1000 ) | ||
46 | #define MSEC_TO_USEC ( 1000 ) | ||
47 | #define USEC_TO_NSEC ( 1000 ) | ||
48 | |||
49 | bool parse_disk_stats(const char* disk_stats_path, struct disk_stats* stats) { | 44 | bool parse_disk_stats(const char* disk_stats_path, struct disk_stats* stats) { |
50 | // Get time | 45 | // Get time |
51 | struct timespec ts; | 46 | struct timespec ts; |