[IMPROVE] Implement freezing/unfreezing apps 01/15801/4
authorAlexander Aksenov <a.aksenov@samsung.com>
Tue, 28 Jan 2014 12:19:32 +0000 (16:19 +0400)
committerAlexander Aksenov <a.aksenov@samsung.com>
Thu, 27 Feb 2014 08:29:51 +0000 (12:29 +0400)
Change-Id: I84628cab91cae8c5f65b274e910e017f751ff72d
Signed-off-by: Alexander Aksenov <a.aksenov@samsung.com>
daemon/Makefile
daemon/da_protocol.c
daemon/daemon.c
daemon/freezing.c [new file with mode: 0644]
daemon/freezing.h [new file with mode: 0644]
daemon/main.c

index 7f93393..5f5c5da 100644 (file)
@@ -42,7 +42,8 @@ DAEMON_SRCS =                 \
        device_vconf.c          \
        device_system_info.c    \
        device_camera.c         \
-       smack.c
+       smack.c \
+       freezing.c
 
 DAEMON_OBJS = $(patsubst %.c,%.o, $(DAEMON_SRCS))
 
index f850101..05125a8 100644 (file)
@@ -48,6 +48,7 @@
 #include "debug.h"
 #include "md5.h"
 #include "da_data.h"
+#include "freezing.h"
 
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -647,6 +648,11 @@ enum ErrorCode stop_all_no_lock(void)
        // stop all only if it has not been called yet
        if (check_running_status(&prof_session)) {
                msg = gen_stop_msg();
+               if(thaw_subgroup()) {
+                       LOGE("Cannot thaw subgroup\n");
+                       error_code = ERR_UNKNOWN;
+                       goto stop_all_exit;
+               }
                terminate_all();
                stop_profiling();
 
index ae53677..9bb0bc9 100644 (file)
@@ -63,6 +63,7 @@
 #include "input_events.h"
 #include "smack.h"
 #include "us_interaction_msg.h"
+#include "freezing.h"
 #include "debug.h"
 
 #define DA_WORK_DIR                    "/home/developer/sdk_tools/da/"
@@ -599,7 +600,8 @@ static Eina_Bool target_event_cb(void *data, Ecore_Fd_Handler *fd_handler)
  */
 static int targetServerHandler(void)
 {
-       msg_target_t log;
+       msg_target_t log, pid_msg;
+       ssize_t recvlen;
 
        int index = getEmptyTargetSlot();
        if (index == MAX_TARGET_COUNT) {
@@ -608,7 +610,7 @@ static int targetServerHandler(void)
        }
 
        manager.target[index].socket =
-           accept(manager.target_server_socket, NULL, NULL);
+               accept(manager.target_server_socket, NULL, NULL);
 
        if (manager.target[index].socket >= 0) {
                /* accept succeed */
@@ -860,6 +862,17 @@ static int kernel_handler(void)
                goto free_and_end;
        }
 
+       switch(*(enum us_interaction_k2u_msg_t *) msg->data) {
+       case US_INT_PAUSE_APPS:
+               freeze_subgroup();
+               break;
+       case US_INT_CONT_APPS:
+               thaw_subgroup();
+               break;
+       default:
+               LOGE("Unknown command\n");
+       }
+
        /* Insert your message handler here */
 
        ret = 0;
diff --git a/daemon/freezing.c b/daemon/freezing.c
new file mode 100644 (file)
index 0000000..9dac901
--- /dev/null
@@ -0,0 +1,158 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "freezing.h"
+#include "debug.h"
+
+#define FREEZER_SUBGROUP "/sys/fs/cgroup/freezer/swap"
+#define FREEZER_TASKS FREEZER_SUBGROUP "/tasks"
+#define FREEZER_STATE FREEZER_SUBGROUP "/freezer.state"
+
+#define US_MANAGER_TASKS "/sys/kernel/debug/swap/us_manager/tasks"
+
+static FILE *f_tasks_fd = NULL, *f_state_fd = NULL, *f_us_man_fd = NULL;
+static const char *freezer_frozen = "FROZEN";
+static const char *freezer_thawed = "THAWED";
+
+static int open_freezer_files(void)
+{
+       f_tasks_fd = fopen(FREEZER_TASKS, "w+");
+       if (f_tasks_fd == NULL)
+               return -1;
+
+       f_state_fd = fopen(FREEZER_STATE, "w");
+       if (f_state_fd == NULL)
+               return -1;
+
+       f_us_man_fd = fopen(US_MANAGER_TASKS, "r");
+       if (f_us_man_fd == NULL)
+               return -1;
+
+       return 0;
+}
+
+static int close_freezer_files(void)
+{
+       int res = 0;
+
+       if (f_tasks_fd != NULL)
+               res = fclose(f_tasks_fd);
+
+       if (f_state_fd != NULL)
+               res |= fclose(f_state_fd);
+
+       if (f_us_man_fd != NULL)
+               res |= fclose(f_us_man_fd);
+
+       return res;
+}
+
+int create_freezer_subgroup(void)
+{
+       struct stat st;
+       int res = 0;
+
+       if (stat(FREEZER_SUBGROUP, &st) == -1) {
+               res = mkdir(FREEZER_SUBGROUP, 0700);
+               if (res)
+                       return res;
+       }
+
+       res = open_freezer_files();
+
+       return res;
+}
+
+int destroy_freezer_subgroup(void)
+{
+       struct stat st;
+       int res = 0;
+
+       res = thaw_subgroup();
+       if (res)
+               return res;
+
+       res = close_freezer_files();
+       if (res)
+               return res;
+
+       if (stat(FREEZER_SUBGROUP, &st) != -1)
+               res = rmdir(FREEZER_SUBGROUP);
+
+       return res;
+}
+
+static int add_tasks_to_freezer(void)
+{
+       ssize_t res;
+       pid_t pid;
+
+       if (f_tasks_fd == NULL) {
+               LOGE("Tasks freezer subgroup file is closed\n");
+               return -1;
+       }
+
+       if (f_us_man_fd == NULL) {
+               LOGE("Us_manager tasks file is closed\n");
+               return -1;
+       }
+
+       while(fscanf(f_us_man_fd, "%u", &pid) == 1) {
+               res = fprintf(f_tasks_fd, "%u", pid);
+               if (res < 0) {
+                       LOGE("Cannot add task %u to freezer group\n", pid);
+                       return -1;
+               }
+       }
+       fflush(f_tasks_fd);
+
+       return 0;
+}
+
+int freeze_subgroup(void)
+{
+       size_t len = strlen(freezer_frozen) + 1;
+       ssize_t res;
+
+       if (f_state_fd == NULL) {
+               LOGE("Freezer.state subgroup file is closed\n");
+               return -1;
+       }
+
+       res = add_tasks_to_freezer();
+       if (res) {
+               LOGE("Cannot add tasks to freezer\n");
+               return -1;
+       }
+
+       res = fwrite(freezer_frozen, len, 1, f_state_fd);
+       if (res < 0) {
+               LOGE("Cannot set FROZEN state\n");
+               return -1;
+       }
+       fflush(f_state_fd);
+
+       return 0;
+}
+
+int thaw_subgroup(void)
+{
+       size_t len = strlen(freezer_thawed) + 1;
+       ssize_t res;
+
+       if (f_state_fd == NULL) {
+               LOGE("Freezer.state subgroup file is closed\n");
+               return -1;
+       }
+
+       res = fwrite(freezer_thawed, len, 1, f_state_fd);
+       if (res < 0) {
+               LOGE("Cannot set THAWED state\n");
+               return -1;
+       }
+       fflush(f_state_fd);
+
+       return 0;
+}
diff --git a/daemon/freezing.h b/daemon/freezing.h
new file mode 100644 (file)
index 0000000..0607eae
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __FREEZING_H__
+#define __FREEZING_H__
+
+int create_freezer_subgroup(void);
+int destroy_freezer_subgroup(void);
+int freeze_subgroup(void);
+int thaw_subgroup(void);
+
+#endif /* __FREEZING_H__ */
index 519c3a2..8e5ffbf 100644 (file)
@@ -53,6 +53,7 @@
 #include "utils.h"
 #include "smack.h"
 #include "us_interaction_msg.h"
+#include "freezing.h"
 
 #define SINGLETON_LOCKFILE                     "/tmp/da_manager.lock"
 #define PORTFILE                                       "/tmp/port.da"
@@ -477,6 +478,12 @@ int main()
        if (err)
                return 1;
 
+       err = create_freezer_subgroup();
+       if (err) {
+               LOGE("cannot create freezer subgroup");
+               return 1;
+       }
+
        //init all file descriptors
        init_system_file_descriptors();
        //daemon work
@@ -485,6 +492,7 @@ int main()
        daemonLoop();
        LOGI("daemon loop finished\n");
        stop_all();
+       destroy_freezer_subgroup();
        finalizeManager();
 
        close_system_file_descriptors();