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
This commit is contained in:
parent
bcd6e3b9d9
commit
3790f5bfaf
7 changed files with 67 additions and 102 deletions
6
storaged/README.properties
Normal file
6
storaged/README.properties
Normal file
|
@ -0,0 +1,6 @@
|
|||
ro.storaged.event.interval # interval storaged scans for IO stats, in seconds
|
||||
ro.storaged.event.perf_check # check for time spent in event loop, in microseconds
|
||||
ro.storaged.disk_stats_pub # interval storaged publish disk stats, in seconds
|
||||
ro.storaged.emmc_info_pub # interval storaged publish emmc info, in seconds
|
||||
ro.storaged.uid_io.interval # interval storaged checks Per UID IO usage, in seconds
|
||||
ro.storaged.uid_io.threshold # Per UID IO usage limit, in bytes
|
|
@ -40,6 +40,12 @@ friend class test_case_name##_##test_name##_Test
|
|||
#define debuginfo(...)
|
||||
#endif
|
||||
|
||||
#define SECTOR_SIZE ( 512 )
|
||||
#define SEC_TO_MSEC ( 1000 )
|
||||
#define MSEC_TO_USEC ( 1000 )
|
||||
#define USEC_TO_NSEC ( 1000 )
|
||||
#define SEC_TO_USEC ( 1000000 )
|
||||
|
||||
// number of attributes diskstats has
|
||||
#define DISK_STATS_SIZE ( 11 )
|
||||
// maximum size limit of a stats file
|
||||
|
@ -266,7 +272,10 @@ public:
|
|||
#define DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT ( 60 )
|
||||
#define DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH ( 3600 )
|
||||
#define DEFAULT_PERIODIC_CHORES_INTERVAL_EMMC_INFO_PUBLISH ( 86400 )
|
||||
#define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_ALERT ( 3600 )
|
||||
#define DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO ( 3600 )
|
||||
|
||||
// UID IO threshold in bytes
|
||||
#define DEFAULT_PERIODIC_CHORES_UID_IO_THRESHOLD ( 1024 * 1024 * 1024ULL )
|
||||
|
||||
struct storaged_config {
|
||||
int periodic_chores_interval_unit;
|
||||
|
@ -277,6 +286,7 @@ struct storaged_config {
|
|||
bool proc_uid_io_available; // whether uid_io is accessible
|
||||
bool emmc_available; // whether eMMC est_csd file is readable
|
||||
bool diskstats_available; // whether diskstats is accessible
|
||||
int event_time_check_usec; // check how much cputime spent in event loop
|
||||
};
|
||||
|
||||
class storaged_t {
|
||||
|
@ -293,21 +303,10 @@ public:
|
|||
storaged_t(void);
|
||||
~storaged_t() {}
|
||||
void event(void);
|
||||
void event_checked(void);
|
||||
void pause(void) {
|
||||
sleep(mConfig.periodic_chores_interval_unit);
|
||||
}
|
||||
void set_unit_interval(int unit) {
|
||||
mConfig.periodic_chores_interval_unit = unit;
|
||||
}
|
||||
void set_diskstats_interval(int disk_stats) {
|
||||
mConfig.periodic_chores_interval_disk_stats_publish = disk_stats;
|
||||
}
|
||||
void set_emmc_interval(int emmc_info) {
|
||||
mConfig.periodic_chores_interval_emmc_info_publish = emmc_info;
|
||||
}
|
||||
void set_uid_io_interval(int uid_io) {
|
||||
mUidm.set_periodic_chores_interval(uid_io);
|
||||
}
|
||||
std::vector<struct task_info> get_tasks(void) {
|
||||
// There could be a race when get_tasks() and the main thread is updating at the same time
|
||||
// While update_running_tasks() is updating the critical sections at the end of the function
|
||||
|
|
|
@ -46,11 +46,12 @@ class uid_monitor {
|
|||
private:
|
||||
std::unordered_map<uint32_t, struct uid_info> last_uids;
|
||||
void set_last_uids(std::unordered_map<uint32_t, struct uid_info>&& uids, uint64_t ts);
|
||||
int interval; // monitor interval in seconds
|
||||
int interval; // monitor interval in seconds
|
||||
int threshold; // monitor threshold in bytes
|
||||
uint64_t last_report_ts; // timestamp of last report in nsec
|
||||
public:
|
||||
uid_monitor();
|
||||
void set_periodic_chores_interval(int t) { interval = t; }
|
||||
void set_periodic_chores_params(int intvl, int thold) { interval = intvl; threshold = thold; }
|
||||
int get_periodic_chores_interval() { return interval; }
|
||||
std::unordered_map<uint32_t, struct uid_info> get_uids();
|
||||
void report();
|
||||
|
|
|
@ -96,7 +96,7 @@ void* storaged_main(void* s) {
|
|||
LOG_TO(SYSTEM, INFO) << "storaged: Start";
|
||||
|
||||
for (;;) {
|
||||
storaged->event();
|
||||
storaged->event_checked();
|
||||
storaged->pause();
|
||||
}
|
||||
return NULL;
|
||||
|
@ -107,10 +107,6 @@ static void help_message(void) {
|
|||
printf(" -d --dump Dump task I/O usage to stdout\n");
|
||||
printf(" -u --uid Dump uid I/O usage to stdout\n");
|
||||
printf(" -s --start Start storaged (default)\n");
|
||||
printf(" --emmc=INTERVAL Set publish interval of emmc lifetime information (in days)\n");
|
||||
printf(" --diskstats=INTERVAL Set publish interval of diskstats (in hours)\n");
|
||||
printf(" --uidio=INTERVAL Set publish interval of uid io (in hours)\n");
|
||||
printf(" --unit=INTERVAL Set storaged's refresh interval (in seconds)\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
@ -121,11 +117,6 @@ int main(int argc, char** argv) {
|
|||
int flag_main_service = 0;
|
||||
int flag_dump_task = 0;
|
||||
int flag_dump_uid = 0;
|
||||
int flag_config = 0;
|
||||
int unit_interval = DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT;
|
||||
int diskstats_interval = DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH;
|
||||
int emmc_interval = DEFAULT_PERIODIC_CHORES_INTERVAL_EMMC_INFO_PUBLISH;
|
||||
int uid_io_interval = DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_ALERT;
|
||||
int fd_emmc = -1;
|
||||
int opt;
|
||||
|
||||
|
@ -136,11 +127,7 @@ int main(int argc, char** argv) {
|
|||
{"kill", no_argument, 0, 'k'},
|
||||
{"dump", no_argument, 0, 'd'},
|
||||
{"uid", no_argument, 0, 'u'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"unit", required_argument, 0, 0 },
|
||||
{"diskstats", required_argument, 0, 0 },
|
||||
{"emmc", required_argument, 0, 0 },
|
||||
{"uidio", required_argument, 0, 0 }
|
||||
{"help", no_argument, 0, 'h'}
|
||||
};
|
||||
opt = getopt_long(argc, argv, ":skdhu0", long_options, &opt_idx);
|
||||
if (opt == -1) {
|
||||
|
@ -148,53 +135,6 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
switch (opt) {
|
||||
case 0:
|
||||
printf("option %s", long_options[opt_idx].name);
|
||||
if (optarg) {
|
||||
printf(" with arg %s", optarg);
|
||||
if (strcmp(long_options[opt_idx].name, "unit") == 0) {
|
||||
unit_interval = atoi(optarg);
|
||||
if (unit_interval == 0) {
|
||||
fprintf(stderr, "Invalid argument. Option %s requires an integer argument greater than 0.\n",
|
||||
long_options[opt_idx].name);
|
||||
help_message();
|
||||
return -1;
|
||||
}
|
||||
} else if (strcmp(long_options[opt_idx].name, "diskstats") == 0) {
|
||||
diskstats_interval = atoi(optarg) * HOUR_TO_SEC;
|
||||
if (diskstats_interval == 0) {
|
||||
fprintf(stderr, "Invalid argument. Option %s requires an integer argument greater than 0.\n",
|
||||
long_options[opt_idx].name);
|
||||
help_message();
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else if (strcmp(long_options[opt_idx].name, "emmc") == 0) {
|
||||
emmc_interval = atoi(optarg) * DAY_TO_SEC;
|
||||
if (emmc_interval == 0) {
|
||||
fprintf(stderr, "Invalid argument. Option %s requires an integer argument greater than 0.\n",
|
||||
long_options[opt_idx].name);
|
||||
help_message();
|
||||
return -1;
|
||||
}
|
||||
} else if (strcmp(long_options[opt_idx].name, "uidio") == 0) {
|
||||
uid_io_interval = atoi(optarg) * HOUR_TO_SEC;
|
||||
if (uid_io_interval == 0) {
|
||||
fprintf(stderr, "Invalid argument. Option %s requires an integer argument greater than 0.\n",
|
||||
long_options[opt_idx].name);
|
||||
help_message();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
flag_config = 1;
|
||||
} else {
|
||||
fprintf(stderr, "Invalid argument. Option %s requires an argument.\n",
|
||||
long_options[opt_idx].name);
|
||||
help_message();
|
||||
return -1;
|
||||
}
|
||||
printf("\n");
|
||||
break;
|
||||
case 's':
|
||||
flag_main_service = 1;
|
||||
break;
|
||||
|
@ -225,12 +165,6 @@ int main(int argc, char** argv) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (flag_config && flag_dump_task) {
|
||||
fprintf(stderr, "Invalid arguments. Cannot set configs in \'dump\' option.\n");
|
||||
help_message();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flag_main_service) { // start main thread
|
||||
static const char mmc0_ext_csd[] = "/d/mmc0/mmc0:0001/ext_csd";
|
||||
fd_emmc = android_get_control_file(mmc0_ext_csd);
|
||||
|
@ -243,13 +177,6 @@ int main(int argc, char** argv) {
|
|||
|
||||
storaged.set_privileged_fds(fd_emmc);
|
||||
|
||||
if (flag_config) {
|
||||
storaged.set_unit_interval(unit_interval);
|
||||
storaged.set_diskstats_interval(diskstats_interval);
|
||||
storaged.set_emmc_interval(emmc_interval);
|
||||
storaged.set_uid_io_interval(uid_io_interval);
|
||||
}
|
||||
|
||||
// Start the main thread of storaged
|
||||
pthread_t storaged_main_thread;
|
||||
errno = pthread_create(&storaged_main_thread, NULL, storaged_main, &storaged);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <cutils/properties.h>
|
||||
|
||||
#include <storaged.h>
|
||||
#include <storaged_utils.h>
|
||||
|
@ -176,10 +177,21 @@ storaged_t::storaged_t(void) {
|
|||
|
||||
mConfig.proc_uid_io_available = (access(UID_IO_STATS_PATH, R_OK) == 0);
|
||||
|
||||
mConfig.periodic_chores_interval_unit = DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT;
|
||||
mConfig.periodic_chores_interval_disk_stats_publish = DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH;
|
||||
mConfig.periodic_chores_interval_emmc_info_publish = DEFAULT_PERIODIC_CHORES_INTERVAL_EMMC_INFO_PUBLISH;
|
||||
mUidm.set_periodic_chores_interval(DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO_ALERT);
|
||||
mConfig.periodic_chores_interval_unit =
|
||||
property_get_int32("ro.storaged.event.interval", DEFAULT_PERIODIC_CHORES_INTERVAL_UNIT);
|
||||
|
||||
mConfig.event_time_check_usec =
|
||||
property_get_int32("ro.storaged.event.perf_check", 0);
|
||||
|
||||
mConfig.periodic_chores_interval_disk_stats_publish =
|
||||
property_get_int32("ro.storaged.disk_stats_pub", DEFAULT_PERIODIC_CHORES_INTERVAL_DISK_STATS_PUBLISH);
|
||||
|
||||
mConfig.periodic_chores_interval_emmc_info_publish =
|
||||
property_get_int32("ro.storaged.emmc_info_pub", DEFAULT_PERIODIC_CHORES_INTERVAL_EMMC_INFO_PUBLISH);
|
||||
|
||||
mUidm.set_periodic_chores_params(
|
||||
property_get_int32("ro.storaged.uid_io.interval", DEFAULT_PERIODIC_CHORES_INTERVAL_UID_IO),
|
||||
property_get_int32("ro.storaged.uid_io.threshold", DEFAULT_PERIODIC_CHORES_UID_IO_THRESHOLD));
|
||||
|
||||
mStarttime = time(NULL);
|
||||
}
|
||||
|
@ -212,3 +224,30 @@ void storaged_t::event(void) {
|
|||
|
||||
mTimer += mConfig.periodic_chores_interval_unit;
|
||||
}
|
||||
|
||||
void storaged_t::event_checked(void) {
|
||||
struct timespec start_ts, end_ts;
|
||||
bool check_time = true;
|
||||
|
||||
if (mConfig.event_time_check_usec &&
|
||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_ts) < 0) {
|
||||
check_time = false;
|
||||
PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed";
|
||||
}
|
||||
|
||||
event();
|
||||
|
||||
if (mConfig.event_time_check_usec) {
|
||||
if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_ts) < 0) {
|
||||
PLOG_TO(SYSTEM, ERROR) << "clock_gettime() failed";
|
||||
return;
|
||||
}
|
||||
int64_t cost = (end_ts.tv_sec - start_ts.tv_sec) * SEC_TO_USEC +
|
||||
(end_ts.tv_nsec - start_ts.tv_nsec) / USEC_TO_NSEC;
|
||||
if (cost > mConfig.event_time_check_usec) {
|
||||
LOG_TO(SYSTEM, ERROR)
|
||||
<< "event loop spent " << cost << " usec, threshold "
|
||||
<< mConfig.event_time_check_usec << " usec";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
#include "storaged.h"
|
||||
#include "storaged_uid_monitor.h"
|
||||
|
||||
static const uint64_t io_alert_threshold = 1024 * 1024 * 1024; // 1GB
|
||||
|
||||
using namespace android;
|
||||
using namespace android::base;
|
||||
|
||||
|
@ -116,7 +114,7 @@ void uid_monitor::report()
|
|||
|
||||
uint64_t curr_ts = ts.tv_sec * NS_PER_SEC + ts.tv_nsec;
|
||||
uint64_t ts_delta = curr_ts - last_report_ts;
|
||||
uint64_t adjusted_threshold = io_alert_threshold * ((double)ts_delta / interval / NS_PER_SEC);
|
||||
uint64_t adjusted_threshold = threshold * ((double)ts_delta / interval / NS_PER_SEC);
|
||||
|
||||
std::unordered_map<uint32_t, struct uid_info> uids = get_uids();
|
||||
if (uids.empty()) {
|
||||
|
|
|
@ -41,11 +41,6 @@
|
|||
#include <storaged.h>
|
||||
#include <storaged_utils.h>
|
||||
|
||||
#define SECTOR_SIZE ( 512 )
|
||||
#define SEC_TO_MSEC ( 1000 )
|
||||
#define MSEC_TO_USEC ( 1000 )
|
||||
#define USEC_TO_NSEC ( 1000 )
|
||||
|
||||
bool parse_disk_stats(const char* disk_stats_path, struct disk_stats* stats) {
|
||||
// Get time
|
||||
struct timespec ts;
|
||||
|
|
Loading…
Reference in a new issue