diff options
author | Konrad Kuchciak <k.kuchciak@samsung.com> | 2019-02-15 08:49:30 +0100 |
---|---|---|
committer | Konrad Kuchciak <k.kuchciak@samsung.com> | 2019-02-15 08:49:30 +0100 |
commit | 64ab7b95b77e01ad60963580cf61d9d81a434fa9 (patch) | |
tree | f5a0bbe315f346f6ef61a292a569e20f99158835 | |
parent | 31cc2c879e8862007334b7dae0216801d75d57af (diff) | |
download | faultd-sandbox/kuchciak/cpu_listener.tar.gz faultd-sandbox/kuchciak/cpu_listener.tar.bz2 faultd-sandbox/kuchciak/cpu_listener.zip |
Add PoC CPU listenersandbox/kuchciak/cpu_listener
Change-Id: I391ce7ff0c27baa178dc60be9af07b4d96436500
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | packaging/faultd.spec | 1 | ||||
-rw-r--r-- | src/listeners/cpu.c | 163 |
3 files changed, 167 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index 3530c11..41a151d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -122,6 +122,7 @@ EXTRA_faultd_SOURCES = \ src/listeners/audit.c \ src/listeners/systemd.c \ src/listeners/startup.c \ + src/listeners/cpu.c \ src/database/sqlite.c \ src/decision_makers/vip_fault_dm.c \ src/decision_makers/rv_dm.c \ @@ -139,6 +140,7 @@ modulesdir = $(pkglibdir)/available-modules modules_LTLIBRARIES = audit_listener.la \ systemd_listener.la \ startup_listener.la \ + cpu_listener.la \ sqlite_dbadapter.la \ vip_fault_eh.la \ resource_violation_eh.la \ @@ -153,6 +155,7 @@ audit_listener_la_SOURCES = src/listeners/audit.c audit_listener_la_LIBADD = $(AUDIT_LIBS) systemd_listener_la_SOURCES = src/listeners/systemd.c startup_listener_la_SOURCES = src/listeners/startup.c +cpu_listener_la_SOURCES = src/listeners/cpu.c sqlite_dbadapter_la_SOURCES = src/database/sqlite.c sqlite_dbadapter_la_LIBADD = $(SQLITE3_LIBS) vip_fault_eh_la_SOURCES = src/decision_makers/vip_fault_dm.c diff --git a/packaging/faultd.spec b/packaging/faultd.spec index 60de114..41331d9 100644 --- a/packaging/faultd.spec +++ b/packaging/faultd.spec @@ -68,6 +68,7 @@ ln -s %{_sbindir}/faultd %{buildroot}/%{_sbindir}/faultctl %define enabled_moduledir %{_sysconfdir}/faultd/enabled-modules/ for mod in systemd_listener \ + cpu_listener \ vip_fault_eh \ system_reboot_action do diff --git a/src/listeners/cpu.c b/src/listeners/cpu.c new file mode 100644 index 0000000..8fae75f --- /dev/null +++ b/src/listeners/cpu.c @@ -0,0 +1,163 @@ +/* + * This file is part of faultd. + * + * Copyright © 2019 Samsung Electronics + * + * 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. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <systemd/sd-event.h> +#include <time.h> + +#include "log.h" +#include "module.h" +#include "event.h" +#include "event_processor.h" + +struct cpu_listener { + struct faultd_module module; + uint64_t timeout_us; + uint64_t cpu_total; + uint64_t cpu_idle; + sd_event_source *event_source; +}; + +#define to_cpu_listener(MOD) \ + container_of(MOD, struct cpu_listener, module) + +static uint64_t time_now() { + struct timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + return ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000ULL; +} + +static int get_cpu_data(uint64_t *total, uint64_t *idle) { + uint64_t cpu_time[10]; + uint64_t total_time = 0; + + FILE *fp = fopen("/proc/stat", "r"); + + fseek(fp, 4, 0); + for (int i=0; i < 10; i++) { + fscanf(fp, "%lu", &cpu_time[i]); + total_time += cpu_time[i]; + } + + fclose(fp); + + *total = total_time; + *idle = cpu_time[3]; + + return 0; +} + +static int timer_handler(sd_event_source *s, uint64_t usec, void *userdata) +{ + struct faultd_module *module = userdata; + struct cpu_listener *clistener = to_cpu_listener(module); + uint64_t total, idle; + int d_total, d_idle; + float cpu_load; + int ret; + + get_cpu_data(&total, &idle); + + d_total = total - clistener->cpu_total; + d_idle = idle - clistener->cpu_idle; + + cpu_load = (1. - ((float)d_idle / (float)d_total)) * 100.; + + /* TODO: Generate event */ + log_info("Current CPU load: %f", cpu_load); + + clistener->cpu_total = total; + clistener->cpu_idle = idle; + + /* Schedule next timer iteration */ + ret = sd_event_source_set_time(s, time_now() + clistener->timeout_us); + if (ret < 0) { + log_error("Unable to set time of the event source %d", ret); + return ret; + } + + ret = sd_event_source_set_enabled(s, SD_EVENT_ON); + if (ret < 0) { + log_error("Unable to reenable timer %d", ret); + return ret; + } + + return 0; +} + +static int cpu_listener_init(struct faultd_module *module, + struct faultd_config *config, + sd_event *event) +{ + struct cpu_listener *clistener = to_cpu_listener(module); + sd_event_source *event_source; + int ret; + + /* TODO: Get timeout from config */ + + get_cpu_data(&clistener->cpu_total, &clistener->cpu_idle); + + ret = sd_event_add_time(event, &event_source, + CLOCK_MONOTONIC, time_now() + clistener->timeout_us, 0, + timer_handler, module); + if (ret < 0) { + log_error_errno(ret, "Could not add time: %m"); + goto cleanup; + } + + clistener->event_source = event_source; + + return 0; + +cleanup: + sd_event_source_unref(event_source); + + return ret; +} + +static void cpu_listener_cleanup(struct faultd_module *module) +{ + struct cpu_listener *clistener = to_cpu_listener(module); + sd_event_source *event_source = clistener->event_source; + int ret; + + ret = sd_event_source_set_enabled(event_source, SD_EVENT_OFF); + if (ret < 0) + log_error("Unable to disable timer event source %d", ret); + + sd_event_source_unref(event_source); +} + +struct cpu_listener cpu_listener = { + .module = { + .name = "cpu_listener", + .type = FAULTD_MODULE_TYPE_LISTENER, + + .init = cpu_listener_init, + .cleanup = cpu_listener_cleanup, + .node = LIST_HEAD_INIT(cpu_listener.module.node), + }, + .timeout_us = 1000000, + .cpu_total = 0, + .cpu_idle = 0, +}; + +FAULTD_MODULE_REGISTER(&cpu_listener.module)
\ No newline at end of file |