change usb control process name to usb-server
[framework/system/system-server.git] / ss_pmon_handler.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.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.tizenopensource.org/license
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
18 #include <sysman.h>
19 #include <fcntl.h>
20 #include <assert.h>
21 #include <limits.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24
25 #include "ss_device_plugin.h"
26 #include "ss_log.h"
27 #include "ss_launch.h"
28 #include "include/ss_data.h"
29
30 #define PMON_PERMANENT_DIR      "/tmp/permanent"
31
32 static int pmon_fd = -1;
33
34 static int replace_char(int size, char *t)
35 {
36         while (size > 0) {
37                 if (*t == 0)
38                         *t = ' ';
39                 size--;
40                 t++;
41         }
42         return 0;
43 }
44
45 static char *pmon_get_permanent_pname(int pid)
46 {
47         int fd;
48         char buf[PATH_MAX];
49         struct stat st;
50         char *cmdline = NULL;
51
52         snprintf(buf, sizeof(buf), "%s/%d", PMON_PERMANENT_DIR, pid);
53         fd = open(buf, O_RDONLY);
54         if (fd == -1) {
55                 PRT_TRACE_ERR("file open error");
56                 return NULL;
57         }
58
59         if (fstat(fd, &st) < 0) {
60                 PRT_TRACE_ERR("fstat error");
61                 return NULL;
62         }
63
64         PRT_TRACE("size = %d", (int)st.st_size);
65
66         cmdline = malloc(st.st_size + 1);
67         if (cmdline == NULL) {
68                 PRT_TRACE_ERR("Not enough memory");
69                 return NULL;
70         }
71         memset(cmdline, 0, st.st_size + 1);
72
73         read(fd, cmdline, st.st_size);
74         /* TODO - must change more smarter */
75         replace_char(st.st_size - 1, cmdline);
76         close(fd);
77
78         return cmdline;
79 }
80
81 static void print_pmon_state(unsigned int dead_pid)
82 {
83         PRT_TRACE("[Process MON] %d killed", dead_pid);
84 }
85
86 static int pmon_process(unsigned int pid, void *ad)
87 {
88         char *cmdline;
89         int new_pid;
90         char old_file[PATH_MAX];
91         int fd;
92
93         if (sysconf_is_vip(pid)) {
94                 PRT_TRACE_ERR("=======================================");
95                 PRT_TRACE_ERR("[Process MON] VIP process dead.");
96                 PRT_TRACE_ERR("=======================================");
97         }
98         /* If there is NOT a .hibernation_start file, run following codes 
99          * On hibernation processing, just ignore relaunching */
100         else if (access("/tmp/.hibernation_start", R_OK) != 0) {
101                 cmdline = pmon_get_permanent_pname(pid);
102                 if (cmdline != NULL) {
103                         PRT_TRACE("[Process MON] %s relaunch", cmdline);
104                         new_pid = ss_launch_evenif_exist(cmdline, "");
105                         free(cmdline);
106                         if (new_pid > 0) {
107                                 /* TODO - set oom */
108                                 char buf[PATH_MAX];
109                                 char filepath[PATH_MAX];
110                                 size_t cnt;
111
112                                 if (access(PMON_PERMANENT_DIR, R_OK) < 0) {
113                                         PRT_TRACE("no predefined matrix dir = %s, so created", PMON_PERMANENT_DIR);
114                                         mkdir(PMON_PERMANENT_DIR, 0777);
115                                 }
116
117                                 snprintf(filepath, sizeof(filepath), "%s/%d", PMON_PERMANENT_DIR, pid);
118                                 fd = open(filepath, O_RDONLY);
119                                 if (fd == -1) {
120                                         PRT_TRACE("Failed to open");
121                                         return -1;
122                                 }
123
124                                 cnt = read(fd, buf, PATH_MAX);
125                                 close(fd);
126
127                                 if (cnt <= 0) {
128                                         PRT_TRACE("Failed to read");
129                                         return -1;
130                                 }
131
132                                 snprintf(filepath, sizeof(filepath), "%s/%d", PMON_PERMANENT_DIR, new_pid);
133
134                                 fd = open(filepath, O_CREAT | O_WRONLY, 0644);
135                                 if (fd == -1) {
136                                         PRT_TRACE("Failed to open");
137                                         return -1;
138                                 }
139
140                                 if (write(fd, buf, cnt) == -1) {
141                                         PRT_TRACE("Failed to write");
142                                         close(fd);
143                                         return -1;
144                                 }
145                                 close(fd);
146
147                                 if (0 > plugin_intf->OEM_sys_set_process_monitor_mp_pnp(new_pid)) {
148                                         PRT_TRACE_ERR("Write new pid failed");
149                                 }
150                                 PRT_TRACE("[Process MON] %d ", new_pid);
151
152                                 FILE *fp;
153
154                                 PRT_TRACE
155                                     ("[Process MON] OOMADJ_SET : pid %d, new_oomadj %d",
156                                      new_pid, (-17));
157                                 snprintf(buf, sizeof(buf), "/proc/%d/oom_adj",
158                                          new_pid);
159                                 fp = fopen(buf, "w");
160                                 if (fp == NULL)
161                                         return -1;
162                                 fprintf(fp, "%d", (-17));
163                                 fclose(fp);
164
165                                 snprintf(old_file, sizeof(old_file), "%s/%d",
166                                          PMON_PERMANENT_DIR, pid);
167                                 unlink(old_file);
168                         } else { 
169                                 PRT_TRACE_ERR("[Process MON] failed relaunching");
170                         }
171                 }
172         }
173         return 0;
174 }
175 /*
176 static unsigned int pmon_read(int fd)
177 {
178         unsigned int pid;
179         read(fd, &pid, sizeof(pid));
180         return pid;
181 }
182 */
183
184 static int pmon_cb(void *data, Ecore_Fd_Handler * fd_handler)
185 {
186         int fd;
187         struct ss_main_data *ad = (struct ss_main_data *)data;
188         int dead_pid;
189
190         if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
191                 PRT_TRACE_ERR
192                     ("ecore_main_fd_handler_active_get error , return\n");
193                 return 1;
194         }
195
196         fd = ecore_main_fd_handler_fd_get(fd_handler);
197
198         if ((read(fd, &dead_pid, sizeof(dead_pid))) < 0) {
199                 PRT_TRACE_ERR("Reading DEAD_PID failed, Return");
200                 return 1;
201         }
202                 
203         print_pmon_state(dead_pid);
204         pmon_process(dead_pid, ad);
205
206         return 1;
207 }
208
209 int ss_pmon_init(struct ss_main_data *ad)
210 {
211         char pmon_dev_node[PATH_MAX];
212
213         if (0 > plugin_intf->OEM_sys_get_process_monitor_node(pmon_dev_node)) {
214                 PRT_TRACE_ERR("ss_pmon_init get dev node path failed");
215                 return -1;
216         }
217
218         pmon_fd = open(pmon_dev_node, O_RDONLY);
219         if (pmon_fd < 0) {
220                 PRT_TRACE_ERR("ss_pmon_init fd open failed");
221                 return -1;
222         }
223         ecore_main_fd_handler_add(pmon_fd, ECORE_FD_READ, pmon_cb, ad, NULL,
224                                   NULL);
225         return 0;
226 }