3c18cceb849dcb092c687df3636817c25300cc4e
[platform/core/system/stability-monitor.git] / src / raw_data_providers / proc_tsm.c
1 /*
2  * This file is part of stability-monitor
3  * 
4  * Copyright © 2019 Samsung Electronics
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <stdio.h>
22 #include <sys/stat.h>
23 #include <sys/syscall.h>
24 #include <sys/types.h>
25 #include <unistd.h>
26 #include <stdlib.h>
27
28 #include "log.h"
29 #include "raw_data.h"
30
31 #define PROC_TSM_MODULE_NAME "proc_tsm"
32 #define PROC_TSM_PATH "/proc/tsm"
33 #define MAX_LINE 100
34 #define finit_module(fd, params, flags) syscall(__NR_finit_module, fd, params, flags)
35
36
37 static int str_to_ullarray(char *str, unsigned long long *array)
38 {
39     char *ptr = str;
40     int n = 0;
41
42     while (*ptr != '\n' && *ptr != 0)
43         if (n < MAX_PARAMS_PER_LINE) {
44             array[n++] = strtoull(ptr, &ptr, 10);
45         } else {
46             _W("Reached maximum number of parameters per line (%d), discarding others",
47                MAX_PARAMS_PER_LINE);
48             break;
49         }
50
51     return n;
52 }
53
54 /* Read data prepared by kernel module */
55 static int get_raw_data(struct list_head *rd)
56 {
57     char buf[MAX_LINE] = {0,};
58     struct raw_data_item *rd_i;
59     int ret;
60     FILE *fp;
61
62     fp = fopen(PROC_TSM_PATH, "r");
63     if (!fp) {
64         _E("Unable to open " PROC_TSM_PATH ": %m");
65         return -EINVAL;
66     }
67
68     while (fgets(buf, MAX_LINE, fp) != NULL) {
69         ret = raw_data_new_item(rd, &rd_i);
70         if (ret)
71             goto error;
72
73         ret = str_to_ullarray(buf, rd_i->v);
74         if (ret <= 0) {
75             _E("Unable to parse raw data from kernel: \"%s\"\n", buf);
76             goto error;
77         }
78     }
79
80     fclose(fp);
81     return 0;
82
83 error:
84     fclose(fp);
85     raw_data_cleanup(rd);
86     return ret;
87 }
88
89 /* Load kernel module if not loaded */
90 static int init(void)
91 {
92     int fd, ret = 0;
93
94     if (access(PROC_TSM_PATH, O_RDONLY) == 0) {
95         _D("Kernel module already loaded\n");
96         return 0;
97     }
98
99     fd = open(KMOD_PATH, O_RDONLY);
100     if (fd == -1) {
101         _E("Unable to open file descriptor");
102         return -1;
103     }
104
105     ret = finit_module(fd, "", 0);
106     if (ret)
107         _E("Unable to load kernel module: %m");
108     close(fd);
109     return ret;
110 }
111
112 static void cleanup(void)
113 {
114     return;
115 }
116
117 struct raw_data_provider proc_tsm_module = {
118     .name = PROC_TSM_MODULE_NAME,
119     .init = init,
120     .get_raw_data = get_raw_data,
121     .cleanup = cleanup,
122 };
123
124 RAW_DATA_PROVIDER_REGISTER(&proc_tsm_module);