summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaly Wool <vitaly.wool@konsulko.com>2018-11-28 00:21:36 +0000
committerVitaly Wool <vitaly.wool@konsulko.com>2018-11-28 01:33:23 +0100
commitbe74f3995c12b204e769dd844dae66edebc9bbcc (patch)
treeb249a6a26e47159aacb209e45fd6f559b14e52ce
parent596b85a263d7b7dbdabf49edc724f17e207901eb (diff)
Fix memory leaks and add 'kill' verbguppy_6.99.2guppy/6.99.26.99.2
Signed-off-by: Vitaly Wool <vitaly.wool@konsulko.com> Change-Id: Idf75bb1ce703300f9b918969289aba7df9b2a182
-rw-r--r--binding/task-manager-binding.c167
1 files changed, 98 insertions, 69 deletions
diff --git a/binding/task-manager-binding.c b/binding/task-manager-binding.c
index 43c9ee3..932a707 100644
--- a/binding/task-manager-binding.c
+++ b/binding/task-manager-binding.c
@@ -6,17 +6,13 @@
#include <math.h>
#include <unistd.h>
#include <json-c/json.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <errno.h>
#define AFB_BINDING_VERSION 2
#include <afb/afb-binding.h>
-void get_process_list(struct afb_req request);
-struct pstat* fill_pstat(proc_t *proc_info);
-struct cpu_percentage* cpu_calculate(struct pstat*, struct pstat*);
-struct process_container* process_container_constr(char* process_name, int euid, struct pstat *pstat_values);
-static const struct afb_binding_interface *interface;
-static struct afb_event event;
-
struct pstat {
long long unsigned int utime_ticks;
long long unsigned int cutime_ticks;
@@ -32,77 +28,110 @@ struct cpu_percentage {
struct process_container {
char *process_name;
- // int tid;
int euid;
- struct pstat *pstat_values;
+ struct pstat pstat_values;
};
+void get_process_list(struct afb_req request);
+int fill_pstat(proc_t *proc_info, struct pstat *pstat);
+void cpu_calculate(struct pstat*, struct pstat*, struct cpu_percentage *perc);
+void fill_process_container(char* process_name, int euid, struct pstat *pstat_values, struct process_container *pc);
+
void get_process_list(struct afb_req request){
- int seconds = 1, page_size;
- page_size = getpagesize();
- struct pstat *last_pstat_values, *now_pstat_values;
- struct cpu_percentage *cpu_usage;
+ struct pstat last_pstat_values, cur_pstat_values;
+ struct cpu_percentage cpu_usage;
struct process_container *process_obj, *elem = NULL;
- struct process_container* object_container[65535]; // array holding process objects
+ struct process_container *object_container[65535]; // array holding process objects
struct json_object *ret_json, *json_array, *json_obj;
ret_json = json_object_new_object();
json_array = json_object_new_array();
char state_str[2] = "\0";
+ int i, ret;
PROCTAB* proc = openproc(PROC_FILLMEM | PROC_FILLSTAT);
if (!proc){
AFB_REQ_ERROR(request, "Unable to open /proc!");
- afb_req_fail_f(request, "Failed", "Error processing arguments.");
+ afb_req_fail(request, "Failed", "Error processing arguments.");
+ return;
}
+ memset(object_container, 0, sizeof(*object_container));
proc_t* proc_info;
while ((proc_info = readproc(proc, NULL)) != NULL) {
- last_pstat_values = fill_pstat(proc_info);
- process_obj = process_container_constr(proc_info->cmd, proc_info->euid, last_pstat_values);
+ ret = fill_pstat(proc_info, &last_pstat_values);
+ if (ret < 0) {
+ AFB_REQ_ERROR(request, "fill_pstat failed");
+ continue;
+ }
+ process_obj = malloc(sizeof(*process_obj));
+ if (process_obj == NULL) {
+ AFB_REQ_ERROR(request, "allocation of process_obj failed");
+ continue;
+ }
+ fill_process_container(proc_info->cmd, proc_info->euid, &last_pstat_values, process_obj);
object_container[proc_info->tid] = process_obj;
freeproc(proc_info);
}
- sleep(seconds);
+ sleep(1);
+ closeproc(proc);
proc = openproc(PROC_FILLMEM | PROC_FILLSTAT);
if (!proc){
AFB_REQ_ERROR(request, "Unable to open /proc!");
- afb_req_fail_f(request, "Failed", "Error processing arguments.");
+ afb_req_fail(request, "Failed", "Error processing arguments.");
+ return;
}
- proc_t* proc_info2;
- while ((proc_info2 = readproc(proc, NULL)) != NULL) {
- now_pstat_values = fill_pstat(proc_info2);
- elem = object_container[proc_info2->tid];
- if(elem){
- cpu_usage = cpu_calculate(elem->pstat_values, now_pstat_values);
+ while ((proc_info = readproc(proc, NULL)) != NULL) {
+ ret = fill_pstat(proc_info, &cur_pstat_values);
+ if (ret < 0) {
+ AFB_REQ_ERROR(request, "fill_pstat failed");
+ continue;
+ }
+ elem = object_container[proc_info->tid];
+ if (elem) {
+ cpu_calculate(&elem->pstat_values, &cur_pstat_values, &cpu_usage);
json_obj = json_object_new_object();
- json_object_object_add(json_obj, "cmd", json_object_new_string(proc_info2->cmd));
- json_object_object_add(json_obj, "tid", json_object_new_int(proc_info2->tid));
- json_object_object_add(json_obj, "euid", json_object_new_int(proc_info2->euid));
- json_object_object_add(json_obj, "scpu", json_object_new_double(cpu_usage->scpu_usage));
- json_object_object_add(json_obj, "ucpu", json_object_new_double(cpu_usage->ucpu_usage));
- json_object_object_add(json_obj, "resident_mem", json_object_new_double((proc_info2->resident * page_size)/ pow(1024, 2)));
- state_str[0] = proc_info2->state;
+ json_object_object_add(json_obj, "cmd", json_object_new_string(proc_info->cmd));
+ json_object_object_add(json_obj, "tid", json_object_new_int(proc_info->tid));
+ json_object_object_add(json_obj, "euid", json_object_new_int(proc_info->euid));
+ json_object_object_add(json_obj, "scpu", json_object_new_double(cpu_usage.scpu_usage));
+ json_object_object_add(json_obj, "ucpu", json_object_new_double(cpu_usage.ucpu_usage));
+ json_object_object_add(json_obj, "resident_mem", json_object_new_double((proc_info->resident * getpagesize())/ pow(1024, 2)));
+ state_str[0] = proc_info->state;
json_object_object_add(json_obj, "state", json_object_new_string(state_str));
json_object_array_add(json_array, json_obj);
}
- freeproc(proc_info2);
+ freeproc(proc_info);
}
json_object_object_add(ret_json, "processes", json_array);
afb_req_success(request, ret_json, NULL);
closeproc(proc);
- // printf ("The json object created: %s\n", json_object_to_json_string(ret_json));
}
-struct pstat* fill_pstat(proc_t *proc_info){
+void kill_process(struct afb_req request)
+{
+ struct json_object *ret_json;
+ ret_json = json_object_new_object();
+ json_object *queryJ = afb_req_json(request);
+ int tid = json_object_get_int(queryJ);
+ int ret;
+
+ AFB_REQ_INFO(request, "killing %d\n", tid);
+ /* XXX: add checks */
+ ret = kill(tid, SIGTERM);
+ if (ret < 0)
+ afb_req_fail_f(request, "Failed", "Error %d", errno);
+ /* we don't signal success, there's no use for it */
+}
+
- long unsigned int cpu_total_time;
- long unsigned int cpu_time[10];
- struct pstat *pstat_values = malloc(sizeof(struct pstat));
+int fill_pstat(proc_t *proc_info, struct pstat *pstat_values)
+{
+ long unsigned int cpu_time[9];
pstat_values->utime_ticks = proc_info->utime;
pstat_values->cutime_ticks = proc_info->cutime;
@@ -110,53 +139,46 @@ struct pstat* fill_pstat(proc_t *proc_info){
pstat_values->cstime_ticks = proc_info->cstime;
FILE *fstat = fopen("/proc/stat", "r");
- if (fstat == NULL) {
- perror("FOPEN ERROR ");
- fclose(fstat);
- }
+ if (fstat == NULL)
+ return -1;
memset(cpu_time, 0, sizeof(cpu_time));
- if (fscanf(fstat, "%*s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
- &cpu_time[0], &cpu_time[1], &cpu_time[2], &cpu_time[3],
- &cpu_time[4], &cpu_time[5], &cpu_time[6], &cpu_time[7],
- &cpu_time[8], &cpu_time[9]) == EOF) {
- fclose(fstat);
- }
+ fscanf(fstat, "%*s %lu %lu %lu %lu %*lu %lu %lu %lu %lu %lu",
+ &cpu_time[0], &cpu_time[1], &cpu_time[2], &cpu_time[3],
+ &cpu_time[4], &cpu_time[5], &cpu_time[6], &cpu_time[7],
+ &cpu_time[8]);
fclose(fstat);
/*
* Returns total CPU time. It is a sum of user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice
+ *
+ *
*/
- for(int i = 0; i < 10; i++)
+ pstat_values->cpu_total_time = 0;
+ for(int i = 0; i < 9; i++)
pstat_values->cpu_total_time += cpu_time[i];
- return pstat_values;
+ return 0;
}
-struct cpu_percentage* cpu_calculate(struct pstat *last_pstat_values, struct pstat *now_pstat_values){
-
- long unsigned int total_time_diff = now_pstat_values->cpu_total_time - last_pstat_values->cpu_total_time;
-
- struct cpu_percentage *cpu_values = malloc(sizeof(struct cpu_percentage));
+void cpu_calculate(struct pstat *last_pstat_values, struct pstat *cur_pstat_values, struct cpu_percentage *cpu_values)
+{
- cpu_values->ucpu_usage = 100 * (((now_pstat_values->utime_ticks + now_pstat_values->cutime_ticks)
- - (last_pstat_values->utime_ticks + last_pstat_values->cutime_ticks)) / (double) total_time_diff);
+ long unsigned int total_time_diff = cur_pstat_values->cpu_total_time - last_pstat_values->cpu_total_time;
- cpu_values->scpu_usage = 100 * (((now_pstat_values->stime_ticks + now_pstat_values->cstime_ticks)
- - (last_pstat_values->stime_ticks + last_pstat_values->cstime_ticks)) / (double) total_time_diff);
+ cpu_values->ucpu_usage = 100.0 * (((cur_pstat_values->utime_ticks + cur_pstat_values->cutime_ticks)
+ - (last_pstat_values->utime_ticks + last_pstat_values->cutime_ticks)) / (double) total_time_diff);
- return cpu_values;
+ cpu_values->scpu_usage = 100.0 * (((cur_pstat_values->stime_ticks + cur_pstat_values->cstime_ticks)
+ - (last_pstat_values->stime_ticks + last_pstat_values->cstime_ticks)) / (double) total_time_diff);
}
-struct process_container* process_container_constr(char* process_name, int euid, struct pstat *pstat_values) {
-
- struct process_container *r = malloc(sizeof(struct process_container));
- r->process_name = process_name;
- r->euid = euid;
- r->pstat_values = pstat_values;
-
- return r;
+void fill_process_container(char *process_name, int euid, struct pstat *pstat_values, struct process_container *pc)
+{
+ pc->process_name = process_name;
+ pc->euid = euid;
+ pc->pstat_values = *pstat_values;
}
static const struct afb_verb_v2 _afb_verbs_v2_taskmanager[] = {
@@ -166,6 +188,13 @@ static const struct afb_verb_v2 _afb_verbs_v2_taskmanager[] = {
.auth = NULL,
.info = "Get an array of all processes currently running on the system",
.session = AFB_SESSION_NONE_V2
+ },
+ {
+ .verb = "kill_process",
+ .callback = kill_process,
+ .auth = NULL,
+ .info = "Kill the process specified by tid",
+ .session = AFB_SESSION_NONE_V2
}
};
@@ -176,4 +205,4 @@ const struct afb_binding_v2 afbBindingV2 = {
.info = "Task Manager service",
.verbs = _afb_verbs_v2_taskmanager,
.noconcurrency = 0
-}; \ No newline at end of file
+};