Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3790f5bf authored by Jin Qian's avatar Jin Qian
Browse files

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
parent bcd6e3b9
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
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
+12 −13
Original line number Diff line number Diff line
@@ -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
+3 −2
Original line number Diff line number Diff line
@@ -47,10 +47,11 @@ 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 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();
+2 −75
Original line number Diff line number Diff line
@@ -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);
+43 −4
Original line number Diff line number Diff line
@@ -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";
        }
    }
}
Loading