4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include <sys/types.h>
25 #include <device-node.h>
28 #include "core/launch.h"
29 #include "core/common.h"
30 #include "core/devices.h"
32 #define PMON_PERMANENT_DIR "/tmp/permanent"
34 static Ecore_Fd_Handler *pmon_efd = NULL;
36 static int __pmon_start(void);
37 static int __pmon_stop(int fd);
38 static int replace_char(int size, char *t)
49 static char *pmon_get_permanent_pname(int pid)
57 snprintf(buf, sizeof(buf), "%s/%d", PMON_PERMANENT_DIR, pid);
58 fd = open(buf, O_RDONLY);
60 _E("file open error");
64 if (fstat(fd, &st) < 0) {
69 _D("size = %d", (int)st.st_size);
71 cmdline = malloc(st.st_size + 1);
72 if (cmdline == NULL) {
73 _E("Not enough memory");
77 memset(cmdline, 0, st.st_size + 1);
79 ret = read(fd, cmdline, st.st_size);
80 if (ret >= 0 && ret < st.st_size) {
81 /* TODO - must change more smarter */
82 replace_char(st.st_size - 1, cmdline);
89 static void print_pmon_state(unsigned int dead_pid)
91 _D("[Process MON] %d killed", dead_pid);
94 static int pmon_process(int pid)
98 char old_file[PATH_MAX];
103 _I("=======================================");
104 _I("[Process MON] VIP process dead.");
105 _I("=======================================");
107 /* If there is NOT a .hibernation_start file, run following codes
108 * On hibernation processing, just ignore relaunching */
109 else if (access("/tmp/.hibernation_start", R_OK) != 0) {
110 cmdline = pmon_get_permanent_pname(pid);
111 if (cmdline != NULL) {
112 _I("[Process MON] %s relaunch", cmdline);
113 new_pid = launch_evenif_exist(cmdline, "");
118 char filepath[PATH_MAX];
121 if (access(PMON_PERMANENT_DIR, R_OK) < 0) {
122 _I("no predefined matrix dir = %s, so created", PMON_PERMANENT_DIR);
123 r = mkdir(PMON_PERMANENT_DIR, 0777);
125 _E("Make Directory is failed");
130 snprintf(filepath, sizeof(filepath), "%s/%d", PMON_PERMANENT_DIR, pid);
131 fd = open(filepath, O_RDONLY);
133 _E("Failed to open");
136 cnt = read(fd, buf, PATH_MAX);
140 _E("Failed to read");
144 snprintf(filepath, sizeof(filepath), "%s/%d", PMON_PERMANENT_DIR, new_pid);
146 fd = open(filepath, O_CREAT | O_WRONLY, 0644);
148 _E("Failed to open");
151 if (write(fd, buf, cnt) == -1) {
152 _E("Failed to write");
157 if ( device_set_property(DEVICE_TYPE_PROCESS, PROP_PROCESS_MP_PNP, new_pid) < 0) {
158 _E("Write new pid failed");
160 _I("[Process MON] %d ", new_pid);
164 _I("[Process MON] OOMADJ_SET : pid %d, new_oomadj %d",
167 fp = open_proc_oom_score_adj_file(new_pid, "w");
173 snprintf(old_file, sizeof(old_file), "%s/%d",
174 PMON_PERMANENT_DIR, pid);
177 _I("[Process MON] failed relaunching");
184 static unsigned int pmon_read(int fd)
187 read(fd, &pid, sizeof(pid));
192 static Eina_Bool pmon_cb(void *data, Ecore_Fd_Handler * fd_handler)
196 char pid_str[PATH_MAX];
199 if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
200 _E("ecore_main_fd_handler_active_get error , return");
204 fd = ecore_main_fd_handler_fd_get(fd_handler);
207 _E("ecore_main_fd_handler_fd_get error , return");
211 ret = read(fd, pid_str, PATH_MAX);
213 if (ret < 0 || ret >= PATH_MAX) {
215 _E("Reading DEAD_PID failed, restart ecore fd");
221 dead_pid = strtoul(pid_str, NULL, 10);
222 print_pmon_state(dead_pid);
223 pmon_process(dead_pid);
228 static int __pmon_start(void)
231 char pmon_dev_node[PATH_MAX];
232 if (device_get_property(DEVICE_TYPE_PROCESS, PROP_PROCESS_NODE,
233 (int *)pmon_dev_node) < 0) {
234 _E("ss_pmon_init get dev node path failed");
238 pmon_fd = open(pmon_dev_node, O_RDONLY);
240 _E("ss_pmon_init fd open failed");
243 pmon_efd = ecore_main_fd_handler_add(pmon_fd, ECORE_FD_READ, pmon_cb, ad, NULL, NULL);
245 _E("error ecore_main_fd_handler_add");
250 static int __pmon_stop(int fd)
253 ecore_main_fd_handler_del(pmon_efd);
263 static void pmon_init(void *data)
268 ecore_main_fd_handler_del(pmon_efd);
271 if (__pmon_start() == -1) {
272 _E("fail pmon control fd init");
276 static const struct device_ops pmon_device_ops = {
277 .priority = DEVICE_PRIORITY_NORMAL,
282 DEVICE_OPS_REGISTER(&pmon_device_ops)