tizen 2.3.1 release
[kernel/api/system-resource.git] / src / proc-stat / proc-main.c
1 /*
2  * resourced
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
20 /*
21  * @file proc-main.c
22  *
23  * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
24  *
25  */
26
27 #include <Ecore.h>
28 #include <Ecore_File.h>
29 #include <pthread.h>
30
31 #include "notifier.h"
32 #include "proc-process.h"
33 #include "proc-main.h"
34 #include "cgroup.h"
35 #include "proc-noti.h"
36 #include "trace.h"
37 #include "proc-handler.h"
38 #include "proc-monitor.h"
39 #include "module.h"
40 #include "macro.h"
41 #include "appid-helper.h"
42 #include "lowmem-handler.h"
43
44 pthread_mutex_t proc_mutex      = PTHREAD_MUTEX_INITIALIZER;
45 static GHashTable *proc_exclude_list;
46 static Ecore_File_Monitor *exclude_list_monitor;
47 static const unsigned int exclude_list_limit = 1024;
48 static int proc_notifd;
49 #define BASE_UGPATH_PREFIX "/usr/ug/bin"
50
51 enum proc_state {
52         PROC_STATE_DEFAULT,
53         PROC_STATE_FOREGROUND,
54         PROC_STATE_BACKGROUND,
55 };
56
57 /*
58  * @brief pid_info_list is only for pid_info_t
59  */
60 GSList *proc_process_list;
61
62 struct pid_info_t *new_pid_info(const pid_t pid, const int type)
63 {
64         struct pid_info_t *result = (struct pid_info_t *)malloc(
65                         sizeof(struct pid_info_t));
66         if (!result) {
67                 _E("Malloc of new_pid_info failed\n");
68                 return NULL;
69         }
70
71         result->pid = pid;
72         result->type = type;
73         return result;
74 }
75
76 static gint compare_pid(gconstpointer a, gconstpointer b)
77 {
78         const struct pid_info_t *pida = (struct pid_info_t *)a;
79         const struct pid_info_t *pidb = (struct pid_info_t *)b;
80         return pida->pid == pidb->pid ? 0 :
81                 pida->pid > pidb->pid ? 1 : -1;
82 }
83
84 static struct pid_info_t *find_pid_info(pid_info_list pids, const pid_t pid)
85 {
86         struct pid_info_t pid_to_find = {
87                 .pid = pid,
88                 /* now it doesn't matter */
89                 .type = RESOURCED_APP_TYPE_UNKNOWN,
90         };
91         GSList *found = NULL;
92
93         ret_value_msg_if(!pids, NULL, "Please provide valid pointer.");
94
95         found = g_slist_find_custom((GSList *)pids,
96                 &pid_to_find, compare_pid);
97
98         if (found)
99                 return (struct pid_info_t *)(found->data);
100         return NULL;
101 }
102
103 void proc_add_pid_list(struct proc_process_info_t *process_info, int pid, enum application_type type)
104 {
105         struct pid_info_t pid_to_find = {
106                 .pid = pid,
107                 /* now it doesn't matter */
108                 .type = RESOURCED_APP_TYPE_UNKNOWN,
109         };
110         GSList *found = NULL;
111
112         if (process_info->pids)
113                 found = g_slist_find_custom((GSList *)process_info->pids,
114                         &pid_to_find, compare_pid);
115
116         if (found)
117                 return;
118
119         pthread_mutex_lock(&proc_mutex);
120         process_info->pids = g_slist_prepend(process_info->pids, new_pid_info(pid, type));
121         pthread_mutex_unlock(&proc_mutex);
122 }
123
124 static int equal_process_info(const char *appid_a, const char *appid_b)
125 {
126         return !strcmp(appid_a, appid_b);
127 }
128
129 static resourced_ret_c proc_check_ug(pid_t pid)
130 {
131         char buf[PROC_BUF_MAX];
132         char cmdline_buf[PROC_NAME_MAX];
133         FILE *fp;
134
135         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
136         fp = fopen(buf, "r");
137         if (fp == NULL)
138                 return RESOURCED_ERROR_FAIL;
139
140         if (fgets(cmdline_buf, PROC_NAME_MAX-1, fp) == NULL) {
141                 fclose(fp);
142                 return RESOURCED_ERROR_FAIL;
143         }
144         fclose(fp);
145         if (strstr(cmdline_buf, BASE_UGPATH_PREFIX)) {
146                 _D("pid(%d) is ug process. don't freeze this process", pid);
147                 return RESOURCED_ERROR_NONFREEZABLE;
148         }
149         return RESOURCED_ERROR_NONE;
150 }
151
152 static void proc_set_service_oomscore(const pid_t pid, const int state)
153 {
154         int oom_score = OOMADJ_SERVICE_DEFAULT;
155         switch(state) {
156         case PROC_STATE_DEFAULT:
157                 oom_score = OOMADJ_SERVICE_DEFAULT;
158                 break;
159         case PROC_STATE_FOREGROUND:
160                 oom_score = OOMADJ_SERVICE_FOREGRD;
161                 break;
162         case PROC_STATE_BACKGROUND:
163                 oom_score = OOMADJ_SERVICE_BACKGRD;
164                 break;
165         }
166         proc_set_oom_score_adj(pid, oom_score);
167 }
168
169 static pid_t get_service_pid(struct proc_process_info_t *info_t)
170 {
171         GSList *iter = NULL;
172
173         if (!info_t) {
174                 _D("Can't find process_info");
175                 return RESOURCED_ERROR_FAIL;
176         }
177
178         gslist_for_each_item(iter, info_t->pids) {
179                 struct pid_info_t *pid_info = (struct pid_info_t *)(iter->data);
180
181                 if (pid_info->type == RESOURCED_APP_TYPE_SERVICE) {
182                         _D("get_service_pid : pid (%d), type (%d)", pid_info->pid, pid_info->type);
183                         return pid_info->pid;
184                 }
185         }
186         return RESOURCED_ERROR_NO_DATA;
187 }
188
189 void proc_set_process_info_memcg(struct proc_process_info_t *process_info, int memcg_idx)
190 {
191         if (!process_info)
192                 return;
193         process_info->memcg_idx = memcg_idx;
194 }
195
196 struct proc_process_info_t *find_process_info(const char *appid, const pid_t pid, const char *pkgid)
197 {
198         GSList *iter = NULL;
199         struct proc_process_info_t *info_t = NULL;
200
201         if (pkgid) {
202                 gslist_for_each_item(iter, proc_process_list) {
203                         info_t = (struct proc_process_info_t *)iter->data;
204                         if (equal_process_info(info_t->pkgname, pkgid))
205                                 return info_t;
206                 }
207                 return NULL;
208         }
209
210         if (!pid) {
211                 gslist_for_each_item(iter, proc_process_list) {
212                         info_t = (struct proc_process_info_t *)iter->data;
213                         if (equal_process_info(info_t->appid, appid))
214                                 return info_t;
215                 }
216                 return NULL;
217         }
218
219         gslist_for_each_item(iter, proc_process_list) {
220                 info_t = (struct proc_process_info_t *)iter->data;
221                 if (info_t->pids && find_pid_info(info_t->pids, pid))
222                         return info_t;
223         }
224         return NULL;
225 }
226
227 static resourced_ret_c proc_update_process_state(const pid_t pid, const int state)
228 {
229         struct proc_process_info_t *process_info = NULL;
230         pid_t service_pid;
231         process_info = find_process_info(NULL, pid, NULL);
232         if (!process_info) {
233                 _E("Current pid (%d) didn't have any process list", pid);
234                 return RESOURCED_ERROR_INVALID_PARAMETER;
235         }
236         process_info->state = state;
237         service_pid = get_service_pid(process_info);
238         if (service_pid)
239                 proc_set_service_oomscore(service_pid, state);
240         return RESOURCED_ERROR_NONE;
241 }
242
243 resourced_ret_c proc_set_runtime_exclude_list(const int pid, int type)
244 {
245         GSList *iter = NULL;
246         struct proc_process_info_t *process_info = NULL;
247         struct pid_info_t *found_pid = NULL;
248
249         gslist_for_each_item(iter, proc_process_list) {
250                 process_info = (struct proc_process_info_t *)iter->data;
251                 if (!process_info->pids)
252                         continue;
253
254                 found_pid = find_pid_info(process_info->pids, pid);
255                 if(!found_pid)
256                         continue;
257
258                 if(process_info->runtime_exclude) {
259                         if (type == PROC_EXCLUDE)
260                                 process_info->runtime_exclude++;
261                         else
262                                 process_info->runtime_exclude--;
263                 } else
264                         process_info->runtime_exclude = type;
265
266                 _D("found_pid %d, set proc exclude list, type = %d, exclude = %d",
267                             found_pid->pid, type, process_info->runtime_exclude);
268                 break;
269         }
270         return RESOURCED_ERROR_NONE;
271 }
272
273 struct proc_process_info_t * proc_add_process_list(const int type, const pid_t pid, const char *appid, const char *pkgid)
274 {
275         struct proc_process_info_t *process_info;
276
277         if (!appid)
278                 return NULL;
279
280         process_info = find_process_info(appid, pid, pkgid);
281         /* do not add if it already in list */
282         if (process_info && find_pid_info(process_info->pids, pid))
283                 return process_info;
284
285         if (!process_info) {
286                 process_info = malloc(sizeof(struct proc_process_info_t));
287                 if (!process_info)
288                         return NULL;
289
290                 memset(process_info, 0, sizeof(struct proc_process_info_t));
291                 strncpy(process_info->appid, appid, MAX_NAME_LENGTH - 1);
292                 process_info->proc_exclude = resourced_proc_excluded(appid);
293                 if (pkgid)
294                         strncpy(process_info->pkgname, pkgid, MAX_NAME_LENGTH - 1);
295                 else
296                         extract_pkgname(process_info->appid, process_info->pkgname,
297                                 MAX_NAME_LENGTH);
298                 pthread_mutex_lock(&proc_mutex);
299                 proc_process_list = g_slist_prepend(proc_process_list,
300                         process_info);
301                 pthread_mutex_unlock(&proc_mutex);
302                 process_info->state = PROC_STATE_DEFAULT;
303         }
304         if (proc_check_ug(pid) == RESOURCED_ERROR_NONFREEZABLE)
305                 process_info->runtime_exclude = PROC_EXCLUDE;
306         if (type == RESOURCED_APP_TYPE_SERVICE)
307                 proc_set_service_oomscore(pid, process_info->state);
308
309         proc_add_pid_list(process_info, pid, type);
310         return process_info;
311 }
312
313 struct proc_process_info_t * proc_create_process_list(const char *appid, const char *pkgid)
314 {
315         struct proc_process_info_t *process_info;
316
317         if (!appid)
318                 return NULL;
319
320         process_info = find_process_info(appid, 0, pkgid);
321         /* do not add if it already in list */
322         if (process_info)
323                 return process_info;
324
325         if (!process_info) {
326                 process_info = malloc(sizeof(struct proc_process_info_t));
327                 if (!process_info)
328                         return NULL;
329
330                 memset(process_info, 0, sizeof(struct proc_process_info_t));
331                 strncpy(process_info->appid, appid, MAX_NAME_LENGTH - 1);
332                 process_info->proc_exclude = resourced_proc_excluded(appid);
333                 if (pkgid)
334                         strncpy(process_info->pkgname, pkgid, MAX_NAME_LENGTH - 1);
335                 else
336                         extract_pkgname(process_info->appid, process_info->pkgname,
337                                 MAX_NAME_LENGTH);
338                 pthread_mutex_lock(&proc_mutex);
339                 proc_process_list = g_slist_prepend(proc_process_list,
340                         process_info);
341                 pthread_mutex_unlock(&proc_mutex);
342                 process_info->state = PROC_STATE_DEFAULT;
343         }
344         return process_info;
345 }
346
347 int proc_remove_process_list(const pid_t pid)
348 {
349         GSList *iter = NULL;
350         struct proc_process_info_t *process_info = NULL;
351         struct pid_info_t *found_pid = NULL;
352
353         pthread_mutex_lock(&proc_mutex);
354         gslist_for_each_item(iter, proc_process_list) {
355                 process_info = (struct proc_process_info_t *)iter->data;
356                 if (!process_info->pids)
357                         continue;
358
359                 found_pid = find_pid_info(process_info->pids, pid);
360                 if(!found_pid)
361                         continue;
362
363                 _D("found_pid %d", found_pid->pid);
364                 /* Introduce function for removing and cleaning */
365                 process_info->pids = g_slist_remove(process_info->pids,
366                         found_pid);
367                 free(found_pid);
368                 if (!process_info->pids) {
369                         proc_process_list = g_slist_remove(
370                                 proc_process_list,
371                                 process_info);
372                         free(process_info);
373                 }
374                 break;
375         }
376         pthread_mutex_unlock(&proc_mutex);
377         return 0;
378 }
379
380 static void proc_free_exclude_key(gpointer data)
381 {
382         if (data)
383                 free(data);
384 }
385
386 static gboolean find_excluded(gpointer key, gpointer value, gpointer user_data)
387 {
388         return (gboolean)strstr((char*)user_data, (char*)key);
389 }
390
391 int resourced_proc_excluded(const char *app_name)
392 {
393         gpointer ret = 0;
394         if (proc_exclude_list)
395                 ret = g_hash_table_find(proc_exclude_list, find_excluded, (gpointer)app_name);
396         else
397                 return RESOURCED_ERROR_NONE;
398         return ret ? RESOURCED_ERROR_NONMONITOR : RESOURCED_ERROR_NONE;
399 }
400
401 static void _prepare_appid(char *appid, const int length)
402 {
403         if (!appid || length - 1 <= 0)
404                 return;
405         appid[length - 1] = '\0'; /*remove ending new line*/
406 }
407
408 static void fill_exclude_list_by_path(const char *exclude_file_name,
409         GHashTable *list)
410 {
411         char *exclude_app_id = 0;
412         int ret;
413         unsigned int excluded_count = 0;
414         size_t buf_size = 0;
415         FILE *exclude_file = NULL;
416
417         if (!list) {
418                 _D("Please initialize exclude list!");
419                 return;
420         }
421
422         exclude_file = fopen(exclude_file_name, "r");
423
424         if (!exclude_file) {
425                 _E("Can't open %s.", exclude_file_name);
426                 return;
427         }
428
429         while (excluded_count++ < exclude_list_limit) {
430                 ret = getline(&exclude_app_id, &buf_size, exclude_file);
431                 if (ret <= 0)
432                         break;
433                 _prepare_appid(exclude_app_id, ret);
434                 _SD("append %s to proc exclude list", exclude_app_id);
435
436                 g_hash_table_insert(list, g_strdup(exclude_app_id),
437                         GINT_TO_POINTER(1));
438         }
439
440         if (excluded_count >= exclude_list_limit)
441                 _E("Exclude list is exceed the limit of %u application",
442                 exclude_list_limit);
443
444         if (exclude_app_id)
445                 free(exclude_app_id);
446
447         fclose(exclude_file);
448 }
449
450 static void _fill_exclude_list(GHashTable *list)
451 {
452         fill_exclude_list_by_path(EXCLUDE_LIST_FULL_PATH, list);
453         fill_exclude_list_by_path(EXCLUDE_LIST_OPT_FULL_PATH, list);
454 }
455
456 static void _exclude_list_change_cb(void *data, Ecore_File_Monitor *em,
457         Ecore_File_Event event, const char *path)
458 {
459         _SD("file %s changed, path: %s, event: %d ", EXCLUDE_LIST_OPT_FULL_PATH,
460         path, event);
461
462         g_hash_table_remove_all(proc_exclude_list);
463         /* reread all */
464         _fill_exclude_list(proc_exclude_list);
465 }
466
467 static void _init_exclude_list_noti(void)
468 {
469         if (ecore_file_init() == 0) {
470                 _E("ecore_file_init() failed");
471                 return;
472         }
473         exclude_list_monitor = ecore_file_monitor_add(EXCLUDE_LIST_OPT_FULL_PATH,
474                 _exclude_list_change_cb,
475                 NULL);
476         if (exclude_list_monitor == NULL)
477                 _E("Dynamic exclude list is not supported. Can not add "
478                         "notification callback");
479 }
480
481 static void proc_exclude_init(void)
482 {
483         proc_exclude_list = g_hash_table_new_full(
484                 g_str_hash,
485                 g_str_equal,
486                 proc_free_exclude_key,
487                 NULL);
488
489         if (proc_exclude_list == NULL) {
490                 _E("Can't initialize exclude_list!");
491                 return;
492         }
493
494         _init_exclude_list_noti();
495         _fill_exclude_list(proc_exclude_list);
496 }
497
498 int resourced_proc_init(const struct daemon_opts *opts)
499 {
500         int ret;
501
502         proc_notifd = proc_noti_init( );
503
504         ret = proc_monitor_init();
505         if (ret)
506                 _E("proc_monitor_init failed : %d", ret);
507
508         proc_exclude_init();
509         return ret;
510 }
511
512 int resourced_proc_exit(const struct daemon_opts *opts)
513 {
514         if (proc_notifd)
515                 close(proc_notifd);
516         g_hash_table_destroy(proc_exclude_list);
517         ecore_file_monitor_del(exclude_list_monitor);
518         g_slist_free_full(proc_process_list, free);
519         return RESOURCED_ERROR_NONE;
520 }
521
522 void proc_set_apptype(const char *appid, const char *pkgid, int type)
523 {
524         struct proc_process_info_t *process_info =
525                 proc_create_process_list(appid, pkgid);
526         if (process_info)
527                 process_info->type = type;
528 }
529
530 int resourced_proc_status_change(int type, pid_t pid, char* app_name, char* pkg_name)
531 {
532         int ret = 0, oom_score_adj = 0;
533         char pidbuf[32];
534         struct proc_status proc_data;;
535
536         if (pid && (proc_get_oom_score_adj(pid, &oom_score_adj) < 0)) {
537                 /* due process with pid is no longer exits
538                  * we need to remove it from
539                  * freezer_process_list  */
540                 proc_remove_process_list(pid);
541                 _E("Empty pid or process not exists. %d", pid);
542                 return RESOURCED_ERROR_FAIL;
543         }
544
545         if (!pid) {
546                 _E("invalid pid : %d of %s", pid, app_name ? app_name : "noprocess");
547                 return RESOURCED_ERROR_FAIL;
548         }
549
550         proc_data.pid = pid;
551         proc_data.appid = app_name;
552         proc_data.processinfo = NULL;
553         switch (type) {
554         case PROC_CGROUP_SET_FOREGRD:
555                 _SD("set foreground : %d", pid);
556                 snprintf(pidbuf, sizeof(pidbuf), "%d", pid);
557                 dbus_proc_handler(PREDEF_FOREGRD, pidbuf);
558                 ret = proc_set_foregrd(pid, oom_score_adj);
559                 if (ret != 0)
560                         return RESOURCED_ERROR_NO_DATA;
561                 proc_update_process_state(pid, PROC_STATE_FOREGROUND);
562                 resourced_notify(RESOURCED_NOTIFIER_APP_FOREGRD, &proc_data);
563                 break;
564         case PROC_CGROUP_SET_LAUNCH_REQUEST:
565                 proc_set_oom_score_adj(pid, OOMADJ_INIT);
566                 if (!app_name) {
567                         _E("need application name!pid = %d", pid);
568                         return RESOURCED_ERROR_NO_DATA;
569                 }
570                 _SD("launch request %s, %d", app_name, pid);
571                 if (pkg_name)
572                         _SD("launch request %s with pkgname", pkg_name);
573                 ret = resourced_proc_excluded(app_name);
574                 if (!ret)
575                         proc_data.processinfo = proc_add_process_list(RESOURCED_APP_TYPE_GUI, pid, app_name, pkg_name);
576                 resourced_notify(RESOURCED_NOTIFIER_APP_LAUNCH, &proc_data);
577                 _E("available memory = %u", get_available());
578                 break;
579         case PROC_CGROUP_SET_SERVICE_REQUEST:
580                 if (!app_name) {
581                         _E("need application name!pid = %d", pid);
582                         return RESOURCED_ERROR_NO_DATA;
583                 }
584                 _SD("service launch request %s, %d", app_name, pid);
585                 if (pkg_name)
586                         _SD("launch request %s with pkgname", pkg_name);
587                 proc_add_process_list(RESOURCED_APP_TYPE_SERVICE, pid, app_name, pkg_name);
588                 if (resourced_proc_excluded(app_name) == RESOURCED_ERROR_NONE)
589                         resourced_notify(RESOURCED_NOTIFIER_SERVICE_LAUNCH, &proc_data);
590                 break;
591         case PROC_CGROUP_SET_RESUME_REQUEST:
592                 _SD("resume request %d", pid);
593                 /* init oom_score_value */
594                 if (oom_score_adj >= OOMADJ_BACKGRD_UNLOCKED) {
595                         resourced_notify(RESOURCED_NOTIFIER_APP_RESUME, &proc_data);
596                         proc_set_oom_score_adj(pid, OOMADJ_INIT);
597                 }
598
599                 if (!app_name) {
600                         _E("need application name!pid = %d", pid);
601                         return RESOURCED_ERROR_NO_DATA;
602                 }
603
604                 proc_add_process_list(RESOURCED_APP_TYPE_GUI, pid, app_name, pkg_name);
605                 if (ret != RESOURCED_ERROR_NONE)
606                         _D("Failed to add to freezer list: pid %d", pid);
607
608                 break;
609         case PROC_CGROUP_SET_TERMINATE_REQUEST:
610                 resourced_notify(RESOURCED_NOTIFIER_APP_TERMINATE, &proc_data);
611                 proc_remove_process_list(pid);
612                 break;
613         case PROC_CGROUP_SET_ACTIVE:
614                 ret = proc_set_active(pid, oom_score_adj);
615                 if (ret != RESOURCED_ERROR_OK)
616                         break;
617                 resourced_notify(RESOURCED_NOTIFIER_APP_ACTIVE, &proc_data);
618                 proc_set_runtime_exclude_list(pid, PROC_EXCLUDE);
619                 break;
620         case PROC_CGROUP_SET_BACKGRD:
621                 snprintf(pidbuf, sizeof(pidbuf), "%d", pid);
622                 dbus_proc_handler(PREDEF_BACKGRD, pidbuf);
623                 ret = proc_set_backgrd(pid, oom_score_adj);
624                 if (ret != 0)
625                         break;
626                 proc_update_process_state(pid, PROC_STATE_BACKGROUND);
627                 break;
628         case PROC_CGROUP_SET_INACTIVE:
629                 ret = proc_set_inactive(pid, oom_score_adj);
630                 if (ret != RESOURCED_ERROR_OK)
631                         break;
632                 resourced_notify(RESOURCED_NOTIFIER_APP_INACTIVE, &proc_data);
633                 break;
634         case PROC_CGROUP_GET_MEMSWEEP:
635                 ret = proc_sweep_memory(PROC_SWEEP_EXCLUDE_ACTIVE, pid);
636                 break;
637         case PROC_CGROUP_SET_NOTI_REQUEST:
638                 break;
639         case PROC_CGROUP_SET_PROC_EXCLUDE_REQUEST:
640                 proc_set_runtime_exclude_list(pid, PROC_EXCLUDE);
641                 break;
642         default:
643                 ret = RESOURCED_ERROR_INVALID_PARAMETER;
644         }
645         return ret;
646 }
647
648 int resourced_proc_action(int type, int argnum, char **arg)
649 {
650         pid_t pid;
651         char *pidbuf = NULL, *cgroup_name = NULL, *pkg_name = NULL;
652         if (argnum < 1) {
653                 _E("Unsupported number of arguments!");
654                 return RESOURCED_ERROR_INVALID_PARAMETER;
655         }
656
657         pidbuf = arg[0];
658         if ((pid = atoi(pidbuf)) < 0) {
659                 _E("Invalid pid argument!");
660                 return RESOURCED_ERROR_INVALID_PARAMETER;
661         }
662
663         /* Getting appid */
664         if (argnum > 1)
665                 /* It's possible to get appid from arg */
666                 cgroup_name = arg[1];
667         if (argnum == 3)
668                 pkg_name = arg[2];
669         _SD("appid %s, pid %d, type %d \n", cgroup_name, pid, type);
670         return resourced_proc_status_change(type, pid, cgroup_name, pkg_name);
671 }
672