4 #include <sys/socket.h>
10 #include "core/common.h"
11 #include "core/devices.h"
12 #include "core/device-notifier.h"
19 #include "journal-reader.h"
24 #include "nlproc-stat.h"
25 #include "socket-helper.h"
26 #include "task-stats.h"
30 static int proc_stat_store_period;
31 static int old_events_rotate_period;
32 static int old_events_del_period;
34 static Eina_Hash *sockets;
40 static int api_socket;
41 static Ecore_Thread *logd_thread;
42 static struct timer *proc_stat_store_timer;
43 static struct timer *old_event_del_timer;
44 static struct timer *old_proc_power_cons_timer;
46 static int send_devices_power_cons(int sock)
51 enum logd_object object;
54 } devices_power_cons[2] = {{
56 get_display_total_power_cons(),
57 get_display_curr_power_cons()
63 const size_t count = ARRAY_SIZE(devices_power_cons);
65 if (write(sock, &count, sizeof(count)) != sizeof(count)) {
67 _E("write failed: %s", strerror(errno));
71 for (i = 0; i < count; ++i) {
72 if (write(sock, &devices_power_cons[i], sizeof(devices_power_cons[i])) !=
73 sizeof(devices_power_cons[i])) {
75 _E("write failed: %s", strerror(errno));
83 static void api_socket_cb(void *user_data)
85 enum logd_socket_req_type req_type;
89 if ((ns = accept(api_socket, NULL, NULL)) < 0) {
90 _E("accept failed: %s", strerror(errno));
94 ret = read(ns, (void*)&req_type, sizeof(req_type));
95 if (ret != sizeof(req_type)) {
96 _E("failed read API request type");
98 _E("close failed: %s", strerror(errno));
103 if (req_type == LOGD_DEV_STAT_REQ) { /* devices power consumption */
104 if (send_devices_power_cons(ns) < 0) {
105 _E("send_devices_power_cons failed");
107 } else if (req_type == LOGD_PROC_STAT_REQ) {
108 if (send_proc_stat(ns) < 0) {
109 _E("send_proc_stat failed");
111 } else if (req_type == LOGD_EST_TIME_REQ) {
112 if (battery_send_estimate_lifetime(ns) < 0) {
113 _E("battery_send_estimate_lifetime failed");
115 } else if (req_type == LOGD_BATTERY_LVL_REQ) {
116 if (battery_send_check_points(ns) < 0) {
117 _E("battery_send_check_points failed");
122 _E("close failed: %s", strerror(errno));
126 static void task_stat_socket_cb(void *user_data)
128 process_task_stats_answer(get_task_stats_sock(), proc_terminated, NULL);
131 static void proc_events_socket_cb(void *user_data)
133 process_proc_event_answer(get_proc_events_sock(), proc_forked, NULL);
136 static void proc_stat_store_timer_cb(void *user_data)
138 if (nlproc_stat_store() < 0) {
139 _E("nlproc_stat_store failed");
142 _I("per-process statistics stored");
145 static void old_event_del_timer_cb(void *usr_data)
147 time_t t = time(NULL);
149 if (t == (time_t) -1) {
150 _E("time failed: %s", strerror(errno));
154 if (delete_old_events(t - old_events_rotate_period) < 0) {
155 _E("delete_old_events failed");
158 _I("old events deleted");
161 static int sec_till_new_day()
169 _E("localtime failed");
173 return SEC_PER_DAY - (tm->tm_sec + tm->tm_min * 60 + tm->tm_hour * 3600);
176 static void old_proc_power_cons_timer_cb(void *user_data)
178 int time_till_new_day = sec_till_new_day();
179 struct timer *timer = (struct timer *)user_data;
181 if (delete_old_proc() < 0) {
182 _E("delete_old_proc failed");
184 _I("old cpu power cons deleted");
186 update_timer_exp(timer, time_till_new_day <= 10 ?
187 SEC_PER_DAY - 10 + time_till_new_day : time_till_new_day);
192 static int init_timers()
195 struct socket_info *socket_info;
198 proc_stat_store_timer = create_timer(proc_stat_store_period,
199 proc_stat_store_timer_cb, NULL);
200 if (!proc_stat_store_timer) {
201 _E("ecore_timer_add failed");
203 socket_info = calloc(1, sizeof(struct socket_info));
206 _E("calloc failed: %s", strerror(errno));
209 socket_info->cb = (void(*)(void*))process_timer;
210 socket_info->user_data = proc_stat_store_timer;
212 if (eina_hash_add(sockets, (void*)&proc_stat_store_timer->fd, socket_info) ==
214 _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
220 old_event_del_timer = create_timer(old_events_del_period,
221 old_event_del_timer_cb, NULL);
222 if (!old_event_del_timer) {
223 _E("ecore_timer_add failed");
225 socket_info = calloc(1, sizeof(struct socket_info));
228 _E("calloc failed: %s", strerror(errno));
231 socket_info->cb = (void(*)(void*))process_timer;
232 socket_info->user_data = old_event_del_timer;
234 if (eina_hash_add(sockets, (void*)&old_event_del_timer->fd, socket_info) ==
236 _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
242 old_proc_power_cons_timer = create_timer(sec_till_new_day() - 10,
243 old_proc_power_cons_timer_cb, NULL);
244 if (!old_proc_power_cons_timer) {
245 _E("ecore_timer_add failed");
247 old_proc_power_cons_timer->user_data = old_proc_power_cons_timer;
248 socket_info = calloc(1, sizeof(struct socket_info));
251 _E("calloc failed: %s", strerror(errno));
254 socket_info->cb = (void(*)(void*))process_timer;
255 socket_info->user_data = old_proc_power_cons_timer;
257 if (eina_hash_add(sockets, (void*)&old_proc_power_cons_timer->fd, socket_info) ==
259 _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
267 void logd_event_loop(void *user_data, Ecore_Thread *th)
274 if (init_timers() < 0)
275 _E("init_timers failed");
277 it = eina_hash_iterator_key_new(sockets);
278 while (eina_iterator_next(it, &data)) {
279 int fd = *(int*)data;
280 max_fd = max(max_fd, fd);
282 eina_iterator_free(it);
286 it = eina_hash_iterator_key_new(sockets);
287 while (!ecore_thread_check(th) && eina_iterator_next(it, &data)) {
288 int fd = *(int*)data;
291 eina_iterator_free(it);
293 if (ecore_thread_check(th))
296 select(max_fd + 1, &set, NULL, NULL, NULL);
298 it = eina_hash_iterator_key_new(sockets);
299 while (!ecore_thread_check(th) && eina_iterator_next(it, &data)) {
300 int fd = *(int*)data;
301 struct socket_info *info;
303 if (FD_ISSET(fd, &set)) {
304 info = eina_hash_find(sockets, &fd);
306 info->cb(info->user_data);
308 _E("eina_hash_find failed: wrong fd");
313 eina_iterator_free(it);
314 if (ecore_thread_check(th))
321 static int init_sockets()
325 int task_stat_socket;
326 int proc_events_socket;
327 struct socket_info *socket_info;
329 sockets = eina_hash_pointer_new(free);
331 _E("eina_hash_pointer_new failed");
337 CHECK_RET(ret, "jr_init");
338 event_socket = jr_get_socket();
339 if (event_socket <= 0) {
340 _E("jr_get_socket returned wrong socket");
344 socket_info = calloc(1, sizeof(struct socket_info));
347 _E("calloc failed: %s", strerror(errno));
350 socket_info->cb = event_socket_cb;
352 if (eina_hash_add(sockets, (void*)&event_socket, socket_info) ==
354 _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
359 if ((api_socket = create_logd_socket()) < 0) {
360 _E("create_logd_socket failed");
364 socket_info = calloc(1, sizeof(struct socket_info));
367 _E("calloc failed: %s", strerror(errno));
370 socket_info->cb = api_socket_cb;
372 if (eina_hash_add(sockets, (void*)&api_socket, socket_info) ==
374 _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
378 /* Task stat socket */
379 task_stat_socket = get_task_stats_sock();
381 socket_info = calloc(1, sizeof(struct socket_info));
384 _E("calloc failed: %s", strerror(errno));
387 socket_info->cb = task_stat_socket_cb;
389 if (eina_hash_add(sockets, (void*)&task_stat_socket, socket_info) ==
391 _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
395 /* Proc events socket */
396 proc_events_socket = get_proc_events_sock();
398 socket_info = calloc(1, sizeof(struct socket_info));
401 _E("calloc failed: %s", strerror(errno));
404 socket_info->cb = proc_events_socket_cb;
406 if (eina_hash_add(sockets, (void*)&proc_events_socket, socket_info) ==
408 _E("eina_hash_add failed: %s", eina_error_msg_get(eina_error_get()));
415 static void logd_grabber_exit()
419 if (!proc_stat_store_timer)
420 delete_timer(proc_stat_store_timer);
421 if (!old_event_del_timer)
422 delete_timer(old_event_del_timer);
423 if (!old_proc_power_cons_timer)
424 delete_timer(old_proc_power_cons_timer);
427 eina_hash_free(sockets);
433 _E("event_exit failed");
437 void logd_loop_cancel(void *user_data, Ecore_Thread *th)
439 _I("logd_loop_cancel called");
443 static int logd_grabber_init()
452 _E("config_init failed");
455 enable = config_get_string("enable_grabber", "yes", NULL);
456 if (strncmp(enable, "yes", 3)) {
457 _I("disable logd_grabber");
463 proc_stat_store_period =
464 config_get_int("proc_stat_store_period", 30 * 60, NULL);
465 old_events_rotate_period =
466 config_get_int("old_events_rotate_period", 60 * 60 *24 * 7, NULL);
467 old_events_del_period =
468 config_get_int("old_events_del_period", 30 * 60, NULL);
472 _E("mmc_init failed");
476 ret = display_init();
478 _E("display_init failed");
482 ret = nlproc_stat_init();
484 _E("nlproc_stat_init failed");
488 ret = battery_init();
490 _E("battery_init failed");
496 _E("event_init failed");
500 ret = init_sockets();
502 _E("init_sockets failed");
506 logd_thread = ecore_thread_run(logd_event_loop,
507 NULL, logd_loop_cancel, NULL);
513 static void logd_init()
515 if (logd_grabber_init() < 0)
516 _E("logd_grabber_init failed");
519 static void logd_exit()
521 if (logd_thread && !ecore_thread_check(logd_thread)) {
522 ecore_thread_cancel(logd_thread);
527 static const struct device_ops logd_device_ops = {
528 .priority = DEVICE_PRIORITY_NORMAL,
534 DEVICE_OPS_REGISTER(&logd_device_ops)