Init basesystem source codes.
[staging/basesystem.git] / video_in_hal / systemservice / resource_manager / server / src / proc_watch.cpp
1 /*
2  * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <string.h>
19 #include <time.h>
20 #include <errno.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25 #include <sys/timerfd.h>
26 #include <sys/vfs.h>    /* or <sys/statfs.h> */
27 #include <dirent.h>
28 #include <stdlib.h>
29
30 #include <soc_temperature_hal.h>
31
32 #include "ss_resm_resourcemanagerlog.h"
33 #include "proc_watch.h"
34 #include "resm_cfg.h"
35 #include "resm_internal.h"
36
37 #define WTC_TMPFS_INTERVAL (5)
38 #define WTC_MEM_INTERVAL (5)
39 #define DEBUG_INFO_OUTPUT_FREQ (1)
40
41 extern int isNfs;
42 extern void watchMem(void);
43 extern void outputResouceInfo(void);
44 extern EFrameworkunifiedStatus resourcemanagerlog_flag_check(UI_8 *mode);
45
46 #define _SOC_TEMP_MONITOR_
47
48 #if defined(_SOC_TEMP_MONITOR_)
49
50 /*********************************************************************************
51  * Soc Temperature
52  register THSSR : T = CTEMP[5-0] x 5 - 65 [Celsius]
53  *********************************************************************************/
54 #define SOC_TEMP_WATCH_INTVAL_TIMESEC (3 * 60)   // 3 minutes
55 // #define SOC_TEMP_WATCH_INTVAL_TIMESEC (1 * 5) // for debug
56 #define THSSR_TEMP_MASK 0x0000003F
57 #define TEMP_120 (120)
58
59 static float last_temp;
60
61 static void soc_temp_init(void) {
62   FRAMEWORKUNIFIEDLOG(ZONE_SOC_TEMP, __FUNCTION__, "start");
63   last_temp = 0.0f;
64 }
65
66 static void soc_temp(void) {
67   float temp = 0.0f;
68   EFrameworkunifiedStatus e_status = GetSoCTemperature(&temp);
69   if (eFrameworkunifiedStatusOK != e_status) {
70     FRAMEWORKUNIFIEDLOG(ZONE_SOC_TEMP, __FUNCTION__,
71           "THSSR:GetSoCTemperature e_status(%d)", e_status);
72     return;
73   }
74
75   if (TEMP_120 <= temp) {
76     // FRAMEWORKUNIFIEDLOG
77     FRAMEWORKUNIFIEDLOG(ZONE_SOC_TEMP, __FUNCTION__, "%f", temp);  // LCOV_EXCL_BR_LINE 15: marco defined in "native_service/ns_logger_if.h"  // NOLINT[whitespace/line_length]
78   } else {
79     // FRAMEWORKUNIFIEDLOG
80     if (TEMP_120 <= last_temp) {
81       FRAMEWORKUNIFIEDLOG(ZONE_SOC_TEMP, __FUNCTION__, "%f", temp);  // LCOV_EXCL_BR_LINE 15: marco defined in "native_service/ns_logger_if.h"  // NOLINT[whitespace/line_length]
82     }
83   }
84   last_temp = temp;
85 }
86 #endif  // defined ( _SOC_TEMP_MONITOR_ )
87
88 //
89 // Monitor /tmp
90 //
91 #define TMP_USED_SIZE (100*1024)  // 100MB
92 #define TMPFS_PATH "/tmp"
93 static int watch_tmpfs_enable = 1;
94
95 static void printdir(const char* path) {
96   DIR *dirp;
97   struct dirent entry, *next;
98   char buf[512];
99
100   dirp = opendir(path);
101   if (dirp == NULL) {  // LCOV_EXCL_BR_LINE 5: opendir's error case.
102     // LCOV_EXCL_START 5: opendir's error case.
103     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
104     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "opendir(%s) error.(%d)\n", path, errno);
105     return;
106     // LCOV_EXCL_STOP 5: opendir's error case.
107   }
108   while ((readdir_r(dirp, &entry, &next) == 0) && next != NULL) {
109     if (((strlen(entry.d_name) == 1) && (strcmp(entry.d_name, ".") == 0))
110         || ((strlen(entry.d_name) == 2) && (strcmp(entry.d_name, "..") == 0))) {
111       continue;
112     }
113     if ((strlen(path) + strlen(entry.d_name) + 2) <= sizeof(buf)) {/* 2: '/','\0' */
114       struct stat stat_buf;
115
116       strcpy(buf, path);  // NOLINT
117       strcat(buf, "/");  // NOLINT
118       strcat(buf, entry.d_name);  // NOLINT
119       if (stat(buf, &stat_buf) == -1) {  // LCOV_EXCL_BR_LINE 5: stat error case
120         // LCOV_EXCL_START 5: stat error case.
121         AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
122         FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "%s stat error! (%d)\n", buf, errno);
123         // LCOV_EXCL_STOP 5: stat's error case.
124       } else if (S_ISDIR(stat_buf.st_mode)) {
125         printdir(buf);
126       } else {
127         FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "%s %ld bytes", buf, stat_buf.st_size);
128       }
129     } else {
130       FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "path(%s) name(%s) length over!\n", path,
131              entry.d_name);
132     }
133   }
134   closedir(dirp);
135
136   return;
137 }
138
139 static void watchtmpfs(void) {
140   int ret;
141   struct statfs buf;
142   long used;  // NOLINT
143
144   if (!watch_tmpfs_enable) {
145     return;
146   }
147   ret = statfs(TMPFS_PATH, &buf);
148   if (ret < 0) {  // LCOV_EXCL_BR_LINE 5: statfs error case
149     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
150     return;  // LCOV_EXCL_LINE 5: statfs error case
151   }
152   used = (buf.f_blocks - buf.f_bavail) * buf.f_bsize / 1024;  // KB
153   if (used > TMP_USED_SIZE) {
154     FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "%s Used %ld KB > %d KB",
155     TMPFS_PATH,
156            used, TMP_USED_SIZE);
157     FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "----- print %s start -----", TMPFS_PATH);
158     printdir(TMPFS_PATH);
159     FRAMEWORKUNIFIEDLOG(ZONE_INFO, __FUNCTION__, "----- print %s end -----", TMPFS_PATH);
160     watch_tmpfs_enable = 0;
161   }
162 }
163
164 /*********************************************************************************
165  * proc_watch thread main
166  *********************************************************************************/
167 void *
168 PRCW_main(void *p) {
169   fd_set fds;
170   int32_t maxFd = 0;
171   int32_t timerFd;
172   struct itimerspec tm;
173   int32_t sec = 0;
174   EFrameworkunifiedStatus flagRet;
175   uint64_t exp;
176   int ret;
177   UI_8 mode;
178 #if defined(_SOC_TEMP_MONITOR_)
179   int32_t timerFd2;
180   struct itimerspec tm2;
181 #endif  // defined(_SOC_TEMP_MONITOR_)
182
183   /* Memory monitoring and display debug information */
184   timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
185   if (timerFd == -1) {  // LCOV_EXCL_BR_LINE 5: timerfd_create error case
186     // LCOV_EXCL_START 5: timerfd_create error case
187     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
188     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
189            "[RESM_ERR]ResMgr Create timerFd Failed. errno[%d]", errno);
190     // LCOV_EXCL_STOP 5: timerfd_create error case
191   } else {
192     tm.it_value.tv_sec = MONITORING_START_DELAT_TIME;
193     tm.it_value.tv_nsec = 0;
194     tm.it_interval.tv_sec = 1;
195     tm.it_interval.tv_nsec = 0;
196     if (timerfd_settime(timerFd, 0, &tm, NULL) == -1) {  // LCOV_EXCL_BR_LINE 5: timerfd_create error case
197       // LCOV_EXCL_START 5: timerfd_settime error case
198       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
199       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
200              "[RESM_ERR]ResMgr Set timerFd Failed. errno[%d]", errno);
201       // LCOV_EXCL_STOP 5: timerfd_settime error case
202     }
203   }
204
205 #if defined(_SOC_TEMP_MONITOR_)
206   /* Soc temperature monitoring */
207   timerFd2 = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
208   if (timerFd2 == -1) {  // LCOV_EXCL_BR_LINE 5: timerfd_create error case
209     // LCOV_EXCL_START 5: timerfd_create error case
210     AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
211     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
212            "[RESM_ERR]ResMgr Create timerFd2 Failed. errno[%d]", errno);
213     // LCOV_EXCL_STOP 5: timerfd_create error case
214   } else {
215     tm2.it_value.tv_sec = 1;
216     tm2.it_value.tv_nsec = 0;
217     tm2.it_interval.tv_sec = SOC_TEMP_WATCH_INTVAL_TIMESEC;
218     tm2.it_interval.tv_nsec = 0;
219     if (timerfd_settime(timerFd2, 0, &tm2, NULL) == -1) {  // LCOV_EXCL_BR_LINE 5: timerfd_settime error case
220       // LCOV_EXCL_START 5: timerfd_settime error case
221       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
222       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__,
223              "[RESM_ERR]ResMgr Set timerFd2 Failed. errno[%d]", errno);
224       // LCOV_EXCL_STOP 5: timerfd_settime error case
225     }
226     soc_temp_init();
227   }
228 #endif  // defined(_SOC_TEMP_MONITOR_)
229
230   while (1) {
231     FD_ZERO(&fds);
232     if (timerFd != -1) {  // LCOV_EXCL_BR_LINE 5: timerfd_create's error case
233       FD_SET(timerFd, &fds);
234       maxFd = MY_MAX(maxFd, timerFd);
235     }
236 #if defined(_SOC_TEMP_MONITOR_)
237     if (timerFd2 != -1) {  // LCOV_EXCL_BR_LINE 5: timerfd_create's error case
238       FD_SET(timerFd2, &fds);
239       maxFd = MY_MAX(maxFd, timerFd2);
240     }
241 #endif  // defined(_SOC_TEMP_MONITOR_)
242
243     ret = select(maxFd + 1, &fds, NULL, NULL, NULL);
244     if (ret < 0) {  // LCOV_EXCL_BR_LINE 5: select error case
245       // LCOV_EXCL_START 5: select error case
246       AGL_ASSERT_NOT_TESTED();  // LCOV_EXCL_LINE 200: test assert
247       if (errno != EINTR) {
248         FRAMEWORKUNIFIEDLOG(ZONE_ERR, __FUNCTION__, "[RESM_ERR]ResMgr Handle Error");
249         exit(EXIT_FAILURE);
250       }
251       continue;
252       // LCOV_EXCL_STOP 5: select error case
253     }
254
255     if ((timerFd != -1) && FD_ISSET(timerFd, &fds)) {
256       read(timerFd, &exp, sizeof(uint64_t));
257       /* Memory monitoring */
258       if ((sec % WTC_MEM_INTERVAL) == 0) {
259         watchMem();
260       }
261       /* tmpfs monitoring */
262       if (!isNfs && ((sec % WTC_TMPFS_INTERVAL) == 0)) {
263         watchtmpfs();
264       }
265       /* Display debug information */
266       if ((sec % DEBUG_INFO_OUTPUT_FREQ) == 0) {
267         flagRet = resourcemanagerlog_flag_check(&mode);
268         if ((flagRet == eFrameworkunifiedStatusOK) && (mode == FRAMEWORKUNIFIEDLOG_FLAG_MODE_DEBUG)) {
269           outputResouceInfo();
270         }
271       }
272       if (sec >= RESET_SEC) {
273         sec = 0;
274       }
275       sec++;
276     }
277 #if defined(_SOC_TEMP_MONITOR_)
278     if ((timerFd2 != -1) && FD_ISSET(timerFd2, &fds)) {
279       read(timerFd2, &exp, sizeof(uint64_t));
280       soc_temp();
281     }
282 #endif  // defined(_SOC_TEMP_MONITOR_)
283   }
284   return p;
285 }