return main_pid;
}
-void memory_limit_hash_destroy(gpointer data)
+static void memory_limit_hash_destroy(gpointer data)
{
struct memory_limit_event *mle = (struct memory_limit_event *)data;
if (!mle) {
return ret;
}
-bool memory_action_cb(int fd, void *data)
+static gboolean liveness_check_cb(gpointer data)
+{
+ struct memory_limit_event *mle = (struct memory_limit_event *)data;
+
+ if (!mle) {
+ _E("[DEBUG] memory limit event structure is NULL");
+ goto timer_out;
+ }
+
+ if (mle->pid <= 0) {
+ _E("[DEBUG] pid should be larger than 0");
+ goto mle_timer_init;
+ }
+
+ if (kill(mle->pid, 0) == 0)
+ safe_kill(mle->pid, SIGKILL);
+
+mle_timer_init:
+ mle->pid = -1;
+ mle->sigterm_timer = NULL;
+timer_out:
+ return G_SOURCE_REMOVE;
+}
+
+static bool memory_action_cb(int fd, void *data)
{
int result;
pid_t main_pid;
}
result = cgroup_read_node_uint32(cg_dir, MEMCG_SWAP_USAGE, &usage);
- if (result < 0)
- result = cgroup_read_node_uint32(cg_dir, MEMCG_USAGE, &usage);
-
if (result < 0) {
- _D("[DEBUG] there is no (%s) cgroup any longer, removed it", cg_dir);
- goto remove_mle;
+ result = cgroup_read_node_uint32(cg_dir, MEMCG_USAGE, &usage);
+ if (result < 0) {
+ _D("[DEBUG] there is no (%s) cgroup any longer, removed it", cg_dir);
+ goto remove_mle;
+ }
}
if (usage < mle->threshold) {
return true;
}
- _I("[DEBUG] action: %d", mle->action);
-
switch (mle->action) {
case PROC_ACTION_BROADCAST:
main_pid = get_main_pid(cg_dir, &max_mem);
_D("[DEBUG] there is no victim, removed cgroup : %s", cg_dir);
goto remove_mle;
}
-
safe_kill(main_pid, SIGTERM);
+
+ if (mle->sigterm_timer == NULL) {
+ mle->pid = main_pid;
+ g_timeout_add_seconds(2, liveness_check_cb, mle);
+ }
break;
default:
_E("[DEBUG] Unkown action of memory threshold");
unsigned int limit, enum proc_action action)
{
int fd;
+ int error;
+ unsigned int prev;
fd_handler_h fdh = NULL;
gpointer hash_entry;
struct memory_limit_event *mle = NULL;
}
}
+ error = cgroup_read_node_uint32(dir, MEMCG_LIMIT_BYTE, &prev);
+ if (error) {
+ _E("[DEBUG] Failed to get %s from %s", MEMCG_LIMIT_BYTE, dir);
+ return RESOURCED_ERROR_FAIL;
+ }
+
+ if (prev > (limit * 1.2)) {
+ cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, (limit * 1.2));
+ cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, (limit * 1.2));
+ }
+ else {
+ cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, (limit * 1.2));
+ cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, (limit * 1.2));
+ }
+
snprintf(buf, sizeof(buf), "%d", limit);
- cgroup_write_node_uint32(dir, MEMCG_LIMIT_BYTE, (limit * 1.2));
- cgroup_write_node_uint32(dir, MEMCG_SWAP_LIMIT_BYTE, (limit * 1.5));
if (mle) {
mle->threshold = limit;
}
mle->action = action;
mle->threshold = limit;
+ mle->pid = -1;
+ mle->sigterm_timer = NULL;
add_fd_read_handler(fd, memory_action_cb, mle->path, NULL, &fdh);
mle->fdh = fdh;
g_hash_table_insert(memory_limit_hash, (gpointer)mle->path,
- (gpointer)mle);
+ (gpointer)mle);
_I("[DEBUG] a memory cgroup notificatoin is registered at %s", dir);
return RESOURCED_ERROR_NONE;
return RESOURCED_ERROR_NONE;
if (strncmp(result->section, MEMLIMIT_CONFIG_SECTION,
- sizeof(MEMLIMIT_CONFIG_SECTION)))
+ sizeof(MEMLIMIT_CONFIG_SECTION)))
return RESOURCED_ERROR_NONE;
if (!result->name || !result->value)
result = cgroup_make_subdir(MEMCG_HIGH_PP_PATH, name, NULL);
if (result < 0) {
_E("[DEBUG] Failed to create cgroup subdir '%s/%s'",
- MEMCG_HIGH_PP_PATH, name);
+ MEMCG_HIGH_PP_PATH, name);
return;
}
result = cgroup_make_subdir(MEMCG_HIGH_PP_PATH, pai->appid, NULL);
if (result < 0) {
_E("Failed to create cgroup subdir '%s/%s'",
- MEMCG_HIGH_PP_PATH, pai->appid);
+ MEMCG_HIGH_PP_PATH, pai->appid);
return result;
}