diff --git a/0002-etmem-remove-unnecessary-log-code.patch b/0002-etmem-remove-unnecessary-log-code.patch new file mode 100644 index 0000000000000000000000000000000000000000..8a066ea2e7fef54853585a628676a55db61f3630 --- /dev/null +++ b/0002-etmem-remove-unnecessary-log-code.patch @@ -0,0 +1,34 @@ +From 3ac65b4eb27e0e5d940e898af98de87e49e1fe99 Mon Sep 17 00:00:00 2001 +From: liubo +Date: Mon, 10 Apr 2023 21:12:25 +0800 +Subject: [PATCH 2/4] etmem: remove unnecessary log code + +etmem supports only 400/600 configuration file +permissions. + +During the permission check, the system check whether +the permisson requirements of 400 or 600 are met. + +Error logs do not need to be printed during each permission +check. + +Signed-off-by: liubo +--- + etmem/src/etmemd_src/etmemd_common.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/etmem/src/etmemd_src/etmemd_common.c b/etmem/src/etmemd_src/etmemd_common.c +index 649f472..7a6125e 100644 +--- a/etmem/src/etmemd_src/etmemd_common.c ++++ b/etmem/src/etmemd_src/etmemd_common.c +@@ -563,7 +563,6 @@ int file_permission_check(const char *file_path, mode_t mode) + + file_p = buf.st_mode & S_IRWX_VALID; + if (file_p != mode) { +- etmemd_log(ETMEMD_LOG_WARN, "file : %s mode is wrong.\n", file_path); + return -1; + } + +-- +2.33.0 + diff --git a/0003-etmem-fix-memory-leak-and-fd-leak.patch b/0003-etmem-fix-memory-leak-and-fd-leak.patch new file mode 100644 index 0000000000000000000000000000000000000000..f141bcc449631d59dc7152532dc5f7fe98dfb166 --- /dev/null +++ b/0003-etmem-fix-memory-leak-and-fd-leak.patch @@ -0,0 +1,199 @@ +From 5892dac2f7de185c2b0f2c9c00fdd2c5e985a9dc Mon Sep 17 00:00:00 2001 +From: liubo +Date: Wed, 31 May 2023 17:12:57 +0800 +Subject: [PATCH 3/4] etmem: fix memory leak and fd leak + +fix memory leak and fp leak. +When user stop the task while task is running, the routine +will run pthread_cancel to stop the task. +memory of vmas struct may leak when this happens. +Set thread cannot be canceled when main routine is running. + +Signed-off-by: liubo +--- + etmem/src/etmemd_src/etmemd_migrate.c | 3 +++ + etmem/src/etmemd_src/etmemd_rpc.c | 7 +++++- + etmem/src/etmemd_src/etmemd_scan.c | 8 ++----- + etmem/src/etmemd_src/etmemd_slide.c | 29 +++++++++++------------ + etmem/src/etmemd_src/etmemd_threadpool.c | 1 + + etmem/src/etmemd_src/etmemd_threadtimer.c | 13 +++++++--- + 6 files changed, 36 insertions(+), 25 deletions(-) + +diff --git a/etmem/src/etmemd_src/etmemd_migrate.c b/etmem/src/etmemd_src/etmemd_migrate.c +index a143c5e..5f41876 100644 +--- a/etmem/src/etmemd_src/etmemd_migrate.c ++++ b/etmem/src/etmemd_src/etmemd_migrate.c +@@ -98,6 +98,7 @@ static int etmemd_migrate_mem(const char *pid, const char *grade_path, struct pa + etmemd_log(ETMEMD_LOG_DEBUG, "migrate failed for pid %s, check if etmem_swap.ko installed\n", pid); + free(swap_str); + fclose(fp); ++ fp = NULL; + return -1; + } + free(swap_str); +@@ -105,6 +106,8 @@ static int etmemd_migrate_mem(const char *pid, const char *grade_path, struct pa + } + + fclose(fp); ++ fp = NULL; ++ + return 0; + } + +diff --git a/etmem/src/etmemd_src/etmemd_rpc.c b/etmem/src/etmemd_src/etmemd_rpc.c +index 780ddce..100a7bd 100644 +--- a/etmem/src/etmemd_src/etmemd_rpc.c ++++ b/etmem/src/etmemd_src/etmemd_rpc.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include "securec.h" + #include "etmemd_rpc.h" + #include "etmemd_project.h" +@@ -162,7 +163,11 @@ static struct obj_cmd_item obj_remove_items[] = { + + static enum opt_result do_obj_remove(GKeyFile *config) + { +- return do_obj_cmd(config, obj_remove_items, ARRAY_SIZE(obj_remove_items), false); ++ enum opt_result ret; ++ ++ ret = do_obj_cmd(config, obj_remove_items, ARRAY_SIZE(obj_remove_items), false); ++ (void)malloc_trim(0); ++ return ret; + } + + static enum opt_result handle_obj_cmd(char *file_name, enum cmd_type type) +diff --git a/etmem/src/etmemd_src/etmemd_scan.c b/etmem/src/etmemd_src/etmemd_scan.c +index e06ba92..699b1cd 100644 +--- a/etmem/src/etmemd_src/etmemd_scan.c ++++ b/etmem/src/etmemd_src/etmemd_scan.c +@@ -347,12 +347,7 @@ struct vmas *get_vmas_with_flags(const char *pid, char *vmflags_array[], int vmf + size_t len; + char *maps_file = NULL; + +- if (vmflags_num == 0) { +- maps_file = MAPS_FILE; +- } else { +- maps_file = SMAPS_FILE; +- } +- ++ maps_file = (vmflags_num == 0) ? MAPS_FILE : SMAPS_FILE; + ret_vmas = (struct vmas *)calloc(1, sizeof(struct vmas)); + if (ret_vmas == NULL) { + etmemd_log(ETMEMD_LOG_ERR, "malloc for vmas fail\n"); +@@ -397,6 +392,7 @@ struct vmas *get_vmas_with_flags(const char *pid, char *vmflags_array[], int vmf + } + + fclose(fp); ++ fp = NULL; + return ret_vmas; + } + +diff --git a/etmem/src/etmemd_src/etmemd_slide.c b/etmem/src/etmemd_src/etmemd_slide.c +index a3c474b..1a11f45 100644 +--- a/etmem/src/etmemd_src/etmemd_slide.c ++++ b/etmem/src/etmemd_src/etmemd_slide.c +@@ -216,11 +216,10 @@ static void *slide_executor(void *arg) + return NULL; + } + +- /* register cleanup function in case of unexpected cancellation detected, +- * and register for memory_grade first, because it needs to clean after page_refs is cleaned */ +- pthread_cleanup_push(clean_memory_grade_unexpected, &memory_grade); +- pthread_cleanup_push(clean_page_refs_unexpected, &page_refs); +- pthread_cleanup_push(clean_page_sort_unexpected, &page_sort); ++ if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) != 0) { ++ etmemd_log(ETMEMD_LOG_ERR, "failed to set pthread cancel state.\n"); ++ return NULL; ++ } + + page_refs = etmemd_do_scan(tk_pid, tk_pid->tk); + if (page_refs == NULL) { +@@ -237,15 +236,10 @@ static void *slide_executor(void *arg) + memory_grade = slide_policy_interface(&page_sort, tk_pid); + + scan_out: +- /* clean up page_sort linked array */ +- pthread_cleanup_pop(1); ++ clean_page_sort_unexpected(&page_sort); + +- /* no need to use page_refs any longer. +- * pop the cleanup function with parameter 1, because the items in page_refs list will be moved +- * into the at least on list of memory_grade after polidy function called if no problems happened, +- * but mig_policy_func() may fails to move page_refs in rare cases. +- * It will do nothing if page_refs is NULL */ +- pthread_cleanup_pop(1); ++ /* no need to use page_refs any longer. */ ++ clean_page_refs_unexpected(&page_refs); + + if (memory_grade == NULL) { + etmemd_log(ETMEMD_LOG_DEBUG, "pid %u memory grade is empty\n", tk_pid->pid); +@@ -261,12 +255,17 @@ scan_out: + } + + exit: +- /* clean memory_grade here */ +- pthread_cleanup_pop(1); ++ clean_memory_grade_unexpected(&memory_grade); ++ + if (malloc_trim(0) == 0) { + etmemd_log(ETMEMD_LOG_INFO, "malloc_trim to release memory for pid %u fail\n", tk_pid->pid); + } + ++ if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0) { ++ etmemd_log(ETMEMD_LOG_DEBUG, "pthread_setcancelstate PTHREAD_CANCEL_ENABLE failed.\n"); ++ } ++ pthread_testcancel(); ++ + return NULL; + } + +diff --git a/etmem/src/etmemd_src/etmemd_threadpool.c b/etmem/src/etmemd_src/etmemd_threadpool.c +index dac42d1..4375ca1 100644 +--- a/etmem/src/etmemd_src/etmemd_threadpool.c ++++ b/etmem/src/etmemd_src/etmemd_threadpool.c +@@ -48,6 +48,7 @@ static void threadpool_cancel_unlock(void *arg) + } + etmemd_log(ETMEMD_LOG_DEBUG, "unlock for threadpool once\n"); + pthread_mutex_unlock(g_pool_lock); ++ g_pool_lock = NULL; + } + + static void *threadpool_routine(void *arg) +diff --git a/etmem/src/etmemd_src/etmemd_threadtimer.c b/etmem/src/etmemd_src/etmemd_threadtimer.c +index d18b3e0..4014c72 100644 +--- a/etmem/src/etmemd_src/etmemd_threadtimer.c ++++ b/etmem/src/etmemd_src/etmemd_threadtimer.c +@@ -37,7 +37,11 @@ static void *thread_timer_routine(void *arg) + + expired_time = timer->expired_time; + +- pthread_cleanup_push(threadtimer_cancel_unlock, &timer->cond_mutex); ++ if (pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL) != 0) { ++ etmemd_log(ETMEMD_LOG_ERR, "failed to set pthread cancel state.\n"); ++ return NULL; ++ } ++ + pthread_mutex_lock(&timer->cond_mutex); + while (!timer->down) { + if (clock_gettime(CLOCK_MONOTONIC, ×pec) != 0) { +@@ -60,9 +64,12 @@ static void *thread_timer_routine(void *arg) + break; + } + } +- /* unlock th timer->cond_mutex */ +- pthread_cleanup_pop(1); ++ threadtimer_cancel_unlock(&timer->cond_mutex); + ++ if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0) { ++ etmemd_log(ETMEMD_LOG_DEBUG, "pthread_setcancelstate PTHREAD_CANCEL_ENABLE failed.\n"); ++ } ++ pthread_testcancel(); + pthread_exit(NULL); + } + +-- +2.33.0 + diff --git a/0004-etmem-fix-multiple-etmemd-and-too-many-err-log-probl.patch b/0004-etmem-fix-multiple-etmemd-and-too-many-err-log-probl.patch new file mode 100644 index 0000000000000000000000000000000000000000..251dc16ef10dc07912b4a448f70bffd799655349 --- /dev/null +++ b/0004-etmem-fix-multiple-etmemd-and-too-many-err-log-probl.patch @@ -0,0 +1,74 @@ +From 5ca2bdd61980b8cf501bc9397611260f4745a7e6 Mon Sep 17 00:00:00 2001 +From: liubo +Date: Tue, 6 Jun 2023 21:14:35 +0800 +Subject: [PATCH 4/4] etmem: fix multiple etmemd and too many err log problem + +1. the etmem uses the fork and exec mode to run the +feature command to botain the corresponding process information. + +If the cmd does not exist, the fork subprocess may not +exit, but the parent process is suspended. +As a result, new etmemd processes are continuously started. + +Signed-off-by: liubo +--- + etmem/src/etmemd_src/etmemd_task.c | 21 ++++++++++++++++----- + 1 file changed, 16 insertions(+), 5 deletions(-) + +diff --git a/etmem/src/etmemd_src/etmemd_task.c b/etmem/src/etmemd_src/etmemd_task.c +index dfe911f..a50c78d 100644 +--- a/etmem/src/etmemd_src/etmemd_task.c ++++ b/etmem/src/etmemd_src/etmemd_task.c +@@ -48,26 +48,33 @@ static int get_pid_through_pipe(char *arg_pid[], const int *pipefd) + if (stdout_copy_fd < 0) { + etmemd_log(ETMEMD_LOG_ERR, "dup(STDOUT_FILENO) fail.\n"); + close(pipefd[1]); +- return -1; ++ exit(SIGPIPE); + } + + ret = dup2(pipefd[1], fileno(stdout)); + if (ret == -1) { + etmemd_log(ETMEMD_LOG_ERR, "dup2 pipefd fail.\n"); + close(pipefd[1]); +- return -1; ++ exit(SIGPIPE); ++ } ++ ++ ret = dup2(pipefd[1], fileno(stderr)); ++ if (ret == -1) { ++ etmemd_log(ETMEMD_LOG_ERR, "dup2 piped fail.\n"); ++ close(pipefd[1]); ++ exit(SIGPIPE); + } + + if (execve(arg_pid[0], arg_pid, NULL) == -1) { + etmemd_log(ETMEMD_LOG_ERR, "execve %s fail with %s.\n", arg_pid[0], strerror(errno)); + close(pipefd[1]); +- return -1; ++ exit(SIGPIPE); + } + +- if (fflush(stdout) != 0) { ++ if (fflush(stdout) != 0 || fflush(stderr) != 0) { + etmemd_log(ETMEMD_LOG_ERR, "fflush execve stdout fail.\n"); + close(pipefd[1]); +- return -1; ++ exit(SIGPIPE); + } + close(pipefd[1]); + dup2(stdout_copy_fd, fileno(stdout)); +@@ -75,6 +82,10 @@ static int get_pid_through_pipe(char *arg_pid[], const int *pipefd) + + /* wait for execve done */ + wait(&status); ++ if ((WIFEXITED(status) && WEXITSTATUS(status) == SIGPIPE) || ++ !WIFEXITED(status)) { ++ return -1; ++ } + + return 0; + } +-- +2.33.0 + diff --git a/etmem.spec b/etmem.spec index c601ffe51145f0710901932f49bd2ca31b6fa13d..1fb175741fa3927b40d387fc63adc657034c575d 100644 --- a/etmem.spec +++ b/etmem.spec @@ -2,12 +2,17 @@ Name: etmem Version: 1.1 -Release: 3 +Release: 4 Summary: etmem License: MulanPSL-2.0 URL: https://gitee.com/openeuler/etmem Source0: https://gitee.com/openeuler/etmem/repository/archive/%{version}.tar.gz + Patch0000: 0001-etmem-1.1-add-loongarch64-support.patch +Patch0001: 0002-etmem-remove-unnecessary-log-code.patch +Patch0002: 0003-etmem-fix-memory-leak-and-fd-leak.patch +Patch0003: 0004-etmem-fix-multiple-etmemd-and-too-many-err-log-probl.patch + #Dependency BuildRequires: cmake gcc gcc-c++ glib2-devel BuildRequires: libboundscheck numactl-devel libcap-devel json-c-devel @@ -60,6 +65,9 @@ install -m 0644 userswap/include/uswap_api.h $RPM_BUILD_ROOT%{_includedir} %postun -p /sbin/ldconfig %changelog +* Thu Jun 8 2023 liubo 1.1-4 +- backport bugfix patch from upstream + * Thu Mar 16 2023 liubo 1.1-3 - update the README file.