~siborgium/prelockdpp

3dde0a0d506d4f55709d080896c614af4b56d668 — Sergey Smirnykh 2 years ago a3c48ca
get_current_set v1
1 files changed, 86 insertions(+), 10 deletions(-)

M main.cpp
M main.cpp => main.cpp +86 -10
@@ 7,6 7,7 @@
#include <filesystem>
#include <vector>

#include <cassert>
#include <cstring>

#include <dirent.h>


@@ 69,6 70,7 @@ struct process_lookup_error: public std::runtime_error {
struct config {
    fs::path dump_path{ "/var/lib/prelockdpp/dump.json" };
    time_t   interval_sec{ 5 };
    bool     lock_only_critical{ 0 };
};

struct sc_info {


@@ 135,6 137,7 @@ struct context {
    config&                               cfg;

    std::vector<int>                      pids;
    std::string                           stat_buffer;

    context(config& cfg): cfg{ cfg } {
        start_time = std::chrono::steady_clock::now();


@@ 160,6 163,13 @@ struct context {
            throw std::runtime_error{ concat("mlockall failed ", errno_) };
        }
    }
    auto get_clock_time(clockid_t id) {
        timespec t;
        if (clock_gettime(id, &t)) {
            throw errno_exception("ctx.get_clock_time failed", errno);
        }
        return t;
    }
    auto get_uptime() {
        int fd = open("/proc/uptime", O_RDONLY);
        if (fd == -1) {


@@ 231,9 241,28 @@ struct context {
        }
        return pids;
    }
    auto get_uniq_id(int pid) {
    void format_path_buf(auto & buf) {

    }
    auto get_uniq_id(const char* stat_path) {
        using namespace std::string_view_literals;
        try {
            throw std::runtime_error{ "Unimplemented" };
            // TODO: can we do reading stat cheaper?
            std::ifstream stat{ stat_path };
            std::getline(stat, stat_buffer);

            std::string_view stat_view{ stat_buffer };
            if (stat_view.ends_with(" 0 0 0")) {
                // ignore kthreads
                return 0;
            }
            auto lparen_idx = stat_view.find('(');
            auto rparen_idx = stat_view.rfind(')');
            assert(lparen_idx != stat_view.npos && rparen_idx != stat_view.npos);
            auto comm = stat_view.substr(lparen_idx + 1, rparen_idx - lparen_idx - 1);
            std::cout << comm;

            return 0;
        } catch (const file_not_found_error&) {
            return -1;
        } catch (const process_lookup_error&) {


@@ 241,17 270,63 @@ struct context {
        }
    }
    auto get_current_set() {
        timespec m0, p0;
        if (clock_gettime(CLOCK_MONOTONIC, &m0)) {
            throw errno_exception("clock_gettime(MONOTONIC) failed", errno);
        using namespace std::string_view_literals;

        auto m0 = get_clock_time(CLOCK_MONOTONIC);
        auto p0 = get_clock_time(CLOCK_PROCESS_CPUTIME_ID);
        auto uptime = get_uptime();

        // FIXME: move to separate function
        constexpr auto proc_path = "/proc/"sv;
        constexpr auto stat_path = "/stat"sv;

        constexpr auto buf_size
        = proc_path.size()
        + std::numeric_limits<int>::digits10
        + stat_path.size()
        + 2;

        char path_buf[buf_size];
        auto const pid_begin = std::copy(
            proc_path.begin(),
            proc_path.end(),
            std::begin(path_buf)
        );


        DIR* proc_dir = opendir("/proc");
        if (!proc_dir) {
            throw errno_exception("opendir(/proc) failed", errno);
        }
        if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &p0)) {
            throw errno_exception("clock_gettime(PROCESS_CPUTIME) failed", errno);
        DEFER{ closedir(proc_dir); };
        errno = 0;
        while (dirent* entry = readdir(proc_dir)) {
            DEFER{ errno = 0; };

            if (entry->d_type != DT_DIR) {
                continue;
            }
            auto name_end = entry->d_name + strlen(entry->d_name);
            int pid;
            auto [p, ec] = std::from_chars(entry->d_name, name_end, pid);
            if (ec != std::errc() || p != name_end) {
                continue;
            }

            auto const pid_end = std::copy(entry->d_name, name_end, pid_begin);
            auto end = std::copy(stat_path.begin(), stat_path.end(), pid_end);
            assert(end < std::end(path_buf));
            *end = '\0';
            ++end;

            std::cout << pid << ' ';
            get_uniq_id(path_buf);
            std::cout << '\n';
        }
        auto uptime = get_uptime();
        for (auto&& pid: get_pid_list()) {
            std::cout << pid << '\n';
        if (errno) {
            throw errno_exception("readdir(proc) failed", errno);
        }

        std::cout << "Uptime: " << uptime.tv_sec << '.' << uptime.tv_nsec << '\n';

    }


@@ 259,6 334,7 @@ struct context {

struct lock_context {
    int         epoll_fd;
    // FIXME: should we keep it?
    epoll_event timer_event = { 0 };
    epoll_event signal_event = { 0 };