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/data.h"
30 #include "core/common.h"
31 #include "core/devices.h"
33 #define PMON_PERMANENT_DIR "/tmp/permanent"
35 static Ecore_Fd_Handler *pmon_efd = NULL;
37 static int __pmon_start(struct main_data *ad);
38 static int __pmon_stop(int fd);
39 static int replace_char(int size, char *t)
50 static char *pmon_get_permanent_pname(int pid)
58 snprintf(buf, sizeof(buf), "%s/%d", PMON_PERMANENT_DIR, pid);
59 fd = open(buf, O_RDONLY);
61 _E("file open error");
65 if (fstat(fd, &st) < 0) {
70 _D("size = %d", (int)st.st_size);
72 cmdline = malloc(st.st_size + 1);
73 if (cmdline == NULL) {
74 _E("Not enough memory");
78 memset(cmdline, 0, st.st_size + 1);
80 ret = read(fd, cmdline, st.st_size);
81 if (ret >= 0 && ret < st.st_size) {
82 /* TODO - must change more smarter */
83 replace_char(st.st_size - 1, cmdline);
90 static void print_pmon_state(unsigned int dead_pid)
92 _D("[Process MON] %d killed", dead_pid);
95 static int pmon_process(int pid, void *ad)
99 char old_file[PATH_MAX];
104 _I("=======================================");
105 _I("[Process MON] VIP process dead.");
106 _I("=======================================");
108 /* If there is NOT a .hibernation_start file, run following codes
109 * On hibernation processing, just ignore relaunching */
110 else if (access("/tmp/.hibernation_start", R_OK) != 0) {
111 cmdline = pmon_get_permanent_pname(pid);
112 if (cmdline != NULL) {
113 _I("[Process MON] %s relaunch", cmdline);
114 new_pid = launch_evenif_exist(cmdline, "");
119 char filepath[PATH_MAX];
122 if (access(PMON_PERMANENT_DIR, R_OK) < 0) {
123 _I("no predefined matrix dir = %s, so created", PMON_PERMANENT_DIR);
124 r = mkdir(PMON_PERMANENT_DIR, 0777);
126 _E("Make Directory is failed");
131 snprintf(filepath, sizeof(filepath), "%s/%d", PMON_PERMANENT_DIR, pid);
132 fd = open(filepath, O_RDONLY);
134 _E("Failed to open");
137 cnt = read(fd, buf, PATH_MAX);
141 _E("Failed to read");
145 snprintf(filepath, sizeof(filepath), "%s/%d", PMON_PERMANENT_DIR, new_pid);
147 fd = open(filepath, O_CREAT | O_WRONLY, 0644);
149 _E("Failed to open");
152 if (write(fd, buf, cnt) == -1) {
153 _E("Failed to write");
158 if ( device_set_property(DEVICE_TYPE_PROCESS, PROP_PROCESS_MP_PNP, new_pid) < 0) {
159 _E("Write new pid failed");
161 _I("[Process MON] %d ", new_pid);
165 _I("[Process MON] OOMADJ_SET : pid %d, new_oomadj %d",
168 fp = open_proc_oom_score_adj_file(new_pid, "w");
174 snprintf(old_file, sizeof(old_file), "%s/%d",
175 PMON_PERMANENT_DIR, pid);
178 _I("[Process MON] failed relaunching");
185 static unsigned int pmon_read(int fd)
188 read(fd, &pid, sizeof(pid));
193 static Eina_Bool pmon_cb(void *data, Ecore_Fd_Handler * fd_handler)
196 struct main_data *ad = (struct main_data *)data;
198 char pid_str[PATH_MAX];
201 if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
202 _E("ecore_main_fd_handler_active_get error , return");
206 fd = ecore_main_fd_handler_fd_get(fd_handler);
209 _E("ecore_main_fd_handler_fd_get error , return");
213 ret = read(fd, pid_str, PATH_MAX);
215 if (ret < 0 || ret >= PATH_MAX) {
217 _E("Reading DEAD_PID failed, restart ecore fd");
223 dead_pid = strtoul(pid_str, NULL, 10);
224 print_pmon_state(dead_pid);
225 pmon_process(dead_pid, ad);
230 static int __pmon_start(struct main_data *ad)
233 char pmon_dev_node[PATH_MAX];
234 if (device_get_property(DEVICE_TYPE_PROCESS, PROP_PROCESS_NODE,
235 (int *)pmon_dev_node) < 0) {
236 _E("ss_pmon_init get dev node path failed");
240 pmon_fd = open(pmon_dev_node, O_RDONLY);
242 _E("ss_pmon_init fd open failed");
245 pmon_efd = ecore_main_fd_handler_add(pmon_fd, ECORE_FD_READ, pmon_cb, ad, NULL, NULL);
247 _E("error ecore_main_fd_handler_add");
252 static int __pmon_stop(int fd)
255 ecore_main_fd_handler_del(pmon_efd);
265 static void pmon_init(void *data)
267 struct main_data *ad = (struct main_data*)data;
271 ecore_main_fd_handler_del(pmon_efd);
274 if (__pmon_start(ad) == -1) {
275 _E("fail pmon control fd init");
279 static const struct device_ops pmon_device_ops = {
280 .priority = DEVICE_PRIORITY_NORMAL,
285 DEVICE_OPS_REGISTER(&pmon_device_ops)