mirror of
https://dev.iopsys.eu/system/sysmngr.git
synced 2025-12-10 08:14:38 +01:00
Added support for DeviceInfo.ProcessStatus.CPU. Object
This commit is contained in:
parent
ac570cb938
commit
ff129f75b9
6 changed files with 641 additions and 62 deletions
49
src/memory.c
49
src/memory.c
|
|
@ -120,47 +120,6 @@ static void send_memory_critical_state_event(unsigned int mem_utilization)
|
||||||
blob_buf_free(&bb);
|
blob_buf_free(&bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generate_log_file(time_t log_time, bool critical_state)
|
|
||||||
{
|
|
||||||
FILE *log_file = fopen(g_memory_ctx.log_file, "w"); // Write mode, clears log each time
|
|
||||||
if (log_file == NULL) {
|
|
||||||
BBF_ERR("Failed to open log file at '%s'", g_memory_ctx.log_file);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(log_file, "=== Memory Critical State %s at %s ===\n",
|
|
||||||
critical_state ? "Reached" : "no longer present", ctime(&log_time));
|
|
||||||
|
|
||||||
const char *commands[] = {
|
|
||||||
"top -b -n 1", // Shows a snapshot of top output, including CPU and memory stats
|
|
||||||
"free", // Shows memory usage statistics in a human-readable format
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; commands[i] != NULL; i++) {
|
|
||||||
FILE *cmd_output = popen(commands[i], "r"); // flawfinder: ignore
|
|
||||||
if (cmd_output == NULL) {
|
|
||||||
fprintf(log_file, "Failed to execute command: %s\n", commands[i]);
|
|
||||||
BBF_ERR("Failed to execute system command: %s", commands[i]);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(log_file, "\nOutput of command: %s\n", commands[i]);
|
|
||||||
char buffer[256];
|
|
||||||
while (fgets(buffer, sizeof(buffer), cmd_output) != NULL) {
|
|
||||||
fprintf(log_file, "%s", buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
pclose(cmd_output);
|
|
||||||
fprintf(log_file, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(log_file, "=== End of Critical Memory Log ===\n\n");
|
|
||||||
fclose(log_file);
|
|
||||||
|
|
||||||
BBF_DEBUG("Generated memory log file at: '%s'", g_memory_ctx.log_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void run_memory_monitor(void)
|
static void run_memory_monitor(void)
|
||||||
{
|
{
|
||||||
unsigned int mem_utilization = calculate_memory_utilization();
|
unsigned int mem_utilization = calculate_memory_utilization();
|
||||||
|
|
@ -169,7 +128,7 @@ static void run_memory_monitor(void)
|
||||||
if ((mem_utilization > g_memory_ctx.critical_rise_threshold) &&
|
if ((mem_utilization > g_memory_ctx.critical_rise_threshold) &&
|
||||||
(g_memory_ctx.critical_fall_time >= g_memory_ctx.critical_rise_time)) {
|
(g_memory_ctx.critical_fall_time >= g_memory_ctx.critical_rise_time)) {
|
||||||
|
|
||||||
BBF_INFO("Memory utilization reached critical threshold: %u%%", mem_utilization);
|
BBF_ERR("Memory utilization reached critical threshold: %u%% !!!!!!!!", mem_utilization);
|
||||||
|
|
||||||
// Update CriticalRiseTimeStamp to the current time
|
// Update CriticalRiseTimeStamp to the current time
|
||||||
g_memory_ctx.critical_rise_time = time(NULL);
|
g_memory_ctx.critical_rise_time = time(NULL);
|
||||||
|
|
@ -178,7 +137,7 @@ static void run_memory_monitor(void)
|
||||||
|
|
||||||
if (g_memory_ctx.enable_critical_log) {
|
if (g_memory_ctx.enable_critical_log) {
|
||||||
// Generate log into the vendor log file referenced by 'VendorLogFileRef' parameter indicating critical condition is reached
|
// Generate log into the vendor log file referenced by 'VendorLogFileRef' parameter indicating critical condition is reached
|
||||||
generate_log_file(g_memory_ctx.critical_rise_time, true);
|
sysmngr_generate_critical_log_file(g_memory_ctx.log_file, "Memory", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send 'MemoryCriticalState!' event
|
// Send 'MemoryCriticalState!' event
|
||||||
|
|
@ -188,7 +147,7 @@ static void run_memory_monitor(void)
|
||||||
if ((mem_utilization < g_memory_ctx.critical_fall_threshold) &&
|
if ((mem_utilization < g_memory_ctx.critical_fall_threshold) &&
|
||||||
(g_memory_ctx.critical_rise_time > g_memory_ctx.critical_fall_time)) {
|
(g_memory_ctx.critical_rise_time > g_memory_ctx.critical_fall_time)) {
|
||||||
|
|
||||||
BBF_INFO("Memory utilization has fallen below critical threshold: %u%%", mem_utilization);
|
BBF_ERR("Memory utilization has fallen below critical threshold: %u%% !!!!!!!!", mem_utilization);
|
||||||
|
|
||||||
// Update CriticalFallTimeStamp to the current time
|
// Update CriticalFallTimeStamp to the current time
|
||||||
g_memory_ctx.critical_fall_time = time(NULL);
|
g_memory_ctx.critical_fall_time = time(NULL);
|
||||||
|
|
@ -197,7 +156,7 @@ static void run_memory_monitor(void)
|
||||||
|
|
||||||
if (g_memory_ctx.enable_critical_log) {
|
if (g_memory_ctx.enable_critical_log) {
|
||||||
// Generate log into the vendor log file referenced by 'VendorLogFileRef' parameter indicating that the critical condition is no longer present
|
// Generate log into the vendor log file referenced by 'VendorLogFileRef' parameter indicating that the critical condition is no longer present
|
||||||
generate_log_file(g_memory_ctx.critical_fall_time, false);
|
sysmngr_generate_critical_log_file(g_memory_ctx.log_file, "Memory", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
605
src/processes.c
605
src/processes.c
|
|
@ -12,6 +12,13 @@
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "processes.h"
|
#include "processes.h"
|
||||||
|
|
||||||
|
#define DEFAULT_CPU_NAME "cpu"
|
||||||
|
#define DEFAULT_CPU_POLL_INTERVAL "5"
|
||||||
|
#define DEFAULT_CPU_NUM_SAMPLES "30"
|
||||||
|
#define DEFAULT_CPU_CRITICAL_RISE_THRESHOLD "80"
|
||||||
|
#define DEFAULT_CPU_CRITICAL_FALL_THRESHOLD "60"
|
||||||
|
#define DEFAULT_CPU_CRITICAL_LOG_PATH "/var/log/critical_cpu.log"
|
||||||
|
|
||||||
typedef struct process_entry {
|
typedef struct process_entry {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
|
||||||
|
|
@ -26,8 +33,10 @@ typedef struct process_entry {
|
||||||
typedef struct jiffy_counts_t {
|
typedef struct jiffy_counts_t {
|
||||||
unsigned long long usr, nic, sys, idle;
|
unsigned long long usr, nic, sys, idle;
|
||||||
unsigned long long iowait, irq, softirq, steal;
|
unsigned long long iowait, irq, softirq, steal;
|
||||||
unsigned long long total;
|
unsigned long long total_time;
|
||||||
unsigned long long busy;
|
unsigned long long idle_time;
|
||||||
|
unsigned long long sys_time;
|
||||||
|
unsigned long long busy_time;
|
||||||
} jiffy_counts_t;
|
} jiffy_counts_t;
|
||||||
|
|
||||||
typedef struct process_ctx {
|
typedef struct process_ctx {
|
||||||
|
|
@ -38,7 +47,28 @@ typedef struct process_ctx {
|
||||||
int process_num;
|
int process_num;
|
||||||
} process_ctx;
|
} process_ctx;
|
||||||
|
|
||||||
|
typedef struct cpu_info {
|
||||||
|
struct uloop_timeout cpu_timer;
|
||||||
|
jiffy_counts_t jiffy;
|
||||||
|
bool enable;
|
||||||
|
bool enable_critical_log;
|
||||||
|
bool full_samples_reached;
|
||||||
|
unsigned int poll_interval;
|
||||||
|
unsigned int critical_rise_threshold;
|
||||||
|
unsigned int critical_fall_threshold;
|
||||||
|
unsigned int *user_utilization_samples;
|
||||||
|
unsigned int *system_utilization_samples;
|
||||||
|
unsigned int *idle_utilization_samples;
|
||||||
|
unsigned int *utilization_samples;
|
||||||
|
unsigned int num_samples;
|
||||||
|
time_t critical_rise_time;
|
||||||
|
time_t critical_fall_time;
|
||||||
|
size_t sample_index;
|
||||||
|
char log_file[512];
|
||||||
|
} cpu_info_t;
|
||||||
|
|
||||||
static process_ctx g_process_ctx = {0};
|
static process_ctx g_process_ctx = {0};
|
||||||
|
static cpu_info_t g_cpu_info = {0};
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* COMMON FUNCTIONS
|
* COMMON FUNCTIONS
|
||||||
|
|
@ -57,10 +87,14 @@ static void get_jif_val(jiffy_counts_t *p_jif)
|
||||||
&p_jif->iowait, &p_jif->irq, &p_jif->softirq, &p_jif->steal);
|
&p_jif->iowait, &p_jif->irq, &p_jif->softirq, &p_jif->steal);
|
||||||
|
|
||||||
if (ret >= 4) {
|
if (ret >= 4) {
|
||||||
p_jif->total = p_jif->usr + p_jif->nic + p_jif->sys + p_jif->idle
|
p_jif->total_time = p_jif->usr + p_jif->nic + p_jif->sys + p_jif->idle
|
||||||
+ p_jif->iowait + p_jif->irq + p_jif->softirq + p_jif->steal;
|
+ p_jif->iowait + p_jif->irq + p_jif->softirq + p_jif->steal;
|
||||||
|
|
||||||
p_jif->busy = p_jif->total - p_jif->idle - p_jif->iowait;
|
p_jif->sys_time = p_jif->sys + p_jif->irq + p_jif->softirq;
|
||||||
|
|
||||||
|
p_jif->idle_time = p_jif->idle + p_jif->iowait;
|
||||||
|
|
||||||
|
p_jif->busy_time = p_jif->total_time - p_jif->idle_time;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -72,12 +106,12 @@ static unsigned int get_cpu_load(jiffy_counts_t *prev_jif, jiffy_counts_t *cur_j
|
||||||
{
|
{
|
||||||
unsigned total_diff, cpu;
|
unsigned total_diff, cpu;
|
||||||
|
|
||||||
total_diff = (unsigned)(cur_jif->total - prev_jif->total);
|
total_diff = (unsigned)(cur_jif->total_time - prev_jif->total_time);
|
||||||
|
|
||||||
if (total_diff == 0)
|
if (total_diff == 0)
|
||||||
total_diff = 1;
|
total_diff = 1;
|
||||||
|
|
||||||
cpu = 100 * (unsigned)(cur_jif->busy - prev_jif->busy) / total_diff;
|
cpu = 100 * (unsigned)(cur_jif->busy_time - prev_jif->busy_time) / total_diff;
|
||||||
|
|
||||||
return cpu;
|
return cpu;
|
||||||
}
|
}
|
||||||
|
|
@ -349,6 +383,200 @@ static void process_refresh_instance_timer(struct uloop_timeout *timeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void send_cpu_critical_state_event(unsigned int cpu_utilization)
|
||||||
|
{
|
||||||
|
struct blob_buf bb = {0};
|
||||||
|
char buf[32] = {0};
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%u", cpu_utilization);
|
||||||
|
|
||||||
|
memset(&bb, 0, sizeof(struct blob_buf));
|
||||||
|
blob_buf_init(&bb, 0);
|
||||||
|
|
||||||
|
blobmsg_add_string(&bb, "name", "Device.DeviceInfo.ProcessStatus.CPU.1.CPUCriticalState!");
|
||||||
|
|
||||||
|
void *arr = blobmsg_open_array(&bb, "input");
|
||||||
|
|
||||||
|
void *cpu_table = blobmsg_open_table(&bb, NULL);
|
||||||
|
blobmsg_add_string(&bb, "path", "CPUUtilization");
|
||||||
|
blobmsg_add_string(&bb, "data", buf);
|
||||||
|
blobmsg_add_string(&bb, "type", DMT_TYPE[DMT_UNINT]);
|
||||||
|
blobmsg_close_table(&bb, cpu_table);
|
||||||
|
|
||||||
|
void *name_table = blobmsg_open_table(&bb, NULL);
|
||||||
|
blobmsg_add_string(&bb, "path", "Name");
|
||||||
|
blobmsg_add_string(&bb, "data", DEFAULT_CPU_NAME);
|
||||||
|
blobmsg_add_string(&bb, "type", DMT_TYPE[DMT_STRING]);
|
||||||
|
blobmsg_close_table(&bb, name_table);
|
||||||
|
|
||||||
|
blobmsg_close_array(&bb, arr);
|
||||||
|
|
||||||
|
if (sysmngr_ubus_invoke_sync("bbfdm", "notify_event", bb.head, NULL, NULL)) {
|
||||||
|
BBF_ERR("Failed to send 'CPUCriticalState!' event");
|
||||||
|
} else {
|
||||||
|
BBF_DEBUG("'CPUCriticalState!' event sent successfully with utilization at %u%%.", cpu_utilization);
|
||||||
|
}
|
||||||
|
|
||||||
|
blob_buf_free(&bb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int calculate_average_samples(unsigned int *samples)
|
||||||
|
{
|
||||||
|
unsigned int num_samples = g_cpu_info.full_samples_reached ? g_cpu_info.num_samples : g_cpu_info.sample_index;
|
||||||
|
unsigned int sum = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < num_samples; i++) {
|
||||||
|
sum += samples[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return num_samples ? (sum / num_samples) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void run_cpu_monitor(void)
|
||||||
|
{
|
||||||
|
char buf[32] = {0};
|
||||||
|
|
||||||
|
jiffy_counts_t prev_jiffy = {
|
||||||
|
.total_time = g_cpu_info.jiffy.total_time,
|
||||||
|
.idle_time = g_cpu_info.jiffy.idle_time,
|
||||||
|
.sys_time = g_cpu_info.jiffy.sys_time,
|
||||||
|
.busy_time = g_cpu_info.jiffy.busy_time,
|
||||||
|
.usr = g_cpu_info.jiffy.usr
|
||||||
|
};
|
||||||
|
|
||||||
|
get_jif_val(&g_cpu_info.jiffy);
|
||||||
|
|
||||||
|
unsigned long long total_diff = g_cpu_info.jiffy.total_time - prev_jiffy.total_time;
|
||||||
|
|
||||||
|
if (total_diff == 0)
|
||||||
|
total_diff = 1;
|
||||||
|
|
||||||
|
g_cpu_info.user_utilization_samples[g_cpu_info.sample_index] = ((g_cpu_info.jiffy.usr - prev_jiffy.usr) * 100) / total_diff;
|
||||||
|
g_cpu_info.system_utilization_samples[g_cpu_info.sample_index] = ((g_cpu_info.jiffy.sys_time - prev_jiffy.sys_time) * 100) / total_diff;
|
||||||
|
g_cpu_info.idle_utilization_samples[g_cpu_info.sample_index] = ((g_cpu_info.jiffy.idle_time - prev_jiffy.idle_time) * 100) / total_diff;
|
||||||
|
g_cpu_info.utilization_samples[g_cpu_info.sample_index] = ((g_cpu_info.jiffy.busy_time - prev_jiffy.busy_time) * 100) / total_diff;
|
||||||
|
|
||||||
|
if (!g_cpu_info.full_samples_reached) {
|
||||||
|
g_cpu_info.full_samples_reached = ((g_cpu_info.sample_index + 1) >= g_cpu_info.num_samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_cpu_info.sample_index = (g_cpu_info.sample_index + 1) % g_cpu_info.num_samples;
|
||||||
|
|
||||||
|
unsigned int avg_utilization = calculate_average_samples(g_cpu_info.utilization_samples);
|
||||||
|
|
||||||
|
if ((avg_utilization > g_cpu_info.critical_rise_threshold) &&
|
||||||
|
(g_cpu_info.critical_fall_time >= g_cpu_info.critical_rise_time)) {
|
||||||
|
|
||||||
|
BBF_ERR("CPU utilization reached critical threshold: %u%% !!!!!!!!", avg_utilization);
|
||||||
|
|
||||||
|
// Update CriticalRiseTimeStamp to the current time
|
||||||
|
g_cpu_info.critical_rise_time = time(NULL);
|
||||||
|
snprintf(buf, sizeof(buf), "%ld", (long int)g_cpu_info.critical_rise_time);
|
||||||
|
sysmngr_uci_set("sysmngr", "cpu", "critical_rise_time", buf);
|
||||||
|
|
||||||
|
if (g_cpu_info.enable_critical_log) {
|
||||||
|
// Generate log into the vendor log file referenced by 'VendorLogFileRef' parameter indicating critical condition is reached
|
||||||
|
sysmngr_generate_critical_log_file(g_cpu_info.log_file, "CPU", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send 'CPUCriticalState!' event
|
||||||
|
send_cpu_critical_state_event(avg_utilization);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((avg_utilization < g_cpu_info.critical_fall_threshold) &&
|
||||||
|
(g_cpu_info.critical_rise_time > g_cpu_info.critical_fall_time)) {
|
||||||
|
|
||||||
|
BBF_ERR("CPU utilization has fallen below critical threshold: %u%% !!!!!!!!", avg_utilization);
|
||||||
|
|
||||||
|
// Update CriticalFallTimeStamp to the current time
|
||||||
|
g_cpu_info.critical_fall_time = time(NULL);
|
||||||
|
snprintf(buf, sizeof(buf), "%ld", (long int)g_cpu_info.critical_fall_time);
|
||||||
|
sysmngr_uci_set("sysmngr", "cpu", "critical_fall_time", buf);
|
||||||
|
|
||||||
|
if (g_cpu_info.enable_critical_log) {
|
||||||
|
// Generate log into the vendor log file referenced by 'VendorLogFileRef' parameter indicating that the critical condition is no longer present
|
||||||
|
sysmngr_generate_critical_log_file(g_cpu_info.log_file, "CPU", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BBF_INFO("Next memory monitor check scheduled in %d sec...", g_cpu_info.poll_interval);
|
||||||
|
uloop_timeout_set(&g_cpu_info.cpu_timer, g_cpu_info.poll_interval * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cpu_timer_callback(struct uloop_timeout *timeout)
|
||||||
|
{
|
||||||
|
run_cpu_monitor();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fill_global_cpu_info(void)
|
||||||
|
{
|
||||||
|
char buf[16] = {0};
|
||||||
|
|
||||||
|
memset(&g_cpu_info, 0, sizeof(struct cpu_info));
|
||||||
|
|
||||||
|
g_cpu_info.cpu_timer.cb = cpu_timer_callback;
|
||||||
|
|
||||||
|
sysmngr_uci_get("sysmngr", "cpu", "enable", "0", buf, sizeof(buf));
|
||||||
|
g_cpu_info.enable = ((int)strtol(buf, NULL, 10) != 0);
|
||||||
|
BBF_DEBUG("Memory Monitor Config: |Enable| |%d|", g_cpu_info.enable);
|
||||||
|
|
||||||
|
sysmngr_uci_get("sysmngr", "cpu", "enable_critical_log", "0", buf, sizeof(buf));
|
||||||
|
g_cpu_info.enable_critical_log = ((int)strtol(buf, NULL, 10) != 0);
|
||||||
|
BBF_DEBUG("Memory Monitor Config: |EnableCriticalLog| |%d|", g_cpu_info.enable_critical_log);
|
||||||
|
|
||||||
|
sysmngr_uci_get("sysmngr", "cpu", "poll_interval", DEFAULT_CPU_POLL_INTERVAL, buf, sizeof(buf));
|
||||||
|
g_cpu_info.poll_interval = strtoul(buf, NULL, 10);
|
||||||
|
BBF_DEBUG("Memory Monitor Config: |PollInterval| |%lu|", g_cpu_info.poll_interval);
|
||||||
|
|
||||||
|
sysmngr_uci_get("sysmngr", "cpu", "num_samples", DEFAULT_CPU_NUM_SAMPLES, buf, sizeof(buf));
|
||||||
|
g_cpu_info.num_samples = strtoul(buf, NULL, 10);
|
||||||
|
BBF_DEBUG("Memory Monitor Config: |NumSamples| |%lu|", g_cpu_info.num_samples);
|
||||||
|
|
||||||
|
sysmngr_uci_get("sysmngr", "cpu", "critical_rise_threshold", DEFAULT_CPU_CRITICAL_RISE_THRESHOLD, buf, sizeof(buf));
|
||||||
|
g_cpu_info.critical_rise_threshold = strtoul(buf, NULL, 10);
|
||||||
|
BBF_DEBUG("Memory Monitor Config: |CriticalRiseThreshold| |%lu|", g_cpu_info.critical_rise_threshold);
|
||||||
|
|
||||||
|
sysmngr_uci_get("sysmngr", "cpu", "critical_fall_threshold", DEFAULT_CPU_CRITICAL_FALL_THRESHOLD, buf, sizeof(buf));
|
||||||
|
g_cpu_info.critical_fall_threshold = strtoul(buf, NULL, 10);
|
||||||
|
BBF_DEBUG("Memory Monitor Config: |CriticalFallThreshold| |%lu|", g_cpu_info.critical_fall_threshold);
|
||||||
|
|
||||||
|
sysmngr_uci_get("sysmngr", "cpu", "critical_rise_time", "0", buf, sizeof(buf));
|
||||||
|
g_cpu_info.critical_rise_time = strtol(buf, NULL, 10);
|
||||||
|
BBF_DEBUG("Memory Monitor Config: |CriticalRiseTimeStamp| |%lu|", g_cpu_info.critical_rise_time);
|
||||||
|
|
||||||
|
sysmngr_uci_get("sysmngr", "cpu", "critical_fall_time", "0", buf, sizeof(buf));
|
||||||
|
g_cpu_info.critical_fall_time = strtol(buf, NULL, 10);
|
||||||
|
BBF_DEBUG("Memory Monitor Config: |CriticalFallTimeStamp| |%lu|", g_cpu_info.critical_fall_time);
|
||||||
|
|
||||||
|
sysmngr_uci_get("sysmngr", "cpu", "file_path", DEFAULT_CPU_CRITICAL_LOG_PATH, g_cpu_info.log_file, sizeof(g_cpu_info.log_file));
|
||||||
|
BBF_DEBUG("Memory Monitor Config: |FilePath| |%s|", g_cpu_info.log_file);
|
||||||
|
if (!file_exists(g_cpu_info.log_file)) {
|
||||||
|
// Create empty file if it doesn't exist
|
||||||
|
create_empty_file(g_cpu_info.log_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_cpu_info.utilization_samples = calloc(g_cpu_info.num_samples, sizeof(unsigned int));
|
||||||
|
g_cpu_info.user_utilization_samples = calloc(g_cpu_info.num_samples, sizeof(unsigned int));
|
||||||
|
g_cpu_info.system_utilization_samples = calloc(g_cpu_info.num_samples, sizeof(unsigned int));
|
||||||
|
g_cpu_info.idle_utilization_samples = calloc(g_cpu_info.num_samples, sizeof(unsigned int));
|
||||||
|
if (!g_cpu_info.utilization_samples || !g_cpu_info.user_utilization_samples ||
|
||||||
|
!g_cpu_info.system_utilization_samples || !g_cpu_info.idle_utilization_samples) {
|
||||||
|
BBF_ERR("Failed to allocate memory for mode utilization samples");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_jif_val(&g_cpu_info.jiffy);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_global_cpu_info(void)
|
||||||
|
{
|
||||||
|
FREE(g_cpu_info.utilization_samples);
|
||||||
|
FREE(g_cpu_info.user_utilization_samples);
|
||||||
|
FREE(g_cpu_info.system_utilization_samples);
|
||||||
|
FREE(g_cpu_info.idle_utilization_samples);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* EXTERNAL APIS
|
* EXTERNAL APIS
|
||||||
**************************************************************/
|
**************************************************************/
|
||||||
|
|
@ -369,6 +597,32 @@ void sysmngr_process_clean(struct ubus_context *ubus_ctx)
|
||||||
uloop_timeout_cancel(&g_process_ctx.instance_timer);
|
uloop_timeout_cancel(&g_process_ctx.instance_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sysmngr_cpu_init(void)
|
||||||
|
{
|
||||||
|
int res = fill_global_cpu_info();
|
||||||
|
if (res) {
|
||||||
|
BBF_ERR("Can't start CPU monitoring!!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!g_cpu_info.enable) {
|
||||||
|
BBF_INFO("CPU monitoring is disabled.");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
BBF_INFO("CPU monitoring is enabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
BBF_INFO("Next CPU monitor check scheduled in %d sec...", g_cpu_info.poll_interval);
|
||||||
|
uloop_timeout_set(&g_cpu_info.cpu_timer, g_cpu_info.poll_interval * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sysmngr_cpu_clean(void)
|
||||||
|
{
|
||||||
|
free_global_cpu_info();
|
||||||
|
uloop_timeout_cancel(&g_cpu_info.cpu_timer);
|
||||||
|
BBF_INFO("CPU monitoring process stopped");
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* ENTRY METHOD
|
* ENTRY METHOD
|
||||||
**************************************************************/
|
**************************************************************/
|
||||||
|
|
@ -397,12 +651,35 @@ static int browseProcessEntriesInst(struct dmctx *dmctx, DMNODE *parent_node, vo
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int browseDeviceInfoProcessStatusCPUInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance)
|
||||||
|
{
|
||||||
|
struct dm_data data = {0};
|
||||||
|
|
||||||
|
struct uci_section *s = is_dmmap_section_exist("dmmap_sysmngr", "cpu");
|
||||||
|
if (!s) dmuci_add_section_bbfdm("dmmap_sysmngr", "cpu", &s);
|
||||||
|
|
||||||
|
data.dmmap_section = s;
|
||||||
|
|
||||||
|
handle_instance(dmctx, parent_node, s, "cpu_instance", "cpu_alias");
|
||||||
|
DM_LINK_INST_OBJ(dmctx, parent_node, &data, "1");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
* GET & SET PARAM
|
* GET & SET PARAM
|
||||||
**************************************************************/
|
**************************************************************/
|
||||||
static int get_process_cpu_usage(char* refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
static int get_process_cpu_usage(char* refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
{
|
{
|
||||||
dmasprintf(value, "%u", get_cpu_usage());
|
char *cpu_monitor_enable = dmuci_get_option_value_fallback_def("sysmngr", "cpu", "enable", "0");
|
||||||
|
|
||||||
|
if (DM_STRCMP(cpu_monitor_enable, "1") == 0) {
|
||||||
|
dmasprintf(value, "%u", calculate_average_samples(g_cpu_info.utilization_samples));
|
||||||
|
} else {
|
||||||
|
dmasprintf(value, "%u", get_cpu_usage());
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -413,6 +690,13 @@ static int get_process_number_of_entries(char* refparam, struct dmctx *ctx, void
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatus_CPUNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
int cnt = get_number_of_entries(ctx, data, instance, browseDeviceInfoProcessStatusCPUInst);
|
||||||
|
dmasprintf(value, "%d", cnt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int get_process_pid(char* refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
static int get_process_pid(char* refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
{
|
{
|
||||||
*value = data ? ((struct process_entry *)((struct dm_data *)data)->additional_data)->pid : "";
|
*value = data ? ((struct process_entry *)((struct dm_data *)data)->additional_data)->pid : "";
|
||||||
|
|
@ -449,12 +733,287 @@ static int get_process_state(char* refparam, struct dmctx *ctx, void *data, char
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
return bbf_get_alias(ctx, ((struct dm_data *)data)->dmmap_section, "cpu_alias", instance, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_DeviceInfoProcessStatusCPU_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||||
|
{
|
||||||
|
return bbf_set_alias(ctx, ((struct dm_data *)data)->dmmap_section, "cpu_alias", instance, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_Name(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
*value = dmstrdup(DEFAULT_CPU_NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
*value = dmuci_get_option_value_fallback_def("sysmngr", "cpu", "enable", "0");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_DeviceInfoProcessStatusCPU_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||||
|
{
|
||||||
|
bool b;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case VALUECHECK:
|
||||||
|
if (bbfdm_validate_boolean(ctx, value))
|
||||||
|
return FAULT_9007;
|
||||||
|
break;
|
||||||
|
case VALUESET:
|
||||||
|
string_to_bool(value, &b);
|
||||||
|
dmuci_set_value("sysmngr", "cpu", "enable", b ? "1" : "0");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_UpTime(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
dmasprintf(value, "%d", sysmngr_get_uptime());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_UserModeUtilization(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
dmasprintf(value, "%u", calculate_average_samples(g_cpu_info.user_utilization_samples));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_SystemModeUtilization(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
dmasprintf(value, "%u", calculate_average_samples(g_cpu_info.system_utilization_samples));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_IdleModeUtilization(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
dmasprintf(value, "%u", calculate_average_samples(g_cpu_info.idle_utilization_samples));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_CPUUtilization(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
dmasprintf(value, "%u", calculate_average_samples(g_cpu_info.utilization_samples));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_PollInterval(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
*value = dmuci_get_option_value_fallback_def("sysmngr", "cpu", "poll_interval", DEFAULT_CPU_POLL_INTERVAL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_DeviceInfoProcessStatusCPU_PollInterval(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||||
|
{
|
||||||
|
switch (action) {
|
||||||
|
case VALUECHECK:
|
||||||
|
if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{NULL,NULL}}, 1))
|
||||||
|
return FAULT_9007;
|
||||||
|
break;
|
||||||
|
case VALUESET:
|
||||||
|
dmuci_set_value("sysmngr", "cpu", "poll_interval", value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_NumSamples(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
*value = dmuci_get_option_value_fallback_def("sysmngr", "cpu", "num_samples", DEFAULT_CPU_NUM_SAMPLES);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_DeviceInfoProcessStatusCPU_NumSamples(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||||
|
{
|
||||||
|
switch (action) {
|
||||||
|
case VALUECHECK:
|
||||||
|
if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{"1","300"}}, 1))
|
||||||
|
return FAULT_9007;
|
||||||
|
break;
|
||||||
|
case VALUESET:
|
||||||
|
dmuci_set_value("sysmngr", "cpu", "num_samples", value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_CriticalRiseThreshold(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
*value = dmuci_get_option_value_fallback_def("sysmngr", "cpu", "critical_rise_threshold", DEFAULT_CPU_CRITICAL_RISE_THRESHOLD);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_DeviceInfoProcessStatusCPU_CriticalRiseThreshold(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||||
|
{
|
||||||
|
switch (action) {
|
||||||
|
case VALUECHECK:
|
||||||
|
if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{NULL,"100"}}, 1))
|
||||||
|
return FAULT_9007;
|
||||||
|
break;
|
||||||
|
case VALUESET:
|
||||||
|
dmuci_set_value("sysmngr", "cpu", "critical_rise_threshold", value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_CriticalFallThreshold(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
*value = dmuci_get_option_value_fallback_def("sysmngr", "cpu", "critical_fall_threshold", DEFAULT_CPU_CRITICAL_FALL_THRESHOLD);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_DeviceInfoProcessStatusCPU_CriticalFallThreshold(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||||
|
{
|
||||||
|
switch (action) {
|
||||||
|
case VALUECHECK:
|
||||||
|
if (bbfdm_validate_unsignedInt(ctx, value, RANGE_ARGS{{NULL,"100"}}, 1))
|
||||||
|
return FAULT_9007;
|
||||||
|
break;
|
||||||
|
case VALUESET:
|
||||||
|
dmuci_set_value("sysmngr", "cpu", "critical_fall_threshold", value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_CriticalRiseTimeStamp(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
char *rise_time = NULL;
|
||||||
|
|
||||||
|
dmuci_get_option_value_string("sysmngr", "cpu", "critical_rise_time", &rise_time);
|
||||||
|
|
||||||
|
return dm_time_utc_format(DM_STRTOL(rise_time), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_CriticalFallTimeStamp(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
char *fall_time = NULL;
|
||||||
|
|
||||||
|
dmuci_get_option_value_string("sysmngr", "cpu", "critical_fall_time", &fall_time);
|
||||||
|
|
||||||
|
return dm_time_utc_format(DM_STRTOL(fall_time), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_EnableCriticalLog(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
*value = dmuci_get_option_value_fallback_def("sysmngr", "cpu", "enable_critical_log", "0");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_DeviceInfoProcessStatusCPU_EnableCriticalLog(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||||
|
{
|
||||||
|
bool b;
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case VALUECHECK:
|
||||||
|
if (bbfdm_validate_boolean(ctx, value))
|
||||||
|
return FAULT_9007;
|
||||||
|
break;
|
||||||
|
case VALUESET:
|
||||||
|
string_to_bool(value, &b);
|
||||||
|
dmuci_set_value("sysmngr", "cpu", "enable_critical_log", b ? "1" : "0");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_VendorLogFileRef(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
char *file_path = dmuci_get_option_value_fallback_def("sysmngr", "cpu", "file_path", DEFAULT_CPU_CRITICAL_LOG_PATH);
|
||||||
|
|
||||||
|
if (file_exists(file_path)) {
|
||||||
|
char file_uri[512] = {0};
|
||||||
|
|
||||||
|
// if there is a path, then prepend file:// to it to comply with bbf requirement of file URI
|
||||||
|
snprintf(file_uri, sizeof(file_uri), "file://%s", file_path);
|
||||||
|
|
||||||
|
// get the vendor file path
|
||||||
|
_bbfdm_get_references(ctx, "Device.DeviceInfo.VendorLogFile.", "Name", file_uri, value);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_DeviceInfoProcessStatusCPU_FilePath(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
*value = dmuci_get_option_value_fallback_def("sysmngr", "cpu", "file_path", DEFAULT_CPU_CRITICAL_LOG_PATH);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_DeviceInfoProcessStatusCPU_FilePath(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action)
|
||||||
|
{
|
||||||
|
char *file_path = dmuci_get_option_value_fallback_def("sysmngr", "cpu", "file_path", DEFAULT_CPU_CRITICAL_LOG_PATH);
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case VALUECHECK:
|
||||||
|
if (bbfdm_validate_string(ctx, value, -1, -1, NULL, NULL))
|
||||||
|
return FAULT_9007;
|
||||||
|
|
||||||
|
// Restriction: The path in `value` must either:
|
||||||
|
// - Start with "/var/log" for non-persistent logs, or
|
||||||
|
// - Start with "/log/" for persistent logs.
|
||||||
|
// Additionally, the path should not contain any '..' sequences
|
||||||
|
// to prevent directory traversal or invalid file paths.
|
||||||
|
if (!((strncmp(value, "/var/log", 8) == 0 || strncmp(value, "/log/", 5) == 0) && !strstr(value, ".."))) {
|
||||||
|
bbfdm_set_fault_message(ctx, "");
|
||||||
|
return FAULT_9007;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case VALUESET:
|
||||||
|
if (file_exists(file_path)) {
|
||||||
|
struct uci_section *dmmap_sec = NULL;
|
||||||
|
char file_uri[512] = {0};
|
||||||
|
|
||||||
|
if (rename(file_path, value) != 0) {
|
||||||
|
bbfdm_set_fault_message(ctx, "Can't rename file from '%s' -> '%s'", file_path, value);
|
||||||
|
return FAULT_9007;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update VendorLogFile dmmap section
|
||||||
|
snprintf(file_uri, sizeof(file_uri), "file://%s", file_path);
|
||||||
|
dmmap_sec = get_dup_section_in_dmmap_opt("dmmap", "vendorlog", "log_file", file_uri);
|
||||||
|
|
||||||
|
snprintf(file_uri, sizeof(file_uri), "file://%s", value);
|
||||||
|
dmuci_set_value_by_section(dmmap_sec, "log_file", file_uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
dmuci_set_value("sysmngr", "cpu", "file_path", value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************
|
||||||
|
* EVENTS
|
||||||
|
*************************************************************/
|
||||||
|
static event_args CPUCriticalState_event_args = {
|
||||||
|
.name = "", // This field is left empty because we are not listening to any external events, The system now operates within a single unified daemon,
|
||||||
|
// removing the need for separate event listeners. See send_cpu_critical_state_event API for details on implementation.
|
||||||
|
.param = (const char *[]) {
|
||||||
|
"CPUUtilization",
|
||||||
|
"Name",
|
||||||
|
NULL
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int get_event_CPUCriticalState(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
|
||||||
|
{
|
||||||
|
*value = (char *)&CPUCriticalState_event_args;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************************************************************************
|
/**********************************************************************************************************************************
|
||||||
* OBJ & LEAF DEFINITION
|
* OBJ & LEAF DEFINITION
|
||||||
***********************************************************************************************************************************/
|
***********************************************************************************************************************************/
|
||||||
/* *** Device.DeviceInfo.ProcessStatus.Process.{i}. *** */
|
/* *** Device.DeviceInfo.ProcessStatus.Process.{i}. *** */
|
||||||
DMLEAF tDeviceInfoProcessStatusProcessParams[] = {
|
DMLEAF tDeviceInfoProcessStatusProcessParams[] = {
|
||||||
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
|
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type */
|
||||||
{"PID", &DMREAD, DMT_UNINT, get_process_pid, NULL, BBFDM_BOTH, DM_FLAG_UNIQUE},
|
{"PID", &DMREAD, DMT_UNINT, get_process_pid, NULL, BBFDM_BOTH, DM_FLAG_UNIQUE},
|
||||||
{"Command", &DMREAD, DMT_STRING, get_process_command, NULL, BBFDM_BOTH},
|
{"Command", &DMREAD, DMT_STRING, get_process_command, NULL, BBFDM_BOTH},
|
||||||
{"Size", &DMREAD, DMT_UNINT, get_process_size, NULL, BBFDM_BOTH},
|
{"Size", &DMREAD, DMT_UNINT, get_process_size, NULL, BBFDM_BOTH},
|
||||||
|
|
@ -464,16 +1023,42 @@ DMLEAF tDeviceInfoProcessStatusProcessParams[] = {
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* *** Device.DeviceInfo.ProcessStatus.CPU.{i}. *** */
|
||||||
|
DMLEAF tDeviceInfoProcessStatusCPUParams[] = {
|
||||||
|
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type */
|
||||||
|
{"Alias", &DMWRITE, DMT_STRING, get_DeviceInfoProcessStatusCPU_Alias, set_DeviceInfoProcessStatusCPU_Alias, BBFDM_BOTH},
|
||||||
|
{"Name", &DMREAD, DMT_STRING, get_DeviceInfoProcessStatusCPU_Name, NULL, BBFDM_BOTH, DM_FLAG_UNIQUE|DM_FLAG_LINKER},
|
||||||
|
{"Enable", &DMWRITE, DMT_BOOL, get_DeviceInfoProcessStatusCPU_Enable, set_DeviceInfoProcessStatusCPU_Enable, BBFDM_BOTH},
|
||||||
|
{"UpTime", &DMREAD, DMT_UNINT, get_DeviceInfoProcessStatusCPU_UpTime, NULL, BBFDM_BOTH},
|
||||||
|
{"UserModeUtilization", &DMREAD, DMT_UNINT, get_DeviceInfoProcessStatusCPU_UserModeUtilization, NULL, BBFDM_BOTH},
|
||||||
|
{"SystemModeUtilization", &DMREAD, DMT_UNINT, get_DeviceInfoProcessStatusCPU_SystemModeUtilization, NULL, BBFDM_BOTH},
|
||||||
|
{"IdleModeUtilization", &DMREAD, DMT_UNINT, get_DeviceInfoProcessStatusCPU_IdleModeUtilization, NULL, BBFDM_BOTH},
|
||||||
|
{"CPUUtilization", &DMREAD, DMT_UNINT, get_DeviceInfoProcessStatusCPU_CPUUtilization, NULL, BBFDM_BOTH},
|
||||||
|
{"PollInterval", &DMWRITE, DMT_UNINT, get_DeviceInfoProcessStatusCPU_PollInterval, set_DeviceInfoProcessStatusCPU_PollInterval, BBFDM_BOTH},
|
||||||
|
{"NumSamples", &DMWRITE, DMT_UNINT, get_DeviceInfoProcessStatusCPU_NumSamples, set_DeviceInfoProcessStatusCPU_NumSamples, BBFDM_BOTH},
|
||||||
|
{"CriticalRiseThreshold", &DMWRITE, DMT_UNINT, get_DeviceInfoProcessStatusCPU_CriticalRiseThreshold, set_DeviceInfoProcessStatusCPU_CriticalRiseThreshold, BBFDM_BOTH},
|
||||||
|
{"CriticalFallThreshold", &DMWRITE, DMT_UNINT, get_DeviceInfoProcessStatusCPU_CriticalFallThreshold, set_DeviceInfoProcessStatusCPU_CriticalFallThreshold, BBFDM_BOTH},
|
||||||
|
{"CriticalRiseTimeStamp", &DMREAD, DMT_TIME, get_DeviceInfoProcessStatusCPU_CriticalRiseTimeStamp, NULL, BBFDM_BOTH},
|
||||||
|
{"CriticalFallTimeStamp", &DMREAD, DMT_TIME, get_DeviceInfoProcessStatusCPU_CriticalFallTimeStamp, NULL, BBFDM_BOTH},
|
||||||
|
{"EnableCriticalLog", &DMWRITE, DMT_BOOL, get_DeviceInfoProcessStatusCPU_EnableCriticalLog, set_DeviceInfoProcessStatusCPU_EnableCriticalLog, BBFDM_BOTH},
|
||||||
|
{"VendorLogFileRef", &DMREAD, DMT_STRING, get_DeviceInfoProcessStatusCPU_VendorLogFileRef, NULL, BBFDM_BOTH},
|
||||||
|
{"FilePath", &DMWRITE, DMT_STRING, get_DeviceInfoProcessStatusCPU_FilePath, set_DeviceInfoProcessStatusCPU_FilePath, BBFDM_BOTH},
|
||||||
|
{"CPUCriticalState!", &DMREAD, DMT_EVENT, get_event_CPUCriticalState, NULL, BBFDM_USP},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
/* *** Device.DeviceInfo.ProcessStatus. *** */
|
/* *** Device.DeviceInfo.ProcessStatus. *** */
|
||||||
DMOBJ tDeviceInfoProcessStatusObj[] = {
|
DMOBJ tDeviceInfoProcessStatusObj[] = {
|
||||||
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys, version*/
|
/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys */
|
||||||
{"Process", &DMREAD, NULL, NULL, NULL, browseProcessEntriesInst, NULL, NULL, NULL, tDeviceInfoProcessStatusProcessParams, NULL, BBFDM_BOTH, NULL},
|
{"Process", &DMREAD, NULL, NULL, NULL, browseProcessEntriesInst, NULL, NULL, NULL, tDeviceInfoProcessStatusProcessParams, NULL, BBFDM_BOTH, NULL},
|
||||||
|
{"CPU", &DMREAD, NULL, NULL, NULL, browseDeviceInfoProcessStatusCPUInst, NULL, NULL, NULL, tDeviceInfoProcessStatusCPUParams, NULL, BBFDM_BOTH, NULL},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
DMLEAF tDeviceInfoProcessStatusParams[] = {
|
DMLEAF tDeviceInfoProcessStatusParams[] = {
|
||||||
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type, version*/
|
/* PARAM, permission, type, getvalue, setvalue, bbfdm_type */
|
||||||
{"CPUUsage", &DMREAD, DMT_UNINT, get_process_cpu_usage, NULL, BBFDM_BOTH},
|
{"CPUUsage", &DMREAD, DMT_UNINT, get_process_cpu_usage, NULL, BBFDM_BOTH},
|
||||||
{"ProcessNumberOfEntries", &DMREAD, DMT_UNINT, get_process_number_of_entries, NULL, BBFDM_BOTH},
|
{"ProcessNumberOfEntries", &DMREAD, DMT_UNINT, get_process_number_of_entries, NULL, BBFDM_BOTH},
|
||||||
|
{"CPUNumberOfEntries", &DMREAD, DMT_UNINT, get_DeviceInfoProcessStatus_CPUNumberOfEntries, NULL, BBFDM_BOTH},
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -17,5 +17,7 @@ extern DMLEAF tDeviceInfoProcessStatusParams[];
|
||||||
|
|
||||||
void sysmngr_process_init(struct ubus_context *ubus_ctx);
|
void sysmngr_process_init(struct ubus_context *ubus_ctx);
|
||||||
void sysmngr_process_clean(struct ubus_context *ubus_ctx);
|
void sysmngr_process_clean(struct ubus_context *ubus_ctx);
|
||||||
|
void sysmngr_cpu_init(void);
|
||||||
|
void sysmngr_cpu_clean(void);
|
||||||
|
|
||||||
#endif //__PROCESSES_H
|
#endif //__PROCESSES_H
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
#include "reboots.h"
|
#include "reboots.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SYSMNGR_REBOOTS
|
#ifdef SYSMNGR_PROCESS_STATUS
|
||||||
#include "processes.h"
|
#include "processes.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -28,6 +28,8 @@
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define DEFAULT_LOG_LEVEL LOG_INFO
|
||||||
|
|
||||||
extern DM_MAP_OBJ tDynamicObj[];
|
extern DM_MAP_OBJ tDynamicObj[];
|
||||||
|
|
||||||
static void usage(char *prog)
|
static void usage(char *prog)
|
||||||
|
|
@ -35,7 +37,7 @@ static void usage(char *prog)
|
||||||
fprintf(stderr, "Usage: %s [options]\n", prog);
|
fprintf(stderr, "Usage: %s [options]\n", prog);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "options:\n");
|
fprintf(stderr, "options:\n");
|
||||||
fprintf(stderr, " -d Use multiple time to get more verbose debug logs (Debug: -dddd)\n");
|
fprintf(stderr, " -l <0-7> Set the loglevel\n");
|
||||||
fprintf(stderr, " -h Displays this help\n");
|
fprintf(stderr, " -h Displays this help\n");
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
@ -43,7 +45,12 @@ static void usage(char *prog)
|
||||||
static void config_reload_cb(struct ubus_context *ctx, struct ubus_event_handler *ev,
|
static void config_reload_cb(struct ubus_context *ctx, struct ubus_event_handler *ev,
|
||||||
const char *type, struct blob_attr *msg)
|
const char *type, struct blob_attr *msg)
|
||||||
{
|
{
|
||||||
BBF_ERR("Reloading sysmngr upon 'sysmngr.reload' event");
|
BBF_INFO("Reloading sysmngr upon 'sysmngr.reload' event");
|
||||||
|
|
||||||
|
#ifdef SYSMNGR_PROCESS_STATUS
|
||||||
|
sysmngr_cpu_clean();
|
||||||
|
sysmngr_cpu_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SYSMNGR_MEMORY_STATUS
|
#ifdef SYSMNGR_MEMORY_STATUS
|
||||||
sysmngr_memory_clean();
|
sysmngr_memory_clean();
|
||||||
|
|
@ -58,13 +65,16 @@ int main(int argc, char **argv)
|
||||||
struct ubus_event_handler ev = {
|
struct ubus_event_handler ev = {
|
||||||
.cb = config_reload_cb,
|
.cb = config_reload_cb,
|
||||||
};
|
};
|
||||||
int log_level = LOG_ERR;
|
int log_level = DEFAULT_LOG_LEVEL;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "dh")) != -1) {
|
while ((c = getopt(argc, argv, "hl:")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'd':
|
case 'l':
|
||||||
log_level += 1;
|
log_level = (int)strtod(optarg, NULL);
|
||||||
|
if (log_level < 0 || log_level > 7) {
|
||||||
|
log_level = DEFAULT_LOG_LEVEL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
usage(argv[0]);
|
usage(argv[0]);
|
||||||
|
|
@ -89,6 +99,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
#ifdef SYSMNGR_PROCESS_STATUS
|
#ifdef SYSMNGR_PROCESS_STATUS
|
||||||
sysmngr_process_init(&bbfdm_ctx.ubus_ctx);
|
sysmngr_process_init(&bbfdm_ctx.ubus_ctx);
|
||||||
|
sysmngr_cpu_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SYSMNGR_MEMORY_STATUS
|
#ifdef SYSMNGR_MEMORY_STATUS
|
||||||
|
|
@ -108,6 +119,7 @@ out:
|
||||||
|
|
||||||
#ifdef SYSMNGR_PROCESS_STATUS
|
#ifdef SYSMNGR_PROCESS_STATUS
|
||||||
sysmngr_process_clean(&bbfdm_ctx.ubus_ctx);
|
sysmngr_process_clean(&bbfdm_ctx.ubus_ctx);
|
||||||
|
sysmngr_cpu_clean();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SYSMNGR_MEMORY_STATUS
|
#ifdef SYSMNGR_MEMORY_STATUS
|
||||||
|
|
|
||||||
19
src/utils.c
19
src/utils.c
|
|
@ -14,6 +14,8 @@
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
|
#define CRITICAL_STATE_LOGGER_PATH "/etc/sysmngr/critical_state_logger.sh"
|
||||||
|
|
||||||
static bool validate_hash_value(const char *algo, const char *file_path, const char *checksum)
|
static bool validate_hash_value(const char *algo, const char *file_path, const char *checksum)
|
||||||
{
|
{
|
||||||
unsigned char buffer[1024 * 16] = {0};
|
unsigned char buffer[1024 * 16] = {0};
|
||||||
|
|
@ -309,3 +311,20 @@ int sysmngr_get_uptime(void)
|
||||||
|
|
||||||
return uptime;
|
return uptime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sysmngr_generate_critical_log_file(const char *log_path, const char *type, bool critical_state)
|
||||||
|
{
|
||||||
|
char cmd[1024] = {0};
|
||||||
|
char output[256] = {0};
|
||||||
|
|
||||||
|
// sh /etc/sysmngr/critical_state_logger.sh 'CPU' '/var/log/critical_memory.log' 'true'
|
||||||
|
snprintf(cmd, sizeof(cmd), "sh %s %s %s %s", CRITICAL_STATE_LOGGER_PATH,
|
||||||
|
type, log_path, critical_state ? "true" : false);
|
||||||
|
|
||||||
|
int res = run_cmd(cmd, output, sizeof(output));
|
||||||
|
if (!res || strncmp(output, "Success", 7) == 0)
|
||||||
|
BBF_DEBUG("Critical log generation succeeded: result=%d, output='%s'", res, output);
|
||||||
|
else
|
||||||
|
BBF_DEBUG("Critical log generation failed: result=%d, output='%s'", res, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,4 +34,6 @@ int sysmngr_ubus_invoke_async(struct ubus_context *ubus_ctx, const char *obj, co
|
||||||
|
|
||||||
int sysmngr_get_uptime(void);
|
int sysmngr_get_uptime(void);
|
||||||
|
|
||||||
|
void sysmngr_generate_critical_log_file(const char *log_path, const char *log_name, bool critical_state);
|
||||||
|
|
||||||
#endif //__UTILS_H
|
#endif //__UTILS_H
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue