Apply systemd socket activation for resourced 64/276964/7
authorUnsung Lee <unsung.lee@samsung.com>
Tue, 28 Jun 2022 11:05:49 +0000 (20:05 +0900)
committerHyotaek Shim <hyotaek.shim@samsung.com>
Wed, 29 Jun 2022 01:43:51 +0000 (01:43 +0000)
+ implement socket-based cpu-boosting (set and clear)

Change-Id: Idb626bf48ab2a69747365fff8f75e5deec504af6
Signed-off-by: Unsung Lee <unsung.lee@samsung.com>
packaging/resourced.spec
src/CMakeLists.txt
src/common/cpu-common.h
src/common/fd-handler.c
src/resource-optimizer/cpu/cpu-boosting.c
src/resourced/resourced.service
src/resourced/resourced.socket [new file with mode: 0644]

index 277e557..ee41391 100644 (file)
@@ -157,7 +157,9 @@ mv %{confdir}/optimizer-profile-tv.conf %{confdir}/optimizer.conf
 %files config
 %config %{_sysconfdir}/dbus-1/system.d/org.tizen.resourced.conf
 %{_unitdir}/resourced.service
+%{_unitdir}/resourced.socket
 %{_unitdir}/multi-user.target.wants/resourced.service
+%{_unitdir}/sockets.target.wants/resourced.socket
 %{confdir}/limiter.conf
 %{confdir}/optimizer.conf
 %{confdir}/process.conf
index 8e71e70..00c3023 100644 (file)
@@ -228,6 +228,12 @@ INSTALL(FILES
   DESTINATION lib/systemd/system)
 INSTALL_SYMLINK(../${RESOURCED}.service lib/systemd/system/multi-user.target.wants/${RESOURCED}.service)
 
+INSTALL(FILES
+  ${RESOURCED_SOURCE_DIR}/${RESOURCED}.socket
+  DESTINATION lib/systemd/system)
+INSTALL_SYMLINK(../${RESOURCED}.socket lib/systemd/system/sockets.target.wants/${RESOURCED}.socket)
+
+
 SET_TARGET_PROPERTIES(${RD_BINARY_NAME} PROPERTIES SKIP_BUILD_RPATH true)
 INSTALL(TARGETS ${RD_BINARY_NAME}
        DESTINATION ${MAKE_INSTALL_PREFIX}/usr/bin RENAME ${RD_BINARY_NAME}
index a8daf58..e797823 100644 (file)
@@ -38,31 +38,16 @@ enum cpu_sched_type {
        CPU_SCHED_DEADLINE,
 };
 
-enum cpu_boosting_command {
-       CPU_BOOSTING_COMMAND_NONE = 0,
-       CPU_BOOSTING_COMMAND_SET,
-       CPU_BOOSTING_COMMAND_CLEAR,
-       CPU_BOOSTING_COMMAND_GET,
-};
-
-struct cpu_boosting_input {
-       enum cpu_boosting_command command;
-       cpu_boosting_level_e level;
-       int timeout_msec;
-       int *tid_list;
-       int tid_count;
-       guint *gsource_id;
-};
-
 struct cpu_boosting_worker {
        pthread_t thread;
        GAsyncQueue *queue;
        int active;
 };
 
-struct cpu_boosting_output {
-       bool success;
-       cpu_boosting_level_info_t level;
+struct cpu_boosting_input {
+       cpu_boosting_input_t client_input;
+       int sock;
+       guint *gsource_id;
 };
 
 struct cpu_sched_info {
index 0ec1aac..6855d98 100644 (file)
@@ -80,8 +80,11 @@ static gboolean channel_changed(GIOChannel *source,
        if (h->fd != g_io_channel_unix_get_fd(source))
                return TRUE;
 
-       if (condition & (G_IO_ERR | G_IO_HUP))
-               _E("GIOChannel receives G_IO_ERR|G_IO_HUP fd = %d condition = %d", h->fd, condition);
+       if (condition & G_IO_HUP)
+               _I("GIOChannel receives G_IO_HUP(connection close) fd = %d condition = %d", h->fd, condition);
+
+       if (condition & G_IO_ERR)
+               _E("GIOChannel receives G_IO_ERR fd = %d condition = %d", h->fd, condition);
 
        if (!(condition & G_IO_IN) && (condition & (G_IO_ERR | G_IO_HUP))) {
                remove_fd_read_handler((fd_handler_h *)&h);
index a4dc5d2..c70b16d 100644 (file)
@@ -1,8 +1,15 @@
+#include <string.h>
+#include <errno.h>
 #include <stdio.h>
 #include <ctype.h>
 #include <pthread.h>
+#include <sys/un.h>
 #include <sys/time.h>
 #include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <systemd/sd-daemon.h>
 
 #include "module.h"
 #include "macro.h"
@@ -11,6 +18,7 @@
 #include "notifier.h"
 #include "resourced.h"
 #include "cpu-common.h"
+#include "fd-handler.h"
 #include "proc-common.h"
 
 static GHashTable *tid_table;
@@ -21,22 +29,28 @@ struct sched_attr cpu_boosting_attr[CPU_BOOSTING_LEVEL_END];
 
 static void cpu_boosting_destroy_request(struct cpu_boosting_input *input);
 
+#define SOCK_PATH "/run/.resourced.socket"
+
 #define CPU_BOOSTING_WORKER_IS_ACTIVE  g_atomic_int_get(&worker.active)
 #define CPU_BOOSTING_WORKER_ACTIVATE   g_atomic_int_set(&worker.active, 1)
 #define CPU_BOOSTING_WORKER_DEACTIVATE g_atomic_int_set(&worker.active, 0)
 
-#define CPU_BOOSTING_SET_REQUEST(_input, _command, _level, _timeout_msec)   \
-{                                                                           \
-       (_input)->command = _command;   (_input)->level = _level;               \
-       (_input)->timeout_msec = _timeout_msec;                                 \
+#define CPU_BOOSTING_SET_REQUEST(_input, _command, _level, _timeout_msec, _pid) \
+{                                                                               \
+       (_input)->client_input.command = _command;                                  \
+       (_input)->client_input.timeout_msec = _timeout_msec;                        \
+       (_input)->client_input.level = _level;                                      \
+       (_input)->client_input.pid = _pid;                                          \
 }
 
 #define CPU_BOOSTING_ENQUEUE_REQUEST(_input)                                \
        do {                                                                    \
                if (CPU_BOOSTING_WORKER_IS_ACTIVE)                                  \
                        g_async_queue_push(worker.queue, _input);                       \
-               else                                                                \
+               else {                                                              \
+                       _W("[CPU-BOOSTING] Cpu boosting is not active");                \
                        cpu_boosting_destroy_request(_input);                           \
+               }                                                                   \
        } while (0)
 
 static void cpu_boosting_destroy_request(struct cpu_boosting_input *input)
@@ -44,8 +58,8 @@ static void cpu_boosting_destroy_request(struct cpu_boosting_input *input)
        if (input == NULL)
                return;
 
-       if (input->tid_list)
-               free(input->tid_list);
+       if (input->client_input.pid.tid)
+               free(input->client_input.pid.tid);
 
        if (input->gsource_id)
                g_free(input->gsource_id);
@@ -53,7 +67,7 @@ static void cpu_boosting_destroy_request(struct cpu_boosting_input *input)
        g_slice_free(struct cpu_boosting_input, input);
 }
 
-static struct cpu_boosting_input *cpu_boosting_new_request(resource_pid_t pid)
+static struct cpu_boosting_input *cpu_boosting_new_request(void)
 {
        struct cpu_boosting_input *input = g_slice_new0(struct cpu_boosting_input);
        if (input == NULL) {
@@ -61,63 +75,7 @@ static struct cpu_boosting_input *cpu_boosting_new_request(resource_pid_t pid)
                return NULL;
        }
 
-#define CPU_BOOSTING_TEMP_TID_LIST_SIZE        50
-       if (pid.pid > 0) {
-               int r;
-               int tid;
-               int tid_list[CPU_BOOSTING_TEMP_TID_LIST_SIZE];
-               int tid_count = 0;
-               _cleanup_free_ char *buf = NULL;
-               DIR *dir;
-               struct dirent *dirent;
-               r = asprintf(&buf, "/proc/%d/task", pid.pid);
-               if (r < 0)
-                       goto dealloc_input;
-
-               dir = opendir(buf);
-               if (!dir)
-                       goto dealloc_input;
-               while ((dirent = readdir(dir))) {
-                       const char *id = dirent->d_name;
-                       if(!isdigit(*id))
-                               continue;
-
-                       tid = atoi(id);
-                       if (tid > 0) {
-                               if (tid_count < CPU_BOOSTING_TEMP_TID_LIST_SIZE)
-                                       tid_list[tid_count++] = tid;
-                               else {
-                                       _E("[CPU_BOOSTING] Temp tid list size is smaller than the number of threads of pid = %d", pid.pid);
-                                       closedir(dir);
-                                       goto dealloc_input;
-                               }
-                       }
-               }
-               closedir(dir);
-
-               input->tid_list = (int *)calloc(tid_count, sizeof(int));
-               if (input->tid_list == NULL)
-                       goto dealloc_input;
-
-               input->tid_count = tid_count;
-               for (int i = 0; i < tid_count; i++)
-                       input->tid_list[i] = tid_list[i];
-       }
-       else {
-               input->tid_list = (int *)calloc(pid.tid_count, sizeof(int));
-               if (input->tid_list == NULL)
-                       goto dealloc_input;
-
-               input->tid_count = pid.tid_count;
-               for (int i = 0; i < pid.tid_count; i++)
-                       input->tid_list[i] = pid.tid[i];
-       }
-
        return input;
-
-dealloc_input:
-       g_slice_free(struct cpu_boosting_input, input);
-       return NULL;
 }
 
 static bool load_cpu_boosting_config(cpu_boosting_level_e level)
@@ -212,6 +170,121 @@ static void load_cpu_boosting_configs(void)
        }
 }
 
+static void cpu_boosting_send_reply(int sock, cpu_boosting_output_t *output)
+{
+       int byte;
+
+       if (sock == 0)
+               return;  /* cpu_boosting by conf */
+       else if (sock < 0) {
+               _E("[CPU-BOOSTING] socket cannot be negative");
+               return;
+       }
+
+       if (output->level.tid_level && output->level.tid_count > 0) {
+               /* Send a header first */
+               byte = send(sock, (const void *)output, sizeof(*output), 0);
+               if (byte != sizeof(*output)) {
+                       _E("[CPU-BOOSTING] Server output size is %u, but sent size is %d",
+                                       (unsigned int)sizeof(*output), byte);
+                       return;
+               }
+
+               /* Check body size */
+               byte = send(sock, (const void *)output->level.tid_level,
+                               output->level.tid_count * sizeof(int), 0);
+               if (byte != output->level.tid_count * sizeof(int)) {
+                       _E("[CPU-BOOSTING] Server output size is %u, but sent size is %d",
+                                       output->level.tid_count * (unsigned int)sizeof(int), byte);
+                       return;
+               }
+       }
+       else {
+               /* Send a header */
+               byte = send(sock, (const void *)&output->success, sizeof(output->success), 0);
+               if (byte != sizeof(output->success)) {
+                       _E("[CPU-BOOSTING] Server output size is %u, but sent size is %d",
+                                       (unsigned int)sizeof(output->success), byte);
+                       return;
+               }
+       }
+}
+
+static int cpu_boosting_enqueue_by_socket(int sock)
+{
+       int ret = RESOURCED_ERROR_NONE;
+       int byte;
+       struct cpu_boosting_input *input;
+       cpu_boosting_output_t output;
+
+       input = cpu_boosting_new_request();
+       if (input == NULL) {
+               ret = RESOURCED_ERROR_OUT_OF_MEMORY;
+               goto destroy_input;
+       }
+
+       /* Get a header from the client */
+       byte = recv(sock, (void *)&input->client_input, sizeof(input->client_input), 0);
+       if (byte != sizeof(input->client_input)) {
+               ret = RESOURCED_ERROR_FAIL;
+               if (byte == 0)
+                       goto destroy_input; /* connection is closed */
+
+               _E("[CPU-BOOSTING] error is based on %s", strerror(errno));
+               _E("[CPU-BOOSTING] client input size is %u, but received size is %d",
+                               (unsigned int)sizeof(input->client_input), byte);
+               input->client_input.pid.tid = NULL;
+               goto destroy_input;
+       }
+
+       /* Check body size */
+       input->client_input.pid.tid = NULL;
+       if (input->client_input.body_size > 0 &&
+           input->client_input.pid.tid_count > 0) {
+               int *tid_list;
+               int tid_count = input->client_input.pid.tid_count;
+
+               tid_list = (int *)calloc(tid_count, sizeof(int));
+               if (tid_list == NULL) {
+                       _E("[CPU-BOOSTING] Failed to allocate memory");
+                       ret = RESOURCED_ERROR_OUT_OF_MEMORY;
+                       goto destroy_input;
+               }
+               else
+                       input->client_input.pid.tid = tid_list;
+
+               /* Get a body from the client */
+               byte = recv(sock, (void *)tid_list, tid_count * sizeof(int), 0);
+               if (byte != tid_count * sizeof(int)) {
+                       ret = RESOURCED_ERROR_FAIL;
+                       if (byte == 0)
+                               goto destroy_input; /* connection is closed */
+
+                       _E("[CPU-BOOSTING] error is based on %s", strerror(errno));
+                       _E("[CPU-BOOSTING] client input size is %u, but received size is %d",
+                                       tid_count * (unsigned int)sizeof(int), byte);
+                       goto destroy_input;
+               }
+       }
+
+       if (input->client_input.command == CPU_BOOSTING_COMMAND_SET ||
+               input->client_input.command == CPU_BOOSTING_COMMAND_CLEAR) {
+               output.success = true;
+               output.level.tid_level = NULL;
+               output.level.tid_count = 0;
+               cpu_boosting_send_reply(sock, &output);
+       }
+
+       input->sock = sock;     /* For a reply */
+       CPU_BOOSTING_ENQUEUE_REQUEST(input);
+       return RESOURCED_ERROR_NONE;
+
+destroy_input:
+       cpu_boosting_destroy_request(input);
+
+       return ret;
+}
+
 /* Called by resourced main thread */
 static int cpu_boosting_enqueue_by_conf(void *data)
 {
@@ -227,6 +300,8 @@ static int cpu_boosting_enqueue_by_conf(void *data)
                return RESOURCED_ERROR_FAIL;
        }
 
+       pid.tid = NULL;
+       pid.tid_count = 0;
        pid.pid = ps->pid;
        if (pid.pid <= 0) {
                _E("[CPU-BOOSTING] pid should be larger than 0");
@@ -238,12 +313,10 @@ static int cpu_boosting_enqueue_by_conf(void *data)
                return RESOURCED_ERROR_NONE;
        }
 
-       input = cpu_boosting_new_request(pid);
-       if (input == NULL) {
-               _E("[CPU-BOOSTING] Failed to allocate cpu boosting input");
+       input = cpu_boosting_new_request();
+       if (input == NULL)
                return RESOURCED_ERROR_FAIL;
-       }
-       CPU_BOOSTING_SET_REQUEST(input, CPU_BOOSTING_COMMAND_SET, cpu_boosting_level, -1);
+       CPU_BOOSTING_SET_REQUEST(input, CPU_BOOSTING_COMMAND_SET, cpu_boosting_level, -1, pid);
        CPU_BOOSTING_ENQUEUE_REQUEST(input);
 
        return RESOURCED_ERROR_NONE;
@@ -266,8 +339,8 @@ static gboolean cpu_boosting_timeout(gpointer data)
                goto timer_out;
        }
 
-       int tid_count = input->tid_count;
-       int *tid_list = input->tid_list;
+       int tid_count = input->client_input.pid.tid_count;
+       int *tid_list = input->client_input.pid.tid;
        cpu_boosting_level_e cpu_boosting_level = CPU_BOOSTING_LEVEL_NONE;
 
        for (int i = 0; i < tid_count; i++) {
@@ -291,38 +364,85 @@ timer_out:
        return G_SOURCE_REMOVE;
 }
 
-static void cpu_boosting_set_or_clear(struct cpu_boosting_input *input,
-               struct cpu_boosting_output *output)
+static void cpu_boosting_set_or_clear(struct cpu_boosting_input *input)
 {
+       int ret;
        bool need_to_clear = false;
        int fail_cnt = 0;
-       int tid_count = input->tid_count;
-       int *tid_list = input->tid_list;
-       int timeout_msec = input->timeout_msec;
-       cpu_boosting_level_e cpu_boosting_level = input->level;
+       int pid = input->client_input.pid.pid;
+       int tid_count = input->client_input.pid.tid_count;
+       int *tid_list = input->client_input.pid.tid;
+       int timeout_msec = input->client_input.timeout_msec;
+       cpu_boosting_level_e cpu_boosting_level = input->client_input.level;
 
-       for (int i = 0; i < tid_count; i++) {
-               if (tid_list[i] > 0) {
-                       g_hash_table_remove(tid_table, (gpointer)&tid_list[i]);
-                       if (sched_setattr(tid_list[i], &cpu_boosting_attr[cpu_boosting_level], 0) < 0) {
-                               _E("[CPU-BOOSTING] Failed to boost cpu of (tid = %d) with (level = %d)",
-                                               tid_list[i], cpu_boosting_level);
-                               fail_cnt++;
+       if (pid > 0) {
+               int tid;
+               DIR *dir;
+               struct dirent *dirent;
+               _cleanup_free_ char *buf = NULL;
+               ret = asprintf(&buf, "/proc/%d/task", pid);
+               if (ret < 0) {
+                       fail_cnt++;
+                       _E("[CPU-BOOSTING] There is no (dir = %s)", buf);
+                       goto output_update;
+               }
+
+               dir = opendir(buf);
+               if (!dir) {
+                       fail_cnt++;
+                       _E("[CPU-BOOSTING] Failed to open (dir = %s)", buf);
+                       goto output_update;
+               }
+
+               while ((dirent = readdir(dir))) {
+                       const char *id = dirent->d_name;
+                       if(!isdigit(*id))
                                continue;
+
+                       tid = atoi(id);
+                       if (tid > 0) {
+                               g_hash_table_remove(tid_table, (gpointer)&tid);
+                               if (sched_setattr(tid, &cpu_boosting_attr[cpu_boosting_level], 0) < 0) {
+                                       _E("[CPU-BOOSTING] Failed to boost cpu of (tid = %d) with (level = %d)",
+                                                       tid, cpu_boosting_level);
+                                       fail_cnt++;
+                                       continue;
+                               }
+                               need_to_clear = true;
                        }
-                       need_to_clear = true;
+                       else
+                               _E("[CPU-BOOSTING] Thread (id = %d) should be larger than 0", tid);
                }
-               else {
-                       _E("[CPU-BOOSTING] Thread (id = %d) should be larger than 0", tid_list[i]);
-                       fail_cnt++;
+               closedir(dir);
+       }
+       else {
+               for (int i = 0; i < tid_count; i++) {
+                       if (tid_list[i] > 0) {
+                               g_hash_table_remove(tid_table, (gpointer)&tid_list[i]);
+                               if (sched_setattr(tid_list[i], &cpu_boosting_attr[cpu_boosting_level], 0) < 0) {
+                                       _E("[CPU-BOOSTING] Failed to boost cpu of (tid = %d) with (level = %d)",
+                                                       tid_list[i], cpu_boosting_level);
+                                       fail_cnt++;
+                                       continue;
+                               }
+                               need_to_clear = true;
+                       }
+                       else {
+                               _E("[CPU-BOOSTING] Thread (id = %d) should be larger than 0", tid_list[i]);
+                       }
                }
        }
 
+output_update:
        if (fail_cnt > 0)
-               output->success = false;
-       else
-               output->success = true;
+               _E("[CPU-BOOSTING] Boosting fail count = %d", fail_cnt);
+
 
+
+       /*
+        * If timeout value is larger than 0 and at least one boosting is succeed,
+        * then set the timer to restore
+        */
        if (timeout_msec > 0 && need_to_clear) {
                input->gsource_id = g_new(guint, 1);
                *(input->gsource_id) = g_timeout_add(timeout_msec, cpu_boosting_timeout, input);
@@ -335,12 +455,13 @@ static void cpu_boosting_set_or_clear(struct cpu_boosting_input *input,
                                        (gpointer)input->gsource_id);
                }
        }
-       else
+       else {
                cpu_boosting_destroy_request(input);
+       }
 }
 
 static void cpu_boosting_get(struct cpu_boosting_input *input,
-               struct cpu_boosting_output *output)
+               cpu_boosting_output_t *output)
 {
 }
 
@@ -355,7 +476,7 @@ static void *cpu_boosting_func(void *data)
 
        while (1) {
                struct cpu_boosting_input *input;
-               struct cpu_boosting_output output;
+               cpu_boosting_output_t output;
 
                if (!CPU_BOOSTING_WORKER_IS_ACTIVE)
                        break;
@@ -370,10 +491,10 @@ static void *cpu_boosting_func(void *data)
                 * Whether current boosting level is supported or not should be checked before
                 * calling CPU_BOOSTING_ENQUEUE_REQUEST. That is the cpu boosting thread ignores it
                 */
-               switch (input->command) {
+               switch (input->client_input.command) {
                        case CPU_BOOSTING_COMMAND_SET:
                        case CPU_BOOSTING_COMMAND_CLEAR:
-                               cpu_boosting_set_or_clear(input, &output);
+                               cpu_boosting_set_or_clear(input);
                                break;
                        case CPU_BOOSTING_COMMAND_GET:
                                cpu_boosting_get(input, &output);
@@ -383,7 +504,6 @@ static void *cpu_boosting_func(void *data)
                                _E("[CPU-BOOSTING] Unknwon cpu boosting command");
                                cpu_boosting_destroy_request(input);
                }
-
        }
 
        g_async_queue_unref(worker.queue);
@@ -442,6 +562,131 @@ static void cpu_boosting_thread_deactivate(void)
        g_async_queue_unref(worker.queue);
 }
 
+static int cpu_boosting_init_socket(void)
+{
+       /* Create a server socket */
+       int ret;
+       int sock = -1;
+       socklen_t size;
+       struct sockaddr_un sockaddr = {0, };
+       int n = sd_listen_fds(0);
+       if (n > 0) {
+               for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
+                       if (sd_is_socket_unix(fd, SOCK_STREAM, 1, SOCK_PATH, 0) > 0) {
+                               sock = fd;
+                               break;
+                       }
+               }
+       }
+
+       if (sock < 0) {
+               sock = socket(AF_UNIX, SOCK_STREAM, 0);
+               if (sock < 0) {
+                       _E("[CPU-BOOSTING] Failed to allocate a socket");
+                       goto return_sock;
+               }
+
+               sockaddr.sun_family = AF_UNIX;
+               strncpy(sockaddr.sun_path, (const char *)SOCK_PATH, strlen(SOCK_PATH)+1);
+               size = sizeof(sockaddr);
+               unlink(SOCK_PATH);
+
+               ret = bind(sock, (struct sockaddr *)&sockaddr, size);
+               if (ret < 0) {
+                       _E("[CPU-BOOSTING] Failed to bind socket");
+                       goto close_sock;
+               }
+
+               ret = listen(sock, SOMAXCONN);
+               if (ret < 0) {
+                       _E("[CPU-BOOSTING] Failed to listen socket");
+                       goto close_sock;
+               }
+       }
+
+return_sock:
+       return sock;
+
+close_sock:
+       close(sock);
+       return 0;
+}
+
+/* Client asks send() to the resourced, so call recv() */
+bool cpu_boosting_recv_from_client(int fd, void *data)
+{
+       int client_sock = fd;
+
+       if (client_sock <= 0) {
+               _E("[CPU-BOOSTING] client socket should be larger than 0");
+               goto remove_handler;
+       }
+
+       if (cpu_boosting_enqueue_by_socket(client_sock) < 0) {
+               goto remove_handler;
+       }
+
+       return G_SOURCE_CONTINUE;
+
+remove_handler:
+       return G_SOURCE_REMOVE;
+}
+
+/* Client asks connect() to the resourced */
+bool cpu_boosting_connect_from_client(int fd, void *data)
+{
+       int ret;
+       int master_sock = fd;
+       static fd_handler_h handler;
+       socklen_t len;
+       struct sockaddr_un cli = { 0 };
+
+       if (master_sock <= 0) {
+               _E("[CPU-BOOSTING] master socket should be larger than 0");
+               goto remove_handler;
+       }
+
+       int new_sock = accept(master_sock, (struct sockaddr *)&cli, &len);
+       if (new_sock < 0) {
+               _E("[CPU-BOOSTING] Failed to allocate a new socket for the client");
+               goto continue_handler;
+       }
+
+       /* Add event handler to receive data from the client */
+       ret = add_fd_read_handler(new_sock, cpu_boosting_recv_from_client,
+                       NULL, NULL, &handler);
+       if (ret < 0) {
+               _E("[CPU-BOOSTING] Failed to add event handler of (sock = %d)", new_sock);
+               close(new_sock);
+       }
+
+continue_handler:
+       return G_SOURCE_CONTINUE;
+
+remove_handler:
+       return G_SOURCE_REMOVE;
+}
+
+static int cpu_boosting_init_server(void)
+{
+       int ret;
+       static fd_handler_h handler;
+       int sock = cpu_boosting_init_socket();
+       if (sock > 0) {
+               ret = add_fd_read_handler(sock, cpu_boosting_connect_from_client,
+                               NULL, NULL, &handler);
+               if (ret < 0) {
+                       _E("[CPU-BOOSTING] Failed to add event handler of (sock = %d)", sock);
+                       close(sock);
+                       return RESOURCED_ERROR_FAIL;
+               }
+       }
+       else
+               return RESOURCED_ERROR_FAIL;
+
+       return RESOURCED_ERROR_NONE;
+}
+
 /* Called by resourced main thread */
 static int cpu_boosting_init(void *data)
 {
@@ -450,7 +695,13 @@ static int cpu_boosting_init(void *data)
        cpu_boosting_thread_activate();
        tid_table = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL);
        g_assert(tid_table);
+       /* For the socket-based client */
+       if (cpu_boosting_init_server() < 0)
+               _E("[CPU-BOOSTING] Failed to initialize server environment");
+       else
+               _D("[CPU-BOOSTING] Success to initialize server environment");
 
+       /* For the conf-based client */
        register_notifier(RESOURCED_NOTIFIER_BOOSTING_RESOURCE, cpu_boosting_enqueue_by_conf);
        return RESOURCED_ERROR_NONE;
 }
index 47c33a4..b911f06 100644 (file)
@@ -7,6 +7,7 @@ Description=Resource management daemon
 # starts after user-sessions are allowed.
 Before=systemd-user-sessions.service
 DefaultDependencies=no
+Requires=resourced.socket
 
 [Service]
 Type=simple
diff --git a/src/resourced/resourced.socket b/src/resourced/resourced.socket
new file mode 100644 (file)
index 0000000..caee1f2
--- /dev/null
@@ -0,0 +1,8 @@
+[Unit]
+Description=Resourced cpu-boosting socket
+
+[Socket]
+ListenStream=/run/.resourced.socket
+SocketMode=0777
+SmackLabelIPIn=*
+SmackLabelIPOut=@