summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonrad Kuchciak <k.kuchciak@samsung.com>2019-02-15 08:49:30 +0100
committerKonrad Kuchciak <k.kuchciak@samsung.com>2019-02-15 08:49:30 +0100
commit64ab7b95b77e01ad60963580cf61d9d81a434fa9 (patch)
treef5a0bbe315f346f6ef61a292a569e20f99158835
parent31cc2c879e8862007334b7dae0216801d75d57af (diff)
downloadfaultd-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.am3
-rw-r--r--packaging/faultd.spec1
-rw-r--r--src/listeners/cpu.c163
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