From 4636a429195371f95c43b93b54c8d3c1923a5a41 Mon Sep 17 00:00:00 2001 From: liubo Date: Sun, 29 Jan 2023 10:23:09 +0800 Subject: [PATCH] etmem: upgrade etmem version to 1.1 upgrade etmem version to 1.1 and incorporate the previous patch. Signed-off-by: liubo --- 0001-fix-64K-pagesize-scan-problem.patch | 109 - 0002-change-aarch64-march-to-armv8-a.patch | 39 - 0003-update-README.md.patch | 82 - 0004-add-cslide-for-etmem.patch | 6484 ----------------- 0005-fix-code-check-problems.patch | 256 - 0006-remove-unused-share-vmas-merge.patch | 240 - ...ix-error-when-open-idle_pages-failed.patch | 52 - 0008-fix-memleak.patch | 134 - ...at-occur-when-execute-obj-add-or-del.patch | 56 - 0010-clean-code.patch | 334 - ...riod-when-error-occurs-in-this-perio.patch | 111 - ...dd-recursive-in-etmemd_get_task_pids.patch | 110 - ...mission-according-cmd-to-be-executed.patch | 130 - ...y-only-replace-cold-mem-in-hot-nodes.patch | 300 - ...t-mig_quota-hot_reserve-to-0-INT_MAX.patch | 41 - 0016-add-some-dfx-info.patch | 122 - ...rocess-when-failed-to-delete-any-obj.patch | 73 - 0018-fix-code-check-warnning.patch | 41 - 0019-accept-review-advise.patch | 78 - 0020-revert-socket-permission-check.patch | 133 - 0021-add-thirdpart-engine.patch | 549 -- ...s-for-user-defined-thirdparty-engine.patch | 321 - 0023-accept-review-advise.patch | 95 - 0024-correct-etmemd-name.patch | 194 - ...rt-for-systemctl-mode-to-start-etmem.patch | 243 - 0026-add-scan-library.patch | 524 -- ...t-to-ignore-host-access-when-scan-vm.patch | 72 - 0028-openlog-with-same-ident.patch | 41 - 0029-accept-advise.patch | 139 - 0030-notify-rpc-success-with-finish-tag.patch | 157 - 0031-remove-node_watermark.patch | 131 - 0032-print-all-log-to-stdout.patch | 80 - 0033-accept-review-advise.patch | 49 - 0034-fix-open-swap_pages-failure.patch | 48 - ...e-the-correct-example-of-config-file.patch | 85 - ...if-start_task-is-NULL-before-call-it.patch | 26 - ...ct-max_threads-when-max_threads-is-0.patch | 26 - 0038-fix-etmem-help-return-error.patch | 25 - ...f-eng_mgt_func-is-NULL-before-use-it.patch | 30 - 0040-make-code-clean-for-etmem.patch | 302 - ...ror-if-migrate-failed-and-clean-code.patch | 64 - 0042-etmemd-fix-memleak-and-clean-code.patch | 59 - 0043-update-README.md.patch | 575 -- 0044-etmem-cleancode.patch | 55 - 0045-add-dram_percent-to-etmem.patch | 520 -- 0046-Fix-memory-leak-in-slide-engine.patch | 52 - ...-the-files-to-sub-directory-of-etmem.patch | 335 - ...ures-memRouter-and-userswap-to-etmem.patch | 3286 --------- 0049-Add-engine-memdcd-to-etmemd.patch | 481 -- ...ists.txt-for-three-features-of-etmem.patch | 39 - 0051-update-memdcd-engine-for-userswap.patch | 99 - 0052-etmem-correct-example-config-file.patch | 38 - 0053-etmem-split-example_conf.yaml.patch | 167 - 0054-add-License-in-memRouter.patch | 146 - ...f-testcase-for-etmem-common-function.patch | 698 -- ...-testcase-for-etmem-project-function.patch | 523 -- 0057-add-test-for-export-scan.patch | 439 -- ...f-testcase-for-etmem-common-function.patch | 1436 ---- ...d-code-of-testcase-for-etmem-log-ops.patch | 253 - ...dd-make-install-support-to-CMakeList.patch | 29 - 0061-add-region-scan.patch | 1315 ---- 0062-fix-etmem-build-problem.patch | 58 - 0063-etmem-add-code-of-testcase.patch | 864 --- 0064-etmem-add-code-of-testcase.patch | 1202 --- 0065-etmem-add-code-of-testcase.patch | 682 -- ..._threshold-and-swap_threshold-parame.patch | 415 -- ...etmem-add-swapcache-reclaim-to-etmem.patch | 552 -- ...lag-to-support-specified-page-swap-o.patch | 434 -- ...apcache-wmark-configuration-parse-er.patch | 93 - 0070-etmem-update-README.md.patch | 108 - 0071-etmem-add-code-of-testcase.patch | 520 -- 0072-etmem-add-code-of-testcase.patch | 1040 --- 0073-etmem-add-testcode-script.patch | 308 - 0074-etmem-add-code-of-testcase.patch | 2375 ------ 0075-etmem-testcode-adaptation.patch | 378 - ..._threshold-range-to-avoid-overflow-a.patch | 87 - ...oblem-of-libso-no-permission-verific.patch | 136 - ...mem-add-config-file-permission-check.patch | 103 - ...m-fix-problem-of-abnormal-task-value.patch | 132 - 0080-etmem-remove-useless-dt-test-code.patch | 97 - 0081-etmem-Fix-help-command.patch | 46 - ...tmem-project-License-and-notice-file.patch | 304 - 0083-etmem-fix-memory-leak.patch | 51 - ...dd-dt-test-code-for-permission-check.patch | 197 - 1.0.tar.gz | Bin 39817 -> 0 bytes 1.1.tar.gz | Bin 0 -> 136498 bytes etmem.spec | 92 +- 87 files changed, 5 insertions(+), 32940 deletions(-) delete mode 100644 0001-fix-64K-pagesize-scan-problem.patch delete mode 100644 0002-change-aarch64-march-to-armv8-a.patch delete mode 100644 0003-update-README.md.patch delete mode 100644 0004-add-cslide-for-etmem.patch delete mode 100644 0005-fix-code-check-problems.patch delete mode 100644 0006-remove-unused-share-vmas-merge.patch delete mode 100644 0007-fix-error-when-open-idle_pages-failed.patch delete mode 100644 0008-fix-memleak.patch delete mode 100644 0009-fix-some-bugs-that-occur-when-execute-obj-add-or-del.patch delete mode 100644 0010-clean-code.patch delete mode 100644 0011-wait-for-next-period-when-error-occurs-in-this-perio.patch delete mode 100644 0012-add-recursive-in-etmemd_get_task_pids.patch delete mode 100644 0013-check-permission-according-cmd-to-be-executed.patch delete mode 100644 0014-stat-pages-info-early-only-replace-cold-mem-in-hot-nodes.patch delete mode 100644 0015-limit-mig_quota-hot_reserve-to-0-INT_MAX.patch delete mode 100644 0016-add-some-dfx-info.patch delete mode 100644 0017-do-not-stop-the-process-when-failed-to-delete-any-obj.patch delete mode 100644 0018-fix-code-check-warnning.patch delete mode 100644 0019-accept-review-advise.patch delete mode 100644 0020-revert-socket-permission-check.patch delete mode 100644 0021-add-thirdpart-engine.patch delete mode 100644 0022-export-symbols-for-user-defined-thirdparty-engine.patch delete mode 100644 0023-accept-review-advise.patch delete mode 100644 0024-correct-etmemd-name.patch delete mode 100644 0025-add-support-for-systemctl-mode-to-start-etmem.patch delete mode 100644 0026-add-scan-library.patch delete mode 100644 0027-add-ign_host-to-ignore-host-access-when-scan-vm.patch delete mode 100644 0028-openlog-with-same-ident.patch delete mode 100644 0029-accept-advise.patch delete mode 100644 0030-notify-rpc-success-with-finish-tag.patch delete mode 100644 0031-remove-node_watermark.patch delete mode 100644 0032-print-all-log-to-stdout.patch delete mode 100644 0033-accept-review-advise.patch delete mode 100644 0034-fix-open-swap_pages-failure.patch delete mode 100644 0035-give-the-correct-example-of-config-file.patch delete mode 100644 0036-check-if-start_task-is-NULL-before-call-it.patch delete mode 100644 0037-correct-max_threads-when-max_threads-is-0.patch delete mode 100644 0038-fix-etmem-help-return-error.patch delete mode 100644 0039-check-if-eng_mgt_func-is-NULL-before-use-it.patch delete mode 100644 0040-make-code-clean-for-etmem.patch delete mode 100644 0041-return-error-if-migrate-failed-and-clean-code.patch delete mode 100644 0042-etmemd-fix-memleak-and-clean-code.patch delete mode 100644 0043-update-README.md.patch delete mode 100644 0044-etmem-cleancode.patch delete mode 100644 0045-add-dram_percent-to-etmem.patch delete mode 100644 0046-Fix-memory-leak-in-slide-engine.patch delete mode 100644 0047-move-all-the-files-to-sub-directory-of-etmem.patch delete mode 100644 0048-Commit-new-features-memRouter-and-userswap-to-etmem.patch delete mode 100644 0049-Add-engine-memdcd-to-etmemd.patch delete mode 100644 0050-Add-CMakeLists.txt-for-three-features-of-etmem.patch delete mode 100644 0051-update-memdcd-engine-for-userswap.patch delete mode 100644 0052-etmem-correct-example-config-file.patch delete mode 100644 0053-etmem-split-example_conf.yaml.patch delete mode 100644 0054-add-License-in-memRouter.patch delete mode 100644 0055-add-code-of-testcase-for-etmem-common-function.patch delete mode 100644 0056-add-code-of-testcase-for-etmem-project-function.patch delete mode 100644 0057-add-test-for-export-scan.patch delete mode 100644 0058-add-code-of-testcase-for-etmem-common-function.patch delete mode 100644 0059-add-code-of-testcase-for-etmem-log-ops.patch delete mode 100644 0060-add-make-install-support-to-CMakeList.patch delete mode 100644 0061-add-region-scan.patch delete mode 100644 0062-fix-etmem-build-problem.patch delete mode 100644 0063-etmem-add-code-of-testcase.patch delete mode 100644 0064-etmem-add-code-of-testcase.patch delete mode 100644 0065-etmem-add-code-of-testcase.patch delete mode 100644 0066-etmem-add-sysmem_threshold-and-swap_threshold-parame.patch delete mode 100644 0067-etmem-add-swapcache-reclaim-to-etmem.patch delete mode 100644 0068-etmem-add-swap-flag-to-support-specified-page-swap-o.patch delete mode 100644 0069-etmem-fix-the-swapcache-wmark-configuration-parse-er.patch delete mode 100644 0070-etmem-update-README.md.patch delete mode 100644 0071-etmem-add-code-of-testcase.patch delete mode 100644 0072-etmem-add-code-of-testcase.patch delete mode 100644 0073-etmem-add-testcode-script.patch delete mode 100644 0074-etmem-add-code-of-testcase.patch delete mode 100644 0075-etmem-testcode-adaptation.patch delete mode 100644 0076-cslide-limit-hot_threshold-range-to-avoid-overflow-a.patch delete mode 100644 0077-etmem-fix-the-problem-of-libso-no-permission-verific.patch delete mode 100644 0078-etmem-add-config-file-permission-check.patch delete mode 100644 0079-etmem-fix-problem-of-abnormal-task-value.patch delete mode 100644 0080-etmem-remove-useless-dt-test-code.patch delete mode 100644 0081-etmem-Fix-help-command.patch delete mode 100644 0082-etmem-add-etmem-project-License-and-notice-file.patch delete mode 100644 0083-etmem-fix-memory-leak.patch delete mode 100644 0084-etmem-add-dt-test-code-for-permission-check.patch delete mode 100644 1.0.tar.gz create mode 100644 1.1.tar.gz diff --git a/0001-fix-64K-pagesize-scan-problem.patch b/0001-fix-64K-pagesize-scan-problem.patch deleted file mode 100644 index 8c389d1..0000000 --- a/0001-fix-64K-pagesize-scan-problem.patch +++ /dev/null @@ -1,109 +0,0 @@ -From b5543c083777aa5d75d6b240b718f8c6be2def12 Mon Sep 17 00:00:00 2001 -From: liubo -Date: Thu, 18 Mar 2021 15:13:22 +0800 -Subject: [PATCH] fix 64K pagesize scan problem - -Signed-off-by: liubo ---- - inc/etmemd_inc/etmemd_scan.h | 1 + - src/etmemd_src/etmemd.c | 5 +++++ - src/etmemd_src/etmemd_scan.c | 38 ++++++++++++++++++++++++++++++++++++-- - 3 files changed, 42 insertions(+), 2 deletions(-) - -diff --git a/inc/etmemd_inc/etmemd_scan.h b/inc/etmemd_inc/etmemd_scan.h -index dbb6f70..9ae387e 100644 ---- a/inc/etmemd_inc/etmemd_scan.h -+++ b/inc/etmemd_inc/etmemd_scan.h -@@ -109,4 +109,5 @@ void clean_page_refs_unexpected(void *arg); - void clean_memory_grade_unexpected(void *arg); - - struct page_refs *add_page_refs_into_memory_grade(struct page_refs *page_refs, struct page_refs **list); -+int init_g_page_size(void); - #endif -diff --git a/src/etmemd_src/etmemd.c b/src/etmemd_src/etmemd.c -index 6670197..d99b7c8 100644 ---- a/src/etmemd_src/etmemd.c -+++ b/src/etmemd_src/etmemd.c -@@ -20,6 +20,7 @@ - #include "etmemd_rpc.h" - #include "etmemd_common.h" - #include "etmemd_project.h" -+#include "etmemd_scan.h" - - int main(int argc, char *argv[]) - { -@@ -35,6 +36,10 @@ int main(int argc, char *argv[]) - return 0; - } - -+ if (init_g_page_size() == -1) { -+ return -1; -+ } -+ - etmemd_handle_signal(); - if (etmemd_rpc_server() != 0) { - printf("fail to start rpc server of etmemd\n"); -diff --git a/src/etmemd_src/etmemd_scan.c b/src/etmemd_src/etmemd_scan.c -index 8617e8f..d67c940 100644 ---- a/src/etmemd_src/etmemd_scan.c -+++ b/src/etmemd_src/etmemd_scan.c -@@ -45,12 +45,46 @@ static const enum page_type g_page_type_by_idle_kind[] = { - PAGE_TYPE_INVAL, - }; - --static const u_int64_t g_page_size[PAGE_TYPE_INVAL] = { -+static u_int64_t g_page_size[PAGE_TYPE_INVAL] = { - 1UL << PTE_SIZE_SHIFT, /* PTE size */ - 1UL << PMD_SIZE_SHIFT, /* PMD size */ - 1UL << PUD_SIZE_SHIFT, /* PUD size */ - }; - -+static unsigned int get_page_shift(long pagesize) -+{ -+ unsigned int page_shift = 0; -+ pagesize = pagesize >> 1; -+ while (pagesize != 0) { -+ page_shift++; -+ pagesize = pagesize >> 1; -+ } -+ -+ return page_shift; -+} -+ -+int init_g_page_size(void) -+{ -+ unsigned int page_shift; -+ long pagesize = -1; -+ -+ pagesize = sysconf(_SC_PAGESIZE); -+ if (pagesize == -1) { -+ etmemd_log(ETMEMD_LOG_ERR, "get pagesize fail, error: %d\n", errno); -+ return -1; -+ } -+ -+ /* In the x86 architecture, the pagesize is 4kB. In the arm64 architecture, -+ * the pagesize is 4KB, 16KB, 64KB. Therefore, the pagesize in different -+ * scenarios is calculated as follows: */ -+ page_shift = get_page_shift(pagesize); -+ g_page_size[PTE_TYPE] = 1 << page_shift; /* PTE_SIZE */ -+ g_page_size[PMD_TYPE] = 1 << (((page_shift - 3) * (4 - 2)) + 3); /* PMD_SIZE = (page_shift - 3) * (4 - 2) + 3 */ -+ g_page_size[PUD_TYPE] = 1 << (((page_shift - 3) * (4 - 1)) + 3); /* PUD_SIZE = (page_shift - 3) * (4 - 1) + 3 */ -+ -+ return 0; -+} -+ - static bool is_anonymous(const struct vma *vma) - { - if (vma->stat[VMA_STAT_MAY_SHARE] || vma->stat[VMA_STAT_EXEC]) { -@@ -470,7 +504,7 @@ static struct page_refs **walk_vmas(int fd, - - /* we make the buffer size as fitable as within a vma. - * because the size of buffer passed to kernel will be calculated again (<< (3 + PAGE_SHIFT)) */ -- size = (walk_address->walk_end - walk_address->walk_start) >> (3 + PAGE_SHIFT); -+ size = ((walk_address->walk_end - walk_address->walk_start) >> 3) / g_page_size[PTE_TYPE]; - - /* we need to compare the size to the minimum size that kernel handled */ - size = size < EPT_IDLE_BUF_MIN ? EPT_IDLE_BUF_MIN : size; --- -1.8.3.1 - diff --git a/0002-change-aarch64-march-to-armv8-a.patch b/0002-change-aarch64-march-to-armv8-a.patch deleted file mode 100644 index 18a7695..0000000 --- a/0002-change-aarch64-march-to-armv8-a.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 4ea1e7293c73143cc60a0d90bc16dfea4ebb7770 Mon Sep 17 00:00:00 2001 -From: sunshihao -Date: Sat, 20 Mar 2021 18:14:42 +0800 -Subject: [PATCH] change aarch64 march to armv8-a - -The atomic operation is used in the etmem code, -If the compiler instruction set is higher than the -executor instruction set, the etmemd process will crash. - -Signed-off-by: liubo ---- - CMakeLists.txt | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index c3064f7..a4a83ca 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -71,7 +71,7 @@ set_target_properties(etmemd PROPERTIES LINK_FLAGS "-s -fPIE -pie -fPIC -Wl,-z,r - target_link_libraries(etmemd PRIVATE pthread dl rt boundscheck) - - if( ${ARCHITECTURE} STREQUAL "aarch64" ) -- target_compile_options(etmemd PRIVATE -march=native) -+ target_compile_options(etmemd PRIVATE -march=armv8-a) - else() - target_compile_options(etmemd PRIVATE -march=core-avx-i -m64) - endif() -@@ -86,7 +86,7 @@ set_target_properties(etmem PROPERTIES LINK_FLAGS "-s -fPIE -pie -fPIC -Wl,-z,re - target_link_libraries(etmem PRIVATE pthread dl rt boundscheck) - - if( ${ARCHITECTURE} STREQUAL "aarch64" ) -- target_compile_options(etmem PRIVATE -march=native) -+ target_compile_options(etmem PRIVATE -march=armv8-a) - else() - target_compile_options(etmem PRIVATE -march=core-avx-i -m64) - endif() --- -1.8.3.1 - diff --git a/0003-update-README.md.patch b/0003-update-README.md.patch deleted file mode 100644 index 0df3bd4..0000000 --- a/0003-update-README.md.patch +++ /dev/null @@ -1,82 +0,0 @@ -From a8620c7e4e5ddb1123e97ed10c2f1bc0a6684d0d Mon Sep 17 00:00:00 2001 -From: louhongxiang -Date: Fri, 2 Apr 2021 11:29:02 +0800 -Subject: [PATCH 03/50] update README.md. - ---- - README.md | 21 ++++++++++++--------- - 1 file changed, 12 insertions(+), 9 deletions(-) - -diff --git a/README.md b/README.md -index 54e28f9..3e2a50a 100644 ---- a/README.md -+++ b/README.md -@@ -4,15 +4,19 @@ - - 随着CPU算力的发展,尤其是ARM核成本的降低,内存成本和内存容量成为约束业务成本和性能的核心痛点,因此如何节省内存成本,如何扩大内存容量成为存储迫切要解决的问题。 - --etmem内存垂直扩展技术,通过DRAM+内存压缩/高性能存储新介质形成多级内存存储,对内存数据进行分级,将分级后的内存冷数据从内存介质迁移到高性能存储介质中,达到内存容量扩展的目的,从而实现内存成本下降。 -+etmem内存分级扩展技术,通过DRAM+内存压缩/高性能存储新介质形成多级内存存储,对内存数据进行分级,将分级后的内存冷数据从内存介质迁移到高性能存储介质中,达到内存容量扩展的目的,从而实现内存成本下降。 - --## 安装教程 -+## 编译教程 - - 1. 下载etmem源码 - -- $ git clone https://gitee.com/src-openeuler/etmem.git -+ $ git clone https://gitee.com/openeuler/etmem.git - --2. 编译安装 -+2. 编译和运行依赖 -+ -+ etmem的编译和运行依赖于libboundscheck组件 -+ -+3. 编译 - - $ cd etmem - -@@ -24,7 +28,6 @@ etmem内存垂直扩展技术,通过DRAM+内存压缩/高性能存储新介质 - - $ make - -- $ make install - - ## 使用说明 - -@@ -56,7 +59,7 @@ options: - - 在运行etmem进程之前,需要管理员预先规划哪些进程需要做内存扩展,将进程信息配置到etmem配置文件中,并配置内存扫描的周期、扫描次数、内存冷热阈值等信息。 - --配置文件的示例文件在安装etmem软件包后,放置在/etc/etmem/example_conf.yaml,示例内容为: -+配置文件的示例文件在源码包中,放置在源码根目录的conf/example_conf.yaml,建议在使用时放置在/etc/etmem/目录下,示例内容为: - - ``` - options: -@@ -100,7 +103,7 @@ options: - - #### 使用方法 - --通过etmem二进制执行工程创建/删除/查询操作,前提是服务端已经成功运行,并且配置文件/etc/etmem/example_conf.yaml内容正确。 -+通过etmem二进制执行工程创建/删除/查询操作,前提是服务端已经成功运行,并且配置文件(e.g. /etc/etmem/example_conf.yaml)内容正确。 - - 添加工程: - -@@ -173,7 +176,7 @@ show命令: - - #### 使用方法 - --通过etmem二进制执行任务启动/停止操作,前提是服务端已经成功运行,配置文件/etc/etmem/example_conf.yaml内容正确,且etmem工程已经创建。 -+通过etmem二进制执行任务启动/停止操作,前提是服务端已经成功运行,配置文件(e.g. /etc/etmem/example_conf.yaml)内容正确,且etmem工程已经创建。 - - 启动工程 - -@@ -213,4 +216,4 @@ Usage: - 1. Fork本仓库 - 2. 新建个人分支 - 3. 提交代码 --4. 新建Pull Request -\ No newline at end of file -+4. 新建Pull Request --- -2.27.0 - diff --git a/0004-add-cslide-for-etmem.patch b/0004-add-cslide-for-etmem.patch deleted file mode 100644 index c53718b..0000000 --- a/0004-add-cslide-for-etmem.patch +++ /dev/null @@ -1,6484 +0,0 @@ -From bf17dfb2b372f630f6f8ca1cbf6e6472c30bba46 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Tue, 6 Apr 2021 21:46:25 +0800 -Subject: [PATCH 04/50] add cslide for etmem - -Signed-off-by: Kemeng Shi ---- - CMakeLists.txt | 12 +- - inc/etmem_inc/etmem.h | 3 +- - inc/etmem_inc/etmem_common.h | 5 + - inc/etmem_inc/etmem_engine.h | 20 + - inc/etmem_inc/{etmem_task.h => etmem_obj.h} | 8 +- - inc/etmemd_inc/etmemd.h | 4 + - inc/etmemd_inc/etmemd_common.h | 6 +- - inc/etmemd_inc/etmemd_cslide.h | 23 + - inc/etmemd_inc/etmemd_engine.h | 51 +- - inc/etmemd_inc/etmemd_file.h | 30 +- - inc/etmemd_inc/etmemd_pool_adapter.h | 7 +- - inc/etmemd_inc/etmemd_project.h | 40 +- - inc/etmemd_inc/etmemd_rpc.h | 9 +- - inc/etmemd_inc/etmemd_scan.h | 10 + - inc/etmemd_inc/etmemd_slide.h | 3 +- - inc/etmemd_inc/etmemd_task.h | 17 +- - src/etmem_src/etmem.c | 64 +- - src/etmem_src/etmem_common.c | 18 +- - src/etmem_src/etmem_engine.c | 156 ++ - src/etmem_src/etmem_obj.c | 197 ++ - src/etmem_src/etmem_project.c | 90 +- - src/etmem_src/etmem_rpc.c | 64 +- - src/etmem_src/etmem_task.c | 161 -- - src/etmemd_src/etmemd_common.c | 53 +- - src/etmemd_src/etmemd_cslide.c | 2272 +++++++++++++++++++ - src/etmemd_src/etmemd_engine.c | 86 +- - src/etmemd_src/etmemd_file.c | 438 +--- - src/etmemd_src/etmemd_migrate.c | 2 +- - src/etmemd_src/etmemd_pool_adapter.c | 34 +- - src/etmemd_src/etmemd_project.c | 707 ++++-- - src/etmemd_src/etmemd_rpc.c | 143 +- - src/etmemd_src/etmemd_scan.c | 150 +- - src/etmemd_src/etmemd_slide.c | 186 +- - src/etmemd_src/etmemd_task.c | 146 +- - 34 files changed, 4047 insertions(+), 1168 deletions(-) - create mode 100644 inc/etmem_inc/etmem_engine.h - rename inc/etmem_inc/{etmem_task.h => etmem_obj.h} (89%) - create mode 100644 inc/etmemd_inc/etmemd_cslide.h - create mode 100644 src/etmem_src/etmem_engine.c - create mode 100644 src/etmem_src/etmem_obj.c - delete mode 100644 src/etmem_src/etmem_task.c - create mode 100644 src/etmemd_src/etmemd_cslide.c - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index a4a83ca..fa64b89 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -32,6 +32,7 @@ set(ETMEMD_SRC - ${ETMEMD_SRC_DIR}/etmemd_project.c - ${ETMEMD_SRC_DIR}/etmemd_engine.c - ${ETMEMD_SRC_DIR}/etmemd_slide.c -+ ${ETMEMD_SRC_DIR}/etmemd_cslide.c - ${ETMEMD_SRC_DIR}/etmemd_task.c - ${ETMEMD_SRC_DIR}/etmemd_scan.c - ${ETMEMD_SRC_DIR}/etmemd_threadpool.c -@@ -42,7 +43,8 @@ set(ETMEMD_SRC - set(ETMEM_SRC - ${ETMEM_SRC_DIR}/etmem.c - ${ETMEM_SRC_DIR}/etmem_project.c -- ${ETMEM_SRC_DIR}/etmem_task.c -+ ${ETMEM_SRC_DIR}/etmem_obj.c -+ ${ETMEM_SRC_DIR}/etmem_engine.c - ${ETMEM_SRC_DIR}/etmem_rpc.c - ${ETMEM_SRC_DIR}/etmem_common.c) - -@@ -54,8 +56,12 @@ add_executable(etmem - - set(EXECUTABLE_OUTPUT_PATH ${BUILD_DIR}/bin) - -+include(FindPkgConfig) -+pkg_search_module(GLIB2 REQUIRED glib-2.0) -+ - target_include_directories(etmemd PRIVATE -- ${PROJECT_SOURCE_DIR}/inc/etmemd_inc) -+ ${PROJECT_SOURCE_DIR}/inc/etmemd_inc -+ ${GLIB2_INCLUDE_DIRS}) - - target_include_directories(etmem PRIVATE - ${PROJECT_SOURCE_DIR}/inc/etmem_inc) -@@ -68,7 +74,7 @@ if(CONFIG_DEBUG STREQUAL "y") - endif() - - set_target_properties(etmemd PROPERTIES LINK_FLAGS "-s -fPIE -pie -fPIC -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines") --target_link_libraries(etmemd PRIVATE pthread dl rt boundscheck) -+target_link_libraries(etmemd PRIVATE pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) - - if( ${ARCHITECTURE} STREQUAL "aarch64" ) - target_compile_options(etmemd PRIVATE -march=armv8-a) -diff --git a/inc/etmem_inc/etmem.h b/inc/etmem_inc/etmem.h -index 8d7b615..47979a2 100644 ---- a/inc/etmem_inc/etmem.h -+++ b/inc/etmem_inc/etmem.h -@@ -24,6 +24,7 @@ typedef enum etmem_cmd_e { - ETMEM_CMD_START, - ETMEM_CMD_STOP, - ETMEM_CMD_SHOW, -+ ETMEM_CMD_ENGINE, - ETMEM_CMD_HELP, - } etmem_cmd; - -@@ -37,7 +38,7 @@ struct etmem_conf { - struct etmem_obj { - char *name; - void (*help)(void); -- int (*do_cmd)(const struct etmem_conf *conf); -+ int (*do_cmd)(struct etmem_conf *conf); - - SLIST_ENTRY(etmem_obj) entry; - }; -diff --git a/inc/etmem_inc/etmem_common.h b/inc/etmem_inc/etmem_common.h -index 9725c87..294d216 100644 ---- a/inc/etmem_inc/etmem_common.h -+++ b/inc/etmem_inc/etmem_common.h -@@ -24,11 +24,16 @@ - #define FILE_NAME_MAX_LEN 256 - #define SOCKET_NAME_MAX_LEN 107 - -+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) -+ - struct mem_proj { - etmem_cmd cmd; - char *proj_name; -+ char *eng_name; -+ char *task_name; - char *file_name; - char *sock_name; -+ char *eng_cmd; - }; - - int parse_name_string(const char *val, char **name_str, size_t max_len); -diff --git a/inc/etmem_inc/etmem_engine.h b/inc/etmem_inc/etmem_engine.h -new file mode 100644 -index 0000000..6d1ca14 ---- /dev/null -+++ b/inc/etmem_inc/etmem_engine.h -@@ -0,0 +1,20 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: louhongxiang -+ * Create: 2019-12-10 -+ * Description: This is a header file of the data structure definition for etmem engine function. -+ ******************************************************************************/ -+ -+#ifndef __ETMEM_ENGINE_H__ -+#define __ETMEM_ENGINE_H__ -+void engine_init(void); -+void engine_exit(void); -+#endif -diff --git a/inc/etmem_inc/etmem_task.h b/inc/etmem_inc/etmem_obj.h -similarity index 89% -rename from inc/etmem_inc/etmem_task.h -rename to inc/etmem_inc/etmem_obj.h -index aa8f218..635b6b3 100644 ---- a/inc/etmem_inc/etmem_task.h -+++ b/inc/etmem_inc/etmem_obj.h -@@ -13,10 +13,10 @@ - * Description: This is a header file of the function declaration for migration functions. - ******************************************************************************/ - --#ifndef __ETMEM_TASK_H__ --#define __ETMEM_TASK_H__ -+#ifndef __ETMEM_OBJ_H__ -+#define __ETMEM_OBJ_H__ - --void migrate_init(void); --void migrate_exit(void); -+void obj_init(void); -+void obj_exit(void); - - #endif -diff --git a/inc/etmemd_inc/etmemd.h b/inc/etmemd_inc/etmemd.h -index ed29d44..797049e 100644 ---- a/inc/etmemd_inc/etmemd.h -+++ b/inc/etmemd_inc/etmemd.h -@@ -19,6 +19,10 @@ - #include - #include - -+#define PTE_SIZE_SHIFT 12 -+#define PMD_SIZE_SHIFT 21 -+#define PUD_SIZE_SHIFT 30 -+ - /* - * page type specified by size - * */ -diff --git a/inc/etmemd_inc/etmemd_common.h b/inc/etmemd_inc/etmemd_common.h -index 2fe8a73..1b62bbd 100644 ---- a/inc/etmemd_inc/etmemd_common.h -+++ b/inc/etmemd_inc/etmemd_common.h -@@ -25,6 +25,8 @@ - #define DECIMAL_RADIX 10 - #define ETMEMD_MAX_PARAMETER_NUM 5 - -+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) -+ - /* - * function: parse cmdline passed to etmemd server. - * -@@ -43,7 +45,7 @@ int get_int_value(const char *val, int *value); - int get_unsigned_int_value(const char *val, unsigned int *value); - void etmemd_safe_free(void **ptr); - --FILE *etmemd_get_proc_file(const char *pid, const char *file, const char *mode); -+FILE *etmemd_get_proc_file(const char *pid, const char *file, int flags, const char *mode); - - int get_keyword_and_value(const char *str, char *key, char *val); - -@@ -56,4 +58,6 @@ int get_keyword_and_value(const char *str, char *key, char *val); - * */ - char *skip_blank_line(FILE *file); - -+int dprintf_all(int fd, const char *format, ...); -+ - #endif -diff --git a/inc/etmemd_inc/etmemd_cslide.h b/inc/etmemd_inc/etmemd_cslide.h -new file mode 100644 -index 0000000..2405f2d ---- /dev/null -+++ b/inc/etmemd_inc/etmemd_cslide.h -@@ -0,0 +1,23 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: louhongxiang -+ * Create: 2019-12-10 -+ * Description: This is a header file of the function declaration for cslide function. -+ ******************************************************************************/ -+ -+#ifndef ETMEMD_CSLIDE_H -+#define ETMEMD_CSLIDE_H -+ -+#include "etmemd_engine.h" -+ -+int fill_engine_type_cslide(struct engine *eng); -+ -+#endif -diff --git a/inc/etmemd_inc/etmemd_engine.h b/inc/etmemd_inc/etmemd_engine.h -index 13d676c..77916a5 100644 ---- a/inc/etmemd_inc/etmemd_engine.h -+++ b/inc/etmemd_inc/etmemd_engine.h -@@ -16,11 +16,13 @@ - #ifndef ETMEMD_ENGINE_H - #define ETMEMD_ENGINE_H - -+#include - #include "etmemd.h" - #include "etmemd_task.h" - - enum eng_type { - SLIDE_ENGINE = 0, -+ CSLIDE_ENGINE, - DYNAMIC_FB_ENGINE, - HISTORICAL_FB_ENGINE, - THIRDPARTY_ENGINE, -@@ -32,44 +34,29 @@ enum eng_type { - * */ - struct engine { - int engine_type; /* engine type used for elimination strategy */ -+ char *name; - void *params; /* point to engine parameter struct */ -- void *task; /* point to task this engine belongs to */ -+ struct project *proj; - struct page_refs *page_ref; /* scan result */ -+ struct engine_ops *ops; -+ struct task *tasks; - uint64_t page_cnt; /* number of pages */ -- struct adapter *adp; /* configured migration strategy */ -- -- /* parse parameter configuration */ -- int (*parse_param_conf)(struct engine *eng, FILE *file); -- -- /* migrate policy function */ -- struct memory_grade *(*mig_policy_func)(struct page_refs **page_refs, void *params); -- -- /* alloc tkpid params space based on different policies. */ -- int (*alloc_params)(struct task_pid **tk_pid); --}; -- --/* -- * adapter struct -- * */ --struct adapter { -- /* scan function */ -- struct page_refs *(*do_scan)(const struct task_pid *tpid, const struct task *tk); -- -- /* migrate function */ -- int (*do_migrate)(unsigned int pid, const struct memory_grade *memory_grade); --}; -- --struct engine_item { -- enum eng_type eng_type; -- int (*fill_eng_func)(struct engine *eng); -+ struct engine *next; - }; - --struct engine_private_item { -- char *priv_sec_name; -- int (*fill_eng_private_func)(const struct engine *eng, const char *val); -+struct engine_ops { -+ int (*fill_eng_params)(GKeyFile *config, struct engine *eng); -+ void (*clear_eng_params)(struct engine *eng); -+ int (*fill_task_params)(GKeyFile *config, struct task *task); -+ void (*clear_task_params)(struct task *tk); -+ int (*start_task)(struct engine *eng, struct task *tk); -+ void (*stop_task)(struct engine *eng, struct task *tk); -+ int (*alloc_pid_params)(struct engine *eng, struct task_pid **tk_pid); -+ void (*free_pid_params)(struct engine *eng, struct task_pid **tk_pid); -+ int (*eng_mgt_func)(struct engine *eng, struct task *tk, char *cmd, int fd); - }; - --const char *etmemd_get_eng_name(enum eng_type type); -+struct engine *etmemd_engine_add(GKeyFile *config); -+void etmemd_engine_remove(struct engine *eng); - --int fill_engine_type(struct engine *eng, const char *val); - #endif -diff --git a/inc/etmemd_inc/etmemd_file.h b/inc/etmemd_inc/etmemd_file.h -index a251d1b..34ccaf9 100644 ---- a/inc/etmemd_inc/etmemd_file.h -+++ b/inc/etmemd_inc/etmemd_file.h -@@ -17,23 +17,31 @@ - #define ETMEMD_FILE_H - - #include -+#include - #include "etmemd_project.h" - #include "etmemd_task.h" - --struct project_item { -- char *proj_sec_name; -- int (*fill_proj_func)(struct project *proj, const char *val); -- bool optional; -- bool set; -+#define PROJ_GROUP "project" -+#define ENG_GROUP "engine" -+#define TASK_GROUP "task" -+ -+enum val_type { -+ INT_VAL, -+ STR_VAL, - }; - --struct task_item { -- char *task_sec_name; -- int (*fill_task_func)(struct task *tk, const char *val); -- bool optional; -- bool set; -+struct config_item { -+ char *key; -+ enum val_type type; -+ int (*fill)(void *obj, void *val); -+ bool option; - }; - --int etmemd_fill_proj_by_conf(struct project *proj, FILE *conf_file); -+int parse_file_config(GKeyFile *config, char *group_name, struct config_item *items, unsigned n, void *obj); -+ -+static inline int parse_to_int(void *val) -+{ -+ return (int)(long long)val; -+} - - #endif -diff --git a/inc/etmemd_inc/etmemd_pool_adapter.h b/inc/etmemd_inc/etmemd_pool_adapter.h -index 7448b50..3cb7b2a 100644 ---- a/inc/etmemd_inc/etmemd_pool_adapter.h -+++ b/inc/etmemd_inc/etmemd_pool_adapter.h -@@ -21,10 +21,15 @@ - #include "etmemd_project.h" - #include "etmemd_log.h" - -+struct task_executor { -+ struct task *tk; -+ void *(*func)(void *arg); -+}; -+ - /* - * Start process scanning and memory migration - * */ --int start_threadpool_work(struct task *tk); -+int start_threadpool_work(struct task_executor *executor); - - /* - * Stop process and cleanup resource of scanning and memory migration -diff --git a/inc/etmemd_inc/etmemd_project.h b/inc/etmemd_inc/etmemd_project.h -index da929b4..d15c7fd 100644 ---- a/inc/etmemd_inc/etmemd_project.h -+++ b/inc/etmemd_inc/etmemd_project.h -@@ -18,6 +18,7 @@ - - #include - #include "etmemd_task.h" -+#include "etmemd_engine.h" - - /* set the length of project name to 32 */ - #define PROJECT_NAME_MAX_LEN 32 -@@ -25,12 +26,12 @@ - #define PROJECT_SHOW_COLM_MAX 128 - - struct project { -- bool start; -+ char *name; - int interval; - int loop; - int sleep; -- char *name; -- struct task *tasks; -+ bool start; -+ struct engine *engs; - - SLIST_ENTRY(project) entry; - }; -@@ -42,6 +43,10 @@ enum opt_result { - OPT_PRO_STARTED, - OPT_PRO_STOPPED, - OPT_PRO_NOEXIST, -+ OPT_ENG_EXISTED, -+ OPT_ENG_NOEXIST, -+ OPT_TASK_EXISTED, -+ OPT_TASK_NOEXIST, - OPT_INTER_ERR, - OPT_RET_END, - }; -@@ -49,32 +54,33 @@ enum opt_result { - /* - * function: Add project to etmem server. - * -- * in: const char *project_name - name of the project to be added -- * const char *file_name - name of the project configuration file -+ * in: GKeyFile *config - loaded config file - * -- * out: OPT_SUCCESS(0) - successed to add project -- * other value - failed to add project -+ * out: OPT_SUCCESS(0) - successed to add project -+ * other value - failed to add project - * */ --enum opt_result etmemd_project_add(const char *project_name, const char *file_name); -+enum opt_result etmemd_project_add(GKeyFile *config); - - /* -- * function: Delete given project. -+ * function: Remove given project. - * -- * in: const char *project_name - name of the project to be deleted -+ * in: GKeyFile *config - loaded config file - * -- * out: OPT_SUCCESS(0) - successed to delete project -- * other value - failed to delete project -+ * out: OPT_SUCCESS(0) - successed to delete project -+ * other value - failed to delete project - * */ --enum opt_result etmemd_project_delete(const char *project_name); -+enum opt_result etmemd_project_remove(GKeyFile *config); - - /* - * function: Show all the projects. - * -+ * in: const char *project_name - name of the project to start migrate -+ * int fd - client socket to show projects info - * - * out: OPT_SUCCESS(0) - successed to show all the projects - * other value - failed to show any project - * */ --enum opt_result etmemd_project_show(void); -+enum opt_result etmemd_project_show(const char *project_name, int fd); - - /* - * function: Start migrate in given project. -@@ -96,6 +102,12 @@ enum opt_result etmemd_migrate_start(const char *project_name); - * */ - enum opt_result etmemd_migrate_stop(const char *project_name); - -+enum opt_result etmemd_project_mgt_engine(const char *project_name, const char *eng_name, char *cmd, char *task_name, int sock_fd); -+enum opt_result etmemd_project_add_engine(GKeyFile *config); -+enum opt_result etmemd_project_remove_engine(GKeyFile *config); -+enum opt_result etmemd_project_add_task(GKeyFile *config); -+enum opt_result etmemd_project_remove_task(GKeyFile *config); -+ - void etmemd_stop_all_projects(void); - - #endif -diff --git a/inc/etmemd_inc/etmemd_rpc.h b/inc/etmemd_inc/etmemd_rpc.h -index ff27494..146cec3 100644 ---- a/inc/etmemd_inc/etmemd_rpc.h -+++ b/inc/etmemd_inc/etmemd_rpc.h -@@ -19,11 +19,12 @@ - #include - - enum cmd_type { -- PROJ_ADD = 0, -- PROJ_DEL, -+ OBJ_ADD = 0, -+ OBJ_DEL, - MIG_START, - MIG_STOP, - PROJ_SHOW, -+ ENG_CMD, - }; - - enum rpc_decode_type { -@@ -36,6 +37,10 @@ struct server_rpc_params { - char *proj_name; - char *file_name; - int cmd; -+ int sock_fd; -+ char *eng_name; -+ char *eng_cmd; -+ char *task_name; - }; - - struct server_rpc_parser { -diff --git a/inc/etmemd_inc/etmemd_scan.h b/inc/etmemd_inc/etmemd_scan.h -index 9ae387e..ed72e1a 100644 ---- a/inc/etmemd_inc/etmemd_scan.h -+++ b/inc/etmemd_inc/etmemd_scan.h -@@ -16,6 +16,7 @@ - #ifndef ETMEMD_SCAN_H - #define ETMEMD_SCAN_H - -+#include - #include "etmemd.h" - #include "etmemd_task.h" - -@@ -31,6 +32,11 @@ - #define MAPS_FILE "/maps" - #define IDLE_SCAN_FILE "/idle_pages" - -+#define SMAPS_FILE "/smaps" -+#define VMFLAG_HEAD "VmFlags" -+ -+#define SCAN_AS_HUGE O_LARGEFILE -+ - enum { - VMA_STAT_READ = 0, - VMA_STAT_WRITE, -@@ -100,8 +106,11 @@ struct page_refs *etmemd_do_scan(const struct task_pid *tpid, const struct task - /* free vma list struct */ - void free_vmas(struct vmas *vmas); - -+struct page_refs **walk_vmas(int fd, struct walk_address *walk_address, struct page_refs **pf, unsigned long *use_rss); - int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **page_refs, unsigned long *use_rss); - -+int split_vmflags(char ***vmflags_array, char *vmflags); -+struct vmas *get_vmas_with_flags(const char *pid, char **vmflags_array, int vmflags_num, bool is_anon_only); - struct vmas *get_vmas(const char *pid); - - void clean_page_refs_unexpected(void *arg); -@@ -110,4 +119,5 @@ void clean_memory_grade_unexpected(void *arg); - - struct page_refs *add_page_refs_into_memory_grade(struct page_refs *page_refs, struct page_refs **list); - int init_g_page_size(void); -+int page_type_to_size(enum page_type type); - #endif -diff --git a/inc/etmemd_inc/etmemd_slide.h b/inc/etmemd_inc/etmemd_slide.h -index e95438d..e76e97a 100644 ---- a/inc/etmemd_inc/etmemd_slide.h -+++ b/inc/etmemd_inc/etmemd_slide.h -@@ -16,10 +16,11 @@ - #ifndef ETMEMD_SLIDE_H - #define ETMEMD_SLIDE_H - -- -+#include "etmemd_pool_adapter.h" - #include "etmemd_engine.h" - - struct slide_params { -+ struct task_executor *executor; - int t; /* watermark */ - }; - -diff --git a/inc/etmemd_inc/etmemd_task.h b/inc/etmemd_inc/etmemd_task.h -index b7fba2b..d6d89ea 100644 ---- a/inc/etmemd_inc/etmemd_task.h -+++ b/inc/etmemd_inc/etmemd_task.h -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include "etmemd_threadpool.h" - #include "etmemd_threadtimer.h" - -@@ -37,20 +38,16 @@ struct task_pid { - struct task { - char *type; - char *value; -+ char *name; - uint64_t max_threads; - -- struct project *proj; -- struct engine *eng; - struct task_pid *pids; -+ struct engine *eng; -+ void *params; - pthread_t task_pt; - timer_thread *timer_inst; - thread_pool *threadpool_inst; - -- int (*start_etmem)(struct task *tk); -- void (*stop_etmem)(struct task *tk); -- void (*delete_etmem)(struct task *tk); -- void *(*workflow_engine)(void *); -- - struct task *next; - }; - -@@ -64,5 +61,9 @@ void etmemd_free_task_struct(struct task **tk); - - void free_task_pid_mem(struct task_pid **tk_pid); - --void etmemd_print_tasks(const struct task *tk); -+void etmemd_print_tasks(int fd, const struct task *tk, char *engine_name, bool started); -+ -+struct task *etmemd_add_task(GKeyFile *config); -+void etmemd_remove_task(struct task *tk); -+ - #endif -diff --git a/src/etmem_src/etmem.c b/src/etmem_src/etmem.c -index 8bd171c..863f91b 100644 ---- a/src/etmem_src/etmem.c -+++ b/src/etmem_src/etmem.c -@@ -19,8 +19,9 @@ - #include - #include "securec.h" - #include "etmem.h" --#include "etmem_task.h" -+#include "etmem_obj.h" - #include "etmem_project.h" -+#include "etmem_engine.h" - - #define CMD_POSITION 1 - -@@ -65,53 +66,10 @@ static int check_param(int argc, char *argv[], struct etmem_conf *conf, - return -1; - } - -- return 0; --} -- --static void fill_cmd_type(struct etmem_conf *conf, const int val) --{ -- conf->cmd = val; --} -- --struct cmd_item { -- char *cmd_name; -- enum etmem_cmd_e cmd; -- void (*fill_cmd_func)(struct etmem_conf *conf, const int val); --}; -- --struct cmd_item g_cmd_items[] = { -- {"add", ETMEM_CMD_ADD, fill_cmd_type}, -- {"del", ETMEM_CMD_DEL, fill_cmd_type}, -- {"start", ETMEM_CMD_START, fill_cmd_type}, -- {"stop", ETMEM_CMD_STOP, fill_cmd_type}, -- {"show", ETMEM_CMD_SHOW, fill_cmd_type}, -- {"help", ETMEM_CMD_HELP, fill_cmd_type}, -- {NULL, 0, NULL}, --}; -- --static int parse_command(int argc, char *argv[], struct etmem_conf *conf, -- const struct etmem_obj *obj) --{ -- int ret = -1; -- int i = 0; -- -- while (g_cmd_items[i].cmd_name != NULL) { -- if (strcmp(argv[CMD_POSITION], g_cmd_items[i].cmd_name) == 0) { -- g_cmd_items[i].fill_cmd_func(conf, (int)g_cmd_items[i].cmd); -- ret = 0; -- break; -- } -- i++; -- } -- -- if (ret != 0) { -- printf("invalid command %s\n", argv[CMD_POSITION]); -- obj->help(); -- return -1; -- } -- -- conf->argc = argc - CMD_POSITION; -- conf->argv = argv + CMD_POSITION; -+ argc--; -+ argv++; -+ conf->argc = argc; -+ conf->argv = argv; - - return 0; - } -@@ -139,7 +97,7 @@ static int parse_args(int argc, char *argv[], struct etmem_conf *conf, - return -EINVAL; - } - -- return parse_command(argc, argv, conf, *obj); -+ return 0; - } - - void etmem_register_obj(struct etmem_obj *obj) -@@ -162,7 +120,8 @@ int main(int argc, char *argv[]) - - SLIST_INIT(&g_etmem_objs); - project_init(); -- migrate_init(); -+ obj_init(); -+ engine_init(); - - if (parse_args(argc, argv, &conf, &obj) != 0) { - if (conf.obj != NULL && strcmp(conf.obj, "help") == 0 && -@@ -173,7 +132,7 @@ int main(int argc, char *argv[]) - goto out; - } - -- if (conf.cmd == ETMEM_CMD_HELP) { -+ if (strcmp(conf.argv[0], "help") == 0) { - obj->help(); - err = 0; - goto out; -@@ -187,7 +146,8 @@ int main(int argc, char *argv[]) - } - - out: -+ engine_exit(); -+ obj_exit(); - project_exit(); -- migrate_exit(); - return err; - } -diff --git a/src/etmem_src/etmem_common.c b/src/etmem_src/etmem_common.c -index 9725db7..65d3690 100644 ---- a/src/etmem_src/etmem_common.c -+++ b/src/etmem_src/etmem_common.c -@@ -60,7 +60,7 @@ int parse_name_string(const char *val, char **name_str, size_t max_len) - int etmem_parse_check_result(int params_cnt, int argc) - { - if (params_cnt > 0 && argc - 1 > params_cnt * 2) { /* maximum number of args is limited to params_cnt * 2+1 */ -- printf("warn: useless parameters passed in\n"); -+ printf("warn: etmem useless parameters passed in\n"); - return -E2BIG; - } - -@@ -83,6 +83,22 @@ void free_proj_member(struct mem_proj *proj) - free(proj->sock_name); - proj->sock_name = NULL; - } -+ -+ if (proj->eng_name != NULL) { -+ free(proj->eng_name); -+ proj->eng_name = NULL; -+ } -+ -+ if (proj->task_name != NULL) { -+ free(proj->task_name); -+ proj->task_name = NULL; -+ } -+ -+ if (proj->eng_cmd != NULL) { -+ free(proj->eng_cmd); -+ proj->eng_cmd = NULL; -+ } -+ - } - - -diff --git a/src/etmem_src/etmem_engine.c b/src/etmem_src/etmem_engine.c -new file mode 100644 -index 0000000..7673205 ---- /dev/null -+++ b/src/etmem_src/etmem_engine.c -@@ -0,0 +1,156 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: louhongxiang -+ * Create: 2021-4-13 -+ * Description: engine operation for etmem client -+ ******************************************************************************/ -+ -+#include -+#include -+#include "etmem_engine.h" -+#include "securec.h" -+#include "etmem.h" -+#include "etmem_common.h" -+#include "etmem_rpc.h" -+ -+static void engine_help(void) -+{ -+ printf("etmem engine help information\n"); -+} -+ -+static int engine_parse_cmd(struct etmem_conf *conf, struct mem_proj *proj) -+{ -+ if (conf->argc == 0) { -+ printf("too few params for etmem client engine command\n"); -+ return -1; -+ } -+ proj->eng_cmd = conf->argv[0]; -+ proj->cmd = ETMEM_CMD_ENGINE; -+ return 0; -+} -+ -+static int engine_parse_args(struct etmem_conf *conf, struct mem_proj *proj) -+{ -+ int opt; -+ int params_cnt = 0; -+ int ret; -+ struct option opts[] = { -+ {"proj_name", required_argument, NULL,'n'}, -+ {"socket", required_argument, NULL,'s'}, -+ {"engine", required_argument, NULL,'e'}, -+ {"task_name", required_argument, NULL,'t'}, -+ {NULL, 0, NULL,0}, -+ }; -+ -+ while ((opt = getopt_long(conf->argc, conf->argv, "n:s:e:t:", opts, NULL)) != -1) { -+ switch (opt) { -+ case 'n': -+ proj->proj_name = optarg; -+ break; -+ -+ case 's': -+ proj->sock_name = optarg; -+ break; -+ -+ case 'e': -+ proj->eng_name = optarg; -+ break; -+ -+ case 't': -+ proj->task_name = optarg; -+ break; -+ -+ case '?': -+ /* fallthrough */ -+ default: -+ printf("invalid options: %s\n", conf->argv[optind]); -+ return -EINVAL; -+ } -+ params_cnt++; -+ -+ } -+ ret = etmem_parse_check_result(params_cnt, conf->argc); -+ return ret; -+} -+ -+static int engine_check_params(struct mem_proj *proj) -+{ -+ if (proj->sock_name == NULL || strlen(proj->sock_name) == 0) { -+ printf("socket name to connect must be given, please check.\n"); -+ return -1; -+ } -+ -+ if (proj->proj_name == NULL || strlen(proj->proj_name) == 0) { -+ printf("project name must be given, please check.\n"); -+ return -1; -+ } -+ -+ if (proj->eng_cmd == NULL || strlen(proj->eng_cmd) == 0) { -+ printf("engine command must be given, please check.\n"); -+ return -1; -+ } -+ -+ if (proj->eng_name == NULL || strlen(proj->eng_name) == 0) { -+ printf("engine name must be given, please check.\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int engine_do_cmd(struct etmem_conf *conf) -+{ -+ struct mem_proj proj; -+ int ret; -+ -+ ret = memset_s(&proj, sizeof(struct mem_proj), 0, sizeof(struct mem_proj)); -+ if (ret != EOK) { -+ printf("memset_s for mem_proj fail\n"); -+ return ret; -+ } -+ -+ ret = engine_parse_cmd(conf, &proj); -+ if (ret != 0) { -+ printf("engine_parse_cmd fail\n"); -+ return -1; -+ } -+ -+ ret = engine_parse_args(conf, &proj); -+ if (ret != 0) { -+ printf("engine_parse_args fail\n"); -+ return -1; -+ } -+ -+ ret = engine_check_params(&proj); -+ if (ret != 0) { -+ printf("engine_check_params fail\n"); -+ return -1; -+ } -+ -+ ret = etmem_rpc_client(&proj); -+ return ret; -+} -+ -+static struct etmem_obj g_etmem_engine = { -+ .name = "engine", -+ .help = engine_help, -+ .do_cmd = engine_do_cmd, -+}; -+ -+void engine_init(void) -+{ -+ etmem_register_obj(&g_etmem_engine); -+} -+ -+void engine_exit(void) -+{ -+ etmem_unregister_obj(&g_etmem_engine); -+} -diff --git a/src/etmem_src/etmem_obj.c b/src/etmem_src/etmem_obj.c -new file mode 100644 -index 0000000..a3f66fe ---- /dev/null -+++ b/src/etmem_src/etmem_obj.c -@@ -0,0 +1,197 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: louhongxiang -+ * Create: 2021-4-14 -+ * Description: etmem obj command API. -+ ******************************************************************************/ -+ -+#include -+#include "securec.h" -+#include "etmem.h" -+#include "etmem_common.h" -+#include "etmem_rpc.h" -+#include "etmem_obj.h" -+ -+static void obj_help(void) -+{ -+ printf("\nUsage:\n" -+ " etmem obj add [options]\n" -+ " etmem obj del [options]\n" -+ " etmem obj help [options]\n" -+ "\nOptions:\n" -+ " -f|--file Add configuration file\n" -+ " -s|--socket Socket name to connect\n" -+ "\nNotes:\n" -+ " 1. Configuration file must be given.\n" -+ " 2. Socket name must be given.\n"); -+} -+ -+struct obj_cmd_item { -+ char *cmd_name; -+ enum etmem_cmd_e cmd; -+}; -+ -+static struct obj_cmd_item g_obj_cmd_items[] = { -+ {"add", ETMEM_CMD_ADD}, -+ {"del", ETMEM_CMD_DEL}, -+}; -+ -+static int obj_parse_cmd(struct etmem_conf *conf, struct mem_proj *proj) -+{ -+ unsigned i; -+ char *cmd = NULL; -+ -+ cmd = conf->argv[0]; -+ for (i = 0; i < ARRAY_SIZE(g_obj_cmd_items); i++) { -+ if (strcmp(cmd, g_obj_cmd_items[i].cmd_name) == 0) { -+ proj->cmd = g_obj_cmd_items[i].cmd; -+ return 0; -+ } -+ } -+ -+ printf("obj cmd %s is not supportted.\n", cmd); -+ return -1; -+} -+ -+static int parse_file_name(const char *val, char **file_name) -+{ -+ size_t len; -+ int ret; -+ -+ len = strlen(val) + 1; -+ if (len > FILE_NAME_MAX_LEN) { -+ printf("file name is too long, should not be larger than %u\n", FILE_NAME_MAX_LEN); -+ return -ENAMETOOLONG; -+ } -+ -+ *file_name = (char *)calloc(len, sizeof(char)); -+ if (*file_name == NULL) { -+ printf("malloc file name failed\n"); -+ return -ENOMEM; -+ } -+ -+ ret = strncpy_s(*file_name, len, val, len - 1); -+ if (ret != EOK) { -+ printf("strncpy_s file name fail\n"); -+ free(*file_name); -+ *file_name = NULL; -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int obj_parse_args(struct etmem_conf *conf, struct mem_proj *proj) -+{ -+ int opt, ret; -+ int params_cnt = 0; -+ struct option opts[] = { -+ {"file", required_argument, NULL, 'f'}, -+ {"socket", required_argument, NULL, 's'}, -+ {NULL, 0, NULL, 0}, -+ }; -+ -+ while ((opt = getopt_long(conf->argc, conf->argv, "f:s:", opts, NULL)) != -1) { -+ switch (opt) { -+ case 'f': -+ ret = parse_file_name(optarg, &proj->file_name); -+ if (ret != 0) { -+ printf("parse file name failed\n"); -+ return ret; -+ } -+ break; -+ case 's': -+ ret = parse_name_string(optarg, &proj->sock_name, SOCKET_NAME_MAX_LEN); -+ if (ret != 0) { -+ printf("parse socket name failed.\n"); -+ return ret; -+ } -+ break; -+ case '?': -+ /* fallthrough */ -+ default: -+ printf("invalid option: %s\n", conf->argv[optind]); -+ return -EINVAL; -+ } -+ params_cnt++; -+ } -+ -+ ret = etmem_parse_check_result(params_cnt, conf->argc); -+ -+ return ret; -+} -+ -+static int obj_check_params(const struct mem_proj *proj) -+{ -+ if (proj->sock_name == NULL || strlen(proj->sock_name) == 0) { -+ printf("socket name to connect must all be given, please check.\n"); -+ return -EINVAL; -+ } -+ -+ if (proj->file_name == NULL || strlen(proj->file_name) == 0) { -+ printf("file name must be given in add command.\n"); -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static int obj_do_cmd(struct etmem_conf *conf) -+{ -+ struct mem_proj proj; -+ int ret; -+ -+ ret = memset_s(&proj, sizeof(struct mem_proj), 0, sizeof(struct mem_proj)); -+ if (ret != EOK) { -+ printf("memset_s for mem_proj failed\n"); -+ return ret; -+ } -+ -+ ret = obj_parse_cmd(conf, &proj); -+ if (ret != 0) { -+ printf("obj_parse_cmd fail\n"); -+ return ret; -+ } -+ -+ ret = obj_parse_args(conf, &proj); -+ if (ret != 0) { -+ printf("obj_parse_args fail\n"); -+ goto EXIT; -+ } -+ -+ ret = obj_check_params(&proj); -+ if (ret != 0) { -+ printf("obj_check_params fail\n"); -+ goto EXIT; -+ } -+ -+ ret = etmem_rpc_client(&proj); -+ -+EXIT: -+ free_proj_member(&proj); -+ return ret; -+} -+ -+static struct etmem_obj g_etmem_obj = { -+ .name = "obj", -+ .help = obj_help, -+ .do_cmd = obj_do_cmd, -+}; -+ -+void obj_init(void) -+{ -+ etmem_register_obj(&g_etmem_obj); -+} -+ -+void obj_exit(void) -+{ -+ etmem_unregister_obj(&g_etmem_obj); -+} -diff --git a/src/etmem_src/etmem_project.c b/src/etmem_src/etmem_project.c -index 85363b0..790979e 100644 ---- a/src/etmem_src/etmem_project.c -+++ b/src/etmem_src/etmem_project.c -@@ -27,65 +27,44 @@ static void project_help(void) - { - fprintf(stderr, - "\nUsage:\n" -- " etmem project add [options]\n" -- " etmem project del [options]\n" -+ " etmem project start [options]\n" -+ " etmem project stop [options]\n" - " etmem project show [options]\n" - " etmem project help\n" - "\nOptions:\n" -- " -f|--file Add configuration file\n" - " -n|--name Add project name\n" - " -s|--socket Socket name to connect\n" - "\nNotes:\n" - " 1. Project name and socket name must be given when execute add or del option.\n" -- " 2. Configuration file must be given when execute add option.\n" -- " 3. Socket name must be given when execute show option.\n"); -+ " 2. Socket name must be given when execute show option.\n"); - } - --static int project_parse_cmd(const struct etmem_conf *conf, struct mem_proj *proj) --{ -- switch (conf->cmd) { -- case ETMEM_CMD_ADD: -- /* fallthrough */ -- case ETMEM_CMD_DEL: -- /* fallthrough */ -- case ETMEM_CMD_SHOW: -- goto EXIT; -- default: -- printf("invalid command %u of project\n", conf->cmd); -- return -EINVAL; -- } -+struct project_cmd_item { -+ char *cmd_name; -+ enum etmem_cmd_e cmd; -+}; - --EXIT: -- proj->cmd = conf->cmd; -- return 0; --} -+static struct project_cmd_item g_project_cmd_items[] = { -+ {"show", ETMEM_CMD_SHOW}, -+ {"start", ETMEM_CMD_START}, -+ {"stop", ETMEM_CMD_STOP}, -+}; - --static int parse_file_name(const char *val, char **file_name) -+static int project_parse_cmd(struct etmem_conf *conf, struct mem_proj *proj) - { -- size_t len; -- int ret; -- -- len = strlen(val) + 1; -- if (len > FILE_NAME_MAX_LEN) { -- printf("file name too long, should not be larger than %u\n", FILE_NAME_MAX_LEN); -- return -ENAMETOOLONG; -- } -- -- *file_name = (char *)calloc(len, sizeof(char)); -- if (*file_name == NULL) { -- printf("malloc file name failed.\n"); -- return -ENOMEM; -- } -- -- ret = strncpy_s(*file_name, len, val, len - 1); -- if (ret != EOK) { -- printf("strncpy_s file name failed.\n"); -- free(*file_name); -- *file_name = NULL; -- return ret; -+ unsigned i; -+ char *cmd = NULL; -+ -+ cmd = conf->argv[0]; -+ for (i = 0; i < ARRAY_SIZE(g_project_cmd_items); i++) { -+ if (strcmp(cmd, g_project_cmd_items[i].cmd_name) == 0) { -+ proj->cmd = g_project_cmd_items[i].cmd; -+ return 0; -+ } - } - -- return 0; -+ printf("project cmd %s is not supported\n", cmd); -+ return -1; - } - - static int project_parse_args(const struct etmem_conf *conf, struct mem_proj *proj) -@@ -94,7 +73,6 @@ static int project_parse_args(const struct etmem_conf *conf, struct mem_proj *pr - int ret; - int params_cnt = 0; - struct option opts[] = { -- {"file", required_argument, NULL, 'f'}, - {"name", required_argument, NULL, 'n'}, - {"socket", required_argument, NULL, 's'}, - {NULL, 0, NULL, 0}, -@@ -103,13 +81,6 @@ static int project_parse_args(const struct etmem_conf *conf, struct mem_proj *pr - while ((opt = getopt_long(conf->argc, conf->argv, "f:n:s:", - opts, NULL)) != -1) { - switch (opt) { -- case 'f': -- ret = parse_file_name(optarg, &proj->file_name); -- if (ret != 0) { -- printf("parse file name failed.\n"); -- return ret; -- } -- break; - case 'n': - ret = parse_name_string(optarg, &proj->proj_name, PROJECT_NAME_MAX_LEN); - if (ret != 0) { -@@ -149,14 +120,9 @@ static int project_check_params(const struct mem_proj *proj) - return 0; - } - -- if (proj->proj_name == NULL || strlen(proj->proj_name) == 0) { -- printf("project name must all be given, please check.\n"); -- return -EINVAL; -- } -- -- if (proj->cmd == ETMEM_CMD_ADD) { -- if (proj->file_name == NULL || strlen(proj->file_name) == 0) { -- printf("file name must be given in add command.\n"); -+ if (proj->cmd == ETMEM_CMD_START || proj->cmd == ETMEM_CMD_STOP) { -+ if (proj->proj_name == NULL || strlen(proj->proj_name) == 0) { -+ printf("project name must be given, please check\n"); - return -EINVAL; - } - } -@@ -164,7 +130,7 @@ static int project_check_params(const struct mem_proj *proj) - return 0; - } - --static int project_do_cmd(const struct etmem_conf *conf) -+static int project_do_cmd(struct etmem_conf *conf) - { - struct mem_proj proj; - int ret; -diff --git a/src/etmem_src/etmem_rpc.c b/src/etmem_src/etmem_rpc.c -index 12a8f6d..8d03914 100644 ---- a/src/etmem_src/etmem_rpc.c -+++ b/src/etmem_src/etmem_rpc.c -@@ -24,7 +24,7 @@ - #include "securec.h" - #include "etmem_rpc.h" - --#define ETMEM_CLIENT_REGISTER "proj_name %s file_name %s cmd %d" -+#define ETMEM_CLIENT_REGISTER "proj_name %s file_name %s cmd %d eng_name %s eng_cmd %s task_name %s" - - #define INT_MAX_LEN 9 - #define ETMEM_RPC_RECV_BUF_LEN 512 -@@ -86,6 +86,15 @@ static size_t etmem_client_get_str_len(const struct mem_proj *proj) - if (proj->file_name != NULL) { - total_len += strlen(proj->file_name); - } -+ if (proj->eng_name != NULL) { -+ total_len += strlen(proj->eng_name); -+ } -+ if (proj->eng_cmd != NULL) { -+ total_len += strlen(proj->eng_cmd); -+ } -+ if (proj->task_name != NULL) { -+ total_len += strlen(proj->task_name); -+ } - - return total_len; - } -@@ -108,7 +117,10 @@ static int etmem_client_send(const struct mem_proj *proj, int sockfd) - if (snprintf_s(reg_cmd, total_len, total_len - 1, ETMEM_CLIENT_REGISTER, - proj->proj_name == NULL ? "-" : proj->proj_name, - proj->file_name == NULL ? "-" : proj->file_name, -- proj->cmd) <= 0) { -+ proj->cmd, -+ proj->eng_name == NULL ? "-" : proj->eng_name, -+ proj->eng_cmd == NULL ? "-" : proj->eng_cmd, -+ proj->task_name == NULL ? "-" : proj->task_name) <= 0) { - printf("snprintf_s failed.\n"); - goto EXIT; - } -@@ -135,16 +147,15 @@ EXIT: - static bool etmem_recv_find_fail_keyword(const char *recv_msg) - { - if (strstr(recv_msg, "error") != NULL) { -- printf("get rpc error response. %s\n", recv_msg); - return true; - } -- - return false; - } - - static int etmem_client_recv(int sockfd) - { -- ssize_t ret; -+ ssize_t recv_size; -+ int ret = -1; - char *recv_msg = NULL; - uint8_t *recv_buf = NULL; - size_t recv_len = ETMEM_RPC_RECV_BUF_LEN; -@@ -155,22 +166,27 @@ static int etmem_client_recv(int sockfd) - return -1; - } - -- ret = recv(sockfd, recv_buf, recv_len, 0); -- if (ret < 0) { -- perror("recv failed:"); -- goto EXIT; -- } -- if ((unsigned long)ret >= recv_len) { -- printf("recv too long.\n"); -- ret = -1; -- goto EXIT; -- } -- -- recv_msg = (char *)recv_buf; -- recv_msg[recv_len - 1] = '\0'; -- if (etmem_recv_find_fail_keyword(recv_msg)) { -- ret = 0; -- goto EXIT; -+ while (true) { -+ recv_size = recv(sockfd, recv_buf, recv_len - 1, 0); -+ if (recv_size < 0) { -+ perror("recv failed:"); -+ goto EXIT; -+ } -+ if (recv_size == 0) { -+ if (errno == EAGAIN || errno == EWOULDBLOCK) { -+ printf("recv timeout:\n"); -+ } -+ ret = 0; -+ goto EXIT; -+ } -+ -+ recv_msg = (char *)recv_buf; -+ recv_msg[recv_size] = '\0'; -+ printf("%s", recv_msg); -+ if (etmem_recv_find_fail_keyword(recv_msg)) { -+ printf("error occurs when getting response from etmemd server\n"); -+ goto EXIT; -+ } - } - - EXIT: -@@ -207,12 +223,6 @@ int etmem_rpc_client(const struct mem_proj *proj) - ret = -ECOMM; - goto EXIT; - } -- if (ret == 0) { -- printf("error occurs when getting response from etmemd server.\n"); -- ret = -EPERM; -- goto EXIT; -- } -- ret = 0; - - EXIT: - close(sockfd); -diff --git a/src/etmem_src/etmem_task.c b/src/etmem_src/etmem_task.c -deleted file mode 100644 -index fc3206d..0000000 ---- a/src/etmem_src/etmem_task.c -+++ /dev/null -@@ -1,161 +0,0 @@ --/****************************************************************************** -- * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -- * etmem is licensed under the Mulan PSL v2. -- * You can use this software according to the terms and conditions of the Mulan PSL v2. -- * You may obtain a copy of Mulan PSL v2 at: -- * http://license.coscl.org.cn/MulanPSL2 -- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -- * PURPOSE. -- * See the Mulan PSL v2 for more details. -- * Author: louhongxiang -- * Create: 2019-12-10 -- * Description: Migration command API. -- ******************************************************************************/ -- --#include --#include --#include --#include --#include "securec.h" --#include "etmem.h" --#include "etmem_task.h" --#include "etmem_common.h" --#include "etmem_rpc.h" -- --static void migrate_help(void) --{ -- fprintf(stderr, -- "\nUsage:\n" -- " etmem migrate start [options]\n" -- " etmem migrate stop [options]\n" -- " etmem migrate help\n" -- "\nOptions:\n" -- " -n|--name Add project name\n" -- " -s|--socket Socket name to connect\n" -- "\nNotes:\n" -- " Project name and socket name must be given when execute start or stop option.\n"); --} -- --static int migrate_parse_cmd(const struct etmem_conf *conf, struct mem_proj *proj) --{ -- switch (conf->cmd) { -- case ETMEM_CMD_START: -- /* fallthrough */ -- case ETMEM_CMD_STOP: -- goto EXIT; -- default: -- printf("invalid command %u of migrate\n", conf->cmd); -- return -EINVAL; -- } -- --EXIT: -- proj->cmd = conf->cmd; -- return 0; --} -- --static int migrate_parse_args(const struct etmem_conf *conf, struct mem_proj *proj) --{ -- int opt; -- int params_cnt = 0; -- int ret; -- struct option opts[] = { -- {"name", required_argument, NULL, 'n'}, -- {"socket", required_argument, NULL, 's'}, -- {NULL, 0, NULL, 0}, -- }; -- -- while ((opt = getopt_long(conf->argc, conf->argv, "n:s:", -- opts, NULL)) != -1) { -- switch (opt) { -- case 'n': -- ret = parse_name_string(optarg, &proj->proj_name, PROJECT_NAME_MAX_LEN); -- if (ret != 0) { -- printf("parse project name failed.\n"); -- return ret; -- } -- break; -- case 's': -- ret = parse_name_string(optarg, &proj->sock_name, SOCKET_NAME_MAX_LEN); -- if (ret != 0) { -- printf("parse socket name failed.\n"); -- return ret; -- } -- break; -- case '?': -- /* fallthrough */ -- default: -- ret = -EINVAL; -- printf("invalid option: %s\n", conf->argv[optind]); -- return ret; -- } -- params_cnt++; -- } -- -- ret = etmem_parse_check_result(params_cnt, conf->argc); -- if (ret != 0) { -- return ret; -- } -- -- return 0; --} -- --static int migrate_check_params(const struct mem_proj *proj) --{ -- if (proj->proj_name == NULL || strlen(proj->proj_name) == 0 || -- proj->sock_name == NULL || strlen(proj->sock_name) == 0) { -- printf("project name and socket name must all be given, please check.\n"); -- return -EINVAL; -- } -- -- return 0; --} -- --static int migrate_do_cmd(const struct etmem_conf *conf) --{ -- struct mem_proj proj; -- int ret; -- -- ret = memset_s(&proj, sizeof(struct mem_proj), 0, sizeof(struct mem_proj)); -- if (ret != EOK) { -- printf("memset_s for mem_proj failed.\n"); -- return ret; -- } -- -- ret = migrate_parse_cmd(conf, &proj); -- if (ret != 0) { -- goto EXIT; -- } -- -- ret = migrate_parse_args(conf, &proj); -- if (ret != 0) { -- goto EXIT; -- } -- -- ret = migrate_check_params(&proj); -- if (ret != 0) { -- goto EXIT; -- } -- -- etmem_rpc_client(&proj); -- --EXIT: -- free_proj_member(&proj); -- return ret; --} -- --static struct etmem_obj g_etmem_migrate = { -- .name = "migrate", -- .help = migrate_help, -- .do_cmd = migrate_do_cmd, --}; -- --void migrate_init(void) --{ -- etmem_register_obj(&g_etmem_migrate); --} -- --void migrate_exit(void) --{ -- etmem_unregister_obj(&g_etmem_migrate); --} -diff --git a/src/etmemd_src/etmemd_common.c b/src/etmemd_src/etmemd_common.c -index 0fe070c..43ed013 100644 ---- a/src/etmemd_src/etmemd_common.c -+++ b/src/etmemd_src/etmemd_common.c -@@ -21,6 +21,9 @@ - #include - #include - #include -+#include -+#include -+#include - - #include "securec.h" - #include "etmemd_common.h" -@@ -214,9 +217,10 @@ static char *etmemd_get_proc_file_str(const char *pid, const char *file) - return file_name; - } - --FILE *etmemd_get_proc_file(const char *pid, const char *file, const char *mode) -+FILE *etmemd_get_proc_file(const char *pid, const char *file, int flags, const char *mode) - { - char *file_name = NULL; -+ int fd = -1; - FILE *fp = NULL; - - file_name = etmemd_get_proc_file_str(pid, file); -@@ -224,7 +228,14 @@ FILE *etmemd_get_proc_file(const char *pid, const char *file, const char *mode) - return NULL; - } - -- fp = fopen(file_name, mode); -+ fd = open(file_name, flags); -+ if (fd < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "open file %s fail\n", file_name); -+ goto free_file_name; -+ } -+ fp = fdopen(fd, mode); -+ -+free_file_name: - free(file_name); - return fp; - } -@@ -366,3 +377,41 @@ char *skip_blank_line(FILE *file) - - return get_line; - } -+ -+static int write_all(int fd, const char *buf) -+{ -+ ssize_t rest = strlen(buf); -+ ssize_t send_size; -+ -+ while (rest > 0) { -+ send_size = write(fd, buf, rest); -+ if (send_size < 0) { -+ return -1; -+ } -+ rest -= send_size; -+ } -+ return 0; -+} -+ -+int dprintf_all(int fd, const char *format, ...) -+{ -+ char line[FILE_LINE_MAX_LEN]; -+ int ret; -+ va_list args_in; -+ -+ va_start(args_in, format); -+ ret = vsprintf_s(line, FILE_LINE_MAX_LEN, format, args_in); -+ if (ret > FILE_LINE_MAX_LEN) { -+ etmemd_log(ETMEMD_LOG_ERR, "fprintf_all fail as truncated.\n"); -+ return -1; -+ } -+ -+ ret = write_all(fd, line); -+ if (ret < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "write_all fail.\n"); -+ return -1; -+ } -+ -+ va_end(args_in); -+ return 0; -+} -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -new file mode 100644 -index 0000000..a3692ad ---- /dev/null -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -0,0 +1,2272 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: louhongxiang -+ * Create: 2021-4-19 -+ * Description: Memigd cslide API. -+ ******************************************************************************/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "securec.h" -+#include "etmemd_log.h" -+#include "etmemd_common.h" -+#include "etmemd_engine.h" -+#include "etmemd_cslide.h" -+#include "etmemd_scan.h" -+#include "etmemd_migrate.h" -+#include "etmemd_file.h" -+ -+#define HUGE_1M_SIZE (1 << 20) -+#define HUGE_2M_SIZE (2 << 20) -+#define HUGE_1G_SIZE (1 << 30) -+#define BYTE_TO_KB(s) ((s) >> 10) -+#define KB_TO_BYTE(s) ((s) << 10) -+ -+#define TO_PCT 100 -+#define MAX_WM 100 -+#define MIN_WM 0 -+ -+#define BATCHSIZE (1 << 16) -+ -+#define factory_foreach_working_pid_params(iter, factory) \ -+ for ((iter) = (factory)->working_head, next_working_params(&(iter)); (iter) != NULL; (iter) = (iter)->next, next_working_params(&(iter))) -+ -+#define factory_foreach_pid_params(iter, factory) \ -+ for ((iter) = (factory)->working_head; (iter) != NULL; (iter) = (iter)->next) -+ -+struct node_mem { -+ long long huge_total; -+ long long huge_free; -+}; -+ -+struct sys_mem { -+ int node_num; -+ struct node_mem *node_mem; -+}; -+ -+struct node_page_refs { -+ struct page_refs *head; -+ struct page_refs *tail; -+ int64_t size; -+ uint32_t num; -+}; -+ -+struct count_page_refs { -+ struct node_page_refs *node_pfs; -+ int node_num; -+}; -+ -+struct node_pair { -+ int index; -+ int hot_node; -+ int cold_node; -+}; -+ -+struct node_map { -+ struct node_pair *pair; -+ int total_num; -+ int cur_num; -+}; -+ -+struct node_verifier { -+ int node_num; -+ int *nodes_map_count; -+}; -+ -+struct cslide_task_params { -+ bool anon_only; -+ struct { -+ char *vmflags_str; -+ char **vmflags_array; -+ int vmflags_num; -+ }; -+}; -+ -+struct vma_pf { -+ struct vma *vma; -+ struct page_refs *page_refs; -+ struct vma_pf *next; -+}; -+ -+struct node_pages_info { -+ uint32_t hot; -+ uint32_t cold; -+}; -+ -+enum pid_param_state { -+ STATE_NONE = 0, -+ STATE_WORKING, -+ STATE_REMOVE, -+ STATE_FREE, -+}; -+ -+struct cslide_pid_params { -+ enum pid_param_state state; -+ int count; -+ struct count_page_refs *count_page_refs; -+ struct memory_grade *memory_grade; -+ struct node_pages_info *node_pages_info; -+ struct vmas *vmas; -+ struct vma_pf *vma_pf; -+ unsigned int pid; -+ struct cslide_eng_params *eng_params; -+ struct cslide_task_params *task_params; -+ struct cslide_pid_params *next; -+}; -+ -+struct cslide_params_factory { -+ pthread_mutex_t mtx; -+ struct cslide_pid_params *to_add_head; -+ struct cslide_pid_params *to_add_tail; -+ struct cslide_pid_params *working_head; -+}; -+ -+struct cslide_eng_params { -+ struct sys_mem mem; -+ struct node_map node_map; -+ int node_watermark; -+ int hot_threshold; -+ int hot_reserve; // in MB -+ int mig_quota; // in MB -+ pthread_t worker; -+ pthread_mutex_t stat_mtx; -+ time_t stat_time; -+ struct { -+ int loop; -+ int interval; -+ int sleep; -+ }; -+ struct cslide_params_factory factory; -+ bool finish; -+}; -+ -+struct ctrl_cap { -+ long long cap; -+ long long used; -+}; -+ -+struct node_ctrl { -+ struct ctrl_cap hot_move_cap; -+ struct ctrl_cap hot_prefetch_cap; -+ struct ctrl_cap cold_move_cap; -+ long long cold_replaced; -+ long long cold_free; -+ long long free; -+ long long total; -+ long long quota; -+ long long reserve; -+}; -+ -+struct flow_ctrl { -+ struct node_ctrl *node_ctrl; -+ int pair_num; -+ int hot_enough; -+ int prefetch_enough; -+ int cold_enough; -+}; -+ -+struct page_filter { -+ void (*flow_cal_func)(struct flow_ctrl *ctrl); -+ long long (*flow_move_func)(struct flow_ctrl *ctrl, long long target, int node); -+ bool (*flow_enough)(struct flow_ctrl *ctrl); -+ void (*filter_policy)(struct page_filter *filter, struct node_pair *pair, struct count_page_refs *cpf, struct memory_grade *memory_grade); -+ struct flow_ctrl *ctrl; -+ int count_start; -+ int count_end; -+ int count_step; -+}; -+ -+struct page_offset { -+ struct page_refs *page_refs; -+ uint64_t to_offset; -+}; -+ -+struct cslide_cmd_item { -+ char *name; -+ int (*func)(void *params, int fd); -+}; -+ -+struct vma_pf *g_share_vma_head = NULL; -+ -+static inline int get_node_num(void) -+{ -+ return numa_num_configured_nodes(); -+} -+ -+static int init_sys_mem(struct sys_mem *mem) -+{ -+ int node_num = get_node_num(); -+ -+ if (node_num <= 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "node number %d is invalid \n", node_num); -+ return -1; -+ } -+ -+ mem->node_mem = malloc(sizeof(struct node_mem) * node_num); -+ if (mem->node_mem == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc node_mem fail\n"); -+ return -1; -+ } -+ mem->node_num = node_num; -+ return 0; -+} -+ -+static void destroy_sys_mem(struct sys_mem *mem) -+{ -+ mem->node_num = -1; -+ free(mem->node_mem); -+ mem->node_mem = NULL; -+} -+ -+static int read_hugepage_num(char *path) -+{ -+ FILE *f = NULL; -+ char *line = NULL; -+ size_t line_len = 0; -+ int nr = -1; -+ -+ f = fopen(path, "r"); -+ if (f == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "open file %s failed\n", path); -+ return -1; -+ } -+ if (getline(&line, &line_len, f) < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "read free hugepage from %s fail\n", path); -+ goto close_file; -+ } -+ -+ nr = strtoull(line, NULL, 0); -+ free(line); -+close_file: -+ fclose(f); -+ return nr; -+} -+ -+static long long get_single_huge_mem(int node, int huge_size, char *huge_state) -+{ -+ char path[PATH_MAX]; -+ int nr; -+ -+ if (sprintf_s(path, PATH_MAX, "/sys/devices/system/node/node%d/hugepages/hugepages-%dkB/%s_hugepages", -+ node, huge_size, huge_state) <= 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "snprintf path to get hugepage number fail\n"); -+ return -1; -+ } -+ -+ nr = read_hugepage_num(path); -+ if (nr < 0) { -+ return -1; -+ } -+ -+ return KB_TO_BYTE((long long)nr * (long long)huge_size); -+} -+ -+static long long get_node_huge_total(int node, char *huge_state) -+{ -+ long long size_2m; -+ -+ size_2m = get_single_huge_mem(node, BYTE_TO_KB(HUGE_2M_SIZE), huge_state); -+ if (size_2m < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get 2M %s page in node %d fail\n", huge_state, node); -+ return -1; -+ } -+ -+ return size_2m; -+} -+ -+static int get_node_huge_mem(int node, struct node_mem *mem) -+{ -+ mem->huge_total = get_node_huge_total(node, "nr"); -+ if (mem->huge_total <= 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get total hugepages of node %d fail\n", node); -+ return -1; -+ } -+ mem->huge_free = get_node_huge_total(node, "free"); -+ if (mem->huge_free < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get free hugepages of node %d fail\n", node); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int get_node_mem(int node, struct node_mem *mem) -+{ -+ if (get_node_huge_mem(node, mem) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get huge memory info of node %d fail\n", node); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int get_sys_mem(struct sys_mem *mem) -+{ -+ int i; -+ -+ for (i = 0; i < mem->node_num; i++) { -+ if (get_node_mem(i, &(mem->node_mem[i])) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get memory info of node %d fail\n", i); -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+static void init_node_page_refs(struct node_page_refs *npf) -+{ -+ npf->head = NULL; -+ npf->tail = NULL; -+ npf->size = 0; -+ npf->num = 0; -+} -+ -+static void clean_node_page_refs(struct node_page_refs *npf) -+{ -+ clean_page_refs_unexpected(&npf->head); -+ npf->tail = NULL; -+ npf->size = 0; -+ npf->num = 0; -+} -+ -+static void npf_add_pf(struct node_page_refs *npf, struct page_refs *page_refs) -+{ -+ if (npf->head == NULL) { -+ npf->head = page_refs; -+ npf->tail = page_refs; -+ } else { -+ npf->tail->next = page_refs; -+ npf->tail = page_refs; -+ } -+ -+ npf->size += page_type_to_size(page_refs->type); -+ npf->num++; -+} -+ -+/* must called when all pf add to npf with npf_add_pf */ -+static void npf_setup_tail(struct node_page_refs *npf) -+{ -+ if (npf->tail != NULL) { -+ npf->tail->next = NULL; -+ } -+} -+ -+static long long move_npf_to_list(struct node_page_refs *npf, struct page_refs **list, long long size) -+{ -+ struct page_refs *t = NULL; -+ struct page_refs *iter = NULL; -+ struct page_refs *tmp = NULL; -+ long long moved_size = 0; -+ -+ if (npf->size <= size) { -+ t = npf->tail; -+ moved_size = npf->size; -+ } else { -+ for (iter = npf->head; iter != NULL && size >= moved_size + page_type_to_size(iter->type); iter = iter->next) { -+ moved_size += page_type_to_size(iter->type); -+ t = iter; -+ } -+ } -+ -+ if (t != NULL) { -+ tmp = t->next; -+ t->next = *list; -+ *list = npf->head; -+ npf->head = tmp; -+ if (tmp == NULL) { -+ npf->tail = NULL; -+ } -+ } -+ -+ npf->size -= moved_size; -+ return moved_size; -+} -+ -+static int init_count_page_refs(struct count_page_refs *cpf, int node_num) -+{ -+ int i; -+ -+ cpf->node_pfs = malloc(sizeof(struct node_page_refs) * node_num); -+ if (cpf->node_pfs == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc node_page_refs fail\n"); -+ return -1; -+ } -+ for (i = 0; i < node_num; i++) { -+ init_node_page_refs(&cpf->node_pfs[i]); -+ } -+ cpf->node_num = node_num; -+ return 0; -+} -+ -+static void clean_count_page_refs(struct count_page_refs *cpf) -+{ -+ int i; -+ -+ for (i = 0; i < cpf->node_num; i++) { -+ clean_node_page_refs(&cpf->node_pfs[i]); -+ } -+} -+ -+static void destroy_count_page_refs(struct count_page_refs *cpf) -+{ -+ clean_count_page_refs(cpf); -+ free(cpf->node_pfs); -+ cpf->node_pfs = NULL; -+ cpf->node_num = 0; -+} -+ -+static void insert_count_pfs(struct count_page_refs *cpf, struct page_refs *pf, int *nodes, int num) -+{ -+ struct node_page_refs *npf = NULL; -+ struct page_refs *next = NULL; -+ int node, count, i; -+ -+ for (i = 0; i < num; i++) { -+ next = pf->next; -+ node = nodes[i]; -+ if (node < 0 || node >= cpf->node_num) { -+ etmemd_log(ETMEMD_LOG_WARN, "addr %llx with invalid node %d\n", pf->addr, node); -+ pf->next = NULL; -+ etmemd_free_page_refs(pf); -+ pf = next; -+ continue; -+ } -+ count = pf->count; -+ npf = &cpf[count].node_pfs[node]; -+ npf_add_pf(npf, pf); -+ pf = next; -+ } -+} -+ -+/* must called after all page_refs insert by insert_count_pfs */ -+static void setup_count_pfs_tail(struct count_page_refs *cpf, int count) -+{ -+ int node, c; -+ struct node_page_refs *npf = NULL; -+ -+ for (c = 0; c <= count; c++) { -+ for (node = 0; node < cpf->node_num; node++) { -+ npf = &cpf[c].node_pfs[node]; -+ npf_setup_tail(npf); -+ } -+ } -+} -+ -+static int init_node_map(struct node_map *node_map, int node_num) -+{ -+ int pair_num; -+ -+ if (node_num % 2 != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "node_num is not even\n"); -+ return -1; -+ } -+ pair_num = node_num / 2; -+ node_map->pair = calloc(pair_num, sizeof(struct node_pair)); -+ if (node_map->pair == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc memory for node map fail\n"); -+ return -1; -+ } -+ node_map->total_num = pair_num; -+ node_map->cur_num = 0; -+ return 0; -+} -+ -+static void destroy_node_map(struct node_map *map) -+{ -+ free(map->pair); -+ map->pair = NULL; -+ map->total_num = 0; -+ map->cur_num = 0; -+} -+ -+static int add_node_pair(struct node_map *map, int cold_node, int hot_node) -+{ -+ if (map->cur_num == map->total_num) { -+ etmemd_log(ETMEMD_LOG_ERR, "too much pair, add pair hot %d cold %d fail\n", -+ hot_node, cold_node); -+ return -1; -+ } -+ map->pair[map->cur_num].hot_node = hot_node; -+ map->pair[map->cur_num].cold_node = cold_node; -+ map->pair[map->cur_num].index = map->cur_num; -+ map->cur_num++; -+ return 0; -+} -+ -+ -+static int init_node_verifier(struct node_verifier *nv, int node_num) -+{ -+ nv->nodes_map_count = calloc(node_num, sizeof(int)); -+ if (nv->nodes_map_count == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc memroy for nodes_map_count failed\n"); -+ return -1; -+ } -+ -+ nv->node_num = node_num; -+ return 0; -+} -+ -+static void destroy_node_verifier(struct node_verifier *nv) -+{ -+ free(nv->nodes_map_count); -+} -+ -+static bool is_node_valid(struct node_verifier *nv, int node) -+{ -+ if (node < 0 || node >= nv->node_num) { -+ etmemd_log(ETMEMD_LOG_ERR, "node %d out of range\n", node); -+ return false; -+ } -+ -+ if (nv->nodes_map_count[node] != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "node %d remap\n", node); -+ return false; -+ } -+ -+ nv->nodes_map_count[node]++; -+ return true; -+} -+ -+static bool has_node_unmap(struct node_verifier *nv) -+{ -+ int i; -+ bool ret = false; -+ -+ for (i = 0; i < nv->node_num; i++) { -+ if (nv->nodes_map_count[i] == 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "unmap node %d\n", i); -+ ret = true; -+ } -+ } -+ -+ return ret; -+} -+ -+static void clear_task_params(struct cslide_task_params *params) -+{ -+ if (params->vmflags_str != NULL) { -+ free(params->vmflags_str); -+ params->vmflags_str = NULL; -+ } -+ if (params->vmflags_array != NULL) { -+ free(params->vmflags_array); -+ params->vmflags_array = NULL; -+ } -+} -+ -+static struct cslide_pid_params *alloc_pid_params(struct cslide_eng_params *eng_params) -+{ -+ int i; -+ struct cslide_pid_params *params = calloc(1, sizeof(struct cslide_pid_params)); -+ int count = eng_params->loop; -+ int pair_num = eng_params->node_map.cur_num; -+ int node_num = eng_params->mem.node_num; -+ -+ if (params == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "malloc cslide pid params fail\n"); -+ return NULL; -+ } -+ params->count_page_refs = malloc(sizeof(struct count_page_refs) * (count + 1)); -+ if (params->count_page_refs == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "malloc counted page_refs fail\n"); -+ goto free_params; -+ } -+ -+ for (i = 0; i <= count; i++) { -+ if (init_count_page_refs(¶ms->count_page_refs[i], node_num) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "init counted page_refs fail\n"); -+ goto free_count_page_refs; -+ } -+ } -+ -+ params->count = count; -+ params->memory_grade = calloc(pair_num, sizeof(struct memory_grade)); -+ if (params->memory_grade == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc memory_grade fail\n"); -+ goto free_count_page_refs; -+ } -+ -+ params->node_pages_info = calloc(node_num, sizeof(struct node_pages_info)); -+ if (params->node_pages_info == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc pages info fail\n"); -+ goto free_memory_grade; -+ } -+ return params; -+ -+free_memory_grade: -+ free(params->memory_grade); -+ params->memory_grade = NULL; -+free_count_page_refs: -+ for (i--; i >= 0; i--) { -+ destroy_count_page_refs(¶ms->count_page_refs[i]); -+ } -+ free(params->count_page_refs); -+ params->count_page_refs = NULL; -+free_params: -+ free(params); -+ params = NULL; -+ return NULL; -+} -+ -+static void free_pid_params(struct cslide_pid_params *params) -+{ -+ int count = params->count; -+ int i; -+ -+ free(params->node_pages_info); -+ params->node_pages_info = NULL; -+ free(params->memory_grade); -+ params->memory_grade = NULL; -+ for (i = 0; i <= count; i++) { -+ destroy_count_page_refs(¶ms->count_page_refs[i]); -+ } -+ free(params->count_page_refs); -+ params->count_page_refs = NULL; -+ if (params->task_params != NULL) { -+ clear_task_params(params->task_params); -+ free(params->task_params); -+ params->task_params = NULL; -+ } -+ free(params); -+} -+ -+static void clean_pid_param(struct cslide_pid_params *pid_params) -+{ -+ struct cslide_eng_params *eng_params = pid_params->eng_params; -+ int pair_num = eng_params->node_map.cur_num; -+ int i; -+ -+ for (i = 0; i < pair_num; i++) { -+ clean_page_refs_unexpected(&pid_params->memory_grade[i].hot_pages); -+ clean_page_refs_unexpected(&pid_params->memory_grade[i].cold_pages); -+ } -+ for (i = 0; i <= pid_params->count; i++) { -+ clean_count_page_refs(&pid_params->count_page_refs[i]); -+ } -+} -+ -+static void destroy_factory(struct cslide_params_factory *factory) -+{ -+ pthread_mutex_destroy(&factory->mtx); -+} -+ -+static int init_factory(struct cslide_params_factory *factory) -+{ -+ return pthread_mutex_init(&factory->mtx, NULL); -+} -+ -+static void factory_add_pid_params(struct cslide_params_factory *factory, struct cslide_pid_params *params) -+{ -+ enum pid_param_state state = params->state; -+ params->state = STATE_WORKING; -+ -+ if (state == STATE_NONE) { -+ pthread_mutex_lock(&factory->mtx); -+ params->next = factory->to_add_head; -+ factory->to_add_head = params; -+ if (factory->to_add_tail == NULL) { -+ factory->to_add_tail = params; -+ } -+ pthread_mutex_unlock(&factory->mtx); -+ } -+} -+ -+static void factory_remove_pid_params(struct cslide_params_factory *factory, struct cslide_pid_params *params) -+{ -+ params->state = STATE_REMOVE; -+} -+ -+static void factory_free_pid_params(struct cslide_params_factory *factory, struct cslide_pid_params *params) -+{ -+ params->state = STATE_FREE; -+} -+ -+static void next_working_params(struct cslide_pid_params **params) -+{ -+ while (*params != NULL && (*params)->state != STATE_WORKING) { -+ *params = (*params)->next; -+ } -+} -+ -+/* add and free operations will take effect here */ -+static void factory_update_pid_params(struct cslide_params_factory *factory) -+{ -+ struct cslide_pid_params **prev = NULL; -+ struct cslide_pid_params *iter = NULL; -+ struct cslide_pid_params *to_add_head = NULL; -+ struct cslide_pid_params *to_add_tail = NULL; -+ -+ /* get new added params first */ -+ pthread_mutex_lock(&factory->mtx); -+ to_add_head = factory->to_add_head; -+ to_add_tail = factory->to_add_tail; -+ factory->to_add_head = NULL; -+ factory->to_add_tail = NULL; -+ pthread_mutex_unlock(&factory->mtx); -+ -+ if (to_add_head != NULL) { -+ to_add_tail->next = factory->working_head; -+ factory->working_head = to_add_head; -+ } -+ -+ /* clear the freed params */ -+ prev = &factory->working_head; -+ for (iter = *prev; iter != NULL; iter = *prev) { -+ if (iter->state != STATE_FREE) { -+ prev = &(iter->next); -+ continue; -+ } -+ *prev = iter->next; -+ iter->next = NULL; -+ free_pid_params(iter); -+ } -+} -+ -+static bool factory_working_empty(struct cslide_params_factory *factory) -+{ -+ struct cslide_pid_params *pid_params = NULL; -+ -+ factory_foreach_pid_params(pid_params, factory) { -+ if (pid_params->state == STATE_WORKING) { -+ return false; -+ } -+ } -+ return true; -+} -+ -+static struct page_refs *next_vma_pf(struct cslide_pid_params *params, int *cur) -+{ -+ int vma_pf_num = params->vmas->vma_cnt; -+ struct vma_pf *vma_pf = params->vma_pf; -+ struct page_refs *pf = NULL; -+ -+ while (*cur < vma_pf_num) { -+ pf = vma_pf[*cur].page_refs; -+ vma_pf[*cur].page_refs = NULL; -+ (*cur)++; -+ if (pf != NULL) { -+ break; -+ } -+ } -+ return pf; -+} -+ -+static int cslide_count_node_pfs(struct cslide_pid_params *params) -+{ -+ struct page_refs *page_refs = NULL; -+ struct page_refs *last = NULL; -+ unsigned int pid = params->pid; -+ int batch_size = BATCHSIZE; -+ void **pages = NULL; -+ int *status = NULL; -+ int actual_num = 0; -+ int ret = -1; -+ int vma_i = 0; -+ -+ if (params->vmas == NULL || params->vma_pf == NULL) { -+ return 0; -+ } -+ -+ status = malloc(sizeof(int) * batch_size); -+ if (status == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "malloc status fail\n"); -+ return -1; -+ } -+ -+ pages = malloc(sizeof(void *) * batch_size); -+ if (pages == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "malloc pages fail\n"); -+ goto free_status; -+ } -+ -+ page_refs = next_vma_pf(params, &vma_i); -+ last = page_refs; -+ while (page_refs != NULL) { -+ pages[actual_num++] = (void *)page_refs->addr; -+ if (page_refs->next == NULL) { -+ page_refs->next = next_vma_pf(params, &vma_i); -+ } -+ if (actual_num == batch_size || page_refs->next == NULL) { -+ if (move_pages(pid, actual_num, pages, NULL, status, MPOL_MF_MOVE_ALL) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get page refs numa node fail\n"); -+ goto free_pages; -+ } -+ insert_count_pfs(params->count_page_refs, last, status, actual_num); -+ last = page_refs->next; -+ actual_num = 0; -+ } -+ page_refs = page_refs->next; -+ } -+ setup_count_pfs_tail(params->count_page_refs, params->count); -+ ret = 0; -+ -+free_pages: -+ free(pages); -+ pages = NULL; -+free_status: -+ free(status); -+ status = NULL; -+ return ret; -+} -+ -+static inline bool cap_avail(struct ctrl_cap *cap) -+{ -+ return cap->used < cap->cap; -+} -+ -+/* return true if cap is still available */ -+static inline bool cap_cost(struct ctrl_cap *cap, long long *cost) -+{ -+ if (*cost < cap->cap - cap->used) { -+ cap->used += *cost; -+ return true; -+ } -+ -+ *cost = cap->cap - cap->used; -+ cap->used = cap->cap; -+ return false; -+} -+ -+/* return true if node can move hot pages */ -+static bool node_cal_hot_can_move(struct node_ctrl *node_ctrl) -+{ -+ long long can_move; -+ -+ if (node_ctrl->quota < node_ctrl->free) { -+ can_move = node_ctrl->quota; -+ } else { -+ can_move = node_ctrl->free + (node_ctrl->quota - node_ctrl->free) / 2; -+ if (can_move > node_ctrl->free + node_ctrl->cold_free) { -+ can_move = node_ctrl->free + node_ctrl->cold_free; -+ } -+ } -+ -+ if (can_move > node_ctrl->total) { -+ can_move = node_ctrl->total; -+ } -+ node_ctrl->hot_move_cap.cap = can_move; -+ return can_move > 0; -+} -+ -+static inline bool node_can_move_hot(struct node_ctrl *node_ctrl) -+{ -+ return cap_avail(&node_ctrl->hot_move_cap); -+} -+ -+static inline bool node_move_hot(struct node_ctrl *node_ctrl, long long *target) -+{ -+ return cap_cost(&node_ctrl->hot_move_cap, target); -+} -+ -+static void node_update_hot_move(struct node_ctrl *node_ctrl) -+{ -+ long long hot_move = node_ctrl->hot_move_cap.used; -+ -+ if (hot_move > node_ctrl->free) { -+ node_ctrl->cold_replaced += hot_move - node_ctrl->free; -+ node_ctrl->quota -= node_ctrl->free + (hot_move - node_ctrl->free) * 2; -+ node_ctrl->cold_free += node_ctrl->free; -+ node_ctrl->free = 0; -+ } else { -+ node_ctrl->free -= hot_move; -+ node_ctrl->quota -= hot_move; -+ node_ctrl->cold_free += hot_move; -+ } -+} -+ -+/* return true if node can prefetch hot pages */ -+static bool node_cal_hot_can_prefetch(struct node_ctrl *node_ctrl) -+{ -+ long long can_prefetch; -+ -+ if (node_ctrl->free <= node_ctrl->reserve) { -+ can_prefetch = 0; -+ goto exit; -+ } -+ -+ can_prefetch = node_ctrl->free - node_ctrl->reserve; -+ if (can_prefetch > node_ctrl->quota) { -+ can_prefetch = node_ctrl->quota; -+ } -+ -+exit: -+ node_ctrl->hot_prefetch_cap.cap = can_prefetch; -+ return can_prefetch > 0; -+} -+ -+static inline bool node_can_prefetch_hot(struct node_ctrl *node_ctrl) -+{ -+ return cap_avail(&node_ctrl->hot_prefetch_cap); -+} -+ -+static inline bool node_prefetch_hot(struct node_ctrl *node_ctrl, long long *target) -+{ -+ return cap_cost(&node_ctrl->hot_prefetch_cap, target); -+} -+ -+static void node_update_hot_prefetch(struct node_ctrl *node_ctrl) -+{ -+ long long hot_prefetch = node_ctrl->hot_prefetch_cap.used; -+ -+ node_ctrl->free -= hot_prefetch; -+ node_ctrl->quota -= hot_prefetch; -+ node_ctrl->cold_free += hot_prefetch; -+} -+ -+static bool node_cal_cold_can_move(struct node_ctrl *node_ctrl) -+{ -+ long long can_move; -+ -+ can_move = node_ctrl->quota < node_ctrl->reserve - node_ctrl->free ? node_ctrl->quota : node_ctrl->reserve - node_ctrl->free; -+ if (can_move > node_ctrl->cold_free) { -+ can_move = node_ctrl->cold_free; -+ } -+ if (can_move < 0) { -+ can_move = 0; -+ } -+ -+ node_ctrl->cold_move_cap.cap = can_move + node_ctrl->cold_replaced; -+ return node_ctrl->cold_move_cap.cap > 0; -+} -+ -+static inline bool node_can_move_cold(struct node_ctrl *node_ctrl) -+{ -+ return cap_avail(&node_ctrl->cold_move_cap); -+} -+ -+/* return true if still can move cold pages */ -+static inline bool node_move_cold(struct node_ctrl *node_ctrl, long long *target) -+{ -+ return cap_cost(&node_ctrl->cold_move_cap, target); -+} -+ -+static int init_flow_ctrl(struct flow_ctrl *ctrl, struct sys_mem *sys_mem, struct node_map *node_map, long long quota, long long reserve) -+{ -+ struct node_pair *pair = NULL; -+ struct node_ctrl *tmp = NULL; -+ int i; -+ -+ ctrl->node_ctrl = calloc(node_map->cur_num, sizeof(struct node_ctrl)); -+ if (ctrl->node_ctrl == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc memory for node_ctrl fail\n"); -+ return -1; -+ } -+ -+ ctrl->pair_num = node_map->cur_num; -+ ctrl->hot_enough = 0; -+ ctrl->cold_enough = 0; -+ ctrl->prefetch_enough = 0; -+ for (i = 0; i < ctrl->pair_num; i++) { -+ pair = &node_map->pair[i]; -+ tmp = &ctrl->node_ctrl[i]; -+ tmp->cold_free = sys_mem->node_mem[pair->cold_node].huge_free; -+ tmp->free = sys_mem->node_mem[pair->hot_node].huge_free; -+ tmp->total = sys_mem->node_mem[pair->hot_node].huge_total; -+ tmp->quota = quota; -+ tmp->reserve = reserve; -+ } -+ return 0; -+} -+ -+static void flow_cal_hot_can_move(struct flow_ctrl *ctrl) -+{ -+ int i; -+ -+ for (i = 0; i < ctrl->pair_num; i++) { -+ if (!node_cal_hot_can_move(&ctrl->node_ctrl[i])) { -+ ctrl->hot_enough++; -+ } -+ } -+} -+ -+static inline bool is_hot_enough(struct flow_ctrl *ctrl) -+{ -+ return ctrl->hot_enough == ctrl->pair_num; -+} -+ -+static long long ctrl_hot_move(struct flow_ctrl *ctrl, long long target, int node) -+{ -+ struct node_ctrl *node_ctrl = &ctrl->node_ctrl[node]; -+ -+ if (!node_can_move_hot(node_ctrl)) { -+ return 0; -+ } -+ -+ if (!node_move_hot(node_ctrl, &target)) { -+ ctrl->hot_enough++; -+ } -+ -+ return target; -+} -+ -+static void flow_cal_hot_can_prefetch(struct flow_ctrl *ctrl) -+{ -+ int i; -+ -+ for (i = 0; i < ctrl->pair_num; i++) { -+ node_update_hot_move(&ctrl->node_ctrl[i]); -+ if (!node_cal_hot_can_prefetch(&ctrl->node_ctrl[i])) { -+ ctrl->prefetch_enough++; -+ } -+ } -+} -+ -+static inline bool is_prefetch_enough(struct flow_ctrl *ctrl) -+{ -+ return ctrl->prefetch_enough == ctrl->pair_num; -+} -+ -+static long long ctrl_prefetch_hot(struct flow_ctrl *ctrl, long long target, int node) -+{ -+ struct node_ctrl *node_ctrl = &ctrl->node_ctrl[node]; -+ -+ if (!node_can_prefetch_hot(node_ctrl)) { -+ return 0; -+ } -+ -+ if (!node_prefetch_hot(node_ctrl, &target)) { -+ ctrl->prefetch_enough++; -+ } -+ -+ return target; -+} -+ -+static void flow_cal_cold_can_move(struct flow_ctrl *ctrl) -+{ -+ int i; -+ -+ for (i = 0; i < ctrl->pair_num; i++) { -+ node_update_hot_prefetch(&ctrl->node_ctrl[i]); -+ if (!node_cal_cold_can_move(&ctrl->node_ctrl[i])) { -+ ctrl->cold_enough++; -+ } -+ } -+} -+ -+static inline bool is_cold_enough(struct flow_ctrl *ctrl) -+{ -+ return ctrl->cold_enough == ctrl->pair_num; -+} -+ -+static long long ctrl_cold_move(struct flow_ctrl *ctrl, long long target, int node) -+{ -+ struct node_ctrl *node_ctrl = &ctrl->node_ctrl[node]; -+ -+ if (!node_can_move_cold(node_ctrl)) { -+ return 0; -+ } -+ -+ if (!node_move_cold(node_ctrl, &target)) { -+ ctrl->cold_enough++; -+ } -+ -+ return target; -+} -+ -+static void destroy_flow_ctrl(struct flow_ctrl *ctrl) -+{ -+ free(ctrl->node_ctrl); -+ ctrl->node_ctrl = NULL; -+} -+ -+static void do_filter(struct page_filter *filter, struct cslide_eng_params *eng_params) -+{ -+ struct cslide_pid_params *params = NULL; -+ struct count_page_refs *cpf = NULL; -+ struct memory_grade *memory_grade = NULL; -+ struct node_pair *pair = NULL; -+ int pair_num = eng_params->node_map.cur_num; -+ int i, j; -+ -+ filter->flow_cal_func(filter->ctrl); -+ if (filter->flow_enough(filter->ctrl)) { -+ return; -+ } -+ -+ for (i = filter->count_start; i != filter->count_end; i += filter->count_step) { -+ factory_foreach_working_pid_params(params, &eng_params->factory) { -+ cpf = ¶ms->count_page_refs[i]; -+ for (j = 0; j < pair_num; j++) { -+ pair = &eng_params->node_map.pair[j]; -+ memory_grade = ¶ms->memory_grade[j]; -+ filter->filter_policy(filter, pair, cpf, memory_grade); -+ if (filter->flow_enough(filter->ctrl)) { -+ return; -+ } -+ } -+ } -+ } -+} -+ -+static void to_hot_policy(struct page_filter *filter, struct node_pair *pair, struct count_page_refs *cpf, struct memory_grade *memory_grade) -+{ -+ long long can_move; -+ struct node_page_refs *npf = &cpf->node_pfs[pair->cold_node]; -+ -+ can_move = filter->flow_move_func(filter->ctrl, npf->size, pair->index); -+ move_npf_to_list(npf, &memory_grade->hot_pages, can_move); -+} -+ -+static void to_cold_policy(struct page_filter *filter, struct node_pair *pair, struct count_page_refs *cpf, struct memory_grade *memory_grade) -+{ -+ long long can_move; -+ struct node_page_refs *npf = &cpf->node_pfs[pair->hot_node]; -+ -+ can_move = filter->flow_move_func(filter->ctrl, npf->size, pair->index); -+ move_npf_to_list(npf, &memory_grade->cold_pages, can_move); -+} -+ -+static void move_hot_pages(struct cslide_eng_params *eng_params, struct flow_ctrl *ctrl) -+{ -+ struct page_filter filter; -+ filter.flow_cal_func = flow_cal_hot_can_move; -+ filter.flow_move_func = ctrl_hot_move; -+ filter.flow_enough = is_hot_enough; -+ filter.filter_policy = to_hot_policy; -+ filter.ctrl = ctrl; -+ filter.count_start = eng_params->loop; -+ filter.count_end = eng_params->hot_threshold - 1; -+ filter.count_step = -1; -+ do_filter(&filter, eng_params); -+} -+ -+static void prefetch_hot_pages(struct cslide_eng_params *eng_params, struct flow_ctrl *ctrl) -+{ -+ struct page_filter filter; -+ filter.flow_cal_func = flow_cal_hot_can_prefetch; -+ filter.flow_move_func = ctrl_prefetch_hot; -+ filter.flow_enough = is_prefetch_enough; -+ filter.filter_policy = to_hot_policy; -+ filter.ctrl = ctrl; -+ filter.count_start = eng_params->hot_threshold - 1; -+ filter.count_end = -1; -+ filter.count_step = -1; -+ do_filter(&filter, eng_params); -+} -+ -+static void move_cold_pages(struct cslide_eng_params *eng_params, struct flow_ctrl *ctrl) -+{ -+ struct page_filter filter; -+ filter.flow_cal_func = flow_cal_cold_can_move; -+ filter.flow_move_func = ctrl_cold_move; -+ filter.flow_enough = is_cold_enough; -+ filter.filter_policy = to_cold_policy; -+ filter.ctrl = ctrl; -+ filter.count_start = 0; -+ filter.count_end = eng_params->hot_threshold; -+ filter.count_step = 1; -+ do_filter(&filter, eng_params); -+} -+ -+static void cslide_filter_pfs(struct cslide_eng_params *eng_params) -+{ -+ struct flow_ctrl ctrl; -+ long long quota = (long long)eng_params->mig_quota * HUGE_1M_SIZE; -+ long long reserve = (long long)eng_params->hot_reserve * HUGE_1M_SIZE; -+ -+ if (init_flow_ctrl(&ctrl, &eng_params->mem, &eng_params->node_map, quota, reserve) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "init_flow_ctrl fail\n"); -+ return; -+ } -+ -+ move_hot_pages(eng_params, &ctrl); -+ prefetch_hot_pages(eng_params, &ctrl); -+ move_cold_pages(eng_params, &ctrl); -+ -+ destroy_flow_ctrl(&ctrl); -+} -+ -+static int cslide_policy(struct cslide_eng_params *eng_params) -+{ -+ struct cslide_pid_params *pid_params = NULL; -+ int ret; -+ -+ factory_foreach_working_pid_params(pid_params, &eng_params->factory) { -+ ret = cslide_count_node_pfs(pid_params); -+ if (ret != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "count node page refs fail\n"); -+ return ret; -+ } -+ } -+ -+ cslide_filter_pfs(eng_params); -+ return 0; -+} -+ -+static void sort_add_vma_pf(struct vma_pf *vma_pf) -+{ -+ struct vma_pf **iter = &g_share_vma_head; -+ -+ for (; *iter != NULL && (*iter)->vma->inode < vma_pf->vma->inode; iter = &((*iter)->next)) { -+ ; -+ } -+ -+ vma_pf->next = *iter; -+ *iter = vma_pf; -+} -+ -+static bool is_share(struct vma_pf *vma_pf) -+{ -+ struct vma *vma = vma_pf->vma; -+ -+ if (vma->inode != 0 && vma->stat[VMA_STAT_MAY_SHARE]) { -+ return true; -+ } -+ -+ return false; -+} -+ -+static inline uint64_t to_offset(struct page_offset *po) -+{ -+ return po->page_refs->addr + po->to_offset; -+} -+ -+static int page_offset_cmp(const void *a, const void *b) -+{ -+ struct page_offset *l = (struct page_offset *)a; -+ struct page_offset *r = (struct page_offset *)b; -+ -+ return to_offset(l) - to_offset(r); -+} -+ -+static inline void init_merge_po(struct page_offset *to_merge_po, int count) -+{ -+ qsort(to_merge_po, count, sizeof(struct page_offset), page_offset_cmp); -+} -+ -+static void next_po(struct page_offset *to_merge_po, int *count) -+{ -+ struct page_offset *po = to_merge_po; -+ struct page_offset tmp; -+ uint64_t offset; -+ int i; -+ -+ po->page_refs = po->page_refs->next; -+ if (po->page_refs == NULL) { -+ for (i = 1; i < *count; i++) { -+ to_merge_po[i - 1] = to_merge_po[i]; -+ } -+ (*count)--; -+ return; -+ } -+ -+ tmp = *po; -+ offset = to_offset(po); -+ for (i = 1; i < *count; i++) { -+ if (to_offset(&to_merge_po[i]) >= offset) { -+ break; -+ } -+ to_merge_po[i - 1] = to_merge_po[i]; -+ } -+ to_merge_po[i - 1] = tmp; -+} -+ -+static void merge_share_pfs(struct page_refs **share_pfs, int share_pfs_num) -+{ -+ int max_count = -1; -+ struct page_refs *max_pf = NULL; -+ int i; -+ -+ /* only keep one page_refs with max count */ -+ for (i = 0; i < share_pfs_num; i++) { -+ if (share_pfs[i]->count > max_count) { -+ max_pf = share_pfs[i]; -+ max_count = share_pfs[i]->count; -+ } -+ share_pfs[i]->count = -1; -+ } -+ max_pf->count = max_count; -+} -+ -+static int do_merge_vma_pf(struct vma_pf *vma_pf, int count) -+{ -+ struct page_refs **share_pfs = NULL; -+ struct page_offset *to_merge_po = NULL; -+ struct page_offset *iter = NULL; -+ int share_pfs_num; -+ uint64_t cur_offset = 0; -+ uint64_t next_offset; -+ int i; -+ -+ share_pfs = calloc(count, sizeof(struct page_refs *)); -+ if (share_pfs == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc share_pfs fail\n"); -+ return -1; -+ } -+ -+ to_merge_po = calloc(count, sizeof(struct page_offset)); -+ if (to_merge_po == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc iter_pfs fail\n"); -+ free(share_pfs); -+ return -1; -+ } -+ -+ for (i = 0; i < count; i++) { -+ to_merge_po[i].page_refs = vma_pf->page_refs; -+ to_merge_po[i].to_offset = vma_pf->vma->offset - vma_pf->vma->start; -+ vma_pf = vma_pf->next; -+ } -+ -+ init_merge_po(to_merge_po, count); -+ iter = to_merge_po; -+ share_pfs[0] = iter->page_refs; -+ share_pfs_num = 1; -+ cur_offset = to_offset(iter); -+ -+ for (next_po(to_merge_po, &count); count > 0; next_po(to_merge_po, &count)) { -+ iter = to_merge_po; -+ next_offset = to_offset(iter); -+ if (next_offset == cur_offset) { -+ share_pfs[share_pfs_num] = iter->page_refs; -+ share_pfs_num++; -+ } else { -+ if (share_pfs_num > 1) { -+ merge_share_pfs(share_pfs, share_pfs_num); -+ } -+ share_pfs[0] = iter->page_refs; -+ share_pfs_num = 1; -+ cur_offset = next_offset; -+ } -+ -+ } -+ if (share_pfs_num > 1) { -+ merge_share_pfs(share_pfs, share_pfs_num); -+ } -+ -+ free(to_merge_po); -+ free(share_pfs); -+ return 0; -+} -+ -+static int cslide_merge_share_vmas(struct cslide_eng_params *eng_params) -+{ -+ struct cslide_pid_params *pid_params = NULL; -+ struct vma_pf *vma_pf = NULL; -+ struct vma_pf *iter = NULL; -+ int count; -+ uint64_t i; -+ -+ factory_foreach_working_pid_params(pid_params, &eng_params->factory) { -+ vma_pf = pid_params->vma_pf; -+ if (vma_pf == NULL) { -+ continue; -+ } -+ for (i = 0; i < pid_params->vmas->vma_cnt; i++) { -+ if (is_share(&vma_pf[i])) { -+ sort_add_vma_pf(&vma_pf[i]); -+ } -+ } -+ } -+ -+ vma_pf = g_share_vma_head; -+ while (vma_pf != NULL) { -+ for (iter = vma_pf->next, count = 1; iter != NULL && iter->vma->inode == vma_pf->vma->inode; iter = iter->next, count++) { -+ ; -+ } -+ if (count > 1) { -+ if (do_merge_vma_pf(vma_pf, count) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "merge vma with inode %lld fail\n", vma_pf->vma->inode); -+ g_share_vma_head = NULL; -+ return -1; -+ } -+ } -+ vma_pf = iter; -+ } -+ g_share_vma_head = NULL; -+ return 0; -+} -+ -+static int cslide_get_vmas(struct cslide_pid_params *pid_params) -+{ -+ struct cslide_task_params *task_params = pid_params->task_params; -+ struct vma *vma = NULL; -+ char pid[PID_STR_MAX_LEN] = {0}; -+ uint64_t i; -+ -+ if (snprintf_s(pid, PID_STR_MAX_LEN, PID_STR_MAX_LEN - 1, "%u", pid_params->pid) <= 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "sprintf pid %u fail\n", pid_params->pid); -+ return -1; -+ } -+ pid_params->vmas = get_vmas_with_flags(pid, task_params->vmflags_array, task_params->vmflags_num, task_params->anon_only); -+ if (pid_params->vmas == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "get vmas for %s fail\n", pid); -+ return -1; -+ } -+ -+ pid_params->vma_pf = calloc(pid_params->vmas->vma_cnt, sizeof(struct vma_pf)); -+ if (pid_params->vma_pf == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc memory for vma_pf fail\n"); -+ goto free_vmas; -+ } -+ -+ vma = pid_params->vmas->vma_list; -+ for (i = 0; i < pid_params->vmas->vma_cnt; i++) { -+ pid_params->vma_pf[i].vma = vma; -+ vma = vma->next; -+ } -+ return 0; -+ -+free_vmas: -+ free_vmas(pid_params->vmas); -+ pid_params->vmas = NULL; -+ return -1; -+} -+ -+static void cslide_free_vmas(struct cslide_pid_params *params) -+{ -+ uint64_t i; -+ -+ if (params->vmas == NULL) { -+ return; -+ } -+ -+ for (i = 0; i < params->vmas->vma_cnt; i++) { -+ clean_page_refs_unexpected(¶ms->vma_pf[i].page_refs); -+ } -+ free(params->vma_pf); -+ params->vma_pf = NULL; -+ free_vmas(params->vmas); -+ params->vmas = NULL; -+} -+ -+static int cslide_scan_vmas(struct cslide_pid_params *params) -+{ -+ char pid[PID_STR_MAX_LEN] = {0}; -+ struct vmas *vmas = params->vmas; -+ struct vma *vma = NULL; -+ struct vma_pf *vma_pf = NULL; -+ FILE *scan_fp = NULL; -+ struct walk_address walk_address; -+ uint64_t i; -+ int fd; -+ -+ if (snprintf_s(pid, PID_STR_MAX_LEN, PID_STR_MAX_LEN - 1, "%u", params->pid) <= 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "snpintf pid %u fail\n", params->pid); -+ return -1; -+ } -+ -+ scan_fp = etmemd_get_proc_file(pid, IDLE_SCAN_FILE, SCAN_AS_HUGE, "r"); -+ if (scan_fp == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "open %s file for pid %u fail\n", IDLE_SCAN_FILE, params->pid); -+ params->vma_pf = NULL; -+ return -1; -+ } -+ -+ fd = fileno(scan_fp); -+ if (fd == -1) { -+ fclose(scan_fp); -+ etmemd_log(ETMEMD_LOG_ERR, "fileno file fail for %s\n", IDLE_SCAN_FILE); -+ return -1; -+ } -+ for (i = 0; i < vmas->vma_cnt; i++) { -+ vma_pf = ¶ms->vma_pf[i]; -+ vma = vma_pf->vma; -+ walk_address.walk_start = vma->start; -+ walk_address.walk_end = vma->end; -+ if (walk_vmas(fd, &walk_address, &vma_pf->page_refs, NULL) == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "scan vma start %llu end %llu fail\n", vma->start, vma->end); -+ cslide_free_vmas(params); -+ fclose(scan_fp); -+ return -1; -+ } -+ } -+ -+ fclose(scan_fp); -+ return 0; -+} -+ -+static int cslide_do_scan(struct cslide_eng_params *eng_params) -+{ -+ struct cslide_pid_params *iter = NULL; -+ int i; -+ -+ factory_foreach_working_pid_params(iter, &eng_params->factory) { -+ if (cslide_get_vmas(iter) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "cslide get vmas fail\n"); -+ continue; -+ } -+ } -+ -+ for (i = 0; i < eng_params->loop; i++) { -+ factory_foreach_working_pid_params(iter, &eng_params->factory) { -+ if (iter->vmas == NULL) { -+ continue; -+ } -+ if (cslide_scan_vmas(iter) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "cslide scan vmas fail\n"); -+ continue; -+ } -+ } -+ sleep(eng_params->sleep); -+ } -+ -+ if (cslide_merge_share_vmas(eng_params) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "cslide merge share vams fail\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int do_migrate_pages(unsigned int pid, struct page_refs *page_refs, int node) -+{ -+ int batch_size = BATCHSIZE; -+ int ret = -1; -+ void **pages = NULL; -+ int *nodes = NULL; -+ int *status = NULL; -+ int actual_num = 0; -+ -+ if (page_refs == NULL) { -+ return 0; -+ } -+ -+ nodes = malloc(sizeof(int) * batch_size); -+ if (nodes == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "malloc nodes fail\n"); -+ return -1; -+ } -+ -+ status = malloc(sizeof(int) * batch_size); -+ if (status == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "malloc status fail\n"); -+ goto free_nodes; -+ } -+ -+ pages = malloc(sizeof(void *) * batch_size); -+ if (pages == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "malloc pages fail\n"); -+ goto free_status; -+ } -+ while (page_refs != NULL) { -+ pages[actual_num] = (void *)page_refs->addr; -+ nodes[actual_num] = node; -+ actual_num++; -+ page_refs = page_refs->next; -+ if (actual_num == batch_size || page_refs == NULL) { -+ ret = move_pages(pid, actual_num, pages, nodes, status, MPOL_MF_MOVE_ALL); -+ actual_num = 0; -+ if (ret != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "task %d move_pages fail with %d errno %d\n", pid, ret, errno); -+ continue; -+ } -+ } -+ } -+ -+ free(pages); -+ pages = NULL; -+free_status: -+ free(status); -+ status = NULL; -+free_nodes: -+ free(nodes); -+ nodes = NULL; -+ return ret; -+} -+ -+static int migrate_single_task(unsigned int pid, const struct memory_grade *memory_grade, int hot_node, int cold_node) -+{ -+ int ret = -1; -+ -+ if (do_migrate_pages(pid, memory_grade->cold_pages, cold_node) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "migrate cold pages fail\n"); -+ return ret; -+ } -+ -+ if (do_migrate_pages(pid, memory_grade->hot_pages, hot_node) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "migrate hot pages fail\n"); -+ return ret; -+ } -+ -+ ret = 0; -+ return ret; -+} -+ -+static int cslide_do_migrate(struct cslide_eng_params *eng_params) -+{ -+ struct cslide_pid_params *iter = NULL; -+ struct node_pair *pair = NULL; -+ int bind_node, i; -+ -+ factory_foreach_working_pid_params(iter, &eng_params->factory) { -+ for (i = 0; i < eng_params->node_map.cur_num; i++) { -+ pair = &eng_params->node_map.pair[i]; -+ bind_node = pair->hot_node < pair->cold_node ? pair->hot_node : pair->cold_node; -+ if (numa_run_on_node(bind_node) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "fail to run on node %d to migrate memory\n", bind_node); -+ } -+ migrate_single_task(iter->pid, &iter->memory_grade[i], pair->hot_node, pair->cold_node); -+ } -+ } -+ if (numa_run_on_node(-1) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "fail to run on all node after migrate memory\n"); -+ } -+ return 0; -+} -+ -+static bool is_node_empty(struct node_mem *mem) -+{ -+ return mem->huge_free == mem->huge_total; -+} -+ -+static bool is_all_cold_node_empty(struct cslide_eng_params *eng_params) -+{ -+ struct sys_mem *mem = &eng_params->mem; -+ struct node_pair *pair = NULL; -+ int i; -+ -+ for (i = 0; i < eng_params->node_map.cur_num; i++) { -+ pair = &eng_params->node_map.pair[i]; -+ if (!is_node_empty(&mem->node_mem[pair->cold_node])) { -+ return false; -+ } -+ } -+ return true; -+} -+ -+static inline bool is_busy(int node_watermark, long long total, long long free) -+{ -+ return free * TO_PCT / total < node_watermark; -+} -+ -+static bool is_node_busy(int node_watermark, struct node_mem *mem) -+{ -+ return is_busy(node_watermark, mem->huge_total, mem->huge_free); -+} -+ -+static bool is_any_hot_node_busy(struct cslide_eng_params *eng_params) -+{ -+ struct sys_mem *mem = &eng_params->mem; -+ struct node_pair *pair = NULL; -+ int node_watermark = eng_params->node_watermark; -+ int i; -+ -+ for (i = 0; i < eng_params->node_map.cur_num; i++) { -+ pair = &eng_params->node_map.pair[i]; -+ if (is_node_busy(node_watermark, &mem->node_mem[pair->hot_node])) { -+ return true; -+ } -+ } -+ -+ return false; -+} -+ -+static bool need_migrate(struct cslide_eng_params *eng_params) -+{ -+ if (!is_all_cold_node_empty(eng_params)) { -+ return true; -+ } -+ if (is_any_hot_node_busy(eng_params)) { -+ return true; -+ } -+ -+ return false; -+} -+ -+static void get_node_pages_info(struct cslide_pid_params *pid_params) -+{ -+ struct cslide_eng_params *eng_params = pid_params->eng_params; -+ int n, c; -+ int t = eng_params->hot_threshold; -+ int count = pid_params->count; -+ int actual_t = t > count ? count + 1 : t; -+ int node_num = pid_params->count_page_refs->node_num; -+ struct node_pages_info *info = pid_params->node_pages_info; -+ -+ for (n = 0; n < node_num; n++) { -+ info[n].cold = 0; -+ info[n].hot = 0; -+ -+ for (c = 0; c < actual_t; c++) { -+ info[n].cold += pid_params->count_page_refs[c].node_pfs[n].num * 2 * 1024; -+ } -+ for (; c <= count; c++) { -+ info[n].hot += pid_params->count_page_refs[c].node_pfs[n].num * 2 * 1024; -+ } -+ } -+} -+ -+static void cslide_stat(struct cslide_eng_params *eng_params) -+{ -+ struct cslide_pid_params *iter = NULL; -+ -+ pthread_mutex_lock(&eng_params->stat_mtx); -+ factory_foreach_working_pid_params(iter, &eng_params->factory) { -+ get_node_pages_info(iter); -+ } -+ eng_params->stat_time = time(NULL); -+ pthread_mutex_unlock(&eng_params->stat_mtx); -+} -+ -+static void cslide_clean_params(struct cslide_eng_params *eng_params) -+{ -+ struct cslide_pid_params *iter = NULL; -+ -+ factory_foreach_pid_params(iter, &eng_params->factory) { -+ clean_pid_param(iter); -+ cslide_free_vmas(iter); -+ } -+} -+ -+static void destroy_cslide_eng_params(struct cslide_eng_params *params) -+{ -+ destroy_factory(¶ms->factory); -+ pthread_mutex_destroy(¶ms->stat_mtx); -+ destroy_node_map(¶ms->node_map); -+ destroy_sys_mem(¶ms->mem); -+} -+ -+static int init_cslide_eng_params(struct cslide_eng_params *params) -+{ -+ if (init_sys_mem(¶ms->mem) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "init system memory fail\n"); -+ return -1; -+ } -+ -+ if (init_node_map(¶ms->node_map, params->mem.node_num) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "init_node_map fail\n"); -+ goto destroy_sys_mem; -+ } -+ -+ if (pthread_mutex_init(¶ms->stat_mtx, NULL) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "init stat mutex fail\n"); -+ goto destroy_node_map; -+ } -+ -+ if (init_factory(¶ms->factory) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "init params factory fail\n"); -+ goto destroy_stat_mtx; -+ } -+ -+ return 0; -+ -+destroy_stat_mtx: -+ pthread_mutex_destroy(¶ms->stat_mtx); -+ -+destroy_node_map: -+ destroy_node_map(¶ms->node_map); -+ -+destroy_sys_mem: -+ destroy_sys_mem(¶ms->mem); -+ return -1; -+} -+ -+static void *cslide_main(void *arg) -+{ -+ struct cslide_eng_params *eng_params = (struct cslide_eng_params *)arg; -+ struct sys_mem *mem = NULL; -+ -+ while (true) { -+ factory_update_pid_params(&eng_params->factory); -+ if (eng_params->finish) { -+ etmemd_log(ETMEMD_LOG_DEBUG, "cslide task is stopping...\n"); -+ break; -+ } -+ if (factory_working_empty(&eng_params->factory)) { -+ goto next; -+ } -+ -+ mem = &eng_params->mem; -+ if (get_sys_mem(mem) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get system meminfo fail\n"); -+ goto next; -+ } -+ -+ if (cslide_do_scan(eng_params) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "cslide_do_scan fail\n"); -+ goto next; -+ } -+ -+ if (cslide_policy(eng_params) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "cslide_policy fail\n"); -+ goto next; -+ } -+ -+ if (!need_migrate(eng_params)) { -+ etmemd_log(ETMEMD_LOG_DEBUG, "no need to migrate\n"); -+ goto next; -+ } -+ -+ if (cslide_do_migrate(eng_params) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "cslide_do_migrate fail\n"); -+ goto next; -+ } -+ -+next: -+ cslide_stat(eng_params); -+ sleep(eng_params->interval); -+ cslide_clean_params(eng_params); -+ } -+ -+ factory_update_pid_params(&eng_params->factory); -+ destroy_cslide_eng_params(eng_params); -+ free(eng_params); -+ return NULL; -+} -+ -+static int cslide_alloc_pid_params(struct engine *eng, struct task_pid **tk_pid) -+{ -+ struct cslide_eng_params *eng_params = (struct cslide_eng_params *)eng->params; -+ unsigned pid = (*tk_pid)->pid; -+ struct cslide_pid_params *pid_params = NULL; -+ -+ pid_params = alloc_pid_params(eng_params); -+ if (pid_params == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc cslide pid params fail\n"); -+ return -1; -+ } -+ -+ pid_params->pid = pid; -+ pid_params->eng_params = eng_params; -+ pid_params->task_params = (*tk_pid)->tk->params; -+ (*tk_pid)->params = pid_params; -+ return 0; -+} -+ -+static void cslide_free_pid_params(struct engine *eng, struct task_pid **tk_pid) -+{ -+ struct cslide_eng_params *eng_params = (struct cslide_eng_params *)eng->params; -+ -+ if ((*tk_pid)->params != NULL) { -+ /* clear pid params in factory_update_pid_params in cslide_main */ -+ factory_free_pid_params(&eng_params->factory, (*tk_pid)->params); -+ (*tk_pid)->params = NULL; -+ } -+} -+ -+static int cslide_start_task(struct engine *eng, struct task *tk) -+{ -+ struct cslide_eng_params *eng_params = (struct cslide_eng_params *)eng->params; -+ struct task_pid *task_pid = NULL; -+ -+ for (task_pid = tk->pids; task_pid != NULL; task_pid = task_pid->next) { -+ factory_add_pid_params(&eng_params->factory, task_pid->params); -+ } -+ -+ return 0; -+} -+ -+static void cslide_stop_task(struct engine *eng, struct task *tk) -+{ -+ struct cslide_eng_params *eng_params = (struct cslide_eng_params *)eng->params; -+ struct task_pid *task_pid = NULL; -+ -+ for (task_pid = tk->pids; task_pid != NULL; task_pid = task_pid->next) { -+ factory_remove_pid_params(&eng_params->factory, task_pid->params); -+ } -+} -+ -+static char *get_time_stamp(time_t *t) -+{ -+ char *ts = asctime(localtime(t)); -+ size_t len = strlen(ts); -+ -+ if (ts[len - 1] == '\n') { -+ ts[len - 1] = '\0'; -+ } -+ return ts; -+} -+ -+static int show_task_pages(void *params, int fd) -+{ -+ struct cslide_pid_params *pid_params = (struct cslide_pid_params *)params; -+ struct cslide_eng_params *eng_params = pid_params->eng_params; -+ int node_num = pid_params->count_page_refs->node_num; -+ struct node_pages_info *info = pid_params->node_pages_info; -+ char *time_str = NULL; -+ int n; -+ -+ time_str = get_time_stamp(&eng_params->stat_time); -+ if (time_str != NULL) { -+ dprintf_all(fd, "[%s] ", time_str); -+ } -+ dprintf_all(fd, "task %d pages info (KB):\n", pid_params->pid); -+ dprintf_all(fd, "%5s %10s %10s %10s\n", "node", "used", "hot", "cold"); -+ for (n = 0; n < node_num; n++) { -+ dprintf_all(fd, "%5d %10d %10d %10d\n", n, -+ info[n].hot + info[n].cold, info[n].hot, info[n].cold); -+ } -+ return 0; -+} -+ -+static struct cslide_cmd_item g_task_cmd_items[] = { -+ {"showtaskpages", show_task_pages}, -+}; -+ -+static int show_host_pages(void *params, int fd) -+{ -+ struct cslide_eng_params *eng_params = (struct cslide_eng_params *)params; -+ struct cslide_pid_params *iter = NULL; -+ char *time_str = NULL; -+ int node_num = eng_params->mem.node_num; -+ int n; -+ uint32_t total; -+ struct node_pages_info *info = calloc(node_num, sizeof(struct node_pages_info)); -+ -+ if (info == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc memory for node_page_info fail\n"); -+ return -1; -+ } -+ -+ factory_foreach_working_pid_params(iter, &eng_params->factory) { -+ for (n = 0; n < node_num; n++) { -+ info[n].hot += iter->node_pages_info[n].hot; -+ info[n].cold += iter->node_pages_info[n].cold; -+ } -+ } -+ -+ time_str = get_time_stamp(&eng_params->stat_time); -+ if (time_str != NULL) { -+ dprintf_all(fd, "[%s] ", time_str); -+ } -+ dprintf_all(fd, "host pages info (KB):\n"); -+ dprintf_all(fd, "%5s %10s %10s %10s %10s\n", "node", "total", "used", "hot", "cold"); -+ for (n = 0; n < node_num; n++) { -+ total = eng_params->mem.node_mem[n].huge_total / 1024; -+ dprintf_all(fd, "%5d %10d %10d %10d %10d\n", -+ n, total, info[n].hot + info[n].cold, info[n].hot, info[n].cold); -+ } -+ -+ free(info); -+ return 0; -+} -+ -+struct cslide_cmd_item g_host_cmd_items[] = { -+ {"showhostpages", show_host_pages}, -+}; -+ -+static struct cslide_cmd_item *find_cmd_item(struct cslide_cmd_item *items, unsigned n, char *cmd) -+{ -+ unsigned i; -+ -+ for (i = 0; i < n; i++) { -+ if (strcmp(cmd, items[i].name) == 0) { -+ return &items[i]; -+ } -+ } -+ -+ return NULL; -+} -+ -+static int cslide_engine_do_cmd(struct engine *eng, struct task *tk, char *cmd, int fd) -+{ -+ struct cslide_eng_params *eng_params = (struct cslide_eng_params *)eng->params; -+ struct cslide_pid_params *pid_params = NULL; -+ struct cslide_cmd_item *item = NULL; -+ int ret; -+ -+ if (factory_working_empty(&eng_params->factory)) { -+ etmemd_log(ETMEMD_LOG_ERR, "no working pid under this cslide engine\n"); -+ return -1; -+ } -+ -+ item = find_cmd_item(g_host_cmd_items, ARRAY_SIZE(g_host_cmd_items), cmd); -+ if (item != NULL) { -+ pthread_mutex_lock(&eng_params->stat_mtx); -+ ret = item->func(eng_params, fd); -+ pthread_mutex_unlock(&eng_params->stat_mtx); -+ return ret; -+ } -+ -+ item = find_cmd_item(g_task_cmd_items, ARRAY_SIZE(g_task_cmd_items), cmd); -+ if (item == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "cslide cmd %s is not supportted\n", cmd); -+ return -1; -+ } -+ if (tk == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "task for cslide cmd %s not found\n", cmd); -+ return -1; -+ } -+ -+ if (tk->pids == NULL || tk->pids->params == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "task %s for cslide cmd %s not started\n", tk->name, cmd); -+ return -1; -+ } -+ -+ pid_params = (struct cslide_pid_params *)tk->pids->params; -+ pthread_mutex_lock(&eng_params->stat_mtx); -+ ret = item->func(pid_params, fd); -+ pthread_mutex_unlock(&eng_params->stat_mtx); -+ return ret; -+} -+ -+static int fill_task_anon_only(void *obj, void *val) -+{ -+ int ret = 0; -+ struct cslide_task_params *params = (struct cslide_task_params *)obj; -+ char *anon_only = (char *)val; -+ -+ if (strcmp(anon_only, "yes") == 0) { -+ params->anon_only = true; -+ } else if (strcmp(anon_only, "no") == 0) { -+ params->anon_only = false; -+ } else { -+ etmemd_log(ETMEMD_LOG_ERR, "only_anon : not support %s\n", anon_only); -+ etmemd_log(ETMEMD_LOG_ERR, "only_anon : only support yes/no\n"); -+ ret = -1; -+ } -+ free(val); -+ return ret; -+} -+ -+static int fill_task_vm_flags(void *obj, void *val) -+{ -+ struct cslide_task_params *params = (struct cslide_task_params *)obj; -+ char *vm_flags = (char *)val; -+ -+ params->vmflags_num = split_vmflags(¶ms->vmflags_array, vm_flags); -+ if (params->vmflags_num <= 0) { -+ free(val); -+ etmemd_log(ETMEMD_LOG_ERR, "fill vm flags fail\n"); -+ return -1; -+ } -+ -+ params->vmflags_str = vm_flags; -+ if (params->vmflags_num != 1 || strcmp(params->vmflags_array[0], "ht") != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "cslide only work with ht set\n"); -+ return -1; -+ } -+ return 0; -+} -+ -+static struct config_item g_cslide_task_config_items[] = { -+ {"vm_flags", STR_VAL, fill_task_vm_flags, false}, -+ {"anon_only", STR_VAL, fill_task_anon_only, false}, -+}; -+ -+static int cslide_fill_task(GKeyFile *config, struct task *tk) -+{ -+ struct cslide_task_params *params = calloc(1, sizeof(struct cslide_task_params)); -+ -+ if (params == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc cslide task params fail\n"); -+ return -1; -+ } -+ -+ if (parse_file_config(config, TASK_GROUP, g_cslide_task_config_items, -+ ARRAY_SIZE(g_cslide_task_config_items), (void *)params) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "cslide fill task params fail\n"); -+ goto exit; -+ } -+ -+ tk->params = params; -+ if (etmemd_get_task_pids(tk) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "cslide fail to get task pids\n"); -+ tk->params = NULL; -+ goto exit; -+ } -+ return 0; -+ -+exit: -+ clear_task_params(params); -+ free(params); -+ return -1; -+} -+ -+static void cslide_clear_task(struct task *tk) -+{ -+ /* clear cslide task params when clear connected cslide pid params */ -+ etmemd_free_task_pids(tk); -+ tk->params = NULL; -+} -+ -+static int fill_node_pair(void *obj, void *val) -+{ -+ struct cslide_eng_params *params = (struct cslide_eng_params *)obj; -+ char *node_pair_str = (char *)val; -+ char *pair = NULL; -+ char *saveptr_pair = NULL; -+ char *hot_node_str = NULL; -+ char *cold_node_str = NULL; -+ char *saveptr_node = NULL; -+ int hot_node, cold_node; -+ struct node_map *map = ¶ms->node_map; -+ struct node_verifier nv; -+ char *pair_delim = " ;"; -+ char *node_delim = " ,"; -+ int ret = -1; -+ -+ if (init_node_verifier(&nv, params->mem.node_num) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "init_node_verifier fail\n"); -+ free(val); -+ return ret; -+ } -+ -+ for (pair = strtok_r(node_pair_str, pair_delim, &saveptr_pair); pair != NULL; pair = strtok_r(NULL, pair_delim, &saveptr_pair)) { -+ hot_node_str = strtok_r(pair, node_delim, &saveptr_node); -+ if (hot_node_str == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "parse hot node failed\n"); -+ goto err; -+ } -+ -+ cold_node_str = strtok_r(NULL, node_delim, &saveptr_node); -+ if (cold_node_str == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "parse cold node failed\n"); -+ goto err; -+ } -+ -+ if (get_int_value(hot_node_str, &hot_node) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "transfer hot node %s to integer fail\n", hot_node_str); -+ goto err; -+ } -+ -+ if (get_int_value(cold_node_str, &cold_node) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "transfer cold node %s to integer fail\n", cold_node_str); -+ goto err; -+ } -+ -+ if (!is_node_valid(&nv, hot_node) || !is_node_valid(&nv, cold_node)) { -+ etmemd_log(ETMEMD_LOG_ERR, "node %d(hot)->%d(cold) invalid\n", hot_node, cold_node); -+ goto err; -+ } -+ -+ if (add_node_pair(map, cold_node, hot_node) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "add %d(hot)->%d(cold) fail\n", hot_node, cold_node); -+ goto err; -+ } -+ } -+ -+ if (has_node_unmap(&nv)) { -+ etmemd_log(ETMEMD_LOG_ERR, "there is node unmap\n"); -+ goto err; -+ } -+ ret = 0; -+ -+err: -+ free(val); -+ destroy_node_verifier(&nv); -+ return ret; -+} -+ -+static int fill_migrate_watermark(void *obj, void *val) -+{ -+ struct cslide_eng_params *params = (struct cslide_eng_params *)obj; -+ int wm = parse_to_int(val); -+ -+ if (wm < MIN_WM || wm > MAX_WM) { -+ etmemd_log(ETMEMD_LOG_ERR, "migrate watermark %d invalid\n", wm); -+ return -1; -+ } -+ params->node_watermark = wm; -+ return 0; -+} -+ -+static int fill_hot_threshold(void *obj, void *val) -+{ -+ struct cslide_eng_params *params = (struct cslide_eng_params *)obj; -+ int t = parse_to_int(val); -+ -+ if (t < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "config hot threshold %d not valid\n", t); -+ return -1; -+ } -+ -+ params->hot_threshold = t; -+ return 0; -+} -+ -+static int fill_hot_reserve(void *obj, void *val) -+{ -+ struct cslide_eng_params *params = (struct cslide_eng_params *)obj; -+ int hot_reserve = parse_to_int(val); -+ -+ params->hot_reserve = hot_reserve; -+ return 0; -+} -+ -+static int fill_mig_quota(void *obj, void *val) -+{ -+ struct cslide_eng_params *params = (struct cslide_eng_params *)obj; -+ int mig_quota = parse_to_int(val); -+ -+ params->mig_quota = mig_quota; -+ return 0; -+} -+ -+static struct config_item cslide_eng_config_items[] = { -+ {"node_pair", STR_VAL, fill_node_pair, false}, -+ {"node_watermark", INT_VAL, fill_migrate_watermark, false}, -+ {"hot_threshold", INT_VAL, fill_hot_threshold, false}, -+ {"node_mig_quota", INT_VAL, fill_mig_quota, false}, -+ {"node_hot_reserve", INT_VAL, fill_hot_reserve, false}, -+}; -+ -+static int cslide_fill_eng(GKeyFile *config, struct engine *eng) -+{ -+ struct cslide_eng_params *params = calloc(1, sizeof(struct cslide_eng_params)); -+ -+ if (params == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc cslide engine params fail\n"); -+ return -1; -+ } -+ -+ if (init_cslide_eng_params(params) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "init cslide engine params fail\n"); -+ return -1; -+ } -+ -+ params->loop = eng->proj->loop; -+ params->interval = eng->proj->interval; -+ params->sleep = eng->proj->sleep; -+ if (parse_file_config(config, ENG_GROUP, cslide_eng_config_items, -+ ARRAY_SIZE(cslide_eng_config_items), (void *)params) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "cslide fill engine params fail\n"); -+ goto destroy_eng_params; -+ } -+ -+ eng->params = params; -+ if (pthread_create(¶ms->worker, NULL, cslide_main, params) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "start cslide main worker fail\n"); -+ goto destroy_eng_params; -+ } -+ -+ return 0; -+ -+destroy_eng_params: -+ destroy_cslide_eng_params(params); -+ return -1; -+} -+ -+static void cslide_clear_eng(struct engine *eng) -+{ -+ struct cslide_eng_params *eng_params = eng->params; -+ /* clear cslide engine params in cslide_main */ -+ eng_params->finish = true; -+ eng->params = NULL; -+} -+ -+struct engine_ops g_cslide_eng_ops = { -+ .fill_eng_params = cslide_fill_eng, -+ .clear_eng_params = cslide_clear_eng, -+ .fill_task_params = cslide_fill_task, -+ .clear_task_params = cslide_clear_task, -+ .alloc_pid_params = cslide_alloc_pid_params, -+ .free_pid_params = cslide_free_pid_params, -+ .start_task = cslide_start_task, -+ .stop_task = cslide_stop_task, -+ .eng_mgt_func = cslide_engine_do_cmd, -+}; -+ -+int fill_engine_type_cslide(struct engine *eng) -+{ -+ eng->ops = &g_cslide_eng_ops; -+ eng->engine_type = CSLIDE_ENGINE; -+ eng->name = "cslide"; -+ return 0; -+} -diff --git a/src/etmemd_src/etmemd_engine.c b/src/etmemd_src/etmemd_engine.c -index 41d8fa5..98a7430 100644 ---- a/src/etmemd_src/etmemd_engine.c -+++ b/src/etmemd_src/etmemd_engine.c -@@ -17,38 +17,82 @@ - #include - #include "etmemd_engine.h" - #include "etmemd_slide.h" -+#include "etmemd_cslide.h" - #include "etmemd_log.h" -+#include "etmemd_common.h" -+#include "etmemd_file.h" - --const char *etmemd_get_eng_name(enum eng_type type) -+struct engine_item { -+ char *name; -+ int (*fill_eng_func)(struct engine *eng); -+}; -+ -+static struct engine_item g_engine_items[] = { -+ {"slide", fill_engine_type_slide}, -+ {"cslide", fill_engine_type_cslide}, -+}; -+ -+static struct engine_item *find_engine_item(const char *name) - { -- if (type == SLIDE_ENGINE) { -- return "slide"; -+ unsigned i; -+ -+ for (i = 0; i < ARRAY_SIZE(g_engine_items); i++) { -+ if (strcmp(name, g_engine_items[i].name) == 0) { -+ return &g_engine_items[i]; -+ } - } - -- return ""; -+ return NULL; - } - --struct engine_item g_eng_items[ENGINE_TYPE_CNT] = { -- {SLIDE_ENGINE, fill_engine_type_slide}, --}; -- --int fill_engine_type(struct engine *eng, const char *val) -+struct engine *etmemd_engine_add(GKeyFile *config) - { -- int ret = -1; -- int i; -+ struct engine *eng = NULL; -+ struct engine_item *item = NULL; -+ char *name = NULL; - -- for (i = 0; i < ENGINE_TYPE_CNT; i++) { -- if (strcmp(val, etmemd_get_eng_name(g_eng_items[i].eng_type)) == 0) { -- ret = g_eng_items[i].fill_eng_func(eng); -- break; -- } -+ if (g_key_file_has_key(config, ENG_GROUP, "name", NULL) == FALSE) { -+ etmemd_log(ETMEMD_LOG_ERR, "engine name is not set\n"); -+ return NULL; - } - -- if (ret != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "invalid engine type %s\n", val); -- return -1; -+ name = g_key_file_get_string(config, ENG_GROUP, "name", NULL); -+ if (name == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "get name string of engine fail\n"); -+ return NULL; - } -- return 0; --} - -+ item = find_engine_item(name); -+ if (item == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "engine %s not support\n", name); -+ goto free_name; -+ } - -+ eng = calloc(1, sizeof(struct engine)); -+ if (eng == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc memory for engine fail\n"); -+ goto free_name; -+ } -+ -+ if (item->fill_eng_func(eng) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "fill engine %s fail\n", name); -+ free(eng); -+ eng = NULL; -+ goto free_name; -+ } -+ -+ if (eng->ops == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "engine %s without operations\n", name); -+ free(eng); -+ eng = NULL; -+ } -+ -+free_name: -+ free(name); -+ return eng; -+} -+ -+void etmemd_engine_remove(struct engine *eng) -+{ -+ free(eng); -+} -diff --git a/src/etmemd_src/etmemd_file.c b/src/etmemd_src/etmemd_file.c -index 1115d7a..ac2654e 100644 ---- a/src/etmemd_src/etmemd_file.c -+++ b/src/etmemd_src/etmemd_file.c -@@ -13,444 +13,52 @@ - * Description: File operation API. - ******************************************************************************/ - --#include --#include --#include --#include -- --#include "securec.h" - #include "etmemd_log.h" --#include "etmemd_common.h" --#include "etmemd_project.h" --#include "etmemd_engine.h" - #include "etmemd_file.h" - --#define MAX_INTERVAL_VALUE 1200 --#define MAX_SLEEP_VALUE 1200 --#define MAX_LOOP_VALUE 120 -- --static int fill_project_interval(struct project *proj, const char *val) -+static int parse_item(GKeyFile *config, char *group_name, struct config_item *item, void *obj) - { -- int value; -- -- if (get_int_value(val, &value) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "invalid project interval value.\n"); -- return -1; -- } -- -- if (value < 1 || value > MAX_INTERVAL_VALUE) { -- etmemd_log(ETMEMD_LOG_ERR, "invalid project interval value, must between 1 and 1200.\n"); -- return -1; -- } -- -- proj->interval = value; -- -- return 0; --} -+ GError *error = NULL; -+ void *val; - --static int fill_project_loop(struct project *proj, const char *val) --{ -- int value; -- -- if (get_int_value(val, &value) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "invalid project loop value.\n"); -- return -1; -- } -- -- if (value < 1 || value > MAX_LOOP_VALUE) { -- etmemd_log(ETMEMD_LOG_ERR, "invalid project loop value, must between 1 and 120.\n"); -- return -1; -- } -- -- proj->loop = value; -- -- return 0; --} -- --static int fill_project_sleep(struct project *proj, const char *val) --{ -- int value; -- -- if (get_int_value(val, &value) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "invalid project sleep value.\n"); -- return -1; -- } -- -- if (value < 1 || value > MAX_SLEEP_VALUE) { -- etmemd_log(ETMEMD_LOG_ERR, "invalid project sleep value, must between 1 and 1200.\n"); -- return -1; -- } -- -- proj->sleep = value; -- -- return 0; --} -- --static struct project_item g_project_items[] = { -- {"interval", fill_project_interval, false, false}, -- {"loop", fill_project_loop, false, false}, -- {"sleep", fill_project_sleep, false, false}, -- {NULL, NULL, false, false}, --}; -- --static int fill_project_params(struct project *proj, const char *key, -- const char *val) --{ -- int ret = -1; -- int i = 0; -- -- while (g_project_items[i].proj_sec_name != NULL) { -- if (strcmp(key, g_project_items[i].proj_sec_name) == 0) { -- ret = g_project_items[i].fill_proj_func(proj, val); -- break; -+ if (!g_key_file_has_key(config, group_name, item->key, NULL)) { -+ if (item->option) { -+ return 0; - } -- -- i++; -- } -- -- if (ret != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "parse %s project config section fail\n", key); -- return -1; -- } -- -- g_project_items[i].set = true; -- return 0; --} -- --static int fill_task_type(struct task *new_task, const char *val) --{ -- if (strcmp(val, "pid") != 0 && strcmp(val, "name") != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "invalid task type, must be pid or name.\n"); -- return -1; -- } -- -- if (new_task->type != NULL) { -- etmemd_log(ETMEMD_LOG_WARN, "duplicate config for task type.\n"); -- return 0; -- } -- -- new_task->type = calloc(1, strlen(val) + 1); -- if (new_task->type == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "malloc task type fail.\n"); -- return -1; -- } -- -- if (strncpy_s(new_task->type, strlen(val) + 1, val, strlen(val)) != EOK) { -- etmemd_log(ETMEMD_LOG_ERR, "strncpy_s for task type fail.\n"); -- free(new_task->type); -- new_task->type = NULL; -- return -1; -- } -- -- return 0; --} -- --static int fill_task_value(struct task *new_task, const char *val) --{ -- if (new_task->value != NULL) { -- etmemd_log(ETMEMD_LOG_WARN, "duplicate config for task value.\n"); -- return 0; -- } -- -- new_task->value = calloc(1, strlen(val) + 1); -- if (new_task->value == NULL) { -- etmemd_log(ETMEMD_LOG_WARN, "malloc task value fail.\n"); -- return -1; -- } -- -- if (strncpy_s(new_task->value, strlen(val) + 1, val, strlen(val)) != EOK) { -- etmemd_log(ETMEMD_LOG_ERR, "strncpy_s for task value fail.\n"); -- free(new_task->value); -- new_task->value = NULL; -- return -1; -- } -- -- return 0; --} -- --static int fill_task_engine(struct task *new_task, const char *val) --{ -- if (new_task->eng != NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "engine is already configured\n"); -- return -1; -- } -- -- new_task->eng = (struct engine *)calloc(1, sizeof(struct engine)); -- if (new_task->eng == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "malloc engine fail\n"); -- return -1; -- } -- -- new_task->eng->task = (void *)new_task; -- -- if (fill_engine_type(new_task->eng, val) != 0) { -- free(new_task->eng); -- new_task->eng = NULL; -- return -1; -- } -- -- return 0; --} -- --static int fill_task_max_threads(struct task *new_task, const char *val) --{ -- int value; -- int core; -- -- if (get_int_value(val, &value) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "invalid task max_threads value.\n"); -+ etmemd_log(ETMEMD_LOG_ERR, "key %s not set for group %s\n", item->key, group_name); - return -1; - } - -- if (value <= 0) { -- etmemd_log(ETMEMD_LOG_WARN, -- "Thread count is abnormal, set the default minimum of current thread count to 1\n"); -- value = 1; -- } -- -- core = get_nprocs(); -- /* -- * For IO intensive businesses, -- * max-threads is limited to 2N+1 of the maximum number of threads -- * */ -- if (value > 2 * core + 1) { -- etmemd_log(ETMEMD_LOG_WARN, -- "max-threads is limited to 2N+1 of the maximum number of threads\n"); -- value = 2 * core + 1; -- } -- -- new_task->max_threads = value; -- -- return 0; --} -- --static struct task_item g_task_items[] = { -- {"type", fill_task_type, false, false}, -- {"value", fill_task_value, false, false}, -- {"engine", fill_task_engine, false, false}, -- {"max_threads", fill_task_max_threads, true, false}, -- {NULL, NULL, false, false}, --}; -- --static int fill_task_params(struct task *new_task, const char *key, -- const char *val) --{ -- int ret = -1; -- int i = 0; -- -- while (g_task_items[i].task_sec_name != NULL) { -- if (strcmp(key, g_task_items[i].task_sec_name) == 0) { -- ret = g_task_items[i].fill_task_func(new_task, val); -+ switch (item->type) { -+ case INT_VAL: -+ val = (void *)(long long)g_key_file_get_integer(config, group_name, item->key, &error); - break; -- } -- -- i++; -- } -- -- if (ret != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "parse %s task config section fail\n", key); -- return -1; -- } -- -- g_task_items[i].set = true; -- return 0; --} -- --static int process_engine_param_keyword(const char *get_line, struct engine *eng, -- FILE *conf_file, int *is_param) --{ -- if (strcmp(get_line, "param") == 0) { -- if (eng == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "must configure engine type first\n"); -- return -1; -- } -- -- if (eng->parse_param_conf(eng, conf_file) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "parse engine parameters fail\n"); -+ case STR_VAL: -+ val = (void *)g_key_file_get_string(config, group_name, item->key, &error); -+ break; -+ default: -+ etmemd_log(ETMEMD_LOG_ERR, "config item type %d not support\n", item->type); - return -1; -- } -- -- *is_param = 1; -- } -- -- return 0; --} -- --static bool etmemd_check_task_params(void) --{ -- int i = 0; -- -- while (g_task_items[i].task_sec_name != NULL) { -- /* do not check for the parameter which is optional */ -- if (g_task_items[i].optional) { -- i++; -- continue; -- } -- -- /* and the other parameters must be set */ -- if (!g_task_items[i].set) { -- etmemd_log(ETMEMD_LOG_ERR, "%s section must be set for task parameters\n", -- g_task_items[i].task_sec_name); -- return false; -- } -- -- /* reset the flag of set of the section, and no need to do this for the optional ones */ -- g_task_items[i].set = false; -- i++; - } - -- return true; --} -- --/* -- * new_task created in this function is needed during the whole -- * process life cycle of etmemd, and will be released when -- * etmemd exit in function etmemd_free_task_struct -- * */ --static int get_task_params(FILE *conf_file, struct project *proj) --{ -- struct task *new_task = NULL; -- char key[KEY_VALUE_MAX_LEN] = {}; -- char value[KEY_VALUE_MAX_LEN] = {}; -- char *get_line = NULL; -- int is_param = 0; -- -- new_task = (struct task *)calloc(1, sizeof(struct task)); -- if (new_task == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "malloc task fail\n"); -+ if (error != NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "get value of key %s fail\n", item->key); - return -1; - } - -- new_task->proj = proj; -- new_task->next = proj->tasks; -- /* set default count of the thread pool to 1 */ -- new_task->max_threads = 1; -- -- while ((get_line = skip_blank_line(conf_file)) != NULL) { -- if (strcmp(get_line, "policies") != 0) { -- if (process_engine_param_keyword(get_line, new_task->eng, -- conf_file, &is_param) != 0) { -- goto out_err; -- } -- -- if (is_param == 1) { -- is_param = 0; -- continue; -- } -- -- if (get_keyword_and_value(get_line, key, value) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "get task keyword and value fail\n"); -- goto out_err; -- } -- -- if (fill_task_params(new_task, key, value) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "fill task parameter fail\n"); -- goto out_err; -- } -- -- continue; -- } -- -- goto next_task; -- } -- --next_task: -- if (etmemd_check_task_params()) { -- proj->tasks = new_task; -- } else { -- goto out_err; -- } -- -- if (get_line == NULL) { -- return 0; -- } -- -- return get_task_params(conf_file, proj); -- --out_err: -- etmemd_free_task_struct(&new_task); -- return -1; -+ return item->fill(obj, val); - } - --static int get_project_params(FILE *conf_file, struct project *proj) -+int parse_file_config(GKeyFile *config, char *group_name, struct config_item *items, unsigned n, void *obj) - { -- char key[KEY_VALUE_MAX_LEN] = {}; -- char value[KEY_VALUE_MAX_LEN] = {}; -- char *get_line = NULL; -- -- while ((get_line = skip_blank_line(conf_file)) != NULL) { -- if (strcmp(get_line, "policies") != 0) { -- if (get_keyword_and_value(get_line, key, value) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "get project keyword and value fail\n"); -- return -1; -- } -- -- if (fill_project_params(proj, key, value) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "fill project parameter fail\n"); -- return -1; -- } -- -- continue; -- } -+ unsigned i; - -- if (get_task_params(conf_file, proj) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "get task parameters fail\n"); -+ for (i = 0; i < n; i++) { -+ if (parse_item(config, group_name, &items[i], obj) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "parse config key %s fail\n", items[i].key); - return -1; - } - } - - return 0; - } -- --static bool etmemd_check_project_params(void) --{ -- int i = 0; -- -- while (g_project_items[i].proj_sec_name != NULL) { -- /* do not check for the parameter which is optional */ -- if (g_project_items[i].optional) { -- i++; -- continue; -- } -- -- /* and the other parameters must be set */ -- if (!g_project_items[i].set) { -- etmemd_log(ETMEMD_LOG_ERR, "%s section must be set for project parameters\n", -- g_project_items[i].proj_sec_name); -- return false; -- } -- -- /* reset the flag of set of the section, and no need to do this for the optional ones */ -- g_project_items[i].set = false; -- i++; -- } -- -- return true; --} -- --int etmemd_fill_proj_by_conf(struct project *proj, FILE *conf_file) --{ -- char *get_line = NULL; -- -- get_line = skip_blank_line(conf_file); -- if (get_line == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "invalid config file, should not be empty\n"); -- return -1; -- } -- -- if (strcmp(get_line, "options") != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "invalid config file, must begin with \"options\"\n"); -- return -1; -- } -- -- if (get_project_params(conf_file, proj) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "get project parameters fail\n"); -- return -1; -- } -- -- if (!etmemd_check_project_params()) { -- return -1; -- } -- -- return 0; --} -diff --git a/src/etmemd_src/etmemd_migrate.c b/src/etmemd_src/etmemd_migrate.c -index 3e2f8e8..a7aa9b8 100644 ---- a/src/etmemd_src/etmemd_migrate.c -+++ b/src/etmemd_src/etmemd_migrate.c -@@ -69,7 +69,7 @@ static int etmemd_migrate_mem(const char *pid, const char *grade_path, struct pa - return 0; - } - -- fp = etmemd_get_proc_file(pid, grade_path, "r+"); -+ fp = etmemd_get_proc_file(pid, grade_path, 0, "r+"); - if (fp == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "cannot open %s for pid %s\n", grade_path, pid); - return -1; -diff --git a/src/etmemd_src/etmemd_pool_adapter.c b/src/etmemd_src/etmemd_pool_adapter.c -index 890aae8..417f864 100644 ---- a/src/etmemd_src/etmemd_pool_adapter.c -+++ b/src/etmemd_src/etmemd_pool_adapter.c -@@ -17,17 +17,18 @@ - #include - #include - #include "etmemd_pool_adapter.h" -+#include "etmemd_engine.h" - --static void push_ctrl_workflow(struct task_pid **tk_pid) -+static void push_ctrl_workflow(struct task_pid **tk_pid, void *(*exector)(void *)) - { - struct task_pid *curr_pid = NULL; - struct task *tk = (*tk_pid)->tk; - while (*tk_pid != NULL) { - if (threadpool_add_worker(tk->threadpool_inst, -- tk->workflow_engine, -+ exector, - (*tk_pid)) != 0) { - etmemd_log(ETMEMD_LOG_DEBUG, "Failed to push < pid %u, Task_value %s, project_name %s >\n", -- (*tk_pid)->pid, tk->value, tk->proj->name); -+ (*tk_pid)->pid, tk->value, tk->eng->proj->name); - curr_pid = *tk_pid; - *tk_pid = (*tk_pid)->next; - free_task_pid_mem(&curr_pid); -@@ -40,18 +41,19 @@ static void push_ctrl_workflow(struct task_pid **tk_pid) - - static void *launch_threadtimer_executor(void *arg) - { -- struct task *tk = (struct task *)arg; -+ struct task_executor *executor = (struct task_executor*)arg; -+ struct task *tk = executor->tk; - thread_pool *pool_inst = NULL; - bool done = false; - int execution_size; - int scheduing_count; - -- if (tk->proj->start) { -+ if (tk->eng->proj->start) { - if (etmemd_get_task_pids(tk) != 0) { - return NULL; - } - -- push_ctrl_workflow(&tk->pids); -+ push_ctrl_workflow(&tk->pids, executor->func); - - threadpool_notify(tk->threadpool_inst); - -@@ -72,32 +74,34 @@ static void *launch_threadtimer_executor(void *arg) - return NULL; - } - --int start_threadpool_work(struct task *tk) -+int start_threadpool_work(struct task_executor *executor) - { -+ struct task *tk = executor->tk; -+ - etmemd_log(ETMEMD_LOG_DEBUG, "start etmem for Task_value %s, project_name %s\n", -- tk->value, tk->proj->name); -+ tk->value, tk->eng->proj->name); - - /* create the threadpool first and it will start auto */ - tk->threadpool_inst = threadpool_create(tk->max_threads); - if (tk->threadpool_inst == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "Thread pool creation failed for project <%s> task <%s>.\n", -- tk->proj->name, tk->value); -+ tk->eng->proj->name, tk->value); - return -1; - } - -- tk->timer_inst = thread_timer_create(tk->proj->interval); -+ tk->timer_inst = thread_timer_create(tk->eng->proj->interval); - if (tk->timer_inst == NULL) { - threadpool_stop_and_destroy(&tk->threadpool_inst); - etmemd_log(ETMEMD_LOG_ERR, "Timer task creation failed for project <%s> task <%s>.\n", -- tk->proj->name, tk->value); -+ tk->eng->proj->name, tk->value); - return -1; - } - -- if (thread_timer_start(tk->timer_inst, launch_threadtimer_executor, tk) != 0) { -+ if (thread_timer_start(tk->timer_inst, launch_threadtimer_executor, executor) != 0) { - threadpool_stop_and_destroy(&tk->threadpool_inst); - thread_timer_destroy(&tk->timer_inst); - etmemd_log(ETMEMD_LOG_ERR, "Timer task start failed for project <%s> task <%s>.\n", -- tk->proj->name, tk->value); -+ tk->eng->proj->name, tk->value); - return -1; - } - -@@ -107,11 +111,11 @@ int start_threadpool_work(struct task *tk) - void stop_and_delete_threadpool_work(struct task *tk) - { - etmemd_log(ETMEMD_LOG_DEBUG, "stop and delete task <%s> of project <%s>\n", -- tk->value, tk->proj->name); -+ tk->value, tk->eng->proj->name); - - if (tk->timer_inst == NULL) { - etmemd_log(ETMEMD_LOG_DEBUG, "task <%s> of project <%s> has not been started, return\n", -- tk->value, tk->proj->name); -+ tk->value, tk->eng->proj->name); - return; - } - -diff --git a/src/etmemd_src/etmemd_project.c b/src/etmemd_src/etmemd_project.c -index 7ddc63f..9ead14c 100644 ---- a/src/etmemd_src/etmemd_project.c -+++ b/src/etmemd_src/etmemd_project.c -@@ -29,280 +29,612 @@ - #include "etmemd_file.h" - #include "etmemd_log.h" - -+#define MAX_INTERVAL_VALUE 1200 -+#define MAX_SLEEP_VALUE 1200 -+#define MAX_LOOP_VALUE 120 -+ - static SLIST_HEAD(project_list, project) g_projects = SLIST_HEAD_INITIALIZER(g_projects); - --static void free_before_delete_project(struct project *proj) -+static struct project *get_proj_by_name(const char *name) - { -- struct task *tmp_tk = NULL; -+ struct project *proj = NULL; -+ -+ SLIST_FOREACH(proj, &g_projects, entry) { -+ if (strcmp(proj->name, name) == 0) { -+ return proj; -+ } -+ } - -- etmemd_safe_free((void **)&proj->name); -+ return NULL; -+} - -- while (proj->tasks != NULL) { -- tmp_tk = proj->tasks; -- proj->tasks = proj->tasks->next; -+static struct engine *get_eng_by_name(struct project *proj, const char *name) -+{ -+ struct engine *eng = proj->engs; - -- etmemd_free_task_pids(tmp_tk); -- etmemd_free_task_struct(&tmp_tk); -+ while (eng != NULL) { -+ if (strcmp(eng->name, name) == 0) { -+ return eng; -+ } -+ eng = eng->next; - } -+ -+ return NULL; - } - --static FILE *memid_project_open_conf(const char *file_name) -+static struct task *get_task_by_name(struct project *proj, struct engine *eng, const char *name) - { -- FILE *file = NULL; -- char path[PATH_MAX] = {0}; -- struct stat info; -- int r; -- int fd; -+ struct task *tk = eng->tasks; - -- if (realpath(file_name, path) == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "%s should be real path.\n", file_name); -- return NULL; -+ while (tk != NULL) { -+ if (strcmp(tk->name, name) == 0) { -+ return tk; -+ } -+ tk = tk->next; - } - -- fd = open(path, O_RDONLY); -- if (fd == -1) { -- return NULL; -+ return NULL; -+} -+ -+static char *get_obj_key(char *obj_name, const char *group_name) -+{ -+ if (strcmp(obj_name, group_name) == 0) { -+ return "name"; -+ } else { -+ return obj_name; - } -+} -+ -+static enum opt_result project_of_group(GKeyFile *config, const char *group_name, struct project **proj) -+{ -+ *proj = NULL; -+ char *proj_name = NULL; -+ char *key = NULL; - -- r = fstat(fd, &info); -- if (r == -1) { -- close(fd); -- return NULL; -+ key = get_obj_key(PROJ_GROUP, group_name); -+ if (g_key_file_has_key(config, group_name, key, NULL) == FALSE) { -+ etmemd_log(ETMEMD_LOG_ERR, "project name is not set for %s\n", group_name); -+ return OPT_INVAL; - } - -- if (S_ISDIR(info.st_mode)) { -- etmemd_log(ETMEMD_LOG_ERR, "%s should be a file , not a folder.\n", path); -- close(fd); -- return NULL; -+ proj_name = g_key_file_get_string(config, group_name, key, NULL); -+ if (proj_name == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "get project name from %s fail\n", group_name); -+ return OPT_INTER_ERR; - } - -- file = fdopen(fd, "r"); -+ *proj = get_proj_by_name(proj_name); - -- return file; -+ free(proj_name); -+ return OPT_SUCCESS; - } - --static struct project *etmemd_project_init_struct(const char *project_name) -+static enum opt_result engine_of_group(GKeyFile *config, char *group_name, struct project *proj, struct engine **eng) - { -- struct project *proj = NULL; -+ char *key = NULL; -+ char *eng_name = NULL; -+ *eng = NULL; - -- proj = (struct project *)calloc(1, sizeof(struct project)); -- if (proj == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "malloc for project fail.\n"); -- return NULL; -+ key = get_obj_key(ENG_GROUP, group_name); -+ if (g_key_file_has_key(config, group_name, key, NULL) == FALSE) { -+ etmemd_log(ETMEMD_LOG_ERR, "engine is not set for %s\n", group_name); -+ return OPT_INVAL; - } - -- proj->name = calloc(1, strlen(project_name) + 1); -- if (proj->name == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "malloc project name fail.\n"); -- free(proj); -- return NULL; -+ eng_name = g_key_file_get_string(config, group_name, key, NULL); -+ if (eng_name == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "get engine name from %s fail\n", group_name); -+ return OPT_INTER_ERR; - } - -- if (strncpy_s(proj->name, strlen(project_name) + 1, project_name, -- strlen(project_name)) != EOK) { -- etmemd_log(ETMEMD_LOG_ERR, "strncpy_s for project name fail\n"); -- free(proj->name); -- proj->name = NULL; -- free(proj); -- return NULL; -+ *eng = get_eng_by_name(proj, eng_name); -+ free(eng_name); -+ return OPT_SUCCESS; -+} -+ -+static enum opt_result task_of_group(GKeyFile *config, char *group_name, struct project *proj, struct engine *eng, struct task **tk) -+{ -+ char *task_name = NULL; -+ char *key = NULL; -+ *tk = NULL; -+ -+ key = get_obj_key(TASK_GROUP, group_name); -+ if (g_key_file_has_key(config, group_name, key, NULL) == FALSE) { -+ etmemd_log(ETMEMD_LOG_ERR, "task name is not set for %s\n", group_name); -+ return OPT_INVAL; -+ } -+ -+ task_name = g_key_file_get_string(config, group_name, key, NULL); -+ if (task_name == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "get task name from %s fail\n", group_name); -+ return OPT_INTER_ERR; - } - -- return proj; -+ *tk = get_task_by_name(proj, eng, task_name); -+ free(task_name); -+ return OPT_SUCCESS; - } - --static struct project *get_proj_by_name(const char *name) -+static enum opt_result get_group_objs(GKeyFile *config, char *group_name, struct project **proj, struct engine **eng, struct task **tk) - { -- struct project *proj = NULL; -+ enum opt_result ret; - -- if (name == NULL || strlen(name) == 0) { -- etmemd_log(ETMEMD_LOG_ERR, "project name must be given and should not be empty.\n"); -- return NULL; -+ /* get project */ -+ ret = project_of_group(config, group_name, proj); -+ if (ret != OPT_SUCCESS) { -+ return ret; - } - -- SLIST_FOREACH(proj, &g_projects, entry) { -- if (strcmp(proj->name, name) == 0) { -- return proj; -- } -+ /* get engine */ -+ if (eng == NULL) { -+ return OPT_SUCCESS; -+ } -+ if (*proj == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "project of group %s not existed\n", group_name); -+ return OPT_PRO_NOEXIST; - } - -- return NULL; -+ ret = engine_of_group(config, group_name, *proj, eng); -+ if (ret != OPT_SUCCESS) { -+ return ret; -+ } -+ -+ /* get task */ -+ if (tk == NULL) { -+ return OPT_SUCCESS; -+ } -+ if (*eng == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "engine of group %s not existed\n", group_name); -+ return OPT_ENG_NOEXIST; -+ } -+ -+ ret = task_of_group(config, group_name, *proj, *eng, tk); -+ if (ret != OPT_SUCCESS) { -+ return ret; -+ } -+ -+ return OPT_SUCCESS; - } - --static enum opt_result check_add_params(const char *project_name, const char *file_name) -+static void project_insert_task(struct project *proj, struct engine *eng, struct task *task) - { -+ task->next = eng->tasks; -+ eng->tasks = task; -+ task->eng = eng; -+} -+ -+static void project_remove_task(struct engine *eng, struct task *task) -+{ -+ struct task **iter = &eng->tasks; -+ -+ for (; *iter != NULL && *iter != task; iter = &(*iter)->next) { -+ ; -+ } -+ -+ if (*iter == NULL) { -+ return; -+ } -+ -+ *iter = (*iter)->next; -+ task->next = NULL; -+ task->eng = NULL; -+} -+ -+static void do_remove_task(struct project *proj, struct engine *eng, struct task *tk) -+{ -+ if (proj->start && eng->ops->stop_task != NULL) { -+ eng->ops->stop_task(eng, tk); -+ } -+ if (eng->ops->clear_task_params != NULL) { -+ eng->ops->clear_task_params(tk); -+ } -+ -+ project_remove_task(eng, tk); -+ etmemd_remove_task(tk); -+} -+ -+enum opt_result etmemd_project_add_task(GKeyFile *config) -+{ -+ struct task *tk = NULL; - struct project *proj = NULL; -+ struct engine *eng = NULL; -+ enum opt_result ret; - -- if (project_name == NULL || strlen(project_name) == 0) { -- etmemd_log(ETMEMD_LOG_ERR, "project name must be given and should not be empty.\n"); -- return OPT_INVAL; -+ ret = get_group_objs(config, TASK_GROUP, &proj, &eng, &tk); -+ if (ret != OPT_SUCCESS) { -+ return ret; - } - -- if (strlen(project_name) > PROJECT_NAME_MAX_LEN) { -- etmemd_log(ETMEMD_LOG_ERR, "the length of project name should not be larger than %d\n", -- PROJECT_NAME_MAX_LEN); -- return OPT_INVAL; -+ if (tk != NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "task already exist\n"); -+ return OPT_TASK_EXISTED; - } - -- if (file_name == NULL || strlen(file_name) == 0) { -- etmemd_log(ETMEMD_LOG_ERR, "file name must be given and should not be empty.\n"); -- return OPT_INVAL; -+ tk = etmemd_add_task(config); -+ if (tk == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "create new task fail\n"); -+ return OPT_INTER_ERR; - } - -- if (strlen(file_name) > FILE_NAME_MAX_LEN) { -- etmemd_log(ETMEMD_LOG_ERR, "the length of file name should not be larger than %d\n", -- FILE_NAME_MAX_LEN); -- return OPT_INVAL; -+ project_insert_task(proj, eng, tk); -+ -+ if (eng->ops->fill_task_params != NULL && eng->ops->fill_task_params(config, tk) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "fill task param fail\n"); -+ goto remove_task; - } - -- proj = get_proj_by_name(project_name); -- if (proj != NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "project %s already exist.\n", project_name); -- return OPT_PRO_EXISTED; -+ if (proj->start && eng->ops->start_task(eng, tk) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "start added task %s fail\n", tk->name); -+ goto clear_task; - } - - return OPT_SUCCESS; -+ -+clear_task: -+ if (eng->ops->clear_task_params != NULL) { -+ eng->ops->clear_task_params(tk); -+ } -+ -+remove_task: -+ project_remove_task(eng, tk); -+ etmemd_remove_task(tk); -+ -+ return OPT_INTER_ERR; - } - --enum opt_result etmemd_project_add(const char *project_name, const char *file_name) -+enum opt_result etmemd_project_remove_task(GKeyFile *config) - { -+ struct task *tk = NULL; - struct project *proj = NULL; -- FILE *file = NULL; -+ struct engine *eng = NULL; - enum opt_result ret; - -- ret = check_add_params(project_name, file_name); -- if (ret != 0) { -+ ret = get_group_objs(config, TASK_GROUP, &proj, &eng, &tk); -+ if (ret != OPT_SUCCESS) { - return ret; - } -- -- file = memid_project_open_conf(file_name); -- if (file == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "open %s fail.\n", file_name); -- return OPT_INVAL; -+ if (tk == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "task not exsit\n"); -+ return OPT_TASK_NOEXIST; - } - -- proj = etmemd_project_init_struct(project_name); -- if (proj == NULL) { -- goto out_close; -+ do_remove_task(proj, eng, tk); -+ return OPT_SUCCESS; -+} -+ -+static void project_insert_engine(struct project *proj, struct engine *eng) -+{ -+ eng->next = proj->engs; -+ proj->engs = eng; -+ eng->proj = proj; -+} -+ -+static void project_remove_engine(struct project *proj, struct engine *eng) -+{ -+ struct engine **iter = &(proj->engs); -+ -+ for (; *iter != NULL && *iter != eng; iter = &(*iter)->next) { -+ ; - } - -- if (etmemd_fill_proj_by_conf(proj, file) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "get project from configuration file fail.\n"); -- free_before_delete_project(proj); -- free(proj); -- proj = NULL; -- goto out_close; -+ if (*iter == NULL) { -+ return; - } - -- SLIST_INSERT_HEAD(&g_projects, proj, entry); -- fclose(file); -- return OPT_SUCCESS; -+ *iter = (*iter)->next; -+ eng->next = NULL; -+ eng->proj = NULL; -+} -+ -+static int project_start_engine(struct project *proj, struct engine *eng) -+{ -+ struct task *tk = eng->tasks; -+ int ret = 0; - --out_close: -- fclose(file); -- return OPT_INVAL; -+ if (eng->ops->start_task == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "engine %s not support start\n", eng->name); -+ return -1; -+ } -+ -+ for (; tk != NULL; tk = tk->next) { -+ if (eng->ops->start_task(eng, tk) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "start task %s fail.\n", tk->value); -+ ret = -1; -+ } -+ } -+ return ret; - } - --static void stop_tasks(struct project *proj) -+static void project_stop_engine(struct project *proj, struct engine *eng) - { -- struct task *curr_task = NULL; -+ struct task *tk = eng->tasks; - -- if (!proj->start) { -+ if (eng->ops->stop_task == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "engine %s not support stop\n", eng->name); - return; - } -+ for (; tk != NULL; tk = tk->next) { -+ eng->ops->stop_task(eng, tk); -+ } -+} - -- proj->start = false; -+static void do_remove_engine_tasks(struct project *proj, struct engine *eng) -+{ -+ while (eng->tasks != NULL) { -+ do_remove_task(proj, eng, eng->tasks); -+ } -+} - -- curr_task = proj->tasks; -- while (curr_task != NULL) { -- curr_task->stop_etmem(curr_task); -- etmemd_log(ETMEMD_LOG_DEBUG, "Stop for Task_value %s, project_name %s \n", curr_task->value, -- curr_task->proj->name); -- curr_task = curr_task->next; -+static void do_remove_engine(struct project *proj, struct engine *eng) -+{ -+ do_remove_engine_tasks(proj, eng); -+ if (eng->ops->clear_eng_params != NULL) { -+ eng->ops->clear_eng_params(eng); - } -+ -+ project_remove_engine(proj, eng); -+ etmemd_engine_remove(eng); - } - --enum opt_result etmemd_project_delete(const char *project_name) -+enum opt_result etmemd_project_add_engine(GKeyFile *config) - { -+ struct engine *eng = NULL; - struct project *proj = NULL; -+ enum opt_result ret; - -- proj = get_proj_by_name(project_name); -- if (proj == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "get project fail to delete.\n"); -- return OPT_PRO_NOEXIST; -+ ret = get_group_objs(config, ENG_GROUP, &proj, &eng, NULL); -+ if (ret != OPT_SUCCESS) { -+ return ret; -+ } -+ if (eng != NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "engine %s exists\n", eng->name); -+ return OPT_ENG_EXISTED; - } - -- stop_tasks(proj); -+ eng = etmemd_engine_add(config); -+ if (eng == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "create engine fail\n"); -+ return OPT_INTER_ERR; -+ } - -- struct task *curr_task = NULL; -- curr_task = proj->tasks; -- while (curr_task != NULL) { -- if (curr_task->delete_etmem != NULL) { -- curr_task->delete_etmem(curr_task); -- curr_task = curr_task->next; -- } -+ project_insert_engine(proj, eng); -+ if (eng->ops->fill_eng_params != NULL && eng->ops->fill_eng_params(config, eng) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "fill %s engine params fail\n", eng->name); -+ project_remove_engine(proj, eng); -+ etmemd_engine_remove(eng); -+ return OPT_INTER_ERR; - } - -- SLIST_REMOVE(&g_projects, proj, project, entry); -+ return OPT_SUCCESS; -+} -+ -+enum opt_result etmemd_project_remove_engine(GKeyFile *config) -+{ -+ struct engine *eng = NULL; -+ struct project *proj = NULL; -+ enum opt_result ret; -+ -+ ret = get_group_objs(config, ENG_GROUP, &proj, &eng, NULL); -+ if (ret != OPT_SUCCESS) { -+ return ret; -+ } -+ if (eng == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "remove engine is not existed\n"); -+ return OPT_ENG_NOEXIST; -+ } -+ -+ do_remove_engine(proj, eng); -+ return OPT_SUCCESS; -+} - -- free_before_delete_project(proj); -+static int fill_project_name(void *obj, void *val) -+{ -+ struct project *proj = (struct project *)obj; -+ char *name = (char *)val; -+ proj->name = name; -+ return 0; -+} -+ -+static int fill_project_loop(void *obj, void *val) -+{ -+ struct project *proj = (struct project *)obj; -+ int loop = parse_to_int(val); -+ if (loop < 1 || loop > MAX_LOOP_VALUE) { -+ etmemd_log(ETMEMD_LOG_ERR, "invalid project loop value %d, it must be between 1 and %d.\n", -+ loop, MAX_LOOP_VALUE); -+ return -1; -+ } -+ -+ proj->loop = loop; -+ return 0; -+} -+ -+static int fill_project_interval(void *obj, void *val) -+{ -+ struct project *proj = (struct project *)obj; -+ int interval = parse_to_int(val); -+ if (interval < 1 || interval > MAX_INTERVAL_VALUE) { -+ etmemd_log(ETMEMD_LOG_ERR, "invalid project interval value %d, it must be between 1 and %d.\n", -+ interval, MAX_INTERVAL_VALUE); -+ return -1; -+ } -+ -+ proj->interval = interval; -+ return 0; -+} -+ -+static int fill_project_sleep(void *obj, void *val) -+{ -+ struct project *proj = (struct project *)obj; -+ int sleep = parse_to_int(val); -+ if (sleep < 1 || sleep > MAX_SLEEP_VALUE) { -+ etmemd_log(ETMEMD_LOG_ERR, "invalid project sleep value %d, it must be between 1 and %d.\n", -+ sleep, MAX_SLEEP_VALUE); -+ return -1; -+ } -+ -+ proj->sleep = sleep; -+ return 0; -+} -+ -+static struct config_item g_project_config_items[] = { -+ {"name", STR_VAL, fill_project_name, false}, -+ {"loop", INT_VAL, fill_project_loop, false}, -+ {"interval", INT_VAL, fill_project_interval, false}, -+ {"sleep", INT_VAL, fill_project_sleep, false}, -+}; -+ -+static void clear_project(struct project *proj) -+{ -+ if (proj->name != NULL) { -+ free(proj->name); -+ proj->name = NULL; -+ } -+} -+ -+static int project_fill_by_conf(GKeyFile *config, struct project *proj) -+{ -+ if (parse_file_config(config, PROJ_GROUP, g_project_config_items, ARRAY_SIZE(g_project_config_items), proj) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "parse project config fail\n"); -+ clear_project(proj); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static void do_remove_project(struct project *proj) -+{ -+ SLIST_REMOVE(&g_projects, proj, project, entry); -+ while (proj->engs != NULL) { -+ do_remove_engine(proj, proj->engs); -+ } -+ clear_project(proj); - free(proj); -+} -+ -+enum opt_result etmemd_project_add(GKeyFile *config) -+{ -+ struct project *proj = NULL; -+ enum opt_result ret; -+ -+ ret = project_of_group(config, PROJ_GROUP, &proj); -+ if (ret != OPT_SUCCESS) { -+ return ret; -+ } -+ if (proj != NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "project %s existes\n", proj->name); -+ return OPT_PRO_EXISTED; -+ } -+ -+ proj = (struct project *)calloc(1, sizeof(struct project)); -+ if (proj == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc memory for project fail\n"); -+ return OPT_INTER_ERR; -+ } -+ if (project_fill_by_conf(config, proj) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "fill project from configuration file fail\n"); -+ free(proj); -+ proj = NULL; -+ return OPT_INVAL; -+ } - -+ SLIST_INSERT_HEAD(&g_projects, proj, entry); - return OPT_SUCCESS; - } - --static void etmemd_project_print_line(void) -+enum opt_result etmemd_project_remove(GKeyFile *config) - { -- int i; -+ struct project *proj = NULL; -+ enum opt_result ret; - -- for (i = 0; i < PROJECT_SHOW_COLM_MAX; i++) { -- printf("-"); -+ ret = get_group_objs(config, PROJ_GROUP, &proj, NULL, NULL); -+ if (ret != OPT_SUCCESS) { -+ return ret; -+ } -+ -+ if (proj == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "remove project not existed\n"); -+ return OPT_PRO_NOEXIST; - } -- printf("\n"); -+ -+ do_remove_project(proj); -+ return OPT_SUCCESS; - } - --static void etmemd_project_print(const struct project *proj) -+static void etmemd_project_print(int fd, const struct project *proj) - { -- etmemd_project_print_line(); -- printf("project: %s\n\n", proj->name); -- printf("%-8s %-32s %-32s %-32s %-16s\n", -- "number", -- "type", -- "value", -- "engine", -- "started"); -- etmemd_print_tasks(proj->tasks); -- etmemd_project_print_line(); -+ struct engine *eng = NULL; -+ -+ dprintf_all(fd, "project: %s\n", proj->name); -+ dprintf_all(fd, "%-8s %-8s %-16s %-16s %-16s %-8s\n", -+ "number", -+ "type", -+ "value", -+ "name", -+ "engine", -+ "started"); -+ for (eng = proj->engs; eng != NULL; eng = eng->next) { -+ etmemd_print_tasks(fd, eng->tasks, eng->name, proj->start); -+ } - } - --enum opt_result etmemd_project_show(void) -+enum opt_result etmemd_project_show(const char *project_name, int sock_fd) - { - struct project *proj = NULL; - bool exists = false; - - SLIST_FOREACH(proj, &g_projects, entry) { -- etmemd_project_print(proj); -+ if (project_name != NULL && strcmp(project_name, proj->name) != 0) { -+ continue; -+ } -+ etmemd_project_print(sock_fd, proj); - exists = true; - } - - if (!exists) { -- etmemd_project_print_line(); -- printf("project: no project exits\n\n"); -- etmemd_project_print_line(); -+ if (project_name == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "no project exists\n"); -+ } else { -+ etmemd_log(ETMEMD_LOG_ERR, "project: project %s is not existed\n\n", project_name); -+ } -+ return OPT_PRO_NOEXIST; - } - -- if (fflush(stdout) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "fflush stdout fail.\n"); -- return OPT_INTER_ERR; -+ return OPT_SUCCESS; -+} -+ -+static int start_tasks(struct project *proj) -+{ -+ struct engine *eng = NULL; -+ int ret = 0; -+ -+ for (eng = proj->engs; eng != NULL; eng = eng->next) { -+ if (project_start_engine(proj, eng) != 0) { -+ ret = -1; -+ } - } - -- return OPT_SUCCESS; -+ return ret; -+} -+ -+static void stop_tasks(struct project *proj) -+{ -+ struct engine *eng = NULL; -+ -+ for (eng = proj->engs; eng != NULL; eng = eng->next) { -+ project_stop_engine(proj, eng); -+ } - } - - enum opt_result etmemd_migrate_start(const char *project_name) - { - struct project *proj = NULL; -- struct task *curr_task = NULL; -- int start_task_num = 0; -+ -+ if (project_name == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "project is not set for start cmd\n"); -+ return OPT_INVAL; -+ } - - proj = get_proj_by_name(project_name); - if (proj == NULL) { -@@ -315,27 +647,12 @@ enum opt_result etmemd_migrate_start(const char *project_name) - return OPT_PRO_STARTED; - } - -- proj->start = true; -- -- curr_task = proj->tasks; -- while (curr_task != NULL) { -- if (curr_task->start_etmem(curr_task) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "start task %s fail.\n", -- curr_task->value); -- curr_task = curr_task->next; -- continue; -- } -- -- start_task_num++; -- curr_task = curr_task->next; -- } -- -- if (start_task_num == 0) { -- etmemd_log(ETMEMD_LOG_ERR, "all tasks start fail.\n"); -- proj->start = false; -+ if (start_tasks(proj) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "some task of project %s start fail\n", project_name); - return OPT_INTER_ERR; - } - -+ proj->start = true; - return OPT_SUCCESS; - } - -@@ -343,6 +660,11 @@ enum opt_result etmemd_migrate_stop(const char *project_name) - { - struct project *proj = NULL; - -+ if (project_name == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "project is not set for stop cmd\n"); -+ return OPT_INVAL; -+ } -+ - proj = get_proj_by_name(project_name); - if (proj == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "get project fail.\n"); -@@ -360,16 +682,47 @@ enum opt_result etmemd_migrate_stop(const char *project_name) - return OPT_SUCCESS; - } - -+enum opt_result etmemd_project_mgt_engine(const char *project_name, const char *eng_name, char *cmd, char *task_name, int sock_fd) -+{ -+ struct engine *eng = NULL; -+ struct project *proj = NULL; -+ struct task *tk = NULL; -+ -+ if (project_name == NULL || eng_name == NULL || cmd == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "project, engine and cmd must all be given\n"); -+ return OPT_INVAL; -+ } -+ -+ proj = get_proj_by_name(project_name); -+ if (proj == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "project %s is not existed\n", project_name); -+ return OPT_PRO_NOEXIST; -+ } -+ if (!proj->start) { -+ etmemd_log(ETMEMD_LOG_ERR, "project %s is not started\n", project_name); -+ return OPT_INVAL; -+ } -+ -+ eng = get_eng_by_name(proj, eng_name); -+ if (eng == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "engine %s is not existed\n", eng_name); -+ return OPT_INVAL; -+ } -+ if (task_name != NULL) { -+ tk = get_task_by_name(proj, eng, task_name); -+ } -+ if (eng->ops->eng_mgt_func(eng, tk, cmd, sock_fd) != 0) { -+ return OPT_INVAL; -+ } -+ return OPT_SUCCESS; -+} -+ - void etmemd_stop_all_projects(void) - { - struct project *proj = NULL; - - while (!SLIST_EMPTY(&g_projects)) { - proj = SLIST_FIRST(&g_projects); -- SLIST_REMOVE_HEAD(&g_projects, entry); -- stop_tasks(proj); -- free_before_delete_project(proj); -- free(proj); -- proj = NULL; -+ do_remove_project(proj); - } - } -diff --git a/src/etmemd_src/etmemd_rpc.c b/src/etmemd_src/etmemd_rpc.c -index e74013a..e154083 100644 ---- a/src/etmemd_src/etmemd_rpc.c -+++ b/src/etmemd_src/etmemd_rpc.c -@@ -18,11 +18,13 @@ - #include - #include - #include -+#include - #include "securec.h" - #include "etmemd_rpc.h" - #include "etmemd_project.h" - #include "etmemd_common.h" - #include "etmemd_log.h" -+#include "etmemd_file.h" - - /* the max length of sun_path in struct sockaddr_un is 108 */ - #define RPC_ADDR_LEN_MAX 108 -@@ -44,6 +46,9 @@ struct server_rpc_parser g_rpc_parser[] = { - {"proj_name", DECODE_STRING, (void **)&(g_rpc_params.proj_name)}, - {"file_name", DECODE_STRING, (void **)&(g_rpc_params.file_name)}, - {"cmd", DECODE_INT, (void **)&(g_rpc_params.cmd)}, -+ {"eng_name", DECODE_STRING, (void **)&(g_rpc_params.eng_name)}, -+ {"eng_cmd", DECODE_STRING, (void **)&(g_rpc_params.eng_cmd)}, -+ {"task_name", DECODE_STRING, (void **)&(g_rpc_params.task_name)}, - {NULL, DECODE_END, NULL}, - }; - -@@ -51,9 +56,13 @@ struct rpc_resp_msg g_resp_msg_arr[] = { - {OPT_SUCCESS, "success"}, - {OPT_INVAL, "error: invalid parameters"}, - {OPT_PRO_EXISTED, "error: project has been existed"}, -+ {OPT_PRO_NOEXIST, "error: project is not exist"}, - {OPT_PRO_STARTED, "error: project has been started"}, - {OPT_PRO_STOPPED, "error: project has been stopped"}, -- {OPT_PRO_NOEXIST, "error: project is not exist"}, -+ {OPT_ENG_EXISTED, "error: engine has been existed"}, -+ {OPT_ENG_NOEXIST, "error: engine is not exist"}, -+ {OPT_TASK_EXISTED, "error: task has been existed"}, -+ {OPT_TASK_NOEXIST, "error: task is not exist"}, - {OPT_INTER_ERR, "error: etmemd has internal error"}, - {OPT_RET_END, NULL}, - }; -@@ -66,27 +75,123 @@ static void etmemd_set_flag(int s) - g_sock_fd = -1; - } - -+static void etmemd_ignore_sig(int s) -+{ -+ return; -+} -+ - void etmemd_handle_signal(void) - { - signal(SIGINT, etmemd_set_flag); - signal(SIGTERM, etmemd_set_flag); -+ signal(SIGPIPE, etmemd_ignore_sig); - - return; - } - -+struct obj_cmd_item { -+ char *name; -+ enum opt_result (*func)(GKeyFile *config); -+}; -+ -+static enum opt_result do_obj_cmd(GKeyFile *config, struct obj_cmd_item *items, unsigned n) -+{ -+ unsigned i; -+ bool parsed = false; -+ enum opt_result ret; -+ -+ for (i = 0; i < n; i++) { -+ if (g_key_file_has_group(config, items[i].name) == FALSE) { -+ continue; -+ } -+ -+ ret = items[i].func(config); -+ if (ret != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "parse group %s fail\n", items[i].name); -+ return ret; -+ } -+ parsed = true; -+ } -+ -+ if (!parsed) { -+ etmemd_log(ETMEMD_LOG_ERR, "no group has been parsed\n"); -+ return OPT_INVAL; -+ } -+ -+ return OPT_SUCCESS; -+} -+ -+struct obj_cmd_item obj_add_items[] = { -+ {PROJ_GROUP, etmemd_project_add}, -+ {ENG_GROUP, etmemd_project_add_engine}, -+ {TASK_GROUP, etmemd_project_add_task}, -+}; -+ -+static enum opt_result do_obj_add(GKeyFile *config) -+{ -+ return do_obj_cmd(config, obj_add_items, ARRAY_SIZE(obj_add_items)); -+} -+ -+static struct obj_cmd_item obj_remove_items[] = { -+ {TASK_GROUP, etmemd_project_remove_task}, -+ {ENG_GROUP, etmemd_project_remove_engine}, -+ {PROJ_GROUP, etmemd_project_remove}, -+}; -+ -+static enum opt_result do_obj_remove(GKeyFile *config) -+{ -+ return do_obj_cmd(config, obj_remove_items, ARRAY_SIZE(obj_remove_items)); -+} -+ -+static enum opt_result handle_obj_cmd(char *file_name, enum cmd_type type) -+{ -+ GKeyFile *config = NULL; -+ enum opt_result ret; -+ -+ if (file_name == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "file name is not set for obj cmd\n"); -+ return OPT_INVAL; -+ } -+ -+ config = g_key_file_new(); -+ if (config == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "get empty config file fail\n"); -+ return OPT_INTER_ERR; -+ } -+ -+ if (g_key_file_load_from_file(config, file_name, G_KEY_FILE_NONE, NULL) == FALSE) { -+ etmemd_log(ETMEMD_LOG_ERR, "load config file fail\n"); -+ ret = OPT_INTER_ERR; -+ goto free_file; -+ } -+ -+ switch (type) { -+ case OBJ_ADD: -+ ret = do_obj_add(config); -+ break; -+ case OBJ_DEL: -+ ret = do_obj_remove(config); -+ break; -+ default: -+ ret = OPT_INVAL; -+ } -+ -+free_file: -+ g_key_file_free(config); -+ return ret; -+} -+ - static enum opt_result etmemd_switch_cmd(const struct server_rpc_params svr_param) - { - enum opt_result ret = OPT_INVAL; - - switch (svr_param.cmd) { -- case PROJ_ADD: -- ret = etmemd_project_add(svr_param.proj_name, svr_param.file_name); -- return ret; -- case PROJ_DEL: -- ret = etmemd_project_delete(svr_param.proj_name); -+ case OBJ_ADD: -+ case OBJ_DEL: -+ ret = handle_obj_cmd(svr_param.file_name, svr_param.cmd); - return ret; - case PROJ_SHOW: -- ret = etmemd_project_show(); -+ ret = etmemd_project_show(svr_param.proj_name, svr_param.sock_fd); - return ret; - case MIG_START: - ret = etmemd_migrate_start(svr_param.proj_name); -@@ -94,6 +199,10 @@ static enum opt_result etmemd_switch_cmd(const struct server_rpc_params svr_para - case MIG_STOP: - ret = etmemd_migrate_stop(svr_param.proj_name); - return ret; -+ case ENG_CMD: -+ ret = etmemd_project_mgt_engine(svr_param.proj_name, svr_param.eng_name, -+ svr_param.eng_cmd, svr_param.task_name, svr_param.sock_fd); -+ return ret; - default: - etmemd_log(ETMEMD_LOG_ERR, "Invalid command.\n"); - return ret; -@@ -297,11 +406,24 @@ static int etmemd_rpc_decode_int(void **ptr, const char *buf, - return 0; - } - -+static bool skip_null_arg(const char *buf, unsigned long *idx) -+{ -+ if (buf[*idx] == '-') { -+ *idx += 2; // add 2 for skipping '- ' -+ return true; -+ } -+ return false; -+} -+ - static int etmemd_rpc_decode(struct server_rpc_parser *parser, const char *buf, - unsigned long buf_len, unsigned long *idx) - { - int ret; - -+ if (skip_null_arg(buf, idx)) { -+ return 0; -+ } -+ - switch (parser->type) { - case DECODE_STRING: - ret = etmemd_rpc_decode_str(parser->member_ptr, buf, buf_len, idx); -@@ -377,6 +499,10 @@ static void etmemd_rpc_send_response_msg(int sock_fd, enum opt_result result) - int i = 0; - ssize_t ret = -1; - -+ if (result == OPT_SUCCESS) { -+ return; -+ } -+ - while (g_resp_msg_arr[i].msg != NULL) { - if (result != g_resp_msg_arr[i].result) { - i++; -@@ -398,6 +524,7 @@ static void etmemd_rpc_handle(int sock_fd) - { - enum opt_result ret; - -+ g_rpc_params.sock_fd = sock_fd; - ret = etmemd_switch_cmd(g_rpc_params); - if (ret != OPT_SUCCESS) { - etmemd_log(ETMEMD_LOG_ERR, "operate cmd %d fail\n", g_rpc_params.cmd); -@@ -474,7 +601,7 @@ static int etmemd_rpc_accept(int sock_fd) - goto RPC_EXIT; - } - -- etmemd_log(ETMEMD_LOG_INFO, "etmemd get socket message \"%s\"\n", recv_buf); -+ etmemd_log(ETMEMD_LOG_DEBUG, "etmemd get socket message \"%s\"\n", recv_buf); - if (etmemd_rpc_parse(recv_buf, (unsigned long)rc) == 0) { - etmemd_rpc_handle(accp_fd); - } -diff --git a/src/etmemd_src/etmemd_scan.c b/src/etmemd_src/etmemd_scan.c -index 66694a1..bb8dfa3 100644 ---- a/src/etmemd_src/etmemd_scan.c -+++ b/src/etmemd_src/etmemd_scan.c -@@ -17,10 +17,12 @@ - #include - #include - #include -+#include - - #include "etmemd.h" - #include "etmemd_scan.h" - #include "etmemd_project.h" -+#include "etmemd_engine.h" - #include "etmemd_common.h" - #include "etmemd_log.h" - #include "securec.h" -@@ -30,6 +32,8 @@ - #define PUD_SIZE_SHIFT 30 - #define HEXADECIMAL_RADIX 16 - #define PMD_IDLE_PTES_PARAMETER 512 -+#define VMFLAG_MAX_LEN 100 -+#define VMFLAG_MAX_NUM 30 - - static const enum page_type g_page_type_by_idle_kind[] = { - PTE_TYPE, -@@ -45,11 +49,12 @@ static const enum page_type g_page_type_by_idle_kind[] = { - PAGE_TYPE_INVAL, - }; - --static u_int64_t g_page_size[PAGE_TYPE_INVAL] = { -- 1UL << PTE_SIZE_SHIFT, /* PTE size */ -- 1UL << PMD_SIZE_SHIFT, /* PMD size */ -- 1UL << PUD_SIZE_SHIFT, /* PUD size */ --}; -+static uint64_t g_page_size[PAGE_TYPE_INVAL]; -+ -+int page_type_to_size(enum page_type type) -+{ -+ return g_page_size[type]; -+} - - static unsigned int get_page_shift(long pagesize) - { -@@ -260,13 +265,91 @@ exit: - return NULL; - } - --struct vmas *get_vmas(const char *pid) -+static bool is_vma_with_vmflags(FILE *fp, char *vmflags_array[], int vmflags_num) -+{ -+ char parse_line[FILE_LINE_MAX_LEN]; -+ size_t len; -+ int i; -+ -+ len = strlen(VMFLAG_HEAD); -+ while (fgets(parse_line, FILE_LINE_MAX_LEN - 1, fp) != NULL) { -+ /* skip the line which has no match length */ -+ if (strlen(parse_line) <= len) { -+ continue; -+ } -+ if (strncmp(VMFLAG_HEAD, parse_line, len) != 0) { -+ continue; -+ } -+ -+ /* check any flag in flags is set */ -+ for (i = 0; i < vmflags_num; i++) { -+ if (strstr(parse_line, vmflags_array[i]) == NULL) { -+ return false; -+ } -+ } -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool is_vmflags_match(FILE *fp, char *vmflags_array[], int vmflags_num) -+{ -+ if (vmflags_num == 0) { -+ return true; -+ } -+ return is_vma_with_vmflags(fp, vmflags_array, vmflags_num); -+} -+ -+static bool is_anon_match(bool is_anon_only, struct vma *vma) -+{ -+ if (!is_anon_only) { -+ return true; -+ } -+ return is_anonymous(vma); -+} -+ -+int split_vmflags(char ***vmflags_array, char *vmflags) -+{ -+ char *flag = NULL; -+ char *saveptr = NULL; -+ char *tmp_array[VMFLAG_MAX_NUM] = {}; -+ int vmflags_num = 0; -+ int i; -+ -+ for (flag = strtok_r(vmflags, " ", &saveptr); flag != NULL; flag = strtok_r(NULL, " ,", &saveptr)) { -+ tmp_array[vmflags_num++] = flag; -+ if (vmflags_num == VMFLAG_MAX_NUM) { -+ break; -+ } -+ } -+ -+ *vmflags_array = malloc(sizeof(char *) * vmflags_num); -+ if (*vmflags_array == NULL) { -+ return -1; -+ } -+ -+ for (i = 0; i < vmflags_num; i++) { -+ (*vmflags_array)[i] = tmp_array[i]; -+ } -+ -+ return vmflags_num; -+} -+ -+struct vmas *get_vmas_with_flags(const char *pid, char *vmflags_array[], int vmflags_num, bool is_anon_only) - { - struct vmas *ret_vmas = NULL; - struct vma **tmp_vma = NULL; - FILE *fp = NULL; - char maps_line[FILE_LINE_MAX_LEN]; - size_t len; -+ char *maps_file = NULL; -+ -+ if (vmflags_num == 0) { -+ maps_file = MAPS_FILE; -+ } else { -+ maps_file = SMAPS_FILE; -+ } - - ret_vmas = (struct vmas *)calloc(1, sizeof(struct vmas)); - if (ret_vmas == NULL) { -@@ -274,9 +357,9 @@ struct vmas *get_vmas(const char *pid) - return NULL; - } - -- fp = etmemd_get_proc_file(pid, MAPS_FILE, "r"); -+ fp = etmemd_get_proc_file(pid, maps_file, 0, "r"); - if (fp == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "open %s file of %s fail\n", MAPS_FILE, pid); -+ etmemd_log(ETMEMD_LOG_ERR, "open %s file of %s fail\n", maps_file, pid); - free(ret_vmas); - return NULL; - } -@@ -291,23 +374,35 @@ struct vmas *get_vmas(const char *pid) - ret_vmas = NULL; - break; - } -- tmp_vma = &((*tmp_vma)->next); -- ret_vmas->vma_cnt++; - -- /* if the file path is too long, maps_line cannot read file line completely, clean invalid characters. */ -+ /* if the file path is too long, maps_line cannot read file line completely, clean invalid characters */ - while (maps_line[len - 1] != '\n') { - if (fgets(maps_line, FILE_LINE_MAX_LEN - 1, fp) != NULL) { - len = strlen(maps_line); - continue; - } - } -+ -+ /* skip vma without vmflags */ -+ if (!is_vmflags_match(fp, vmflags_array, vmflags_num) || !is_anon_match(is_anon_only, *tmp_vma)) { -+ free(*tmp_vma); -+ *tmp_vma = NULL; -+ continue; -+ } -+ -+ tmp_vma = &((*tmp_vma)->next); -+ ret_vmas->vma_cnt++; - } - - fclose(fp); -- - return ret_vmas; - } - -+struct vmas *get_vmas(const char *pid) -+{ -+ return get_vmas_with_flags(pid, NULL, 0, true); -+} -+ - static u_int64_t get_address_from_buf(const unsigned char *buf, u_int64_t index) - { - u_int64_t address; -@@ -408,9 +503,9 @@ static struct page_refs **record_parse_result(u_int64_t addr, enum page_idle_typ - enum page_type page_size_type; - - /* ignore unaligned address when walk, because pages handled need to be aligned */ -- if ((addr & (g_page_size[g_page_type_by_idle_kind[type]] - 1)) > 0) { -+ if ((addr & (page_type_to_size(g_page_type_by_idle_kind[type]) - 1)) > 0) { - etmemd_log(ETMEMD_LOG_WARN, "ignore address %lx which not aligned %lx for type %d\n", addr, -- g_page_size[g_page_type_by_idle_kind[type]], type); -+ page_type_to_size(g_page_type_by_idle_kind[type]), type); - return pf; - } - -@@ -429,7 +524,7 @@ static struct page_refs **record_parse_result(u_int64_t addr, enum page_idle_typ - break; - } - -- addr += g_page_size[page_size_type]; -+ addr += page_type_to_size(page_size_type); - } - - return pf; -@@ -480,23 +575,23 @@ static struct page_refs **parse_vma_result(const unsigned char *buf, u_int64_t s - } else if (type < PMD_IDLE_PTES) { - pf = record_parse_result(address, type, nr, pf); - } else { -- address = address + (u_int64_t)nr * g_page_size[g_page_type_by_idle_kind[type]]; -+ address = address + (u_int64_t)nr * page_type_to_size(g_page_type_by_idle_kind[type]); - continue; - } - - if (pf == NULL) { - return NULL; - } -- address = address + (u_int64_t)nr * g_page_size[g_page_type_by_idle_kind[type]]; -+ address = address + (u_int64_t)nr * page_type_to_size(g_page_type_by_idle_kind[type]); - } - *end = address; - return pf; - } - --static struct page_refs **walk_vmas(int fd, -- struct walk_address *walk_address, -- struct page_refs **pf, -- unsigned long *use_rss) -+struct page_refs **walk_vmas(int fd, -+ struct walk_address *walk_address, -+ struct page_refs **pf, -+ unsigned long *use_rss) - { - unsigned char *buf = NULL; - u_int64_t size; -@@ -504,7 +599,7 @@ static struct page_refs **walk_vmas(int fd, - - /* we make the buffer size as fitable as within a vma. - * because the size of buffer passed to kernel will be calculated again (<< (3 + PAGE_SHIFT)) */ -- size = ((walk_address->walk_end - walk_address->walk_start) >> 3) / g_page_size[PTE_TYPE]; -+ size = ((walk_address->walk_end - walk_address->walk_start) >> 3) / page_type_to_size(PTE_TYPE); - - /* we need to compare the size to the minimum size that kernel handled */ - size = size < EPT_IDLE_BUF_MIN ? EPT_IDLE_BUF_MIN : size; -@@ -547,7 +642,7 @@ int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **p - struct page_refs **tmp_page_refs = NULL; - struct walk_address walk_address = {0, 0, 0}; - -- scan_fp = etmemd_get_proc_file(pid, IDLE_SCAN_FILE, "r"); -+ scan_fp = etmemd_get_proc_file(pid, IDLE_SCAN_FILE, 0, "r"); - if (scan_fp == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "open %s file fail\n", IDLE_SCAN_FILE); - return -1; -@@ -567,11 +662,6 @@ int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **p - continue; - } - -- if (!(is_anonymous(vma))) { -- vma = vma->next; -- continue; -- } -- - /* meeting this branch means the end of address for last scan is between the address of - * start and end this round, so we start from lastScanEnd address in case of scan repeatly. */ - walk_address.walk_end = vma->end; -@@ -630,7 +720,7 @@ struct page_refs *etmemd_do_scan(const struct task_pid *tpid, const struct task - } - - /* loop for scanning idle_pages to get result of memory access. */ -- for (i = 0; i < tk->proj->loop; i++) { -+ for (i = 0; i < tk->eng->proj->loop; i++) { - ret = get_page_refs(vmas, pid, &page_refs, NULL); - if (ret != 0) { - etmemd_log(ETMEMD_LOG_ERR, "scan operation failed\n"); -@@ -639,7 +729,7 @@ struct page_refs *etmemd_do_scan(const struct task_pid *tpid, const struct task - page_refs = NULL; - break; - } -- sleep((unsigned)tk->proj->sleep); -+ sleep((unsigned)tk->eng->proj->sleep); - } - - free_vmas(vmas); -diff --git a/src/etmemd_src/etmemd_slide.c b/src/etmemd_src/etmemd_slide.c -index fe8ae92..ea9ccb4 100644 ---- a/src/etmemd_src/etmemd_slide.c -+++ b/src/etmemd_src/etmemd_slide.c -@@ -26,57 +26,7 @@ - #include "etmemd_scan.h" - #include "etmemd_migrate.h" - #include "etmemd_pool_adapter.h" -- --static int fill_slide_param_t(struct engine *eng, const char *val) --{ -- int value; -- struct slide_params *s_param = (struct slide_params *)eng->params; -- struct task *tk = (struct task *)eng->task; -- -- if (get_int_value(val, &value) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "invalid engine param T value.\n"); -- return -1; -- } -- -- /* the max value of T watermark is weight of write multipled by time of loop */ -- if (value < 1 || value > tk->proj->loop * WRITE_TYPE_WEIGHT) { -- etmemd_log(ETMEMD_LOG_ERR, "invalid engine param T value, must between 1 and loop.\n"); -- return -1; -- } -- -- s_param->t = value; -- -- return 0; --} -- --static int parse_slide_params(struct engine *eng, FILE *file) --{ -- char key[KEY_VALUE_MAX_LEN] = {}; -- char value[KEY_VALUE_MAX_LEN] = {}; -- char *get_line = NULL; -- -- get_line = skip_blank_line(file); -- if (get_line == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "lack of config for slide engine privately\n"); -- return -1; -- } -- -- if (get_keyword_and_value(get_line, key, value) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "get engine param keyword and value fail\n"); -- return -1; -- } -- -- if (strcmp(key, "T") != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "invalid slide parameter keyword, must be T\n"); -- return -1; -- } -- -- if (fill_slide_param_t(eng, value) != 0) { -- return -1; -- } -- -- return 0; --} -+#include "etmemd_file.h" - - static struct memory_grade *slide_policy_interface(struct page_refs **page_refs, void *params) - { -@@ -125,32 +75,20 @@ static int slide_do_migrate(unsigned int pid, const struct memory_grade *memory_ - return ret; - } - --static void *slide_exector(void *arg) -+static void *slide_executor(void *arg) - { - struct task_pid *tk_pid = (struct task_pid *)arg; - struct page_refs *page_refs = NULL; - struct memory_grade *memory_grade = NULL; -- struct engine *eng = NULL; -- -- eng = tk_pid->tk->eng; -- if (eng == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "pid %u engine is null!\n", tk_pid->pid); -- return NULL; -- } -- -- if (eng->adp == NULL || eng->adp->do_scan == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "pid %u scan function is not registered!\n", tk_pid->pid); -- 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); - -- page_refs = eng->adp->do_scan(tk_pid, tk_pid->tk); -+ page_refs = etmemd_do_scan(tk_pid, tk_pid->tk); - if (page_refs != NULL) { -- memory_grade = eng->mig_policy_func(&page_refs, eng->params); -+ memory_grade = slide_policy_interface(&page_refs, tk_pid->tk->params); - } - - /* no need to use page_refs any longer. -@@ -165,12 +103,7 @@ static void *slide_exector(void *arg) - goto exit; - } - -- if (eng->adp->do_migrate == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "pid %u migrate function is not registered!\n", tk_pid->pid); -- goto exit; -- } -- -- if (eng->adp->do_migrate(tk_pid->pid, memory_grade) != 0) { -+ if (slide_do_migrate(tk_pid->pid, memory_grade) != 0) { - etmemd_log(ETMEMD_LOG_DEBUG, "slide migrate for pid %u fail\n", tk_pid->pid); - } - -@@ -184,41 +117,104 @@ exit: - return NULL; - } - --static int alloc_slide_params(struct task_pid **tk_pid) -+static int fill_task_threshold(void *obj, void *val) - { -- (*tk_pid)->params = NULL; -+ struct slide_params *params = (struct slide_params *)obj; -+ int t = parse_to_int(val); -+ -+ if (t < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "slide engine param T should not be less than 0"); -+ return -1; -+ } -+ -+ params->t = t; - return 0; - } - --int fill_engine_type_slide(struct engine *eng) -+static struct config_item g_slide_task_config_items[] = { -+ {"T", INT_VAL, fill_task_threshold, false}, -+}; -+ -+static int slide_fill_task(GKeyFile *config, struct task *tk) - { -- struct slide_params *s_param = NULL; -- struct task *tk = (struct task *)eng->task; -+ struct slide_params *params = calloc(1, sizeof(struct slide_params)); - -- s_param = (struct slide_params *)calloc(1, sizeof(struct slide_params)); -- if (s_param == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "malloc slide engine params fail\n"); -+ if (params == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc slide param fail\n"); - return -1; - } - -- eng->adp = (struct adapter *)calloc(1, sizeof(struct adapter)); -- if (eng->adp == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "malloc adapter for task %s engine fail\n", tk->value); -- free(s_param); -+ if (parse_file_config(config, TASK_GROUP, g_slide_task_config_items, ARRAY_SIZE(g_slide_task_config_items), -+ (void *)params) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "slide fill task fail\n"); -+ goto free_params; -+ } -+ -+ if (params->t > tk->eng->proj->loop * WRITE_TYPE_WEIGHT) { -+ etmemd_log(ETMEMD_LOG_ERR, "engine param T must less than loop.\n"); -+ goto free_params; -+ } -+ tk->params = params; -+ return 0; -+ -+free_params: -+ free(params); -+ return -1; -+} -+ -+static void slide_clear_task(struct task *tk) -+{ -+ free(tk->params); -+ tk->params = NULL; -+} -+ -+static int slide_start_task(struct engine *eng, struct task *tk) -+{ -+ struct slide_params *params = tk->params; -+ -+ params->executor = malloc(sizeof(struct task_executor)); -+ if (params->executor == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "slide alloc memory for task_executor fail\n"); - return -1; - } - -- eng->params = (void *)s_param; -- eng->engine_type = SLIDE_ENGINE; -- eng->parse_param_conf = parse_slide_params; -- eng->mig_policy_func = slide_policy_interface; -- eng->adp->do_scan = etmemd_do_scan; -- eng->adp->do_migrate = slide_do_migrate; -- eng->alloc_params = alloc_slide_params; -- tk->start_etmem = start_threadpool_work; -- tk->stop_etmem = stop_and_delete_threadpool_work; -- tk->delete_etmem = stop_and_delete_threadpool_work; -- tk->workflow_engine = slide_exector; -+ params->executor->tk = tk; -+ params->executor->func = slide_executor; -+ if (start_threadpool_work(params->executor) != 0) { -+ free(params->executor); -+ params->executor = NULL; -+ etmemd_log(ETMEMD_LOG_ERR, "slide start task executor fail\n"); -+ return -1; -+ } -+ -+ return 0; -+} - -+static void slide_stop_task(struct engine *eng, struct task *tk) -+{ -+ struct slide_params *params = tk->params; -+ -+ stop_and_delete_threadpool_work(tk); -+ free(params->executor); -+ params->executor = NULL; -+} -+ -+struct engine_ops slide_eng_ops = { -+ .fill_eng_params = NULL, -+ .clear_eng_params = NULL, -+ .fill_task_params = slide_fill_task, -+ .clear_task_params = slide_clear_task, -+ .start_task = slide_start_task, -+ .stop_task = slide_stop_task, -+ .alloc_pid_params = NULL, -+ .free_pid_params = NULL, -+ .eng_mgt_func = NULL, -+}; -+ -+int fill_engine_type_slide(struct engine *eng) -+{ -+ eng->ops = &slide_eng_ops; -+ eng->engine_type = SLIDE_ENGINE; -+ eng->name = "slide"; - return 0; - } -diff --git a/src/etmemd_src/etmemd_task.c b/src/etmemd_src/etmemd_task.c -index 8474c6c..5c81b74 100644 ---- a/src/etmemd_src/etmemd_task.c -+++ b/src/etmemd_src/etmemd_task.c -@@ -20,12 +20,14 @@ - #include - #include - #include -+#include - - #include "securec.h" - #include "etmemd_log.h" - #include "etmemd_common.h" - #include "etmemd_task.h" - #include "etmemd_engine.h" -+#include "etmemd_file.h" - - static int get_pid_through_pipe(char *arg_pid[], const int *pipefd) - { -@@ -74,7 +76,10 @@ static int get_pid_through_pipe(char *arg_pid[], const int *pipefd) - - void free_task_pid_mem(struct task_pid **tk_pid) - { -- etmemd_safe_free((void **)(&((*tk_pid)->params))); -+ struct engine *eng = (*tk_pid)->tk->eng; -+ if (eng->ops->free_pid_params != NULL) { -+ eng->ops->free_pid_params(eng, tk_pid); -+ } - etmemd_safe_free((void **)tk_pid); - } - -@@ -91,8 +96,8 @@ static void clean_nouse_pid(struct task_pid **tk_pid) - - static struct task_pid *alloc_tkpid_node(unsigned int pid, struct task *tk) - { -- int ret; - struct task_pid *tk_pid = NULL; -+ struct engine *eng = tk->eng; - - tk_pid = (struct task_pid *)calloc(1, sizeof(struct task_pid)); - if (tk_pid == NULL) { -@@ -102,8 +107,7 @@ static struct task_pid *alloc_tkpid_node(unsigned int pid, struct task *tk) - tk_pid->pid = pid; - tk_pid->tk = tk; - -- ret = tk->eng->alloc_params(&tk_pid); -- if (ret != 0) { -+ if (eng->ops->alloc_pid_params != NULL && eng->ops->alloc_pid_params(eng, &tk_pid) != 0) { - free(tk_pid); - return NULL; - } -@@ -362,6 +366,13 @@ int etmemd_get_task_pids(struct task *tk) - return 0; - } - -+static void clear_task_struct(struct task *task) -+{ -+ etmemd_safe_free((void **)&task->type); -+ etmemd_safe_free((void **)&task->value); -+ etmemd_safe_free((void **)&task->name); -+} -+ - void etmemd_free_task_struct(struct task **tk) - { - struct task *task = NULL; -@@ -371,36 +382,125 @@ void etmemd_free_task_struct(struct task **tk) - } - - task = *tk; -- etmemd_safe_free((void **)&task->type); -- etmemd_safe_free((void **)&task->value); -- -- if (task->eng != NULL) { -- etmemd_safe_free((void **)&task->eng->params); -- etmemd_safe_free((void **)&task->eng->adp); -- task->eng->task = NULL; -- etmemd_safe_free((void **)&task->eng); -- task->eng = NULL; -- } -- -- task->proj = NULL; -+ clear_task_struct(task); - free(task); - *tk = NULL; - } - --void etmemd_print_tasks(const struct task *tk) -+void etmemd_print_tasks(int fd, const struct task *tk, char *eng_name, bool started) - { - const struct task *tmp = tk; - int i = 1; - - while (tmp != NULL) { -- printf("%-8d %-32s %-32s %-32s %-16s\n", -- i, -- tmp->type, -- tmp->value, -- etmemd_get_eng_name(tmp->eng->engine_type), -- tmp->timer_inst == NULL ? "false" : "true"); -+ dprintf_all(fd, "%-8d %-8s %-16s %-16s %-16s %-8s\n", -+ i, -+ tmp->type, -+ tmp->value, -+ tmp->name, -+ eng_name, -+ started ? "true" : "false"); - - tmp = tmp->next; - i++; - } - } -+ -+static int fill_task_name(void *obj, void *val) -+{ -+ struct task *tk = (struct task *)obj; -+ char *name = (char *)val; -+ tk->name = name; -+ return 0; -+} -+ -+static int fill_task_type(void *obj, void *val) -+{ -+ struct task *tk = (struct task *)obj; -+ char *type = (char *)val; -+ if (strcmp(val, "pid") != 0 && strcmp(val, "name") != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "invalid task type, must be pid or name.\n"); -+ return -1; -+ } -+ -+ tk->type = type; -+ return 0; -+} -+ -+static int fill_task_value(void *obj, void *val) -+{ -+ struct task *tk = (struct task *)obj; -+ char *value = (char *)val; -+ tk->value = value; -+ return 0; -+} -+ -+static int fill_task_threads(void *obj, void *val) -+{ -+ struct task *tk = (struct task *)obj; -+ int max_threads = parse_to_int(val); -+ int core; -+ -+ if (max_threads < 0) { -+ etmemd_log(ETMEMD_LOG_WARN, -+ "Thread count is abnormal, set the default minimum of current thread count to 1\n"); -+ max_threads = 1; -+ } -+ -+ core = get_nprocs(); -+ /* -+ * For IO intensive bussinesses, max-threads is limited to 2N + 1 of the maximum number -+ * of threads -+ */ -+ if (max_threads > 2 * core + 1) { -+ etmemd_log(ETMEMD_LOG_WARN, -+ "max-threads is limited to 2N+1 of the maximum number of threads\n"); -+ max_threads = 2 * core + 1; -+ } -+ -+ tk->max_threads = max_threads; -+ return 0; -+} -+ -+struct config_item g_task_config_items[] = { -+ {"name", STR_VAL, fill_task_name, false}, -+ {"type", STR_VAL, fill_task_type, false}, -+ {"value", STR_VAL, fill_task_value, false}, -+ {"max_threads", INT_VAL, fill_task_threads, true}, -+}; -+ -+static int task_fill_by_conf(GKeyFile *config, struct task *tk) -+{ -+ if (parse_file_config(config, TASK_GROUP, g_task_config_items, -+ ARRAY_SIZE(g_task_config_items), (void *)tk) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "parse task config fail\n"); -+ clear_task_struct(tk); -+ return -1; -+ } -+ return 0; -+} -+ -+struct task *etmemd_add_task(GKeyFile *config) -+{ -+ struct task *tk = calloc(1, sizeof(struct task)); -+ -+ if (tk == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc task struct fail\n"); -+ return NULL; -+ } -+ -+ /* set default count of the thread pool to 1 */ -+ tk->max_threads = 1; -+ if (task_fill_by_conf(config, tk) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "fill task from configuration file fail.\n"); -+ free(tk); -+ return NULL; -+ } -+ return tk; -+} -+ -+void etmemd_remove_task(struct task *tk) -+{ -+ clear_task_struct(tk); -+ free(tk); -+} --- -2.27.0 - diff --git a/0005-fix-code-check-problems.patch b/0005-fix-code-check-problems.patch deleted file mode 100644 index 15f2eca..0000000 --- a/0005-fix-code-check-problems.patch +++ /dev/null @@ -1,256 +0,0 @@ -From b54b30489959a7692cc6d484e3b16d1d54f7ed85 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Sun, 25 Apr 2021 21:44:44 +0800 -Subject: [PATCH 05/50] fix code check problems - -Signed-off-by: Kemeng Shi ---- - inc/etmemd_inc/etmemd_project.h | 3 ++- - src/etmem_src/etmem_common.c | 2 +- - src/etmemd_src/etmemd_common.c | 2 ++ - src/etmemd_src/etmemd_cslide.c | 32 +++++++++++++++++++++----------- - src/etmemd_src/etmemd_project.c | 9 ++++++--- - src/etmemd_src/etmemd_rpc.c | 4 ++-- - src/etmemd_src/etmemd_slide.c | 4 ++-- - 7 files changed, 36 insertions(+), 20 deletions(-) - -diff --git a/inc/etmemd_inc/etmemd_project.h b/inc/etmemd_inc/etmemd_project.h -index d15c7fd..e574a84 100644 ---- a/inc/etmemd_inc/etmemd_project.h -+++ b/inc/etmemd_inc/etmemd_project.h -@@ -102,7 +102,8 @@ enum opt_result etmemd_migrate_start(const char *project_name); - * */ - enum opt_result etmemd_migrate_stop(const char *project_name); - --enum opt_result etmemd_project_mgt_engine(const char *project_name, const char *eng_name, char *cmd, char *task_name, int sock_fd); -+enum opt_result etmemd_project_mgt_engine(const char *project_name, const char *eng_name, char *cmd, char *task_name, -+ int sock_fd); - enum opt_result etmemd_project_add_engine(GKeyFile *config); - enum opt_result etmemd_project_remove_engine(GKeyFile *config); - enum opt_result etmemd_project_add_task(GKeyFile *config); -diff --git a/src/etmem_src/etmem_common.c b/src/etmem_src/etmem_common.c -index 65d3690..8d0cee3 100644 ---- a/src/etmem_src/etmem_common.c -+++ b/src/etmem_src/etmem_common.c -@@ -36,7 +36,7 @@ int parse_name_string(const char *val, char **name_str, size_t max_len) - return -EINVAL; - } - if (len > max_len) { -- printf("string is too long, it should not be larger than %lu\n", max_len); -+ printf("string is too long, it should not be larger than %zu\n", max_len); - return -ENAMETOOLONG; - } - -diff --git a/src/etmemd_src/etmemd_common.c b/src/etmemd_src/etmemd_common.c -index 43ed013..4b9c4cb 100644 ---- a/src/etmemd_src/etmemd_common.c -+++ b/src/etmemd_src/etmemd_common.c -@@ -403,12 +403,14 @@ int dprintf_all(int fd, const char *format, ...) - ret = vsprintf_s(line, FILE_LINE_MAX_LEN, format, args_in); - if (ret > FILE_LINE_MAX_LEN) { - etmemd_log(ETMEMD_LOG_ERR, "fprintf_all fail as truncated.\n"); -+ va_end(args_in); - return -1; - } - - ret = write_all(fd, line); - if (ret < 0) { - etmemd_log(ETMEMD_LOG_ERR, "write_all fail.\n"); -+ va_end(args_in); - return -1; - } - -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index a3692ad..5fd1c32 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -8,7 +8,7 @@ - * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR - * PURPOSE. - * See the Mulan PSL v2 for more details. -- * Author: louhongxiang -+ * Author: shikemeng - * Create: 2021-4-19 - * Description: Memigd cslide API. - ******************************************************************************/ -@@ -44,7 +44,9 @@ - #define BATCHSIZE (1 << 16) - - #define factory_foreach_working_pid_params(iter, factory) \ -- for ((iter) = (factory)->working_head, next_working_params(&(iter)); (iter) != NULL; (iter) = (iter)->next, next_working_params(&(iter))) -+ for ((iter) = (factory)->working_head, next_working_params(&(iter)); \ -+ (iter) != NULL; \ -+ (iter) = (iter)->next, next_working_params(&(iter))) - - #define factory_foreach_pid_params(iter, factory) \ - for ((iter) = (factory)->working_head; (iter) != NULL; (iter) = (iter)->next) -@@ -184,7 +186,8 @@ struct page_filter { - void (*flow_cal_func)(struct flow_ctrl *ctrl); - long long (*flow_move_func)(struct flow_ctrl *ctrl, long long target, int node); - bool (*flow_enough)(struct flow_ctrl *ctrl); -- void (*filter_policy)(struct page_filter *filter, struct node_pair *pair, struct count_page_refs *cpf, struct memory_grade *memory_grade); -+ void (*filter_policy)(struct page_filter *filter, struct node_pair *pair, -+ struct count_page_refs *cpf, struct memory_grade *memory_grade); - struct flow_ctrl *ctrl; - int count_start; - int count_end; -@@ -509,7 +512,6 @@ static int add_node_pair(struct node_map *map, int cold_node, int hot_node) - return 0; - } - -- - static int init_node_verifier(struct node_verifier *nv, int node_num) - { - nv->nodes_map_count = calloc(node_num, sizeof(int)); -@@ -933,7 +935,8 @@ static bool node_cal_cold_can_move(struct node_ctrl *node_ctrl) - { - long long can_move; - -- can_move = node_ctrl->quota < node_ctrl->reserve - node_ctrl->free ? node_ctrl->quota : node_ctrl->reserve - node_ctrl->free; -+ can_move = node_ctrl->quota < node_ctrl->reserve - node_ctrl->free ? -+ node_ctrl->quota : node_ctrl->reserve - node_ctrl->free; - if (can_move > node_ctrl->cold_free) { - can_move = node_ctrl->cold_free; - } -@@ -956,7 +959,8 @@ static inline bool node_move_cold(struct node_ctrl *node_ctrl, long long *target - return cap_cost(&node_ctrl->cold_move_cap, target); - } - --static int init_flow_ctrl(struct flow_ctrl *ctrl, struct sys_mem *sys_mem, struct node_map *node_map, long long quota, long long reserve) -+static int init_flow_ctrl(struct flow_ctrl *ctrl, struct sys_mem *sys_mem, struct node_map *node_map, -+ long long quota, long long reserve) - { - struct node_pair *pair = NULL; - struct node_ctrl *tmp = NULL; -@@ -1114,7 +1118,8 @@ static void do_filter(struct page_filter *filter, struct cslide_eng_params *eng_ - } - } - --static void to_hot_policy(struct page_filter *filter, struct node_pair *pair, struct count_page_refs *cpf, struct memory_grade *memory_grade) -+static void to_hot_policy(struct page_filter *filter, struct node_pair *pair, -+ struct count_page_refs *cpf, struct memory_grade *memory_grade) - { - long long can_move; - struct node_page_refs *npf = &cpf->node_pfs[pair->cold_node]; -@@ -1123,7 +1128,8 @@ static void to_hot_policy(struct page_filter *filter, struct node_pair *pair, st - move_npf_to_list(npf, &memory_grade->hot_pages, can_move); - } - --static void to_cold_policy(struct page_filter *filter, struct node_pair *pair, struct count_page_refs *cpf, struct memory_grade *memory_grade) -+static void to_cold_policy(struct page_filter *filter, struct node_pair *pair, -+ struct count_page_refs *cpf, struct memory_grade *memory_grade) - { - long long can_move; - struct node_page_refs *npf = &cpf->node_pfs[pair->hot_node]; -@@ -1376,7 +1382,9 @@ static int cslide_merge_share_vmas(struct cslide_eng_params *eng_params) - - vma_pf = g_share_vma_head; - while (vma_pf != NULL) { -- for (iter = vma_pf->next, count = 1; iter != NULL && iter->vma->inode == vma_pf->vma->inode; iter = iter->next, count++) { -+ for (iter = vma_pf->next, count = 1; -+ iter != NULL && iter->vma->inode == vma_pf->vma->inode; -+ iter = iter->next, count++) { - ; - } - if (count > 1) { -@@ -1403,7 +1411,8 @@ static int cslide_get_vmas(struct cslide_pid_params *pid_params) - etmemd_log(ETMEMD_LOG_ERR, "sprintf pid %u fail\n", pid_params->pid); - return -1; - } -- pid_params->vmas = get_vmas_with_flags(pid, task_params->vmflags_array, task_params->vmflags_num, task_params->anon_only); -+ pid_params->vmas = get_vmas_with_flags(pid, task_params->vmflags_array, task_params->vmflags_num, -+ task_params->anon_only); - if (pid_params->vmas == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "get vmas for %s fail\n", pid); - return -1; -@@ -2108,7 +2117,8 @@ static int fill_node_pair(void *obj, void *val) - return ret; - } - -- for (pair = strtok_r(node_pair_str, pair_delim, &saveptr_pair); pair != NULL; pair = strtok_r(NULL, pair_delim, &saveptr_pair)) { -+ for (pair = strtok_r(node_pair_str, pair_delim, &saveptr_pair); pair != NULL; -+ pair = strtok_r(NULL, pair_delim, &saveptr_pair)) { - hot_node_str = strtok_r(pair, node_delim, &saveptr_node); - if (hot_node_str == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "parse hot node failed\n"); -diff --git a/src/etmemd_src/etmemd_project.c b/src/etmemd_src/etmemd_project.c -index 9ead14c..bd21819 100644 ---- a/src/etmemd_src/etmemd_project.c -+++ b/src/etmemd_src/etmemd_project.c -@@ -132,7 +132,8 @@ static enum opt_result engine_of_group(GKeyFile *config, char *group_name, struc - return OPT_SUCCESS; - } - --static enum opt_result task_of_group(GKeyFile *config, char *group_name, struct project *proj, struct engine *eng, struct task **tk) -+static enum opt_result task_of_group(GKeyFile *config, char *group_name, -+ struct project *proj, struct engine *eng, struct task **tk) - { - char *task_name = NULL; - char *key = NULL; -@@ -155,7 +156,8 @@ static enum opt_result task_of_group(GKeyFile *config, char *group_name, struct - return OPT_SUCCESS; - } - --static enum opt_result get_group_objs(GKeyFile *config, char *group_name, struct project **proj, struct engine **eng, struct task **tk) -+static enum opt_result get_group_objs(GKeyFile *config, char *group_name, -+ struct project **proj, struct engine **eng, struct task **tk) - { - enum opt_result ret; - -@@ -682,7 +684,8 @@ enum opt_result etmemd_migrate_stop(const char *project_name) - return OPT_SUCCESS; - } - --enum opt_result etmemd_project_mgt_engine(const char *project_name, const char *eng_name, char *cmd, char *task_name, int sock_fd) -+enum opt_result etmemd_project_mgt_engine(const char *project_name, const char *eng_name, char *cmd, char *task_name, -+ int sock_fd) - { - struct engine *eng = NULL; - struct project *proj = NULL; -diff --git a/src/etmemd_src/etmemd_rpc.c b/src/etmemd_src/etmemd_rpc.c -index e154083..2e8e49d 100644 ---- a/src/etmemd_src/etmemd_rpc.c -+++ b/src/etmemd_src/etmemd_rpc.c -@@ -121,7 +121,7 @@ static enum opt_result do_obj_cmd(GKeyFile *config, struct obj_cmd_item *items, - return OPT_SUCCESS; - } - --struct obj_cmd_item obj_add_items[] = { -+struct obj_cmd_item g_obj_add_items[] = { - {PROJ_GROUP, etmemd_project_add}, - {ENG_GROUP, etmemd_project_add_engine}, - {TASK_GROUP, etmemd_project_add_task}, -@@ -129,7 +129,7 @@ struct obj_cmd_item obj_add_items[] = { - - static enum opt_result do_obj_add(GKeyFile *config) - { -- return do_obj_cmd(config, obj_add_items, ARRAY_SIZE(obj_add_items)); -+ return do_obj_cmd(config, g_obj_add_items, ARRAY_SIZE(g_obj_add_items)); - } - - static struct obj_cmd_item obj_remove_items[] = { -diff --git a/src/etmemd_src/etmemd_slide.c b/src/etmemd_src/etmemd_slide.c -index ea9ccb4..f7609f4 100644 ---- a/src/etmemd_src/etmemd_slide.c -+++ b/src/etmemd_src/etmemd_slide.c -@@ -199,7 +199,7 @@ static void slide_stop_task(struct engine *eng, struct task *tk) - params->executor = NULL; - } - --struct engine_ops slide_eng_ops = { -+struct engine_ops g_slide_eng_ops = { - .fill_eng_params = NULL, - .clear_eng_params = NULL, - .fill_task_params = slide_fill_task, -@@ -213,7 +213,7 @@ struct engine_ops slide_eng_ops = { - - int fill_engine_type_slide(struct engine *eng) - { -- eng->ops = &slide_eng_ops; -+ eng->ops = &g_slide_eng_ops; - eng->engine_type = SLIDE_ENGINE; - eng->name = "slide"; - return 0; --- -2.27.0 - diff --git a/0006-remove-unused-share-vmas-merge.patch b/0006-remove-unused-share-vmas-merge.patch deleted file mode 100644 index d3946c1..0000000 --- a/0006-remove-unused-share-vmas-merge.patch +++ /dev/null @@ -1,240 +0,0 @@ -From c367b624d3674a572701e9ceee93ca5b73107f0c Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Mon, 26 Apr 2021 17:04:07 +0800 -Subject: [PATCH 06/50] remove unused share vmas merge - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_cslide.c | 197 --------------------------------- - 1 file changed, 197 deletions(-) - -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 5fd1c32..3983a32 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -194,18 +194,11 @@ struct page_filter { - int count_step; - }; - --struct page_offset { -- struct page_refs *page_refs; -- uint64_t to_offset; --}; -- - struct cslide_cmd_item { - char *name; - int (*func)(void *params, int fd); - }; - --struct vma_pf *g_share_vma_head = NULL; -- - static inline int get_node_num(void) - { - return numa_num_configured_nodes(); -@@ -1215,191 +1208,6 @@ static int cslide_policy(struct cslide_eng_params *eng_params) - return 0; - } - --static void sort_add_vma_pf(struct vma_pf *vma_pf) --{ -- struct vma_pf **iter = &g_share_vma_head; -- -- for (; *iter != NULL && (*iter)->vma->inode < vma_pf->vma->inode; iter = &((*iter)->next)) { -- ; -- } -- -- vma_pf->next = *iter; -- *iter = vma_pf; --} -- --static bool is_share(struct vma_pf *vma_pf) --{ -- struct vma *vma = vma_pf->vma; -- -- if (vma->inode != 0 && vma->stat[VMA_STAT_MAY_SHARE]) { -- return true; -- } -- -- return false; --} -- --static inline uint64_t to_offset(struct page_offset *po) --{ -- return po->page_refs->addr + po->to_offset; --} -- --static int page_offset_cmp(const void *a, const void *b) --{ -- struct page_offset *l = (struct page_offset *)a; -- struct page_offset *r = (struct page_offset *)b; -- -- return to_offset(l) - to_offset(r); --} -- --static inline void init_merge_po(struct page_offset *to_merge_po, int count) --{ -- qsort(to_merge_po, count, sizeof(struct page_offset), page_offset_cmp); --} -- --static void next_po(struct page_offset *to_merge_po, int *count) --{ -- struct page_offset *po = to_merge_po; -- struct page_offset tmp; -- uint64_t offset; -- int i; -- -- po->page_refs = po->page_refs->next; -- if (po->page_refs == NULL) { -- for (i = 1; i < *count; i++) { -- to_merge_po[i - 1] = to_merge_po[i]; -- } -- (*count)--; -- return; -- } -- -- tmp = *po; -- offset = to_offset(po); -- for (i = 1; i < *count; i++) { -- if (to_offset(&to_merge_po[i]) >= offset) { -- break; -- } -- to_merge_po[i - 1] = to_merge_po[i]; -- } -- to_merge_po[i - 1] = tmp; --} -- --static void merge_share_pfs(struct page_refs **share_pfs, int share_pfs_num) --{ -- int max_count = -1; -- struct page_refs *max_pf = NULL; -- int i; -- -- /* only keep one page_refs with max count */ -- for (i = 0; i < share_pfs_num; i++) { -- if (share_pfs[i]->count > max_count) { -- max_pf = share_pfs[i]; -- max_count = share_pfs[i]->count; -- } -- share_pfs[i]->count = -1; -- } -- max_pf->count = max_count; --} -- --static int do_merge_vma_pf(struct vma_pf *vma_pf, int count) --{ -- struct page_refs **share_pfs = NULL; -- struct page_offset *to_merge_po = NULL; -- struct page_offset *iter = NULL; -- int share_pfs_num; -- uint64_t cur_offset = 0; -- uint64_t next_offset; -- int i; -- -- share_pfs = calloc(count, sizeof(struct page_refs *)); -- if (share_pfs == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "alloc share_pfs fail\n"); -- return -1; -- } -- -- to_merge_po = calloc(count, sizeof(struct page_offset)); -- if (to_merge_po == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "alloc iter_pfs fail\n"); -- free(share_pfs); -- return -1; -- } -- -- for (i = 0; i < count; i++) { -- to_merge_po[i].page_refs = vma_pf->page_refs; -- to_merge_po[i].to_offset = vma_pf->vma->offset - vma_pf->vma->start; -- vma_pf = vma_pf->next; -- } -- -- init_merge_po(to_merge_po, count); -- iter = to_merge_po; -- share_pfs[0] = iter->page_refs; -- share_pfs_num = 1; -- cur_offset = to_offset(iter); -- -- for (next_po(to_merge_po, &count); count > 0; next_po(to_merge_po, &count)) { -- iter = to_merge_po; -- next_offset = to_offset(iter); -- if (next_offset == cur_offset) { -- share_pfs[share_pfs_num] = iter->page_refs; -- share_pfs_num++; -- } else { -- if (share_pfs_num > 1) { -- merge_share_pfs(share_pfs, share_pfs_num); -- } -- share_pfs[0] = iter->page_refs; -- share_pfs_num = 1; -- cur_offset = next_offset; -- } -- -- } -- if (share_pfs_num > 1) { -- merge_share_pfs(share_pfs, share_pfs_num); -- } -- -- free(to_merge_po); -- free(share_pfs); -- return 0; --} -- --static int cslide_merge_share_vmas(struct cslide_eng_params *eng_params) --{ -- struct cslide_pid_params *pid_params = NULL; -- struct vma_pf *vma_pf = NULL; -- struct vma_pf *iter = NULL; -- int count; -- uint64_t i; -- -- factory_foreach_working_pid_params(pid_params, &eng_params->factory) { -- vma_pf = pid_params->vma_pf; -- if (vma_pf == NULL) { -- continue; -- } -- for (i = 0; i < pid_params->vmas->vma_cnt; i++) { -- if (is_share(&vma_pf[i])) { -- sort_add_vma_pf(&vma_pf[i]); -- } -- } -- } -- -- vma_pf = g_share_vma_head; -- while (vma_pf != NULL) { -- for (iter = vma_pf->next, count = 1; -- iter != NULL && iter->vma->inode == vma_pf->vma->inode; -- iter = iter->next, count++) { -- ; -- } -- if (count > 1) { -- if (do_merge_vma_pf(vma_pf, count) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "merge vma with inode %lld fail\n", vma_pf->vma->inode); -- g_share_vma_head = NULL; -- return -1; -- } -- } -- vma_pf = iter; -- } -- g_share_vma_head = NULL; -- return 0; --} -- - static int cslide_get_vmas(struct cslide_pid_params *pid_params) - { - struct cslide_task_params *task_params = pid_params->task_params; -@@ -1525,11 +1333,6 @@ static int cslide_do_scan(struct cslide_eng_params *eng_params) - sleep(eng_params->sleep); - } - -- if (cslide_merge_share_vmas(eng_params) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "cslide merge share vams fail\n"); -- return -1; -- } -- - return 0; - } - --- -2.27.0 - diff --git a/0007-fix-error-when-open-idle_pages-failed.patch b/0007-fix-error-when-open-idle_pages-failed.patch deleted file mode 100644 index 66fa3d4..0000000 --- a/0007-fix-error-when-open-idle_pages-failed.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 910519ccf986b80a7ee5a5aab90b62828bdc8b84 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Wed, 28 Apr 2021 09:54:06 +0800 -Subject: [PATCH 07/50] fix error when open idle_pages failed - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_cslide.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 3983a32..618cafe 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -1281,7 +1281,6 @@ static int cslide_scan_vmas(struct cslide_pid_params *params) - scan_fp = etmemd_get_proc_file(pid, IDLE_SCAN_FILE, SCAN_AS_HUGE, "r"); - if (scan_fp == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "open %s file for pid %u fail\n", IDLE_SCAN_FILE, params->pid); -- params->vma_pf = NULL; - return -1; - } - -@@ -1298,7 +1297,6 @@ static int cslide_scan_vmas(struct cslide_pid_params *params) - walk_address.walk_end = vma->end; - if (walk_vmas(fd, &walk_address, &vma_pf->page_refs, NULL) == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "scan vma start %llu end %llu fail\n", vma->start, vma->end); -- cslide_free_vmas(params); - fclose(scan_fp); - return -1; - } -@@ -1308,6 +1306,8 @@ static int cslide_scan_vmas(struct cslide_pid_params *params) - return 0; - } - -+// allocted data will be cleaned in cslide_main->cslide_clean_params -+// ->cslide_free_vmas - static int cslide_do_scan(struct cslide_eng_params *eng_params) - { - struct cslide_pid_params *iter = NULL; -@@ -1531,7 +1531,9 @@ static void cslide_clean_params(struct cslide_eng_params *eng_params) - struct cslide_pid_params *iter = NULL; - - factory_foreach_pid_params(iter, &eng_params->factory) { -+ // clean memory allocted in cslide_policy - clean_pid_param(iter); -+ // clean memory allocted in cslide_do_scan - cslide_free_vmas(iter); - } - } --- -2.27.0 - diff --git a/0008-fix-memleak.patch b/0008-fix-memleak.patch deleted file mode 100644 index ce7f29a..0000000 --- a/0008-fix-memleak.patch +++ /dev/null @@ -1,134 +0,0 @@ -From c76f33082c0a67fe95fd7a00b079fb7191da32d5 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Wed, 28 Apr 2021 16:39:49 +0800 -Subject: [PATCH 08/50] fix memleak - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_cslide.c | 23 ++++++++++++++++++----- - src/etmemd_src/etmemd_rpc.c | 17 ++++++++++++++++- - 2 files changed, 34 insertions(+), 6 deletions(-) - -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 618cafe..18cf740 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -689,6 +689,14 @@ static void factory_remove_pid_params(struct cslide_params_factory *factory, str - - static void factory_free_pid_params(struct cslide_params_factory *factory, struct cslide_pid_params *params) - { -+ // Pid not started i.e not used. Free it here -+ if (params->state == STATE_NONE) { -+ free_pid_params(params); -+ return; -+ } -+ -+ // Pid in use, free by cslide main when call factory_update_pid_params -+ // Avoid data race - params->state = STATE_FREE; - } - -@@ -771,7 +779,7 @@ static int cslide_count_node_pfs(struct cslide_pid_params *params) - void **pages = NULL; - int *status = NULL; - int actual_num = 0; -- int ret = -1; -+ int ret = 0; - int vma_i = 0; - - if (params->vmas == NULL || params->vma_pf == NULL) { -@@ -787,6 +795,7 @@ static int cslide_count_node_pfs(struct cslide_pid_params *params) - pages = malloc(sizeof(void *) * batch_size); - if (pages == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "malloc pages fail\n"); -+ ret = -1; - goto free_status; - } - -@@ -800,7 +809,9 @@ static int cslide_count_node_pfs(struct cslide_pid_params *params) - if (actual_num == batch_size || page_refs->next == NULL) { - if (move_pages(pid, actual_num, pages, NULL, status, MPOL_MF_MOVE_ALL) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "get page refs numa node fail\n"); -- goto free_pages; -+ clean_page_refs_unexpected(&last); -+ ret = -1; -+ break; - } - insert_count_pfs(params->count_page_refs, last, status, actual_num); - last = page_refs->next; -@@ -808,10 +819,10 @@ static int cslide_count_node_pfs(struct cslide_pid_params *params) - } - page_refs = page_refs->next; - } -+ -+ // this must be called before return - setup_count_pfs_tail(params->count_page_refs, params->count); -- ret = 0; - --free_pages: - free(pages); - pages = NULL; - free_status: -@@ -2033,7 +2044,7 @@ static int cslide_fill_eng(GKeyFile *config, struct engine *eng) - - if (init_cslide_eng_params(params) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "init cslide engine params fail\n"); -- return -1; -+ goto free_eng_params; - } - - params->loop = eng->proj->loop; -@@ -2055,6 +2066,8 @@ static int cslide_fill_eng(GKeyFile *config, struct engine *eng) - - destroy_eng_params: - destroy_cslide_eng_params(params); -+free_eng_params: -+ free(params); - return -1; - } - -diff --git a/src/etmemd_src/etmemd_rpc.c b/src/etmemd_src/etmemd_rpc.c -index 2e8e49d..49c292d 100644 ---- a/src/etmemd_src/etmemd_rpc.c -+++ b/src/etmemd_src/etmemd_rpc.c -@@ -492,6 +492,21 @@ static void free_server_rpc_params(struct server_rpc_params *svr) - free(svr->file_name); - svr->file_name = NULL; - } -+ -+ if (svr->eng_name != NULL) { -+ free(svr->eng_name); -+ svr->eng_name = NULL; -+ } -+ -+ if (svr->eng_cmd != NULL) { -+ free(svr->eng_cmd); -+ svr->eng_cmd = NULL; -+ } -+ -+ if (svr->task_name != NULL) { -+ free(svr->task_name); -+ svr->task_name = NULL; -+ } - } - - static void etmemd_rpc_send_response_msg(int sock_fd, enum opt_result result) -@@ -531,7 +546,6 @@ static void etmemd_rpc_handle(int sock_fd) - } - - etmemd_rpc_send_response_msg(sock_fd, ret); -- free_server_rpc_params(&g_rpc_params); - return; - } - -@@ -605,6 +619,7 @@ static int etmemd_rpc_accept(int sock_fd) - if (etmemd_rpc_parse(recv_buf, (unsigned long)rc) == 0) { - etmemd_rpc_handle(accp_fd); - } -+ free_server_rpc_params(&g_rpc_params); - ret = 0; - - RPC_EXIT: --- -2.27.0 - diff --git a/0009-fix-some-bugs-that-occur-when-execute-obj-add-or-del.patch b/0009-fix-some-bugs-that-occur-when-execute-obj-add-or-del.patch deleted file mode 100644 index ceea45c..0000000 --- a/0009-fix-some-bugs-that-occur-when-execute-obj-add-or-del.patch +++ /dev/null @@ -1,56 +0,0 @@ -From a3e62729dafbb634a73921c2200337fb46ab923e Mon Sep 17 00:00:00 2001 -From: louhongxiang -Date: Thu, 29 Apr 2021 10:47:51 +0800 -Subject: [PATCH 09/50] fix some bugs that occur when execute obj add or del - command. - ---- - src/etmem_src/etmem_rpc.c | 2 +- - src/etmemd_src/etmemd_file.c | 4 ++++ - src/etmemd_src/etmemd_rpc.c | 2 +- - 3 files changed, 6 insertions(+), 2 deletions(-) - -diff --git a/src/etmem_src/etmem_rpc.c b/src/etmem_src/etmem_rpc.c -index 8d03914..fadf1ea 100644 ---- a/src/etmem_src/etmem_rpc.c -+++ b/src/etmem_src/etmem_rpc.c -@@ -182,7 +182,7 @@ static int etmem_client_recv(int sockfd) - - recv_msg = (char *)recv_buf; - recv_msg[recv_size] = '\0'; -- printf("%s", recv_msg); -+ printf("%s\n", recv_msg); - if (etmem_recv_find_fail_keyword(recv_msg)) { - printf("error occurs when getting response from etmemd server\n"); - goto EXIT; -diff --git a/src/etmemd_src/etmemd_file.c b/src/etmemd_src/etmemd_file.c -index ac2654e..8b478c6 100644 ---- a/src/etmemd_src/etmemd_file.c -+++ b/src/etmemd_src/etmemd_file.c -@@ -35,6 +35,10 @@ static int parse_item(GKeyFile *config, char *group_name, struct config_item *it - break; - case STR_VAL: - val = (void *)g_key_file_get_string(config, group_name, item->key, &error); -+ if (val == NULL || strlen(val) == 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "section %s of group [%s] should not be empty\n", item->key, group_name); -+ return -1; -+ } - break; - default: - etmemd_log(ETMEMD_LOG_ERR, "config item type %d not support\n", item->type); -diff --git a/src/etmemd_src/etmemd_rpc.c b/src/etmemd_src/etmemd_rpc.c -index 49c292d..a8653e2 100644 ---- a/src/etmemd_src/etmemd_rpc.c -+++ b/src/etmemd_src/etmemd_rpc.c -@@ -63,7 +63,7 @@ struct rpc_resp_msg g_resp_msg_arr[] = { - {OPT_ENG_NOEXIST, "error: engine is not exist"}, - {OPT_TASK_EXISTED, "error: task has been existed"}, - {OPT_TASK_NOEXIST, "error: task is not exist"}, -- {OPT_INTER_ERR, "error: etmemd has internal error"}, -+ {OPT_INTER_ERR, "error: etmemd has internal error, see reason details in messages"}, - {OPT_RET_END, NULL}, - }; - --- -2.27.0 - diff --git a/0010-clean-code.patch b/0010-clean-code.patch deleted file mode 100644 index 69d60fa..0000000 --- a/0010-clean-code.patch +++ /dev/null @@ -1,334 +0,0 @@ -From 146be685ec749239979023358a653ef960652f6c Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Wed, 28 Apr 2021 19:19:30 +0800 -Subject: [PATCH 10/50] clean code - -Signed-off-by: Kemeng Shi ---- - inc/etmem_inc/etmem_common.h | 2 - - src/etmem_src/etmem.c | 2 +- - src/etmem_src/etmem_common.c | 73 --------------------------------- - src/etmem_src/etmem_engine.c | 18 +++++--- - src/etmem_src/etmem_obj.c | 46 ++------------------- - src/etmem_src/etmem_project.c | 22 +++------- - src/etmem_src/etmem_rpc.c | 2 +- - src/etmemd_src/etmemd_project.c | 6 ++- - 8 files changed, 30 insertions(+), 141 deletions(-) - -diff --git a/inc/etmem_inc/etmem_common.h b/inc/etmem_inc/etmem_common.h -index 294d216..09f6e1a 100644 ---- a/inc/etmem_inc/etmem_common.h -+++ b/inc/etmem_inc/etmem_common.h -@@ -36,8 +36,6 @@ struct mem_proj { - char *eng_cmd; - }; - --int parse_name_string(const char *val, char **name_str, size_t max_len); - int etmem_parse_check_result(int params_cnt, int argc); --void free_proj_member(struct mem_proj *proj); - - #endif -diff --git a/src/etmem_src/etmem.c b/src/etmem_src/etmem.c -index 863f91b..7f04ad1 100644 ---- a/src/etmem_src/etmem.c -+++ b/src/etmem_src/etmem.c -@@ -34,7 +34,7 @@ static void usage(void) - " etmem OBJECT COMMAND\n" - " etmem help\n" - "\nParameters:\n" -- " OBJECT := { project | migrate }\n" -+ " OBJECT := { project | obj }\n" - " COMMAND := { add | del | start | stop | show | help }\n"); - } - -diff --git a/src/etmem_src/etmem_common.c b/src/etmem_src/etmem_common.c -index 8d0cee3..66fbfc9 100644 ---- a/src/etmem_src/etmem_common.c -+++ b/src/etmem_src/etmem_common.c -@@ -20,43 +20,6 @@ - #include "securec.h" - #include "etmem_common.h" - --int parse_name_string(const char *val, char **name_str, size_t max_len) --{ -- size_t len; -- int ret; -- -- if (val == NULL) { -- printf("name string should not be NULL\n"); -- return -EINVAL; -- } -- -- len = strlen(val) + 1; -- if (len == 1) { -- printf("name string should not be empty\n"); -- return -EINVAL; -- } -- if (len > max_len) { -- printf("string is too long, it should not be larger than %zu\n", max_len); -- return -ENAMETOOLONG; -- } -- -- *name_str = (char *)calloc(len, sizeof(char)); -- if (*name_str == NULL) { -- printf("malloc project name failed.\n"); -- return -ENOMEM; -- } -- -- ret = strncpy_s(*name_str, len, val, len - 1); -- if (ret != EOK) { -- printf("strncpy_s project name failed.\n"); -- free(*name_str); -- *name_str = NULL; -- return ret; -- } -- -- return 0; --} -- - int etmem_parse_check_result(int params_cnt, int argc) - { - if (params_cnt > 0 && argc - 1 > params_cnt * 2) { /* maximum number of args is limited to params_cnt * 2+1 */ -@@ -66,39 +29,3 @@ int etmem_parse_check_result(int params_cnt, int argc) - - return 0; - } -- --void free_proj_member(struct mem_proj *proj) --{ -- if (proj->proj_name != NULL) { -- free(proj->proj_name); -- proj->proj_name = NULL; -- } -- -- if (proj->file_name != NULL) { -- free(proj->file_name); -- proj->file_name = NULL; -- } -- -- if (proj->sock_name != NULL) { -- free(proj->sock_name); -- proj->sock_name = NULL; -- } -- -- if (proj->eng_name != NULL) { -- free(proj->eng_name); -- proj->eng_name = NULL; -- } -- -- if (proj->task_name != NULL) { -- free(proj->task_name); -- proj->task_name = NULL; -- } -- -- if (proj->eng_cmd != NULL) { -- free(proj->eng_cmd); -- proj->eng_cmd = NULL; -- } -- --} -- -- -diff --git a/src/etmem_src/etmem_engine.c b/src/etmem_src/etmem_engine.c -index 7673205..e744aaa 100644 ---- a/src/etmem_src/etmem_engine.c -+++ b/src/etmem_src/etmem_engine.c -@@ -23,15 +23,23 @@ - - static void engine_help(void) - { -- printf("etmem engine help information\n"); -+ printf("\nUsage:\n" -+ " memig engine eng_cmd [options]\n" -+ " memig engine help\n" -+ "\nOptions:\n" -+ " -n|--proj_name project engine belongs to\n" -+ " -s|--socket socket name to connect\n" -+ " -e|--engine engine to execute cmd\n" -+ " -t|--task_name task for cmd\n" -+ "\nNotes:\n" -+ " 1. project name must be given.\n" -+ " 2. socket name must be given.\n" -+ " 3. engine name must be given.\n" -+ " 4. engine cmd must be given.\n"); - } - - static int engine_parse_cmd(struct etmem_conf *conf, struct mem_proj *proj) - { -- if (conf->argc == 0) { -- printf("too few params for etmem client engine command\n"); -- return -1; -- } - proj->eng_cmd = conf->argv[0]; - proj->cmd = ETMEM_CMD_ENGINE; - return 0; -diff --git a/src/etmem_src/etmem_obj.c b/src/etmem_src/etmem_obj.c -index a3f66fe..a5517ea 100644 ---- a/src/etmem_src/etmem_obj.c -+++ b/src/etmem_src/etmem_obj.c -@@ -61,34 +61,6 @@ static int obj_parse_cmd(struct etmem_conf *conf, struct mem_proj *proj) - return -1; - } - --static int parse_file_name(const char *val, char **file_name) --{ -- size_t len; -- int ret; -- -- len = strlen(val) + 1; -- if (len > FILE_NAME_MAX_LEN) { -- printf("file name is too long, should not be larger than %u\n", FILE_NAME_MAX_LEN); -- return -ENAMETOOLONG; -- } -- -- *file_name = (char *)calloc(len, sizeof(char)); -- if (*file_name == NULL) { -- printf("malloc file name failed\n"); -- return -ENOMEM; -- } -- -- ret = strncpy_s(*file_name, len, val, len - 1); -- if (ret != EOK) { -- printf("strncpy_s file name fail\n"); -- free(*file_name); -- *file_name = NULL; -- return ret; -- } -- -- return 0; --} -- - static int obj_parse_args(struct etmem_conf *conf, struct mem_proj *proj) - { - int opt, ret; -@@ -102,18 +74,10 @@ static int obj_parse_args(struct etmem_conf *conf, struct mem_proj *proj) - while ((opt = getopt_long(conf->argc, conf->argv, "f:s:", opts, NULL)) != -1) { - switch (opt) { - case 'f': -- ret = parse_file_name(optarg, &proj->file_name); -- if (ret != 0) { -- printf("parse file name failed\n"); -- return ret; -- } -+ proj->file_name = optarg; - break; - case 's': -- ret = parse_name_string(optarg, &proj->sock_name, SOCKET_NAME_MAX_LEN); -- if (ret != 0) { -- printf("parse socket name failed.\n"); -- return ret; -- } -+ proj->sock_name = optarg; - break; - case '?': - /* fallthrough */ -@@ -164,19 +128,17 @@ static int obj_do_cmd(struct etmem_conf *conf) - ret = obj_parse_args(conf, &proj); - if (ret != 0) { - printf("obj_parse_args fail\n"); -- goto EXIT; -+ return ret; - } - - ret = obj_check_params(&proj); - if (ret != 0) { - printf("obj_check_params fail\n"); -- goto EXIT; -+ return ret; - } - - ret = etmem_rpc_client(&proj); - --EXIT: -- free_proj_member(&proj); - return ret; - } - -diff --git a/src/etmem_src/etmem_project.c b/src/etmem_src/etmem_project.c -index 790979e..bb53df3 100644 ---- a/src/etmem_src/etmem_project.c -+++ b/src/etmem_src/etmem_project.c -@@ -78,22 +78,14 @@ static int project_parse_args(const struct etmem_conf *conf, struct mem_proj *pr - {NULL, 0, NULL, 0}, - }; - -- while ((opt = getopt_long(conf->argc, conf->argv, "f:n:s:", -+ while ((opt = getopt_long(conf->argc, conf->argv, "n:s:", - opts, NULL)) != -1) { - switch (opt) { - case 'n': -- ret = parse_name_string(optarg, &proj->proj_name, PROJECT_NAME_MAX_LEN); -- if (ret != 0) { -- printf("parse project name failed.\n"); -- return ret; -- } -+ proj->proj_name = optarg; - break; - case 's': -- ret = parse_name_string(optarg, &proj->sock_name, SOCKET_NAME_MAX_LEN); -- if (ret != 0) { -- printf("parse socket name failed.\n"); -- return ret; -- } -+ proj->sock_name = optarg; - break; - case '?': - /* fallthrough */ -@@ -148,18 +140,16 @@ static int project_do_cmd(struct etmem_conf *conf) - - ret = project_parse_args(conf, &proj); - if (ret != 0) { -- goto EXIT; -+ return ret; - } - - ret = project_check_params(&proj); - if (ret != 0) { -- goto EXIT; -+ return ret; - } - -- etmem_rpc_client(&proj); -+ ret = etmem_rpc_client(&proj); - --EXIT: -- free_proj_member(&proj); - return ret; - } - -diff --git a/src/etmem_src/etmem_rpc.c b/src/etmem_src/etmem_rpc.c -index 8d03914..76fadb8 100644 ---- a/src/etmem_src/etmem_rpc.c -+++ b/src/etmem_src/etmem_rpc.c -@@ -134,7 +134,7 @@ static int etmem_client_send(const struct mem_proj *proj, int sockfd) - } - - if (send(sockfd, reg_cmd, reg_cmd_len, 0) < 0) { -- perror("send failed:"); -+ perror("send failed:"); - goto EXIT; - } - ret = 0; -diff --git a/src/etmemd_src/etmemd_project.c b/src/etmemd_src/etmemd_project.c -index bd21819..b3158d8 100644 ---- a/src/etmemd_src/etmemd_project.c -+++ b/src/etmemd_src/etmemd_project.c -@@ -709,10 +709,14 @@ enum opt_result etmemd_project_mgt_engine(const char *project_name, const char * - eng = get_eng_by_name(proj, eng_name); - if (eng == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "engine %s is not existed\n", eng_name); -- return OPT_INVAL; -+ return OPT_ENG_NOEXIST; - } - if (task_name != NULL) { - tk = get_task_by_name(proj, eng, task_name); -+ if (tk == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "task %s not found\n", task_name); -+ return OPT_TASK_NOEXIST; -+ } - } - if (eng->ops->eng_mgt_func(eng, tk, cmd, sock_fd) != 0) { - return OPT_INVAL; --- -2.27.0 - diff --git a/0011-wait-for-next-period-when-error-occurs-in-this-perio.patch b/0011-wait-for-next-period-when-error-occurs-in-this-perio.patch deleted file mode 100644 index aa82585..0000000 --- a/0011-wait-for-next-period-when-error-occurs-in-this-perio.patch +++ /dev/null @@ -1,111 +0,0 @@ -From e92f5b0da3bde551281df30c498e701c767e3335 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Wed, 28 Apr 2021 19:36:57 +0800 -Subject: [PATCH 11/50] wait for next period when error occurs in this period - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_cslide.c | 24 ++++++++++++++++-------- - 1 file changed, 16 insertions(+), 8 deletions(-) - -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 18cf740..1749383 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -1184,7 +1184,7 @@ static void move_cold_pages(struct cslide_eng_params *eng_params, struct flow_ct - do_filter(&filter, eng_params); - } - --static void cslide_filter_pfs(struct cslide_eng_params *eng_params) -+static int cslide_filter_pfs(struct cslide_eng_params *eng_params) - { - struct flow_ctrl ctrl; - long long quota = (long long)eng_params->mig_quota * HUGE_1M_SIZE; -@@ -1192,7 +1192,7 @@ static void cslide_filter_pfs(struct cslide_eng_params *eng_params) - - if (init_flow_ctrl(&ctrl, &eng_params->mem, &eng_params->node_map, quota, reserve) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "init_flow_ctrl fail\n"); -- return; -+ return -1; - } - - move_hot_pages(eng_params, &ctrl); -@@ -1200,6 +1200,7 @@ static void cslide_filter_pfs(struct cslide_eng_params *eng_params) - move_cold_pages(eng_params, &ctrl); - - destroy_flow_ctrl(&ctrl); -+ return 0; - } - - static int cslide_policy(struct cslide_eng_params *eng_params) -@@ -1215,8 +1216,7 @@ static int cslide_policy(struct cslide_eng_params *eng_params) - } - } - -- cslide_filter_pfs(eng_params); -- return 0; -+ return cslide_filter_pfs(eng_params); - } - - static int cslide_get_vmas(struct cslide_pid_params *pid_params) -@@ -1225,6 +1225,7 @@ static int cslide_get_vmas(struct cslide_pid_params *pid_params) - struct vma *vma = NULL; - char pid[PID_STR_MAX_LEN] = {0}; - uint64_t i; -+ int ret = -1; - - if (snprintf_s(pid, PID_STR_MAX_LEN, PID_STR_MAX_LEN - 1, "%u", pid_params->pid) <= 0) { - etmemd_log(ETMEMD_LOG_ERR, "sprintf pid %u fail\n", pid_params->pid); -@@ -1236,6 +1237,13 @@ static int cslide_get_vmas(struct cslide_pid_params *pid_params) - etmemd_log(ETMEMD_LOG_ERR, "get vmas for %s fail\n", pid); - return -1; - } -+ // avoid calloc for vma_pf with size 0 below -+ // return success as vma may be created later -+ if (pid_params->vmas->vma_cnt == 0) { -+ etmemd_log(ETMEMD_LOG_WARN, "no vma detect for %s\n", pid); -+ ret = 0; -+ goto free_vmas; -+ } - - pid_params->vma_pf = calloc(pid_params->vmas->vma_cnt, sizeof(struct vma_pf)); - if (pid_params->vma_pf == NULL) { -@@ -1253,7 +1261,7 @@ static int cslide_get_vmas(struct cslide_pid_params *pid_params) - free_vmas: - free_vmas(pid_params->vmas); - pid_params->vmas = NULL; -- return -1; -+ return ret; - } - - static void cslide_free_vmas(struct cslide_pid_params *params) -@@ -1327,7 +1335,7 @@ static int cslide_do_scan(struct cslide_eng_params *eng_params) - factory_foreach_working_pid_params(iter, &eng_params->factory) { - if (cslide_get_vmas(iter) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "cslide get vmas fail\n"); -- continue; -+ return -1; - } - } - -@@ -1338,7 +1346,7 @@ static int cslide_do_scan(struct cslide_eng_params *eng_params) - } - if (cslide_scan_vmas(iter) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "cslide scan vmas fail\n"); -- continue; -+ return -1; - } - } - sleep(eng_params->sleep); -@@ -1387,7 +1395,7 @@ static int do_migrate_pages(unsigned int pid, struct page_refs *page_refs, int n - actual_num = 0; - if (ret != 0) { - etmemd_log(ETMEMD_LOG_ERR, "task %d move_pages fail with %d errno %d\n", pid, ret, errno); -- continue; -+ break; - } - } - } --- -2.27.0 - diff --git a/0012-add-recursive-in-etmemd_get_task_pids.patch b/0012-add-recursive-in-etmemd_get_task_pids.patch deleted file mode 100644 index 65faf51..0000000 --- a/0012-add-recursive-in-etmemd_get_task_pids.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 2eba7f18281d1a7a6a728095cd16b1ebb1b36c0a Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Wed, 28 Apr 2021 19:48:33 +0800 -Subject: [PATCH 12/50] add recursive in etmemd_get_task_pids to control if it - should get child pids. cslide will not get child pids. - -Signed-off-by: Kemeng Shi ---- - inc/etmemd_inc/etmemd_task.h | 2 +- - src/etmemd_src/etmemd_cslide.c | 2 +- - src/etmemd_src/etmemd_pool_adapter.c | 2 +- - src/etmemd_src/etmemd_task.c | 23 +++++++++++++---------- - 4 files changed, 16 insertions(+), 13 deletions(-) - -diff --git a/inc/etmemd_inc/etmemd_task.h b/inc/etmemd_inc/etmemd_task.h -index d6d89ea..3f32be5 100644 ---- a/inc/etmemd_inc/etmemd_task.h -+++ b/inc/etmemd_inc/etmemd_task.h -@@ -51,7 +51,7 @@ struct task { - struct task *next; - }; - --int etmemd_get_task_pids(struct task *tk); -+int etmemd_get_task_pids(struct task *tk, bool recursive); - - void etmemd_free_task_pids(struct task *tk); - -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 1749383..43d8108 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -1899,7 +1899,7 @@ static int cslide_fill_task(GKeyFile *config, struct task *tk) - } - - tk->params = params; -- if (etmemd_get_task_pids(tk) != 0) { -+ if (etmemd_get_task_pids(tk, false) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "cslide fail to get task pids\n"); - tk->params = NULL; - goto exit; -diff --git a/src/etmemd_src/etmemd_pool_adapter.c b/src/etmemd_src/etmemd_pool_adapter.c -index 417f864..b879dbc 100644 ---- a/src/etmemd_src/etmemd_pool_adapter.c -+++ b/src/etmemd_src/etmemd_pool_adapter.c -@@ -49,7 +49,7 @@ static void *launch_threadtimer_executor(void *arg) - int scheduing_count; - - if (tk->eng->proj->start) { -- if (etmemd_get_task_pids(tk) != 0) { -+ if (etmemd_get_task_pids(tk, true) != 0) { - return NULL; - } - -diff --git a/src/etmemd_src/etmemd_task.c b/src/etmemd_src/etmemd_task.c -index 5c81b74..61ba0df 100644 ---- a/src/etmemd_src/etmemd_task.c -+++ b/src/etmemd_src/etmemd_task.c -@@ -264,19 +264,13 @@ int get_pid_from_task_type(const struct task *tk, char *pid) - return -1; - } - --static int get_and_fill_pids(struct task *tk, char *pid) -+static int fill_task_child_pid(struct task *tk, char *pid) - { - char *arg_pid[] = {"/usr/bin/pgrep", "-P", pid, NULL}; - FILE *file = NULL; - int ret; - int pipefd[2]; /* used for pipefd[2] communication to obtain the task PID */ - -- /* first, insert the pid of task into the pids list */ -- if (fill_task_pid(tk, pid) != 0) { -- etmemd_log(ETMEMD_LOG_WARN, "fill task pid fail\n"); -- return -1; -- } -- - if (pipe(pipefd) == -1) { - return -1; - } -@@ -341,7 +335,7 @@ void etmemd_free_task_pids(struct task *tk) - } - } - --int etmemd_get_task_pids(struct task *tk) -+int etmemd_get_task_pids(struct task *tk, bool recursive) - { - char pid[PID_STR_MAX_LEN] = {0}; - -@@ -356,8 +350,17 @@ int etmemd_get_task_pids(struct task *tk) - return -1; - } - -- /* then fill the pids according to the pid of task */ -- if (get_and_fill_pids(tk, pid) != 0) { -+ /* first, insert the pid of task into the pids list */ -+ if (fill_task_pid(tk, pid) != 0) { -+ etmemd_log(ETMEMD_LOG_WARN, "fill task pid fail\n"); -+ return -1; -+ } -+ if (!recursive) { -+ return 0; -+ } -+ -+ /* then fill the child pids according to the pid of task */ -+ if (fill_task_child_pid(tk, pid) != 0) { - etmemd_free_task_pids(tk); - etmemd_log(ETMEMD_LOG_WARN, "get task child pids fail\n"); - return -1; --- -2.27.0 - diff --git a/0013-check-permission-according-cmd-to-be-executed.patch b/0013-check-permission-according-cmd-to-be-executed.patch deleted file mode 100644 index 9ba7154..0000000 --- a/0013-check-permission-according-cmd-to-be-executed.patch +++ /dev/null @@ -1,130 +0,0 @@ -From c4aca9bea94bc7fd639a6b508675b3f113e3736e Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Thu, 29 Apr 2021 09:26:06 +0800 -Subject: [PATCH 13/50] check permission according cmd to be executed - -Signed-off-by: Kemeng Shi ---- - inc/etmemd_inc/etmemd_rpc.h | 2 + - src/etmemd_src/etmemd_rpc.c | 75 ++++++++++++++++++++++--------------- - 2 files changed, 46 insertions(+), 31 deletions(-) - -diff --git a/inc/etmemd_inc/etmemd_rpc.h b/inc/etmemd_inc/etmemd_rpc.h -index 146cec3..4f61390 100644 ---- a/inc/etmemd_inc/etmemd_rpc.h -+++ b/inc/etmemd_inc/etmemd_rpc.h -@@ -55,5 +55,7 @@ int etmemd_parse_sock_name(const char *sock_name); - int etmemd_rpc_server(void); - bool etmemd_sock_name_set(void); - void etmemd_sock_name_free(void); -+// some engine cmd need to check socket permission -+int check_socket_permission(int sock_fd); - - #endif -diff --git a/src/etmemd_src/etmemd_rpc.c b/src/etmemd_src/etmemd_rpc.c -index 49c292d..09497b3 100644 ---- a/src/etmemd_src/etmemd_rpc.c -+++ b/src/etmemd_src/etmemd_rpc.c -@@ -181,10 +181,54 @@ free_file: - return ret; - } - -+int check_socket_permission(int sock_fd) { -+ struct ucred cred; -+ socklen_t len; -+ ssize_t rc; -+ -+ len = sizeof(struct ucred); -+ -+ rc = getsockopt(sock_fd, -+ SOL_SOCKET, -+ SO_PEERCRED, -+ &cred, -+ &len); -+ if (rc < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "getsockopt failed, err(%s)\n", -+ strerror(errno)); -+ return -1; -+ } -+ -+ if (cred.uid != 0 || cred.gid != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "client socket connect failed, permition denied\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+// ENG_CMD cmd permission checked inside engine -+static int check_cmd_permission(int sock_fd, int cmd) -+{ -+ switch (cmd) { -+ case OBJ_ADD: -+ case OBJ_DEL: -+ case MIG_STOP: -+ case MIG_START: -+ return check_socket_permission(sock_fd); -+ default: -+ return 0; -+ } -+} -+ - static enum opt_result etmemd_switch_cmd(const struct server_rpc_params svr_param) - { - enum opt_result ret = OPT_INVAL; - -+ if (check_cmd_permission(svr_param.sock_fd, svr_param.cmd) != 0) { -+ return OPT_INVAL; -+ } -+ - switch (svr_param.cmd) { - case OBJ_ADD: - case OBJ_DEL: -@@ -549,32 +593,6 @@ static void etmemd_rpc_handle(int sock_fd) - return; - } - --static int check_socket_permission(int sock_fd) { -- struct ucred cred; -- socklen_t len; -- ssize_t rc; -- -- len = sizeof(struct ucred); -- -- rc = getsockopt(sock_fd, -- SOL_SOCKET, -- SO_PEERCRED, -- &cred, -- &len); -- if (rc < 0) { -- etmemd_log(ETMEMD_LOG_ERR, "getsockopt failed, err(%s)\n", -- strerror(errno)); -- return -1; -- } -- -- if (cred.uid != 0 || cred.gid != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "client socket connect failed, permition denied\n"); -- return -1; -- } -- -- return 0; --} -- - static int etmemd_rpc_accept(int sock_fd) - { - char *recv_buf = NULL; -@@ -597,11 +615,6 @@ static int etmemd_rpc_accept(int sock_fd) - return 0; - } - -- rc = check_socket_permission(accp_fd); -- if (rc != 0) { -- goto RPC_EXIT; -- } -- - rc = recv(accp_fd, recv_buf, RPC_BUFF_LEN_MAX, 0); - if (rc <= 0) { - etmemd_log(ETMEMD_LOG_WARN, "socket recive from client fail, error(%s)\n", --- -2.27.0 - diff --git a/0014-stat-pages-info-early-only-replace-cold-mem-in-hot-nodes.patch b/0014-stat-pages-info-early-only-replace-cold-mem-in-hot-nodes.patch deleted file mode 100644 index ab0ecc8..0000000 --- a/0014-stat-pages-info-early-only-replace-cold-mem-in-hot-nodes.patch +++ /dev/null @@ -1,300 +0,0 @@ -From 2a63484709098a551cbf6996c5362f25f6539ca5 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Thu, 29 Apr 2021 11:32:07 +0800 -Subject: [PATCH 14/50] stat pages info early only replace cold mem in hot node - in order to reduce pages to move - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_cslide.c | 134 ++++++++++++++++++++------------- - 1 file changed, 81 insertions(+), 53 deletions(-) - -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 43d8108..7c30508 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -36,6 +36,7 @@ - #define HUGE_1G_SIZE (1 << 30) - #define BYTE_TO_KB(s) ((s) >> 10) - #define KB_TO_BYTE(s) ((s) << 10) -+#define HUGE_2M_TO_KB(s) ((s) << 11) - - #define TO_PCT 100 - #define MAX_WM 100 -@@ -154,6 +155,7 @@ struct cslide_eng_params { - int sleep; - }; - struct cslide_params_factory factory; -+ struct node_pages_info *host_pages_info; - bool finish; - }; - -@@ -166,12 +168,13 @@ struct node_ctrl { - struct ctrl_cap hot_move_cap; - struct ctrl_cap hot_prefetch_cap; - struct ctrl_cap cold_move_cap; -- long long cold_replaced; -- long long cold_free; -- long long free; -- long long total; -- long long quota; -- long long reserve; -+ long long cold_replaced; // cold mem in hot node replace by hot mem in cold node -+ long long cold_free; // free mem in cold node -+ long long free; // free mem in hot node -+ long long cold; // cold mem in hot node -+ long long total; // total mem in hot node -+ long long quota; // move quota -+ long long reserve; // reserve space can't used by cold mem - }; - - struct flow_ctrl { -@@ -854,17 +857,21 @@ static bool node_cal_hot_can_move(struct node_ctrl *node_ctrl) - { - long long can_move; - -+ // can_move limited by quota - if (node_ctrl->quota < node_ctrl->free) { - can_move = node_ctrl->quota; - } else { -+ // can_move limited by hot node free - can_move = node_ctrl->free + (node_ctrl->quota - node_ctrl->free) / 2; -+ // can_move limited by cold node free - if (can_move > node_ctrl->free + node_ctrl->cold_free) { - can_move = node_ctrl->free + node_ctrl->cold_free; - } - } - -- if (can_move > node_ctrl->total) { -- can_move = node_ctrl->total; -+ // can_move limited by free and cold mem in hot node -+ if (can_move > node_ctrl->cold + node_ctrl->free) { -+ can_move = node_ctrl->cold + node_ctrl->free; - } - node_ctrl->hot_move_cap.cap = can_move; - return can_move > 0; -@@ -963,9 +970,13 @@ static inline bool node_move_cold(struct node_ctrl *node_ctrl, long long *target - return cap_cost(&node_ctrl->cold_move_cap, target); - } - --static int init_flow_ctrl(struct flow_ctrl *ctrl, struct sys_mem *sys_mem, struct node_map *node_map, -- long long quota, long long reserve) -+static int init_flow_ctrl(struct flow_ctrl *ctrl, struct cslide_eng_params *eng_params) - { -+ -+ long long quota = (long long)eng_params->mig_quota * HUGE_1M_SIZE; -+ long long reserve = (long long)eng_params->hot_reserve * HUGE_1M_SIZE; -+ struct sys_mem *sys_mem = &eng_params->mem; -+ struct node_map *node_map = &eng_params->node_map; - struct node_pair *pair = NULL; - struct node_ctrl *tmp = NULL; - int i; -@@ -985,6 +996,7 @@ static int init_flow_ctrl(struct flow_ctrl *ctrl, struct sys_mem *sys_mem, struc - tmp = &ctrl->node_ctrl[i]; - tmp->cold_free = sys_mem->node_mem[pair->cold_node].huge_free; - tmp->free = sys_mem->node_mem[pair->hot_node].huge_free; -+ tmp->cold = KB_TO_BYTE((unsigned long long)eng_params->host_pages_info[pair->hot_node].cold); - tmp->total = sys_mem->node_mem[pair->hot_node].huge_total; - tmp->quota = quota; - tmp->reserve = reserve; -@@ -1187,10 +1199,8 @@ static void move_cold_pages(struct cslide_eng_params *eng_params, struct flow_ct - static int cslide_filter_pfs(struct cslide_eng_params *eng_params) - { - struct flow_ctrl ctrl; -- long long quota = (long long)eng_params->mig_quota * HUGE_1M_SIZE; -- long long reserve = (long long)eng_params->hot_reserve * HUGE_1M_SIZE; - -- if (init_flow_ctrl(&ctrl, &eng_params->mem, &eng_params->node_map, quota, reserve) != 0) { -+ if (init_flow_ctrl(&ctrl, eng_params) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "init_flow_ctrl fail\n"); - return -1; - } -@@ -1203,22 +1213,6 @@ static int cslide_filter_pfs(struct cslide_eng_params *eng_params) - return 0; - } - --static int cslide_policy(struct cslide_eng_params *eng_params) --{ -- struct cslide_pid_params *pid_params = NULL; -- int ret; -- -- factory_foreach_working_pid_params(pid_params, &eng_params->factory) { -- ret = cslide_count_node_pfs(pid_params); -- if (ret != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "count node page refs fail\n"); -- return ret; -- } -- } -- -- return cslide_filter_pfs(eng_params); --} -- - static int cslide_get_vmas(struct cslide_pid_params *pid_params) - { - struct cslide_task_params *task_params = pid_params->task_params; -@@ -1510,26 +1504,41 @@ static bool need_migrate(struct cslide_eng_params *eng_params) - return false; - } - --static void get_node_pages_info(struct cslide_pid_params *pid_params) -+static void init_host_pages_info(struct cslide_eng_params *eng_params) -+{ -+ int n; -+ int node_num = eng_params->mem.node_num; -+ struct node_pages_info *host_pages = eng_params->host_pages_info; -+ -+ for (n = 0; n < node_num; n++) { -+ host_pages[n].cold = 0; -+ host_pages[n].hot = 0; -+ } -+} -+ -+static void update_pages_info(struct cslide_eng_params *eng_params, struct cslide_pid_params *pid_params) - { -- struct cslide_eng_params *eng_params = pid_params->eng_params; - int n, c; - int t = eng_params->hot_threshold; - int count = pid_params->count; - int actual_t = t > count ? count + 1 : t; - int node_num = pid_params->count_page_refs->node_num; -- struct node_pages_info *info = pid_params->node_pages_info; -+ struct node_pages_info *task_pages = pid_params->node_pages_info; -+ struct node_pages_info *host_pages = eng_params->host_pages_info; - - for (n = 0; n < node_num; n++) { -- info[n].cold = 0; -- info[n].hot = 0; -+ task_pages[n].cold = 0; -+ task_pages[n].hot = 0; - - for (c = 0; c < actual_t; c++) { -- info[n].cold += pid_params->count_page_refs[c].node_pfs[n].num * 2 * 1024; -+ task_pages[n].cold += HUGE_2M_TO_KB(pid_params->count_page_refs[c].node_pfs[n].num); - } - for (; c <= count; c++) { -- info[n].hot += pid_params->count_page_refs[c].node_pfs[n].num * 2 * 1024; -+ task_pages[n].hot += HUGE_2M_TO_KB(pid_params->count_page_refs[c].node_pfs[n].num); - } -+ -+ host_pages[n].cold += task_pages[n].cold; -+ host_pages[n].hot += task_pages[n].hot; - } - } - -@@ -1538,13 +1547,33 @@ static void cslide_stat(struct cslide_eng_params *eng_params) - struct cslide_pid_params *iter = NULL; - - pthread_mutex_lock(&eng_params->stat_mtx); -+ init_host_pages_info(eng_params); - factory_foreach_working_pid_params(iter, &eng_params->factory) { -- get_node_pages_info(iter); -+ update_pages_info(eng_params, iter); - } - eng_params->stat_time = time(NULL); - pthread_mutex_unlock(&eng_params->stat_mtx); - } - -+static int cslide_policy(struct cslide_eng_params *eng_params) -+{ -+ struct cslide_pid_params *pid_params = NULL; -+ int ret; -+ -+ factory_foreach_working_pid_params(pid_params, &eng_params->factory) { -+ ret = cslide_count_node_pfs(pid_params); -+ if (ret != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "count node page refs fail\n"); -+ return ret; -+ } -+ } -+ -+ // update pages info now, so cslide_filter_pfs can use this info -+ cslide_stat(eng_params); -+ -+ return cslide_filter_pfs(eng_params); -+} -+ - static void cslide_clean_params(struct cslide_eng_params *eng_params) - { - struct cslide_pid_params *iter = NULL; -@@ -1559,6 +1588,8 @@ static void cslide_clean_params(struct cslide_eng_params *eng_params) - - static void destroy_cslide_eng_params(struct cslide_eng_params *params) - { -+ free(params->host_pages_info); -+ params->host_pages_info = NULL; - destroy_factory(¶ms->factory); - pthread_mutex_destroy(¶ms->stat_mtx); - destroy_node_map(¶ms->node_map); -@@ -1567,6 +1598,8 @@ static void destroy_cslide_eng_params(struct cslide_eng_params *params) - - static int init_cslide_eng_params(struct cslide_eng_params *params) - { -+ int node_num; -+ - if (init_sys_mem(¶ms->mem) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "init system memory fail\n"); - return -1; -@@ -1587,8 +1620,18 @@ static int init_cslide_eng_params(struct cslide_eng_params *params) - goto destroy_stat_mtx; - } - -+ node_num = params->mem.node_num; -+ params->host_pages_info = calloc(node_num, sizeof(struct node_pages_info)); -+ if (params->host_pages_info == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc host_pages_info fail\n"); -+ goto destroy_factory; -+ } -+ - return 0; - -+destroy_factory: -+ destroy_factory(¶ms->factory); -+ - destroy_stat_mtx: - pthread_mutex_destroy(¶ms->stat_mtx); - -@@ -1642,7 +1685,6 @@ static void *cslide_main(void *arg) - } - - next: -- cslide_stat(eng_params); - sleep(eng_params->interval); - cslide_clean_params(eng_params); - } -@@ -1745,24 +1787,11 @@ static struct cslide_cmd_item g_task_cmd_items[] = { - static int show_host_pages(void *params, int fd) - { - struct cslide_eng_params *eng_params = (struct cslide_eng_params *)params; -- struct cslide_pid_params *iter = NULL; - char *time_str = NULL; - int node_num = eng_params->mem.node_num; - int n; - uint32_t total; -- struct node_pages_info *info = calloc(node_num, sizeof(struct node_pages_info)); -- -- if (info == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "alloc memory for node_page_info fail\n"); -- return -1; -- } -- -- factory_foreach_working_pid_params(iter, &eng_params->factory) { -- for (n = 0; n < node_num; n++) { -- info[n].hot += iter->node_pages_info[n].hot; -- info[n].cold += iter->node_pages_info[n].cold; -- } -- } -+ struct node_pages_info *info = eng_params->host_pages_info; - - time_str = get_time_stamp(&eng_params->stat_time); - if (time_str != NULL) { -@@ -1776,7 +1805,6 @@ static int show_host_pages(void *params, int fd) - n, total, info[n].hot + info[n].cold, info[n].hot, info[n].cold); - } - -- free(info); - return 0; - } - --- -2.27.0 - diff --git a/0015-limit-mig_quota-hot_reserve-to-0-INT_MAX.patch b/0015-limit-mig_quota-hot_reserve-to-0-INT_MAX.patch deleted file mode 100644 index 466c1b9..0000000 --- a/0015-limit-mig_quota-hot_reserve-to-0-INT_MAX.patch +++ /dev/null @@ -1,41 +0,0 @@ -From fd0ac585faf4f7893c728cb7898c265767f51082 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Thu, 29 Apr 2021 13:54:39 +0800 -Subject: [PATCH 15/50] limit mig_quota, hot_reserve to [0, INT_MAX] - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_cslide.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 7c30508..18a78d3 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -2048,6 +2048,11 @@ static int fill_hot_reserve(void *obj, void *val) - struct cslide_eng_params *params = (struct cslide_eng_params *)obj; - int hot_reserve = parse_to_int(val); - -+ if (hot_reserve < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "config hot reserve %d not valid\n", hot_reserve); -+ return -1; -+ } -+ - params->hot_reserve = hot_reserve; - return 0; - } -@@ -2057,6 +2062,11 @@ static int fill_mig_quota(void *obj, void *val) - struct cslide_eng_params *params = (struct cslide_eng_params *)obj; - int mig_quota = parse_to_int(val); - -+ if (mig_quota < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "config mig quota %d not valid\n", mig_quota); -+ return -1; -+ } -+ - params->mig_quota = mig_quota; - return 0; - } --- -2.27.0 - diff --git a/0016-add-some-dfx-info.patch b/0016-add-some-dfx-info.patch deleted file mode 100644 index f5d5a58..0000000 --- a/0016-add-some-dfx-info.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 3ffad08c0870cabea2656de19047b558c53d7fbd Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Thu, 29 Apr 2021 14:33:52 +0800 -Subject: [PATCH 16/50] add some dfx info - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_cslide.c | 43 +++++++++++++++++++++++----------- - 1 file changed, 29 insertions(+), 14 deletions(-) - -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 18a78d3..f311a44 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -1300,7 +1300,7 @@ static int cslide_scan_vmas(struct cslide_pid_params *params) - fd = fileno(scan_fp); - if (fd == -1) { - fclose(scan_fp); -- etmemd_log(ETMEMD_LOG_ERR, "fileno file fail for %s\n", IDLE_SCAN_FILE); -+ etmemd_log(ETMEMD_LOG_ERR, "task %u fileno file fail for %s\n", params->pid, IDLE_SCAN_FILE); - return -1; - } - for (i = 0; i < vmas->vma_cnt; i++) { -@@ -1309,7 +1309,7 @@ static int cslide_scan_vmas(struct cslide_pid_params *params) - walk_address.walk_start = vma->start; - walk_address.walk_end = vma->end; - if (walk_vmas(fd, &walk_address, &vma_pf->page_refs, NULL) == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "scan vma start %llu end %llu fail\n", vma->start, vma->end); -+ etmemd_log(ETMEMD_LOG_ERR, "task %u scan vma start %llu end %llu fail\n", params->pid, vma->start, vma->end); - fclose(scan_fp); - return -1; - } -@@ -1349,14 +1349,16 @@ static int cslide_do_scan(struct cslide_eng_params *eng_params) - return 0; - } - -+// error return -1; success return moved pages number - static int do_migrate_pages(unsigned int pid, struct page_refs *page_refs, int node) - { - int batch_size = BATCHSIZE; -- int ret = -1; -+ int ret; - void **pages = NULL; - int *nodes = NULL; - int *status = NULL; - int actual_num = 0; -+ int moved = -1; - - if (page_refs == NULL) { - return 0; -@@ -1379,6 +1381,8 @@ static int do_migrate_pages(unsigned int pid, struct page_refs *page_refs, int n - etmemd_log(ETMEMD_LOG_ERR, "malloc pages fail\n"); - goto free_status; - } -+ -+ moved = 0; - while (page_refs != NULL) { - pages[actual_num] = (void *)page_refs->addr; - nodes[actual_num] = node; -@@ -1386,11 +1390,13 @@ static int do_migrate_pages(unsigned int pid, struct page_refs *page_refs, int n - page_refs = page_refs->next; - if (actual_num == batch_size || page_refs == NULL) { - ret = move_pages(pid, actual_num, pages, nodes, status, MPOL_MF_MOVE_ALL); -- actual_num = 0; - if (ret != 0) { - etmemd_log(ETMEMD_LOG_ERR, "task %d move_pages fail with %d errno %d\n", pid, ret, errno); -+ moved = -1; - break; - } -+ moved += actual_num; -+ actual_num = 0; - } - } - -@@ -1402,25 +1408,34 @@ free_status: - free_nodes: - free(nodes); - nodes = NULL; -- return ret; -+ return moved; - } - - static int migrate_single_task(unsigned int pid, const struct memory_grade *memory_grade, int hot_node, int cold_node) - { -- int ret = -1; -+ int moved; - -- if (do_migrate_pages(pid, memory_grade->cold_pages, cold_node) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "migrate cold pages fail\n"); -- return ret; -+ moved = do_migrate_pages(pid, memory_grade->cold_pages, cold_node); -+ if (moved == -1) { -+ etmemd_log(ETMEMD_LOG_ERR, "task %u migrate cold pages fail\n", pid); -+ return -1; -+ } -+ if (moved != 0) { -+ etmemd_log(ETMEMD_LOG_INFO, "task %u move pages %lld KB from node %d to node %d\n", -+ pid, HUGE_2M_TO_KB((unsigned int)moved), hot_node, cold_node); - } - -- if (do_migrate_pages(pid, memory_grade->hot_pages, hot_node) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "migrate hot pages fail\n"); -- return ret; -+ moved = do_migrate_pages(pid, memory_grade->hot_pages, hot_node); -+ if (moved == -1) { -+ etmemd_log(ETMEMD_LOG_ERR, "task %u migrate hot pages fail\n", pid); -+ return -1; -+ } -+ if (moved != 0) { -+ etmemd_log(ETMEMD_LOG_INFO, "task %u move pages %lld KB from node %d to %d\n", -+ pid, HUGE_2M_TO_KB((unsigned int)moved), cold_node, hot_node); - } - -- ret = 0; -- return ret; -+ return 0; - } - - static int cslide_do_migrate(struct cslide_eng_params *eng_params) --- -2.27.0 - diff --git a/0017-do-not-stop-the-process-when-failed-to-delete-any-obj.patch b/0017-do-not-stop-the-process-when-failed-to-delete-any-obj.patch deleted file mode 100644 index 121ec8e..0000000 --- a/0017-do-not-stop-the-process-when-failed-to-delete-any-obj.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 598735e135a95bf646da66708bab80a673f1344f Mon Sep 17 00:00:00 2001 -From: louhongxiang -Date: Thu, 29 Apr 2021 15:28:22 +0800 -Subject: [PATCH 17/50] do not stop the process when failed to delete any obj, - continue to delte the next one in config file specified. - ---- - src/etmemd_src/etmemd_rpc.c | 17 +++++++++++++---- - 1 file changed, 13 insertions(+), 4 deletions(-) - -diff --git a/src/etmemd_src/etmemd_rpc.c b/src/etmemd_src/etmemd_rpc.c -index a8653e2..8360f5a 100644 ---- a/src/etmemd_src/etmemd_rpc.c -+++ b/src/etmemd_src/etmemd_rpc.c -@@ -94,11 +94,12 @@ struct obj_cmd_item { - enum opt_result (*func)(GKeyFile *config); - }; - --static enum opt_result do_obj_cmd(GKeyFile *config, struct obj_cmd_item *items, unsigned n) -+static enum opt_result do_obj_cmd(GKeyFile *config, struct obj_cmd_item *items, unsigned n,bool add_opt) - { - unsigned i; - bool parsed = false; - enum opt_result ret; -+ enum opt_result err_ret = OPT_SUCCESS; - - for (i = 0; i < n; i++) { - if (g_key_file_has_group(config, items[i].name) == FALSE) { -@@ -108,7 +109,10 @@ static enum opt_result do_obj_cmd(GKeyFile *config, struct obj_cmd_item *items, - ret = items[i].func(config); - if (ret != 0) { - etmemd_log(ETMEMD_LOG_ERR, "parse group %s fail\n", items[i].name); -- return ret; -+ if (add_opt) { -+ return ret; -+ } -+ err_ret = ret; - } - parsed = true; - } -@@ -118,6 +122,11 @@ static enum opt_result do_obj_cmd(GKeyFile *config, struct obj_cmd_item *items, - return OPT_INVAL; - } - -+ if (err_ret != OPT_SUCCESS) { -+ etmemd_log(ETMEMD_LOG_ERR, "error occurs in %s operation\n", add_opt ? "add" : "del"); -+ return err_ret; -+ } -+ - return OPT_SUCCESS; - } - -@@ -129,7 +138,7 @@ struct obj_cmd_item g_obj_add_items[] = { - - static enum opt_result do_obj_add(GKeyFile *config) - { -- return do_obj_cmd(config, g_obj_add_items, ARRAY_SIZE(g_obj_add_items)); -+ return do_obj_cmd(config, g_obj_add_items, ARRAY_SIZE(g_obj_add_items), true); - } - - static struct obj_cmd_item obj_remove_items[] = { -@@ -140,7 +149,7 @@ 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)); -+ return do_obj_cmd(config, obj_remove_items, ARRAY_SIZE(obj_remove_items), false); - } - - static enum opt_result handle_obj_cmd(char *file_name, enum cmd_type type) --- -2.27.0 - diff --git a/0018-fix-code-check-warnning.patch b/0018-fix-code-check-warnning.patch deleted file mode 100644 index 1f96fe1..0000000 --- a/0018-fix-code-check-warnning.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 6d9c2711f4fee6ec29ffcbf6bda5991e37cd12bb Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Thu, 29 Apr 2021 16:17:55 +0800 -Subject: [PATCH 18/50] fix code check warnning remove redundant space - -Signed-off-by: Kemeng Shi ---- - src/etmem_src/etmem_project.c | 2 +- - src/etmemd_src/etmemd_cslide.c | 3 ++- - 2 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/src/etmem_src/etmem_project.c b/src/etmem_src/etmem_project.c -index bb53df3..5892789 100644 ---- a/src/etmem_src/etmem_project.c -+++ b/src/etmem_src/etmem_project.c -@@ -107,7 +107,7 @@ static int project_check_params(const struct mem_proj *proj) - printf("socket name to connect must all be given, please check.\n"); - return -EINVAL; - } -- -+ - if (proj->cmd == ETMEM_CMD_SHOW) { - return 0; - } -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index f311a44..5914ca1 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -1309,7 +1309,8 @@ static int cslide_scan_vmas(struct cslide_pid_params *params) - walk_address.walk_start = vma->start; - walk_address.walk_end = vma->end; - if (walk_vmas(fd, &walk_address, &vma_pf->page_refs, NULL) == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "task %u scan vma start %llu end %llu fail\n", params->pid, vma->start, vma->end); -+ etmemd_log(ETMEMD_LOG_ERR, "task %u scan vma start %llu end %llu fail\n", -+ params->pid, vma->start, vma->end); - fclose(scan_fp); - return -1; - } --- -2.27.0 - diff --git a/0019-accept-review-advise.patch b/0019-accept-review-advise.patch deleted file mode 100644 index 903ccc0..0000000 --- a/0019-accept-review-advise.patch +++ /dev/null @@ -1,78 +0,0 @@ -From a8bea6d5ffcfe66020832eb57d233f4962aa3672 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Thu, 29 Apr 2021 18:58:52 +0800 -Subject: [PATCH 19/50] accept review advise - -Signed-off-by: Kemeng Shi ---- - src/etmem_src/etmem_engine.c | 7 ++++--- - src/etmemd_src/etmemd_cslide.c | 4 ++-- - src/etmemd_src/etmemd_rpc.c | 3 +++ - 3 files changed, 9 insertions(+), 5 deletions(-) - -diff --git a/src/etmem_src/etmem_engine.c b/src/etmem_src/etmem_engine.c -index e744aaa..bafcfe6 100644 ---- a/src/etmem_src/etmem_engine.c -+++ b/src/etmem_src/etmem_engine.c -@@ -24,8 +24,8 @@ - static void engine_help(void) - { - printf("\nUsage:\n" -- " memig engine eng_cmd [options]\n" -- " memig engine help\n" -+ " etmem engine eng_cmd [options]\n" -+ " etmem engine help\n" - "\nOptions:\n" - " -n|--proj_name project engine belongs to\n" - " -s|--socket socket name to connect\n" -@@ -35,7 +35,8 @@ static void engine_help(void) - " 1. project name must be given.\n" - " 2. socket name must be given.\n" - " 3. engine name must be given.\n" -- " 4. engine cmd must be given.\n"); -+ " 4. engine cmd must be given.\n" -+ " 5. eng_cmd is supported by engine own.\n"); - } - - static int engine_parse_cmd(struct etmem_conf *conf, struct mem_proj *proj) -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 5914ca1..9c65464 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -1422,7 +1422,7 @@ static int migrate_single_task(unsigned int pid, const struct memory_grade *memo - return -1; - } - if (moved != 0) { -- etmemd_log(ETMEMD_LOG_INFO, "task %u move pages %lld KB from node %d to node %d\n", -+ etmemd_log(ETMEMD_LOG_INFO, "task %u move pages %llu KB from node %d to node %d\n", - pid, HUGE_2M_TO_KB((unsigned int)moved), hot_node, cold_node); - } - -@@ -1432,7 +1432,7 @@ static int migrate_single_task(unsigned int pid, const struct memory_grade *memo - return -1; - } - if (moved != 0) { -- etmemd_log(ETMEMD_LOG_INFO, "task %u move pages %lld KB from node %d to %d\n", -+ etmemd_log(ETMEMD_LOG_INFO, "task %u move pages %llu KB from node %d to %d\n", - pid, HUGE_2M_TO_KB((unsigned int)moved), cold_node, hot_node); - } - -diff --git a/src/etmemd_src/etmemd_rpc.c b/src/etmemd_src/etmemd_rpc.c -index 09497b3..fe0b975 100644 ---- a/src/etmemd_src/etmemd_rpc.c -+++ b/src/etmemd_src/etmemd_rpc.c -@@ -212,8 +212,11 @@ static int check_cmd_permission(int sock_fd, int cmd) - { - switch (cmd) { - case OBJ_ADD: -+ /* fallthrough */ - case OBJ_DEL: -+ /* fallthrough */ - case MIG_STOP: -+ /* fallthrough */ - case MIG_START: - return check_socket_permission(sock_fd); - default: --- -2.27.0 - diff --git a/0020-revert-socket-permission-check.patch b/0020-revert-socket-permission-check.patch deleted file mode 100644 index fb1381d..0000000 --- a/0020-revert-socket-permission-check.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 40e9ddb6fafbcbeda9db7d848967d0b4f38b1514 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Thu, 6 May 2021 09:22:05 +0800 -Subject: [PATCH 20/50] revert socket permission check - -Signed-off-by: Kemeng Shi ---- - inc/etmemd_inc/etmemd_rpc.h | 2 - - src/etmemd_src/etmemd_rpc.c | 78 +++++++++++++++---------------------- - 2 files changed, 31 insertions(+), 49 deletions(-) - -diff --git a/inc/etmemd_inc/etmemd_rpc.h b/inc/etmemd_inc/etmemd_rpc.h -index 4f61390..146cec3 100644 ---- a/inc/etmemd_inc/etmemd_rpc.h -+++ b/inc/etmemd_inc/etmemd_rpc.h -@@ -55,7 +55,5 @@ int etmemd_parse_sock_name(const char *sock_name); - int etmemd_rpc_server(void); - bool etmemd_sock_name_set(void); - void etmemd_sock_name_free(void); --// some engine cmd need to check socket permission --int check_socket_permission(int sock_fd); - - #endif -diff --git a/src/etmemd_src/etmemd_rpc.c b/src/etmemd_src/etmemd_rpc.c -index fe0b975..d7bf8d7 100644 ---- a/src/etmemd_src/etmemd_rpc.c -+++ b/src/etmemd_src/etmemd_rpc.c -@@ -181,57 +181,10 @@ free_file: - return ret; - } - --int check_socket_permission(int sock_fd) { -- struct ucred cred; -- socklen_t len; -- ssize_t rc; -- -- len = sizeof(struct ucred); -- -- rc = getsockopt(sock_fd, -- SOL_SOCKET, -- SO_PEERCRED, -- &cred, -- &len); -- if (rc < 0) { -- etmemd_log(ETMEMD_LOG_ERR, "getsockopt failed, err(%s)\n", -- strerror(errno)); -- return -1; -- } -- -- if (cred.uid != 0 || cred.gid != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "client socket connect failed, permition denied\n"); -- return -1; -- } -- -- return 0; --} -- --// ENG_CMD cmd permission checked inside engine --static int check_cmd_permission(int sock_fd, int cmd) --{ -- switch (cmd) { -- case OBJ_ADD: -- /* fallthrough */ -- case OBJ_DEL: -- /* fallthrough */ -- case MIG_STOP: -- /* fallthrough */ -- case MIG_START: -- return check_socket_permission(sock_fd); -- default: -- return 0; -- } --} -- - static enum opt_result etmemd_switch_cmd(const struct server_rpc_params svr_param) - { - enum opt_result ret = OPT_INVAL; - -- if (check_cmd_permission(svr_param.sock_fd, svr_param.cmd) != 0) { -- return OPT_INVAL; -- } -- - switch (svr_param.cmd) { - case OBJ_ADD: - case OBJ_DEL: -@@ -596,6 +549,32 @@ static void etmemd_rpc_handle(int sock_fd) - return; - } - -+int check_socket_permission(int sock_fd) { -+ struct ucred cred; -+ socklen_t len; -+ ssize_t rc; -+ -+ len = sizeof(struct ucred); -+ -+ rc = getsockopt(sock_fd, -+ SOL_SOCKET, -+ SO_PEERCRED, -+ &cred, -+ &len); -+ if (rc < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "getsockopt failed, err(%s)\n", -+ strerror(errno)); -+ return -1; -+ } -+ -+ if (cred.uid != 0 || cred.gid != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "client socket connect failed, permition denied\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ - static int etmemd_rpc_accept(int sock_fd) - { - char *recv_buf = NULL; -@@ -618,6 +597,11 @@ static int etmemd_rpc_accept(int sock_fd) - return 0; - } - -+ rc = check_socket_permission(accp_fd); -+ if (rc != 0) { -+ goto RPC_EXIT; -+ } -+ - rc = recv(accp_fd, recv_buf, RPC_BUFF_LEN_MAX, 0); - if (rc <= 0) { - etmemd_log(ETMEMD_LOG_WARN, "socket recive from client fail, error(%s)\n", --- -2.27.0 - diff --git a/0021-add-thirdpart-engine.patch b/0021-add-thirdpart-engine.patch deleted file mode 100644 index c3260c0..0000000 --- a/0021-add-thirdpart-engine.patch +++ /dev/null @@ -1,549 +0,0 @@ -From c009890697542083329ee384ac0e72f3c976f331 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Thu, 6 May 2021 10:32:50 +0800 -Subject: [PATCH 21/50] add thirdpart engine - -Signed-off-by: Kemeng Shi ---- - CMakeLists.txt | 1 + - inc/etmemd_inc/etmemd_cslide.h | 2 +- - inc/etmemd_inc/etmemd_engine.h | 1 + - inc/etmemd_inc/etmemd_slide.h | 2 +- - inc/etmemd_inc/etmemd_thirdparty.h | 24 ++++ - src/etmemd_src/etmemd_cslide.c | 2 +- - src/etmemd_src/etmemd_engine.c | 51 +++++++-- - src/etmemd_src/etmemd_project.c | 75 ++++++------ - src/etmemd_src/etmemd_rpc.c | 2 +- - src/etmemd_src/etmemd_slide.c | 2 +- - src/etmemd_src/etmemd_thirdparty.c | 178 +++++++++++++++++++++++++++++ - 11 files changed, 291 insertions(+), 49 deletions(-) - create mode 100644 inc/etmemd_inc/etmemd_thirdparty.h - create mode 100644 src/etmemd_src/etmemd_thirdparty.c - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index fa64b89..9ce4724 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -33,6 +33,7 @@ set(ETMEMD_SRC - ${ETMEMD_SRC_DIR}/etmemd_engine.c - ${ETMEMD_SRC_DIR}/etmemd_slide.c - ${ETMEMD_SRC_DIR}/etmemd_cslide.c -+ ${ETMEMD_SRC_DIR}/etmemd_thirdparty.c - ${ETMEMD_SRC_DIR}/etmemd_task.c - ${ETMEMD_SRC_DIR}/etmemd_scan.c - ${ETMEMD_SRC_DIR}/etmemd_threadpool.c -diff --git a/inc/etmemd_inc/etmemd_cslide.h b/inc/etmemd_inc/etmemd_cslide.h -index 2405f2d..9b03f6f 100644 ---- a/inc/etmemd_inc/etmemd_cslide.h -+++ b/inc/etmemd_inc/etmemd_cslide.h -@@ -18,6 +18,6 @@ - - #include "etmemd_engine.h" - --int fill_engine_type_cslide(struct engine *eng); -+int fill_engine_type_cslide(struct engine *eng, GKeyFile *config); - - #endif -diff --git a/inc/etmemd_inc/etmemd_engine.h b/inc/etmemd_inc/etmemd_engine.h -index 77916a5..36e1760 100644 ---- a/inc/etmemd_inc/etmemd_engine.h -+++ b/inc/etmemd_inc/etmemd_engine.h -@@ -42,6 +42,7 @@ struct engine { - struct task *tasks; - uint64_t page_cnt; /* number of pages */ - struct engine *next; -+ void *handler; - }; - - struct engine_ops { -diff --git a/inc/etmemd_inc/etmemd_slide.h b/inc/etmemd_inc/etmemd_slide.h -index e76e97a..af48be7 100644 ---- a/inc/etmemd_inc/etmemd_slide.h -+++ b/inc/etmemd_inc/etmemd_slide.h -@@ -24,6 +24,6 @@ struct slide_params { - int t; /* watermark */ - }; - --int fill_engine_type_slide(struct engine *eng); -+int fill_engine_type_slide(struct engine *eng, GKeyFile *config); - - #endif -diff --git a/inc/etmemd_inc/etmemd_thirdparty.h b/inc/etmemd_inc/etmemd_thirdparty.h -new file mode 100644 -index 0000000..1cd750c ---- /dev/null -+++ b/inc/etmemd_inc/etmemd_thirdparty.h -@@ -0,0 +1,24 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: shikemeng -+ * Create: 2021-4-30 -+ * Description: This is a header file of the function declaration for thirdparty function. -+ ******************************************************************************/ -+ -+#ifndef ETMEMD_THIRDPARTY_H -+#define ETMEMD_THIRDPARTY_H -+ -+#include "etmemd_engine.h" -+ -+int fill_engine_type_thirdparty(struct engine *eng, GKeyFile *config); -+void clear_engine_type_thirdparty(struct engine *eng); -+ -+#endif -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 9c65464..71b510f 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -2153,7 +2153,7 @@ struct engine_ops g_cslide_eng_ops = { - .eng_mgt_func = cslide_engine_do_cmd, - }; - --int fill_engine_type_cslide(struct engine *eng) -+int fill_engine_type_cslide(struct engine *eng, GKeyFile *config) - { - eng->ops = &g_cslide_eng_ops; - eng->engine_type = CSLIDE_ENGINE; -diff --git a/src/etmemd_src/etmemd_engine.c b/src/etmemd_src/etmemd_engine.c -index 98a7430..c745e15 100644 ---- a/src/etmemd_src/etmemd_engine.c -+++ b/src/etmemd_src/etmemd_engine.c -@@ -18,27 +18,51 @@ - #include "etmemd_engine.h" - #include "etmemd_slide.h" - #include "etmemd_cslide.h" -+#include "etmemd_thirdparty.h" - #include "etmemd_log.h" - #include "etmemd_common.h" - #include "etmemd_file.h" - --struct engine_item { -+struct engine_add_item { - char *name; -- int (*fill_eng_func)(struct engine *eng); -+ int (*fill_eng_func)(struct engine *eng, GKeyFile *config); - }; - --static struct engine_item g_engine_items[] = { -+struct engine_remove_item { -+ int type; -+ void (*clear_eng_func)(struct engine *eng); -+}; -+ -+static struct engine_add_item g_engine_add_items[] = { - {"slide", fill_engine_type_slide}, - {"cslide", fill_engine_type_cslide}, -+ {"thirdparty", fill_engine_type_thirdparty}, -+}; -+ -+static struct engine_add_item *find_engine_add_item(const char *name) -+{ -+ unsigned i; -+ -+ for (i = 0; i < ARRAY_SIZE(g_engine_add_items); i++) { -+ if (strcmp(name, g_engine_add_items[i].name) == 0) { -+ return &g_engine_add_items[i]; -+ } -+ } -+ -+ return NULL; -+} -+ -+static struct engine_remove_item g_engine_remove_items[] = { -+ {THIRDPARTY_ENGINE, clear_engine_type_thirdparty}, - }; - --static struct engine_item *find_engine_item(const char *name) -+static struct engine_remove_item *find_engine_remove_item(int type) - { - unsigned i; - -- for (i = 0; i < ARRAY_SIZE(g_engine_items); i++) { -- if (strcmp(name, g_engine_items[i].name) == 0) { -- return &g_engine_items[i]; -+ for (i = 0; i < ARRAY_SIZE(g_engine_remove_items); i++) { -+ if (g_engine_remove_items[i].type == type) { -+ return &g_engine_remove_items[i]; - } - } - -@@ -48,7 +72,7 @@ static struct engine_item *find_engine_item(const char *name) - struct engine *etmemd_engine_add(GKeyFile *config) - { - struct engine *eng = NULL; -- struct engine_item *item = NULL; -+ struct engine_add_item *item = NULL; - char *name = NULL; - - if (g_key_file_has_key(config, ENG_GROUP, "name", NULL) == FALSE) { -@@ -62,7 +86,7 @@ struct engine *etmemd_engine_add(GKeyFile *config) - return NULL; - } - -- item = find_engine_item(name); -+ item = find_engine_add_item(name); - if (item == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "engine %s not support\n", name); - goto free_name; -@@ -74,7 +98,7 @@ struct engine *etmemd_engine_add(GKeyFile *config) - goto free_name; - } - -- if (item->fill_eng_func(eng) != 0) { -+ if (item->fill_eng_func(eng, config) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "fill engine %s fail\n", name); - free(eng); - eng = NULL; -@@ -94,5 +118,12 @@ free_name: - - void etmemd_engine_remove(struct engine *eng) - { -+ struct engine_remove_item *item = NULL; -+ -+ item = find_engine_remove_item(eng->engine_type); -+ if (item != NULL) { -+ item->clear_eng_func(eng); -+ } -+ - free(eng); - } -diff --git a/src/etmemd_src/etmemd_project.c b/src/etmemd_src/etmemd_project.c -index b3158d8..885c86e 100644 ---- a/src/etmemd_src/etmemd_project.c -+++ b/src/etmemd_src/etmemd_project.c -@@ -76,7 +76,7 @@ static struct task *get_task_by_name(struct project *proj, struct engine *eng, c - return NULL; - } - --static char *get_obj_key(char *obj_name, const char *group_name) -+static const char *get_obj_key(const char *obj_name, const char *group_name) - { - if (strcmp(obj_name, group_name) == 0) { - return "name"; -@@ -85,46 +85,61 @@ static char *get_obj_key(char *obj_name, const char *group_name) - } - } - --static enum opt_result project_of_group(GKeyFile *config, const char *group_name, struct project **proj) -+static enum opt_result get_name_by_key(GKeyFile *config, const char *group_name, const char *key, char **name) - { -- *proj = NULL; -- char *proj_name = NULL; -- char *key = NULL; -- -- key = get_obj_key(PROJ_GROUP, group_name); - if (g_key_file_has_key(config, group_name, key, NULL) == FALSE) { -- etmemd_log(ETMEMD_LOG_ERR, "project name is not set for %s\n", group_name); -+ etmemd_log(ETMEMD_LOG_ERR, "key %s is not set in group %s\n", key, group_name); - return OPT_INVAL; - } - -- proj_name = g_key_file_get_string(config, group_name, key, NULL); -- if (proj_name == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "get project name from %s fail\n", group_name); -+ *name = g_key_file_get_string(config, group_name, key, NULL); -+ if (*name == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "get value of key %s from group %s fail\n", key, group_name); - return OPT_INTER_ERR; - } - -- *proj = get_proj_by_name(proj_name); -+ return OPT_SUCCESS; -+} -+ -+static enum opt_result get_obj_name(GKeyFile *config, const char *group_name, const char *obj, char **name) -+{ -+ const char *key = get_obj_key(obj, group_name); -+ -+ return get_name_by_key(config, group_name, key, name); -+} - -+static enum opt_result project_of_group(GKeyFile *config, const char *group_name, struct project **proj) -+{ -+ char *proj_name = NULL; -+ enum opt_result ret; -+ -+ ret = get_obj_name(config, group_name, PROJ_GROUP, &proj_name); -+ if (ret != OPT_SUCCESS) { -+ return ret; -+ } -+ -+ *proj = get_proj_by_name(proj_name); - free(proj_name); - return OPT_SUCCESS; - } - - static enum opt_result engine_of_group(GKeyFile *config, char *group_name, struct project *proj, struct engine **eng) - { -- char *key = NULL; - char *eng_name = NULL; -- *eng = NULL; -+ enum opt_result ret; - -- key = get_obj_key(ENG_GROUP, group_name); -- if (g_key_file_has_key(config, group_name, key, NULL) == FALSE) { -- etmemd_log(ETMEMD_LOG_ERR, "engine is not set for %s\n", group_name); -- return OPT_INVAL; -+ ret = get_obj_name(config, group_name, ENG_GROUP, &eng_name); -+ if (ret != OPT_SUCCESS) { -+ return ret; - } - -- eng_name = g_key_file_get_string(config, group_name, key, NULL); -- if (eng_name == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "get engine name from %s fail\n", group_name); -- return OPT_INTER_ERR; -+ // real engine name is set with "eng_name" for thirdparty engine -+ if (strcmp(eng_name, "thirdparty") == 0 && strcmp(group_name, ENG_GROUP) == 0) { -+ free(eng_name); -+ ret = get_name_by_key(config, ENG_GROUP, "eng_name", &eng_name); -+ if (ret != OPT_SUCCESS) { -+ return ret; -+ } - } - - *eng = get_eng_by_name(proj, eng_name); -@@ -136,19 +151,11 @@ static enum opt_result task_of_group(GKeyFile *config, char *group_name, - struct project *proj, struct engine *eng, struct task **tk) - { - char *task_name = NULL; -- char *key = NULL; -- *tk = NULL; -- -- key = get_obj_key(TASK_GROUP, group_name); -- if (g_key_file_has_key(config, group_name, key, NULL) == FALSE) { -- etmemd_log(ETMEMD_LOG_ERR, "task name is not set for %s\n", group_name); -- return OPT_INVAL; -- } -+ enum opt_result ret; - -- task_name = g_key_file_get_string(config, group_name, key, NULL); -- if (task_name == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "get task name from %s fail\n", group_name); -- return OPT_INTER_ERR; -+ ret = get_obj_name(config, group_name, TASK_GROUP, &task_name); -+ if (ret != OPT_SUCCESS) { -+ return ret; - } - - *tk = get_task_by_name(proj, eng, task_name); -diff --git a/src/etmemd_src/etmemd_rpc.c b/src/etmemd_src/etmemd_rpc.c -index d7bf8d7..49c292d 100644 ---- a/src/etmemd_src/etmemd_rpc.c -+++ b/src/etmemd_src/etmemd_rpc.c -@@ -549,7 +549,7 @@ static void etmemd_rpc_handle(int sock_fd) - return; - } - --int check_socket_permission(int sock_fd) { -+static int check_socket_permission(int sock_fd) { - struct ucred cred; - socklen_t len; - ssize_t rc; -diff --git a/src/etmemd_src/etmemd_slide.c b/src/etmemd_src/etmemd_slide.c -index f7609f4..64d0533 100644 ---- a/src/etmemd_src/etmemd_slide.c -+++ b/src/etmemd_src/etmemd_slide.c -@@ -211,7 +211,7 @@ struct engine_ops g_slide_eng_ops = { - .eng_mgt_func = NULL, - }; - --int fill_engine_type_slide(struct engine *eng) -+int fill_engine_type_slide(struct engine *eng, GKeyFile *config) - { - eng->ops = &g_slide_eng_ops; - eng->engine_type = SLIDE_ENGINE; -diff --git a/src/etmemd_src/etmemd_thirdparty.c b/src/etmemd_src/etmemd_thirdparty.c -new file mode 100644 -index 0000000..1a05512 ---- /dev/null -+++ b/src/etmemd_src/etmemd_thirdparty.c -@@ -0,0 +1,178 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: shikemeng -+ * Create: 2021-04-30 -+ * Description: Memigd thirdparty API. -+ ******************************************************************************/ -+ -+#include -+#include -+ -+#include "etmemd_engine.h" -+#include "etmemd_file.h" -+#include "etmemd_log.h" -+#include "etmemd_common.h" -+#include "etmemd_thirdparty.h" -+#include "securec.h" -+ -+struct thirdparty_params { -+ char *eng_name; -+ char *libname; -+ char *ops_name; -+}; -+ -+static int fill_eng_name(void *obj, void *val) -+{ -+ char *eng_name = (char *)val; -+ struct thirdparty_params *params = (struct thirdparty_params *)obj; -+ -+ params->eng_name = eng_name; -+ return 0; -+} -+ -+static int fill_libname(void *obj, void *val) -+{ -+ char *libname = (char *)val; -+ struct thirdparty_params *params = (struct thirdparty_params *)obj; -+ -+ params->libname = libname; -+ return 0; -+} -+ -+static int fill_ops_name(void *obj, void *val) -+{ -+ char *ops_name = (char *)val; -+ struct thirdparty_params *params = (struct thirdparty_params *)obj; -+ -+ params->ops_name = ops_name; -+ return 0; -+} -+ -+static struct config_item g_thirdparty_configs[] = { -+ {"eng_name", STR_VAL, fill_eng_name, false}, -+ {"libname", STR_VAL, fill_libname, false}, -+ {"ops_name", STR_VAL, fill_ops_name, false}, -+}; -+ -+static void clear_thirdparty_params(struct thirdparty_params *params) -+{ -+ if (params->eng_name != NULL) { -+ free(params->eng_name); -+ params->eng_name = NULL; -+ } -+ if (params->libname != NULL) { -+ free(params->libname); -+ params->libname = NULL; -+ } -+ if (params->ops_name != NULL) { -+ free(params->ops_name); -+ params->ops_name = NULL; -+ } -+} -+ -+static int set_engine_ops(struct engine *eng, struct thirdparty_params *params) -+{ -+ void *handler = NULL; -+ struct engine_ops *ops = NULL; -+ char *err = NULL; -+ -+ handler = dlopen(params->libname, RTLD_NOW | RTLD_LOCAL); -+ if (handler == NULL) { -+ err = dlerror(); -+ etmemd_log(ETMEMD_LOG_ERR, "load library %s fail with error: %s\n", params->libname, err); -+ return -1; -+ } -+ -+ /* Clear error */ -+ dlerror(); -+ ops = dlsym(handler, params->ops_name); -+ err = dlerror(); -+ if (err != NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "load engine_ops symbol %s fail with error: %s\n", params->ops_name, err); -+ dlclose(handler); -+ return -1; -+ } -+ -+ eng->ops = ops; -+ eng->handler = handler; -+ return 0; -+} -+ -+static void clear_engine_ops(struct engine *eng) -+{ -+ dlclose(eng->handler); -+ eng->handler = NULL; -+ eng->ops = NULL; -+} -+ -+static void set_engine_name(struct engine *eng, struct thirdparty_params *params) -+{ -+ eng->name = params->eng_name; -+ /* avoid that eng_name will be freed in clear_thirdparty_params */ -+ params->eng_name = NULL; -+} -+ -+static void clear_engine_name(struct engine *eng) -+{ -+ free(eng->name); -+ eng->name = NULL; -+} -+ -+static int set_engine(struct engine *eng, struct thirdparty_params *params) -+{ -+ if (set_engine_ops(eng, params) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "set engine ops fail\n"); -+ return -1; -+ } -+ set_engine_name(eng, params); -+ eng->engine_type = THIRDPARTY_ENGINE; -+ -+ return 0; -+} -+ -+static void clear_engine(struct engine *eng) -+{ -+ clear_engine_name(eng); -+ clear_engine_ops(eng); -+} -+ -+int fill_engine_type_thirdparty(struct engine *eng, GKeyFile *config) -+{ -+ struct thirdparty_params params; -+ int ret = -1; -+ -+ if (memset_s(¶ms, sizeof(struct thirdparty_params), 0, sizeof(struct thirdparty_params)) != EOK) { -+ etmemd_log(ETMEMD_LOG_ERR, "memset_s for thirdparty_params fail\n"); -+ return -1; -+ } -+ -+ if (parse_file_config(config, ENG_GROUP, g_thirdparty_configs, -+ ARRAY_SIZE(g_thirdparty_configs), ¶ms) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "parse thirdparty_params fail\n"); -+ goto clear_params; -+ } -+ -+ if (set_engine(eng, ¶ms) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "set engine fail\n"); -+ goto clear_params; -+ } -+ -+ ret = 0; -+ -+clear_params: -+ clear_thirdparty_params(¶ms); -+ return ret; -+} -+ -+void clear_engine_type_thirdparty(struct engine *eng) -+{ -+ clear_engine(eng); -+} --- -2.27.0 - diff --git a/0022-export-symbols-for-user-defined-thirdparty-engine.patch b/0022-export-symbols-for-user-defined-thirdparty-engine.patch deleted file mode 100644 index a9e8122..0000000 --- a/0022-export-symbols-for-user-defined-thirdparty-engine.patch +++ /dev/null @@ -1,321 +0,0 @@ -From 2191a3f804026b73a82d146dfe834be0e515fc0e Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Thu, 6 May 2021 14:20:29 +0800 -Subject: [PATCH 22/50] export symbols for user defined thirdparty engine - -Signed-off-by: Kemeng Shi ---- - inc/etmemd_inc/etmem_thirdparty.h | 23 +++++++++++++ - inc/etmemd_inc/etmemd_engine.h | 30 +---------------- - inc/etmemd_inc/etmemd_engine_exp.h | 52 +++++++++++++++++++++++++++++ - inc/etmemd_inc/etmemd_project.h | 13 +------- - inc/etmemd_inc/etmemd_project_exp.h | 33 ++++++++++++++++++ - inc/etmemd_inc/etmemd_task.h | 19 +---------- - inc/etmemd_inc/etmemd_task_exp.h | 43 ++++++++++++++++++++++++ - 7 files changed, 154 insertions(+), 59 deletions(-) - create mode 100644 inc/etmemd_inc/etmem_thirdparty.h - create mode 100644 inc/etmemd_inc/etmemd_engine_exp.h - create mode 100644 inc/etmemd_inc/etmemd_project_exp.h - create mode 100644 inc/etmemd_inc/etmemd_task_exp.h - -diff --git a/inc/etmemd_inc/etmem_thirdparty.h b/inc/etmemd_inc/etmem_thirdparty.h -new file mode 100644 -index 0000000..0e128ce ---- /dev/null -+++ b/inc/etmemd_inc/etmem_thirdparty.h -@@ -0,0 +1,23 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: shikemeng -+ * Create: 2021-4-30 -+ * Description: This is a header file of the function declaration for user defined thirdparty engine. -+ ******************************************************************************/ -+ -+#ifndef ETMEM_THIRDPARTY_H -+#define ETMEM_THIRDPARTY_H -+ -+#include "etmemd_project_exp.h" -+#include "etmemd_engine_exp.h" -+#include "etmemd_task_exp.h" -+ -+#endif -diff --git a/inc/etmemd_inc/etmemd_engine.h b/inc/etmemd_inc/etmemd_engine.h -index 36e1760..b513ae8 100644 ---- a/inc/etmemd_inc/etmemd_engine.h -+++ b/inc/etmemd_inc/etmemd_engine.h -@@ -16,9 +16,9 @@ - #ifndef ETMEMD_ENGINE_H - #define ETMEMD_ENGINE_H - --#include - #include "etmemd.h" - #include "etmemd_task.h" -+#include "etmemd_engine_exp.h" - - enum eng_type { - SLIDE_ENGINE = 0, -@@ -29,34 +29,6 @@ enum eng_type { - ENGINE_TYPE_CNT, - }; - --/* -- * engine struct -- * */ --struct engine { -- int engine_type; /* engine type used for elimination strategy */ -- char *name; -- void *params; /* point to engine parameter struct */ -- struct project *proj; -- struct page_refs *page_ref; /* scan result */ -- struct engine_ops *ops; -- struct task *tasks; -- uint64_t page_cnt; /* number of pages */ -- struct engine *next; -- void *handler; --}; -- --struct engine_ops { -- int (*fill_eng_params)(GKeyFile *config, struct engine *eng); -- void (*clear_eng_params)(struct engine *eng); -- int (*fill_task_params)(GKeyFile *config, struct task *task); -- void (*clear_task_params)(struct task *tk); -- int (*start_task)(struct engine *eng, struct task *tk); -- void (*stop_task)(struct engine *eng, struct task *tk); -- int (*alloc_pid_params)(struct engine *eng, struct task_pid **tk_pid); -- void (*free_pid_params)(struct engine *eng, struct task_pid **tk_pid); -- int (*eng_mgt_func)(struct engine *eng, struct task *tk, char *cmd, int fd); --}; -- - struct engine *etmemd_engine_add(GKeyFile *config); - void etmemd_engine_remove(struct engine *eng); - -diff --git a/inc/etmemd_inc/etmemd_engine_exp.h b/inc/etmemd_inc/etmemd_engine_exp.h -new file mode 100644 -index 0000000..2c119ec ---- /dev/null -+++ b/inc/etmemd_inc/etmemd_engine_exp.h -@@ -0,0 +1,52 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: shikemeng -+ * Create: 2021-04-30 -+ * Description: This is a header file of the export engine symbols. -+ ******************************************************************************/ -+ -+#ifndef ETMEMD_ENGINE_EXP_H -+#define ETMEMD_ENGINE_EXP_H -+ -+#include -+#include -+ -+struct task_pid; -+ -+/* -+ * engine struct -+ * */ -+struct engine { -+ int engine_type; /* engine type used for elimination strategy */ -+ char *name; -+ void *params; /* point to engine parameter struct */ -+ struct project *proj; -+ struct page_refs *page_ref; /* scan result */ -+ struct engine_ops *ops; -+ struct task *tasks; -+ uint64_t page_cnt; /* number of pages */ -+ struct engine *next; -+ void *handler; -+}; -+ -+struct engine_ops { -+ int (*fill_eng_params)(GKeyFile *config, struct engine *eng); -+ void (*clear_eng_params)(struct engine *eng); -+ int (*fill_task_params)(GKeyFile *config, struct task *task); -+ void (*clear_task_params)(struct task *tk); -+ int (*start_task)(struct engine *eng, struct task *tk); -+ void (*stop_task)(struct engine *eng, struct task *tk); -+ int (*alloc_pid_params)(struct engine *eng, struct task_pid **tk_pid); -+ void (*free_pid_params)(struct engine *eng, struct task_pid **tk_pid); -+ int (*eng_mgt_func)(struct engine *eng, struct task *tk, char *cmd, int fd); -+}; -+ -+#endif -diff --git a/inc/etmemd_inc/etmemd_project.h b/inc/etmemd_inc/etmemd_project.h -index e574a84..b44d68b 100644 ---- a/inc/etmemd_inc/etmemd_project.h -+++ b/inc/etmemd_inc/etmemd_project.h -@@ -16,26 +16,15 @@ - #ifndef ETMEMD_PROJECT_H - #define ETMEMD_PROJECT_H - --#include - #include "etmemd_task.h" - #include "etmemd_engine.h" -+#include "etmemd_project_exp.h" - - /* set the length of project name to 32 */ - #define PROJECT_NAME_MAX_LEN 32 - #define FILE_NAME_MAX_LEN 256 - #define PROJECT_SHOW_COLM_MAX 128 - --struct project { -- char *name; -- int interval; -- int loop; -- int sleep; -- bool start; -- struct engine *engs; -- -- SLIST_ENTRY(project) entry; --}; -- - enum opt_result { - OPT_SUCCESS = 0, - OPT_INVAL, -diff --git a/inc/etmemd_inc/etmemd_project_exp.h b/inc/etmemd_inc/etmemd_project_exp.h -new file mode 100644 -index 0000000..bcd5108 ---- /dev/null -+++ b/inc/etmemd_inc/etmemd_project_exp.h -@@ -0,0 +1,33 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: shikemeng -+ * Create: 2021-4-30 -+ * Description: This is a header file of the export project symbols. -+ ******************************************************************************/ -+ -+#ifndef ETMEMD_PROJECT_EXP_H -+#define ETMEMD_PROJECT_EXP_H -+ -+#include -+#include -+ -+struct project { -+ char *name; -+ int interval; -+ int loop; -+ int sleep; -+ bool start; -+ struct engine *engs; -+ -+ SLIST_ENTRY(project) entry; -+}; -+ -+#endif -diff --git a/inc/etmemd_inc/etmemd_task.h b/inc/etmemd_inc/etmemd_task.h -index 3f32be5..be3ade3 100644 ---- a/inc/etmemd_inc/etmemd_task.h -+++ b/inc/etmemd_inc/etmemd_task.h -@@ -17,12 +17,11 @@ - #ifndef ETMEMD_TASK_H - #define ETMEMD_TASK_H - --#include - #include --#include - #include - #include "etmemd_threadpool.h" - #include "etmemd_threadtimer.h" -+#include "etmemd_task_exp.h" - - /* in some system the max length of pid may be larger than 5, so we use 10 here */ - #define PID_STR_MAX_LEN 10 -@@ -35,22 +34,6 @@ struct task_pid { - struct task_pid *next; - }; - --struct task { -- char *type; -- char *value; -- char *name; -- uint64_t max_threads; -- -- struct task_pid *pids; -- struct engine *eng; -- void *params; -- pthread_t task_pt; -- timer_thread *timer_inst; -- thread_pool *threadpool_inst; -- -- struct task *next; --}; -- - int etmemd_get_task_pids(struct task *tk, bool recursive); - - void etmemd_free_task_pids(struct task *tk); -diff --git a/inc/etmemd_inc/etmemd_task_exp.h b/inc/etmemd_inc/etmemd_task_exp.h -new file mode 100644 -index 0000000..b62f382 ---- /dev/null -+++ b/inc/etmemd_inc/etmemd_task_exp.h -@@ -0,0 +1,43 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: shikemeng -+ * Create: 2021-4-30 -+ * Description: This is a header file of the export task symbols. -+ ******************************************************************************/ -+ -+#ifndef ETMEMD_TASK_EXP_H -+#define ETMEMD_TASK_EXP_H -+ -+#include -+#include -+ -+struct timer_thread_t; -+typedef struct timer_thread_t timer_thread; -+struct thread_pool_t; -+typedef struct thread_pool_t thread_pool; -+ -+struct task { -+ char *type; -+ char *value; -+ char *name; -+ uint64_t max_threads; -+ -+ struct task_pid *pids; -+ struct engine *eng; -+ void *params; -+ pthread_t task_pt; -+ timer_thread *timer_inst; -+ thread_pool *threadpool_inst; -+ -+ struct task *next; -+}; -+ -+#endif --- -2.27.0 - diff --git a/0023-accept-review-advise.patch b/0023-accept-review-advise.patch deleted file mode 100644 index b5f49c0..0000000 --- a/0023-accept-review-advise.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 0cf348d3f3288237855b7e05b0500c886ee98be0 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Sat, 8 May 2021 11:46:55 +0800 -Subject: [PATCH 23/50] accept review advise - -Signed-off-by: Kemeng Shi ---- - inc/etmemd_inc/etmemd_engine.h | 1 + - .../{etmem_thirdparty.h => etmemd_thirdparty_export.h} | 4 ++-- - src/etmemd_src/etmemd_project.c | 9 ++++++++- - src/etmemd_src/etmemd_thirdparty.c | 6 ++---- - 4 files changed, 13 insertions(+), 7 deletions(-) - rename inc/etmemd_inc/{etmem_thirdparty.h => etmemd_thirdparty_export.h} (93%) - -diff --git a/inc/etmemd_inc/etmemd_engine.h b/inc/etmemd_inc/etmemd_engine.h -index b513ae8..0134d21 100644 ---- a/inc/etmemd_inc/etmemd_engine.h -+++ b/inc/etmemd_inc/etmemd_engine.h -@@ -16,6 +16,7 @@ - #ifndef ETMEMD_ENGINE_H - #define ETMEMD_ENGINE_H - -+#include - #include "etmemd.h" - #include "etmemd_task.h" - #include "etmemd_engine_exp.h" -diff --git a/inc/etmemd_inc/etmem_thirdparty.h b/inc/etmemd_inc/etmemd_thirdparty_export.h -similarity index 93% -rename from inc/etmemd_inc/etmem_thirdparty.h -rename to inc/etmemd_inc/etmemd_thirdparty_export.h -index 0e128ce..9d145ce 100644 ---- a/inc/etmemd_inc/etmem_thirdparty.h -+++ b/inc/etmemd_inc/etmemd_thirdparty_export.h -@@ -13,8 +13,8 @@ - * Description: This is a header file of the function declaration for user defined thirdparty engine. - ******************************************************************************/ - --#ifndef ETMEM_THIRDPARTY_H --#define ETMEM_THIRDPARTY_H -+#ifndef ETMEM_THIRDPARTY_EXPORT_H -+#define ETMEM_THIRDPARTY_EXPORT_H - - #include "etmemd_project_exp.h" - #include "etmemd_engine_exp.h" -diff --git a/src/etmemd_src/etmemd_project.c b/src/etmemd_src/etmemd_project.c -index 885c86e..deeaf5e 100644 ---- a/src/etmemd_src/etmemd_project.c -+++ b/src/etmemd_src/etmemd_project.c -@@ -33,6 +33,8 @@ - #define MAX_SLEEP_VALUE 1200 - #define MAX_LOOP_VALUE 120 - -+#define MAX_OBJ_NAME_LEN 64 -+ - static SLIST_HEAD(project_list, project) g_projects = SLIST_HEAD_INITIALIZER(g_projects); - - static struct project *get_proj_by_name(const char *name) -@@ -95,7 +97,12 @@ static enum opt_result get_name_by_key(GKeyFile *config, const char *group_name, - *name = g_key_file_get_string(config, group_name, key, NULL); - if (*name == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "get value of key %s from group %s fail\n", key, group_name); -- return OPT_INTER_ERR; -+ return OPT_INVAL; -+ } -+ if (strlen(*name) > MAX_OBJ_NAME_LEN) { -+ etmemd_log(ETMEMD_LOG_ERR, "name len should not be greater than %d\n", MAX_OBJ_NAME_LEN); -+ free(*name); -+ return OPT_INVAL; - } - - return OPT_SUCCESS; -diff --git a/src/etmemd_src/etmemd_thirdparty.c b/src/etmemd_src/etmemd_thirdparty.c -index 1a05512..0fd2a70 100644 ---- a/src/etmemd_src/etmemd_thirdparty.c -+++ b/src/etmemd_src/etmemd_thirdparty.c -@@ -85,14 +85,12 @@ static int set_engine_ops(struct engine *eng, struct thirdparty_params *params) - char *err = NULL; - - handler = dlopen(params->libname, RTLD_NOW | RTLD_LOCAL); -- if (handler == NULL) { -- err = dlerror(); -+ err = dlerror(); -+ if (err != NULL && handler == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "load library %s fail with error: %s\n", params->libname, err); - return -1; - } - -- /* Clear error */ -- dlerror(); - ops = dlsym(handler, params->ops_name); - err = dlerror(); - if (err != NULL) { --- -2.27.0 - diff --git a/0024-correct-etmemd-name.patch b/0024-correct-etmemd-name.patch deleted file mode 100644 index 84b975d..0000000 --- a/0024-correct-etmemd-name.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 3ea01a06171bba33358edbec6c8b5cb4101c8e8f Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Sat, 8 May 2021 11:48:12 +0800 -Subject: [PATCH 24/50] correct etmemd name - -Signed-off-by: Kemeng Shi ---- - src/etmem_src/etmem_project.c | 2 +- - src/etmemd_src/etmemd_cslide.c | 2 +- - src/etmemd_src/etmemd_engine.c | 2 +- - src/etmemd_src/etmemd_log.c | 2 +- - src/etmemd_src/etmemd_migrate.c | 2 +- - src/etmemd_src/etmemd_pool_adapter.c | 2 +- - src/etmemd_src/etmemd_project.c | 2 +- - src/etmemd_src/etmemd_scan.c | 2 +- - src/etmemd_src/etmemd_slide.c | 2 +- - src/etmemd_src/etmemd_task.c | 2 +- - src/etmemd_src/etmemd_thirdparty.c | 2 +- - src/etmemd_src/etmemd_threadpool.c | 2 +- - src/etmemd_src/etmemd_threadtimer.c | 2 +- - 13 files changed, 13 insertions(+), 13 deletions(-) - -diff --git a/src/etmem_src/etmem_project.c b/src/etmem_src/etmem_project.c -index 5892789..ef2d8fe 100644 ---- a/src/etmem_src/etmem_project.c -+++ b/src/etmem_src/etmem_project.c -@@ -10,7 +10,7 @@ - * See the Mulan PSL v2 for more details. - * Author: louhongxiang - * Create: 2019-12-10 -- * Description: Memig project command API. -+ * Description: Etmem project command API. - ******************************************************************************/ - - #include -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 71b510f..47a3608 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -10,7 +10,7 @@ - * See the Mulan PSL v2 for more details. - * Author: shikemeng - * Create: 2021-4-19 -- * Description: Memigd cslide API. -+ * Description: Etmemd cslide API. - ******************************************************************************/ - - #include -diff --git a/src/etmemd_src/etmemd_engine.c b/src/etmemd_src/etmemd_engine.c -index c745e15..f57d52b 100644 ---- a/src/etmemd_src/etmemd_engine.c -+++ b/src/etmemd_src/etmemd_engine.c -@@ -10,7 +10,7 @@ - * See the Mulan PSL v2 for more details. - * Author: louhongxiang - * Create: 2019-12-10 -- * Description: Memigd engine API. -+ * Description: Etmemd engine API. - ******************************************************************************/ - - #include -diff --git a/src/etmemd_src/etmemd_log.c b/src/etmemd_src/etmemd_log.c -index 86c8857..fc49db8 100644 ---- a/src/etmemd_src/etmemd_log.c -+++ b/src/etmemd_src/etmemd_log.c -@@ -10,7 +10,7 @@ - * See the Mulan PSL v2 for more details. - * Author: louhongxiang - * Create: 2019-12-10 -- * Description: Memigd log API. -+ * Description: Etmemd log API. - ******************************************************************************/ - - #include -diff --git a/src/etmemd_src/etmemd_migrate.c b/src/etmemd_src/etmemd_migrate.c -index a7aa9b8..2f29f31 100644 ---- a/src/etmemd_src/etmemd_migrate.c -+++ b/src/etmemd_src/etmemd_migrate.c -@@ -10,7 +10,7 @@ - * See the Mulan PSL v2 for more details. - * Author: louhongxiang - * Create: 2019-12-10 -- * Description: Memigd migration API. -+ * Description: Etmemd migration API. - ******************************************************************************/ - - #include -diff --git a/src/etmemd_src/etmemd_pool_adapter.c b/src/etmemd_src/etmemd_pool_adapter.c -index b879dbc..8c0068e 100644 ---- a/src/etmemd_src/etmemd_pool_adapter.c -+++ b/src/etmemd_src/etmemd_pool_adapter.c -@@ -10,7 +10,7 @@ - * See the Mulan PSL v2 for more details. - * Author: louhongxiang - * Create: 2019-12-10 -- * Description: Memigd pool adapter API. -+ * Description: Etmemd pool adapter API. - ******************************************************************************/ - - #include -diff --git a/src/etmemd_src/etmemd_project.c b/src/etmemd_src/etmemd_project.c -index deeaf5e..3b12296 100644 ---- a/src/etmemd_src/etmemd_project.c -+++ b/src/etmemd_src/etmemd_project.c -@@ -10,7 +10,7 @@ - * See the Mulan PSL v2 for more details. - * Author: louhongxiang - * Create: 2019-12-10 -- * Description: Memigd project API. -+ * Description: Etmemd project API. - ******************************************************************************/ - - #include -diff --git a/src/etmemd_src/etmemd_scan.c b/src/etmemd_src/etmemd_scan.c -index bb8dfa3..fb4dd33 100644 ---- a/src/etmemd_src/etmemd_scan.c -+++ b/src/etmemd_src/etmemd_scan.c -@@ -10,7 +10,7 @@ - * See the Mulan PSL v2 for more details. - * Author: louhongxiang - * Create: 2019-12-10 -- * Description: Memigd scan API. -+ * Description: Etmemd scan API. - ******************************************************************************/ - - #include -diff --git a/src/etmemd_src/etmemd_slide.c b/src/etmemd_src/etmemd_slide.c -index 64d0533..96d3dcc 100644 ---- a/src/etmemd_src/etmemd_slide.c -+++ b/src/etmemd_src/etmemd_slide.c -@@ -10,7 +10,7 @@ - * See the Mulan PSL v2 for more details. - * Author: louhongxiang - * Create: 2019-12-10 -- * Description: Memigd slide API. -+ * Description: Etmemd slide API. - ******************************************************************************/ - - #include -diff --git a/src/etmemd_src/etmemd_task.c b/src/etmemd_src/etmemd_task.c -index 61ba0df..b948c63 100644 ---- a/src/etmemd_src/etmemd_task.c -+++ b/src/etmemd_src/etmemd_task.c -@@ -10,7 +10,7 @@ - * See the Mulan PSL v2 for more details. - * Author: louhongxiang - * Create: 2019-12-10 -- * Description: Memigd task API. -+ * Description: Etmemd task API. - ******************************************************************************/ - - #include -diff --git a/src/etmemd_src/etmemd_thirdparty.c b/src/etmemd_src/etmemd_thirdparty.c -index 0fd2a70..53d4b8e 100644 ---- a/src/etmemd_src/etmemd_thirdparty.c -+++ b/src/etmemd_src/etmemd_thirdparty.c -@@ -10,7 +10,7 @@ - * See the Mulan PSL v2 for more details. - * Author: shikemeng - * Create: 2021-04-30 -- * Description: Memigd thirdparty API. -+ * Description: Etmemd thirdparty API. - ******************************************************************************/ - - #include -diff --git a/src/etmemd_src/etmemd_threadpool.c b/src/etmemd_src/etmemd_threadpool.c -index 953d5a4..dac42d1 100644 ---- a/src/etmemd_src/etmemd_threadpool.c -+++ b/src/etmemd_src/etmemd_threadpool.c -@@ -10,7 +10,7 @@ - * See the Mulan PSL v2 for more details. - * Author: louhongxiang - * Create: 2019-12-10 -- * Description: Memigd threadpool API. -+ * Description: Etmemd threadpool API. - ******************************************************************************/ - - #include -diff --git a/src/etmemd_src/etmemd_threadtimer.c b/src/etmemd_src/etmemd_threadtimer.c -index 660085b..d18b3e0 100644 ---- a/src/etmemd_src/etmemd_threadtimer.c -+++ b/src/etmemd_src/etmemd_threadtimer.c -@@ -10,7 +10,7 @@ - * See the Mulan PSL v2 for more details. - * Author: louhongxiang - * Create: 2019-12-10 -- * Description: Memigd threadtimer API. -+ * Description: Etmemd threadtimer API. - ******************************************************************************/ - - #include --- -2.27.0 - diff --git a/0025-add-support-for-systemctl-mode-to-start-etmem.patch b/0025-add-support-for-systemctl-mode-to-start-etmem.patch deleted file mode 100644 index 6813af6..0000000 --- a/0025-add-support-for-systemctl-mode-to-start-etmem.patch +++ /dev/null @@ -1,243 +0,0 @@ -From 7701548a6a1d131e642e74ef39a5a38093023b3f Mon Sep 17 00:00:00 2001 -From: louhongxiang -Date: Mon, 10 May 2021 20:31:23 +0800 -Subject: [PATCH 25/50] add support for systemctl mode to start etmem - ---- - inc/etmemd_inc/etmemd_common.h | 7 ++- - inc/etmemd_inc/etmemd_rpc.h | 1 + - inc/etmemd_inc/etmemd_task.h | 3 -- - src/etmemd_src/etmemd_common.c | 7 ++- - src/etmemd_src/etmemd_rpc.c | 80 ++++++++++++++++++++++++++++++++++ - src/etmemd_src/etmemd_task.c | 4 +- - 6 files changed, 95 insertions(+), 7 deletions(-) - -diff --git a/inc/etmemd_inc/etmemd_common.h b/inc/etmemd_inc/etmemd_common.h -index 1b62bbd..e228476 100644 ---- a/inc/etmemd_inc/etmemd_common.h -+++ b/inc/etmemd_inc/etmemd_common.h -@@ -23,10 +23,15 @@ - #define FILE_LINE_MAX_LEN 1024 - #define KEY_VALUE_MAX_LEN 64 - #define DECIMAL_RADIX 10 --#define ETMEMD_MAX_PARAMETER_NUM 5 -+#define ETMEMD_MAX_PARAMETER_NUM 6 - - #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) - -+/* in some system the max length of pid may be larger than 5, so we use 10 herr */ -+#define PID_STR_MAX_LEN 10 -+ -+#define PIPE_FD_LEN 2 -+ - /* - * function: parse cmdline passed to etmemd server. - * -diff --git a/inc/etmemd_inc/etmemd_rpc.h b/inc/etmemd_inc/etmemd_rpc.h -index 146cec3..aa0a49b 100644 ---- a/inc/etmemd_inc/etmemd_rpc.h -+++ b/inc/etmemd_inc/etmemd_rpc.h -@@ -55,5 +55,6 @@ int etmemd_parse_sock_name(const char *sock_name); - int etmemd_rpc_server(void); - bool etmemd_sock_name_set(void); - void etmemd_sock_name_free(void); -+int etmemd_deal_systemctl(void); - - #endif -diff --git a/inc/etmemd_inc/etmemd_task.h b/inc/etmemd_inc/etmemd_task.h -index be3ade3..29e8e8f 100644 ---- a/inc/etmemd_inc/etmemd_task.h -+++ b/inc/etmemd_inc/etmemd_task.h -@@ -23,9 +23,6 @@ - #include "etmemd_threadtimer.h" - #include "etmemd_task_exp.h" - --/* in some system the max length of pid may be larger than 5, so we use 10 here */ --#define PID_STR_MAX_LEN 10 -- - struct task_pid { - unsigned int pid; - float rt_swapin_rate; /* real time swapin rate */ -diff --git a/src/etmemd_src/etmemd_common.c b/src/etmemd_src/etmemd_common.c -index 4b9c4cb..155a64b 100644 ---- a/src/etmemd_src/etmemd_common.c -+++ b/src/etmemd_src/etmemd_common.c -@@ -37,6 +37,7 @@ static void usage(void) - "\noptions:\n" - " -l|--log-level Log level\n" - " -s|--socket Socket name to listen to\n" -+ " -m|--mode-systemctl mode used to start(systemctl)\n" - " -h|--help Show this message\n"); - } - -@@ -66,6 +67,9 @@ static int etmemd_parse_opts_valid(int opt, bool *is_help) - *is_help = true; - usage(); - break; -+ case 'm': -+ ret = etmemd_deal_systemctl(); -+ break; - case '?': - printf("error: parse parameters failed\n"); - /* fallthrough */ -@@ -99,12 +103,13 @@ static int etmemd_parse_check_result(int params_cnt, int argc, const bool *is_he - - int etmemd_parse_cmdline(int argc, char *argv[], bool *is_help) - { -- const char *op_str = "s:l:h"; -+ const char *op_str = "s:l:mh"; - int params_cnt = 0; - int opt, ret; - struct option long_options[] = { - {"socket", required_argument, NULL, 's'}, - {"log-level", required_argument, NULL, 'l'}, -+ {"mode-systemctl", no_argument, NULL, 'm'}, - {"help", no_argument, NULL, 'h'}, - {NULL, 0, NULL, 0}, - }; -diff --git a/src/etmemd_src/etmemd_rpc.c b/src/etmemd_src/etmemd_rpc.c -index 8360f5a..ba5971c 100644 ---- a/src/etmemd_src/etmemd_rpc.c -+++ b/src/etmemd_src/etmemd_rpc.c -@@ -19,6 +19,9 @@ - #include - #include - #include -+#include -+#include -+#include - #include "securec.h" - #include "etmemd_rpc.h" - #include "etmemd_project.h" -@@ -35,6 +38,8 @@ - static bool g_exit = true; - static char *g_sock_name = NULL; - static int g_sock_fd; -+static int g_fd[PIPE_FD_LEN]; -+static int g_use_systemctl = 0; - struct server_rpc_params g_rpc_params; - - struct rpc_resp_msg { -@@ -67,6 +72,12 @@ struct rpc_resp_msg g_resp_msg_arr[] = { - {OPT_RET_END, NULL}, - }; - -+int etmemd_deal_systemctl(void) -+{ -+ g_use_systemctl = 1; -+ return 0; -+} -+ - static void etmemd_set_flag(int s) - { - etmemd_log(ETMEMD_LOG_ERR, "caught signal %d\n", s); -@@ -637,8 +648,69 @@ RPC_EXIT: - return ret; - } - -+static int rpc_deal_parent(void) -+{ -+ int len, handle, pid; -+ char pid_s[PID_STR_MAX_LEN]; -+ int val = 0; -+ -+ /* in systemctl mode, parent process need to write child pid */ -+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, g_fd) < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "Error initing pipefd\n"); -+ return -1; -+ } -+ -+ pid = fork(); -+ if (pid != 0) { -+ if ((handle = open("/run/etmemd.pid", O_WRONLY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE)) == -1) { -+ etmemd_log(ETMEMD_LOG_ERR, "Error opening file\n"); -+ exit(1); -+ } -+ -+ if ((len = sprintf_s(pid_s, PID_STR_MAX_LEN, "%d", pid)) <= 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "sprintf for pid failed\n"); -+ exit(1); -+ } -+ -+ if ((write(handle, pid_s, len)) != len) { -+ etmemd_log(ETMEMD_LOG_ERR, "Error writing to the file\n"); -+ exit(1); -+ } -+ -+ close(g_fd[1]); -+ if (read(g_fd[0], &val, sizeof(val)) <= 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "Error reading to the file\n"); -+ exit(1); -+ } -+ -+ if (val == 1) { -+ exit(0); -+ } -+ } -+ return 0; -+} -+ -+static int rpc_deal_child(void) -+{ -+ int val = 1; -+ close(g_fd[0]); -+ if (write(g_fd[1], &val, sizeof(val)) <= 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "Error writing pipe fd\n"); -+ return -1; -+ } -+ close(g_fd[1]); -+ return 0; -+} -+ - int etmemd_rpc_server(void) - { -+ /* in systemctl mode, parent process need to write child pid */ -+ if (g_use_systemctl) { -+ if (rpc_deal_parent() != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "Error deal by parent process\n"); -+ return -1; -+ } -+ } - if (!etmemd_sock_name_set()) { - etmemd_log(ETMEMD_LOG_ERR, "socket name of rpc must be provided\n"); - return -1; -@@ -661,6 +733,14 @@ int etmemd_rpc_server(void) - return -1; - } - -+ /* in systemctl mode, child process need to notify parent to exit */ -+ if (g_use_systemctl) { -+ if (rpc_deal_child() != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "Error sending message to parent process\n"); -+ return -1; -+ } -+ } -+ - while (!g_exit) { - if (etmemd_rpc_accept(g_sock_fd) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "handle remote call failed once, error(%s)\n", -diff --git a/src/etmemd_src/etmemd_task.c b/src/etmemd_src/etmemd_task.c -index b948c63..01491f7 100644 ---- a/src/etmemd_src/etmemd_task.c -+++ b/src/etmemd_src/etmemd_task.c -@@ -205,7 +205,7 @@ static int get_pid_from_type_name(char *val, char *pid) - char *arg_pid[] = {"/usr/bin/pgrep", "-x", val, NULL}; - FILE *file = NULL; - int ret = -1; -- int pipefd[2]; /* used for pipefd[2] communication to obtain the task PID */ -+ int pipefd[PIPE_FD_LEN]; /* used for pipefd[PIPE_FD_LEN] communication to obtain the task PID */ - - if (pipe(pipefd) == -1) { - return -1; -@@ -269,7 +269,7 @@ static int fill_task_child_pid(struct task *tk, char *pid) - char *arg_pid[] = {"/usr/bin/pgrep", "-P", pid, NULL}; - FILE *file = NULL; - int ret; -- int pipefd[2]; /* used for pipefd[2] communication to obtain the task PID */ -+ int pipefd[PIPE_FD_LEN]; /* used for pipefd[PIPE_FD_LEN] communication to obtain the task PID */ - - if (pipe(pipefd) == -1) { - return -1; --- -2.27.0 - diff --git a/0026-add-scan-library.patch b/0026-add-scan-library.patch deleted file mode 100644 index 61f6ddb..0000000 --- a/0026-add-scan-library.patch +++ /dev/null @@ -1,524 +0,0 @@ -From dcf4760df185d5e75f522914e160d85d4f3543ce Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Tue, 11 May 2021 15:53:10 +0800 -Subject: [PATCH 26/50] add scan library - -Signed-off-by: Kemeng Shi ---- - CMakeLists.txt | 25 ++++++++++ - inc/etmemd_inc/etmemd.h | 23 +--------- - inc/etmemd_inc/etmemd_exp.h | 42 +++++++++++++++++ - inc/etmemd_inc/etmemd_scan.h | 43 ++--------------- - inc/etmemd_inc/etmemd_scan_exp.h | 71 +++++++++++++++++++++++++++++ - inc/etmemd_inc/etmemd_scan_export.h | 22 +++++++++ - src/etmemd_src/etmemd_common.c | 13 +++++- - src/etmemd_src/etmemd_scan.c | 67 +++++++++++++++++++++++++-- - src/etmemd_src/etmemd_scan.version | 4 ++ - 9 files changed, 244 insertions(+), 66 deletions(-) - create mode 100644 inc/etmemd_inc/etmemd_exp.h - create mode 100644 inc/etmemd_inc/etmemd_scan_exp.h - create mode 100644 inc/etmemd_inc/etmemd_scan_export.h - create mode 100644 src/etmemd_src/etmemd_scan.version - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 9ce4724..6d11da9 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -55,8 +55,13 @@ add_executable(etmemd - add_executable(etmem - ${ETMEM_SRC}) - -+add_library(etmemd_scan SHARED -+ ${ETMEMD_SRC}) -+ - set(EXECUTABLE_OUTPUT_PATH ${BUILD_DIR}/bin) - -+set(LIBRARY_OUTPUT_PATH ${BUILD_DIR}/lib) -+ - include(FindPkgConfig) - pkg_search_module(GLIB2 REQUIRED glib-2.0) - -@@ -67,6 +72,10 @@ target_include_directories(etmemd PRIVATE - target_include_directories(etmem PRIVATE - ${PROJECT_SOURCE_DIR}/inc/etmem_inc) - -+target_include_directories(etmemd_scan PRIVATE -+ ${PROJECT_SOURCE_DIR}/inc/etmemd_inc -+ ${GLIB2_INCLUDE_DIRS}) -+ - target_compile_options(etmemd PRIVATE -fsigned-char -fno-omit-frame-pointer -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wmissing-declarations -fno-strict-aliasing -Werror -Wformat -Wformat-security -D_GNU_SOURCE -fPIE -pie -fPIC -fstack-protector-strong -fno-common -DNDEBUG -O2 -D_FORTIFY_SOURCE=2 -Wall -Werror -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -pthread -Wno-pointer-sign -Wstrict-prototypes -Wold-style-definition -std=gnu99) - - -@@ -97,3 +106,19 @@ if( ${ARCHITECTURE} STREQUAL "aarch64" ) - else() - target_compile_options(etmem PRIVATE -march=core-avx-i -m64) - endif() -+ -+target_compile_options(etmemd_scan PRIVATE -fsigned-char -fno-omit-frame-pointer -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wmissing-declarations -fno-strict-aliasing -Werror -Wformat -Wformat-security -D_GNU_SOURCE -fPIE -pie -fPIC -fstack-protector-strong -fno-common -DNDEBUG -O2 -D_FORTIFY_SOURCE=2 -Wall -Werror -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -pthread -Wno-pointer-sign -Wstrict-prototypes -Wold-style-definition -std=gnu99 -fPIC -shared) -+ -+ -+if(CONFIG_DEBUG STREQUAL "y") -+ target_compile_options(etmemd_scan PRIVATE -g) -+endif() -+ -+set_target_properties(etmemd_scan PROPERTIES LINK_FLAGS "-s -fPIE -pie -fPIC -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -Wl,--version-script=${ETMEMD_SRC_DIR}/etmemd_scan.version") -+target_link_libraries(etmemd_scan PRIVATE pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -+ -+if( ${ARCHITECTURE} STREQUAL "aarch64" ) -+ target_compile_options(etmemd_scan PRIVATE -march=armv8-a) -+else() -+ target_compile_options(etmemd_scan PRIVATE -march=core-avx-i -m64) -+endif() -diff --git a/inc/etmemd_inc/etmemd.h b/inc/etmemd_inc/etmemd.h -index 797049e..357ea4a 100644 ---- a/inc/etmemd_inc/etmemd.h -+++ b/inc/etmemd_inc/etmemd.h -@@ -16,34 +16,13 @@ - #ifndef ETMEMD_H - #define ETMEMD_H - --#include - #include -+#include "etmemd_exp.h" - - #define PTE_SIZE_SHIFT 12 - #define PMD_SIZE_SHIFT 21 - #define PUD_SIZE_SHIFT 30 - --/* -- * page type specified by size -- * */ --enum page_type { -- PTE_TYPE = 0, -- PMD_TYPE, -- PUD_TYPE, -- PAGE_TYPE_INVAL, --}; -- --/* -- * page struct after scan and parse -- * */ --struct page_refs { -- uint64_t addr; /* page address */ -- int count; /* page count */ -- enum page_type type; /* page type including PTE/PMD/PUD */ -- -- struct page_refs *next; /* point to next page */ --}; -- - /* memory grade is the result that judged by policy function after pagerefs come into it, - * every policy fucntion has its own rule to make the choice which page is hot grade or - * the other grades */ -diff --git a/inc/etmemd_inc/etmemd_exp.h b/inc/etmemd_inc/etmemd_exp.h -new file mode 100644 -index 0000000..8c57d9f ---- /dev/null -+++ b/inc/etmemd_inc/etmemd_exp.h -@@ -0,0 +1,42 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: shikemeng -+ * Create: 2021-04-30 -+ * Description: This is a header file of the export data structure definition for page. -+ ******************************************************************************/ -+ -+#ifndef ETMEMD_EXP_H -+#define ETMEMD_EXP_H -+ -+#include -+ -+/* -+ * page type specified by size -+ * */ -+enum page_type { -+ PTE_TYPE = 0, -+ PMD_TYPE, -+ PUD_TYPE, -+ PAGE_TYPE_INVAL, -+}; -+ -+/* -+ * page struct after scan and parse -+ * */ -+struct page_refs { -+ uint64_t addr; /* page address */ -+ int count; /* page count */ -+ enum page_type type; /* page type including PTE/PMD/PUD */ -+ -+ struct page_refs *next; /* point to next page */ -+}; -+ -+#endif -diff --git a/inc/etmemd_inc/etmemd_scan.h b/inc/etmemd_inc/etmemd_scan.h -index ed72e1a..09ad51c 100644 ---- a/inc/etmemd_inc/etmemd_scan.h -+++ b/inc/etmemd_inc/etmemd_scan.h -@@ -19,9 +19,8 @@ - #include - #include "etmemd.h" - #include "etmemd_task.h" -+#include "etmemd_scan_exp.h" - --#define VMA_PATH_STR_LEN 256 --#define VMA_MAJOR_MINOR_LEN 8 - #define VMA_SEG_CNT_MAX 6 - #define VMA_PERMS_STR_LEN 5 - #define VMA_ADDR_STR_LEN 17 -@@ -35,15 +34,7 @@ - #define SMAPS_FILE "/smaps" - #define VMFLAG_HEAD "VmFlags" - --#define SCAN_AS_HUGE O_LARGEFILE -- --enum { -- VMA_STAT_READ = 0, -- VMA_STAT_WRITE, -- VMA_STAT_EXEC, -- VMA_STAT_MAY_SHARE, -- VMA_STAT_INIT, --}; -+#define ALL_SCAN_FLAGS (SCAN_AS_HUGE | SCAN_IGN_HOST) - - enum page_idle_type { - PTE_ACCESS = 0, /* 4k page */ -@@ -66,40 +57,12 @@ enum access_type_weight { - WRITE_TYPE_WEIGHT = 3, - }; - --/* -- * vma struct -- * */ --struct vma { -- uint64_t start; /* address start */ -- uint64_t end; /* address end */ -- bool stat[VMA_STAT_INIT]; /* vm area permissions */ -- uint64_t offset; /* vm area offset */ -- uint64_t inode; /* vm area inode */ -- char path[VMA_PATH_STR_LEN]; /* path name */ -- char major[VMA_MAJOR_MINOR_LEN]; /* device number major part */ -- char minor[VMA_MAJOR_MINOR_LEN]; /* device number minor part */ -- -- struct vma *next; /* point to next vma */ --}; -- - struct walk_address { - uint64_t walk_start; /* walk address start */ - uint64_t walk_end; /* walk address end */ - uint64_t last_walk_end; /* last walk address end */ - }; - --/* -- * vmas struct -- * */ --struct vmas { -- uint64_t vma_cnt; /* number of vm area */ -- -- struct vma *vma_list; /* vm area list */ --}; -- --/* etmemd_free_page_refs need to be called by the handler who called etmemd_do_scan() successfully */ --void etmemd_free_page_refs(struct page_refs *pf); -- - /* the caller need to judge value returned by etmemd_do_scan(), NULL means fail. */ - struct page_refs *etmemd_do_scan(const struct task_pid *tpid, const struct task *tk); - -@@ -107,7 +70,7 @@ struct page_refs *etmemd_do_scan(const struct task_pid *tpid, const struct task - void free_vmas(struct vmas *vmas); - - struct page_refs **walk_vmas(int fd, struct walk_address *walk_address, struct page_refs **pf, unsigned long *use_rss); --int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **page_refs, unsigned long *use_rss); -+int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **page_refs, unsigned long *use_rss, int flags); - - int split_vmflags(char ***vmflags_array, char *vmflags); - struct vmas *get_vmas_with_flags(const char *pid, char **vmflags_array, int vmflags_num, bool is_anon_only); -diff --git a/inc/etmemd_inc/etmemd_scan_exp.h b/inc/etmemd_inc/etmemd_scan_exp.h -new file mode 100644 -index 0000000..1fd4379 ---- /dev/null -+++ b/inc/etmemd_inc/etmemd_scan_exp.h -@@ -0,0 +1,71 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: shikemeng -+ * Create: 2021-04-30 -+ * Description: This is a header file of the function declaration for export scan function. -+ ******************************************************************************/ -+ -+#ifndef ETMEMD_SCAN_EXP_H -+#define ETMEMD_SCAN_EXP_H -+ -+#include -+#include -+#include -+ -+#define VMA_PATH_STR_LEN 256 -+#define VMA_MAJOR_MINOR_LEN 8 -+ -+#define SCAN_AS_HUGE 0100000000 /* treat normal vm page as vm hugepage */ -+#define SCAN_IGN_HOST 0200000000 /* ignore host access when scan vm */ -+ -+enum { -+ VMA_STAT_READ = 0, -+ VMA_STAT_WRITE, -+ VMA_STAT_EXEC, -+ VMA_STAT_MAY_SHARE, -+ VMA_STAT_INIT, -+}; -+ -+/* -+ * vma struct -+ * */ -+struct vma { -+ uint64_t start; /* address start */ -+ uint64_t end; /* address end */ -+ bool stat[VMA_STAT_INIT]; /* vm area permissions */ -+ uint64_t offset; /* vm area offset */ -+ uint64_t inode; /* vm area inode */ -+ char path[VMA_PATH_STR_LEN]; /* path name */ -+ char major[VMA_MAJOR_MINOR_LEN]; /* device number major part */ -+ char minor[VMA_MAJOR_MINOR_LEN]; /* device number minor part */ -+ -+ struct vma *next; /* point to next vma */ -+}; -+ -+/* -+ * vmas struct -+ * */ -+struct vmas { -+ uint64_t vma_cnt; /* number of vm area */ -+ -+ struct vma *vma_list; /* vm area list */ -+}; -+ -+int etmemd_scan_init(void); -+void etmemd_scan_exit(void); -+ -+struct vmas *etmemd_get_vmas(const char *pid, char **vmflags_array, int vmflags_num, bool is_anon_only); -+void etmemd_free_vmas(struct vmas *vmas); -+ -+int etmemd_get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **page_refs, int flags); -+void etmemd_free_page_refs(struct page_refs *page_refs); -+ -+#endif -diff --git a/inc/etmemd_inc/etmemd_scan_export.h b/inc/etmemd_inc/etmemd_scan_export.h -new file mode 100644 -index 0000000..7ddc097 ---- /dev/null -+++ b/inc/etmemd_inc/etmemd_scan_export.h -@@ -0,0 +1,22 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: shikemeng -+ * Create: 2021-4-30 -+ * Description: This is a header file of the export scan library. -+ ******************************************************************************/ -+ -+#ifndef ETMEMD_SCAN_EXPORT_H -+#define ETMEMD_SCAN_EXPORT_H -+ -+#include "etmemd_exp.h" -+#include "etmemd_scan_exp.h" -+ -+#endif -diff --git a/src/etmemd_src/etmemd_common.c b/src/etmemd_src/etmemd_common.c -index 4b9c4cb..59933c4 100644 ---- a/src/etmemd_src/etmemd_common.c -+++ b/src/etmemd_src/etmemd_common.c -@@ -24,12 +24,18 @@ - #include - #include - #include -+#include -+#include - - #include "securec.h" - #include "etmemd_common.h" - #include "etmemd_rpc.h" - #include "etmemd_log.h" - -+#define IDLE_SCAN_MAGIC 0X66 -+#define IDLE_SCAN_ADD_FLAGS _IOW(IDLE_SCAN_MAGIC, 0x0, unsigned int) -+#define IDLE_SCAN_REMOVE_FLAGS _IOW(IDLE_SCAN_MAGIC, 0x1, unsigned int) -+ - static void usage(void) - { - printf("\nusage of etmemd:\n" -@@ -228,11 +234,16 @@ FILE *etmemd_get_proc_file(const char *pid, const char *file, int flags, const c - return NULL; - } - -- fd = open(file_name, flags); -+ fd = open(file_name, 0); - if (fd < 0) { - etmemd_log(ETMEMD_LOG_ERR, "open file %s fail\n", file_name); - goto free_file_name; - } -+ if (flags != 0 && ioctl(fd, IDLE_SCAN_ADD_FLAGS, &flags) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "set idle flags for %s fail with %s\n", pid, strerror(errno)); -+ close(fd); -+ goto free_file_name; -+ } - fp = fdopen(fd, mode); - - free_file_name: -diff --git a/src/etmemd_src/etmemd_scan.c b/src/etmemd_src/etmemd_scan.c -index fb4dd33..ba0cf5e 100644 ---- a/src/etmemd_src/etmemd_scan.c -+++ b/src/etmemd_src/etmemd_scan.c -@@ -35,6 +35,8 @@ - #define VMFLAG_MAX_LEN 100 - #define VMFLAG_MAX_NUM 30 - -+static bool g_exp_scan_inited = false; -+ - static const enum page_type g_page_type_by_idle_kind[] = { - PTE_TYPE, - PMD_TYPE, -@@ -403,6 +405,25 @@ struct vmas *get_vmas(const char *pid) - return get_vmas_with_flags(pid, NULL, 0, true); - } - -+struct vmas *etmemd_get_vmas(const char *pid, char *vmflags_array[], int vmflags_num, bool is_anon_only) -+{ -+ int i; -+ -+ if (pid == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "etmemd_get_vmas pid param is NULL\n"); -+ return NULL; -+ } -+ -+ for (i = 0; i < vmflags_num; i++) { -+ if (vmflags_array[i] == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "etmemd_get_vmas vmflags_array[%d] is NULL\n", i); -+ return NULL; -+ } -+ } -+ -+ return get_vmas_with_flags(pid, vmflags_array, vmflags_num, is_anon_only); -+} -+ - static u_int64_t get_address_from_buf(const unsigned char *buf, u_int64_t index) - { - u_int64_t address; -@@ -633,7 +654,7 @@ struct page_refs **walk_vmas(int fd, - * this parameter is used only in the dynamic engine to calculate the swap-in rate. - * In other policies, NULL can be directly transmitted. - * */ --int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **page_refs, unsigned long *use_rss) -+int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **page_refs, unsigned long *use_rss, int flags) - { - u_int64_t i; - FILE *scan_fp = NULL; -@@ -642,7 +663,7 @@ int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **p - struct page_refs **tmp_page_refs = NULL; - struct walk_address walk_address = {0, 0, 0}; - -- scan_fp = etmemd_get_proc_file(pid, IDLE_SCAN_FILE, 0, "r"); -+ scan_fp = etmemd_get_proc_file(pid, IDLE_SCAN_FILE, flags, "r"); - if (scan_fp == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "open %s file fail\n", IDLE_SCAN_FILE); - return -1; -@@ -683,6 +704,21 @@ int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **p - return 0; - } - -+int etmemd_get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **page_refs, int flags) -+{ -+ if (!g_exp_scan_inited) { -+ etmemd_log(ETMEMD_LOG_ERR, "scan module is not inited before etmemd_get_page_refs\n"); -+ return -1; -+ } -+ -+ if (vmas == NULL || pid == NULL || page_refs == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "NULL param is found in etmemd_get_page_refs\n"); -+ return -1; -+ } -+ -+ return get_page_refs(vmas, pid, page_refs, NULL, flags & ALL_SCAN_FLAGS); -+} -+ - void etmemd_free_page_refs(struct page_refs *pf) - { - struct page_refs *tmp_pf = NULL; -@@ -721,7 +757,7 @@ struct page_refs *etmemd_do_scan(const struct task_pid *tpid, const struct task - - /* loop for scanning idle_pages to get result of memory access. */ - for (i = 0; i < tk->eng->proj->loop; i++) { -- ret = get_page_refs(vmas, pid, &page_refs, NULL); -+ ret = get_page_refs(vmas, pid, &page_refs, NULL, 0); - if (ret != 0) { - etmemd_log(ETMEMD_LOG_ERR, "scan operation failed\n"); - /* free page_refs nodes already exist */ -@@ -737,6 +773,11 @@ struct page_refs *etmemd_do_scan(const struct task_pid *tpid, const struct task - return page_refs; - } - -+void etmemd_free_vmas(struct vmas *vmas) -+{ -+ free_vmas(vmas); -+} -+ - void clean_page_refs_unexpected(void *arg) - { - struct page_refs **pf = (struct page_refs **)arg; -@@ -773,3 +814,23 @@ struct page_refs *add_page_refs_into_memory_grade(struct page_refs *page_refs, s - /* return the next page_refs of the one that passed in */ - return tmp; - } -+ -+int etmemd_scan_init(void) -+{ -+ if (g_exp_scan_inited) { -+ etmemd_log(ETMEMD_LOG_ERR, "scan module already inited\n"); -+ return -1; -+ } -+ -+ if (init_g_page_size() == -1) { -+ return -1; -+ } -+ -+ g_exp_scan_inited = true; -+ return 0; -+} -+ -+void etmemd_scan_exit(void) -+{ -+ g_exp_scan_inited = false; -+} -diff --git a/src/etmemd_src/etmemd_scan.version b/src/etmemd_src/etmemd_scan.version -new file mode 100644 -index 0000000..576c96f ---- /dev/null -+++ b/src/etmemd_src/etmemd_scan.version -@@ -0,0 +1,4 @@ -+libetmemd_scan { -+ global: etmemd_scan_init; etmemd_scan_exit; etmemd_get_vmas; etmemd_free_vmas; etmemd_get_page_refs; etmemd_free_page_refs; -+ local:*; -+}; --- -2.27.0 - diff --git a/0027-add-ign_host-to-ignore-host-access-when-scan-vm.patch b/0027-add-ign_host-to-ignore-host-access-when-scan-vm.patch deleted file mode 100644 index 67938ba..0000000 --- a/0027-add-ign_host-to-ignore-host-access-when-scan-vm.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 104406ad127feeafbf5c8d618c608285ff23cd78 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Tue, 11 May 2021 16:08:39 +0800 -Subject: [PATCH 27/50] add ign_host to ignore host access when scan vm - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_cslide.c | 25 ++++++++++++++++++++++++- - 1 file changed, 24 insertions(+), 1 deletion(-) - -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 47a3608..9a2ab04 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -98,6 +98,7 @@ struct cslide_task_params { - char **vmflags_array; - int vmflags_num; - }; -+ int scan_flags; - }; - - struct vma_pf { -@@ -1285,13 +1286,14 @@ static int cslide_scan_vmas(struct cslide_pid_params *params) - struct walk_address walk_address; - uint64_t i; - int fd; -+ struct cslide_task_params *task_params = params->task_params; - - if (snprintf_s(pid, PID_STR_MAX_LEN, PID_STR_MAX_LEN - 1, "%u", params->pid) <= 0) { - etmemd_log(ETMEMD_LOG_ERR, "snpintf pid %u fail\n", params->pid); - return -1; - } - -- scan_fp = etmemd_get_proc_file(pid, IDLE_SCAN_FILE, SCAN_AS_HUGE, "r"); -+ scan_fp = etmemd_get_proc_file(pid, IDLE_SCAN_FILE, task_params->scan_flags, "r"); - if (scan_fp == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "open %s file for pid %u fail\n", IDLE_SCAN_FILE, params->pid); - return -1; -@@ -1922,9 +1924,30 @@ static int fill_task_vm_flags(void *obj, void *val) - return 0; - } - -+static int fill_task_scan_flags(void *obj, void *val) -+{ -+ struct cslide_task_params *params = (struct cslide_task_params *)obj; -+ char *ign_host = (char *)val; -+ int ret = 0; -+ -+ params->scan_flags |= SCAN_AS_HUGE; -+ -+ if (strcmp(ign_host, "yes") == 0) { -+ params->scan_flags |= SCAN_IGN_HOST; -+ } else if (strcmp(ign_host, "no") != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "ign_host : not support %s\n", ign_host); -+ etmemd_log(ETMEMD_LOG_ERR, "ign_host : only support yes/no\n"); -+ return -1; -+ } -+ -+ free(val); -+ return ret; -+} -+ - static struct config_item g_cslide_task_config_items[] = { - {"vm_flags", STR_VAL, fill_task_vm_flags, false}, - {"anon_only", STR_VAL, fill_task_anon_only, false}, -+ {"ign_host", STR_VAL, fill_task_scan_flags, false}, - }; - - static int cslide_fill_task(GKeyFile *config, struct task *tk) --- -2.27.0 - diff --git a/0028-openlog-with-same-ident.patch b/0028-openlog-with-same-ident.patch deleted file mode 100644 index 08da55c..0000000 --- a/0028-openlog-with-same-ident.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 4c33e102cd7745a4b2c2186414e0f2338e763916 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Tue, 11 May 2021 16:09:26 +0800 -Subject: [PATCH 28/50] openlog with same ident - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_log.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/src/etmemd_src/etmemd_log.c b/src/etmemd_src/etmemd_log.c -index fc49db8..5d7dece 100644 ---- a/src/etmemd_src/etmemd_log.c -+++ b/src/etmemd_src/etmemd_log.c -@@ -58,19 +58,19 @@ void etmemd_log(enum log_level log_level, const char *format, ...) - - switch (log_level) { - case ETMEMD_LOG_DEBUG: -- openlog("[etmemd_debug] ", LOG_PID, LOG_USER); -+ openlog("[etmemd] ", LOG_PID, LOG_USER); - vsyslog(LOG_DEBUG, format, args_in); - break; - case ETMEMD_LOG_INFO: -- openlog("[etmemd_info] ", LOG_PID, LOG_USER); -+ openlog("[etmemd] ", LOG_PID, LOG_USER); - vsyslog(LOG_INFO, format, args_in); - break; - case ETMEMD_LOG_WARN: -- openlog("[etmemd_warning] ", LOG_PID, LOG_USER); -+ openlog("[etmemd] ", LOG_PID, LOG_USER); - vsyslog(LOG_WARNING, format, args_in); - break; - case ETMEMD_LOG_ERR: -- openlog("[etmemd_error] ", LOG_PID, LOG_USER); -+ openlog("[etmemd] ", LOG_PID, LOG_USER); - vsyslog(LOG_ERR, format, args_in); - break; - default: --- -2.27.0 - diff --git a/0029-accept-advise.patch b/0029-accept-advise.patch deleted file mode 100644 index 3936a85..0000000 --- a/0029-accept-advise.patch +++ /dev/null @@ -1,139 +0,0 @@ -From fee91c2853f346d5222bf818930182b7b05b0e9f Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Tue, 11 May 2021 22:44:06 +0800 -Subject: [PATCH 29/50] accept advise - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_common.c | 2 +- - src/etmemd_src/etmemd_cslide.c | 2 +- - src/etmemd_src/etmemd_log.c | 6 ++---- - src/etmemd_src/etmemd_scan.c | 23 ++++++++++++++++++++++- - 4 files changed, 26 insertions(+), 7 deletions(-) - -diff --git a/src/etmemd_src/etmemd_common.c b/src/etmemd_src/etmemd_common.c -index 59933c4..e1cb1dd 100644 ---- a/src/etmemd_src/etmemd_common.c -+++ b/src/etmemd_src/etmemd_common.c -@@ -32,7 +32,7 @@ - #include "etmemd_rpc.h" - #include "etmemd_log.h" - --#define IDLE_SCAN_MAGIC 0X66 -+#define IDLE_SCAN_MAGIC 0x66 - #define IDLE_SCAN_ADD_FLAGS _IOW(IDLE_SCAN_MAGIC, 0x0, unsigned int) - #define IDLE_SCAN_REMOVE_FLAGS _IOW(IDLE_SCAN_MAGIC, 0x1, unsigned int) - -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 9a2ab04..6f609b8 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -1937,7 +1937,7 @@ static int fill_task_scan_flags(void *obj, void *val) - } else if (strcmp(ign_host, "no") != 0) { - etmemd_log(ETMEMD_LOG_ERR, "ign_host : not support %s\n", ign_host); - etmemd_log(ETMEMD_LOG_ERR, "ign_host : only support yes/no\n"); -- return -1; -+ ret = -1; - } - - free(val); -diff --git a/src/etmemd_src/etmemd_log.c b/src/etmemd_src/etmemd_log.c -index 5d7dece..0ffcc20 100644 ---- a/src/etmemd_src/etmemd_log.c -+++ b/src/etmemd_src/etmemd_log.c -@@ -56,26 +56,24 @@ void etmemd_log(enum log_level log_level, const char *format, ...) - - va_start(args_in, format); - -+ openlog("[etmemd] ", LOG_PID, LOG_USER); - switch (log_level) { - case ETMEMD_LOG_DEBUG: -- openlog("[etmemd] ", LOG_PID, LOG_USER); - vsyslog(LOG_DEBUG, format, args_in); - break; - case ETMEMD_LOG_INFO: -- openlog("[etmemd] ", LOG_PID, LOG_USER); - vsyslog(LOG_INFO, format, args_in); - break; - case ETMEMD_LOG_WARN: -- openlog("[etmemd] ", LOG_PID, LOG_USER); - vsyslog(LOG_WARNING, format, args_in); - break; - case ETMEMD_LOG_ERR: -- openlog("[etmemd] ", LOG_PID, LOG_USER); - vsyslog(LOG_ERR, format, args_in); - break; - default: - va_end(args_in); - printf("log_level is invalid, please check!\n"); -+ closelog(); - return; - } - -diff --git a/src/etmemd_src/etmemd_scan.c b/src/etmemd_src/etmemd_scan.c -index ba0cf5e..c287c48 100644 ---- a/src/etmemd_src/etmemd_scan.c -+++ b/src/etmemd_src/etmemd_scan.c -@@ -34,6 +34,7 @@ - #define PMD_IDLE_PTES_PARAMETER 512 - #define VMFLAG_MAX_LEN 100 - #define VMFLAG_MAX_NUM 30 -+#define VMFLAG_VALID_LEN 2 - - static bool g_exp_scan_inited = false; - -@@ -272,6 +273,7 @@ static bool is_vma_with_vmflags(FILE *fp, char *vmflags_array[], int vmflags_num - char parse_line[FILE_LINE_MAX_LEN]; - size_t len; - int i; -+ char *flags_start = NULL; - - len = strlen(VMFLAG_HEAD); - while (fgets(parse_line, FILE_LINE_MAX_LEN - 1, fp) != NULL) { -@@ -283,9 +285,10 @@ static bool is_vma_with_vmflags(FILE *fp, char *vmflags_array[], int vmflags_num - continue; - } - -+ flags_start = strstr(parse_line, ":"); - /* check any flag in flags is set */ - for (i = 0; i < vmflags_num; i++) { -- if (strstr(parse_line, vmflags_array[i]) == NULL) { -+ if (strstr(flags_start + 1, vmflags_array[i]) == NULL) { - return false; - } - } -@@ -405,6 +408,20 @@ struct vmas *get_vmas(const char *pid) - return get_vmas_with_flags(pid, NULL, 0, true); - } - -+static bool is_flag_valid(char *flag) -+{ -+ if (strstr(flag, " ") != NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "flag %s include space\n", flag); -+ return false; -+ } -+ if (strlen(flag) != VMFLAG_VALID_LEN) { -+ etmemd_log(ETMEMD_LOG_ERR, "flag %s len is not 2\n", flag); -+ return false; -+ } -+ -+ return true; -+} -+ - struct vmas *etmemd_get_vmas(const char *pid, char *vmflags_array[], int vmflags_num, bool is_anon_only) - { - int i; -@@ -419,6 +436,10 @@ struct vmas *etmemd_get_vmas(const char *pid, char *vmflags_array[], int vmflags - etmemd_log(ETMEMD_LOG_ERR, "etmemd_get_vmas vmflags_array[%d] is NULL\n", i); - return NULL; - } -+ if (!is_flag_valid(vmflags_array[i])) { -+ etmemd_log(ETMEMD_LOG_ERR, "etmemd_get_vmas flag %s invalid\n", vmflags_array[i]); -+ return NULL; -+ } - } - - return get_vmas_with_flags(pid, vmflags_array, vmflags_num, is_anon_only); --- -2.27.0 - diff --git a/0030-notify-rpc-success-with-finish-tag.patch b/0030-notify-rpc-success-with-finish-tag.patch deleted file mode 100644 index f8c4afa..0000000 --- a/0030-notify-rpc-success-with-finish-tag.patch +++ /dev/null @@ -1,157 +0,0 @@ -From 21795f23fa1532edffb636de90789749bf7dae04 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Tue, 11 May 2021 16:35:55 +0800 -Subject: [PATCH 30/50] notify rpc success with finish tag - -Signed-off-by: Kemeng Shi ---- - src/etmem_src/etmem_rpc.c | 39 +++++++++++++++++++++---------------- - src/etmemd_src/etmemd_rpc.c | 25 ++++++++++++++++-------- - 2 files changed, 39 insertions(+), 25 deletions(-) - -diff --git a/src/etmem_src/etmem_rpc.c b/src/etmem_src/etmem_rpc.c -index 48a4a96..2c70cf8 100644 ---- a/src/etmem_src/etmem_rpc.c -+++ b/src/etmem_src/etmem_rpc.c -@@ -31,6 +31,9 @@ - #define ETMEM_RPC_SEND_BUF_LEN 512 - #define ETMEM_RPC_CONN_TIMEOUT 10 - -+#define SUCCESS_CHAR (0xff) -+#define FAIL_CHAR (0xfe) -+ - static int etmem_client_conn(const struct mem_proj *proj, int sockfd) - { - struct sockaddr_un svr_addr; -@@ -144,14 +147,6 @@ EXIT: - return ret; - } - --static bool etmem_recv_find_fail_keyword(const char *recv_msg) --{ -- if (strstr(recv_msg, "error") != NULL) { -- return true; -- } -- return false; --} -- - static int etmem_client_recv(int sockfd) - { - ssize_t recv_size; -@@ -159,6 +154,7 @@ static int etmem_client_recv(int sockfd) - char *recv_msg = NULL; - uint8_t *recv_buf = NULL; - size_t recv_len = ETMEM_RPC_RECV_BUF_LEN; -+ bool done = false; - - recv_buf = (uint8_t *)calloc(recv_len, sizeof(uint8_t)); - if (recv_buf == NULL) { -@@ -166,27 +162,36 @@ static int etmem_client_recv(int sockfd) - return -1; - } - -- while (true) { -+ while (!done) { - recv_size = recv(sockfd, recv_buf, recv_len - 1, 0); - if (recv_size < 0) { - perror("recv failed:"); - goto EXIT; - } - if (recv_size == 0) { -- if (errno == EAGAIN || errno == EWOULDBLOCK) { -- printf("recv timeout:\n"); -- } -- ret = 0; -+ printf("connection closed by peer\n"); - goto EXIT; - } - - recv_msg = (char *)recv_buf; - recv_msg[recv_size] = '\0'; -- printf("%s\n", recv_msg); -- if (etmem_recv_find_fail_keyword(recv_msg)) { -- printf("error occurs when getting response from etmemd server\n"); -- goto EXIT; -+ -+ // check and erease finish flag -+ switch (recv_msg[recv_size - 1]) { -+ case (char)SUCCESS_CHAR: -+ ret = 0; -+ done = true; -+ recv_msg[recv_size - 1] = '\0'; -+ break; -+ case (char)FAIL_CHAR: -+ done = true; -+ recv_msg[recv_size - 1] = '\n'; -+ break; -+ default: -+ break; - } -+ -+ printf("%s", recv_msg); - } - - EXIT: -diff --git a/src/etmemd_src/etmemd_rpc.c b/src/etmemd_src/etmemd_rpc.c -index ba5971c..208f6b5 100644 ---- a/src/etmemd_src/etmemd_rpc.c -+++ b/src/etmemd_src/etmemd_rpc.c -@@ -35,6 +35,9 @@ - #define RPC_CLIENT_MAX 1 - #define RPC_BUFF_LEN_MAX 512 - -+#define SUCCESS_CHAR (0xff) -+#define FAIL_CHAR (0Xfe) -+ - static bool g_exit = true; - static char *g_sock_name = NULL; - static int g_sock_fd; -@@ -58,7 +61,6 @@ struct server_rpc_parser g_rpc_parser[] = { - }; - - struct rpc_resp_msg g_resp_msg_arr[] = { -- {OPT_SUCCESS, "success"}, - {OPT_INVAL, "error: invalid parameters"}, - {OPT_PRO_EXISTED, "error: project has been existed"}, - {OPT_PRO_NOEXIST, "error: project is not exist"}, -@@ -533,10 +535,7 @@ static void etmemd_rpc_send_response_msg(int sock_fd, enum opt_result result) - { - int i = 0; - ssize_t ret = -1; -- -- if (result == OPT_SUCCESS) { -- return; -- } -+ char finish_tag; - - while (g_resp_msg_arr[i].msg != NULL) { - if (result != g_resp_msg_arr[i].result) { -@@ -545,12 +544,22 @@ static void etmemd_rpc_send_response_msg(int sock_fd, enum opt_result result) - } - - ret = send(sock_fd, g_resp_msg_arr[i].msg, strlen(g_resp_msg_arr[i].msg), 0); -+ if (ret < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "send response to client fail, error(%s)\n", -+ strerror(errno)); -+ } - break; - } - -- if (ret < 0) { -- etmemd_log(ETMEMD_LOG_ERR, "send response to client fail, error(%s)\n", -- strerror(errno)); -+ // notify result with finish tag -+ if (result == OPT_SUCCESS) { -+ finish_tag = SUCCESS_CHAR; -+ } else { -+ finish_tag = FAIL_CHAR; -+ } -+ ret = send(sock_fd, &finish_tag, 1, 0); -+ if (ret <= 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "send finish tag fail\n"); - } - return; - } --- -2.27.0 - diff --git a/0031-remove-node_watermark.patch b/0031-remove-node_watermark.patch deleted file mode 100644 index 66fa08f..0000000 --- a/0031-remove-node_watermark.patch +++ /dev/null @@ -1,131 +0,0 @@ -From 57861ad98668370ef2b8de094ba2b5bfed4f9bac Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Wed, 12 May 2021 15:40:17 +0800 -Subject: [PATCH 31/50] remove node_watermark - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_cslide.c | 79 ---------------------------------- - 1 file changed, 79 deletions(-) - -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 6f609b8..745dbcc 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -143,7 +143,6 @@ struct cslide_params_factory { - struct cslide_eng_params { - struct sys_mem mem; - struct node_map node_map; -- int node_watermark; - int hot_threshold; - int hot_reserve; // in MB - int mig_quota; // in MB -@@ -1463,65 +1462,6 @@ static int cslide_do_migrate(struct cslide_eng_params *eng_params) - return 0; - } - --static bool is_node_empty(struct node_mem *mem) --{ -- return mem->huge_free == mem->huge_total; --} -- --static bool is_all_cold_node_empty(struct cslide_eng_params *eng_params) --{ -- struct sys_mem *mem = &eng_params->mem; -- struct node_pair *pair = NULL; -- int i; -- -- for (i = 0; i < eng_params->node_map.cur_num; i++) { -- pair = &eng_params->node_map.pair[i]; -- if (!is_node_empty(&mem->node_mem[pair->cold_node])) { -- return false; -- } -- } -- return true; --} -- --static inline bool is_busy(int node_watermark, long long total, long long free) --{ -- return free * TO_PCT / total < node_watermark; --} -- --static bool is_node_busy(int node_watermark, struct node_mem *mem) --{ -- return is_busy(node_watermark, mem->huge_total, mem->huge_free); --} -- --static bool is_any_hot_node_busy(struct cslide_eng_params *eng_params) --{ -- struct sys_mem *mem = &eng_params->mem; -- struct node_pair *pair = NULL; -- int node_watermark = eng_params->node_watermark; -- int i; -- -- for (i = 0; i < eng_params->node_map.cur_num; i++) { -- pair = &eng_params->node_map.pair[i]; -- if (is_node_busy(node_watermark, &mem->node_mem[pair->hot_node])) { -- return true; -- } -- } -- -- return false; --} -- --static bool need_migrate(struct cslide_eng_params *eng_params) --{ -- if (!is_all_cold_node_empty(eng_params)) { -- return true; -- } -- if (is_any_hot_node_busy(eng_params)) { -- return true; -- } -- -- return false; --} -- - static void init_host_pages_info(struct cslide_eng_params *eng_params) - { - int n; -@@ -1692,11 +1632,6 @@ static void *cslide_main(void *arg) - goto next; - } - -- if (!need_migrate(eng_params)) { -- etmemd_log(ETMEMD_LOG_DEBUG, "no need to migrate\n"); -- goto next; -- } -- - if (cslide_do_migrate(eng_params) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "cslide_do_migrate fail\n"); - goto next; -@@ -2055,19 +1990,6 @@ err: - return ret; - } - --static int fill_migrate_watermark(void *obj, void *val) --{ -- struct cslide_eng_params *params = (struct cslide_eng_params *)obj; -- int wm = parse_to_int(val); -- -- if (wm < MIN_WM || wm > MAX_WM) { -- etmemd_log(ETMEMD_LOG_ERR, "migrate watermark %d invalid\n", wm); -- return -1; -- } -- params->node_watermark = wm; -- return 0; --} -- - static int fill_hot_threshold(void *obj, void *val) - { - struct cslide_eng_params *params = (struct cslide_eng_params *)obj; -@@ -2112,7 +2034,6 @@ static int fill_mig_quota(void *obj, void *val) - - static struct config_item cslide_eng_config_items[] = { - {"node_pair", STR_VAL, fill_node_pair, false}, -- {"node_watermark", INT_VAL, fill_migrate_watermark, false}, - {"hot_threshold", INT_VAL, fill_hot_threshold, false}, - {"node_mig_quota", INT_VAL, fill_mig_quota, false}, - {"node_hot_reserve", INT_VAL, fill_hot_reserve, false}, --- -2.27.0 - diff --git a/0032-print-all-log-to-stdout.patch b/0032-print-all-log-to-stdout.patch deleted file mode 100644 index 4b28277..0000000 --- a/0032-print-all-log-to-stdout.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 3412ce69e8b61ad6d38f3d792930e8f2bafe6f00 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Wed, 12 May 2021 19:50:43 +0800 -Subject: [PATCH 32/50] print all log to stdout - -Signed-off-by: Kemeng Shi ---- - src/etmem_src/etmem.c | 2 +- - src/etmem_src/etmem_project.c | 2 +- - src/etmem_src/etmem_rpc.c | 7 ++++--- - 3 files changed, 6 insertions(+), 5 deletions(-) - -diff --git a/src/etmem_src/etmem.c b/src/etmem_src/etmem.c -index 7f04ad1..aadde74 100644 ---- a/src/etmem_src/etmem.c -+++ b/src/etmem_src/etmem.c -@@ -29,7 +29,7 @@ SLIST_HEAD(etmem_obj_list, etmem_obj) g_etmem_objs; - - static void usage(void) - { -- fprintf(stderr, -+ fprintf(stdout, - "\nUsage:\n" - " etmem OBJECT COMMAND\n" - " etmem help\n" -diff --git a/src/etmem_src/etmem_project.c b/src/etmem_src/etmem_project.c -index ef2d8fe..2caaff5 100644 ---- a/src/etmem_src/etmem_project.c -+++ b/src/etmem_src/etmem_project.c -@@ -25,7 +25,7 @@ - - static void project_help(void) - { -- fprintf(stderr, -+ fprintf(stdout, - "\nUsage:\n" - " etmem project start [options]\n" - " etmem project stop [options]\n" -diff --git a/src/etmem_src/etmem_rpc.c b/src/etmem_src/etmem_rpc.c -index 2c70cf8..76a8cf4 100644 ---- a/src/etmem_src/etmem_rpc.c -+++ b/src/etmem_src/etmem_rpc.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include "securec.h" - #include "etmem_rpc.h" - -@@ -71,7 +72,7 @@ static int etmem_client_conn(const struct mem_proj *proj, int sockfd) - - if (connect(sockfd, (struct sockaddr *)&svr_addr, - offsetof(struct sockaddr_un, sun_path) + strlen(proj->sock_name) + 1) < 0) { -- perror("etmem connect to server failed:"); -+ printf("etmem connect to server failed: %s\n", strerror(errno)); - return errno; - } - -@@ -137,7 +138,7 @@ static int etmem_client_send(const struct mem_proj *proj, int sockfd) - } - - if (send(sockfd, reg_cmd, reg_cmd_len, 0) < 0) { -- perror("send failed:"); -+ printf("send failed: %s\n", strerror(errno)); - goto EXIT; - } - ret = 0; -@@ -165,7 +166,7 @@ static int etmem_client_recv(int sockfd) - while (!done) { - recv_size = recv(sockfd, recv_buf, recv_len - 1, 0); - if (recv_size < 0) { -- perror("recv failed:"); -+ printf("recv failed: %s\n", strerror(errno)); - goto EXIT; - } - if (recv_size == 0) { --- -2.27.0 - diff --git a/0033-accept-review-advise.patch b/0033-accept-review-advise.patch deleted file mode 100644 index a89fd4f..0000000 --- a/0033-accept-review-advise.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 509a5306e685b18f03eea91d84bf3aa70b8a5c2e Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Thu, 13 May 2021 14:20:29 +0800 -Subject: [PATCH 33/50] accept review advise - -Signed-off-by: Kemeng Shi ---- - src/etmem_src/etmem_rpc.c | 2 +- - src/etmemd_src/etmemd_rpc.c | 4 ++-- - 2 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/etmem_src/etmem_rpc.c b/src/etmem_src/etmem_rpc.c -index 76a8cf4..384ead1 100644 ---- a/src/etmem_src/etmem_rpc.c -+++ b/src/etmem_src/etmem_rpc.c -@@ -177,7 +177,7 @@ static int etmem_client_recv(int sockfd) - recv_msg = (char *)recv_buf; - recv_msg[recv_size] = '\0'; - -- // check and erease finish flag -+ // check and erase finish flag - switch (recv_msg[recv_size - 1]) { - case (char)SUCCESS_CHAR: - ret = 0; -diff --git a/src/etmemd_src/etmemd_rpc.c b/src/etmemd_src/etmemd_rpc.c -index 208f6b5..969d4af 100644 ---- a/src/etmemd_src/etmemd_rpc.c -+++ b/src/etmemd_src/etmemd_rpc.c -@@ -546,7 +546,7 @@ static void etmemd_rpc_send_response_msg(int sock_fd, enum opt_result result) - ret = send(sock_fd, g_resp_msg_arr[i].msg, strlen(g_resp_msg_arr[i].msg), 0); - if (ret < 0) { - etmemd_log(ETMEMD_LOG_ERR, "send response to client fail, error(%s)\n", -- strerror(errno)); -+ strerror(errno)); - } - break; - } -@@ -557,7 +557,7 @@ static void etmemd_rpc_send_response_msg(int sock_fd, enum opt_result result) - } else { - finish_tag = FAIL_CHAR; - } -- ret = send(sock_fd, &finish_tag, 1, 0); -+ ret = send(sock_fd, &finish_tag, sizeof(finish_tag), 0); - if (ret <= 0) { - etmemd_log(ETMEMD_LOG_ERR, "send finish tag fail\n"); - } --- -2.27.0 - diff --git a/0034-fix-open-swap_pages-failure.patch b/0034-fix-open-swap_pages-failure.patch deleted file mode 100644 index 026da69..0000000 --- a/0034-fix-open-swap_pages-failure.patch +++ /dev/null @@ -1,48 +0,0 @@ -From bcbd8d433b5a0e64d202a781599a691183388024 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Sun, 16 May 2021 16:46:45 +0800 -Subject: [PATCH 34/50] fix open swap_pages failure - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_common.c | 17 +++++++++++++---- - 1 file changed, 13 insertions(+), 4 deletions(-) - -diff --git a/src/etmemd_src/etmemd_common.c b/src/etmemd_src/etmemd_common.c -index 07c9e7a..29aa52a 100644 ---- a/src/etmemd_src/etmemd_common.c -+++ b/src/etmemd_src/etmemd_common.c -@@ -239,17 +239,26 @@ FILE *etmemd_get_proc_file(const char *pid, const char *file, int flags, const c - return NULL; - } - -- fd = open(file_name, 0); -- if (fd < 0) { -+ fp = fopen(file_name, mode); -+ if (fp == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "open file %s fail\n", file_name); - goto free_file_name; - } -+ -+ fd = fileno(fp); -+ if (fd < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get fd of file %s fail\n", file_name); -+ fclose(fp); -+ fp = NULL; -+ goto free_file_name; -+ } -+ - if (flags != 0 && ioctl(fd, IDLE_SCAN_ADD_FLAGS, &flags) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "set idle flags for %s fail with %s\n", pid, strerror(errno)); -- close(fd); -+ fclose(fp); -+ fp = NULL; - goto free_file_name; - } -- fp = fdopen(fd, mode); - - free_file_name: - free(file_name); --- -2.27.0 - diff --git a/0035-give-the-correct-example-of-config-file.patch b/0035-give-the-correct-example-of-config-file.patch deleted file mode 100644 index da5e444..0000000 --- a/0035-give-the-correct-example-of-config-file.patch +++ /dev/null @@ -1,85 +0,0 @@ -From d560b00961e95e7eda3840a8189d226b0cbf08d5 Mon Sep 17 00:00:00 2001 -From: louhongxiang -Date: Sat, 15 May 2021 17:29:40 +0800 -Subject: [PATCH 35/50] give the correct example of config file - ---- - conf/example_conf.yaml | 68 ++++++++++++++++++++++++++++++++++-------- - 1 file changed, 56 insertions(+), 12 deletions(-) - -diff --git a/conf/example_conf.yaml b/conf/example_conf.yaml -index 485c35a..de612f6 100644 ---- a/conf/example_conf.yaml -+++ b/conf/example_conf.yaml -@@ -1,12 +1,56 @@ --options: --loop : 3 --interval : 1 --sleep: 2 -- --policies: -- type : pid/name -- value : 123456/mysql -- max_threads: 3 -- engine :slide -- param: -- T : 3 -+[project] -+name=test -+loop=1 -+interval=1 -+sleep=1 -+ -+#slide -+[engine] -+name=slide -+project=test -+ -+[task] -+project=test -+engine=slide -+name=background_slide -+type=name -+value=mysql -+T=1 -+max_threads=1 -+ -+#cslide -+[engine] -+name=cslide -+project=test -+node_pair=2,0;3,1 -+hot_threshold=1 -+node_mig_quota=1024 -+node_hot_reserve=1024 -+ -+[task] -+project=test -+engine=cslide -+name=background_cslide -+type=pid -+name=23456 -+vm_flags=ht -+anon_only=no -+ign_host=no -+ -+#thirdparty -+[engine] -+name=thirdparty -+project=test -+eng_name=my_engine -+libname=/usr/lib/etmem_fetch/my_engine.so -+ops_name=my_engine_ops -+engine_private_key=engine_private_value -+ -+[task] -+project=test -+engine=my_engine -+name=backgroud_third -+type=pid -+value=12345 -+task_private_key=task_private_value -+ --- -2.27.0 - diff --git a/0036-check-if-start_task-is-NULL-before-call-it.patch b/0036-check-if-start_task-is-NULL-before-call-it.patch deleted file mode 100644 index f176250..0000000 --- a/0036-check-if-start_task-is-NULL-before-call-it.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 8a66153b5d2094fae65e08418ac3752d868175dc Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Mon, 24 May 2021 20:08:38 +0800 -Subject: [PATCH 36/50] check if start_task is NULL before call it - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_project.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/etmemd_src/etmemd_project.c b/src/etmemd_src/etmemd_project.c -index 3b12296..2e69dd6 100644 ---- a/src/etmemd_src/etmemd_project.c -+++ b/src/etmemd_src/etmemd_project.c -@@ -279,7 +279,7 @@ enum opt_result etmemd_project_add_task(GKeyFile *config) - goto remove_task; - } - -- if (proj->start && eng->ops->start_task(eng, tk) != 0) { -+ if (proj->start && eng->ops->start_task != NULL && eng->ops->start_task(eng, tk) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "start added task %s fail\n", tk->name); - goto clear_task; - } --- -2.27.0 - diff --git a/0037-correct-max_threads-when-max_threads-is-0.patch b/0037-correct-max_threads-when-max_threads-is-0.patch deleted file mode 100644 index 7d2d760..0000000 --- a/0037-correct-max_threads-when-max_threads-is-0.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 77d80edcb65316d95f8f09810613ee857dc7f8f9 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Mon, 24 May 2021 20:24:18 +0800 -Subject: [PATCH 37/50] correct max_threads when max_threads is 0 - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_task.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/etmemd_src/etmemd_task.c b/src/etmemd_src/etmemd_task.c -index 01491f7..5aa693b 100644 ---- a/src/etmemd_src/etmemd_task.c -+++ b/src/etmemd_src/etmemd_task.c -@@ -444,7 +444,7 @@ static int fill_task_threads(void *obj, void *val) - int max_threads = parse_to_int(val); - int core; - -- if (max_threads < 0) { -+ if (max_threads <= 0) { - etmemd_log(ETMEMD_LOG_WARN, - "Thread count is abnormal, set the default minimum of current thread count to 1\n"); - max_threads = 1; --- -2.27.0 - diff --git a/0038-fix-etmem-help-return-error.patch b/0038-fix-etmem-help-return-error.patch deleted file mode 100644 index aeaeba9..0000000 --- a/0038-fix-etmem-help-return-error.patch +++ /dev/null @@ -1,25 +0,0 @@ -From d99225f7e64d824b18c95fb475191ea50861169f Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Mon, 24 May 2021 21:17:47 +0800 -Subject: [PATCH 38/50] fix etmem help return error - -Signed-off-by: Kemeng Shi ---- - src/etmem_src/etmem.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/etmem_src/etmem.c b/src/etmem_src/etmem.c -index aadde74..76ea8d2 100644 ---- a/src/etmem_src/etmem.c -+++ b/src/etmem_src/etmem.c -@@ -127,6 +127,7 @@ int main(int argc, char *argv[]) - if (conf.obj != NULL && strcmp(conf.obj, "help") == 0 && - argc == 2) { /* 2 is for param num of "etmem help" */ - err = 0; -+ goto out; - } - err = -EINVAL; - goto out; --- -2.27.0 - diff --git a/0039-check-if-eng_mgt_func-is-NULL-before-use-it.patch b/0039-check-if-eng_mgt_func-is-NULL-before-use-it.patch deleted file mode 100644 index 94f217c..0000000 --- a/0039-check-if-eng_mgt_func-is-NULL-before-use-it.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 10accbfc9c4d0a7658a333d94f5c3d0f31aeb6e5 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Wed, 26 May 2021 09:15:32 +0800 -Subject: [PATCH 39/50] check if eng_mgt_func is NULL before use it - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_project.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/src/etmemd_src/etmemd_project.c b/src/etmemd_src/etmemd_project.c -index 2e69dd6..decae76 100644 ---- a/src/etmemd_src/etmemd_project.c -+++ b/src/etmemd_src/etmemd_project.c -@@ -732,6 +732,12 @@ enum opt_result etmemd_project_mgt_engine(const char *project_name, const char * - return OPT_TASK_NOEXIST; - } - } -+ -+ if (eng->ops->eng_mgt_func == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "engine %s does not support eng_mgt_func\n", eng->name); -+ return OPT_INVAL; -+ } -+ - if (eng->ops->eng_mgt_func(eng, tk, cmd, sock_fd) != 0) { - return OPT_INVAL; - } --- -2.27.0 - diff --git a/0040-make-code-clean-for-etmem.patch b/0040-make-code-clean-for-etmem.patch deleted file mode 100644 index 8d17700..0000000 --- a/0040-make-code-clean-for-etmem.patch +++ /dev/null @@ -1,302 +0,0 @@ -From 01e8f7ea6c15c12991026a1838ca0573bbf9b910 Mon Sep 17 00:00:00 2001 -From: HukunaMatata -Date: Wed, 26 May 2021 09:45:27 +0800 -Subject: [PATCH 40/50] make code clean for etmem. - ---- - inc/etmemd_inc/etmemd_common.h | 9 ------ - inc/etmemd_inc/etmemd_task_exp.h | 2 +- - src/etmem_src/etmem.c | 2 -- - src/etmem_src/etmem_engine.c | 10 ++----- - src/etmemd_src/etmemd_common.c | 44 ------------------------------ - src/etmemd_src/etmemd_cslide.c | 28 ++++++++++++------- - src/etmemd_src/etmemd_rpc.c | 9 ++++++ - src/etmemd_src/etmemd_scan.c | 1 - - src/etmemd_src/etmemd_thirdparty.c | 7 +++++ - 9 files changed, 38 insertions(+), 74 deletions(-) - -diff --git a/inc/etmemd_inc/etmemd_common.h b/inc/etmemd_inc/etmemd_common.h -index e228476..4127ccf 100644 ---- a/inc/etmemd_inc/etmemd_common.h -+++ b/inc/etmemd_inc/etmemd_common.h -@@ -54,15 +54,6 @@ FILE *etmemd_get_proc_file(const char *pid, const char *file, int flags, const c - - int get_keyword_and_value(const char *str, char *key, char *val); - --/* function: get the line which has effective content only from the file -- * -- * in: FILE *file - the file to read -- * -- * out: char * - the string with effective content -- * NULL - end of file. -- * */ --char *skip_blank_line(FILE *file); -- - int dprintf_all(int fd, const char *format, ...); - - #endif -diff --git a/inc/etmemd_inc/etmemd_task_exp.h b/inc/etmemd_inc/etmemd_task_exp.h -index b62f382..33d505a 100644 ---- a/inc/etmemd_inc/etmemd_task_exp.h -+++ b/inc/etmemd_inc/etmemd_task_exp.h -@@ -28,7 +28,7 @@ struct task { - char *type; - char *value; - char *name; -- uint64_t max_threads; -+ int max_threads; - - struct task_pid *pids; - struct engine *eng; -diff --git a/src/etmem_src/etmem.c b/src/etmem_src/etmem.c -index 76ea8d2..f243a75 100644 ---- a/src/etmem_src/etmem.c -+++ b/src/etmem_src/etmem.c -@@ -23,8 +23,6 @@ - #include "etmem_project.h" - #include "etmem_engine.h" - --#define CMD_POSITION 1 -- - SLIST_HEAD(etmem_obj_list, etmem_obj) g_etmem_objs; - - static void usage(void) -diff --git a/src/etmem_src/etmem_engine.c b/src/etmem_src/etmem_engine.c -index bafcfe6..675c38f 100644 ---- a/src/etmem_src/etmem_engine.c -+++ b/src/etmem_src/etmem_engine.c -@@ -39,11 +39,11 @@ static void engine_help(void) - " 5. eng_cmd is supported by engine own.\n"); - } - --static int engine_parse_cmd(struct etmem_conf *conf, struct mem_proj *proj) -+static void engine_parse_cmd(struct etmem_conf *conf, struct mem_proj *proj) - { - proj->eng_cmd = conf->argv[0]; - proj->cmd = ETMEM_CMD_ENGINE; -- return 0; -+ return; - } - - static int engine_parse_args(struct etmem_conf *conf, struct mem_proj *proj) -@@ -126,11 +126,7 @@ static int engine_do_cmd(struct etmem_conf *conf) - return ret; - } - -- ret = engine_parse_cmd(conf, &proj); -- if (ret != 0) { -- printf("engine_parse_cmd fail\n"); -- return -1; -- } -+ engine_parse_cmd(conf, &proj); - - ret = engine_parse_args(conf, &proj); - if (ret != 0) { -diff --git a/src/etmemd_src/etmemd_common.c b/src/etmemd_src/etmemd_common.c -index 29aa52a..8aad0eb 100644 ---- a/src/etmemd_src/etmemd_common.c -+++ b/src/etmemd_src/etmemd_common.c -@@ -34,7 +34,6 @@ - - #define IDLE_SCAN_MAGIC 0x66 - #define IDLE_SCAN_ADD_FLAGS _IOW(IDLE_SCAN_MAGIC, 0x0, unsigned int) --#define IDLE_SCAN_REMOVE_FLAGS _IOW(IDLE_SCAN_MAGIC, 0x1, unsigned int) - - static void usage(void) - { -@@ -360,49 +359,6 @@ int get_keyword_and_value(const char *str, char *key, char *val) - return 0; - } - --static char *skip_colon_space_and_blank_line(char *str) --{ -- size_t len; -- -- len = strlen(str); -- while (len-- > 0) { -- if (is_valid_char_for_value(" :\n\t", str[len])) { -- str[len] = '\0'; -- continue; -- } -- -- break; -- } -- -- if (strlen(str) == 0) { -- return ""; -- } -- -- while (is_valid_char_for_value(" \t", *str)) { -- str++; -- } -- -- return str; --} -- --char *skip_blank_line(FILE *file) --{ -- static char line[FILE_LINE_MAX_LEN] = {}; -- char *get_line = NULL; -- -- while (fgets(line, FILE_LINE_MAX_LEN, file) != NULL) { -- get_line = skip_colon_space_and_blank_line(line); -- if (strcmp(get_line, "") != 0) { -- break; -- } -- /* in case the last line is an empty line, -- * make the get_line equals to NULL before next loop begins */ -- get_line = NULL; -- } -- -- return get_line; --} -- - static int write_all(int fd, const char *buf) - { - ssize_t rest = strlen(buf); -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 745dbcc..a77b7bb 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -33,15 +33,10 @@ - - #define HUGE_1M_SIZE (1 << 20) - #define HUGE_2M_SIZE (2 << 20) --#define HUGE_1G_SIZE (1 << 30) - #define BYTE_TO_KB(s) ((s) >> 10) - #define KB_TO_BYTE(s) ((s) << 10) - #define HUGE_2M_TO_KB(s) ((s) << 11) - --#define TO_PCT 100 --#define MAX_WM 100 --#define MIN_WM 0 -- - #define BATCHSIZE (1 << 16) - - #define factory_foreach_working_pid_params(iter, factory) \ -@@ -104,7 +99,6 @@ struct cslide_task_params { - struct vma_pf { - struct vma *vma; - struct page_refs *page_refs; -- struct vma_pf *next; - }; - - struct node_pages_info { -@@ -366,7 +360,7 @@ static void npf_setup_tail(struct node_page_refs *npf) - } - } - --static long long move_npf_to_list(struct node_page_refs *npf, struct page_refs **list, long long size) -+static void move_npf_to_list(struct node_page_refs *npf, struct page_refs **list, long long size) - { - struct page_refs *t = NULL; - struct page_refs *iter = NULL; -@@ -394,7 +388,7 @@ static long long move_npf_to_list(struct node_page_refs *npf, struct page_refs * - } - - npf->size -= moved_size; -- return moved_size; -+ return; - } - - static int init_count_page_refs(struct count_page_refs *cpf, int node_num) -@@ -1702,9 +1696,23 @@ static void cslide_stop_task(struct engine *eng, struct task *tk) - - static char *get_time_stamp(time_t *t) - { -- char *ts = asctime(localtime(t)); -- size_t len = strlen(ts); -+ struct tm *lt = NULL; -+ char *ts = NULL; -+ size_t len; -+ -+ lt = localtime(t); -+ if (lt == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "get local time fail\n"); -+ return NULL; -+ } -+ -+ ts = asctime(localtime(t)); -+ if (ts == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "get asctime fail\n"); -+ return NULL; -+ } - -+ len = strlen(ts); - if (ts[len - 1] == '\n') { - ts[len - 1] = '\0'; - } -diff --git a/src/etmemd_src/etmemd_rpc.c b/src/etmemd_src/etmemd_rpc.c -index 969d4af..6b23059 100644 ---- a/src/etmemd_src/etmemd_rpc.c -+++ b/src/etmemd_src/etmemd_rpc.c -@@ -169,12 +169,18 @@ static enum opt_result handle_obj_cmd(char *file_name, enum cmd_type type) - { - GKeyFile *config = NULL; - enum opt_result ret; -+ char resolve_path[PATH_MAX] = {0}; - - if (file_name == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "file name is not set for obj cmd\n"); - return OPT_INVAL; - } - -+ if (realpath(file_name, resolve_path) == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "config file is not a real path(%s)\n", strerror(errno)); -+ return OPT_INVAL; -+ } -+ - config = g_key_file_new(); - if (config == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "get empty config file fail\n"); -@@ -678,14 +684,17 @@ static int rpc_deal_parent(void) - - if ((len = sprintf_s(pid_s, PID_STR_MAX_LEN, "%d", pid)) <= 0) { - etmemd_log(ETMEMD_LOG_ERR, "sprintf for pid failed\n"); -+ close(handle); - exit(1); - } - - if ((write(handle, pid_s, len)) != len) { - etmemd_log(ETMEMD_LOG_ERR, "Error writing to the file\n"); -+ close(handle); - exit(1); - } - -+ close(handle); - close(g_fd[1]); - if (read(g_fd[0], &val, sizeof(val)) <= 0) { - etmemd_log(ETMEMD_LOG_ERR, "Error reading to the file\n"); -diff --git a/src/etmemd_src/etmemd_scan.c b/src/etmemd_src/etmemd_scan.c -index c287c48..1cafaed 100644 ---- a/src/etmemd_src/etmemd_scan.c -+++ b/src/etmemd_src/etmemd_scan.c -@@ -32,7 +32,6 @@ - #define PUD_SIZE_SHIFT 30 - #define HEXADECIMAL_RADIX 16 - #define PMD_IDLE_PTES_PARAMETER 512 --#define VMFLAG_MAX_LEN 100 - #define VMFLAG_MAX_NUM 30 - #define VMFLAG_VALID_LEN 2 - -diff --git a/src/etmemd_src/etmemd_thirdparty.c b/src/etmemd_src/etmemd_thirdparty.c -index 53d4b8e..8d1b50e 100644 ---- a/src/etmemd_src/etmemd_thirdparty.c -+++ b/src/etmemd_src/etmemd_thirdparty.c -@@ -83,6 +83,13 @@ static int set_engine_ops(struct engine *eng, struct thirdparty_params *params) - void *handler = NULL; - struct engine_ops *ops = NULL; - char *err = NULL; -+ char resolve_path[PATH_MAX] = {0}; -+ -+ if (realpath(params->libname, resolve_path) == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "file of thirdparty libname %s is not a real path(%s)\n", -+ params->libname, strerror(errno)); -+ return -1; -+ } - - handler = dlopen(params->libname, RTLD_NOW | RTLD_LOCAL); - err = dlerror(); --- -2.27.0 - diff --git a/0041-return-error-if-migrate-failed-and-clean-code.patch b/0041-return-error-if-migrate-failed-and-clean-code.patch deleted file mode 100644 index aaac650..0000000 --- a/0041-return-error-if-migrate-failed-and-clean-code.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 8945313183ecfd752c4d8fbd5d8e5e464bd9ed37 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Wed, 26 May 2021 19:57:09 +0800 -Subject: [PATCH 41/50] return error if migrate failed and clean code - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_cslide.c | 14 ++++++++++---- - src/etmemd_src/etmemd_scan.c | 3 --- - 2 files changed, 10 insertions(+), 7 deletions(-) - -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index 745dbcc..3a30d6b 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -1445,21 +1445,27 @@ static int cslide_do_migrate(struct cslide_eng_params *eng_params) - struct cslide_pid_params *iter = NULL; - struct node_pair *pair = NULL; - int bind_node, i; -+ int ret = 0; - - factory_foreach_working_pid_params(iter, &eng_params->factory) { - for (i = 0; i < eng_params->node_map.cur_num; i++) { - pair = &eng_params->node_map.pair[i]; - bind_node = pair->hot_node < pair->cold_node ? pair->hot_node : pair->cold_node; - if (numa_run_on_node(bind_node) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "fail to run on node %d to migrate memory\n", bind_node); -+ etmemd_log(ETMEMD_LOG_INFO, "fail to run on node %d to migrate memory\n", bind_node); -+ } -+ ret = migrate_single_task(iter->pid, &iter->memory_grade[i], pair->hot_node, pair->cold_node); -+ if (ret != 0) { -+ goto exit; - } -- migrate_single_task(iter->pid, &iter->memory_grade[i], pair->hot_node, pair->cold_node); - } - } -+ -+exit: - if (numa_run_on_node(-1) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "fail to run on all node after migrate memory\n"); -+ etmemd_log(ETMEMD_LOG_INFO, "fail to run on all node after migrate memory\n"); - } -- return 0; -+ return ret; - } - - static void init_host_pages_info(struct cslide_eng_params *eng_params) -diff --git a/src/etmemd_src/etmemd_scan.c b/src/etmemd_src/etmemd_scan.c -index c287c48..ed17d2b 100644 ---- a/src/etmemd_src/etmemd_scan.c -+++ b/src/etmemd_src/etmemd_scan.c -@@ -27,9 +27,6 @@ - #include "etmemd_log.h" - #include "securec.h" - --#define PTE_SIZE_SHIFT 12 --#define PMD_SIZE_SHIFT 21 --#define PUD_SIZE_SHIFT 30 - #define HEXADECIMAL_RADIX 16 - #define PMD_IDLE_PTES_PARAMETER 512 - #define VMFLAG_MAX_NUM 30 --- -2.27.0 - diff --git a/0042-etmemd-fix-memleak-and-clean-code.patch b/0042-etmemd-fix-memleak-and-clean-code.patch deleted file mode 100644 index ff3a224..0000000 --- a/0042-etmemd-fix-memleak-and-clean-code.patch +++ /dev/null @@ -1,59 +0,0 @@ -From bc6ed8fe0b2691b92f0d508d73e1b903aee5fd63 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Thu, 27 May 2021 14:42:55 +0800 -Subject: [PATCH 42/50] etmemd: fix memleak and clean code - -1.detach cslide main thread to release resource when exit -2.clean code - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_cslide.c | 6 +++++- - src/etmemd_src/etmemd_task.c | 7 ++++++- - 2 files changed, 11 insertions(+), 2 deletions(-) - -diff --git a/src/etmemd_src/etmemd_cslide.c b/src/etmemd_src/etmemd_cslide.c -index d1dd06c..ad3eff8 100644 ---- a/src/etmemd_src/etmemd_cslide.c -+++ b/src/etmemd_src/etmemd_cslide.c -@@ -1606,6 +1606,10 @@ static void *cslide_main(void *arg) - struct cslide_eng_params *eng_params = (struct cslide_eng_params *)arg; - struct sys_mem *mem = NULL; - -+ // only invalid pthread id or deatch more than once will cause error -+ // so no need to check return value of pthread_detach -+ (void)pthread_detach(pthread_self()); -+ - while (true) { - factory_update_pid_params(&eng_params->factory); - if (eng_params->finish) { -@@ -1712,7 +1716,7 @@ static char *get_time_stamp(time_t *t) - return NULL; - } - -- ts = asctime(localtime(t)); -+ ts = asctime(lt); - if (ts == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "get asctime fail\n"); - return NULL; -diff --git a/src/etmemd_src/etmemd_task.c b/src/etmemd_src/etmemd_task.c -index 5aa693b..618245e 100644 ---- a/src/etmemd_src/etmemd_task.c -+++ b/src/etmemd_src/etmemd_task.c -@@ -58,7 +58,12 @@ static int get_pid_through_pipe(char *arg_pid[], const int *pipefd) - return -1; - } - -- execve(arg_pid[0], arg_pid, NULL); -+ 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; -+ } -+ - if (fflush(stdout) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "fflush execve stdout fail.\n"); - close(pipefd[1]); --- -2.27.0 - diff --git a/0043-update-README.md.patch b/0043-update-README.md.patch deleted file mode 100644 index 5b60157..0000000 --- a/0043-update-README.md.patch +++ /dev/null @@ -1,575 +0,0 @@ -From a70963f9e9d030a08b6b716c8cbd9826c8ba25bc Mon Sep 17 00:00:00 2001 -From: shikemeng -Date: Tue, 10 Aug 2021 02:22:02 +0000 -Subject: [PATCH 43/50] =?UTF-8?q?update=20README.md.=20=E6=9B=B4=E6=96=B0?= - =?UTF-8?q?=E4=BA=8C=E8=BF=9B=E5=88=B6=E5=90=AF=E5=8A=A8=EF=BC=8C=E9=85=8D?= - =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=E8=AF=B4=E6=98=8E=EF=BC=8C=E5=B7=A5?= - =?UTF-8?q?=E7=A8=8B=E5=88=9B=E5=BB=BA=EF=BC=8C=E5=88=A0=E9=99=A4=EF=BC=8C?= - =?UTF-8?q?=E5=90=AF=E5=8A=A8=EF=BC=8C=E5=81=9C=E6=AD=A2=EF=BC=8C=E6=9F=A5?= - =?UTF-8?q?=E8=AF=A2=E7=9A=84=E7=AB=A0=E8=8A=82=E3=80=82=20=E6=96=B0?= - =?UTF-8?q?=E5=A2=9Eetmem=E6=94=AF=E6=8C=81=E9=9A=8F=E7=B3=BB=E7=BB=9F?= - =?UTF-8?q?=E5=90=AF=E5=8A=A8=EF=BC=8Cetmem=E6=94=AF=E6=8C=81=E7=AC=AC?= - =?UTF-8?q?=E4=B8=89=E6=96=B9=E5=86=85=E5=AD=98=E6=89=A9=E5=B1=95=E7=AD=96?= - =?UTF-8?q?=E7=95=A5=EF=BC=8Cetmem=E6=94=AF=E6=8C=81=E4=BD=BF=E7=94=A8AEP?= - =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E5=86=85=E5=AD=98=E6=89=A9=E5=B1=95=E7=9A=84?= - =?UTF-8?q?=E7=AB=A0=E8=8A=82=E3=80=82?= -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---- - README.md | 457 +++++++++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 366 insertions(+), 91 deletions(-) - -diff --git a/README.md b/README.md -index 3e2a50a..93631a1 100644 ---- a/README.md -+++ b/README.md -@@ -43,18 +43,22 @@ $ etmemd -l 0 -s etmemd_socket - - options: - ---l|--log-level Log level ---s|--socket Socket name to listen to ---h|--help Show this message -+-l|\-\-log-level Log level -+ -+-s|\-\-socket Socket name to listen to -+ -+-h|\-\-help Show this message -+ -+-m|\-\-mode-systemctl mode used to start(systemctl) - - #### 命令行参数说明 - - | 参数 | 参数含义 | 是否必须 | 是否有参数 | 参数范围 | 示例说明 | - | --------------- | ---------------------------------- | -------- | ---------- | --------------------- | ------------------------------------------------------------ | --| -l或--log-level | etmemd日志级别 | 否 | 是 | 0~3 | 0:debug级别 1:info级别 2:warning级别 3:error级别 只有大于等于配置的级别才会打印到/var/log/message文件中 | --| -s或--socket | etmemd监听的名称,用于与客户端交互 | 是 | 是 | 107个字符之内的字符串 | 指定服务端监听的名称 | --| -h或--help | 帮助信息 | 否 | 否 | NA | 执行时带有此参数会打印后退出 | -- -+| -l或\-\-log-level | etmemd日志级别 | 否 | 是 | 0~3 | 0:debug级别 1:info级别 2:warning级别 3:error级别 只有大于等于配置的级别才会打印到/var/log/message文件中 | -+| -s或\-\-socket | etmemd监听的名称,用于与客户端交互 | 是 | 是 | 107个字符之内的字符串 | 指定服务端监听的名称 | -+| -h或\-\-help | 帮助信息 | 否 | 否 | NA | 执行时带有此参数会打印后退出 | -+| -m或\-\-mode-systemctl| etmemd作为service被拉起时,命令中可以使用此参数来支持fork模式启动| 否| 否| NA| NA| - ### etmem配置文件 - - 在运行etmem进程之前,需要管理员预先规划哪些进程需要做内存扩展,将进程信息配置到etmem配置文件中,并配置内存扫描的周期、扫描次数、内存冷热阈值等信息。 -@@ -62,158 +66,429 @@ options: - 配置文件的示例文件在源码包中,放置在源码根目录的conf/example_conf.yaml,建议在使用时放置在/etc/etmem/目录下,示例内容为: - - ``` --options: -- loop : 3 -- interval : 1 -- sleep: 2 -- policies: -- type : pid/name -- value : 123456/mysql -- max_threads: 3 -- engine : slide -- param: -- T: 3 -+[project] -+name=test -+loop=1 -+interval=1 -+sleep=1 -+ -+#slide引擎示例 -+[engine] -+name=slide -+project=test -+ -+[task] -+project=test -+engine=slide -+name=background_slide -+type=name -+value=mysql -+T=1 -+max_threads=1 -+ -+#cslide引擎示例 -+[engine] -+name=cslide -+project=test -+node_pair=2,0;3,1 -+hot_threshold=1 -+node_mig_quota=1024 -+node_hot_reserve=1024 -+ -+[task] -+project=test -+engine=cslide -+name=background_cslide -+type=pid -+name=23456 -+vm_flags=ht -+anon_only=no -+ign_host=no -+ -+#thirdparty引擎示例 -+[engine] -+name=thirdparty -+project=test -+eng_name=my_engine -+libname=/usr/lib/etmem_fetch/my_engine.so -+ops_name=my_engine_ops -+engine_private_key=engine_private_value -+ -+[task] -+project=test -+engine=my_engine -+name=backgroud_third -+type=pid -+value=12345 -+task_private_key=task_private_value - ``` - - 配置文件各字段说明: - --| **置项** | **配置项含义** | **是否必须** | **是否有参数** | **参数范围** | **示例说明** | --| ----------- | ------------------------------------------------------------ | ------------ | -------------- | ------------------------- | ------------------------------------------------------------ | --| options | project公用配置段起始标识 | 是 | 否 | NA | 每个配置文件有且仅有一个此字段,并且文件以此字段开始 | --| loop | 内存扫描的循环次数 | 是 | 是 | 1~120 | loop:3 //扫描3次 | --| interval | 每次内存扫描的时间间隔 | 是 | 是 | 1~1200 | interval:5 //每次扫描之间间隔5s | --| sleep | 每个内存扫描+操作的大周期之间时间间隔 | 是 | 是 | 1~1200 | sleep:10 //每次大周期之间间隔10s | --| policies | project中各task任务配置段起始标识 | 是 | 否 | NA | 一个project中可以配置多个task,每个task以policies:开头 | --| type | 目标进程识别的方式 | 是 | 是 | pid/name | pid代表通过进程号识别,name代表通过进程名称识别 | --| value | 目标进程识别的具体字段 | 是 | 是 | 实际的进程号/进程名称 | 与type字段配合使用,指定目标进程的进程号或进程名称,由使用者保证配置的正确及唯一性 | --| max_threads | etmemd内部线程池最大线程数,每个线程处理一个进程/子进程的内存扫描+操作任务 | 否 | 是 | 1~2 * core数 + 1,默认为1 | 对外部无表象,控制etmemd服务端内部处理线程个数,当目标进程有多个子进程时,配置越大,并发执行的个数也多,但占用资源也越多 | --| engine | 扫描引擎类型 | 是 | 是 | slide | 声明使用slide引擎进行冷热内存识别 | --| param | 扫描引擎私有参数配置起始标识 | 是 | 否 | NA | 引擎私有参数配置段以此标识起始,每个task对应一种引擎,每个引擎对应一个param及其字段 | --| T | slide引擎的水线配置 | 是 | 否 | 1~3 * loop | 水线阈值,大于等于此值的内存会被识别为热内存,反之为冷内存 | -- --### etmem工程创建/删除/查询 -+| 配置项 | 配置项含义 | 是否必须 | 是否有参数 | 参数范围 | 示例说明 | -+|-----------|---------------------|------|-------|------------|-----------------------------------------------------------------| -+| [project] | project公用配置段起始标识 | 否 | 否 | NA | project参数的开头标识,表示下面的参数直到另外的[xxx]或文件结尾为止的范围内均为project section的参数 | -+| name | project的名字 | 是 | 是 | 64个字以内的字符串 | 用来标识project,engine和task在配置时需要指定要挂载到的project | -+| loop | 内存扫描的循环次数 | 是 | 是 | 1~10 | loop=3 //扫描3次 | -+| interval | 每次内存扫描的时间间隔 | 是 | 是 | 1~1200 | interval=5 //每次扫描之间间隔5s | -+| sleep | 每个内存扫描+操作的大周期之间时间间隔 | 是 | 是 | 1~1200 | sleep=10 //每次大周期之间间隔10s | -+| [engine] | engine公用配置段起始标识 | 否 | 否 | NA | engine参数的开头标识,表示下面的参数直到另外的[xxx]或文件结尾为止的范围内均为engine section的参数 | -+| project | 声明所在的project | 是 | 是 | 64个字以内的字符串 | 已经存在名字为test的project,则可以写为project=test | -+| engine | 声明所在的engine | 是 | 是 | slide/cslide/thridparty | 声明使用的是slide或cslide或thirdparty策略 | -+| node_pair | cslide engine的配置项,声明系统中AEP和DRAM的node pair | engine为cslide时必须配置 | 是 | 成对配置AEP和DRAM的node号,AEP和DRAM之间用逗号隔开,没对pair之间用分号隔开 | node_pair=2,0;3,1 | -+| hot_threshold | cslide engine的配置项,声明内存冷热水线的阈值 | engine为cslide时必须配置 | 是 | >= 0的整数 | hot_threshold=3 //访问次数小于3的内存会被识别为冷内存 | -+|node_mig_quota|cslide engine的配置项,流控,声明每次DRAM和AEP互相迁移时单向最大流量|engine为cslide时必须配置|是|>= 0的整数|node_mig_quota=1024 //单位为MB,AEP到DRAM或DRAM到AEP搬迁一次最大1024M| -+|node_hot_reserve|cslide engine的配置项,声明DRAM中热内存的预留空间大小|engine为cslide时必须配置|是|>= 0的整数|node_hot_reserve=1024 //单位为MB,当所有虚拟机热内存大于此配置值时,热内存也会迁移到AEP中| -+|eng_name|thirdparty engine的配置项,声明engine自己的名字,供task挂载|engine为thirdparty时必须配置|是|64个字以内的字符串|eng_name=my_engine //对此第三方策略engine挂载task时,task中写明engine=my_engine| -+|libname|thirdparty engine的配置项,声明第三方策略的动态库的地址,绝对地址|engine为thirdparty时必须配置|是|64个字以内的字符串|libname=/user/lib/etmem_fetch/code_test/my_engine.so| -+|ops_name|thirdparty engine的配置项,声明第三方策略的动态库中操作符号的名字|engine为thirdparty时必须配置|是|64个字以内的字符串|ops_name=my_engine_ops //第三方策略实现接口的结构体的名字| -+|engine_private_key|thirdparty engine的配置项,预留给第三方策略自己解析私有参数的配置项,选配|否|否|根据第三方策略私有参数自行限制|根据第三方策略私有engine参数自行配置| -+| [task] | task公用配置段起始标识 | 否 | 否 | NA | task参数的开头标识,表示下面的参数直到另外的[xxx]或文件结尾为止的范围内均为task section的参数 | -+| project | 声明所挂的project | 是 | 是 | 64个字以内的字符串 | 已经存在名字为test的project,则可以写为project=test | -+| engine | 声明所挂的engine | 是 | 是 | 64个字以内的字符串 | 所要挂载的engine的名字 | -+| name | task的名字 | 是 | 是 | 64个字以内的字符串 | name=background1 //声明task的名字是backgound1 | -+| type | 目标进程识别的方式 | 是 | 是 | pid/name | pid代表通过进程号识别,name代表通过进程名称识别 | -+| value | 目标进程识别的具体字段 | 是 | 是 | 实际的进程号/进程名称 | 与type字段配合使用,指定目标进程的进程号或进程名称,由使用者保证配置的正确及唯一性 | -+| T | engine为slide的task配置项,声明内存冷热水线的阈值 | engine为slide时必须配置 | 是 | 0~loop * 3 | T=3 //访问次数小于3的内存会被识别为冷内存 | -+| max_threads | engine为slide的task配置项,etmemd内部线程池最大线程数,每个线程处理一个进程/子进程的内存扫描+操作任务 | 否 | 是 | 1~2 * core数 + 1,默认为1 | 对外部无表象,控制etmemd服务端内部处理线程个数,当目标进程有多个子进程时,配置越大,并发执行的个数也多,但占用资源也越多 | -+| vm_flags | engine为cslide的task配置项,通过指定flag扫描的vma,不配置此项时扫描则不会区分 | engine为cslide时必须配置 | 是 | 当前只支持ht | vm_flags=ht //扫描flags为ht(大页)的vma内存 | -+| anon_only | engine为cslide的task配置项,标识是否只扫描匿名页 | 否 | 是 | yes/no | anon_only=no //配置为yes时只扫描匿名页,配置为no时非匿名页也会扫描 | -+| ign_host | engine为cslide的task配置项,标识是否忽略host上的页表扫描信息 | 否 | 是 | yes/no | ign_host=no //yes为忽略,no为不忽略 | -+| task_private_key | engine为thirdparty的task配置项,预留给第三方策略的task解析私有参数的配置项,选配 | 否 | 否 | 根据第三方策略私有参数自行限制 | 根据第三方策略私有task参数自行配置 | -+ -+ -+ -+### etmem project/engine/task对象的创建和删除 - - #### 场景描述 - --1)管理员创建etmem工程(一个工程可包含多个etmem任务) -- --2)管理员查询已有的etmem工程 -+1)管理员创建etmem的project/engine/task(一个工程可包含多个etmem engine,一个engine可以包含多个任务) - --3)管理员删除已有的etmem工程(删除工程前,会自动先停止该工程中的所有任务) -+2)管理员删除已有的etmem project/engine/task(删除工程前,会自动先停止该工程中的所有任务) - - #### 使用方法 - --通过etmem二进制执行工程创建/删除/查询操作,前提是服务端已经成功运行,并且配置文件(e.g. /etc/etmem/example_conf.yaml)内容正确。 -+运行etmem二进制,通过第二个参数指定为obj,来进行创建或删除动作,对project/engine/task则是通过配置文件中配置的内容来进行识别和区分。前提是etmem配置文件已配置正确,etmemd进程已启动。 - --添加工程: -+添加对象: - --etmem project add -n test -f /etc/etmem/example_conf.yaml -s etmemd_socket -+etmem obj add -f /etc/example_config.yaml -s etmemd_socket - --删除工程: -+删除对象: - --etmem project del -n test -s etmemd_socket -- --查询工程: -- --etmem project show -s etmemd_socket -+etmem obj del -f /etc/example_config.yaml -s etmemd_socket - - 打印帮助: - --etmem project help -+etmem obj help - - #### 帮助信息 - - Usage: -- etmem project add [options] -- etmem project del [options] -- etmem project show -- etmem project help - -- Options: -- -f|--file Add configuration file -- -n|--name Add project name -- -s|--sock Socket name to connect -+etmem obj add [options] - -- Notes: -- \1. Project name and socket name must be given when execute add or del option. -- \2. Configuration file must be given when execute add option. -- \3. Socket name must be given when execute show option. -+etmem obj del [options] - --#### 命令行参数说明 -+etmem obj help - --add命令: -+Options: - --| 参数 | 参数含义 | 是否必须 | 是否有参数 | 示例说明 | --| ------------ | ------------------------------------------------------------ | -------- | ---------- | -------------------------------------------------------- | --| -n或--name | 指定project名称 | 是 | 是 | project名称,与配置文件一一对应 | --| -f或--file | 指定project的配置文件 | 是 | 是 | 需要指定路径名称 | --| -s或--socket | 与etmemd服务端通信的socket名称,需要与etmemd启动时指定的保持一致 | 是 | 是 | 必须配置,在有多个etmemd时,由管理员选择与哪个etmemd通信 | -+-f|\-\-file Add configuration file - --del命令: -+-s|\-\-socket Socket name to connect - --| 参数 | 参数含义 | 是否必须 | 是否有参数 | 示例说明 | --| ------------ | ------------------------------------------------------------ | -------- | ---------- | -------------------------------------------------------- | --| -n或--name | 指定project名称 | 是 | 是 | project名称,与配置文件一一对应 | --| -s或--socket | 与etmemd服务端通信的socket名称,需要与etmemd启动时指定的保持一致 | 是 | 是 | 必须配置,在有多个etmemd时,由管理员选择与哪个etmemd通信 | -+Notes: -+ -+1. Configuration file must be given. -+ -+#### 命令行参数说明 - --show命令: - - | 参数 | 参数含义 | 是否必须 | 是否有参数 | 示例说明 | - | ------------ | ------------------------------------------------------------ | -------- | ---------- | -------------------------------------------------------- | --| -s或--socket | 与etmemd服务端通信的socket名称,需要与etmemd启动时指定的保持一致 | 是 | 是 | 必须配置,在有多个etmemd时,由管理员选择与哪个etmemd通信 | -+| -f或\-\-file | 指定对象的配置文件 | add,del子命令必须包含 | 是 | 需要指定路径名称 | -+| -s或\-\-socket | 与etmemd服务端通信的socket名称,需要与etmemd启动时指定的保持一致 | add,del子命令必须包含 | 是 | 必须配置,在有多个etmemd时,由管理员选择与哪个etmemd通信 | - --### etmem任务启动/停止 -+### etmem任务启动/停止/查询 - - #### 场景描述 - --在已经通过etmem project add添加工程之后,在还未调用etmem project del删除工程之前,可以对etmem的工程进行启动和停止。 -+在已经通过etmem obj add添加工程之后,在还未调用etmem obj del删除工程之前,可以对etmem的工程进行启动和停止。 - - 1)管理员启动已添加的工程 - - 2)管理员停止已启动的工程 - --在管理员调用project del删除工程时,如果工程已经启动,则会自动停止。 -+在管理员调用obj del删除工程时,如果工程已经启动,则会自动停止。 - - #### 使用方法 - --通过etmem二进制执行任务启动/停止操作,前提是服务端已经成功运行,配置文件(e.g. /etc/etmem/example_conf.yaml)内容正确,且etmem工程已经创建。 -+对于已经添加成功的工程,可以通过etmem project的命令来控制工程的启动和停止,命令示例如下: - - 启动工程 - --etmem migrate start -n test -s etmemd_socket -+etmem project start -n test -s etmemd_socket - - 停止工程 - --etmem migrate stop -n test -s etmemd_socket -+etmem project stop -n test -s etmemd_socket -+ -+查询工程 -+ -+etmem project show -n test -s etmemd_socket - - 打印帮助 - --etmem migrate help -+etmem project help - - #### 帮助信息 - - Usage: -- etmem migrate start [options] -- etmem migrate stop [options] -- etmem migrate help - -- Options: -- -n|--name Add project name -- -s|--sock Socket name to connect -+etmem project start [options] -+ -+etmem project stop [options] -+ -+etmem project show [options] -+ -+etmem project help -+ -+Options: -+ -+-n|\-\-name Add project name -+ -+-s|\-\-socket Socket name to connect -+ -+Notes: - -- Notes: -- Project name and socket name must be given when execute start or stop option. -+1. Project name and socket name must be given when execute add or del option. -+ -+2. Socket name must be given when execute show option. - - #### 命令行参数说明 - - | 参数 | 参数含义 | 是否必须 | 是否有参数 | 示例说明 | - | ------------ | ------------------------------------------------------------ | -------- | ---------- | -------------------------------------------------------- | --| -n或--name | 指定project名称 | 是 | 是 | project名称,与配置文件一一对应 | --| -s或--socket | 与etmemd服务端通信的socket名称,需要与etmemd启动时指定的保持一致 | 是 | 是 | 必须配置,在有多个etmemd时,由管理员选择与哪个etmemd通信 | -+| -n或\-\-name | 指定project名称 | start,stop,show子命令必须包含 | 是 | project名称,与配置文件一一对应 | -+| -s或\-\-socket | 与etmemd服务端通信的socket名称,需要与etmemd启动时指定的保持一致 | start,stop,show子命令必须包含 | 是 | 必须配置,在有多个etmemd时,由管理员选择与哪个etmemd通信 | -+ -+### etmem支持随系统自启动 -+ -+#### 场景描述 -+ -+etmemd支持由用户配置systemd配置文件后,以fork模式作为systemd服务被拉起运行 -+ -+#### 使用方法 -+ -+编写service配置文件,来启动etmemd,必须使用-m参数来指定此模式,例如 -+ -+etmemd -l 0 -s etmemd_socket -m -+ -+#### 帮助信息 -+ -+options: -+ -+-l|\-\-log-level Log level -+ -+-s|\-\-socket Socket name to listen to -+ -+-m|\-\-mode-systemctl mode used to start(systemctl) -+ -+-h|\-\-help Show this message -+ -+#### 命令行参数说明 -+| 参数 | 参数含义 | 是否必须 | 是否有参数 | 参数范围 | 实例说明 | -+|----------------|------------|------|-------|------|-----------| -+| -l或\-\-log-level | etmemd日志级别 | 否 | 是 | 0~3 | 0:debug级别;1:info级别;2:warning级别;3:error级别;只有大于等于配置的级别才会打印到/var/log/message文件中| -+| -s或\-\-socket |etmemd监听的名称,用于与客户端交互 | 是 | 是| 107个字符之内的字符串| 指定服务端监听的名称| -+|-m或\-\-mode-systemctl | etmemd作为service被拉起时,命令中需要指定此参数来支持 | 否 | 否 | NA | NA | -+| -h或\-\-help | 帮助信息 | 否 |否 |NA |执行时带有此参数会打印后退出| -+ -+ -+ -+ -+### etmem支持第三方内存扩展策略 -+ -+#### 场景描述 -+ -+etmem支持用户注册第三方内存扩展策略,同时提供扫描模块动态库,运行时通过第三方策略淘汰算法淘汰内存。 -+ -+用户使用etmem所提供的扫描模块动态库并实现对接etmem所需要的结构体中的接口 -+ -+#### 使用方法 -+ -+用户使用自己实现的第三方扩展淘汰策略,主要需要按下面步骤进行实现和操作: -+ -+1. 按需调用扫描模块提供的扫描接口, -+ -+2. 按照etmem头文件中提供的函数模板来实现各个接口,最终封装成结构体 -+ -+3. 编译出第三方扩展淘汰策略的动态库 -+ -+4. 在配置文件中按要求声明类型为thirdparty的engine -+ -+5. 将动态库的名称和接口结构体的名称按要求填入配置文件中task对应的字段 -+ -+其他操作步骤与使用etmem的其他engine类似 -+ -+接口结构体模板 -+ -+struct engine_ops { -+ -+/* 针对引擎私有参数的解析,如果有,需要实现,否则置NULL */ -+ -+int (*fill_eng_params)(GKeyFile *config, struct engine *eng); -+ -+/* 针对引擎私有参数的清理,如果有,需要实现,否则置NULL */ -+ -+void (*clear_eng_params)(struct engine *eng); -+ -+/* 针对任务私有参数的解析,如果有,需要实现,否则置NULL */ -+ -+int (*fill_task_params)(GKeyFile *config, struct task *task); -+ -+/* 针对任务私有参数的清理,如果有,需要实现,否则置NULL */ -+ -+void (*clear_task_params)(struct task *tk); -+ -+/* 启动任务的接口 */ -+ -+int (*start_task)(struct engine *eng, struct task *tk); -+ -+/* 停止任务的接口 */ -+ -+void (*stop_task)(struct engine *eng, struct task *tk); -+ -+/* 填充pid相关私有参数 */ -+ -+int (*alloc_pid_params)(struct engine *eng, struct task_pid **tk_pid); -+ -+/* 销毁pid相关私有参数 */ -+ -+void (*free_pid_params)(struct engine *eng, struct task_pid **tk_pid); -+ -+/* 第三方策略自身所需要的私有命令支持,如果没有,置为NULL */ -+ -+int (*eng_mgt_func)(struct engine *eng, struct task *tk, char *cmd, int fd); -+ -+}; -+ -+配置文件示例如下所示,具体含义请参考配置文件说明章节: -+ -+#thirdparty -+ -+[engine] -+ -+name=thirdparty -+ -+project=test -+ -+eng_name=my_engine -+ -+libname=/user/lib/etmem_fetch/code_test/my_engine.so -+ -+ops_name=my_engine_ops -+ -+engine_private_key=engine_private_value -+ -+[task] -+ -+project=test -+ -+engine=my_engine -+ -+name=background1 -+ -+type=pid -+ -+value=1798245 -+ -+task_private_key=task_private_value -+ -+ **注意** : -+ -+用户需使用etmem所提供的扫描模块动态库并实现对接etmem所需要的结构体中的接口 -+ -+eng_mgt_func接口中的fd不能写入0xff和0xfe字 -+ -+支持在一个工程内添加多个不同的第三方策略动态库,以配置文件中的eng_name来区分 -+ -+### etmem支持使用AEP进行内存扩展 -+ -+#### 场景描述 -+ -+使用etmem组件包,使能内存分级扩展至AEP的通路。 -+ -+在节点内对虚拟机的大页进行扫描,并通过cslide引擎进行策略淘汰,将冷内存搬迁至AEP中 -+ -+#### 使用方法 -+ -+使用cslide引擎进行内存扩展,参数示例如下,具体参数含义请参考配置文件说明章节 -+ -+#cslide -+ -+[engine] -+ -+name=cslide -+ -+project=test -+ -+node_pair=2,0;3,1 -+ -+hot_threshold=1 -+ -+node_mig_quota=1024 -+ -+node_hot_reserve=1024 -+ -+[task] -+ -+project=test -+ -+engine=cslide -+ -+name=background1 -+ -+type=pid -+ -+value=1823197 -+ -+vm_flags=ht -+ -+anon_only=no -+ -+ign_host=no -+ -+ **注意** :禁止并发扫描同一个进程 -+ -+同时,此cslide策略支持私有的命令 -+ -+ -+- showtaskpages -+- showhostpages -+ -+针对使用此策略引擎的engine和engine所有的task,可以通过这两个命令分别查看task相关的页面访问情况和虚拟机的host上系统大页的使用情况。 -+ -+示例命令如下: -+ -+etmem engine showtaskpages <-t task_name> -n proj_name -e cslide -s etmemd_socket -+ -+etmem engine showhostpages -n proj_name -e cslide -s etmemd_socket -+ -+ **注意** :showtaskpages和showhostpages仅支持引擎使用cslide的场景 -+ -+#### 命令行参数说明 -+| 参数 | 参数含义 | 是否必须 | 是否有参数 | 实例说明 | -+|----|------|------|-------|------| -+|-n或\-\-proj_name| 指定project的名字| 是| 是| 指定已经存在,所需要执行的project的名字| -+|-s或\-\-socket| 与etmemd服务端通信的socket名称,需要与etmemd启动时指定的保持一致| 是| 是| 必须配置,在有多个etmemd时,由管理员选择与哪个etmemd通信| -+|-e或\-\-engine| 指定执行的引擎的名字| 是| 是| 指定已经存在的,所需要执行的引擎的名字| -+|-t或\-\-task_name| 指定执行的任务的名字| 否| 是| 指定已经存在的,所需要执行的任务的名字| - - ## 参与贡献 - - 1. Fork本仓库 - 2. 新建个人分支 - 3. 提交代码 --4. 新建Pull Request -+4. 新建Pull Request -\ No newline at end of file --- -2.27.0 - diff --git a/0044-etmem-cleancode.patch b/0044-etmem-cleancode.patch deleted file mode 100644 index 8cbfdcb..0000000 --- a/0044-etmem-cleancode.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 85a0e330d50c1546805c68cd621d1d85b5d08489 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Tue, 10 Aug 2021 11:13:06 +0800 -Subject: [PATCH 44/50] etmem: cleancode - -1. group_name for task_of_group and engine_of_group is defined as const, so add const -to group_name in function definition -2. pagesize in init_g_page_size is assigned with a value following init_g_page_size -assigned with initial value -1. Remove redundant initialization. - -Signed-off-by: Kemeng Shi ---- - src/etmemd_src/etmemd_project.c | 5 +++-- - src/etmemd_src/etmemd_scan.c | 2 +- - 2 files changed, 4 insertions(+), 3 deletions(-) - -diff --git a/src/etmemd_src/etmemd_project.c b/src/etmemd_src/etmemd_project.c -index decae76..53ef567 100644 ---- a/src/etmemd_src/etmemd_project.c -+++ b/src/etmemd_src/etmemd_project.c -@@ -130,7 +130,8 @@ static enum opt_result project_of_group(GKeyFile *config, const char *group_name - return OPT_SUCCESS; - } - --static enum opt_result engine_of_group(GKeyFile *config, char *group_name, struct project *proj, struct engine **eng) -+static enum opt_result engine_of_group(GKeyFile *config, const char *group_name, -+ struct project *proj, struct engine **eng) - { - char *eng_name = NULL; - enum opt_result ret; -@@ -154,7 +155,7 @@ static enum opt_result engine_of_group(GKeyFile *config, char *group_name, struc - return OPT_SUCCESS; - } - --static enum opt_result task_of_group(GKeyFile *config, char *group_name, -+static enum opt_result task_of_group(GKeyFile *config, const char *group_name, - struct project *proj, struct engine *eng, struct task **tk) - { - char *task_name = NULL; -diff --git a/src/etmemd_src/etmemd_scan.c b/src/etmemd_src/etmemd_scan.c -index 3238668..0fb4fe6 100644 ---- a/src/etmemd_src/etmemd_scan.c -+++ b/src/etmemd_src/etmemd_scan.c -@@ -70,7 +70,7 @@ static unsigned int get_page_shift(long pagesize) - int init_g_page_size(void) - { - unsigned int page_shift; -- long pagesize = -1; -+ long pagesize; - - pagesize = sysconf(_SC_PAGESIZE); - if (pagesize == -1) { --- -2.27.0 - diff --git a/0045-add-dram_percent-to-etmem.patch b/0045-add-dram_percent-to-etmem.patch deleted file mode 100644 index a7cad10..0000000 --- a/0045-add-dram_percent-to-etmem.patch +++ /dev/null @@ -1,520 +0,0 @@ -From 6ef46195753a4f383e931b7267cebedc40e756c5 Mon Sep 17 00:00:00 2001 -From: liubo -Date: Wed, 18 Aug 2021 10:22:50 +0800 -Subject: [PATCH 45/50] add dram_percent to etmem - ---- - inc/etmemd_inc/etmemd_common.h | 9 ++++ - inc/etmemd_inc/etmemd_exp.h | 5 ++ - inc/etmemd_inc/etmemd_migrate.h | 3 +- - inc/etmemd_inc/etmemd_scan.h | 5 +- - inc/etmemd_inc/etmemd_slide.h | 1 + - src/etmemd_src/etmemd_common.c | 94 +++++++++++++++++++++++++++++++++ - src/etmemd_src/etmemd_migrate.c | 46 ++++++++++++++++ - src/etmemd_src/etmemd_scan.c | 70 ++++++++++++++++++++++++ - src/etmemd_src/etmemd_slide.c | 83 +++++++++++++++++++++++++---- - 9 files changed, 304 insertions(+), 12 deletions(-) - -diff --git a/inc/etmemd_inc/etmemd_common.h b/inc/etmemd_inc/etmemd_common.h -index 4127ccf..8d18f8a 100644 ---- a/inc/etmemd_inc/etmemd_common.h -+++ b/inc/etmemd_inc/etmemd_common.h -@@ -20,10 +20,16 @@ - #include - - #define PROC_PATH "/proc/" -+#define STATUS_FILE "/status" -+#define SWAPIN "SwapIN" -+#define VMRSS "VmRSS" -+#define VMSWAP "VmSwap" - #define FILE_LINE_MAX_LEN 1024 - #define KEY_VALUE_MAX_LEN 64 - #define DECIMAL_RADIX 10 - #define ETMEMD_MAX_PARAMETER_NUM 6 -+#define BYTE_TO_KB(s) ((s) >> 10) -+#define KB_TO_BYTE(s) ((s) << 10) - - #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) - -@@ -48,11 +54,14 @@ int etmemd_parse_cmdline(int argc, char *argv[], bool *is_help); - bool check_str_format(char endptr); - int get_int_value(const char *val, int *value); - int get_unsigned_int_value(const char *val, unsigned int *value); -+int get_unsigned_long_value(const char *val, unsigned long *value); - void etmemd_safe_free(void **ptr); - - FILE *etmemd_get_proc_file(const char *pid, const char *file, int flags, const char *mode); - - int get_keyword_and_value(const char *str, char *key, char *val); -+unsigned long get_pagesize(void); -+int get_mem_from_proc_file(const char *pid, const char *file_name, unsigned long *data, const char *cmpstr); - - int dprintf_all(int fd, const char *format, ...); - -diff --git a/inc/etmemd_inc/etmemd_exp.h b/inc/etmemd_inc/etmemd_exp.h -index 8c57d9f..48a0018 100644 ---- a/inc/etmemd_inc/etmemd_exp.h -+++ b/inc/etmemd_inc/etmemd_exp.h -@@ -39,4 +39,9 @@ struct page_refs { - struct page_refs *next; /* point to next page */ - }; - -+struct page_sort { -+ struct page_refs **page_refs_sort; -+ struct page_refs **page_refs; -+ int loop; -+}; - #endif -diff --git a/inc/etmemd_inc/etmemd_migrate.h b/inc/etmemd_inc/etmemd_migrate.h -index db61c69..ef20bde 100644 ---- a/inc/etmemd_inc/etmemd_migrate.h -+++ b/inc/etmemd_inc/etmemd_migrate.h -@@ -17,6 +17,7 @@ - #define ETMEMD_MIGRATE_H - - #include "etmemd.h" -+#include "etmemd_task.h" - - #define COLD_PAGE "/swap_pages" - -@@ -26,5 +27,5 @@ - #define SWAP_ADDR_LEN 20 - - int etmemd_grade_migrate(const char* pid, const struct memory_grade *memory_grade); -- -+unsigned long check_should_migrate(const struct task_pid *tk_pid); - #endif -diff --git a/inc/etmemd_inc/etmemd_scan.h b/inc/etmemd_inc/etmemd_scan.h -index 09ad51c..9e5bcc4 100644 ---- a/inc/etmemd_inc/etmemd_scan.h -+++ b/inc/etmemd_inc/etmemd_scan.h -@@ -77,9 +77,12 @@ struct vmas *get_vmas_with_flags(const char *pid, char **vmflags_array, int vmfl - struct vmas *get_vmas(const char *pid); - - void clean_page_refs_unexpected(void *arg); -- - void clean_memory_grade_unexpected(void *arg); - -+void clean_page_sort_unexpected(void *arg); -+struct page_sort *alloc_page_sort(const struct task_pid *tk_pid); -+struct page_sort *sort_page_refs(struct page_refs **page_refs, const struct task_pid *tk_pid); -+ - struct page_refs *add_page_refs_into_memory_grade(struct page_refs *page_refs, struct page_refs **list); - int init_g_page_size(void); - int page_type_to_size(enum page_type type); -diff --git a/inc/etmemd_inc/etmemd_slide.h b/inc/etmemd_inc/etmemd_slide.h -index af48be7..93de502 100644 ---- a/inc/etmemd_inc/etmemd_slide.h -+++ b/inc/etmemd_inc/etmemd_slide.h -@@ -22,6 +22,7 @@ - struct slide_params { - struct task_executor *executor; - int t; /* watermark */ -+ uint8_t dram_percent; - }; - - int fill_engine_type_slide(struct engine *eng, GKeyFile *config); -diff --git a/src/etmemd_src/etmemd_common.c b/src/etmemd_src/etmemd_common.c -index 8aad0eb..4595499 100644 ---- a/src/etmemd_src/etmemd_common.c -+++ b/src/etmemd_src/etmemd_common.c -@@ -195,6 +195,19 @@ int get_unsigned_int_value(const char *val, unsigned int *value) - return 0; - } - -+int get_unsigned_long_value(const char *val, unsigned long *value) -+{ -+ char *pos = NULL; -+ -+ errno = 0; -+ *value = strtoul(val, &pos, DECIMAL_RADIX); -+ if (check_str_format(pos[0])) { -+ etmemd_log(ETMEMD_LOG_ERR, "invalid value, must be type of unsigned long.\n"); -+ return -1; -+ } -+ -+ return 0; -+} - void etmemd_safe_free(void **ptr) - { - if (ptr == NULL || *ptr == NULL) { -@@ -205,6 +218,36 @@ void etmemd_safe_free(void **ptr) - *ptr = NULL; - } - -+static int get_status_num(char *getline, char *value, size_t value_len) -+{ -+ size_t len = strlen(getline); -+ int start_cp_index = 0; -+ int end_cp_index = 0; -+ size_t i; -+ -+ for (i = 0; i < len; i++) { -+ if (isdigit(getline[i])) { -+ start_cp_index = i; -+ end_cp_index = start_cp_index; -+ break; -+ } -+ } -+ -+ for (; i < len; i++) { -+ if (!isdigit(getline[i])) { -+ end_cp_index = i - 1; -+ break; -+ } -+ } -+ -+ if (strncpy_s(value, value_len, getline + start_cp_index, end_cp_index - start_cp_index + 1) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "strncpy_s for result failed.\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ - static char *etmemd_get_proc_file_str(const char *pid, const char *file) - { - char *file_name = NULL; -@@ -398,3 +441,54 @@ int dprintf_all(int fd, const char *format, ...) - va_end(args_in); - return 0; - } -+ -+int get_mem_from_proc_file(const char *pid, const char *file_name, unsigned long *data, const char *cmpstr) -+{ -+ FILE *file = NULL; -+ char value[KEY_VALUE_MAX_LEN] = {}; -+ char get_line[FILE_LINE_MAX_LEN] = {}; -+ unsigned long val; -+ int ret = -1; -+ -+ file = etmemd_get_proc_file(pid, file_name, 0, "r"); -+ if (file == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "cannot open %s for pid %s\n", file_name, pid); -+ return ret; -+ } -+ -+ while (fgets(get_line, FILE_LINE_MAX_LEN - 1, file) != NULL) { -+ if (strstr(get_line, cmpstr) == NULL) { -+ continue; -+ } -+ -+ if (get_status_num(get_line, value, KEY_VALUE_MAX_LEN) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get mem from /proc/%s/%s fail\n", pid, file_name); -+ break; -+ } -+ -+ if (get_unsigned_long_value(value, &val) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get value with strtoul fail.\n"); -+ break; -+ } -+ -+ *data = val; -+ ret = 0; -+ break; -+ } -+ -+ fclose(file); -+ return ret; -+} -+ -+unsigned long get_pagesize(void) -+{ -+ long pagesize; -+ -+ pagesize = sysconf(_SC_PAGESIZE); -+ if (pagesize == -1) { -+ etmemd_log(ETMEMD_LOG_ERR, "get pageszie fail,error: %d\n", errno); -+ return -1; -+ } -+ -+ return (unsigned long)pagesize; -+} -diff --git a/src/etmemd_src/etmemd_migrate.c b/src/etmemd_src/etmemd_migrate.c -index 2f29f31..639d570 100644 ---- a/src/etmemd_src/etmemd_migrate.c -+++ b/src/etmemd_src/etmemd_migrate.c -@@ -20,6 +20,7 @@ - #include "etmemd.h" - #include "etmemd_migrate.h" - #include "etmemd_common.h" -+#include "etmemd_slide.h" - #include "etmemd_log.h" - - static char *get_swap_string(struct page_refs **page_refs, int batchsize) -@@ -113,3 +114,48 @@ int etmemd_grade_migrate(const char *pid, const struct memory_grade *memory_grad - return ret; - } - -+unsigned long check_should_migrate(const struct task_pid *tk_pid) -+{ -+ int ret = -1; -+ unsigned long vm_rss; -+ unsigned long vm_swap; -+ unsigned long vm_cmp; -+ unsigned long need_to_swap_page_num; -+ char pid_str[PID_STR_MAX_LEN] = {0}; -+ unsigned long pagesize; -+ struct slide_params *slide_params = NULL; -+ -+ if (snprintf_s(pid_str, PID_STR_MAX_LEN, PID_STR_MAX_LEN - 1, "%u", tk_pid->pid) <= 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "snprintf pid fail %u", tk_pid->pid); -+ return 0; -+ } -+ -+ ret = get_mem_from_proc_file(pid_str, STATUS_FILE, &vm_rss, VMRSS); -+ if (ret != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get vmrss %s fail", pid_str); -+ return 0; -+ } -+ -+ ret = get_mem_from_proc_file(pid_str, STATUS_FILE, &vm_swap, VMSWAP); -+ if (ret != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get swapout %s fail", pid_str); -+ return 0; -+ } -+ -+ slide_params = (struct slide_params *)tk_pid->tk->params; -+ if (slide_params == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "slide params is null"); -+ return 0; -+ } -+ -+ vm_cmp = (vm_rss + vm_swap) / 100 * slide_params->dram_percent; -+ if (vm_cmp > vm_rss) { -+ etmemd_log(ETMEMD_LOG_DEBUG, "migrate too much, stop migrate this time\n"); -+ return 0; -+ } -+ -+ pagesize = get_pagesize(); -+ need_to_swap_page_num = KB_TO_BYTE(vm_rss - vm_cmp) / pagesize; -+ -+ return need_to_swap_page_num; -+} -diff --git a/src/etmemd_src/etmemd_scan.c b/src/etmemd_src/etmemd_scan.c -index 0fb4fe6..fec6373 100644 ---- a/src/etmemd_src/etmemd_scan.c -+++ b/src/etmemd_src/etmemd_scan.c -@@ -24,6 +24,7 @@ - #include "etmemd_project.h" - #include "etmemd_engine.h" - #include "etmemd_common.h" -+#include "etmemd_slide.h" - #include "etmemd_log.h" - #include "securec.h" - -@@ -819,6 +820,46 @@ void clean_memory_grade_unexpected(void *arg) - return; - } - -+void clean_page_sort_unexpected(void *arg) -+{ -+ struct page_sort **msg = (struct page_sort **)arg; -+ -+ if (*msg == NULL) { -+ return; -+ } -+ -+ for (int i = 0; i < (*msg)->loop + 1; i++) { -+ clean_page_refs_unexpected(&((*msg)->page_refs_sort)[i]); -+ } -+ -+ free(*msg); -+ *msg = NULL; -+ -+ return; -+} -+ -+struct page_sort *alloc_page_sort(const struct task_pid *tpid) -+{ -+ struct page_sort *page_sort = NULL; -+ -+ page_sort = (struct page_sort *)calloc(1, sizeof(struct page_sort)); -+ if (page_sort == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "calloc page sort failed.\n"); -+ return NULL; -+ } -+ -+ page_sort->loop = tpid->tk->eng->proj->loop; -+ -+ page_sort->page_refs_sort = (struct page_refs **)calloc((tpid->tk->eng->proj->loop + 1), sizeof(struct page_refs *)); -+ if (page_sort->page_refs_sort == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "calloc page refs sort failed.\n"); -+ free(page_sort); -+ return NULL; -+ } -+ -+ return page_sort; -+} -+ - struct page_refs *add_page_refs_into_memory_grade(struct page_refs *page_refs, struct page_refs **list) - { - struct page_refs *tmp = NULL; -@@ -851,3 +892,32 @@ void etmemd_scan_exit(void) - { - g_exp_scan_inited = false; - } -+ -+/* Move the colder pages by sorting page refs. -+ * Use original page_refs if dram_percent is not set. -+ * But, use the sorting result of page_refs, if dram_percent is set to (0, 100] */ -+struct page_sort *sort_page_refs(struct page_refs **page_refs, const struct task_pid *tpid) -+{ -+ struct slide_params *slide_params = NULL; -+ struct page_sort *page_sort = NULL; -+ struct page_refs *page_next = NULL; -+ -+ page_sort = alloc_page_sort(tpid); -+ if (page_sort == NULL) -+ return NULL; -+ -+ slide_params = (struct slide_params *)tpid->tk->params; -+ if (slide_params == NULL || slide_params->dram_percent == 0) { -+ page_sort->page_refs = page_refs; -+ return page_sort; -+ } -+ -+ while (*page_refs != NULL) { -+ page_next = (*page_refs)->next; -+ (*page_refs)->next = (page_sort->page_refs_sort[(*page_refs)->count]); -+ (page_sort->page_refs_sort[(*page_refs)->count]) = *page_refs; -+ *page_refs = page_next; -+ } -+ -+ return page_sort; -+} -diff --git a/src/etmemd_src/etmemd_slide.c b/src/etmemd_src/etmemd_slide.c -index 96d3dcc..a024178 100644 ---- a/src/etmemd_src/etmemd_slide.c -+++ b/src/etmemd_src/etmemd_slide.c -@@ -28,12 +28,15 @@ - #include "etmemd_pool_adapter.h" - #include "etmemd_file.h" - --static struct memory_grade *slide_policy_interface(struct page_refs **page_refs, void *params) -+static struct memory_grade *slide_policy_interface(struct page_sort **page_sort, const struct task_pid *tpid) - { -- struct slide_params *slide_params = (struct slide_params *)params; -+ struct slide_params *slide_params = (struct slide_params *)(tpid->tk->params); -+ struct page_refs **page_refs = NULL; - struct memory_grade *memory_grade = NULL; -+ unsigned long need_2_swap_num; -+ volatile uint64_t count = 0; - -- if (params == NULL) { -+ if (slide_params == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "cannot get params for slide\n"); - return NULL; - } -@@ -44,14 +47,41 @@ static struct memory_grade *slide_policy_interface(struct page_refs **page_refs, - return NULL; - } - -- while (*page_refs != NULL) { -- if ((*page_refs)->count >= slide_params->t) { -- *page_refs = add_page_refs_into_memory_grade(*page_refs, &memory_grade->hot_pages); -- continue; -+ if (slide_params->dram_percent == 0) { -+ page_refs = (*page_sort)->page_refs; -+ -+ while (*page_refs != NULL) { -+ if ((*page_refs)->count >= slide_params->t) { -+ *page_refs = add_page_refs_into_memory_grade(*page_refs, &memory_grade->hot_pages); -+ continue; -+ } -+ *page_refs = add_page_refs_into_memory_grade(*page_refs, &memory_grade->cold_pages); -+ } -+ -+ return memory_grade; -+ } -+ -+ need_2_swap_num = check_should_migrate(tpid); -+ if (need_2_swap_num == 0) -+ goto count_out; -+ -+ for (int i = 0; i < tpid->tk->eng->proj->loop + 1; i++) { -+ page_refs = &((*page_sort)->page_refs_sort[i]); -+ -+ while (*page_refs != NULL) { -+ if ((*page_refs)->count >= slide_params->t) { -+ *page_refs = add_page_refs_into_memory_grade(*page_refs, &memory_grade->hot_pages); -+ goto count_out; -+ } -+ -+ *page_refs = add_page_refs_into_memory_grade(*page_refs, &memory_grade->cold_pages); -+ count++; -+ if (count >= need_2_swap_num) -+ goto count_out; - } -- *page_refs = add_page_refs_into_memory_grade(*page_refs, &memory_grade->cold_pages); - } - -+count_out: - return memory_grade; - } - -@@ -80,17 +110,32 @@ static void *slide_executor(void *arg) - struct task_pid *tk_pid = (struct task_pid *)arg; - struct page_refs *page_refs = NULL; - struct memory_grade *memory_grade = NULL; -+ struct page_sort *page_sort = 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); - - page_refs = etmemd_do_scan(tk_pid, tk_pid->tk); -- if (page_refs != NULL) { -- memory_grade = slide_policy_interface(&page_refs, tk_pid->tk->params); -+ if (page_refs == NULL) { -+ etmemd_log(ETMEMD_LOG_WARN, "pid %u cannot get page refs\n", tk_pid->pid); -+ goto scan_out; - } - -+ page_sort = sort_page_refs(&page_refs, tk_pid); -+ if (page_sort == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "failed to alloc memory for page sort.", tk_pid->pid); -+ goto scan_out; -+ } -+ -+ memory_grade = slide_policy_interface(&page_sort, tk_pid); -+ -+scan_out: -+ /* clean up page_sort linked array */ -+ pthread_cleanup_pop(1); -+ - /* 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, -@@ -131,8 +176,26 @@ static int fill_task_threshold(void *obj, void *val) - return 0; - } - -+static int fill_task_dram_percent(void *obj, void *val) -+{ -+ struct slide_params *params = (struct slide_params *)obj; -+ int value = parse_to_int(val); -+ -+ if (value <= 0 || value > 100) { -+ etmemd_log(ETMEMD_LOG_WARN, -+ "dram_percent %d is abnormal, the reasonable range is (0, 100],\ -+ cancle the dram_percent parameter of current task\n", value); -+ value = 0; -+ } -+ -+ params->dram_percent = value; -+ -+ return 0; -+} -+ - static struct config_item g_slide_task_config_items[] = { - {"T", INT_VAL, fill_task_threshold, false}, -+ {"dram_percent", INT_VAL, fill_task_dram_percent, true}, - }; - - static int slide_fill_task(GKeyFile *config, struct task *tk) --- -2.27.0 - diff --git a/0046-Fix-memory-leak-in-slide-engine.patch b/0046-Fix-memory-leak-in-slide-engine.patch deleted file mode 100644 index 5b920f5..0000000 --- a/0046-Fix-memory-leak-in-slide-engine.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 10883d861456fe5daf7e664c0311abed754da8fd Mon Sep 17 00:00:00 2001 -From: liubo -Date: Mon, 27 Sep 2021 15:58:11 +0800 -Subject: [PATCH 46/50] Fix memory leak in slide engine, remove project show - cmd error msg. - -If a process has multiple subprocess, release the task_pid resource of -the subprocess corresponding to the task when project stops. - -Remove project show error message if show cmd is executed successfully. - -Signed-off-by: liubo ---- - src/etmemd_src/etmemd_project.c | 7 ++++--- - src/etmemd_src/etmemd_slide.c | 1 + - 2 files changed, 5 insertions(+), 3 deletions(-) - -diff --git a/src/etmemd_src/etmemd_project.c b/src/etmemd_src/etmemd_project.c -index 53ef567..f7f1885 100644 ---- a/src/etmemd_src/etmemd_project.c -+++ b/src/etmemd_src/etmemd_project.c -@@ -611,11 +611,12 @@ enum opt_result etmemd_project_show(const char *project_name, int sock_fd) - - if (!exists) { - if (project_name == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "no project exists\n"); -+ etmemd_log(ETMEMD_LOG_DEBUG, "no project exists\n"); -+ dprintf_all(sock_fd, "no project exists\n\n"); - } else { -- etmemd_log(ETMEMD_LOG_ERR, "project: project %s is not existed\n\n", project_name); -+ etmemd_log(ETMEMD_LOG_DEBUG, "project: project %s is not existed\n\n", project_name); -+ dprintf_all(sock_fd, "project: project %s is not existed\n\n", project_name); - } -- return OPT_PRO_NOEXIST; - } - - return OPT_SUCCESS; -diff --git a/src/etmemd_src/etmemd_slide.c b/src/etmemd_src/etmemd_slide.c -index a024178..45db00a 100644 ---- a/src/etmemd_src/etmemd_slide.c -+++ b/src/etmemd_src/etmemd_slide.c -@@ -227,6 +227,7 @@ free_params: - - static void slide_clear_task(struct task *tk) - { -+ etmemd_free_task_pids(tk); - free(tk->params); - tk->params = NULL; - } --- -2.27.0 - diff --git a/0047-move-all-the-files-to-sub-directory-of-etmem.patch b/0047-move-all-the-files-to-sub-directory-of-etmem.patch deleted file mode 100644 index f010a7d..0000000 --- a/0047-move-all-the-files-to-sub-directory-of-etmem.patch +++ /dev/null @@ -1,335 +0,0 @@ -From b89f142798ebb23ad58ad3a0d1fe34f74e7801a6 Mon Sep 17 00:00:00 2001 -From: louhongxiang -Date: Thu, 30 Sep 2021 14:15:50 +0800 -Subject: [PATCH 47/50] move all the files to sub directory of etmem. - ---- - CMakeLists.txt => etmem/CMakeLists.txt | 0 - {conf => etmem/conf}/example_conf.yaml | 0 - {inc => etmem/inc}/etmem_inc/etmem.h | 0 - {inc => etmem/inc}/etmem_inc/etmem_common.h | 0 - {inc => etmem/inc}/etmem_inc/etmem_engine.h | 0 - {inc => etmem/inc}/etmem_inc/etmem_obj.h | 0 - {inc => etmem/inc}/etmem_inc/etmem_project.h | 0 - {inc => etmem/inc}/etmem_inc/etmem_rpc.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_common.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_cslide.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_engine.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_engine_exp.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_exp.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_file.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_log.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_migrate.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_pool_adapter.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_project.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_project_exp.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_rpc.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_scan.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_scan_exp.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_scan_export.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_slide.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_task.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_task_exp.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_thirdparty.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_thirdparty_export.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_threadpool.h | 0 - {inc => etmem/inc}/etmemd_inc/etmemd_threadtimer.h | 0 - {src => etmem/src}/etmem_src/etmem.c | 0 - {src => etmem/src}/etmem_src/etmem_common.c | 0 - {src => etmem/src}/etmem_src/etmem_engine.c | 0 - {src => etmem/src}/etmem_src/etmem_obj.c | 0 - {src => etmem/src}/etmem_src/etmem_project.c | 0 - {src => etmem/src}/etmem_src/etmem_rpc.c | 0 - {src => etmem/src}/etmemd_src/etmemd.c | 0 - {src => etmem/src}/etmemd_src/etmemd_common.c | 0 - {src => etmem/src}/etmemd_src/etmemd_cslide.c | 0 - {src => etmem/src}/etmemd_src/etmemd_engine.c | 0 - {src => etmem/src}/etmemd_src/etmemd_file.c | 0 - {src => etmem/src}/etmemd_src/etmemd_log.c | 0 - {src => etmem/src}/etmemd_src/etmemd_migrate.c | 0 - {src => etmem/src}/etmemd_src/etmemd_pool_adapter.c | 0 - {src => etmem/src}/etmemd_src/etmemd_project.c | 0 - {src => etmem/src}/etmemd_src/etmemd_rpc.c | 0 - {src => etmem/src}/etmemd_src/etmemd_scan.c | 0 - {src => etmem/src}/etmemd_src/etmemd_scan.version | 0 - {src => etmem/src}/etmemd_src/etmemd_slide.c | 0 - {src => etmem/src}/etmemd_src/etmemd_task.c | 0 - {src => etmem/src}/etmemd_src/etmemd_thirdparty.c | 0 - {src => etmem/src}/etmemd_src/etmemd_threadpool.c | 0 - {src => etmem/src}/etmemd_src/etmemd_threadtimer.c | 0 - 56 files changed, 0 insertions(+), 0 deletions(-) - rename CMakeLists.txt => etmem/CMakeLists.txt (100%) - rename {conf => etmem/conf}/example_conf.yaml (100%) - rename {inc => etmem/inc}/etmem_inc/etmem.h (100%) - rename {inc => etmem/inc}/etmem_inc/etmem_common.h (100%) - rename {inc => etmem/inc}/etmem_inc/etmem_engine.h (100%) - rename {inc => etmem/inc}/etmem_inc/etmem_obj.h (100%) - rename {inc => etmem/inc}/etmem_inc/etmem_project.h (100%) - rename {inc => etmem/inc}/etmem_inc/etmem_rpc.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_common.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_cslide.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_engine.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_engine_exp.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_exp.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_file.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_log.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_migrate.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_pool_adapter.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_project.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_project_exp.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_rpc.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_scan.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_scan_exp.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_scan_export.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_slide.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_task.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_task_exp.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_thirdparty.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_thirdparty_export.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_threadpool.h (100%) - rename {inc => etmem/inc}/etmemd_inc/etmemd_threadtimer.h (100%) - rename {src => etmem/src}/etmem_src/etmem.c (100%) - rename {src => etmem/src}/etmem_src/etmem_common.c (100%) - rename {src => etmem/src}/etmem_src/etmem_engine.c (100%) - rename {src => etmem/src}/etmem_src/etmem_obj.c (100%) - rename {src => etmem/src}/etmem_src/etmem_project.c (100%) - rename {src => etmem/src}/etmem_src/etmem_rpc.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_common.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_cslide.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_engine.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_file.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_log.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_migrate.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_pool_adapter.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_project.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_rpc.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_scan.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_scan.version (100%) - rename {src => etmem/src}/etmemd_src/etmemd_slide.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_task.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_thirdparty.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_threadpool.c (100%) - rename {src => etmem/src}/etmemd_src/etmemd_threadtimer.c (100%) - -diff --git a/CMakeLists.txt b/etmem/CMakeLists.txt -similarity index 100% -rename from CMakeLists.txt -rename to etmem/CMakeLists.txt -diff --git a/conf/example_conf.yaml b/etmem/conf/example_conf.yaml -similarity index 100% -rename from conf/example_conf.yaml -rename to etmem/conf/example_conf.yaml -diff --git a/inc/etmem_inc/etmem.h b/etmem/inc/etmem_inc/etmem.h -similarity index 100% -rename from inc/etmem_inc/etmem.h -rename to etmem/inc/etmem_inc/etmem.h -diff --git a/inc/etmem_inc/etmem_common.h b/etmem/inc/etmem_inc/etmem_common.h -similarity index 100% -rename from inc/etmem_inc/etmem_common.h -rename to etmem/inc/etmem_inc/etmem_common.h -diff --git a/inc/etmem_inc/etmem_engine.h b/etmem/inc/etmem_inc/etmem_engine.h -similarity index 100% -rename from inc/etmem_inc/etmem_engine.h -rename to etmem/inc/etmem_inc/etmem_engine.h -diff --git a/inc/etmem_inc/etmem_obj.h b/etmem/inc/etmem_inc/etmem_obj.h -similarity index 100% -rename from inc/etmem_inc/etmem_obj.h -rename to etmem/inc/etmem_inc/etmem_obj.h -diff --git a/inc/etmem_inc/etmem_project.h b/etmem/inc/etmem_inc/etmem_project.h -similarity index 100% -rename from inc/etmem_inc/etmem_project.h -rename to etmem/inc/etmem_inc/etmem_project.h -diff --git a/inc/etmem_inc/etmem_rpc.h b/etmem/inc/etmem_inc/etmem_rpc.h -similarity index 100% -rename from inc/etmem_inc/etmem_rpc.h -rename to etmem/inc/etmem_inc/etmem_rpc.h -diff --git a/inc/etmemd_inc/etmemd.h b/etmem/inc/etmemd_inc/etmemd.h -similarity index 100% -rename from inc/etmemd_inc/etmemd.h -rename to etmem/inc/etmemd_inc/etmemd.h -diff --git a/inc/etmemd_inc/etmemd_common.h b/etmem/inc/etmemd_inc/etmemd_common.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_common.h -rename to etmem/inc/etmemd_inc/etmemd_common.h -diff --git a/inc/etmemd_inc/etmemd_cslide.h b/etmem/inc/etmemd_inc/etmemd_cslide.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_cslide.h -rename to etmem/inc/etmemd_inc/etmemd_cslide.h -diff --git a/inc/etmemd_inc/etmemd_engine.h b/etmem/inc/etmemd_inc/etmemd_engine.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_engine.h -rename to etmem/inc/etmemd_inc/etmemd_engine.h -diff --git a/inc/etmemd_inc/etmemd_engine_exp.h b/etmem/inc/etmemd_inc/etmemd_engine_exp.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_engine_exp.h -rename to etmem/inc/etmemd_inc/etmemd_engine_exp.h -diff --git a/inc/etmemd_inc/etmemd_exp.h b/etmem/inc/etmemd_inc/etmemd_exp.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_exp.h -rename to etmem/inc/etmemd_inc/etmemd_exp.h -diff --git a/inc/etmemd_inc/etmemd_file.h b/etmem/inc/etmemd_inc/etmemd_file.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_file.h -rename to etmem/inc/etmemd_inc/etmemd_file.h -diff --git a/inc/etmemd_inc/etmemd_log.h b/etmem/inc/etmemd_inc/etmemd_log.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_log.h -rename to etmem/inc/etmemd_inc/etmemd_log.h -diff --git a/inc/etmemd_inc/etmemd_migrate.h b/etmem/inc/etmemd_inc/etmemd_migrate.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_migrate.h -rename to etmem/inc/etmemd_inc/etmemd_migrate.h -diff --git a/inc/etmemd_inc/etmemd_pool_adapter.h b/etmem/inc/etmemd_inc/etmemd_pool_adapter.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_pool_adapter.h -rename to etmem/inc/etmemd_inc/etmemd_pool_adapter.h -diff --git a/inc/etmemd_inc/etmemd_project.h b/etmem/inc/etmemd_inc/etmemd_project.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_project.h -rename to etmem/inc/etmemd_inc/etmemd_project.h -diff --git a/inc/etmemd_inc/etmemd_project_exp.h b/etmem/inc/etmemd_inc/etmemd_project_exp.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_project_exp.h -rename to etmem/inc/etmemd_inc/etmemd_project_exp.h -diff --git a/inc/etmemd_inc/etmemd_rpc.h b/etmem/inc/etmemd_inc/etmemd_rpc.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_rpc.h -rename to etmem/inc/etmemd_inc/etmemd_rpc.h -diff --git a/inc/etmemd_inc/etmemd_scan.h b/etmem/inc/etmemd_inc/etmemd_scan.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_scan.h -rename to etmem/inc/etmemd_inc/etmemd_scan.h -diff --git a/inc/etmemd_inc/etmemd_scan_exp.h b/etmem/inc/etmemd_inc/etmemd_scan_exp.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_scan_exp.h -rename to etmem/inc/etmemd_inc/etmemd_scan_exp.h -diff --git a/inc/etmemd_inc/etmemd_scan_export.h b/etmem/inc/etmemd_inc/etmemd_scan_export.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_scan_export.h -rename to etmem/inc/etmemd_inc/etmemd_scan_export.h -diff --git a/inc/etmemd_inc/etmemd_slide.h b/etmem/inc/etmemd_inc/etmemd_slide.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_slide.h -rename to etmem/inc/etmemd_inc/etmemd_slide.h -diff --git a/inc/etmemd_inc/etmemd_task.h b/etmem/inc/etmemd_inc/etmemd_task.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_task.h -rename to etmem/inc/etmemd_inc/etmemd_task.h -diff --git a/inc/etmemd_inc/etmemd_task_exp.h b/etmem/inc/etmemd_inc/etmemd_task_exp.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_task_exp.h -rename to etmem/inc/etmemd_inc/etmemd_task_exp.h -diff --git a/inc/etmemd_inc/etmemd_thirdparty.h b/etmem/inc/etmemd_inc/etmemd_thirdparty.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_thirdparty.h -rename to etmem/inc/etmemd_inc/etmemd_thirdparty.h -diff --git a/inc/etmemd_inc/etmemd_thirdparty_export.h b/etmem/inc/etmemd_inc/etmemd_thirdparty_export.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_thirdparty_export.h -rename to etmem/inc/etmemd_inc/etmemd_thirdparty_export.h -diff --git a/inc/etmemd_inc/etmemd_threadpool.h b/etmem/inc/etmemd_inc/etmemd_threadpool.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_threadpool.h -rename to etmem/inc/etmemd_inc/etmemd_threadpool.h -diff --git a/inc/etmemd_inc/etmemd_threadtimer.h b/etmem/inc/etmemd_inc/etmemd_threadtimer.h -similarity index 100% -rename from inc/etmemd_inc/etmemd_threadtimer.h -rename to etmem/inc/etmemd_inc/etmemd_threadtimer.h -diff --git a/src/etmem_src/etmem.c b/etmem/src/etmem_src/etmem.c -similarity index 100% -rename from src/etmem_src/etmem.c -rename to etmem/src/etmem_src/etmem.c -diff --git a/src/etmem_src/etmem_common.c b/etmem/src/etmem_src/etmem_common.c -similarity index 100% -rename from src/etmem_src/etmem_common.c -rename to etmem/src/etmem_src/etmem_common.c -diff --git a/src/etmem_src/etmem_engine.c b/etmem/src/etmem_src/etmem_engine.c -similarity index 100% -rename from src/etmem_src/etmem_engine.c -rename to etmem/src/etmem_src/etmem_engine.c -diff --git a/src/etmem_src/etmem_obj.c b/etmem/src/etmem_src/etmem_obj.c -similarity index 100% -rename from src/etmem_src/etmem_obj.c -rename to etmem/src/etmem_src/etmem_obj.c -diff --git a/src/etmem_src/etmem_project.c b/etmem/src/etmem_src/etmem_project.c -similarity index 100% -rename from src/etmem_src/etmem_project.c -rename to etmem/src/etmem_src/etmem_project.c -diff --git a/src/etmem_src/etmem_rpc.c b/etmem/src/etmem_src/etmem_rpc.c -similarity index 100% -rename from src/etmem_src/etmem_rpc.c -rename to etmem/src/etmem_src/etmem_rpc.c -diff --git a/src/etmemd_src/etmemd.c b/etmem/src/etmemd_src/etmemd.c -similarity index 100% -rename from src/etmemd_src/etmemd.c -rename to etmem/src/etmemd_src/etmemd.c -diff --git a/src/etmemd_src/etmemd_common.c b/etmem/src/etmemd_src/etmemd_common.c -similarity index 100% -rename from src/etmemd_src/etmemd_common.c -rename to etmem/src/etmemd_src/etmemd_common.c -diff --git a/src/etmemd_src/etmemd_cslide.c b/etmem/src/etmemd_src/etmemd_cslide.c -similarity index 100% -rename from src/etmemd_src/etmemd_cslide.c -rename to etmem/src/etmemd_src/etmemd_cslide.c -diff --git a/src/etmemd_src/etmemd_engine.c b/etmem/src/etmemd_src/etmemd_engine.c -similarity index 100% -rename from src/etmemd_src/etmemd_engine.c -rename to etmem/src/etmemd_src/etmemd_engine.c -diff --git a/src/etmemd_src/etmemd_file.c b/etmem/src/etmemd_src/etmemd_file.c -similarity index 100% -rename from src/etmemd_src/etmemd_file.c -rename to etmem/src/etmemd_src/etmemd_file.c -diff --git a/src/etmemd_src/etmemd_log.c b/etmem/src/etmemd_src/etmemd_log.c -similarity index 100% -rename from src/etmemd_src/etmemd_log.c -rename to etmem/src/etmemd_src/etmemd_log.c -diff --git a/src/etmemd_src/etmemd_migrate.c b/etmem/src/etmemd_src/etmemd_migrate.c -similarity index 100% -rename from src/etmemd_src/etmemd_migrate.c -rename to etmem/src/etmemd_src/etmemd_migrate.c -diff --git a/src/etmemd_src/etmemd_pool_adapter.c b/etmem/src/etmemd_src/etmemd_pool_adapter.c -similarity index 100% -rename from src/etmemd_src/etmemd_pool_adapter.c -rename to etmem/src/etmemd_src/etmemd_pool_adapter.c -diff --git a/src/etmemd_src/etmemd_project.c b/etmem/src/etmemd_src/etmemd_project.c -similarity index 100% -rename from src/etmemd_src/etmemd_project.c -rename to etmem/src/etmemd_src/etmemd_project.c -diff --git a/src/etmemd_src/etmemd_rpc.c b/etmem/src/etmemd_src/etmemd_rpc.c -similarity index 100% -rename from src/etmemd_src/etmemd_rpc.c -rename to etmem/src/etmemd_src/etmemd_rpc.c -diff --git a/src/etmemd_src/etmemd_scan.c b/etmem/src/etmemd_src/etmemd_scan.c -similarity index 100% -rename from src/etmemd_src/etmemd_scan.c -rename to etmem/src/etmemd_src/etmemd_scan.c -diff --git a/src/etmemd_src/etmemd_scan.version b/etmem/src/etmemd_src/etmemd_scan.version -similarity index 100% -rename from src/etmemd_src/etmemd_scan.version -rename to etmem/src/etmemd_src/etmemd_scan.version -diff --git a/src/etmemd_src/etmemd_slide.c b/etmem/src/etmemd_src/etmemd_slide.c -similarity index 100% -rename from src/etmemd_src/etmemd_slide.c -rename to etmem/src/etmemd_src/etmemd_slide.c -diff --git a/src/etmemd_src/etmemd_task.c b/etmem/src/etmemd_src/etmemd_task.c -similarity index 100% -rename from src/etmemd_src/etmemd_task.c -rename to etmem/src/etmemd_src/etmemd_task.c -diff --git a/src/etmemd_src/etmemd_thirdparty.c b/etmem/src/etmemd_src/etmemd_thirdparty.c -similarity index 100% -rename from src/etmemd_src/etmemd_thirdparty.c -rename to etmem/src/etmemd_src/etmemd_thirdparty.c -diff --git a/src/etmemd_src/etmemd_threadpool.c b/etmem/src/etmemd_src/etmemd_threadpool.c -similarity index 100% -rename from src/etmemd_src/etmemd_threadpool.c -rename to etmem/src/etmemd_src/etmemd_threadpool.c -diff --git a/src/etmemd_src/etmemd_threadtimer.c b/etmem/src/etmemd_src/etmemd_threadtimer.c -similarity index 100% -rename from src/etmemd_src/etmemd_threadtimer.c -rename to etmem/src/etmemd_src/etmemd_threadtimer.c --- -2.27.0 - diff --git a/0048-Commit-new-features-memRouter-and-userswap-to-etmem.patch b/0048-Commit-new-features-memRouter-and-userswap-to-etmem.patch deleted file mode 100644 index c09c539..0000000 --- a/0048-Commit-new-features-memRouter-and-userswap-to-etmem.patch +++ /dev/null @@ -1,3286 +0,0 @@ -From 3d4006defc9ac08581b1cbc7fb5c0ad06473273c Mon Sep 17 00:00:00 2001 -From: Yangxin <245051644@qq.com> -Date: Thu, 30 Sep 2021 17:40:21 +0800 -Subject: [PATCH 48/50] Commit new features memRouter and userswap to etmem. - -Signed-off-by: Yangxin <245051644@qq.com> ---- - memRouter/CMakeLists.txt | 74 +++ - memRouter/README.md | 90 +++ - memRouter/include/memdcd_cmd.h | 21 + - memRouter/include/memdcd_daemon.h | 23 + - memRouter/include/memdcd_log.h | 34 + - memRouter/include/memdcd_message.h | 75 +++ - memRouter/include/memdcd_migrate.h | 21 + - memRouter/include/memdcd_policy.h | 42 ++ - memRouter/include/memdcd_policy_threshold.h | 22 + - memRouter/include/memdcd_process.h | 41 ++ - memRouter/src/memdcd.c | 143 +++++ - memRouter/src/memdcd_cmd.c | 93 +++ - memRouter/src/memdcd_daemon.c | 257 ++++++++ - memRouter/src/memdcd_log.c | 80 +++ - memRouter/src/memdcd_migrate.c | 150 +++++ - memRouter/src/memdcd_policy.c | 132 ++++ - memRouter/src/memdcd_policy_threshold.c | 209 ++++++ - memRouter/src/memdcd_process.c | 345 ++++++++++ - userswap/CMakeLists.txt | 36 ++ - userswap/License/LICENSE | 127 ++++ - userswap/README.md | 7 + - userswap/configure.sh | 4 + - userswap/include/uswap_api.h | 69 ++ - userswap/include/uswap_log.h | 30 + - userswap/include/uswap_server.h | 40 ++ - userswap/src/lib_uswap.c | 663 ++++++++++++++++++++ - userswap/src/uswap_log.c | 81 +++ - userswap/src/uswap_server.c | 138 ++++ - 28 files changed, 3047 insertions(+) - create mode 100644 memRouter/CMakeLists.txt - create mode 100644 memRouter/README.md - create mode 100644 memRouter/include/memdcd_cmd.h - create mode 100644 memRouter/include/memdcd_daemon.h - create mode 100644 memRouter/include/memdcd_log.h - create mode 100644 memRouter/include/memdcd_message.h - create mode 100644 memRouter/include/memdcd_migrate.h - create mode 100644 memRouter/include/memdcd_policy.h - create mode 100644 memRouter/include/memdcd_policy_threshold.h - create mode 100644 memRouter/include/memdcd_process.h - create mode 100644 memRouter/src/memdcd.c - create mode 100644 memRouter/src/memdcd_cmd.c - create mode 100644 memRouter/src/memdcd_daemon.c - create mode 100644 memRouter/src/memdcd_log.c - create mode 100644 memRouter/src/memdcd_migrate.c - create mode 100644 memRouter/src/memdcd_policy.c - create mode 100644 memRouter/src/memdcd_policy_threshold.c - create mode 100644 memRouter/src/memdcd_process.c - create mode 100644 userswap/CMakeLists.txt - create mode 100644 userswap/License/LICENSE - create mode 100644 userswap/README.md - create mode 100644 userswap/configure.sh - create mode 100644 userswap/include/uswap_api.h - create mode 100644 userswap/include/uswap_log.h - create mode 100644 userswap/include/uswap_server.h - create mode 100644 userswap/src/lib_uswap.c - create mode 100644 userswap/src/uswap_log.c - create mode 100644 userswap/src/uswap_server.c - -diff --git a/memRouter/CMakeLists.txt b/memRouter/CMakeLists.txt -new file mode 100644 -index 0000000..1e55115 ---- /dev/null -+++ b/memRouter/CMakeLists.txt -@@ -0,0 +1,74 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: YangXin -+# * Create: 2020-09-08 -+# * Description: CMakefileList for memRouter to compile -+# ******************************************************************************/ -+ -+cmake_minimum_required (VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) -+project(memdcd C) -+ -+set(CMAKE_C_STANDARD 99) -+ -+set(LOCAL_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) -+ -+IF(CMAKE_BUILD_TYPE STREQUAL Test) -+ IF(COVERAGE_ENABLE) -+ MESSAGE(STATUS "Enable coverage compile option") -+ SET(COVERAGE_OPTION "${COVERAGE_OPTION} -fprofile-arcs -ftest-coverage") -+ ENDIF(COVERAGE_ENABLE) -+ IF(ASAN_ENABLE) -+ MESSAGE(STATUS "Enable asan compile option") -+ SET(ASAN_OPTIONS "${ASAN_OPTION} -fsanitize=address -fsanitize-recover=address") -+ ENDIF(ASAN_ENABLE) -+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_DEBUG} ${COVERAGE_OPTION} ${ASAN_OPTIONS}") -+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_DEBUG} ${COVERAGE_OPTION} ${ASAN_OPTIONS}") -+ add_subdirectory(test) -+ENDIF() -+ -+set(CMAKE_POSITION_INDEPENDENT_CODE ON) -+ -+set(SRC_DIR ${PROJECT_SOURCE_DIR}/src) -+set(INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include) -+set(BUILD_DIR ${PROJECT_SOURCE_DIR}/build) -+ -+set(MEMROUTER_SRC -+ ${SRC_DIR}/memdcd.c -+ ${SRC_DIR}/memdcd_policy.c -+ ${SRC_DIR}/memdcd_policy_threshold.c -+ ${SRC_DIR}/memdcd_migrate.c -+ ${SRC_DIR}/memdcd_process.c -+ ${SRC_DIR}/memdcd_daemon.c -+ ${SRC_DIR}/memdcd_cmd.c -+ ${SRC_DIR}/memdcd_log.c -+ ) -+ -+add_executable(memdcd ${MEMROUTER_SRC}) -+ -+target_include_directories(memdcd PRIVATE -+ ${INCLUDE_DIR}/) -+ -+add_definitions(-D_GNU_SOURCE -DNDEBUG -D_FORTIFY_SOURCE=2) -+target_compile_options(memdcd PRIVATE -fsigned-char --param ssp-buffer-size=4 -fno-omit-frame-pointer -Wall -Wextra -+-Wno-missing-field-initializers -Wmissing-declarations -fno-strict-aliasing -+-Wformat -Wformat-security -fPIE -pie -fPIC -ftrapv -+-Wno-error=deprecated-declarations -fstack-protector-all -fno-common -O2 -Wall -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -pthread -Wstrict-prototypes -Wl,--no-whole-archive -Wold-style-definition -std=gnu99 -Wno-error=unused-result -Wno-error=strict-prototypes -Wno-error=old-style-definition -Wno-error=missing-declarations -Wno-error=format-overflow -I${INCLUDE_DIR}) -+ -+if(CONFIG_DEBUG STREQUAL "y") -+ target_compile_options(memdcd PRIVATE -g) -+endif() -+ -+target_link_libraries(memdcd PRIVATE pthread dl rt numa json-c cap -s) -+ -+install(TARGETS memdcd -+ PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE -+ RUNTIME DESTINATION /usr/bin -+ ) -diff --git a/memRouter/README.md b/memRouter/README.md -new file mode 100644 -index 0000000..4350a4c ---- /dev/null -+++ b/memRouter/README.md -@@ -0,0 +1,90 @@ -+# memRouter -+ -+## 介绍 -+ -+随着CPU算力的发展,尤其是ARM核成本的降低,内存成本和内存容量成为约束业务成本和性能的核心痛点,因此如何节省内存成本,如何扩大内存容量成为存储迫切要解决的问题。 -+ -+memRouter内存分级扩展,根据用户选择内存迁移策略对内存进行分级,分发到不同级别的介质上,降低dram的使用量,来达到内存容量扩展的目的。 -+ -+## 编译方法 -+ -+1. 下载memRouter源码 -+``` -+git clone https://gitee.com/openeuler/etmem.git -+``` -+2. 编译和运行依赖 -+ -+ memRouter的编译和运行依赖于libcap-devel、json-c-devel、numactl-devel软件包 -+ -+3. 编译 -+``` -+cd memRouter -+mkdir build -+cd build -+cmake .. -+make -+``` -+ -+## 使用说明 -+ -+### 启动memdcd进程 -+ -+#### 使用方法 -+ -+通过运行memdcd二进制运行服务端进程,例如: -+``` -+memdcd -p xx.json -+``` -+策略配置文件的权限需为600,属主需为当前memRouter启动者 -+#### 命令行参数说明 -+ -+| 参数 | 参数含义 | 是否必须 | 是否有参数 | 参数范围 | 示例说明 | -+| --------------- | ---------------------------------- | -------- | ---------- | --------------------- | ------------------------------------------------------------ | -+| -p或--policy | memRouter日志级别 | 是 | 是 | 有效地址 | memdcd所采用的页面分级策略 -+| -s或--socket | memRouter监听的名称,用于与客户端交互 | 否 | 是 | 107个字符之内的字符串 | 指定服务端监听的unix socket名称 | -+| -l或--log | 帮助信息 | 否 | 是 | LOG_INFO/LOG_DEBUG | LOG_INFO: info级别 LOG_DEBUG: debug级别出 | -+| -t或--timeout | 帮助信息 | 否 | 是 | 0-4294967295 | 收集进程页面信息的时长限制 | -+| -h或--help | 帮助信息 | 否 | 否 | NA | 执行时带有此参数会打印后退出 | -+ -+### 配置文件 -+目前仅支持阈值策略 -+ -+#### 阈值策略配置文件 -+``` -+{ -+ "type": "mig_policy_threshold", -+ "policy": { -+ "unit": "KB", -+ "threshold": 20 -+ } -+} -+``` -+ -+| **配置项** | **配置项含义** | **是否必须** | **是否有参数** | **参数范围** | **示例说明** | -+| ----------- | ------------------------------------------------------------ | ------------ | -------------- | ------------------------- | ------------------------------------------------------------ | -+| type | 采取的分级策略 | 是 | 是 | 暂时支支持mig_policy_threshold | "type": "mig_policy_threshold" | -+| policy | 采取的策略 | 是 | 是 | NA | NA | -+| unit | 采用的单位 | 是 | 是 | KB/MB/GB | "unit": "KB"以KB作为单位 | -+| threshold | 被监控进程的内存阈值 | 是 | 是 | 0~INT32_MAX | "threshold": 20 //限制配监控进程内存上限20KB | -+ -+ -+#### 所需etmemd配置文件: -+各字段含义参见[etmemd](https://gitee.com/openeuler/etmem/blob/master/README.md) -+``` -+options: -+ loop : ${loop} -+ interval : ${interval} -+ sleep: ${sleep} -+ policies: -+ type : pid/name -+ value : ${pid}/${name} -+ max_threads: ${max_threads} -+ engine : memdcd -+``` -+ -+## 参与贡献 -+ -+1. Fork本仓库 -+2. 新建个人分支 -+3. 提交代码 -+4. 新建Pull Request -diff --git a/memRouter/include/memdcd_cmd.h b/memRouter/include/memdcd_cmd.h -new file mode 100644 -index 0000000..757d50c ---- /dev/null -+++ b/memRouter/include/memdcd_cmd.h -@@ -0,0 +1,21 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liruilin -+ * Create: 2021-02-26 -+ * Description: handle receive buffer. -+ ******************************************************************************/ -+#ifndef MEMDCD_CMD_H -+#define MEMDCD_CMD_H -+ -+int handle_recv_buffer(const void *buf, int msg_len); -+ -+#endif // MEMDCD_H -+ -diff --git a/memRouter/include/memdcd_daemon.h b/memRouter/include/memdcd_daemon.h -new file mode 100644 -index 0000000..fa2b641 ---- /dev/null -+++ b/memRouter/include/memdcd_daemon.h -@@ -0,0 +1,23 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liruilin -+ * Create: 2021-02-26 -+ * Description: init memdcd daemon. -+ ******************************************************************************/ -+#ifndef MEMDCD_DAEMON_H -+#define MEMDCD_DAEMON_H -+ -+#define MAX_MESSAGE_LENGTH 40960 -+ -+void *memdcd_daemon_start(const char *sock_path); -+ -+#endif -+ -diff --git a/memRouter/include/memdcd_log.h b/memRouter/include/memdcd_log.h -new file mode 100644 -index 0000000..b29b412 ---- /dev/null -+++ b/memRouter/include/memdcd_log.h -@@ -0,0 +1,34 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liruilin -+ * Create: 2020-10-30 -+ * Description: print log. -+ ******************************************************************************/ -+#ifndef MEMDCD_LOG_H__ -+#define MEMDCD_LOG_H__ -+ -+ -+#define ERROR_STR_MAX_LEN 256 -+ -+enum _log_level { -+ _LOG_ERROR = 0, -+ _LOG_WARN, -+ _LOG_INFO, -+ _LOG_DEBUG, -+}; -+ -+ -+int init_log_level(const char *log_level_str); -+int set_log_level(const int level); -+void memdcd_log(const int level, const char *, ...); -+ -+#endif -+ -diff --git a/memRouter/include/memdcd_message.h b/memRouter/include/memdcd_message.h -new file mode 100644 -index 0000000..9663ef2 ---- /dev/null -+++ b/memRouter/include/memdcd_message.h -@@ -0,0 +1,75 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liruilin -+ * Create: 2021-02-26 -+ * Description: data structure used in interprocess communication. -+ ******************************************************************************/ -+#ifndef MEMDCD_MESSAGE_H -+#define MEMDCD_MESSAGE_H -+#include -+ -+enum memdcd_cmd_type { -+ MEMDCD_CMD_MEM, -+ MEMDCD_CMD_NODE, -+ MEMDCD_CMD_POLICY, -+}; -+ -+enum SwapType { -+ SWAP_TYPE_VMA_ADDR = 0xFFFFFF01, -+ SWAP_TYPE_MAX -+}; -+ -+#define MAX_VMA_NUM 512 -+struct vma_addr { -+ uint64_t start_addr; -+ uint64_t vma_len; -+}; -+ -+struct vma_addr_with_count { -+ struct vma_addr vma; -+ int count; -+}; -+ -+struct swap_vma { -+ enum SwapType type; -+ uint64_t length; -+ struct vma_addr vma_addrs[MAX_VMA_NUM]; -+}; -+ -+enum MEMDCD_MESSAGE_STATUS { -+ MEMDCD_SEND_START, -+ MEMDCD_SEND_PROCESS, -+ MEMDCD_SEND_END, -+}; -+ -+struct swap_vma_with_count { -+ enum SwapType type; -+ uint64_t length; -+ uint64_t total_length; -+ enum MEMDCD_MESSAGE_STATUS status; -+ struct vma_addr_with_count vma_addrs[MAX_VMA_NUM]; -+}; -+ -+struct memory_message { -+ int pid; -+ uint32_t enable_uswap; -+ struct swap_vma_with_count vma; -+}; -+ -+struct memdcd_message { -+ enum memdcd_cmd_type cmd_type; -+ union { -+ struct memory_message memory_msg; -+ }; -+}; -+ -+#endif -+ -diff --git a/memRouter/include/memdcd_migrate.h b/memRouter/include/memdcd_migrate.h -new file mode 100644 -index 0000000..22598e2 ---- /dev/null -+++ b/memRouter/include/memdcd_migrate.h -@@ -0,0 +1,21 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: zhangxuzhou -+ * Create: 2020-09-18 -+ * Description: engines migrating memory pages -+ ******************************************************************************/ -+#ifndef MEMDCD_CONNECT_H -+#define MEMDCD_CONNECT_H -+#include "memdcd_process.h" -+ -+int send_to_userswap(int pid, const struct migrate_page_list *pages); -+ -+#endif /* MEMDCD_CONNECT_H */ -diff --git a/memRouter/include/memdcd_policy.h b/memRouter/include/memdcd_policy.h -new file mode 100644 -index 0000000..47c40f5 ---- /dev/null -+++ b/memRouter/include/memdcd_policy.h -@@ -0,0 +1,42 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: zhangxuzhou -+ * Create: 2020-09-08 -+ * Description: init policy -+ ******************************************************************************/ -+ -+#ifndef MEMDCD_POLICY_H -+#define MEMDCD_POLICY_H -+#include "memdcd_process.h" -+ -+enum mem_policy_type { -+ POL_TYPE_THRESHOLD, -+ POL_TYPE_MAX, -+}; -+ -+struct mem_policy { -+ enum mem_policy_type type; -+ void *private; -+ struct memdcd_policy_opt *opt; -+}; -+ -+struct memdcd_policy_opt { -+ int (*init)(struct mem_policy *policy, const char *path); -+ int (*parse)(const struct mem_policy *policy, int pid, struct migrate_page_list *page_list, -+ struct migrate_page_list **pages_to_numa, struct migrate_page_list **pages_to_swap); -+ int (*destroy)(struct mem_policy *policy); -+}; -+ -+struct mem_policy *get_policy(void); -+int init_mem_policy(char *path); -+ -+#endif /* MEMDCD_POLICY_H */ -+ -diff --git a/memRouter/include/memdcd_policy_threshold.h b/memRouter/include/memdcd_policy_threshold.h -new file mode 100644 -index 0000000..f75d3e7 ---- /dev/null -+++ b/memRouter/include/memdcd_policy_threshold.h -@@ -0,0 +1,22 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liruilin -+ * Create: 2021-02-26 -+ * Description: head file of threshold policy -+ ******************************************************************************/ -+#ifndef MEMDCD_POLICY_THRESHOLD_H -+#define MEMDCD_POLICY_THRESHOLD_H -+#include "memdcd_policy.h" -+ -+struct memdcd_policy_opt *get_threshold_policy(void); -+ -+#endif -+ -diff --git a/memRouter/include/memdcd_process.h b/memRouter/include/memdcd_process.h -new file mode 100644 -index 0000000..eaa86f8 ---- /dev/null -+++ b/memRouter/include/memdcd_process.h -@@ -0,0 +1,41 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liruilin -+ * Create: 2021-02-26 -+ * Description: process received pages -+ ******************************************************************************/ -+#ifndef MEMDCD_PROCESS_H -+#define MEMDCD_PROCESS_H -+ -+#include -+#include "memdcd_message.h" -+ -+#define DEFAULT_COLLECT_PAGE_TIMEOUT 3 -+ -+struct migrate_page { -+ uint64_t addr; -+ uint64_t length; -+ int visit_count; -+ -+ int numanode; -+}; -+ -+struct migrate_page_list { -+ uint64_t length; -+ struct migrate_page pages[]; -+}; -+ -+void init_collect_pages_timeout(time_t timeout); -+int migrate_process_get_pages(int pid, const struct swap_vma_with_count *vma); -+void migrate_process_exit(void); -+ -+#endif /* MEMDCD_MIGRATE_H */ -+ -diff --git a/memRouter/src/memdcd.c b/memRouter/src/memdcd.c -new file mode 100644 -index 0000000..70f9f7b ---- /dev/null -+++ b/memRouter/src/memdcd.c -@@ -0,0 +1,143 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: zhangxuzhou -+ * Create: 2020-09-08 -+ * Description: main function of memdcd. -+ ******************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "memdcd_policy.h" -+#include "memdcd_daemon.h" -+#include "memdcd_log.h" -+ -+#define DEFAULT_SOCK_PATH "@_memdcd.server" -+#define REQUIRE_CAP_MAX 1 -+#define TIMEOUT_VALID_LEN 10 -+ -+static void usage(void) -+{ -+ printf("Usage: memdcd -p|--policy [options]\n"); -+ printf(" -p --policy specify policy config file\n"); -+ printf(" -s --socket specify socket path. default: %s\n", DEFAULT_SOCK_PATH); -+ printf(" -l --log LOG_INFO|LOG_DEBUG set log level to print. default: LOG_INFO\n"); -+ printf(" -t --timeout set timeout for collect pages by second.\n"); -+ printf(" set 0 to disable timeout. default: %d\n", DEFAULT_COLLECT_PAGE_TIMEOUT); -+ printf(" -h --help show this help info\n"); -+} -+ -+static int check_permission(void) -+{ -+ cap_t cap = NULL; -+ cap_flag_value_t cap_flag_value = CAP_CLEAR; -+ cap_value_t cap_val = 0; -+ const char *req_cap[REQUIRE_CAP_MAX] = { -+ "cap_sys_nice" -+ }; -+ -+ cap = cap_get_proc(); -+ if (cap == NULL) { -+ memdcd_log(_LOG_ERROR, "Get capability error."); -+ return -1; -+ } -+ for (int i = 0; i < REQUIRE_CAP_MAX; i++) { -+ cap_from_name(req_cap[i], &cap_val); -+ cap_get_flag(cap, cap_val, CAP_EFFECTIVE, &cap_flag_value); -+ if (cap_flag_value != CAP_SET) { -+ memdcd_log(_LOG_ERROR, "Not sufficient capacity: %s.", req_cap[i]); -+ cap_free(cap); -+ return -1; -+ } -+ } -+ cap_free(cap); -+ return 0; -+} -+ -+int main(int argc, char *argv[]) -+{ -+ int opt; -+ struct option long_options[] = { -+ {"policy", required_argument, NULL, 'p'}, -+ {"socket", required_argument, NULL, 's'}, -+ {"log", required_argument, NULL, 'l'}, -+ {"timeout", required_argument, NULL, 't'}, -+ {"help", no_argument, NULL, 'h'}, -+ {NULL, 0, NULL, 0}, -+ }; -+ time_t timeout; -+ char *policy_file = NULL, *socket_path = NULL; -+ char *endptr = NULL; -+ -+ while ((opt = getopt_long(argc, argv, "p:s:l:t:h", long_options, NULL)) != -1) { -+ switch (opt) { -+ case 'p': -+ policy_file = optarg; -+ break; -+ case 's': -+ socket_path = optarg; -+ break; -+ case 'l': -+ if (init_log_level(optarg) < 0) { -+ printf("error parsing log level: %s\n", optarg); -+ return -EINVAL; -+ } -+ break; -+ case 't': -+ errno = 0; -+ timeout = strtol(optarg, &endptr, TIMEOUT_VALID_LEN); -+ if (errno || optarg == endptr || (endptr && *endptr != ' ' && *endptr != '\0') || timeout < 0) { -+ printf("error parsing timeout %s\n", optarg); -+ return -EINVAL; -+ } -+ init_collect_pages_timeout(timeout); -+ break; -+ case 'h': -+ usage(); -+ return 0; -+ default: -+ usage(); -+ return -EINVAL; -+ } -+ } -+ -+ if (policy_file == NULL) { -+ printf("policy file should be assigned\n"); -+ usage(); -+ return 0; -+ } -+ if (socket_path == NULL) -+ socket_path = DEFAULT_SOCK_PATH; -+ -+ if (check_permission() != 0) { -+ memdcd_log(_LOG_ERROR, "This program is lack of nessary privileges."); -+ return -1; -+ } -+ -+ if (init_mem_policy(policy_file) != 0) { -+ memdcd_log(_LOG_ERROR, "Error parsing policy from policy config file %s.", policy_file); -+ return -1; -+ } -+ -+ memdcd_daemon_start(socket_path); -+ -+ return 0; -+} -diff --git a/memRouter/src/memdcd_cmd.c b/memRouter/src/memdcd_cmd.c -new file mode 100644 -index 0000000..9f3fcc0 ---- /dev/null -+++ b/memRouter/src/memdcd_cmd.c -@@ -0,0 +1,93 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liruilin -+ * Create: 2021-02-26 -+ * Description: handle receive buffer. -+ ******************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "memdcd_process.h" -+#include "memdcd_log.h" -+#include "memdcd_cmd.h" -+ -+#define FILEPATH_MAX_LEN 64 -+ -+static uint64_t get_process_vmsize(int pid) -+{ -+ char statm_path[FILEPATH_MAX_LEN]; -+ FILE *fp = NULL; -+ uint64_t vmsize; -+ char error_str[ERROR_STR_MAX_LEN] = {0}; -+ -+ if (snprintf(statm_path, FILEPATH_MAX_LEN, "/proc/%d/statm", pid) <= 0) { -+ memdcd_log(_LOG_ERROR, "memdcd_uswap: snprintf for statm_path from pid %d failed.", pid); -+ return -1; -+ } -+ fp = fopen(statm_path, "r"); -+ if (fp == NULL) { -+ memdcd_log(_LOG_ERROR, "Error opening statm file %s: %s.", statm_path, error_str); -+ return 0; -+ } -+ if (fscanf(fp, "%lu", &vmsize) <= 0) { -+ memdcd_log(_LOG_ERROR, "Error reading file %s. err: %s", -+ statm_path, strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ fclose(fp); -+ return 0; -+ } -+ fclose(fp); -+ return vmsize; -+} -+ -+static int handle_mem_message(const struct memory_message *msg) -+{ -+ uint64_t total_pages = get_process_vmsize(msg->pid); -+ if (total_pages == 0) { -+ memdcd_log(_LOG_ERROR, "Error getting vmsize of process %d.", msg->pid); -+ return -1; -+ } else if (total_pages < msg->vma.total_length) { -+ memdcd_log(_LOG_ERROR, "Total page num of process %lu is less than incoming page num %lu.", -+ total_pages, msg->vma.total_length); -+ return -1; -+ } -+ -+ if (msg->vma.length / sizeof(struct vma_addr_with_count) > MAX_VMA_NUM) { -+ memdcd_log(_LOG_ERROR, "Invalid message length %lu.", msg->vma.length); -+ return -1; -+ } -+ -+ return migrate_process_get_pages(msg->pid, &msg->vma); -+} -+ -+int handle_recv_buffer(const void *buffer, int msg_len) -+{ -+ struct memdcd_message *msg = (struct memdcd_message *)buffer; -+ if (msg_len != sizeof(struct memdcd_message)) { -+ memdcd_log(_LOG_ERROR, "Invalid recv message length %d.", msg_len); -+ return -1; -+ } -+ memdcd_log(_LOG_DEBUG, "Type: %d.", msg->cmd_type); -+ -+ switch (msg->cmd_type) { -+ case MEMDCD_CMD_MEM: -+ return handle_mem_message(&msg->memory_msg); -+ default: -+ memdcd_log(_LOG_ERROR, "Invalid cmd type."); -+ return -1; -+ } -+ return 0; -+} -\ No newline at end of file -diff --git a/memRouter/src/memdcd_daemon.c b/memRouter/src/memdcd_daemon.c -new file mode 100644 -index 0000000..f88593d ---- /dev/null -+++ b/memRouter/src/memdcd_daemon.c -@@ -0,0 +1,257 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liruilin -+ * Create: 2021-02-26 -+ * Description: init memdcd daemon. -+ ******************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "memdcd_log.h" -+#include "memdcd_process.h" -+#include "memdcd_cmd.h" -+#include "memdcd_daemon.h" -+ -+#define MAX_PENDING_QUEUE_LENGTH 64 -+#define MAX_SOCK_PATH_LENGTH 108 -+ -+static volatile sig_atomic_t g_sock_fd; -+static volatile sig_atomic_t g_exit_signal; -+ -+static void _set_exit_flag(int s) -+{ -+ (void)s; -+ g_exit_signal = 1; -+ if (g_sock_fd > 0) { -+ close(g_sock_fd); -+ } -+ g_sock_fd = -1; -+} -+ -+static void memdcd_install_signal(void) -+{ -+ signal(SIGINT, _set_exit_flag); -+ signal(SIGTERM, _set_exit_flag); -+} -+ -+ -+static int _set_socket_option(int sock_fd) -+{ -+ int rc; -+ int buf_len = MAX_MESSAGE_LENGTH; -+ struct timeval timeout = {5, 0}; -+ char error_str[ERROR_STR_MAX_LEN] = {0}; -+ -+ /* set timeout limit to socket for sending */ -+ rc = setsockopt(sock_fd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)); -+ if (rc < 0) { -+ memdcd_log(_LOG_ERROR, "Set send timeout for socket failed. err: %s", -+ strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ return -1; -+ } -+ -+ /* set max length of buffer to recive */ -+ rc = setsockopt(sock_fd, SOL_SOCKET, SO_RCVBUF, (const char *)&buf_len, sizeof(buf_len)); -+ if (rc < 0) { -+ memdcd_log(_LOG_ERROR, "Set recive buffer length for socket failed. err: %s", -+ strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ return -1; -+ } -+ -+ /* set max length of buffer to send */ -+ rc = setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF, (const char *)&buf_len, sizeof(buf_len)); -+ if (rc < 0) { -+ memdcd_log(_LOG_ERROR, "Set send buffer length for socket failed. err: %s", -+ strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int memdcd_server_init(const char *sock_path) -+{ -+ int sock_fd; -+ struct sockaddr_un sock_addr; -+ size_t sock_len; -+ char error_str[ERROR_STR_MAX_LEN] = {0}; -+ -+ memset(&sock_addr, 0, sizeof(struct sockaddr_un)); -+ -+ sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); -+ if (sock_fd < 0) { -+ memdcd_log(_LOG_ERROR, "Create socket for fail. err: %s", strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ return -1; -+ } -+ -+ sock_len = strlen(sock_path); -+ if (sock_len >= MAX_SOCK_PATH_LENGTH) { -+ memdcd_log(_LOG_ERROR, "Socket path is too long."); -+ close(sock_fd); -+ return -1; -+ } -+ sock_addr.sun_family = AF_UNIX; -+ memcpy(sock_addr.sun_path, sock_path, sock_len); -+ -+ sock_addr.sun_path[0] = 0; -+ sock_len += offsetof(struct sockaddr_un, sun_path); -+ -+ if (_set_socket_option(sock_fd) != 0) { -+ memdcd_log(_LOG_ERROR, "Set for socket fail. err: %s", strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ close(sock_fd); -+ return -1; -+ } -+ -+ if (bind(sock_fd, (struct sockaddr *)&sock_addr, sock_len) != 0) { -+ memdcd_log(_LOG_ERROR, "Socket bind %s fail. err: %s", -+ (char *)&sock_addr.sun_path[1], strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ close(sock_fd); -+ return -1; -+ } -+ -+ return sock_fd; -+} -+ -+static int check_socket_permission(int sock_fd) -+{ -+ struct ucred cred; -+ socklen_t len; -+ ssize_t rc; -+ char error_str[ERROR_STR_MAX_LEN] = {0}; -+ -+ len = sizeof(struct ucred); -+ -+ rc = getsockopt(sock_fd, -+ SOL_SOCKET, -+ SO_PEERCRED, -+ &cred, -+ &len); -+ if (rc < 0) { -+ memdcd_log(_LOG_ERROR, "Getsockopt failed. err: %s\n", strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ return -1; -+ } -+ -+ if (cred.uid != 0 || cred.gid != 0) { -+ memdcd_log(_LOG_ERROR, "Socket connect failed, need recieving from app of root privilege.\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int memdcd_accept(char *recv_buf) -+{ -+ int accp_fd = -1; -+ int ret = 0; -+ ssize_t rc; -+ char error_str[ERROR_STR_MAX_LEN] = {0}; -+ -+ accp_fd = accept(g_sock_fd, NULL, NULL); -+ if (accp_fd < 0) { -+ memdcd_log(_LOG_ERROR, "Accept message failed. err: %s", strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ return -1; -+ } -+ -+ rc = check_socket_permission(accp_fd); -+ if (rc != 0) { -+ ret = rc; -+ goto close_fd; -+ } -+ -+ rc = recv(accp_fd, recv_buf, MAX_MESSAGE_LENGTH, 0); -+ if (rc <= 0) { -+ memdcd_log(_LOG_WARN, "Socket recive from client fail. err: %s", \ -+ strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ ret = -1; -+ goto close_fd; -+ } -+ -+ if (rc > MAX_MESSAGE_LENGTH) { -+ memdcd_log(_LOG_WARN, "Buffer sent to memdcd is too long, should be less than %d.", MAX_MESSAGE_LENGTH); -+ ret = -1; -+ goto close_fd; -+ } -+ -+ memdcd_log(_LOG_DEBUG, "Memdcd got one connection."); -+ ret = rc; -+ -+close_fd: -+ close(accp_fd); -+ return ret; -+} -+ -+void *memdcd_daemon_start(const char *sock_path) -+{ -+ char *recv_buf = NULL; -+ int msg_len; -+ int sock_fd; -+ char error_str[ERROR_STR_MAX_LEN] = {0}; -+ -+ if (sock_path == NULL) { -+ return NULL; -+ } -+ g_exit_signal = 0; -+ g_sock_fd = 0; -+ memdcd_install_signal(); -+ -+ sock_fd = memdcd_server_init(sock_path); -+ if (sock_fd < 0) -+ return NULL; -+ -+ recv_buf = (char *)malloc(sizeof(char) * MAX_MESSAGE_LENGTH); -+ if (recv_buf == NULL) { -+ memdcd_log(_LOG_ERROR, "Failed to alloc buffer to receive message."); -+ close(sock_fd); -+ sock_fd = -1; -+ return NULL; -+ } -+ -+ /* allow RPC_CLIENT_MAX clients to connect at the same time */ -+ if (listen(sock_fd, MAX_PENDING_QUEUE_LENGTH) != 0) { -+ memdcd_log(_LOG_ERROR, "Error listening on socket %s. err: %s", -+ sock_path, strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ close(sock_fd); -+ sock_fd = -1; -+ goto free_buf; -+ } -+ -+ if (g_sock_fd < 0) { -+ close(sock_fd); -+ sock_fd = -1; -+ goto free_buf; -+ } -+ g_sock_fd = sock_fd; -+ memdcd_log(_LOG_INFO, "Start listening on %s.", sock_path); -+ while (g_exit_signal == 0) { -+ msg_len = memdcd_accept(recv_buf); -+ if (msg_len < 0) { -+ memdcd_log(_LOG_ERROR, "Error accepting message. err: %s", strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ continue; -+ } -+ if (handle_recv_buffer(recv_buf, msg_len) < 0) -+ memdcd_log(_LOG_DEBUG, "Error handling message."); -+ } -+ migrate_process_exit(); -+ -+ if (g_sock_fd > 0) { -+ close(g_sock_fd); -+ g_sock_fd = -1; -+ } -+free_buf: -+ free(recv_buf); -+ return NULL; -+} -diff --git a/memRouter/src/memdcd_log.c b/memRouter/src/memdcd_log.c -new file mode 100644 -index 0000000..125fced ---- /dev/null -+++ b/memRouter/src/memdcd_log.c -@@ -0,0 +1,80 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liruilin -+ * Create: 2020-10-30 -+ * Description: print log. -+ ******************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "memdcd_log.h" -+ -+static int log_level = 0; -+ -+int set_log_level(const int level) -+{ -+ log_level = level; -+ return log_level; -+} -+ -+int init_log_level(const char *log_level_str) -+{ -+ if (log_level_str == NULL) -+ return set_log_level(_LOG_INFO); -+ if (strcmp(log_level_str, "LOG_DEBUG") == 0) -+ return set_log_level(_LOG_DEBUG); -+ if (strcmp(log_level_str, "LOG_INFO") == 0) -+ return set_log_level(_LOG_INFO); -+ if (strcmp(log_level_str, "LOG_WARN") == 0) -+ return set_log_level(_LOG_WARN); -+ if (strcmp(log_level_str, "LOG_ERROR") == 0) -+ return set_log_level(_LOG_ERROR); -+ memdcd_log(_LOG_ERROR, "Error initint log_level: %s.", log_level_str); -+ return -EINVAL; -+} -+ -+void memdcd_log(const int level, const char *va_alist, ...) -+{ -+ va_list ap; -+ -+ if (level > log_level) -+ return; -+ -+ va_start(ap, va_alist); -+ switch (level) { -+ case _LOG_INFO: -+ openlog("[MEMDCD_INFO] ", LOG_PID, LOG_USER); -+ vsyslog(LOG_INFO, va_alist, ap); -+ break; -+ case _LOG_DEBUG: -+ openlog("[MEMDCD_DEBUG] ", LOG_PID, LOG_USER); -+ vsyslog(LOG_INFO, va_alist, ap); -+ break; -+ case _LOG_WARN: -+ openlog("[MEMDCD_WARNING] ", LOG_PID, LOG_USER); -+ vsyslog(LOG_WARNING, va_alist, ap); -+ break; -+ case _LOG_ERROR: -+ openlog("[MEMDCD_ERROR] ", LOG_PID, LOG_USER); -+ vsyslog(LOG_ERR, va_alist, ap); -+ break; -+ default: -+ va_end(ap); -+ return; -+ } -+ -+ va_end(ap); -+ closelog(); -+ return; -+} -\ No newline at end of file -diff --git a/memRouter/src/memdcd_migrate.c b/memRouter/src/memdcd_migrate.c -new file mode 100644 -index 0000000..4017033 ---- /dev/null -+++ b/memRouter/src/memdcd_migrate.c -@@ -0,0 +1,150 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: zhangxuzhou -+ * Create: 2020-09-18 -+ * Description: engines migrating memory pages -+ ******************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "memdcd_policy.h" -+#include "memdcd_process.h" -+#include "memdcd_log.h" -+#include "memdcd_migrate.h" -+ -+#define CLIENT_RECV_DEFAULT_TIME 10 // default 10s -+#define RESP_MSG_MAX_LEN 10 -+#define FILEPATH_MAX_LEN 64 -+ -+static int uswap_init_connection(int server_pid, time_t recv_timeout) -+{ -+ socklen_t addrlen; -+ struct timeval timeout; -+ struct sockaddr_un addr; -+ char error_str[ERROR_STR_MAX_LEN] = {0}; -+ -+ int socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0); -+ if (socket_fd < 0) { -+ memdcd_log(_LOG_ERROR, "memdcd_uswap: Error opening socket."); -+ return -1; -+ } -+ -+ /* set recv timeout */ -+ timeout.tv_sec = recv_timeout; -+ timeout.tv_usec = 0; -+ if (setsockopt(socket_fd, SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(struct timeval)) != 0) { -+ memdcd_log(_LOG_ERROR, "memdcd_uswap: Setsockopt set recv timeout failed!"); -+ close(socket_fd); -+ return -1; -+ } -+ -+ bzero(&addr, sizeof(struct sockaddr_un)); -+ /* UNIX domain Socket abstract namespace */ -+ addr.sun_family = AF_UNIX; -+ addr.sun_path[0] = 0; -+ -+ if (snprintf(addr.sun_path + 1, FILEPATH_MAX_LEN, "userswap%d.sock", server_pid) <= 0) { -+ memdcd_log(_LOG_ERROR, "memdcd_uswap: Snprintf_s for abtract_path from pid %d failed.", server_pid); -+ close(socket_fd); -+ return -1; -+ } -+ -+ addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path + 1) + 1; -+ if (connect(socket_fd, (struct sockaddr *)&addr, addrlen) < 0) { -+ memdcd_log(_LOG_ERROR, "memdcd_uswap: Connect failed. err: %s! ", \ -+ strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ close(socket_fd); -+ return -1; -+ } -+ -+ return socket_fd; -+} -+ -+static int uswap_send_data(int client_fd, int server_pid, const struct swap_vma *swap_vma) -+{ -+ int ret = 0; -+ int read_bytes; -+ int write_bytes; -+ int in_datalen; -+ char buff[RESP_MSG_MAX_LEN] = {0}; -+ int len = strlen("success"); -+ -+ in_datalen = swap_vma->length + sizeof(int) + sizeof(long); -+ write_bytes = write(client_fd, swap_vma, in_datalen); -+ if (write_bytes <= 0) { -+ memdcd_log(_LOG_DEBUG, "memdcd_uswap: Write to pid %d server, bytes: %d.", server_pid, write_bytes); -+ return -1; -+ } -+ -+ read_bytes = read(client_fd, buff, RESP_MSG_MAX_LEN - 1); -+ if (read_bytes >= len && strncmp(buff, "success", len) == 0) { -+ memdcd_log(_LOG_DEBUG, "memdcd_uswap: Recv respond success."); -+ } else { -+ memdcd_log(_LOG_DEBUG, "memdcd_uswap: Recv respond failed."); -+ ret = -1; -+ } -+ -+ return ret; -+} -+ -+static int min(int a, int b) -+{ -+ return a < b ? a : b; -+} -+ -+int send_to_userswap(int pid, const struct migrate_page_list *page_list) -+{ -+ int ret = 0; -+ struct swap_vma *swap_vma = NULL; -+ int client_fd; -+ uint64_t i, rest, size; -+ uint64_t dst; -+ if (page_list->pages == NULL) { -+ memdcd_log(_LOG_WARN, "memdcd_uswap: Mig_addrs NULL."); -+ return 0; -+ } -+ memdcd_log(_LOG_INFO, "Send %lu addresses to userswap: pid %d.", page_list->length, pid); -+ swap_vma = (struct swap_vma *)malloc(sizeof(struct swap_vma)); -+ if (swap_vma == NULL) { -+ memdcd_log(_LOG_WARN, "memdcd_uswap: Malloc for swap vma failed."); -+ return -ENOMEM; -+ } -+ swap_vma->type = SWAP_TYPE_VMA_ADDR; -+ rest = page_list->length; -+ while (rest > 0) { -+ client_fd = uswap_init_connection(pid, CLIENT_RECV_DEFAULT_TIME); -+ if (client_fd < 0) { -+ ret = -1; -+ break; -+ } -+ size = min(rest, MAX_VMA_NUM); -+ -+ swap_vma->length = size * sizeof(struct vma_addr); -+ for (i = 0; i < size; i++) { -+ dst = page_list->length - rest + i; -+ swap_vma->vma_addrs[i].start_addr = page_list->pages[dst].addr; -+ swap_vma->vma_addrs[i].vma_len = page_list->pages[dst].length; -+ } -+ if (uswap_send_data(client_fd, pid, swap_vma) != 0) -+ ret = -1; -+ close(client_fd); -+ rest -= size; -+ } -+ -+ free(swap_vma); -+ return ret; -+} -\ No newline at end of file -diff --git a/memRouter/src/memdcd_policy.c b/memRouter/src/memdcd_policy.c -new file mode 100644 -index 0000000..063dbfc ---- /dev/null -+++ b/memRouter/src/memdcd_policy.c -@@ -0,0 +1,132 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: zhangxuzhou -+ * Create: 2020-09-08 -+ * Description: init policy -+ ******************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "memdcd_log.h" -+#include "memdcd_policy_threshold.h" -+#include "memdcd_policy.h" -+ -+#define FULL_PERMISSION 0777 -+ -+static struct { -+ char *name; -+ enum mem_policy_type type; -+ struct memdcd_policy_opt * (*get_opt)(void); -+} mem_policy_opts[] = { -+ {"mig_policy_threshold", POL_TYPE_THRESHOLD, get_threshold_policy}, -+ {NULL, POL_TYPE_MAX, NULL}, -+}; -+ -+struct mem_policy g_policy; -+ -+static int check_policy_file_permission(const char *path) -+{ -+ char error_str[ERROR_STR_MAX_LEN] = {0}; -+ struct stat permission_buffer; -+ -+ if (stat(path, &permission_buffer) != 0) { -+ memdcd_log(_LOG_ERROR, "Get file stat failed. err: %s", -+ strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ return -1; -+ } -+ -+ if (permission_buffer.st_uid != geteuid()) { -+ memdcd_log(_LOG_ERROR, "Owner of config file is not same with user of this process."); -+ return -EACCES; -+ } -+ -+ if ((permission_buffer.st_mode & FULL_PERMISSION) != (S_IRUSR | S_IWUSR)) { -+ memdcd_log(_LOG_ERROR, "Access permission of config file is not 600."); -+ return -EACCES; -+ } -+ -+ return 0; -+} -+ -+static int parse_policy_type(const char *path) -+{ -+ int i; -+ const char *str = NULL; -+ -+ json_object *root = json_object_from_file(path); -+ if (root == NULL) -+ return -1; -+ -+ json_object *type = json_object_object_get(root, "type"); -+ if (type == NULL) -+ return -1; -+ -+ str = json_object_get_string(type); -+ if (str == NULL) -+ return -1; -+ -+ for (i = 0; mem_policy_opts[i].name != NULL; i++) { -+ if (strcmp(str, mem_policy_opts[i].name) == 0) { -+ return i; -+ } -+ } -+ -+ return -1; -+} -+ -+int init_mem_policy(char *path) -+{ -+ int ret; -+ int type; -+ struct memdcd_policy_opt *opt = NULL; -+ char file_path[PATH_MAX] = {0}; -+ -+ if (!realpath(path, file_path)) { -+ memdcd_log(_LOG_ERROR, "Config file not exist."); -+ return -EEXIST; -+ } -+ ret = check_policy_file_permission(file_path); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ type = parse_policy_type(file_path); -+ if (type < 0) -+ return -EINVAL; -+ -+ memdcd_log(_LOG_DEBUG, "%s: type: %d.", __func__, g_policy.type); -+ -+ opt = mem_policy_opts[type].get_opt(); -+ -+ ret = opt->init(&g_policy, file_path); -+ if (ret != 0) -+ return ret; -+ -+ return 0; -+} -+ -+struct mem_policy *get_policy(void) -+{ -+ return &g_policy; -+} -diff --git a/memRouter/src/memdcd_policy_threshold.c b/memRouter/src/memdcd_policy_threshold.c -new file mode 100644 -index 0000000..3b5e1dc ---- /dev/null -+++ b/memRouter/src/memdcd_policy_threshold.c -@@ -0,0 +1,209 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liruilin -+ * Create: 2021-02-26 -+ * Description: function of threshold policy -+ ******************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "memdcd_log.h" -+#include "memdcd_policy.h" -+#include "memdcd_process.h" -+#include "memdcd_policy_threshold.h" -+ -+struct threshold_policy { -+ uint64_t threshold; -+}; -+ -+int threshold_policy_init(struct mem_policy *policy, const char *path); -+int threshold_policy_parse(const struct mem_policy *policy, int pid, struct migrate_page_list *page_list, -+ struct migrate_page_list **pages_to_numa, struct migrate_page_list **pages_to_swap); -+int threshold_policy_destroy(struct mem_policy *policy); -+ -+struct memdcd_policy_opt threshold_policy_opt = { -+ .init = threshold_policy_init, -+ .parse = threshold_policy_parse, -+ .destroy = threshold_policy_destroy, -+}; -+ -+int threshold_policy_init(struct mem_policy *policy, const char *path) -+{ -+ int ret = 0; -+ json_object *root = NULL, *obj_policy = NULL, *unit = NULL, *threshold = NULL; -+ int th_val = -1; -+ const char *str = NULL; -+ struct threshold_policy *t = (struct threshold_policy *)malloc(sizeof(struct threshold_policy)); -+ if (t == NULL) -+ return -1; -+ -+ root = json_object_from_file(path); -+ if (root == NULL) { -+ ret = -1; -+ goto err_out; -+ } -+ -+ obj_policy = json_object_object_get(root, "policy"); -+ if (obj_policy == NULL) { -+ ret = -1; -+ goto err_out; -+ } -+ -+ unit = json_object_object_get(obj_policy, "unit"); -+ if (unit == NULL) { -+ ret = -1; -+ goto err_out; -+ } -+ -+ threshold = json_object_object_get(obj_policy, "threshold"); -+ if (threshold == NULL) { -+ ret = -1; -+ goto err_out; -+ } -+ -+ th_val = json_object_get_int(threshold); -+ if (th_val == INT32_MAX || th_val < 0) { -+ memdcd_log(_LOG_ERROR, "Invalid threshold value, allowed range is [0, INT_MAX)."); -+ ret = -1; -+ goto err_out; -+ } -+ -+ str = json_object_get_string(unit); -+ if (str == NULL) { -+ ret = -1; -+ goto err_out; -+ } -+ -+ memdcd_log(_LOG_INFO, "Threshold policy loaded."); -+ if (strcmp("B", str) == 0) { -+ t->threshold = th_val; -+ } else if (strcmp("KB", str) == 0) { -+ t->threshold = (uint64_t)th_val * 1024; -+ } else if (strcmp("MB", str) == 0) { -+ t->threshold = (uint64_t)th_val * 1024 * 1024; -+ } else if (strcmp("GB", str) == 0) { -+ t->threshold = (uint64_t)th_val * 1024 * 1024 * 1024; -+ } else { -+ memdcd_log(_LOG_ERROR, "Detected invalid threshold setting. Abort."); -+ ret = -1; -+ goto err_out; -+ } -+ -+ policy->type = POL_TYPE_THRESHOLD; -+ policy->opt = &threshold_policy_opt; -+ policy->private = t; -+ -+ return 0; -+ -+err_out: -+ free(t); -+ return ret; -+} -+ -+static int addr_cmp_by_count(const void *a, const void *b) -+{ -+ return ((struct migrate_page *)a)->visit_count - ((struct migrate_page *)b)->visit_count; -+} -+ -+int threshold_policy_parse(const struct mem_policy *policy, int pid, struct migrate_page_list *page_list, -+ struct migrate_page_list **pages_to_numa, struct migrate_page_list **pages_to_swap) -+{ -+ int ret = 0; -+ uint64_t swap_count = 0; -+ uint64_t sum_size = 0; -+ int *status = NULL; -+ uint64_t *move_addr = NULL; -+ uint64_t length = page_list->length; -+ -+ (void)pages_to_numa; -+ -+ qsort(page_list->pages, length, sizeof(struct migrate_page), addr_cmp_by_count); -+ -+ status = malloc(sizeof(int) * length); -+ if (status == NULL) -+ return -1; -+ -+ move_addr = malloc(sizeof(uint64_t) * length); -+ if (move_addr == NULL) { -+ free(status); -+ return -1; -+ } -+ -+ for (uint64_t i = 0; i < length; i++) -+ move_addr[i] = page_list->pages[i].addr; -+ -+ if (move_pages(pid, length, (void **)move_addr, NULL, status, MPOL_MF_MOVE) < 0) { -+ memdcd_log(_LOG_ERROR, "Error when locate node for src_addr by move_page."); -+ ret = -1; -+ goto tpp_err_out; -+ } -+ -+ for (int64_t i = length - 1; i >= 0; i--) { -+ page_list->pages[i].numanode = status[i]; -+ if (status[i] < 0) { // negative means not on a numa node -+ memdcd_log(_LOG_DEBUG, "memdcd_migrate: Error getting current node of page %lx: %d, %ld.", -+ move_addr[i], status[i], i); -+ continue; -+ } -+ -+ /*judge if Integer Overflow happen*/ -+ if (sum_size + page_list->pages[i].length < sum_size) { -+ ret = -1; -+ goto tpp_err_out; -+ } -+ sum_size += page_list->pages[i].length; -+ if (sum_size < ((struct threshold_policy *)policy->private)->threshold) -+ continue; -+ -+ swap_count++; -+ // reuse the second half array -+ page_list->pages[length - swap_count] = page_list->pages[i]; -+ } -+ -+ *pages_to_swap = malloc(sizeof(struct migrate_page) * swap_count + sizeof(struct migrate_page_list)); -+ if (*pages_to_swap == NULL) { -+ memdcd_log(_LOG_ERROR, "memdcd_migrate: error allocating space for pages_to_swap."); -+ ret = -1; -+ goto tpp_err_out; -+ } -+ -+ memcpy((*pages_to_swap)->pages, page_list->pages + length - swap_count, sizeof(struct migrate_page) * swap_count); -+ (*pages_to_swap)->length = swap_count; -+ -+tpp_err_out: -+ free(status); -+ free(move_addr); -+ return ret; -+} -+ -+int threshold_policy_destroy(struct mem_policy *policy) -+{ -+ if (policy == NULL) { -+ return -1; -+ } -+ if (policy->private == NULL) { -+ return -1; -+ } -+ free(policy->private); -+ policy->private = NULL; -+ return 0; -+} -+ -+struct memdcd_policy_opt *get_threshold_policy(void) -+{ -+ return &threshold_policy_opt; -+} -diff --git a/memRouter/src/memdcd_process.c b/memRouter/src/memdcd_process.c -new file mode 100644 -index 0000000..8b2ef71 ---- /dev/null -+++ b/memRouter/src/memdcd_process.c -@@ -0,0 +1,345 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. -+ * etmem/memRouter licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liruilin -+ * Create: 2021-02-26 -+ * Description: process received pages -+ ******************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "memdcd_log.h" -+#include "memdcd_policy.h" -+#include "memdcd_migrate.h" -+#include "memdcd_message.h" -+ -+#define PID_MAX_FILE "/proc/sys/kernel/pid_max" -+#define PID_MAX_LEN 256 -+ -+struct migrate_process { -+ int pid; -+ -+ struct migrate_page_list *page_list; -+ uint64_t offset; -+ struct timeval timestamp; -+ -+ pthread_t worker; -+ -+ struct migrate_process *prev; -+ struct migrate_process *next; -+}; -+ -+struct migrate_process g_process_head = { -+ .prev = &g_process_head, -+ .next = &g_process_head, -+}; -+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; -+ -+time_t collect_page_timeout = DEFAULT_COLLECT_PAGE_TIMEOUT; -+ -+static void migrate_process_free(struct migrate_process *p) -+{ -+ p->prev->next = p->next; -+ p->next->prev = p->prev; -+ -+ if (p->page_list) -+ free(p->page_list); -+ free(p); -+} -+ -+static void migrate_process_remove(int pid) -+{ -+ struct migrate_process *cur; -+ -+ cur = g_process_head.next; -+ -+ memdcd_log(_LOG_DEBUG, "Remove process %d.", pid); -+ while (cur != &g_process_head) { -+ if (cur->pid == pid) -+ break; -+ cur = cur->next; -+ } -+ if (cur == &g_process_head) { -+ memdcd_log(_LOG_DEBUG, "Failed to remove process %d: not exist.", pid); -+ return; -+ } -+ -+ migrate_process_free(cur); -+ memdcd_log(_LOG_DEBUG, "End free process %d.", pid); -+} -+ -+static struct migrate_process *migrate_process_search(int pid) -+{ -+ struct migrate_process *cur; -+ -+ cur = g_process_head.next; -+ while (cur != &g_process_head) { -+ if (cur->pid == pid) { -+ return cur; -+ } -+ cur = cur->next; -+ } -+ -+ return NULL; -+} -+ -+static struct migrate_process *migrate_process_add(int pid, uint64_t len) -+{ -+ struct migrate_process *process = NULL; -+ -+ process = (struct migrate_process *)malloc(sizeof(struct migrate_process)); -+ if (process == NULL) -+ return NULL; -+ -+ process->page_list = -+ (struct migrate_page_list *)malloc(sizeof(struct migrate_page) * len + sizeof(struct migrate_page_list)); -+ if (process->page_list == NULL) { -+ free(process); -+ return NULL; -+ } -+ -+ process->pid = pid; -+ process->page_list->length = len; -+ process->offset = 0; -+ process->worker = 0; -+ -+ process->next = g_process_head.next; -+ process->next->prev = process; -+ g_process_head.next = process; -+ process->prev = &g_process_head; -+ -+ memdcd_log(_LOG_INFO, "Add new process %d.", pid); -+ -+ return process; -+} -+ -+static void migrate_process_recycle(void) -+{ -+ static struct timeval last = {0}; -+ struct timeval now; -+ struct migrate_process *iter = g_process_head.next, *next = NULL; -+ time_t time_lag; -+ -+ if (collect_page_timeout == 0) -+ return; -+ -+ gettimeofday(&now, NULL); -+ if (last.tv_sec == 0 || now.tv_sec - last.tv_sec < collect_page_timeout) { -+ last = now; -+ return; -+ } -+ last = now; -+ -+ pthread_mutex_lock(&mutex); -+ while (iter != &g_process_head) { -+ next = iter->next; -+ time_lag = now.tv_sec - iter->timestamp.tv_sec; -+ if (time_lag > collect_page_timeout && !(iter->worker && pthread_tryjoin_np(iter->worker, NULL) == EBUSY)) { -+ memdcd_log(_LOG_WARN, "Process exceed collect page timeout %ld: %ld.", time_lag, collect_page_timeout); -+ migrate_process_free(iter); -+ } -+ iter = next; -+ } -+ pthread_mutex_unlock(&mutex); -+ -+} -+ -+static pthread_t get_active_tid(void) -+{ -+ pthread_mutex_lock(&mutex); -+ struct migrate_process *iter = g_process_head.next; -+ pthread_t tid = iter->worker; -+ pthread_mutex_unlock(&mutex); -+ return (iter == &g_process_head) ? 0 : tid; -+} -+ -+void migrate_process_exit(void) -+{ -+ pthread_t tid; -+ migrate_process_recycle(); -+ while ((tid = get_active_tid()) != 0) { -+ pthread_join(tid, NULL); -+ } -+} -+ -+static struct migrate_process *migrate_process_collect_pages(int pid, const struct swap_vma_with_count *vma) -+{ -+ uint64_t count = vma->length / sizeof(struct vma_addr_with_count); -+ struct migrate_process *process = NULL; -+ uint64_t i; -+ -+ migrate_process_recycle(); -+ -+ pthread_mutex_lock(&mutex); -+ process = migrate_process_search(pid); -+ if (process != NULL) { -+ if (process->worker != 0 && pthread_tryjoin_np(process->worker, NULL) == EBUSY) { -+ memdcd_log(_LOG_DEBUG, "Previous send work of process %d has been doing. discard pages.", pid); -+ pthread_mutex_unlock(&mutex); -+ return NULL; -+ } -+ -+ if (vma->status == MEMDCD_SEND_START) { -+ memdcd_log(_LOG_DEBUG, "Previous send work of process %d is interrupted.", pid); -+ migrate_process_remove(pid); -+ process = NULL; -+ } -+ } -+ if (process == NULL) { -+ if (vma->status != MEMDCD_SEND_START) { -+ memdcd_log(_LOG_DEBUG, "Current send work of process %d is incomplete.", pid); -+ pthread_mutex_unlock(&mutex); -+ return NULL; -+ } -+ -+ process = migrate_process_add(pid, vma->total_length); -+ if (process == NULL) { -+ memdcd_log(_LOG_ERROR, "Cannot allocate space for process %d.", pid); -+ pthread_mutex_unlock(&mutex); -+ return NULL; -+ } -+ } -+ pthread_mutex_unlock(&mutex); -+ -+ memdcd_log(_LOG_DEBUG, "Collect %d pages for process %d; %lu has been collected; total %lu.", count, pid, -+ process->offset, process->page_list->length); -+ -+ if (process->offset + count > process->page_list->length) { -+ memdcd_log(_LOG_ERROR, "Collected pages of process %d is greater than total count: %lu %lu %lu.", pid, -+ process->offset, count, process->page_list->length); -+ migrate_process_remove(pid); -+ return NULL; -+ } -+ -+ for (i = 0; i < count; i++) { -+ process->page_list->pages[process->offset + i].addr = vma->vma_addrs[i].vma.start_addr; -+ process->page_list->pages[process->offset + i].length = vma->vma_addrs[i].vma.vma_len; -+ process->page_list->pages[process->offset + i].visit_count = vma->vma_addrs[i].count; -+ } -+ process->offset += count; -+ gettimeofday(&process->timestamp, NULL); -+ -+ if (vma->status == MEMDCD_SEND_END && process->offset != process->page_list->length) { -+ memdcd_log(_LOG_ERROR, "Count of pages of process %d is not equal to total count: %lu %lu.", -+ pid, process->offset, process->page_list->length); -+ migrate_process_remove(pid); -+ return NULL; -+ } -+ if (vma->status != MEMDCD_SEND_PROCESS && process->offset == process->page_list->length) { -+ memdcd_log(_LOG_INFO, "Collected %lu vmas for process %d.", process->page_list->length, pid); -+ return process; -+ } -+ -+ return NULL; -+} -+ -+void init_collect_pages_timeout(time_t timeout) -+{ -+ collect_page_timeout = timeout; -+} -+ -+static void *memdcd_migrate(void *args) -+{ -+ struct migrate_process *process = (struct migrate_process *)args; -+ struct mem_policy *policy = NULL; -+ struct migrate_page_list *pages = NULL, *pages_to_numa = NULL, *pages_to_swap = NULL; -+ -+ if (process == NULL) { -+ memdcd_log(_LOG_ERROR, "Process freed."); -+ return NULL; -+ } -+ -+ policy = get_policy(); -+ if (policy == NULL) { -+ memdcd_log(_LOG_ERROR, "Policy not initialized."); -+ return NULL; -+ } -+ -+ pages = (struct migrate_page_list *)malloc(sizeof(struct migrate_page_list) + -+ sizeof(struct migrate_page) * process->page_list->length); -+ if (pages == NULL) -+ return NULL; -+ memcpy(pages, process->page_list, -+ sizeof(struct migrate_page_list) + sizeof(struct migrate_page) * process->page_list->length); -+ -+ if (policy->opt->parse(policy, process->pid, pages, &pages_to_numa, &pages_to_swap)) { -+ memdcd_log(_LOG_ERROR, "Error parsing policy."); -+ goto free_pages; -+ } -+ -+ if (pages_to_swap->pages != NULL) -+ send_to_userswap(process->pid, pages_to_swap); -+ -+ if (pages_to_numa != NULL) -+ free(pages_to_numa); -+ if (pages_to_swap != NULL) -+ free(pages_to_swap); -+ -+free_pages: -+ free(pages); -+ -+ pthread_mutex_lock(&mutex); -+ migrate_process_remove(process->pid); -+ pthread_mutex_unlock(&mutex); -+ return NULL; -+} -+ -+static int get_pid_max(void) -+{ -+ FILE *fp; -+ char buf[PID_MAX_LEN] = {0}; -+ char error_str[ERROR_STR_MAX_LEN] = {0}; -+ -+ fp = fopen(PID_MAX_FILE, "r"); -+ if (fp == NULL) { -+ memdcd_log(_LOG_ERROR, "Error opening pid_max file %s. err: %s", -+ PID_MAX_FILE, strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ return 0; -+ } -+ if (fread(buf, sizeof(buf), 1, fp) == 0) { -+ if (feof(fp) == 0) { -+ memdcd_log(_LOG_ERROR, "Error reading pid_max file %s.", PID_MAX_FILE); -+ fclose(fp); -+ return 0; -+ } -+ } -+ fclose(fp); -+ return atoi(buf); -+} -+ -+int migrate_process_get_pages(int pid, const struct swap_vma_with_count *vma) -+{ -+ char error_str[ERROR_STR_MAX_LEN] = {0}; -+ struct migrate_process *process = NULL; -+ if (pid <= 0 || pid > get_pid_max()) { -+ memdcd_log(_LOG_ERROR, "Invalid input pid:%d.\n ", pid); -+ return -1; -+ } -+ -+ process = migrate_process_collect_pages(pid, vma); -+ -+ if (process != NULL) { -+ if (pthread_create(&process->worker, NULL, memdcd_migrate, (void *)process) != 0) { -+ memdcd_log(_LOG_ERROR, "Error creating pthread for process %d. err: %s", -+ process->pid, strerror_r(errno, error_str, ERROR_STR_MAX_LEN)); -+ return -1; -+ } -+ } else { -+ return -1; -+ } -+ return 0; -+} -+ -diff --git a/userswap/CMakeLists.txt b/userswap/CMakeLists.txt -new file mode 100644 -index 0000000..415b0f7 ---- /dev/null -+++ b/userswap/CMakeLists.txt -@@ -0,0 +1,36 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: LiuYongqiang -+# * Create: 2020-11-06 -+# * Description: CMakefileList for userswap to compile -+# ******************************************************************************/ -+ -+cmake_minimum_required (VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) -+ -+project(libuswap) -+ -+set(SRC_DIR ${PROJECT_SOURCE_DIR}/src) -+set(BUILD_DIR ${PROJECT_SOURCE_DIR}/build) -+ -+set(USWAP_SRC -+ ${SRC_DIR}/lib_uswap.c -+ ${SRC_DIR}/uswap_server.c -+ ${SRC_DIR}/uswap_log.c) -+ -+include_directories(${PROJECT_SOURCE_DIR}/include) -+ -+add_library(uswap STATIC ${USWAP_SRC}) -+ -+target_compile_options(uswap PRIVATE -fPIC -ftrapv -D_FORTIFY_SOURCE=2 -O2 -+-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -fvisibility=hidden) -+ -+install(TARGETS uswap PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE DESTINATION /usr/lib64) -+install(FILES ${PROJECT_SOURCE_DIR}/include/uswap_api.h DESTINATION /usr/include) -diff --git a/userswap/License/LICENSE b/userswap/License/LICENSE -new file mode 100644 -index 0000000..0db93af ---- /dev/null -+++ b/userswap/License/LICENSE -@@ -0,0 +1,127 @@ -+木兰宽松许可证, 第2版 -+ -+ 木兰宽松许可证, 第2版 -+ 2020年1月 http://license.coscl.org.cn/MulanPSL2 -+ -+ -+ 您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束: -+ -+ 0. 定义 -+ -+ “软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。 -+ -+ “贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。 -+ -+ “贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。 -+ -+ “法人实体”是指提交贡献的机构及其“关联实体”。 -+ -+ “关联实体”是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 -+ -+ 1. 授予版权许可 -+ -+ 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。 -+ -+ 2. 授予专利许可 -+ -+ 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。 -+ -+ 3. 无商标许可 -+ -+ “本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。 -+ -+ 4. 分发限制 -+ -+ 您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。 -+ -+ 5. 免责声明与责任限制 -+ -+ “软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。 -+ -+ 6. 语言 -+ “本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。 -+ -+ 条款结束 -+ -+ 如何将木兰宽松许可证,第2版,应用到您的软件 -+ -+ 如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: -+ -+ 1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; -+ -+ 2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中; -+ -+ 3, 请将如下声明文本放入每个源文件的头部注释中。 -+ -+ Copyright (c) [Year] [name of copyright holder] -+ [Software Name] is licensed under Mulan PSL v2. -+ You can use this software according to the terms and conditions of the Mulan PSL v2. -+ You may obtain a copy of Mulan PSL v2 at: -+ http://license.coscl.org.cn/MulanPSL2 -+ THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -+ See the Mulan PSL v2 for more details. -+ -+ -+ Mulan Permissive Software License,Version 2 -+ -+ Mulan Permissive Software License,Version 2 (Mulan PSL v2) -+ January 2020 http://license.coscl.org.cn/MulanPSL2 -+ -+ Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions: -+ -+ 0. Definition -+ -+ Software means the program and related documents which are licensed under this License and comprise all Contribution(s). -+ -+ Contribution means the copyrightable work licensed by a particular Contributor under this License. -+ -+ Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License. -+ -+ Legal Entity means the entity making a Contribution and all its Affiliates. -+ -+ Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity. -+ -+ 1. Grant of Copyright License -+ -+ Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not. -+ -+ 2. Grant of Patent License -+ -+ Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken. -+ -+ 3. No Trademark License -+ -+ No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in Section 4. -+ -+ 4. Distribution Restriction -+ -+ You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software. -+ -+ 5. Disclaimer of Warranty and Limitation of Liability -+ -+ THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -+ -+ 6. Language -+ -+ THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL. -+ -+ END OF THE TERMS AND CONDITIONS -+ -+ How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software -+ -+ To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps: -+ -+ i Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner; -+ -+ ii Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package; -+ -+ iii Attach the statement to the appropriate annotated syntax at the beginning of each source file. -+ -+ -+ Copyright (c) [Year] [name of copyright holder] -+ [Software Name] is licensed under Mulan PSL v2. -+ You can use this software according to the terms and conditions of the Mulan PSL v2. -+ You may obtain a copy of Mulan PSL v2 at: -+ http://license.coscl.org.cn/MulanPSL2 -+ THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -+ See the Mulan PSL v2 for more details. -diff --git a/userswap/README.md b/userswap/README.md -new file mode 100644 -index 0000000..b02edfe ---- /dev/null -+++ b/userswap/README.md -@@ -0,0 +1,7 @@ -+# Introduction -+userswap is a component of RAA memory-fabric. It supplies a userswap method for -+storage and net devices which is designed by user-mode protocol. It works with -+special kernel. -+ -+# Build -+./configure -diff --git a/userswap/configure.sh b/userswap/configure.sh -new file mode 100644 -index 0000000..6bca78d ---- /dev/null -+++ b/userswap/configure.sh -@@ -0,0 +1,4 @@ -+mkdir build -+cd ./build -+cmake .. -+make -diff --git a/userswap/include/uswap_api.h b/userswap/include/uswap_api.h -new file mode 100644 -index 0000000..9e26dfe ---- /dev/null -+++ b/userswap/include/uswap_api.h -@@ -0,0 +1,69 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+ * userswap licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liuyongqiang -+ * Create: 2020-11-06 -+ * Description: userswap interface -+ ******************************************************************************/ -+ -+#ifndef __USWAP_API_H__ -+#define __USWAP_API_H__ -+ -+#include -+ -+#define USWAP_SUCCESS 0 -+#define USWAP_ERROR (-1) -+#define USWAP_UNREGISTER_MEM (-2) -+#define USWAP_ALREADY_SWAPPED (-3) -+#define USWAP_ABORT (-4) -+#define USWAP_ALREADY_SWAPIN (-5) -+ -+#define MAX_USWAP_NAME_LEN 32 -+#define MAX_SWAPIN_THREAD_NUMS 5 -+ -+/* flag field of struct swap_data */ -+#define USWAP_DATA_DIRTY 0x1 -+#define USWAP_DATA_ABORT 0x2 -+ -+struct swap_data { -+ void *start_va; -+ size_t len; -+ void *buf; -+ /* -+ * Bit 0 (Dirty Flag): -+ * indicate the data in the range of 'start_va ~ start_va+len' is -+ * dirty if this bit is set. -+ * Bit 1 (Abort Flag): -+ * This bit only takes affect in do_swapout. It indicates -+ * aborting the swapout operation if it is set. -+ */ -+ size_t flag; -+}; -+ -+struct uswap_operations { -+ int (*get_swapout_buf) (const void *, size_t, struct swap_data *); -+ int (*do_swapout) (struct swap_data *); -+ int (*do_swapin) (const void *, struct swap_data *); -+ int (*release_buf) (struct swap_data *); -+}; -+ -+int set_uswap_log_level(int log_level); -+ -+int register_userfaultfd(void *addr, size_t size); -+ -+int unregister_userfaultfd(void *addr, size_t size); -+ -+int register_uswap(const char *name, size_t len, -+ const struct uswap_operations *ops); -+ -+int force_swapout(const void *addr, size_t len); -+ -+int uswap_init(int swapin_nums); -+#endif -diff --git a/userswap/include/uswap_log.h b/userswap/include/uswap_log.h -new file mode 100644 -index 0000000..1084d16 ---- /dev/null -+++ b/userswap/include/uswap_log.h -@@ -0,0 +1,30 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+ * userswap licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liuyongqiang -+ * Create: 2020-11-06 -+ * Description: userswap log headfile -+ ******************************************************************************/ -+ -+#ifndef __USWAP_LOG_H__ -+#define __USWAP_LOG_H__ -+ -+enum log_level { -+ USWAP_LOG_DEBUG = 0, -+ USWAP_LOG_INFO, -+ USWAP_LOG_WARN, -+ USWAP_LOG_ERR, -+ USWAP_LOG_INVAL, -+}; -+ -+int uswap_log_level_init(enum log_level level); -+ -+void uswap_log(enum log_level level, const char *format, ...); -+#endif -diff --git a/userswap/include/uswap_server.h b/userswap/include/uswap_server.h -new file mode 100644 -index 0000000..bcfb16f ---- /dev/null -+++ b/userswap/include/uswap_server.h -@@ -0,0 +1,40 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+ * userswap licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liuyongqiang -+ * Create: 2020-11-06 -+ * Description: userswap server interface -+ ******************************************************************************/ -+ -+#ifndef __USWAP_SERVER_H__ -+#define __USWAP_SERVER_H__ -+ -+#define MAX_VMA_NUM 512 -+ -+enum swap_type { -+ SWAP_TYPE_VMA_ADDR = 0xFFFFFF01, -+ SWAP_TYPE_MAX -+}; -+ -+struct vma_addr { -+ unsigned long start_addr; -+ unsigned long vma_len; -+}; -+ -+struct swap_vma { -+ enum swap_type type; -+ unsigned long length; -+ struct vma_addr vma_addrs[MAX_VMA_NUM]; -+}; -+ -+int init_socket(void); -+int sock_handle_rec(int fd, struct swap_vma *swap_vma); -+int sock_handle_respond(int client_fd, int result); -+#endif -diff --git a/userswap/src/lib_uswap.c b/userswap/src/lib_uswap.c -new file mode 100644 -index 0000000..0dc1337 ---- /dev/null -+++ b/userswap/src/lib_uswap.c -@@ -0,0 +1,663 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+ * userswap licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liuyongqiang -+ * Create: 2020-11-06 -+ * Description: userswap interface definition. -+ ******************************************************************************/ -+ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "uswap_server.h" -+#include "uswap_log.h" -+#include "uswap_api.h" -+ -+#define MAP_REPLACE 0x1000000 -+#ifndef UFFDIO_REGISTER_MODE_USWAP -+#define UFFDIO_REGISTER_MODE_USWAP (1 << 2) -+#endif -+#define MMAP_RETVAL_DIRTY_MASK 0x01L -+#define MAX_TRY_NUMS 10 -+ -+struct uswap_dev { -+ char name[MAX_USWAP_NAME_LEN]; -+ struct uswap_operations *ops; -+ bool enabled; -+ bool alive; -+ int uffd; -+ pthread_cond_t cond; -+ pthread_mutex_t mutex; -+}; -+ -+static struct uswap_dev g_dev = { -+ .name = "", -+ .ops = NULL, -+ .enabled = false, -+ .alive = false, -+ .uffd = -1, -+ .cond = PTHREAD_COND_INITIALIZER, -+ .mutex = PTHREAD_MUTEX_INITIALIZER, -+}; -+ -+static size_t get_page_size(void) -+{ -+ static size_t page_size = 0; -+ if (page_size != 0) { -+ return page_size; -+ } -+ -+ page_size = sysconf(_SC_PAGESIZE); -+ return page_size; -+} -+ -+static bool is_uswap_enabled(void) -+{ -+ return g_dev.enabled; -+} -+ -+static bool is_uswap_threads_alive(void) -+{ -+ return g_dev.alive; -+} -+ -+static int set_uswap_uffd(int uffd) -+{ -+ if (g_dev.uffd != -1) { -+ return USWAP_ERROR; -+ } -+ g_dev.uffd = uffd; -+ return USWAP_SUCCESS; -+} -+ -+static int get_uswap_uffd(void) -+{ -+ return g_dev.uffd; -+} -+ -+static void uswap_mutex_lock(void) -+{ -+ pthread_mutex_lock(&g_dev.mutex); -+} -+ -+static void uswap_mutex_unlock(void) -+{ -+ pthread_mutex_unlock(&g_dev.mutex); -+} -+ -+static void uswap_cond_wait(void) -+{ -+ pthread_cond_wait(&g_dev.cond, &g_dev.mutex); -+} -+ -+static void uswap_cond_wake(void) -+{ -+ pthread_cond_signal(&g_dev.cond); -+} -+ -+static int call_get_swapout_buf(const void *start_va, size_t len, -+ struct swap_data *swapout_data) -+{ -+ return g_dev.ops->get_swapout_buf(start_va, len, swapout_data); -+} -+ -+static int call_do_swapout(struct swap_data *swapout_data) -+{ -+ return g_dev.ops->do_swapout(swapout_data); -+} -+ -+static int call_do_swapin(const void *fault_addr, struct swap_data *swapin_data) -+{ -+ return g_dev.ops->do_swapin(fault_addr, swapin_data); -+} -+ -+static int call_release_buf(struct swap_data *swap_data) -+{ -+ return g_dev.ops->release_buf(swap_data); -+} -+ -+static int init_userfaultfd(void) -+{ -+ struct uffdio_api uffdio_api; -+ int uswap_uffd; -+ int ret; -+ -+ uswap_uffd = syscall(__NR_userfaultfd, O_NONBLOCK); -+ if (uswap_uffd < 0) { -+ return USWAP_ERROR; -+ } -+ -+ uffdio_api.api = UFFD_API; -+ uffdio_api.features = 0; -+ ret = ioctl(uswap_uffd, UFFDIO_API, &uffdio_api); -+ if (ret < 0) { -+ return ret; -+ } -+ ret = set_uswap_uffd(uswap_uffd); -+ return ret; -+} -+ -+int register_userfaultfd(void *addr, size_t size) -+{ -+ struct uffdio_register uffdio_register; -+ int ret; -+ int uswap_uffd; -+ size_t page_size; -+ -+ if (size > SSIZE_MAX || addr == NULL) { -+ return USWAP_ERROR; -+ } -+ -+ uswap_uffd = get_uswap_uffd(); -+ if (uswap_uffd < 0) { -+ uswap_mutex_lock(); -+ ret = init_userfaultfd(); -+ uswap_cond_wake(); -+ uswap_mutex_unlock(); -+ if (ret == USWAP_ERROR) { -+ uswap_log(USWAP_LOG_ERR, "init userfaultfd failed\n"); -+ return USWAP_ERROR; -+ } -+ uswap_uffd = get_uswap_uffd(); -+ } -+ -+ page_size = get_page_size(); -+ if (size >= page_size) { -+ uffdio_register.range.start = (unsigned long)addr; -+ uffdio_register.range.len = size; -+ uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING | -+ UFFDIO_REGISTER_MODE_USWAP; -+ ret = ioctl(uswap_uffd, UFFDIO_REGISTER, &uffdio_register); -+ if (ret < 0) { -+ uswap_log(USWAP_LOG_ERR, "register uffd failed\n"); -+ return USWAP_ERROR; -+ } -+ return USWAP_SUCCESS; -+ } -+ uswap_log(USWAP_LOG_ERR, "register uffd: the size smaller than page_size\n"); -+ return USWAP_ERROR; -+} -+ -+int unregister_userfaultfd(void *addr, size_t size) -+{ -+ struct uffdio_register uffdio_register; -+ int uswap_uffd; -+ int ret; -+ -+ uswap_uffd = get_uswap_uffd(); -+ if (uswap_uffd < 0 || size > SSIZE_MAX || addr == NULL) { -+ return USWAP_ERROR; -+ } -+ -+ uffdio_register.range.start = (unsigned long)addr; -+ uffdio_register.range.len = size; -+ ret = ioctl(uswap_uffd, UFFDIO_UNREGISTER, &uffdio_register); -+ if (ret < 0) { -+ uswap_log(USWAP_LOG_ERR, "unregister userfaultfd failed\n"); -+ return USWAP_ERROR; -+ } -+ return USWAP_SUCCESS; -+} -+ -+int register_uswap(const char *name, size_t len, -+ const struct uswap_operations *ops) -+{ -+ static struct uswap_operations uswap_ops; -+ if (name == NULL || len > MAX_USWAP_NAME_LEN - 1) { -+ return USWAP_ERROR; -+ } -+ -+ if (ops == NULL) { -+ return USWAP_ERROR; -+ } -+ -+ if (ops->get_swapout_buf == NULL || ops->do_swapout == NULL || -+ ops->do_swapin == NULL || ops->release_buf == NULL) { -+ return USWAP_ERROR; -+ } -+ -+ uswap_ops = *ops; -+ -+ snprintf(g_dev.name, MAX_USWAP_NAME_LEN, "%s", name); -+ g_dev.ops = &uswap_ops; -+ g_dev.enabled = true; -+ uswap_log(USWAP_LOG_INFO, "register uswap ops [%s] success\n", g_dev.name); -+ return USWAP_SUCCESS; -+} -+ -+static int mlock_pthread_stack(pthread_t tid) -+{ -+ int ret; -+ pthread_attr_t attr_t; -+ void *stack_addr = NULL; -+ size_t stack_size; -+ -+ ret = pthread_getattr_np(tid, &attr_t); -+ if (ret < 0) { -+ return USWAP_ERROR; -+ } -+ ret = pthread_attr_getstack(&attr_t, &stack_addr, &stack_size); -+ pthread_attr_destroy(&attr_t); -+ if (ret < 0) { -+ return USWAP_ERROR; -+ } -+ -+ ret = mlock(stack_addr, stack_size); -+ if (ret < 0) { -+ return USWAP_ERROR; -+ } -+ return USWAP_SUCCESS; -+} -+ -+static int read_uffd_msg(int uffd, struct uffd_msg *msg) -+{ -+ int ret; -+ int msg_len = sizeof(struct uffd_msg); -+ -+ for (int i = 0; i < MAX_TRY_NUMS; i++) { -+ ret = read(uffd, msg, msg_len); -+ if (ret != msg_len) { -+ if (errno == EAGAIN) { -+ continue; -+ } -+ return USWAP_ERROR; -+ } -+ -+ if (msg->event != UFFD_EVENT_PAGEFAULT) { -+ uswap_log(USWAP_LOG_ERR, "unexpected event on userfaultfd\n"); -+ return USWAP_ERROR; -+ } -+ return USWAP_SUCCESS; -+ } -+ return USWAP_ABORT; -+} -+ -+static int ioctl_uffd_copy_pages(int uffd, const struct swap_data *swapin_data) -+{ -+ int ret; -+ int offset = 0; -+ size_t page_size = get_page_size(); -+ struct uffdio_copy uffdio_copy = { -+ .len = page_size, -+ .mode = 0, -+ .copy = 0, -+ }; -+ -+ while (offset < swapin_data->len) { -+ uffdio_copy.src = (unsigned long)swapin_data->buf + offset; -+ uffdio_copy.dst = (unsigned long)swapin_data->start_va + offset; -+ ret = ioctl(uffd, UFFDIO_COPY, &uffdio_copy); -+ if (ret < 0 && errno != EEXIST) { -+ uswap_log(USWAP_LOG_ERR, "uffd ioctl copy one page failed\n"); -+ return USWAP_ERROR; -+ } -+ offset += page_size; -+ } -+ -+ return USWAP_SUCCESS; -+} -+ -+static int ioctl_uffd_copy(int uffd, struct swap_data *swapin_data) -+{ -+ int ret; -+ struct uffdio_copy uffdio_copy = { -+ .src = (unsigned long)swapin_data->buf, -+ .dst = (unsigned long)swapin_data->start_va, -+ .len = swapin_data->len, -+ .mode = 0, -+ .copy = 0, -+ }; -+ for (int i = 0; i < MAX_TRY_NUMS; i++) { -+ ret = ioctl(uffd, UFFDIO_COPY, &uffdio_copy); -+ if (ret < 0) { -+ if (errno == EAGAIN) { -+ continue; -+ } -+ -+ if (errno == EEXIST) { -+ return USWAP_ALREADY_SWAPIN; -+ } -+ /* -+ * 'start_va ~ start_va+len' may exceed the range of one vma. -+ * If that is the case, copy one page at a time. -+ */ -+ ret = ioctl_uffd_copy_pages(uffd, swapin_data); -+ if (ret == USWAP_ERROR) { -+ return USWAP_ERROR; -+ } -+ } -+ return USWAP_SUCCESS; -+ } -+ uswap_log(USWAP_LOG_ERR, "ioctl copy max try failed\n"); -+ return USWAP_ERROR; -+} -+ -+static void *swapin_thread(void *arg) -+{ -+ struct swap_data swapin_data; -+ struct uffd_msg uffd_msg; -+ struct pollfd pollfd; -+ unsigned long fault_addr; -+ int uswap_uffd; -+ int ret; -+ -+ prctl(PR_SET_NAME, "uswap-swapin", 0, 0, 0); -+ -+ uswap_mutex_lock(); -+ uswap_uffd = get_uswap_uffd(); -+ while (uswap_uffd < 0) { -+ uswap_cond_wait(); -+ uswap_uffd = get_uswap_uffd(); -+ } -+ uswap_mutex_unlock(); -+ while (1) { -+ pollfd.fd = uswap_uffd; -+ pollfd.events = POLLIN; -+ ret = poll(&pollfd, 1, -1); -+ if (ret < 0) { -+ uswap_log(USWAP_LOG_ERR, "poll failed\n"); -+ usleep(10); -+ continue; -+ } -+ ret = read_uffd_msg(uswap_uffd, &uffd_msg); -+ if (ret == USWAP_ABORT) { -+ continue; -+ } else if (ret == USWAP_ERROR) { -+ uswap_log(USWAP_LOG_ERR, "read uffd failed\n"); -+ continue; -+ } -+ -+ fault_addr = uffd_msg.arg.pagefault.address; -+ -+ ret = call_do_swapin((void *)fault_addr, &swapin_data); -+ if (ret == USWAP_ERROR) { -+ uswap_log(USWAP_LOG_ERR, "do_swapin failed\n"); -+ exit(-1); -+ } -+ -+ ret = ioctl_uffd_copy(uswap_uffd, &swapin_data); -+ if (ret == USWAP_ERROR) { -+ uswap_log(USWAP_LOG_ERR, "uffd ioctl copy failed\n"); -+ exit(-1); -+ } -+ ret = call_release_buf(&swapin_data); -+ if (ret == USWAP_ERROR) { -+ uswap_log(USWAP_LOG_ERR, "release buf failed\n"); -+ } -+ } -+} -+ -+static void* mmap_tmpva(const void *start, size_t len, int *is_dirty) -+{ -+ unsigned long new_addr; -+ new_addr = syscall(__NR_mmap, start, len, PROT_READ | PROT_WRITE, -+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_REPLACE, -1, 0); -+ if ((void *)new_addr == MAP_FAILED) { -+ if (errno != ENODEV) { -+ uswap_log(USWAP_LOG_ERR, "the addr can't be swapout\n"); -+ } -+ return MAP_FAILED; -+ } else { -+ *is_dirty = new_addr & MMAP_RETVAL_DIRTY_MASK; -+ new_addr = new_addr & (~MMAP_RETVAL_DIRTY_MASK); -+ } -+ return (void *)new_addr; -+} -+ -+static int do_swapout_once(const void *start, size_t len, -+ struct swap_data *swapout_data) -+{ -+ int ret; -+ int is_dirty = 1; -+ void *tmpva = NULL; -+ -+ ret = call_get_swapout_buf(start, len, swapout_data); -+ if (ret == USWAP_ALREADY_SWAPPED) { -+ return USWAP_SUCCESS; -+ } -+ if (ret < 0) { -+ uswap_log(USWAP_LOG_ERR, "get swapout buf error\n"); -+ return ret; -+ } -+ -+ tmpva = mmap_tmpva(swapout_data->start_va, swapout_data->len, &is_dirty); -+ -+ swapout_data->flag = 0; -+ if (tmpva != MAP_FAILED) { -+ memcpy(swapout_data->buf, tmpva, swapout_data->len); -+ munmap(tmpva, swapout_data->len); -+ } else { -+ swapout_data->flag |= USWAP_DATA_ABORT; -+ } -+ -+ if (is_dirty != 0) { -+ swapout_data->flag |= USWAP_DATA_DIRTY; -+ } -+ -+ ret = call_do_swapout(swapout_data); -+ -+ return ret; -+} -+ -+static int do_swapout(const void *start, size_t len) -+{ -+ int ret; -+ size_t succ_len = 0; -+ struct swap_data swapout_data; -+ -+ while (succ_len < len) { -+ ret = do_swapout_once(start + succ_len, len - succ_len, &swapout_data); -+ if (ret < 0) { -+ return ret; -+ } -+ if (succ_len >= len - swapout_data.len) { -+ break; -+ } -+ succ_len += swapout_data.len; -+ } -+ uswap_log(USWAP_LOG_DEBUG, "do swapout addr: %p, len %lx\n", start, len); -+ return succ_len; -+} -+ -+static int vma_merge(const struct swap_vma *src, struct swap_vma *dst) -+{ -+ int index = 0; -+ int swapout_nums; -+ size_t page_size = get_page_size(); -+ -+ swapout_nums = src->length / sizeof(struct vma_addr); -+ if (swapout_nums > MAX_VMA_NUM) { -+ swapout_nums = MAX_VMA_NUM; -+ } -+ for (int i = 0; i < swapout_nums; i++) { -+ if (src->vma_addrs[i].vma_len == 0 || -+ src->vma_addrs[i].vma_len > SSIZE_MAX) { -+ continue; -+ } -+ if (src->vma_addrs[i].vma_len == page_size) { -+ int j = i + 1; -+ dst->vma_addrs[index].start_addr = src->vma_addrs[i].start_addr; -+ dst->vma_addrs[index].vma_len = page_size; -+ while (j < swapout_nums && -+ src->vma_addrs[j - 1].start_addr + page_size == -+ src->vma_addrs[j].start_addr) { -+ j++; -+ dst->vma_addrs[index].vma_len += page_size; -+ } -+ i = j - 1; -+ index++; -+ } else { -+ dst->vma_addrs[index].start_addr = src->vma_addrs[i].start_addr; -+ dst->vma_addrs[index].vma_len = src->vma_addrs[i].vma_len; -+ index++; -+ } -+ } -+ dst->length = index * sizeof(struct vma_addr); -+ return USWAP_SUCCESS; -+} -+ -+static int swapout_source_init(void) -+{ -+ size_t page_size; -+ int socket_fd = -1; -+ -+ page_size = get_page_size(); -+ socket_fd = init_socket(); -+ if (socket_fd < 0) { -+ uswap_log(USWAP_LOG_DEBUG, "init_socket failed err:%d\n", errno); -+ return USWAP_ERROR; -+ } -+ return socket_fd; -+} -+ -+static void *swapout_thread(void *arg) -+{ -+ struct swap_vma src, dst; -+ unsigned long start; -+ size_t len; -+ int swapout_nums; -+ int succ_count = 0; -+ int socket_fd, client_fd; -+ int ret; -+ -+ prctl(PR_SET_NAME, "uswap-swapout", 0, 0, 0); -+ ret = swapout_source_init(); -+ if (ret < 0) { -+ uswap_log(USWAP_LOG_ERR, "swapout source init failed\n"); -+ return NULL; -+ } -+ socket_fd = ret; -+ while (1) { -+ client_fd = sock_handle_rec(socket_fd, &src); -+ if (client_fd <= 0) { -+ uswap_log(USWAP_LOG_DEBUG, "sock_handle_rec failed\n"); -+ continue; -+ } -+ -+ vma_merge(&src, &dst); -+ ret = USWAP_SUCCESS; -+ swapout_nums = dst.length / sizeof(struct vma_addr); -+ for (int i = 0; i < swapout_nums; i++) { -+ len = dst.vma_addrs[i].vma_len; -+ start = dst.vma_addrs[i].start_addr; -+ succ_count = do_swapout((void *)start, len); -+ if (succ_count < 0) { -+ uswap_log(USWAP_LOG_ERR, "do swapout once failed\n"); -+ ret = USWAP_ERROR; -+ } -+ } -+ sock_handle_respond(client_fd, ret); -+ } -+ close(socket_fd); -+} -+ -+int force_swapout(const void *addr, size_t len) -+{ -+ int ret; -+ size_t page_size = get_page_size(); -+ if (!is_uswap_enabled() || !is_uswap_threads_alive()) { -+ return USWAP_ERROR; -+ } -+ if (addr == NULL || len > SSIZE_MAX) { -+ return USWAP_ERROR; -+ } -+ -+ ret = do_swapout(addr, len); -+ return ret; -+} -+ -+static int create_uswap_threads(int swapin_nums) -+{ -+ int ret; -+ pthread_t swapout_tid; -+ pthread_t swapin_tid[MAX_SWAPIN_THREAD_NUMS]; -+ -+ if (swapin_nums <= 0 || swapin_nums > MAX_SWAPIN_THREAD_NUMS) { -+ return USWAP_ERROR; -+ } -+ -+ ret = pthread_create(&swapout_tid, NULL, swapout_thread, NULL); -+ if (ret < 0) { -+ uswap_log(USWAP_LOG_ERR, "can't create swapout thread"); -+ return USWAP_ERROR; -+ } -+ ret = mlock_pthread_stack(swapout_tid); -+ if (ret == USWAP_ERROR) { -+ uswap_log(USWAP_LOG_ERR, "mlock swapout thread stack failed\n"); -+ pthread_cancel(swapout_tid); -+ return USWAP_ERROR; -+ } -+ -+ for (int i = 0; i < swapin_nums; i++) { -+ ret = pthread_create(&swapin_tid[i], NULL, swapin_thread, NULL); -+ if (ret < 0) { -+ uswap_log(USWAP_LOG_ERR, "can't create swapin thread\n"); -+ pthread_cancel(swapout_tid); -+ for (int j = 0; j < i; j++) { -+ pthread_cancel(swapin_tid[j]); -+ } -+ return USWAP_ERROR; -+ } -+ ret = mlock_pthread_stack(swapin_tid[i]); -+ if (ret == USWAP_ERROR) { -+ uswap_log(USWAP_LOG_ERR, "mlock swapin thread stack failed\n"); -+ pthread_cancel(swapout_tid); -+ for (int j = 0; j <= i; j++) { -+ pthread_cancel(swapin_tid[j]); -+ } -+ return USWAP_ERROR; -+ } -+ } -+ -+ return USWAP_SUCCESS; -+} -+ -+int set_uswap_log_level(int log_level) -+{ -+ return uswap_log_level_init(log_level); -+} -+ -+int uswap_init(int swapin_nums) -+{ -+ int ret; -+ -+ if (!is_uswap_enabled() || is_uswap_threads_alive()) { -+ return USWAP_ERROR; -+ } -+ -+ ret = create_uswap_threads(swapin_nums); -+ if (ret == USWAP_ERROR) { -+ return USWAP_ERROR; -+ } -+ -+ g_dev.alive = true; -+ return USWAP_SUCCESS; -+} -diff --git a/userswap/src/uswap_log.c b/userswap/src/uswap_log.c -new file mode 100644 -index 0000000..09bdff6 ---- /dev/null -+++ b/userswap/src/uswap_log.c -@@ -0,0 +1,81 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+ * userswap licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liuyongqiang -+ * Create: 2020-11-06 -+ * Description: userswap log definition. -+ ******************************************************************************/ -+ -+#include -+#include -+#include -+#include -+#include "uswap_log.h" -+ -+enum log_level g_log_level = USWAP_LOG_ERR; -+ -+static void log_level_usage(void) -+{ -+ printf("\n" -+ "[0] for debug level\n" -+ "[1] for info level\n" -+ "[2] for warning level\n" -+ "[3] for error level\n" -+ "default level is error\n" -+ "\n"); -+} -+ -+int uswap_log_level_init(enum log_level level) -+{ -+ if (level < 0 || level >= USWAP_LOG_INVAL) { -+ printf("error: invalid log level [%d]\n", level); -+ log_level_usage(); -+ return -EINVAL; -+ } -+ g_log_level = level; -+ return 0; -+} -+ -+void uswap_log(enum log_level level, const char *format, ...) -+{ -+ va_list args; -+ -+ if (level < g_log_level) { -+ return; -+ } -+ -+ va_start(args, format); -+ -+ switch (level) { -+ case USWAP_LOG_DEBUG: -+ openlog("[uswap_debug] ", LOG_PID, LOG_USER); -+ vsyslog(LOG_INFO, format, args); -+ break; -+ case USWAP_LOG_INFO: -+ openlog("[uswap_info] ", LOG_PID, LOG_USER); -+ vsyslog(LOG_INFO, format, args); -+ break; -+ case USWAP_LOG_WARN: -+ openlog("[uswap_warn] ", LOG_PID, LOG_USER); -+ vsyslog(LOG_WARNING, format, args); -+ break; -+ case USWAP_LOG_ERR: -+ openlog("[uswap_error] ", LOG_PID, LOG_USER); -+ vsyslog(LOG_ERR, format, args); -+ break; -+ default: -+ openlog("[uswap_error] ", LOG_PID, LOG_USER); -+ vsyslog(LOG_ERR, "invalid uswap_log_level\n", args); -+ } -+ -+ va_end(args); -+ closelog(); -+ return; -+} -diff --git a/userswap/src/uswap_server.c b/userswap/src/uswap_server.c -new file mode 100644 -index 0000000..ecb16a9 ---- /dev/null -+++ b/userswap/src/uswap_server.c -@@ -0,0 +1,138 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+ * userswap licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liuyongqiang -+ * Create: 2020-11-06 -+ * Description: userswap server definition. -+ ******************************************************************************/ -+ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "uswap_log.h" -+#include "uswap_server.h" -+ -+#define MAX_LISTENQ_NUM 1 -+#define RESP_MSG_MAX_LEN 10 -+#define PATH_MAX_LEN 127 -+ -+ -+int init_socket(void) -+{ -+ int socket_fd; -+ int addrlen; -+ struct sockaddr_un addr; -+ char abstract_path[PATH_MAX_LEN] = {0}; -+ pid_t pid = getpid(); -+ -+ socket_fd = socket(AF_LOCAL, SOCK_STREAM, 0); -+ if (socket_fd < 0) { -+ uswap_log(USWAP_LOG_ERR, "create socket failed\n"); -+ return -EINVAL; -+ } -+ -+ bzero(&addr, sizeof(struct sockaddr_un)); -+ addr.sun_family = AF_UNIX; -+ addr.sun_path[0] = 0; -+ snprintf(abstract_path, sizeof(abstract_path), "userswap%d.sock", pid); -+ memcpy(addr.sun_path + 1, abstract_path, strlen(abstract_path) + 1); -+ addrlen = sizeof(addr.sun_family) + strlen(abstract_path) + 1; -+ if (bind(socket_fd, (struct sockaddr *)&addr, addrlen) < 0) { -+ uswap_log(USWAP_LOG_ERR, "bind socket failed\n"); -+ close(socket_fd); -+ return -EINVAL; -+ } -+ -+ listen(socket_fd, MAX_LISTENQ_NUM); -+ -+ return socket_fd; -+} -+ -+static int check_socket_permission(int fd, int client_fd) -+{ -+ struct ucred local_cred, client_cred; -+ socklen_t len; -+ int ret; -+ -+ len = sizeof(struct ucred); -+ ret = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &local_cred, &len); -+ if (ret < 0) { -+ uswap_log(USWAP_LOG_ERR, "get server sockopt failed\n"); -+ return ret; -+ } -+ ret = getsockopt(client_fd, SOL_SOCKET, SO_PEERCRED, &client_cred, &len); -+ if (ret < 0) { -+ uswap_log(USWAP_LOG_ERR, "get client sockopt failed\n"); -+ return ret; -+ } -+ -+ if (local_cred.uid != client_cred.uid || -+ local_cred.gid != client_cred.gid) { -+ return -EPERM; -+ } -+ return 0; -+} -+ -+int sock_handle_rec(int fd, struct swap_vma *swap_vma) -+{ -+ int client_fd; -+ int readbytes; -+ struct sockaddr_un clientun; -+ socklen_t clientun_len = sizeof(clientun); -+ -+ client_fd = accept(fd, (struct sockaddr *)&clientun, &clientun_len); -+ if (client_fd < 0) { -+ return -EINVAL; -+ } -+ -+ if (check_socket_permission(fd, client_fd) < 0) { -+ close(client_fd); -+ return -EPERM; -+ } -+ -+ readbytes = read(client_fd, swap_vma, sizeof(struct swap_vma)); -+ if (readbytes <= 0) { -+ close(client_fd); -+ return -EINVAL; -+ } -+ -+ return client_fd; -+} -+ -+int sock_handle_respond(int client_fd, int result) -+{ -+ int writebytes; -+ char buff[RESP_MSG_MAX_LEN] = {0}; -+ -+ if (client_fd < 0) { -+ return -EINVAL; -+ } -+ -+ if (result == 0) { -+ snprintf(buff, sizeof(buff), "success"); -+ } else { -+ snprintf(buff, sizeof(buff), "failed"); -+ } -+ -+ writebytes = write(client_fd, buff, (strlen(buff) + 1)); -+ if (writebytes != (strlen(buff) + 1)) { -+ close(client_fd); -+ return -EIO; -+ } -+ -+ close(client_fd); -+ return 0; -+} --- -2.27.0 - diff --git a/0049-Add-engine-memdcd-to-etmemd.patch b/0049-Add-engine-memdcd-to-etmemd.patch deleted file mode 100644 index ec8bc1f..0000000 --- a/0049-Add-engine-memdcd-to-etmemd.patch +++ /dev/null @@ -1,481 +0,0 @@ -From 498679879e2a81820126971839a23d307cdce9f5 Mon Sep 17 00:00:00 2001 -From: Yangxin <245051644@qq.com> -Date: Thu, 30 Sep 2021 18:09:41 +0800 -Subject: [PATCH 49/50] Add engine memdcd to etmemd. - -Signed-off-by: Yangxin <245051644@qq.com> ---- - etmem/CMakeLists.txt | 1 + - etmem/inc/etmemd_inc/etmemd_engine.h | 1 + - etmem/inc/etmemd_inc/etmemd_memdcd.h | 31 +++ - etmem/src/etmemd_src/etmemd_engine.c | 2 + - etmem/src/etmemd_src/etmemd_memdcd.c | 374 +++++++++++++++++++++++++++ - 5 files changed, 409 insertions(+) - create mode 100644 etmem/inc/etmemd_inc/etmemd_memdcd.h - create mode 100644 etmem/src/etmemd_src/etmemd_memdcd.c - -diff --git a/etmem/CMakeLists.txt b/etmem/CMakeLists.txt -index 6d11da9..b5eb83e 100644 ---- a/etmem/CMakeLists.txt -+++ b/etmem/CMakeLists.txt -@@ -31,6 +31,7 @@ set(ETMEMD_SRC - ${ETMEMD_SRC_DIR}/etmemd_log.c - ${ETMEMD_SRC_DIR}/etmemd_project.c - ${ETMEMD_SRC_DIR}/etmemd_engine.c -+ ${ETMEMD_SRC_DIR}/etmemd_memdcd.c - ${ETMEMD_SRC_DIR}/etmemd_slide.c - ${ETMEMD_SRC_DIR}/etmemd_cslide.c - ${ETMEMD_SRC_DIR}/etmemd_thirdparty.c -diff --git a/etmem/inc/etmemd_inc/etmemd_engine.h b/etmem/inc/etmemd_inc/etmemd_engine.h -index 0134d21..9a50e10 100644 ---- a/etmem/inc/etmemd_inc/etmemd_engine.h -+++ b/etmem/inc/etmemd_inc/etmemd_engine.h -@@ -24,6 +24,7 @@ - enum eng_type { - SLIDE_ENGINE = 0, - CSLIDE_ENGINE, -+ MEMDCD_ENGINE, - DYNAMIC_FB_ENGINE, - HISTORICAL_FB_ENGINE, - THIRDPARTY_ENGINE, -diff --git a/etmem/inc/etmemd_inc/etmemd_memdcd.h b/etmem/inc/etmemd_inc/etmemd_memdcd.h -new file mode 100644 -index 0000000..96f9307 ---- /dev/null -+++ b/etmem/inc/etmemd_inc/etmemd_memdcd.h -@@ -0,0 +1,31 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: YangXin -+ * Create: 2021-4-20 -+ * Description: This is a header file of the function declaration for memdcd engine.. -+ ******************************************************************************/ -+ -+ -+#ifndef ETMEMD_MEMDCD_H -+#define ETMEMD_MEMDCD_H -+ -+#include "etmemd_engine.h" -+ -+#define MAX_SOCK_PATH_LENGTH 108 -+ -+struct memdcd_params { -+ struct task_executor *executor; -+ char memdcd_socket[MAX_SOCK_PATH_LENGTH]; -+}; -+ -+int fill_engine_type_memdcd(struct engine *eng, GKeyFile *config); -+ -+#endif -diff --git a/etmem/src/etmemd_src/etmemd_engine.c b/etmem/src/etmemd_src/etmemd_engine.c -index f57d52b..6a14ecb 100644 ---- a/etmem/src/etmemd_src/etmemd_engine.c -+++ b/etmem/src/etmemd_src/etmemd_engine.c -@@ -18,6 +18,7 @@ - #include "etmemd_engine.h" - #include "etmemd_slide.h" - #include "etmemd_cslide.h" -+#include "etmemd_memdcd.h" - #include "etmemd_thirdparty.h" - #include "etmemd_log.h" - #include "etmemd_common.h" -@@ -36,6 +37,7 @@ struct engine_remove_item { - static struct engine_add_item g_engine_add_items[] = { - {"slide", fill_engine_type_slide}, - {"cslide", fill_engine_type_cslide}, -+ {"memdcd", fill_engine_type_memdcd}, - {"thirdparty", fill_engine_type_thirdparty}, - }; - -diff --git a/etmem/src/etmemd_src/etmemd_memdcd.c b/etmem/src/etmemd_src/etmemd_memdcd.c -new file mode 100644 -index 0000000..635e5a2 ---- /dev/null -+++ b/etmem/src/etmemd_src/etmemd_memdcd.c -@@ -0,0 +1,374 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: Yangxin -+ * Create: 2021-04-05 -+ * Description: API of memdcd engine. -+ ******************************************************************************/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "securec.h" -+#include "etmemd_log.h" -+#include "etmemd_common.h" -+#include "etmemd_engine.h" -+#include "etmemd_scan.h" -+#include "etmemd_migrate.h" -+#include "etmemd_pool_adapter.h" -+#include "etmemd_file.h" -+#include "etmemd_memdcd.h" -+ -+#define MAX_VMA_NUM 512 -+#define RESP_MSG_MAX_LEN 10 -+#define CLIENT_RECV_DEFAULT_TIME 10 -+ -+enum MEMDCD_CMD_TYPE { -+ MEMDCD_CMD_MEM = 0 -+}; -+ -+enum SwapType { -+ SWAP_TYPE_VMA_ADDR = 0xFFFFFF01, -+ SWAP_TYPE_MAX -+}; -+ -+struct vma_addr { -+ uint64_t start_addr; -+ uint64_t vma_len; -+}; -+ -+struct vma_addr_with_count { -+ struct vma_addr vma; -+ int count; -+}; -+ -+enum MEMDCD_MESSAGE_STATUS { -+ MEMDCD_SEND_START, -+ MEMDCD_SEND_PROCESS, -+ MEMDCD_SEND_END, -+}; -+ -+struct swap_vma_with_count { -+ enum SwapType type; -+ uint64_t length; -+ uint64_t total_length; -+ enum MEMDCD_MESSAGE_STATUS status; -+ struct vma_addr_with_count vma_addrs[MAX_VMA_NUM]; -+}; -+ -+struct memory_message { -+ int pid; -+ uint32_t enable_uswap; -+ struct swap_vma_with_count vma; -+}; -+ -+struct memdcd_message { -+ enum MEMDCD_CMD_TYPE cmd_type; -+ union { -+ struct memory_message memory_msg; -+ }; -+}; -+ -+static int memdcd_connection_init(time_t tm_out, const char sock_path[]) -+{ -+ struct sockaddr_un addr; -+ int len; -+ -+ int sockfd = socket(AF_UNIX, SOCK_STREAM, 0); -+ if (sockfd < 0){ -+ etmemd_log(ETMEMD_LOG_ERR, "new socket for memdcd error."); -+ return -1; -+ } -+ -+ len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path); -+ -+ if (memset_s(&addr, sizeof(struct sockaddr_un), -+ 0, sizeof(struct sockaddr_un)) != EOK) { -+ etmemd_log(ETMEMD_LOG_ERR, "clear addr failed\n"); -+ goto err_out; -+ } -+ -+ addr.sun_family = AF_UNIX; -+ if (memcpy_s(addr.sun_path, sizeof(addr.sun_path), -+ sock_path, strlen(sock_path)) != EOK) { -+ etmemd_log(ETMEMD_LOG_ERR, "copy for memdcd server path to addr fail, error(%s)\n", -+ strerror(errno)); -+ goto err_out; -+ } -+ -+ /* note, the below two line **MUST** maintain the order */ -+ len = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path); -+ addr.sun_path[0] = '\0'; -+ if (connect(sockfd, (struct sockaddr *)&addr, len) < 0){ -+ etmemd_log(ETMEMD_LOG_ERR, "connect memdcd failed\n"); -+ goto err_out; -+ } -+ -+ return sockfd; -+ -+err_out: -+ close(sockfd); -+ return -1; -+} -+ -+static int send_data_to_memdcd(unsigned int pid, struct memdcd_message *msg, const char sock_path[]) -+{ -+ int client_fd; -+ int ret = 0; -+ int read_bytes; -+ int write_bytes; -+ char buff[RESP_MSG_MAX_LEN] = {0}; -+ time_t recv_timeout = CLIENT_RECV_DEFAULT_TIME; -+ -+ client_fd = memdcd_connection_init(recv_timeout, sock_path); -+ if (client_fd < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "%s: connect error %d.\n", __func__, client_fd); -+ return -1; -+ } -+ write_bytes = write(client_fd, msg, sizeof(struct memdcd_message)); -+ if (write_bytes <= 0) { -+ etmemd_log(ETMEMD_LOG_DEBUG, "etmemd_socket: send to memdcd for pid %u, bytes: %d\n", -+ pid, write_bytes); -+ ret = -1; -+ goto CLOSE_SOCK; -+ } -+ -+ read_bytes = read(client_fd, buff, RESP_MSG_MAX_LEN); -+ if (read_bytes > 0) { -+ if (strcmp(buff, "success") == 0) { -+ etmemd_log(ETMEMD_LOG_INFO, "etmemd_socket: recv respond success.\n"); -+ } else { -+ etmemd_log(ETMEMD_LOG_ERR, "etmemd_socket: recv respond failed.\n"); -+ ret = -1; -+ } -+ } -+ -+CLOSE_SOCK: -+ close(client_fd); -+ -+ return ret; -+} -+ -+static int memdcd_do_migrate(unsigned int pid, struct page_refs *page_refs_list, const char sock_path[]) -+{ -+ int count = 0, total_count = 0; -+ int ret = 0; -+ struct swap_vma_with_count *swap_vma = NULL; -+ struct page_refs *page_refs = page_refs_list; -+ struct memdcd_message *msg; -+ -+ if (page_refs_list == NULL) { -+ /* do nothing */ -+ return 0; -+ } -+ -+ while (page_refs != NULL) { -+ page_refs = page_refs->next; -+ total_count++; -+ } -+ page_refs = page_refs_list; -+ -+ msg = (struct memdcd_message *)calloc(1, sizeof(struct memdcd_message)); -+ if (msg == NULL) { -+ etmemd_log(ETMEMD_LOG_WARN, "memigd_socket: malloc for swap vma failed. \n"); -+ return -1; -+ } -+ -+ msg->cmd_type = MEMDCD_CMD_MEM; -+ msg->memory_msg.pid = pid; -+ msg->memory_msg.enable_uswap = true; -+ msg->memory_msg.vma.status = MEMDCD_SEND_START; -+ -+ swap_vma = &(msg->memory_msg.vma); -+ swap_vma->type = SWAP_TYPE_VMA_ADDR; -+ swap_vma->total_length = total_count; -+ -+ while (page_refs != NULL) { -+ swap_vma->vma_addrs[count].vma.start_addr = page_refs->addr; -+ swap_vma->vma_addrs[count].vma.vma_len = page_type_to_size(page_refs->type); -+ swap_vma->vma_addrs[count].count = page_refs->count; -+ count++; -+ page_refs = page_refs->next; -+ -+ if (count < MAX_VMA_NUM) { -+ continue; -+ } -+ if (page_refs == NULL) { -+ break; -+ } -+ swap_vma->length = count * sizeof(struct vma_addr_with_count); -+ if (send_data_to_memdcd(pid, msg, sock_path) != 0) { -+ ret = -1; -+ goto FREE_SWAP; -+ } -+ count = 0; -+ msg->memory_msg.vma.status = MEMDCD_SEND_PROCESS; -+ if (memset_s(swap_vma->vma_addrs, sizeof(swap_vma->vma_addrs), -+ 0, sizeof(swap_vma->vma_addrs)) != EOK) { -+ etmemd_log(ETMEMD_LOG_ERR, "clear swap_vma failed\n"); -+ ret = -1; -+ goto FREE_SWAP; -+ } -+ } -+ -+ if (msg->memory_msg.vma.status != MEMDCD_SEND_START) -+ msg->memory_msg.vma.status = MEMDCD_SEND_END; -+ swap_vma->length = count * sizeof(struct vma_addr_with_count); -+ if (send_data_to_memdcd(pid, msg, sock_path) != 0) { -+ ret = -1; -+ } -+ -+FREE_SWAP: -+ free(msg); -+ return ret; -+} -+ -+static void *memdcd_executor(void *arg) -+{ -+ struct task_pid *tk_pid = (struct task_pid *)arg; -+ struct memdcd_params *memdcd_params = (struct memdcd_params *)(tk_pid->tk->params); -+ struct page_refs *page_refs = 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_page_refs_unexpected, &page_refs); -+ page_refs = etmemd_do_scan(tk_pid, tk_pid->tk); -+ if (page_refs != NULL) { -+ if (memdcd_do_migrate(tk_pid->pid, page_refs, memdcd_params->memdcd_socket) != 0) { -+ etmemd_log(ETMEMD_LOG_WARN, "memdcd migrate for pid %u fail\n", tk_pid->pid); -+ } -+ } -+ -+ /* 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); -+ -+ return NULL; -+} -+ -+static int fill_task_sock_path(void *obj, void *val) -+{ -+ const char *default_path = "@_memdcd.server"; -+ -+ struct memdcd_params *params = (struct memdcd_params *)obj; -+ char *sock_path = (char *)val; -+ -+ if(strcmp(sock_path, "-") == 0) { -+ if (strncpy_s(params->memdcd_socket, MAX_SOCK_PATH_LENGTH, default_path, strlen(default_path)) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "strncpy for memdcd_socket fail"); -+ return -1; -+ } -+ } else { -+ if (strncpy_s(params->memdcd_socket, MAX_SOCK_PATH_LENGTH, sock_path, strlen(sock_path)) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "strncpy for memdcd_socket fail"); -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct config_item g_memdcd_task_config_items[] = { -+ {"Sock", STR_VAL, fill_task_sock_path, false}, -+}; -+ -+static int memdcd_fill_task(GKeyFile *config, struct task *tk) -+{ -+ struct memdcd_params *params = calloc(1, sizeof(struct memdcd_params)); -+ memset_s(params->memdcd_socket, MAX_SOCK_PATH_LENGTH, 0, MAX_SOCK_PATH_LENGTH); -+ -+ if (params == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc memdcd param fail\n"); -+ return -1; -+ } -+ -+ if (parse_file_config(config, TASK_GROUP, g_memdcd_task_config_items, ARRAY_SIZE(g_memdcd_task_config_items), -+ (void *)params) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "memdcd fill task fail\n"); -+ goto free_params; -+ } -+ -+ if (strlen(params->memdcd_socket) >= MAX_SOCK_PATH_LENGTH) { -+ etmemd_log(ETMEMD_LOG_ERR, "length of engine param Sock must less than 108.\n"); -+ goto free_params; -+ } -+ -+ tk->params = params; -+ return 0; -+ -+free_params: -+ free(params); -+ return -1; -+} -+ -+static void memdcd_clear_task(struct task *tk) -+{ -+ free(tk->params); -+ tk->params = NULL; -+} -+ -+static int memdcd_start_task(struct engine *eng, struct task *tk) -+{ -+ struct memdcd_params *params = tk->params; -+ -+ params->executor = malloc(sizeof(struct task_executor)); -+ if (params->executor == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "memdcd alloc memory for task_executor fail\n"); -+ return -1; -+ } -+ -+ params->executor->tk = tk; -+ params->executor->func = memdcd_executor; -+ if (start_threadpool_work(params->executor) != 0) { -+ free(params->executor); -+ params->executor = NULL; -+ etmemd_log(ETMEMD_LOG_ERR, "memdcd start task executor fail\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static void memdcd_stop_task(struct engine *eng, struct task *tk) -+{ -+ struct memdcd_params *params = tk->params; -+ -+ stop_and_delete_threadpool_work(tk); -+ free(params->executor); -+ params->executor = NULL; -+} -+ -+struct engine_ops g_memdcd_eng_ops = { -+ .fill_eng_params = NULL, -+ .clear_eng_params = NULL, -+ .fill_task_params = memdcd_fill_task, -+ .clear_task_params = memdcd_clear_task, -+ .start_task = memdcd_start_task, -+ .stop_task = memdcd_stop_task, -+ .alloc_pid_params = NULL, -+ .free_pid_params = NULL, -+ .eng_mgt_func = NULL, -+}; -+ -+int fill_engine_type_memdcd(struct engine *eng, GKeyFile *config) -+{ -+ eng->ops = &g_memdcd_eng_ops; -+ eng->engine_type = MEMDCD_ENGINE; -+ eng->name = "memdcd"; -+ return 0; -+} -\ No newline at end of file --- -2.27.0 - diff --git a/0050-Add-CMakeLists.txt-for-three-features-of-etmem.patch b/0050-Add-CMakeLists.txt-for-three-features-of-etmem.patch deleted file mode 100644 index 8cd6ac7..0000000 --- a/0050-Add-CMakeLists.txt-for-three-features-of-etmem.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 1aef995d51254409b7aa1e2e84b9b750007e2413 Mon Sep 17 00:00:00 2001 -From: YangXin <245051644@qq.com> -Date: Thu, 30 Sep 2021 18:58:33 +0800 -Subject: [PATCH 50/50] Add CMakeLists.txt for three features of etmem. - -Signed-off-by: YangXin <245051644@qq.com> ---- - CMakeLists.txt | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - create mode 100644 CMakeLists.txt - -diff --git a/CMakeLists.txt b/CMakeLists.txt -new file mode 100644 -index 0000000..a5d6761 ---- /dev/null -+++ b/CMakeLists.txt -@@ -0,0 +1,18 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2020-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author:YangXin -+# * Create: 2021-09-31 -+# * Description:CMakeLists for three features of etmem to compile -+# ******************************************************************************/ -+ -+add_subdirectory(etmem) -+add_subdirectory(memRouter) -+add_subdirectory(userswap) -\ No newline at end of file --- -2.27.0 - diff --git a/0051-update-memdcd-engine-for-userswap.patch b/0051-update-memdcd-engine-for-userswap.patch deleted file mode 100644 index 6a8b593..0000000 --- a/0051-update-memdcd-engine-for-userswap.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 6b25858292a295ab928cd8bfb89715ecee2e600b Mon Sep 17 00:00:00 2001 -From: yangxin <245051644@qq.com> -Date: Wed, 15 Dec 2021 10:19:43 +0000 -Subject: [PATCH] update memdcd engine for userswap - -Filter out vmas without userswap flags in the memdcd engine. - -Signed-off-by: YangXin <245051644@qq.com> ---- - etmem/src/etmemd_src/etmemd_memdcd.c | 54 ++++++++++++++++++++++++++-- - 1 file changed, 51 insertions(+), 3 deletions(-) - -diff --git a/etmem/src/etmemd_src/etmemd_memdcd.c b/etmem/src/etmemd_src/etmemd_memdcd.c -index 635e5a2..28590e2 100644 ---- a/etmem/src/etmemd_src/etmemd_memdcd.c -+++ b/etmem/src/etmemd_src/etmemd_memdcd.c -@@ -235,6 +235,54 @@ FREE_SWAP: - return ret; - } - -+static struct page_refs *memdcd_do_scan(const struct task_pid *tpid, const struct task *tk) -+{ -+ int i = 0; -+ struct vmas *vmas = NULL; -+ struct page_refs *page_refs = NULL; -+ int ret = 0; -+ char pid[PID_STR_MAX_LEN] = {0}; -+ char *us = "us"; -+ -+ if(tpid == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "task pid is null\n"); -+ return NULL; -+ } -+ -+ if (tk == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "task struct is null for pid %u\n", tpid->pid); -+ return NULL; -+ } -+ -+ if (snprintf_s(pid, PID_STR_MAX_LEN, PID_STR_MAX_LEN - 1, "%u", tpid->pid) <= 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "snprintf pid fail %u", tpid->pid); -+ return NULL; -+ } -+ /* get vmas of target pid first. */ -+ vmas = get_vmas_with_flags(pid, &us, 1, true); -+ if (vmas == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "get vmas for %s fail\n", pid); -+ return NULL; -+ } -+ -+ /* loop for scanning idle_pages to get result of memory access. */ -+ for (i = 0; i < tk->eng->proj->loop; i++) { -+ ret = get_page_refs(vmas, pid, &page_refs, NULL, 0); -+ if (ret != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "scan operation failed\n"); -+ /* free page_refs nodes already exist */ -+ etmemd_free_page_refs(page_refs); -+ page_refs = NULL; -+ break; -+ } -+ sleep((unsigned)tk->eng->proj->sleep); -+ } -+ -+ free_vmas(vmas); -+ -+ return page_refs; -+} -+ - static void *memdcd_executor(void *arg) - { - struct task_pid *tk_pid = (struct task_pid *)arg; -@@ -244,7 +292,7 @@ static void *memdcd_executor(void *arg) - /* 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_page_refs_unexpected, &page_refs); -- page_refs = etmemd_do_scan(tk_pid, tk_pid->tk); -+ page_refs = memdcd_do_scan(tk_pid, tk_pid->tk); - if (page_refs != NULL) { - if (memdcd_do_migrate(tk_pid->pid, page_refs, memdcd_params->memdcd_socket) != 0) { - etmemd_log(ETMEMD_LOG_WARN, "memdcd migrate for pid %u fail\n", tk_pid->pid); -@@ -290,13 +338,13 @@ static struct config_item g_memdcd_task_config_items[] = { - static int memdcd_fill_task(GKeyFile *config, struct task *tk) - { - struct memdcd_params *params = calloc(1, sizeof(struct memdcd_params)); -- memset_s(params->memdcd_socket, MAX_SOCK_PATH_LENGTH, 0, MAX_SOCK_PATH_LENGTH); -- - if (params == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "alloc memdcd param fail\n"); - return -1; - } - -+ memset_s(params->memdcd_socket, MAX_SOCK_PATH_LENGTH, 0, MAX_SOCK_PATH_LENGTH); -+ - if (parse_file_config(config, TASK_GROUP, g_memdcd_task_config_items, ARRAY_SIZE(g_memdcd_task_config_items), - (void *)params) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "memdcd fill task fail\n"); --- -2.27.0 - diff --git a/0052-etmem-correct-example-config-file.patch b/0052-etmem-correct-example-config-file.patch deleted file mode 100644 index c65d83f..0000000 --- a/0052-etmem-correct-example-config-file.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 560e15aea0edc9bf53f33e739b6d430f4fe16150 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Tue, 19 Oct 2021 10:36:01 +0800 -Subject: [PATCH 01/33] etmem: correct example config file - -corret value config in cslide task -corret node_pair config in cslide engine - -Signed-off-by: Kemeng Shi ---- - etmem/conf/example_conf.yaml | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/etmem/conf/example_conf.yaml b/etmem/conf/example_conf.yaml -index de612f6..61ee68c 100644 ---- a/etmem/conf/example_conf.yaml -+++ b/etmem/conf/example_conf.yaml -@@ -22,7 +22,7 @@ max_threads=1 - [engine] - name=cslide - project=test --node_pair=2,0;3,1 -+node_pair=0,2;1,3 - hot_threshold=1 - node_mig_quota=1024 - node_hot_reserve=1024 -@@ -32,7 +32,7 @@ project=test - engine=cslide - name=background_cslide - type=pid --name=23456 -+value=23456 - vm_flags=ht - anon_only=no - ign_host=no --- -1.8.3.1 - diff --git a/0053-etmem-split-example_conf.yaml.patch b/0053-etmem-split-example_conf.yaml.patch deleted file mode 100644 index a6a134a..0000000 --- a/0053-etmem-split-example_conf.yaml.patch +++ /dev/null @@ -1,167 +0,0 @@ -From 0b40944b0a57393ccedb19b18f5c8307cfd42ffe Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Tue, 19 Oct 2021 10:43:09 +0800 -Subject: [PATCH 02/33] etmem: split example_conf.yaml - -User can't use example_conf.yaml directly as it contains diffrent -engine configs. Split it into three single engine config and user -can use it directly - -Signed-off-by: Kemeng Shi ---- - etmem/conf/cslide_conf.yaml | 24 ++++++++++++++++++ - etmem/conf/example_conf.yaml | 56 ----------------------------------------- - etmem/conf/slide_conf.yaml | 18 +++++++++++++ - etmem/conf/thirdparty_conf.yaml | 21 ++++++++++++++++ - 4 files changed, 63 insertions(+), 56 deletions(-) - create mode 100644 etmem/conf/cslide_conf.yaml - delete mode 100644 etmem/conf/example_conf.yaml - create mode 100644 etmem/conf/slide_conf.yaml - create mode 100644 etmem/conf/thirdparty_conf.yaml - -diff --git a/etmem/conf/cslide_conf.yaml b/etmem/conf/cslide_conf.yaml -new file mode 100644 -index 0000000..6b6ecc3 ---- /dev/null -+++ b/etmem/conf/cslide_conf.yaml -@@ -0,0 +1,24 @@ -+[project] -+name=test -+loop=1 -+interval=1 -+sleep=1 -+ -+#cslide -+[engine] -+name=cslide -+project=test -+node_pair=0,2;1,3 -+hot_threshold=1 -+node_mig_quota=1024 -+node_hot_reserve=1024 -+ -+[task] -+project=test -+engine=cslide -+name=background_cslide -+type=pid -+value=23456 -+vm_flags=ht -+anon_only=no -+ign_host=no -diff --git a/etmem/conf/example_conf.yaml b/etmem/conf/example_conf.yaml -deleted file mode 100644 -index 61ee68c..0000000 ---- a/etmem/conf/example_conf.yaml -+++ /dev/null -@@ -1,56 +0,0 @@ --[project] --name=test --loop=1 --interval=1 --sleep=1 -- --#slide --[engine] --name=slide --project=test -- --[task] --project=test --engine=slide --name=background_slide --type=name --value=mysql --T=1 --max_threads=1 -- --#cslide --[engine] --name=cslide --project=test --node_pair=0,2;1,3 --hot_threshold=1 --node_mig_quota=1024 --node_hot_reserve=1024 -- --[task] --project=test --engine=cslide --name=background_cslide --type=pid --value=23456 --vm_flags=ht --anon_only=no --ign_host=no -- --#thirdparty --[engine] --name=thirdparty --project=test --eng_name=my_engine --libname=/usr/lib/etmem_fetch/my_engine.so --ops_name=my_engine_ops --engine_private_key=engine_private_value -- --[task] --project=test --engine=my_engine --name=backgroud_third --type=pid --value=12345 --task_private_key=task_private_value -- -diff --git a/etmem/conf/slide_conf.yaml b/etmem/conf/slide_conf.yaml -new file mode 100644 -index 0000000..b99ab50 ---- /dev/null -+++ b/etmem/conf/slide_conf.yaml -@@ -0,0 +1,18 @@ -+[project] -+name=test -+loop=1 -+interval=1 -+sleep=1 -+ -+[engine] -+name=slide -+project=test -+ -+[task] -+project=test -+engine=slide -+name=background_slide -+type=name -+value=mysql -+T=1 -+max_threads=1 -diff --git a/etmem/conf/thirdparty_conf.yaml b/etmem/conf/thirdparty_conf.yaml -new file mode 100644 -index 0000000..1e1e9ac ---- /dev/null -+++ b/etmem/conf/thirdparty_conf.yaml -@@ -0,0 +1,21 @@ -+[project] -+name=test -+loop=1 -+interval=1 -+sleep=1 -+ -+[engine] -+name=thirdparty -+project=test -+eng_name=my_engine -+libname=/usr/lib/etmem_fetch/my_engine.so -+ops_name=my_engine_ops -+engine_private_key=engine_private_value -+ -+[task] -+project=test -+engine=my_engine -+name=backgroud_third -+type=pid -+value=12345 -+task_private_key=task_private_value --- -1.8.3.1 - diff --git a/0054-add-License-in-memRouter.patch b/0054-add-License-in-memRouter.patch deleted file mode 100644 index 07d9838..0000000 --- a/0054-add-License-in-memRouter.patch +++ /dev/null @@ -1,146 +0,0 @@ -From 4a8a5272e74994a694b88ab516a5331deea25bd2 Mon Sep 17 00:00:00 2001 -From: volcanodragon -Date: Tue, 9 Nov 2021 15:40:17 +0800 -Subject: [PATCH 03/33] add License in memRouter - ---- - memRouter/License/LICENSE | 127 ++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 127 insertions(+) - create mode 100644 memRouter/License/LICENSE - -diff --git a/memRouter/License/LICENSE b/memRouter/License/LICENSE -new file mode 100644 -index 0000000..0db93af ---- /dev/null -+++ b/memRouter/License/LICENSE -@@ -0,0 +1,127 @@ -+木兰宽松许可证, 第2版 -+ -+ 木兰宽松许可证, 第2版 -+ 2020年1月 http://license.coscl.org.cn/MulanPSL2 -+ -+ -+ 您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束: -+ -+ 0. 定义 -+ -+ “软件”是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。 -+ -+ “贡献”是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。 -+ -+ “贡献者”是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。 -+ -+ “法人实体”是指提交贡献的机构及其“关联实体”。 -+ -+ “关联实体”是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 -+ -+ 1. 授予版权许可 -+ -+ 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可以复制、使用、修改、分发其“贡献”,不论修改与否。 -+ -+ 2. 授予专利许可 -+ -+ 每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权行动之日终止。 -+ -+ 3. 无商标许可 -+ -+ “本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定的声明义务而必须使用除外。 -+ -+ 4. 分发限制 -+ -+ 您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。 -+ -+ 5. 免责声明与责任限制 -+ -+ “软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于何种法律理论,即使其曾被建议有此种损失的可能性。 -+ -+ 6. 语言 -+ “本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文版为准。 -+ -+ 条款结束 -+ -+ 如何将木兰宽松许可证,第2版,应用到您的软件 -+ -+ 如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: -+ -+ 1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; -+ -+ 2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中; -+ -+ 3, 请将如下声明文本放入每个源文件的头部注释中。 -+ -+ Copyright (c) [Year] [name of copyright holder] -+ [Software Name] is licensed under Mulan PSL v2. -+ You can use this software according to the terms and conditions of the Mulan PSL v2. -+ You may obtain a copy of Mulan PSL v2 at: -+ http://license.coscl.org.cn/MulanPSL2 -+ THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -+ See the Mulan PSL v2 for more details. -+ -+ -+ Mulan Permissive Software License,Version 2 -+ -+ Mulan Permissive Software License,Version 2 (Mulan PSL v2) -+ January 2020 http://license.coscl.org.cn/MulanPSL2 -+ -+ Your reproduction, use, modification and distribution of the Software shall be subject to Mulan PSL v2 (this License) with the following terms and conditions: -+ -+ 0. Definition -+ -+ Software means the program and related documents which are licensed under this License and comprise all Contribution(s). -+ -+ Contribution means the copyrightable work licensed by a particular Contributor under this License. -+ -+ Contributor means the Individual or Legal Entity who licenses its copyrightable work under this License. -+ -+ Legal Entity means the entity making a Contribution and all its Affiliates. -+ -+ Affiliates means entities that control, are controlled by, or are under common control with the acting entity under this License, ‘control’ means direct or indirect ownership of at least fifty percent (50%) of the voting power, capital or other securities of controlled or commonly controlled entity. -+ -+ 1. Grant of Copyright License -+ -+ Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not. -+ -+ 2. Grant of Patent License -+ -+ Subject to the terms and conditions of this License, each Contributor hereby grants to you a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (except for revocation under this Section) patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution, where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Software to which the Contribution was contributed. The patent license shall not apply to any modification of the Contribution, and any other combination which includes the Contribution. If you or your Affiliates directly or indirectly institute patent litigation (including a cross claim or counterclaim in a litigation) or other patent enforcement activities against any individual or entity by alleging that the Software or any Contribution in it infringes patents, then any patent license granted to you under this License for the Software shall terminate as of the date such litigation or activity is filed or taken. -+ -+ 3. No Trademark License -+ -+ No trademark license is granted to use the trade names, trademarks, service marks, or product names of Contributor, except as required to fulfill notice requirements in Section 4. -+ -+ 4. Distribution Restriction -+ -+ You may distribute the Software in any medium with or without modification, whether in source or executable forms, provided that you provide recipients with a copy of this License and retain copyright, patent, trademark and disclaimer statements in the Software. -+ -+ 5. Disclaimer of Warranty and Limitation of Liability -+ -+ THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. -+ -+ 6. Language -+ -+ THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION SHALL PREVAIL. -+ -+ END OF THE TERMS AND CONDITIONS -+ -+ How to Apply the Mulan Permissive Software License,Version 2 (Mulan PSL v2) to Your Software -+ -+ To apply the Mulan PSL v2 to your work, for easy identification by recipients, you are suggested to complete following three steps: -+ -+ i Fill in the blanks in following statement, including insert your software name, the year of the first publication of your software, and your name identified as the copyright owner; -+ -+ ii Create a file named “LICENSE” which contains the whole context of this License in the first directory of your software package; -+ -+ iii Attach the statement to the appropriate annotated syntax at the beginning of each source file. -+ -+ -+ Copyright (c) [Year] [name of copyright holder] -+ [Software Name] is licensed under Mulan PSL v2. -+ You can use this software according to the terms and conditions of the Mulan PSL v2. -+ You may obtain a copy of Mulan PSL v2 at: -+ http://license.coscl.org.cn/MulanPSL2 -+ THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. -+ See the Mulan PSL v2 for more details. --- -1.8.3.1 - diff --git a/0055-add-code-of-testcase-for-etmem-common-function.patch b/0055-add-code-of-testcase-for-etmem-common-function.patch deleted file mode 100644 index 5209bda..0000000 --- a/0055-add-code-of-testcase-for-etmem-common-function.patch +++ /dev/null @@ -1,698 +0,0 @@ -From e36c5a68a748080a473988c7530786f3f7ac90d3 Mon Sep 17 00:00:00 2001 -From: louhongxiang -Date: Mon, 22 Nov 2021 17:51:33 +0800 -Subject: [PATCH 04/33] add code of testcase for etmem common function. - ---- - etmem/test/CMakeLists.txt | 198 ++++++++++++++++++++++++ - etmem/test/common/test_common.c | 327 ++++++++++++++++++++++++++++++++++++++++ - etmem/test/common/test_common.h | 138 +++++++++++++++++ - 3 files changed, 663 insertions(+) - create mode 100644 etmem/test/CMakeLists.txt - create mode 100644 etmem/test/common/test_common.c - create mode 100644 etmem/test/common/test_common.h - -diff --git a/etmem/test/CMakeLists.txt b/etmem/test/CMakeLists.txt -new file mode 100644 -index 0000000..5bf3477 ---- /dev/null -+++ b/etmem/test/CMakeLists.txt -@@ -0,0 +1,198 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: louhongxiang -+# * Create: 2021-11-19 -+# * Description: CMakefileList for etmem to compile -+# ******************************************************************************/ -+ -+cmake_minimum_required (VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) -+project(etmem) -+ -+EXECUTE_PROCESS( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE ARCHITECTURE ) -+message( STATUS "Architecture: ${ARCHITECTURE}" ) -+ -+set(ETMEMD_SRC_DIR ${PROJECT_SOURCE_DIR}/../src/etmemd_src) -+set(ETMEM_SRC_DIR ${PROJECT_SOURCE_DIR}/../src/etmem_src) -+set(TEST_COMMON_DIR ${PROJECT_SOURCE_DIR}/common) -+set(BUILD_DIR ${PROJECT_SOURCE_DIR}/build) -+ -+set(ETMEMD_SRC -+ ${ETMEMD_SRC_DIR}/etmemd.c -+ ${ETMEMD_SRC_DIR}/etmemd_file.c -+ ${ETMEMD_SRC_DIR}/etmemd_common.c -+ ${ETMEMD_SRC_DIR}/etmemd_rpc.c -+ ${ETMEMD_SRC_DIR}/etmemd_log.c -+ ${ETMEMD_SRC_DIR}/etmemd_project.c -+ ${ETMEMD_SRC_DIR}/etmemd_engine.c -+ ${ETMEMD_SRC_DIR}/etmemd_memdcd.c -+ ${ETMEMD_SRC_DIR}/etmemd_slide.c -+ ${ETMEMD_SRC_DIR}/etmemd_cslide.c -+ ${ETMEMD_SRC_DIR}/etmemd_thirdparty.c -+ ${ETMEMD_SRC_DIR}/etmemd_task.c -+ ${ETMEMD_SRC_DIR}/etmemd_scan.c -+ ${ETMEMD_SRC_DIR}/etmemd_threadpool.c -+ ${ETMEMD_SRC_DIR}/etmemd_threadtimer.c -+ ${ETMEMD_SRC_DIR}/etmemd_pool_adapter.c -+ ${ETMEMD_SRC_DIR}/etmemd_migrate.c) -+ -+set(ETMEM_SRC -+ ${ETMEM_SRC_DIR}/etmem.c -+ ${ETMEM_SRC_DIR}/etmem_project.c -+ ${ETMEM_SRC_DIR}/etmem_obj.c -+ ${ETMEM_SRC_DIR}/etmem_engine.c -+ ${ETMEM_SRC_DIR}/etmem_rpc.c -+ ${ETMEM_SRC_DIR}/etmem_common.c) -+ -+set(ETMEMD_CSLIDE_DEP -+ ${ETMEMD_SRC_DIR}/etmemd.c -+ ${ETMEMD_SRC_DIR}/etmemd_file.c -+ ${ETMEMD_SRC_DIR}/etmemd_common.c -+ ${ETMEMD_SRC_DIR}/etmemd_rpc.c -+ ${ETMEMD_SRC_DIR}/etmemd_log.c -+ ${ETMEMD_SRC_DIR}/etmemd_project.c -+ ${ETMEMD_SRC_DIR}/etmemd_engine.c -+ ${ETMEMD_SRC_DIR}/etmemd_slide.c -+ ${ETMEMD_SRC_DIR}/etmemd_thirdparty.c -+ ${ETMEMD_SRC_DIR}/etmemd_task.c -+ ${ETMEMD_SRC_DIR}/etmemd_scan.c -+ ${ETMEMD_SRC_DIR}/etmemd_threadpool.c -+ ${ETMEMD_SRC_DIR}/etmemd_threadtimer.c -+ ${ETMEMD_SRC_DIR}/etmemd_pool_adapter.c -+ ${ETMEMD_SRC_DIR}/etmemd_migrate.c) -+ -+set(TEST_COMMON_SRC -+ ${TEST_COMMON_DIR}/test_common.c) -+ -+add_library( -+etmemd_shared -+SHARED -+${ETMEMD_SRC}) -+ -+add_library( -+etmem_shared -+SHARED -+${ETMEM_SRC}) -+ -+add_library( -+test_common -+SHARED -+${TEST_COMMON_SRC}) -+ -+add_library( -+cslide_dep -+SHARED -+${ETMEMD_CSLIDE_DEP}) -+ -+add_executable(etmemd -+ ${ETMEMD_SRC}) -+ -+add_executable(etmem -+ ${ETMEM_SRC}) -+ -+set(EXECUTABLE_OUTPUT_PATH ${BUILD_DIR}/bin) -+ -+set(LIBRARY_OUTPUT_PATH ${BUILD_DIR}/lib) -+ -+include(FindPkgConfig) -+pkg_search_module(GLIB2 REQUIRED glib-2.0) -+ -+target_include_directories(etmemd PRIVATE -+ ${PROJECT_SOURCE_DIR}/../inc/etmemd_inc -+ ${GLIB2_INCLUDE_DIRS}) -+ -+target_include_directories(etmemd_shared PRIVATE -+ ${PROJECT_SOURCE_DIR}/../inc/etmemd_inc -+ ${GLIB2_INCLUDE_DIRS}) -+ -+target_include_directories(etmem PRIVATE -+ ${PROJECT_SOURCE_DIR}/../inc/etmem_inc) -+ -+target_include_directories(etmem_shared PRIVATE -+ ${PROJECT_SOURCE_DIR}/../inc/etmem_inc) -+ -+target_include_directories(test_common PRIVATE -+ ${PROJECT_SOURCE_DIR}/../inc/etmemd_inc -+ ${PROJECT_SOURCE_DIR}/COMMON -+ ${GLIB2_INCLUDE_DIRS}) -+ -+target_include_directories(cslide_dep PRIVATE -+ ${PROJECT_SOURCE_DIR}/../inc/etmemd_inc -+ ${GLIB2_INCLUDE_DIRS}) -+ -+if(COVERAGE_ENABLE) -+ message(STATUS "Enable coverage compile option") -+ SET(COVERAGE_OPTION "${COVERAGE_OPTION} -fprofile-arcs -ftest-coverage") -+endif(COVERAGE_ENABLE) -+ -+if(ASAN_ENABLE) -+ message(STATUS "Enable asan compile option") -+ SET(ASAN_OPTIONS "${ASAN_OPTION} -fsanitize=address -fsanitize-recover=address") -+endif(ASAN_ENABLE) -+ -+IF(CMAKE_BUILD_TYPE STREQUAL Debug) -+ SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${COVERAGE_OPTION} ${ASAN_OPTIONS}") -+ SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COVERAGE_OPTION} ${ASAN_OPTIONS}") -+ENDIF() -+ -+# set common compile options -+set(COMMON_COMPILE_OPT -fsigned-char -fno-omit-frame-pointer -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wmissing-declarations -fno-strict-aliasing -Werror -Wformat -Wformat-security -D_GNU_SOURCE -fPIE -pie -fPIC -fstack-protector-strong -fno-common -DNDEBUG -O2 -D_FORTIFY_SOURCE=2 -Wall -Werror -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines -pthread -Wno-pointer-sign -Wstrict-prototypes -Wold-style-definition -std=gnu99) -+ -+if (CONFIG_DEBUG STREQUAL "y") -+ SET(COMMON_COMPILE_OPT ${COMMON_COMPILE_OPT} -g) -+endif() -+ -+if( ${ARCHITECTURE} STREQUAL "aarch64") -+ SET(COMMON_COMPILE_OPT ${COMMON_COMPILE_OPT} -march=armv8-a) -+else() -+ SET(COMMON_COMPILE_OPT ${COMMON_COMPILE_OPT} -march=core-avx-i -m64) -+endif() -+ -+# set common share library compile options -+set(SHARE_COMPILE_OPT -ldl -rdynamic) -+ -+# set common link options -+set(COMMON_LINK_OPT "-fPIE -pie -fPIC -Wl,-z,relro,-z,now,-z,noexecstack -Wtrampolines") -+set(COMMON_LINK_LIB pthread dl rt boundscheck) -+set(SERVER_LINK_LIB numa ${GLIB2_LIBRARIES}) -+ -+# target etmemd -+target_compile_options(etmemd PRIVATE ${COMMON_COMPILE_OPT}) -+set_target_properties(etmemd PROPERTIES LINK_FLAGS ${COMMON_LINK_OPT}) -+target_link_libraries(etmemd PRIVATE ${COMMON_LINK_LIB} ${SERVER_LINK_LIB}) -+ -+# target etmem -+target_compile_options(etmem PRIVATE ${COMMON_COMPILE_OPT}) -+set_target_properties(etmem PROPERTIES LINK_FLAGS ${COMMON_LINK_OPT}) -+target_link_libraries(etmem PRIVATE ${COMMON_LINK_LIB} ${SERVER_LINK_LIB}) -+ -+# target etmemd share -+target_compile_options(etmemd_shared PRIVATE ${COMMON_COMPILE_OPT} ${SHARE_COMPILE_OPT}) -+set_target_properties(etmemd_shared PROPERTIES LINK_FLAGS ${COMMON_LINK_OPT}) -+target_link_libraries(etmemd_shared PRIVATE ${COMMON_LINK_LIB} ${SERVER_LINK_LIB}) -+SET_TARGET_PROPERTIES(etmemd_shared PROPERTIES OUTPUT_NAME "etmemd") -+ -+# target etmem share -+target_compile_options(etmem_shared PRIVATE ${COMMON_COMPILE_OPT} ${SHARE_COMPILE_OPT}) -+set_target_properties(etmem_shared PROPERTIES LINK_FLAGS ${COMMON_LINK_OPT}) -+target_link_libraries(etmem_shared PRIVATE ${COMMON_LINK_LIB}) -+SET_TARGET_PROPERTIES(etmem_shared PROPERTIES OUTPUT_NAME "etmem") -+ -+# target test etmemd share -+target_compile_options(test_common PRIVATE ${COMMON_COMPILE_OPT} ${SHARE_COMPILE_OPT}) -+set_target_properties(test_common PROPERTIES LINK_FLAGS ${COMMON_LINK_OPT}) -+target_link_libraries(test_common PRIVATE ${COMMON_LINK_LIB} ${SERVER_LINK_LIB}) -+SET_TARGET_PROPERTIES(test_common PROPERTIES OUTPUT_NAME "test") -+ -+# target etmemd cslide share -+target_compile_options(cslide_dep PRIVATE ${COMMON_COMPILE_OPT} ${SHARE_COMPILE_OPT}) -+set_target_properties(cslide_dep PROPERTIES LINK_FLAGS ${COMMON_LINK_OPT}) -+target_link_libraries(cslide_dep PRIVATE ${COMMON_LINK_LIB} ${SERVER_LINK_LIB}) -+ -diff --git a/etmem/test/common/test_common.c b/etmem/test/common/test_common.c -new file mode 100644 -index 0000000..4551177 ---- /dev/null -+++ b/etmem/test/common/test_common.c -@@ -0,0 +1,327 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: louhongxiang -+ * Create: 2021-11-19 -+ * Description: This is a header file of the export data structure definition for page. -+ ******************************************************************************/ -+ -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "etmemd_project.h" -+ -+#include "test_common.h" -+ -+#define FIRST_COLD_NODE_INDEX 2 -+#define FIRST_HOT_NODE_INDEX 0 -+#define SECOND_COLD_NODE_INDEX 6 -+#define SECOND_HOT_NODE_INDEX 4 -+ -+GKeyFile *load_config(const char *file_name) -+{ -+ GKeyFile *config = NULL; -+ -+ config = g_key_file_new(); -+ CU_ASSERT_PTR_NOT_NULL(config); -+ CU_ASSERT_NOT_EQUAL(g_key_file_load_from_file(config, file_name, G_KEY_FILE_NONE, NULL), FALSE); -+ return config; -+} -+ -+void unload_config(GKeyFile *config) -+{ -+ g_key_file_free(config); -+} -+ -+void construct_proj_file(struct proj_test_param *param) -+{ -+ FILE *file = NULL; -+ -+ file = fopen(param->file_name, "w+"); -+ CU_ASSERT_PTR_NOT_NULL(file); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, "[project]\n"), -1); -+ if (param->proj_name != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_NAME, param->proj_name), -1); -+ } -+ if (param->interval != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_INTERVAL, param->interval), -1); -+ } -+ if (param->loop != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_LOOP, param->loop), -1); -+ } -+ if (param->sleep != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_SLEEP, param->sleep), -1); -+ } -+ fclose(file); -+} -+ -+GKeyFile *construct_proj_config(struct proj_test_param *param) -+{ -+ construct_proj_file(param); -+ -+ return load_config(param->file_name); -+} -+ -+void destroy_proj_config(GKeyFile *config) -+{ -+ unload_config(config); -+} -+ -+void init_proj_param(struct proj_test_param *param) -+{ -+ param->sleep = "1"; -+ param->interval = "1"; -+ param->loop = "1"; -+ param->file_name = TMP_PROJ_CONFIG; -+ param->proj_name = DEFAULT_PROJ; -+ param->expt = OPT_SUCCESS; -+} -+ -+void do_add_proj_test(struct proj_test_param * param) -+{ -+ GKeyFile *config = NULL; -+ -+ config = construct_proj_config(param); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), param->expt); -+ destroy_proj_config(config); -+} -+ -+void do_rm_proj_test(struct proj_test_param *param) -+{ -+ GKeyFile *config = NULL; -+ -+ config = load_config(param->file_name); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), param->expt); -+ unload_config(config); -+} -+ -+void construct_eng_file(struct eng_test_param *param) -+{ -+ FILE *file = NULL; -+ -+ file = fopen(param->file_name, "w+"); -+ CU_ASSERT_PTR_NOT_NULL(file); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, "[engine]\n"), -1); -+ if (param->name != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_NAME, param->name), -1); -+ } -+ if (param->proj != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_PROJ, param->proj), -1); -+ } -+ fclose(file); -+} -+ -+GKeyFile *construct_eng_config(struct eng_test_param *param) -+{ -+ construct_eng_file(param); -+ -+ return load_config(param->file_name); -+} -+ -+void destroy_eng_config(GKeyFile *config) -+{ -+ unload_config(config); -+} -+ -+void init_task_param(struct task_test_param *param, const char *eng) -+{ -+ param->name = DEFAULT_TASK; -+ param->proj = DEFAULT_PROJ; -+ param->eng = eng; -+ param->type = "pid"; -+ param->value = "1"; -+ param->file_name = TMP_TASK_CONFIG; -+} -+ -+void construct_task_file(struct task_test_param *param) -+{ -+ FILE *file = NULL; -+ -+ file = fopen(param->file_name, "w+"); -+ CU_ASSERT_PTR_NOT_NULL(file); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, "[task]\n"), -1); -+ if (param->name != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_NAME, param->name), -1); -+ } -+ if (param->proj != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_PROJ, param->name), -1); -+ } -+ if (param->eng != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_ENG, param->name), -1); -+ } -+ if (param->type != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_TYPE, param->name), -1); -+ } -+ if (param->value != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_VALUE, param->name), -1); -+ } -+ fclose(file); -+} -+ -+void init_slide_task(struct slide_task_test_param *param) -+{ -+ init_task_param(¶m->task_param, "slide"); -+ param->max_threads = "1"; -+ param->T = "1"; -+} -+ -+void add_slide_task(struct slide_task_test_param *param) -+{ -+ FILE *file = NULL; -+ const char *file_name = param->task_param.file_name; -+ -+ file = fopen(file_name, "a+"); -+ CU_ASSERT_PTR_NOT_NULL(file); -+ if (param->max_threads != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_MAX_THREADS, param->max_threads), -1); -+ } -+ if (param->T != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_T, param->T), -1); -+ } -+ fclose(file); -+} -+ -+GKeyFile *construct_slide_task_config(struct slide_task_test_param *param) -+{ -+ struct task_test_param *task_param = ¶m->task_param; -+ -+ construct_task_file(task_param); -+ add_slide_task(param); -+ -+ return load_config(task_param->file_name); -+} -+ -+void destroy_slide_task_config(GKeyFile *config) -+{ -+ unload_config(config); -+} -+ -+void init_slide_eng(struct eng_test_param *param) -+{ -+ param->name = "slide"; -+ param->proj = DEFAULT_PROJ; -+ param->file_name = TMP_ENG_CONFIG; -+} -+ -+static char *get_node_pair(void) -+{ -+ int node_num = numa_num_configured_nodes(); -+ -+ switch (node_num) { -+ case ONE_NODE_PAIR: -+ return "0,1"; -+ case TWO_NODE_PAIR: -+ return "0,2;1,3"; -+ case THREE_NODE_PAIR: -+ return "0,3;1,4;2,5"; -+ default: -+ return NULL; -+ } -+} -+ -+int get_first_cold_node(struct cslide_eng_test_param *param) -+{ -+ return param->node_pair[FIRST_COLD_NODE_INDEX] - '0'; -+} -+ -+int get_first_hot_node(struct cslide_eng_test_param *param) -+{ -+ return param->node_pair[FIRST_HOT_NODE_INDEX] - '0'; -+} -+ -+int get_second_cold_node(struct cslide_eng_test_param *param) -+{ -+ return param->node_pair[SECOND_COLD_NODE_INDEX] - '0'; -+} -+ -+int get_second_hot_node(struct cslide_eng_test_param *param) -+{ -+ return param->node_pair[SECOND_HOT_NODE_INDEX] - '0'; -+} -+ -+void init_cslide_eng(struct cslide_eng_test_param *param) -+{ -+ param->eng_param.name = "cslide"; -+ param->eng_param.proj = DEFAULT_PROJ; -+ param->eng_param.file_name = TMP_ENG_CONFIG; -+ param->node_pair = get_node_pair(); -+ param->hot_threshold = "2"; -+ param->node_mig_quota = "1024"; -+ param->node_hot_reserve = "1024"; -+} -+ -+void add_cslide_eng(struct cslide_eng_test_param *param) -+{ -+ FILE *file = NULL; -+ const char *file_name = param->eng_param.file_name; -+ -+ file = fopen(file_name, "a+"); -+ CU_ASSERT_PTR_NOT_NULL(file); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_NODE_PAIR, param->node_pair), -1); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_THRESH, param->hot_threshold), -1); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_QUOTA, param->node_mig_quota), -1); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_RESV, param->node_hot_reserve), -1); -+ fclose(file); -+} -+ -+GKeyFile *construct_cslide_eng_config(struct cslide_eng_test_param *param) -+{ -+ struct eng_test_param *eng_param = ¶m->eng_param; -+ -+ construct_eng_file(eng_param); -+ add_cslide_eng(param); -+ -+ return load_config(eng_param->file_name); -+} -+ -+void destroy_cslide_eng_config(GKeyFile *config) -+{ -+ unload_config(config); -+} -+ -+void init_cslide_task(struct cslide_task_test_param *param) -+{ -+ init_task_param(¶m->task_param, "cslide"); -+ param->vm_flags = "ht"; -+ param->anon_only = "no"; -+ param->ign_host = "yes"; -+} -+ -+void add_cslide_task(struct cslide_task_test_param *param) -+{ -+ FILE *file = NULL; -+ const char *file_name = param->task_param.file_name; -+ -+ file = fopen(file_name, "a+"); -+ CU_ASSERT_PTR_NOT_NULL(file); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_VM_FLAGS, param->vm_flags), -1); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_ANON_ONLY, param->anon_only), -1); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_IGN_HOST, param->ign_host), -1); -+ fclose(file); -+} -+ -+GKeyFile *construct_cslide_task_config(struct cslide_task_test_param *param) -+{ -+ struct task_test_param *task_param = ¶m->task_param; -+ -+ construct_task_file(task_param); -+ add_cslide_task(param); -+ -+ return load_config(task_param->file_name); -+} -+ -+void destroy_cslide_task_config(GKeyFile *config) -+{ -+ unload_config(config); -+} -diff --git a/etmem/test/common/test_common.h b/etmem/test/common/test_common.h -new file mode 100644 -index 0000000..009c458 ---- /dev/null -+++ b/etmem/test/common/test_common.h -@@ -0,0 +1,138 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: louhongxiang -+ * Create: 2021-11-19 -+ * Description: This is a header file of the export data structure definition for page. -+ ******************************************************************************/ -+ -+#ifndef TEST_COMMON_H -+#define TEST_COMMON_H -+ -+#include -+ -+#include "etmemd_project.h" -+ -+#define CONFIG_NAME "name=%s\n" -+#define CONFIG_INTERVAL "interval=%s\n" -+#define CONFIG_LOOP "loop=%s\n" -+#define CONFIG_SLEEP "sleep=%s\n" -+#define TMP_PROJ_CONFIG "proj_tmp.config" -+#define DEFAULT_PROJ "default_proj" -+ -+#define CONFIG_PROJ "project=%s\n" -+#define TMP_ENG_CONFIG "eng_tmp.config" -+ -+#define CONFIG_ENG "engine=%s\n" -+#define CONFIG_TYPE "type=%s\n" -+#define CONFIG_VALUE "value=%s\n" -+#define TMP_TASK_CONFIG "task_tmp.config" -+#define DEFAULT_TASK "default_task" -+ -+#define CONFIG_MAX_THREADS "max_threads=%s\n" -+#define CONFIG_T "T=%s\n" -+ -+#define CONFIG_NODE_PAIR "node_pair=%s\n" -+#define CONFIG_THRESH "hot_threshold=%s\n" -+#define CONFIG_QUOTA "node_mig_quota=%s\n" -+#define CONFIG_RESV "node_hot_reserve=%s\n" -+ -+#define CONFIG_VM_FLAGS "vm_flags=%s\n" -+#define CONFIG_ANON_ONLY "anon_only=%s\n" -+#define CONFIG_IGN_HOST "igno_host=%s\n" -+ -+#define ONE_NODE_PAIR 2 -+#define TWO_NODE_PAIR 4 -+#define THREE_NODE_PAIR 5 -+ -+ -+struct proj_test_param { -+ const char *sleep; -+ const char *interval; -+ const char *loop; -+ const char *proj_name; -+ const char *file_name; -+ enum opt_result expt; -+}; -+ -+struct eng_test_param { -+ const char *name; -+ const char *proj; -+ const char *file_name; -+}; -+ -+struct task_test_param { -+ const char *name; -+ const char *proj; -+ const char *eng; -+ const char *type; -+ const char *value; -+ const char *file_name; -+}; -+ -+struct slide_task_test_param { -+ struct task_test_param task_param; -+ const char *max_threads; -+ const char *T; -+}; -+ -+struct cslide_eng_test_param { -+ struct eng_test_param eng_param; -+ const char *node_pair; -+ const char *hot_threshold; -+ const char *node_mig_quota; -+ const char *node_hot_reserve; -+}; -+ -+struct cslide_task_test_param { -+ struct task_test_param task_param; -+ const char *vm_flags; -+ const char *anon_only; -+ const char *ign_host; -+}; -+ -+GKeyFile *load_config(const char *file_name); -+void unload_config(GKeyFile *config); -+ -+void construct_proj_file(struct proj_test_param *param); -+GKeyFile *construct_proj_config(struct proj_test_param *param); -+void destroy_proj_config(GKeyFile *config); -+void init_proj_param(struct proj_test_param *param); -+void do_add_proj_test(struct proj_test_param *param); -+void do_rm_proj_test(struct proj_test_param *param); -+ -+void construct_eng_file(struct eng_test_param *param); -+GKeyFile *construct_eng_config(struct eng_test_param *param); -+void destroy_eng_config(GKeyFile *config); -+ -+void init_task_param(struct task_test_param *param, const char *eng); -+void construct_task_file(struct task_test_param *param); -+ -+void init_slide_task(struct slide_task_test_param *param); -+void add_slide_task(struct slide_task_test_param *param); -+GKeyFile *construct_slide_task_config(struct slide_task_test_param *param); -+void destroy_slide_task_config(GKeyFile *config); -+void init_slide_eng(struct eng_test_param *param); -+ -+void init_cslide_eng(struct cslide_eng_test_param *param); -+void add_cslide_eng(struct cslide_eng_test_param *param); -+GKeyFile *construct_cslide_eng_config(struct cslide_eng_test_param *param); -+void destroy_cslide_eng_config(GKeyFile *config); -+ -+int get_first_cold_node(struct cslide_eng_test_param *param); -+int get_first_hot_node(struct cslide_eng_test_param *param); -+int get_second_cold_node(struct cslide_eng_test_param *param); -+int get_second_hot_node(struct cslide_eng_test_param *param); -+ -+void init_cslide_task(struct cslide_task_test_param *param); -+void add_cslide_task(struct cslide_task_test_param *param); -+GKeyFile *construct_cslide_task_config(struct cslide_task_test_param *param); -+void destroy_cslide_task_config(GKeyFile *config); -+#endif --- -1.8.3.1 - diff --git a/0056-add-code-of-testcase-for-etmem-project-function.patch b/0056-add-code-of-testcase-for-etmem-project-function.patch deleted file mode 100644 index 814c3d2..0000000 --- a/0056-add-code-of-testcase-for-etmem-project-function.patch +++ /dev/null @@ -1,523 +0,0 @@ -From f63083aff0d1d305079d9f0c47717faa512361f8 Mon Sep 17 00:00:00 2001 -From: liubo -Date: Tue, 30 Nov 2021 09:42:50 +0800 -Subject: [PATCH 05/33] add code of testcase for etmem project function - ---- - etmem/test/project/CMakeLists.txt | 28 ++ - etmem/test/project/etmem_project_ops_llt.c | 468 +++++++++++++++++++++++++++++ - 2 files changed, 496 insertions(+) - create mode 100644 etmem/test/project/CMakeLists.txt - create mode 100644 etmem/test/project/etmem_project_ops_llt.c - -diff --git a/etmem/test/project/CMakeLists.txt b/etmem/test/project/CMakeLists.txt -new file mode 100644 -index 0000000..70cd530 ---- /dev/null -+++ b/etmem/test/project/CMakeLists.txt -@@ -0,0 +1,28 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: liubo -+# * Create: 2021-11-29 -+# * Description: CMakefileList for etmem_project_ops_llt to compile -+# ******************************************************************************/ -+ -+project(etmem) -+ -+INCLUDE_DIRECTORIES(../../inc/etmem_inc) -+INCLUDE_DIRECTORIES(../../inc/etmemd_inc) -+INCLUDE_DIRECTORIES(../common) -+INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -+ -+SET(EXE etmem_project_ops_llt) -+ -+add_executable(${EXE} -+etmem_project_ops_llt.c) -+ -+target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so ${BUILD_DIR}/lib/libtest.so pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/project/etmem_project_ops_llt.c b/etmem/test/project/etmem_project_ops_llt.c -new file mode 100644 -index 0000000..edd2330 ---- /dev/null -+++ b/etmem/test/project/etmem_project_ops_llt.c -@@ -0,0 +1,468 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liubo -+ * Create: 2021-11-29 -+ * Description: This is a source file of the unit test for project-related commands in etmem. -+ ******************************************************************************/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "etmemd_project.h" -+#include "etmemd_file.h" -+#include "etmemd_common.h" -+#include "securec.h" -+ -+#include "test_common.h" -+ -+#include -+#include -+#include -+ -+#define PROJECT_ADD_TEST_MAX_NUM 50 -+ -+static struct proj_test_param g_proj_test_param; -+ -+static void etmem_pro_add_name(void) -+{ -+ const char *project_name_long = "project name cannot longer than 32 ppmpppppppppppppppppppppppppppppppppppppppppppppp"; -+ GKeyFile *config = NULL; -+ struct proj_test_param param; -+ -+ init_proj_param(¶m); -+ -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_PRO_EXISTED); -+ destroy_proj_config(config); -+ -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.proj_name = ""; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.proj_name = project_name_long; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.proj_name = DEFAULT_PROJ; -+} -+ -+static void etmem_pro_add_interval(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ param.interval = "0"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.interval = "1"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.interval = "2"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.interval = "1199"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.interval = "1200"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.interval = "1201"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.interval = "abc"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+} -+ -+static void etmem_pro_add_loop(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ param.loop = "0"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.loop = "1"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.loop = "2"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.loop = "119"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.loop = "120"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.loop = "121"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.loop = "abc"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+} -+ -+static void etmem_pro_add_sleep(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ param.sleep = "0"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.sleep = "1"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.sleep = "2"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.sleep = "1199"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.sleep = "1200"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.sleep = "1201"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.sleep = "wrong sleep type"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+} -+ -+static void etmem_pro_lack_loop(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ param.loop = NULL; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+} -+ -+void test_etmem_prj_add_error(void) -+{ -+ etmem_pro_add_name(); -+ etmem_pro_add_interval(); -+ etmem_pro_add_loop(); -+ etmem_pro_add_sleep(); -+ etmem_pro_lack_loop(); -+} -+ -+void test_etmem_prj_del_error(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ param.proj_name = ""; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.proj_name = "noexist"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_PRO_NOEXIST); -+ destroy_proj_config(config); -+} -+ -+static void add_project_once(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ CU_ASSERT_EQUAL(etmemd_project_show(NULL, 0), OPT_PRO_NOEXIST); -+ -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ CU_ASSERT_EQUAL(etmemd_project_show(NULL, 0), OPT_SUCCESS); -+ -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ CU_ASSERT_EQUAL(etmemd_project_show("noexist", 0), OPT_PRO_NOEXIST); -+} -+ -+static int add_project_multiple(int proj_add_num) -+{ -+ char project_name_str[PROJECT_NAME_MAX_LEN] = {0}; -+ unsigned int project_num; -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ for (project_num = 0; project_num < proj_add_num; project_num++) { -+ if (snprintf_s(project_name_str, PROJECT_NAME_MAX_LEN, PROJECT_NAME_MAX_LEN - 1, "project_add_del_test_num%d", -+ project_num) <= 0) { -+ printf("get project_name wrong.\n"); -+ return -1; -+ } -+ param.proj_name = project_name_str; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ } -+ -+ CU_ASSERT_EQUAL(etmemd_project_show(NULL, 0), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_show("project_add_del_test_num5", 0), OPT_SUCCESS); -+ -+ for (project_num = 0; project_num < proj_add_num; project_num++) { -+ if (snprintf_s(project_name_str, PROJECT_NAME_MAX_LEN, PROJECT_NAME_MAX_LEN - 1, "project_add_del_test_num%d", -+ project_num) <= 0) { -+ printf("get project_name wrong.\n"); -+ return -1; -+ } -+ param.proj_name = project_name_str; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ } -+ -+ return 0; -+} -+ -+void test_etmem_project_add_ok(void) -+{ -+ add_project_once(); -+ CU_ASSERT_EQUAL(add_project_multiple(PROJECT_ADD_TEST_MAX_NUM), 0); -+} -+ -+void test_etmem_mig_start_error(void) -+{ -+ struct proj_test_param param; -+ -+ init_proj_param(¶m); -+ -+ CU_ASSERT_EQUAL(etmemd_migrate_start(NULL), OPT_INVAL); -+ CU_ASSERT_EQUAL(etmemd_migrate_start(""), OPT_PRO_NOEXIST); -+ CU_ASSERT_EQUAL(etmemd_migrate_start("etmem"), OPT_PRO_NOEXIST); -+ CU_ASSERT_EQUAL(etmemd_migrate_start("me^$%*mig"), OPT_PRO_NOEXIST); -+ -+ param.proj_name = "add_for_migrate_test"; -+ do_add_proj_test(¶m); -+ -+ CU_ASSERT_EQUAL(etmemd_migrate_start("add_for_migrate_test"), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_start("add_for_migrate_test"), OPT_PRO_STARTED); -+ -+ etmemd_stop_all_projects(); -+} -+ -+void test_etmem_mig_stop_error(void) -+{ -+ struct proj_test_param param; -+ -+ init_proj_param(¶m); -+ -+ CU_ASSERT_EQUAL(etmemd_migrate_stop(NULL), OPT_INVAL); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop(""), OPT_PRO_NOEXIST); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop("ETMEM"), OPT_PRO_NOEXIST); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop("ET^$%*MEM"), OPT_PRO_NOEXIST); -+ -+ param.proj_name = "add_for_migrate_stop_test"; -+ do_add_proj_test(¶m); -+ -+ CU_ASSERT_EQUAL(etmemd_migrate_start("add_for_migrate_stop_test"), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop("add_for_migrate_stop_test"), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop("add_for_migrate_stop_test"), OPT_PRO_STOPPED); -+ -+ etmemd_stop_all_projects(); -+} -+ -+static int start_project_multiple(int proj_add_num) -+{ -+ char project_name_str[PROJECT_NAME_MAX_LEN] = {0}; -+ unsigned int project_num; -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ for (project_num = 0; project_num < proj_add_num; project_num++) { -+ if (snprintf_s(project_name_str, PROJECT_NAME_MAX_LEN, PROJECT_NAME_MAX_LEN - 1, "project_add_del_test_num%d", -+ project_num) <= 0) { -+ printf("get project_name wrong.\n"); -+ return -1; -+ } -+ param.proj_name = project_name_str; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ CU_ASSERT_EQUAL(etmemd_migrate_start(project_name_str), OPT_SUCCESS); -+ } -+ -+ for (project_num = 0; project_num < proj_add_num; project_num++) { -+ if (snprintf_s(project_name_str, PROJECT_NAME_MAX_LEN, PROJECT_NAME_MAX_LEN - 1, "project_add_del_test_num%d", -+ project_num) <= 0) { -+ printf("get project_name wrong.\n"); -+ return -1; -+ } -+ param.proj_name = project_name_str; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop(project_name_str), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ } -+ -+ return 0; -+} -+ -+void test_etmem_mig_start_ok(void) -+{ -+ CU_ASSERT_EQUAL(start_project_multiple(1), 0); -+ CU_ASSERT_EQUAL(start_project_multiple(PROJECT_ADD_TEST_MAX_NUM), 0); -+} -+ -+typedef enum { -+ CUNIT_SCREEN = 0, -+ CUNIT_XMLFILE, -+ CUNIT_CONSOLE -+} cu_run_mode; -+ -+int main(int argc, const char **argv) -+{ -+ CU_pSuite suite; -+ CU_pTest pTest; -+ unsigned int num_failures; -+ cu_run_mode cunit_mode = CUNIT_SCREEN; -+ int error_num; -+ -+ if (argc > 1) { -+ cunit_mode = atoi(argv[1]); -+ } -+ -+ if (CU_initialize_registry() != CUE_SUCCESS) { -+ return -CU_get_error(); -+ } -+ -+ suite = CU_add_suite("etmem_project_ops", NULL, NULL); -+ if (suite == NULL) { -+ goto ERROR; -+ } -+ -+ if (CU_ADD_TEST(suite, test_etmem_prj_add_error) == NULL || -+ CU_ADD_TEST(suite, test_etmem_prj_del_error) == NULL || -+ CU_ADD_TEST(suite, test_etmem_project_add_ok) == NULL || -+ CU_ADD_TEST(suite, test_etmem_mig_start_error) == NULL || -+ CU_ADD_TEST(suite, test_etmem_mig_stop_error) == NULL || -+ CU_ADD_TEST(suite, test_etmem_mig_start_ok) == NULL) { -+ printf("CU_ADD_TEST fail. \n"); -+ goto ERROR; -+ } -+ -+ switch (cunit_mode) { -+ case CUNIT_SCREEN: -+ CU_basic_set_mode(CU_BRM_VERBOSE); -+ CU_basic_run_tests(); -+ break; -+ case CUNIT_XMLFILE: -+ CU_set_output_filename("etmemd_project.c"); -+ CU_automated_run_tests(); -+ break; -+ case CUNIT_CONSOLE: -+ CU_console_run_tests(); -+ break; -+ default: -+ printf("not support cunit mode, only support: 0 or 1\n"); -+ goto ERROR; -+ } -+ -+ num_failures = CU_get_number_of_failures(); -+ CU_cleanup_registry(); -+ return num_failures; -+ -+ERROR: -+ error_num = CU_get_error(); -+ CU_cleanup_registry(); -+ return -error_num; -+} --- -1.8.3.1 - diff --git a/0057-add-test-for-export-scan.patch b/0057-add-test-for-export-scan.patch deleted file mode 100644 index 9aa46b1..0000000 --- a/0057-add-test-for-export-scan.patch +++ /dev/null @@ -1,439 +0,0 @@ -From 50fb3c7251e423268164627db86c1c312c707e63 Mon Sep 17 00:00:00 2001 -From: Kemeng Shi -Date: Tue, 30 Nov 2021 11:11:01 +0800 -Subject: [PATCH 06/33] add test for export scan - -Signed-off-by: Kemeng Shi ---- - etmem/test/etmem_scan_ops_llt_test/CMakeLists.txt | 28 ++ - .../etmem_scan_ops_llt_test/etmem_scan_ops_llt.c | 383 +++++++++++++++++++++ - 2 files changed, 411 insertions(+) - create mode 100644 etmem/test/etmem_scan_ops_llt_test/CMakeLists.txt - create mode 100644 etmem/test/etmem_scan_ops_llt_test/etmem_scan_ops_llt.c - -diff --git a/etmem/test/etmem_scan_ops_llt_test/CMakeLists.txt b/etmem/test/etmem_scan_ops_llt_test/CMakeLists.txt -new file mode 100644 -index 0000000..c6ff96c ---- /dev/null -+++ b/etmem/test/etmem_scan_ops_llt_test/CMakeLists.txt -@@ -0,0 +1,28 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: shikemeng -+# * Create: 2021-11-30 -+# * Description: CMakefileList for etmem_scan_ops_llt_test -+# ******************************************************************************/ -+ -+project(etmem) -+ -+INCLUDE_DIRECTORIES(../../inc/etmem_inc) -+INCLUDE_DIRECTORIES(../../inc/etmemd_inc) -+INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -+ -+SET(EXE etmem_scan_ops_llt) -+ -+add_executable(etmem_scan_ops_llt -+ etmem_scan_ops_llt.c -+ ) -+ -+target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so pthread dl rt libboundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_scan_ops_llt_test/etmem_scan_ops_llt.c b/etmem/test/etmem_scan_ops_llt_test/etmem_scan_ops_llt.c -new file mode 100644 -index 0000000..1856072 ---- /dev/null -+++ b/etmem/test/etmem_scan_ops_llt_test/etmem_scan_ops_llt.c -@@ -0,0 +1,383 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: shikemeng -+ * Create: 2021-11-30 -+ * Description: test for export scan -+ ******************************************************************************/ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "etmemd_scan.h" -+#include "etmemd_project.h" -+#include "etmemd_engine.h" -+ -+static struct task_pid *alloc_tkpid(unsigned int pid, struct task *tk) -+{ -+ struct task_pid *tpid = NULL; -+ -+ tpid = (struct task_pid *)calloc(1, sizeof(struct task_pid)); -+ CU_ASSERT_PTR_NOT_NULL(tpid); -+ tpid->pid = pid; -+ tpid->tk = tk; -+ -+ return tpid; -+} -+ -+ -+static struct task *alloc_tk(int loop, int sleep) -+{ -+ struct task *tk = NULL; -+ struct project *proj = NULL; -+ struct engine *eng = NULL; -+ -+ proj = (struct project *)calloc(1, sizeof(struct project)); -+ CU_ASSERT_PTR_NOT_NULL(proj); -+ -+ proj->loop = loop; -+ proj->sleep = sleep; -+ -+ tk = (struct task *)calloc(1, sizeof(struct task)); -+ CU_ASSERT_PTR_NOT_NULL(tk); -+ -+ eng = calloc(1, sizeof(struct engine)); -+ eng->name = "cslide"; -+ -+ eng->proj = proj; -+ tk->eng = eng; -+ -+ return tk; -+} -+ -+void check_vmas(struct vmas *vmas) -+{ -+ CU_ASSERT_NOT_EQUAL(vmas->vma_cnt, 0); -+ -+ int i; -+ struct vma *curr_vma = NULL; -+ -+ curr_vma = vmas->vma_list; -+ for (i = 0; i < vmas->vma_cnt; i++) { -+ CU_ASSERT_PTR_NOT_NULL(curr_vma); -+ curr_vma = curr_vma->next; -+ } -+} -+ -+static void test_get_vmas_invalid(void) -+{ -+ const char *pid = "1"; -+ char *vmflags_array[10] = {"rd"}; -+ int vmflag_num = 1; -+ int is_anon_only = false; -+ struct vmas *vmas = NULL; -+ -+ CU_ASSERT_EQUAL(etmemd_scan_init(), 0); -+ -+ // non-exist pid -+ vmas = etmemd_get_vmas("0", vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NULL(vmas); -+ -+ // pid is NULL -+ vmas = etmemd_get_vmas(NULL, vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NULL(vmas); -+ -+ // pid contains invalid characters -+ vmas = etmemd_get_vmas("1-", vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NULL(vmas); -+ -+ // vmflags contains space -+ vmflags_array[0] = "r "; -+ vmas = etmemd_get_vmas(pid, vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NULL(vmas); -+ -+ // vmflags length is not 2 -+ vmflags_array[0] = "r"; -+ vmas = etmemd_get_vmas(pid, vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NULL(vmas); -+ -+ // vmflags is NULL -+ vmflags_array[0] = NULL; -+ vmas = etmemd_get_vmas(pid, vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NULL(vmas); -+ -+ // test free NULL -+ vmas = NULL; -+ etmemd_free_vmas(vmas); -+ -+ etmemd_scan_exit(); -+} -+ -+ -+static void test_get_vmas_valid(void) -+{ -+ const char *pid = "1"; -+ char *vmflags_array[10] = {"rd"}; -+ int vmflag_num = 1; -+ int is_anon_only = false; -+ struct vmas *vmas = NULL; -+ struct vma *curr_vma = NULL; -+ int i; -+ -+ // get vmas without init -+ vmas = etmemd_get_vmas(pid, vmflags_array, vmflag_num, is_anon_only); -+ -+ CU_ASSERT_PTR_NOT_NULL(vmas); -+ check_vmas(vmas); -+ -+ etmemd_free_vmas(vmas); -+ -+ // get vmas with init -+ CU_ASSERT_EQUAL(etmemd_scan_init(), 0); -+ -+ vmas = etmemd_get_vmas(pid, vmflags_array, vmflag_num, is_anon_only); -+ -+ CU_ASSERT_PTR_NOT_NULL(vmas); -+ check_vmas(vmas); -+ -+ etmemd_free_vmas(vmas); -+ -+ vmas = get_vmas("1"); -+ CU_ASSERT_PTR_NOT_NULL(vmas); -+ CU_ASSERT_NOT_EQUAL(vmas->vma_cnt, 0); -+ -+ curr_vma = vmas->vma_list; -+ for (i = 0; i < vmas->vma_cnt; i++) { -+ CU_ASSERT_PTR_NOT_NULL(curr_vma); -+ curr_vma = curr_vma->next; -+ } -+ -+ free_vmas(vmas); -+ etmemd_scan_exit(); -+} -+ -+static void test_get_vmas(void) -+{ -+ test_get_vmas_invalid(); -+ test_get_vmas_valid(); -+} -+ -+static void test_get_page_refs_invalid(void) -+{ -+ CU_ASSERT_EQUAL(etmemd_scan_init(), 0); -+ -+ const char *pid = "1"; -+ char *vmflags_array[10] = {"rd"}; -+ int vmflag_num = 1; -+ int is_anon_only = false; -+ struct vmas *vmas = NULL; -+ struct page_refs *page_refs = NULL; -+ int flags = SCAN_AS_HUGE | SCAN_IGN_HOST; -+ -+ // free null pointer -+ etmemd_free_page_refs(page_refs); -+ -+ // vmas is NULL -+ CU_ASSERT_EQUAL(etmemd_get_page_refs(vmas, pid, &page_refs, flags), -1); -+ -+ // vmas address range invalid -+ vmas = (struct vmas *)calloc(1, sizeof(struct vmas)); -+ CU_ASSERT_PTR_NOT_NULL(vmas); -+ vmas->vma_cnt = 1; -+ -+ struct vma *vma = (struct vma *)calloc(1, sizeof(struct vma)); -+ CU_ASSERT_PTR_NOT_NULL(vma); -+ vma->start = 0x0ff; -+ vma->end = 0x000; -+ vma->next = NULL; -+ vmas->vma_list = vma; -+ -+ CU_ASSERT_EQUAL(etmemd_get_page_refs(vmas, pid, &page_refs, flags), -1); -+ etmemd_free_vmas(vmas); -+ -+ vmas = etmemd_get_vmas(pid, vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NOT_NULL(vmas); -+ check_vmas(vmas); -+ -+ // pid not exist -+ CU_ASSERT_EQUAL(etmemd_get_page_refs(vmas, "0", &page_refs, flags), -1); -+ CU_ASSERT_PTR_NULL(page_refs); -+ -+ // pid is NULL -+ CU_ASSERT_EQUAL(etmemd_get_page_refs(vmas, NULL, &page_refs, flags), -1); -+ CU_ASSERT_PTR_NULL(page_refs); -+ -+ // pid contains invalid chars -+ CU_ASSERT_EQUAL(etmemd_get_page_refs(vmas, "--", &page_refs, flags), -1); -+ CU_ASSERT_PTR_NULL(page_refs); -+ -+ etmemd_free_page_refs(page_refs); -+ etmemd_free_vmas(vmas); -+ etmemd_scan_exit(); -+} -+ -+static void test_get_page_refs_valid() -+{ -+ CU_ASSERT_EQUAL(etmemd_scan_init(), 0); -+ -+ const char *pid = "1"; -+ char *vmflags_array[10] = {"rd"}; -+ int vmflag_num = 1; -+ int is_anon_only = false; -+ struct vmas *vmas = NULL; -+ struct page_refs *page_refs = NULL; -+ int flags = SCAN_AS_HUGE | SCAN_IGN_HOST; -+ -+ vmas = etmemd_get_vmas(pid, vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NOT_NULL(vmas); -+ check_vmas(vmas); -+ -+ CU_ASSERT_EQUAL(etmemd_get_page_refs(vmas, pid, &page_refs, flags), 0); -+ CU_ASSERT_PTR_NOT_NULL(page_refs); -+ -+ unsigned long use_rss; -+ -+ CU_ASSERT_EQUAL(get_page_refs(vmas, pid, &page_refs, &use_rss, 0), 0); -+ CU_ASSERT_PTR_NOT_NULL(page_refs); -+ CU_ASSERT_NOT_EQUAL(use_rss, 0); -+ -+ etmemd_free_page_refs(page_refs); -+ etmemd_free_vmas(vmas); -+ etmemd_scan_exit(); -+} -+ -+static void test_get_page_refs(void) -+{ -+ test_get_page_refs_invalid(); -+ test_get_page_refs_valid(); -+} -+ -+static void test_scan_error(void) -+{ -+ unsigned int pid_error = 1111111111; -+ int loop = 1; -+ int sleep = 1; -+ struct task_pid *tpid = NULL; -+ struct task *tk = NULL; -+ -+ tk = alloc_tk(loop, sleep); -+ tpid = alloc_tkpid(pid_error, tk); -+ -+ CU_ASSERT_PTR_NULL(etmemd_do_scan(tpid, NULL)); -+ CU_ASSERT_PTR_NULL(etmemd_do_scan(tpid, tk)); -+ -+ free(tk); -+ free(tpid); -+} -+ -+static void test_etmem_scan_ok(void) -+{ -+ unsigned int pid_ok = 1; -+ int loop = 1; -+ int sleep = 1; -+ struct page_refs *page_refs = NULL; -+ struct task_pid *tpid = NULL; -+ struct task *tk = NULL; -+ -+ tk = alloc_tk(loop, sleep); -+ tpid = alloc_tkpid(pid_ok, tk); -+ -+ CU_ASSERT_EQUAL(etmemd_scan_init(), 0); -+ -+ page_refs = etmemd_do_scan(tpid, tk); -+ CU_ASSERT_PTR_NOT_NULL(page_refs); -+ free(tk); -+ free(tpid); -+ clean_page_refs_unexpected(&page_refs); -+ CU_ASSERT_PTR_NULL(page_refs); -+ etmemd_scan_exit(); -+} -+ -+static void test_add_pg_to_mem_grade() -+{ -+ const char *pid = "1"; -+ struct vmas *vma = NULL; -+ struct page_refs *page_refs = NULL; -+ struct page_refs *list = NULL; -+ -+ CU_ASSERT_EQUAL(etmemd_scan_init(), 0); -+ -+ vma = get_vmas(pid); -+ CU_ASSERT_EQUAL(get_page_refs(vma, pid, &page_refs, NULL, 0), 0); -+ page_refs = add_page_refs_into_memory_grade(page_refs, &list); -+ CU_ASSERT_PTR_NOT_NULL(page_refs); -+ CU_ASSERT_PTR_NOT_NULL(list); -+ -+ free(list); -+ etmemd_free_page_refs(page_refs); -+ free_vmas(vma); -+ etmemd_scan_exit(); -+} -+ -+typedef enum { -+ CUNIT_SCREEN = 0, -+ CUNIT_XMLFILE, -+ CUNIT_CONSOLE -+} cu_run_mode; -+ -+int main(int argc, const char **argv) -+{ -+ CU_pSuite suite; -+ CU_pTest pTest; -+ unsigned int num_failures; -+ cu_run_mode cunit_mode = CUNIT_SCREEN; -+ int error_num; -+ -+ if (argc > 1) { -+ cunit_mode = atoi(argv[1]); -+ } -+ -+ if (CU_initialize_registry() != CUE_SUCCESS) { -+ return CU_get_error(); -+ } -+ -+ suite = CU_add_suite("etmem_scan_ops", NULL, NULL); -+ if (suite == NULL) { -+ goto ERROR; -+ } -+ -+ if (CU_ADD_TEST(suite, test_get_vmas) == NULL || -+ CU_ADD_TEST(suite, test_get_page_refs) == NULL || -+ CU_ADD_TEST(suite, test_scan_error) == NULL || -+ CU_ADD_TEST(suite, test_etmem_scan_ok) == NULL || -+ CU_ADD_TEST(suite, test_add_pg_to_mem_grade) == NULL) { -+ goto ERROR; -+ } -+ -+ switch (cunit_mode) { -+ case CUNIT_SCREEN: -+ CU_basic_set_mode(CU_BRM_VERBOSE); -+ CU_basic_run_tests(); -+ break; -+ case CUNIT_XMLFILE: -+ CU_set_output_filename("etmemd_scan.c"); -+ CU_automated_run_tests(); -+ break; -+ case CUNIT_CONSOLE: -+ CU_console_run_tests(); -+ break; -+ default: -+ printf("not support cunit mode, only support: 0 or 1\n"); -+ goto ERROR; -+ } -+ -+ num_failures = CU_get_number_of_failures(); -+ CU_cleanup_registry(); -+ return num_failures; -+ -+ERROR: -+ error_num = CU_get_error(); -+ CU_cleanup_registry(); -+ return -error_num; -+} --- -1.8.3.1 - diff --git a/0058-add-code-of-testcase-for-etmem-common-function.patch b/0058-add-code-of-testcase-for-etmem-common-function.patch deleted file mode 100644 index 583df69..0000000 --- a/0058-add-code-of-testcase-for-etmem-common-function.patch +++ /dev/null @@ -1,1436 +0,0 @@ -From f4b6e6e9e15d7bfb3e82d7b5a59157adf49fc426 Mon Sep 17 00:00:00 2001 -From: liubo -Date: Wed, 8 Dec 2021 16:11:36 +0800 -Subject: [PATCH 07/33] add code of testcase for etmem common function - ---- - .../test/etmem_common_func_llt_test/CMakeLists.txt | 27 ++ - .../etmem_common_func_llt.c | 315 ++++++++++++++ - .../test_systemd_service.sh | 35 ++ - .../test/etmem_project_ops_llt_test/CMakeLists.txt | 28 ++ - .../etmem_project_ops_llt.c | 468 +++++++++++++++++++++ - etmem/test/project/CMakeLists.txt | 28 -- - etmem/test/project/etmem_project_ops_llt.c | 468 --------------------- - 7 files changed, 873 insertions(+), 496 deletions(-) - create mode 100644 etmem/test/etmem_common_func_llt_test/CMakeLists.txt - create mode 100644 etmem/test/etmem_common_func_llt_test/etmem_common_func_llt.c - create mode 100755 etmem/test/etmem_common_func_llt_test/test_systemd_service.sh - create mode 100644 etmem/test/etmem_project_ops_llt_test/CMakeLists.txt - create mode 100644 etmem/test/etmem_project_ops_llt_test/etmem_project_ops_llt.c - delete mode 100644 etmem/test/project/CMakeLists.txt - delete mode 100644 etmem/test/project/etmem_project_ops_llt.c - -diff --git a/etmem/test/etmem_common_func_llt_test/CMakeLists.txt b/etmem/test/etmem_common_func_llt_test/CMakeLists.txt -new file mode 100644 -index 0000000..be3b365 ---- /dev/null -+++ b/etmem/test/etmem_common_func_llt_test/CMakeLists.txt -@@ -0,0 +1,27 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: liubo -+# * Create: 2021-12-07 -+# * Description: CMakefileList for etmem_common_ops_llt to compile -+# ******************************************************************************/ -+ -+project(etmem) -+ -+INCLUDE_DIRECTORIES(../../inc/etmem_inc) -+INCLUDE_DIRECTORIES(../../inc/etmemd_inc) -+INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -+ -+SET(EXE etmem_common_func_llt) -+ -+add_executable(${EXE} -+etmem_common_func_llt.c) -+ -+target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_common_func_llt_test/etmem_common_func_llt.c b/etmem/test/etmem_common_func_llt_test/etmem_common_func_llt.c -new file mode 100644 -index 0000000..2bb5b11 ---- /dev/null -+++ b/etmem/test/etmem_common_func_llt_test/etmem_common_func_llt.c -@@ -0,0 +1,315 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liubo -+ * Create: 2021-12-07 -+ * Description: This is a source file of the unit test for common function in etmem. -+ ******************************************************************************/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "etmemd_common.h" -+#include "etmemd_engine.h" -+#include "etmemd_rpc.h" -+ -+static void clean_flags(bool *ishelp) -+{ -+ *ishelp = false; -+ optarg = NULL; -+ optind = 0; -+} -+ -+static void test_parse_cmdline_error(void) -+{ -+ bool is_help = false; -+ char *cmd[] = {"./etmemd"}; -+ char *cmd_error_para[] = {"./etmemd", "-d"}; -+ char *cmd_error_help[] = {"./etmemd", "help"}; -+ char *cmd_err_help[] = {"./etmemd", "---help"}; -+ char *cmd_error_log[] = {"./etmemd", "-l"}; -+ char *cmd_lack_sock[] = {"./etmemd", "-l", "0"}; -+ char *cmd_sock_lack_para[] = {"./etmemd", "-l", "0", "-s"}; -+ char *cmd_sock_err[] = {"./etmemd", "-l", "0", "1", "-s"}; -+ char *cmd_mul_log[] = {"./etmemd", "-l", "0", "-l", "0"}; -+ char *cmd_mul_sock[] = {"./etmemd", "-s", "sock0", "-s", "sock1"}; -+ char *cmd_para_too_long[] = {"./etmemd", "-l", "0", "-l", "0", "-s", "sock"}; -+ char *cmd_para_redundant[] = {"./etmemd", "-l", "0", "-h", "-s", "sock"}; -+ char *cmd_lack_s[] = {"./etmemd", "-l", "0", "-h"}; -+ char *cmd_unwanted_para[] = {"./etmemd", "-l", "0", "-d", "file"}; -+ -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(0, NULL, &is_help), -1); -+ clean_flags(&is_help); -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd) / sizeof(cmd[0]), cmd, &is_help), -1); -+ clean_flags(&is_help); -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_error_para) / sizeof(cmd_error_para[0]), cmd_error_para, &is_help), -1); -+ clean_flags(&is_help); -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_error_help) / sizeof(cmd_error_help[0]), cmd_error_help, &is_help), -1); -+ clean_flags(&is_help); -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_err_help) / sizeof(cmd_err_help[0]), cmd_err_help, &is_help), -1); -+ clean_flags(&is_help); -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_error_log) / sizeof(cmd_error_log[0]), cmd_error_log, &is_help), -1); -+ clean_flags(&is_help); -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_lack_sock) / sizeof(cmd_lack_sock[0]), cmd_lack_sock, &is_help), -1); -+ clean_flags(&is_help); -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_sock_lack_para) / sizeof(cmd_sock_lack_para[0]), cmd_sock_lack_para, &is_help), -1); -+ clean_flags(&is_help); -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_sock_err) / sizeof(cmd_sock_err[0]), cmd_sock_err, &is_help), -1); -+ clean_flags(&is_help); -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_mul_log) / sizeof(cmd_mul_log[0]), cmd_mul_log, &is_help), -1); -+ clean_flags(&is_help); -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_mul_sock) / sizeof(cmd_mul_sock[0]), cmd_mul_sock, &is_help), -1); -+ etmemd_sock_name_free(); -+ clean_flags(&is_help); -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_para_too_long) / sizeof(cmd_para_too_long[0]), cmd_para_too_long, &is_help), -1); -+ clean_flags(&is_help); -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_para_redundant) / sizeof(cmd_para_redundant[0]), cmd_para_redundant, &is_help), -1); -+ clean_flags(&is_help); -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_lack_s) / sizeof(cmd_lack_s[0]), cmd_lack_s, &is_help), -1); -+ clean_flags(&is_help); -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_unwanted_para) / sizeof(cmd_unwanted_para[0]), cmd_unwanted_para, &is_help), -1); -+ clean_flags(&is_help); -+} -+ -+static void test_parse_cmdline_ok(void) -+{ -+ bool is_help = false; -+ char *cmd[] = {"./etmemd", "-h"}; -+ char *cmd_h[] = {"./etmemd", "-help"}; -+ char *cmd_help[] = {"./etmemd", "--help"}; -+ char *cmd_ok[] = {"./etmemd", "-l", "0", "-s", "cmd_ok"}; -+ char *cmd_only_sock[] = {"./etmemd", "-s", "cmd_only_sock"}; -+ -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd) / sizeof(cmd[0]), cmd, &is_help), 0); -+ etmemd_sock_name_free(); -+ clean_flags(&is_help); -+ -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_ok) / sizeof(cmd_ok[0]), cmd_ok, &is_help), 0); -+ clean_flags(&is_help); -+ -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_h) / sizeof(cmd_h[0]), cmd_h, &is_help), 0); -+ clean_flags(&is_help); -+ -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_help) / sizeof(cmd_help[0]), cmd_help, &is_help), 0); -+ clean_flags(&is_help); -+ -+ CU_ASSERT_EQUAL(etmemd_parse_cmdline(sizeof(cmd_only_sock) / sizeof(cmd_only_sock[0]), cmd_only_sock, &is_help), 0); -+ etmemd_sock_name_free(); -+ clean_flags(&is_help); -+} -+ -+static void test_get_int_value_error(void) -+{ -+ int value; -+ -+ CU_ASSERT_EQUAL(get_int_value("a1", &value), -1); -+ CU_ASSERT_EQUAL(get_int_value("-2147483649", &value), -1); -+ CU_ASSERT_EQUAL(get_int_value("2147483648", &value), -1); -+} -+ -+static void test_get_int_value_ok(void) -+{ -+ int value; -+ -+ CU_ASSERT_EQUAL(get_int_value("-2147483648", &value), 0); -+ CU_ASSERT_EQUAL(value, INT_MIN); -+ CU_ASSERT_EQUAL(get_int_value("-2147483647", &value), 0); -+ CU_ASSERT_EQUAL(value, INT_MIN + 1); -+ CU_ASSERT_EQUAL(get_int_value("0", &value), 0); -+ CU_ASSERT_EQUAL(value, 0); -+ CU_ASSERT_EQUAL(get_int_value("2147483646", &value), 0); -+ CU_ASSERT_EQUAL(value, INT_MAX - 1); -+ CU_ASSERT_EQUAL(get_int_value("2147483647", &value), 0); -+ CU_ASSERT_EQUAL(value, INT_MAX); -+} -+ -+static void test_get_uint_value_error(void) -+{ -+ unsigned int value; -+ -+ CU_ASSERT_EQUAL(get_unsigned_int_value("a1", &value), -1); -+ CU_ASSERT_EQUAL(get_unsigned_int_value("-1", &value), -1); -+ CU_ASSERT_EQUAL(get_unsigned_int_value("4294967296", &value), -1); -+} -+ -+static void test_get_uint_value_ok(void) -+{ -+ unsigned int value; -+ -+ CU_ASSERT_EQUAL(get_unsigned_int_value("0", &value), 0); -+ CU_ASSERT_EQUAL(value, 0); -+ CU_ASSERT_EQUAL(get_unsigned_int_value("1", &value), 0); -+ CU_ASSERT_EQUAL(value, 1); -+ CU_ASSERT_EQUAL(get_unsigned_int_value("4294967294", &value), 0); -+ CU_ASSERT_EQUAL(value, UINT_MAX - 1); -+ CU_ASSERT_EQUAL(get_unsigned_int_value("4294967295", &value), 0); -+ CU_ASSERT_EQUAL(value, UINT_MAX); -+} -+ -+static void test_get_proc_file_error(void) -+{ -+ CU_ASSERT_PTR_NULL(etmemd_get_proc_file("0", "/maps", 0, "r")); -+ CU_ASSERT_PTR_NULL(etmemd_get_proc_file("1", "maps", 0, "r")); -+ CU_ASSERT_PTR_NULL(etmemd_get_proc_file("1", "/map", 0, "r")); -+} -+ -+static void test_get_proc_file_ok(void) -+{ -+ FILE *fp = NULL; -+ -+ fp = etmemd_get_proc_file("1", "/maps", 0, "r"); -+ -+ CU_ASSERT_EQUAL(fclose(fp), 0); -+} -+ -+static void test_get_key_value_error(void) -+{ -+ char key[KEY_VALUE_MAX_LEN] = {}; -+ char value[KEY_VALUE_MAX_LEN] = {}; -+ -+ CU_ASSERT_EQUAL(get_keyword_and_value("", key, value), -1); -+ CU_ASSERT_EQUAL(get_keyword_and_value("abcd", key, value), -1); -+ CU_ASSERT_EQUAL(get_keyword_and_value(":1", key, value), -1); -+ CU_ASSERT_EQUAL(get_keyword_and_value("a:", key, value), -1); -+ CU_ASSERT_EQUAL(get_keyword_and_value("#a:1", key, value), -1); -+ CU_ASSERT_EQUAL(get_keyword_and_value("a.b:1", key, value), -1); -+ CU_ASSERT_EQUAL(get_keyword_and_value("loop:2*4", key, value), -1); -+} -+ -+static void test_get_key_value_ok(void) -+{ -+ char key[KEY_VALUE_MAX_LEN] = {}; -+ char value[KEY_VALUE_MAX_LEN] = {}; -+ -+ CU_ASSERT_EQUAL(get_keyword_and_value("loop:30", key, value), 0); -+ CU_ASSERT_STRING_EQUAL(key, "loop"); -+ CU_ASSERT_STRING_EQUAL(value, "30"); -+ CU_ASSERT_EQUAL(get_keyword_and_value("loop 30", key, value), 0); -+ CU_ASSERT_STRING_EQUAL(key, "loop"); -+ CU_ASSERT_STRING_EQUAL(value, "30"); -+ CU_ASSERT_EQUAL(get_keyword_and_value("loop\t30", key, value), 0); -+ CU_ASSERT_STRING_EQUAL(key, "loop"); -+ CU_ASSERT_STRING_EQUAL(value, "30"); -+ CU_ASSERT_EQUAL(get_keyword_and_value("loop :30", key, value), 0); -+ CU_ASSERT_STRING_EQUAL(key, "loop"); -+ CU_ASSERT_STRING_EQUAL(value, "30"); -+ CU_ASSERT_EQUAL(get_keyword_and_value("loop\t:30", key, value), 0); -+ CU_ASSERT_STRING_EQUAL(key, "loop"); -+ CU_ASSERT_STRING_EQUAL(value, "30"); -+ CU_ASSERT_EQUAL(get_keyword_and_value("loop\t 30", key, value), 0); -+ CU_ASSERT_STRING_EQUAL(key, "loop"); -+ CU_ASSERT_STRING_EQUAL(value, "30"); -+ CU_ASSERT_EQUAL(get_keyword_and_value("a_b:1", key, value), 0); -+ CU_ASSERT_STRING_EQUAL(key, "a_b"); -+ CU_ASSERT_STRING_EQUAL(value, "1"); -+ CU_ASSERT_EQUAL(get_keyword_and_value("%P:1", key, value), 0); -+ CU_ASSERT_STRING_EQUAL(key, "%P"); -+ CU_ASSERT_STRING_EQUAL(value, "1"); -+ CU_ASSERT_EQUAL(get_keyword_and_value("%P:0.2", key, value), 0); -+ CU_ASSERT_STRING_EQUAL(key, "%P"); -+ CU_ASSERT_STRING_EQUAL(value, "0.2"); -+ CU_ASSERT_EQUAL(get_keyword_and_value("%P:20%", key, value), 0); -+ CU_ASSERT_STRING_EQUAL(key, "%P"); -+ CU_ASSERT_STRING_EQUAL(value, "20%"); -+ CU_ASSERT_EQUAL(get_keyword_and_value("output:/var/run", key, value), 0); -+ CU_ASSERT_STRING_EQUAL(key, "output"); -+ CU_ASSERT_STRING_EQUAL(value, "/var/run"); -+ CU_ASSERT_EQUAL(get_keyword_and_value("engine:dynamic_fb", key, value), 0); -+ CU_ASSERT_STRING_EQUAL(key, "engine"); -+ CU_ASSERT_STRING_EQUAL(value, "dynamic_fb"); -+ CU_ASSERT_EQUAL(get_keyword_and_value("name:qemu-kvm", key, value), 0); -+ CU_ASSERT_STRING_EQUAL(key, "name"); -+ CU_ASSERT_STRING_EQUAL(value, "qemu-kvm"); -+} -+ -+typedef enum { -+ CUNIT_SCREEN = 0, -+ CUNIT_XMLFILE, -+ CUNIT_CONSOLE -+} cu_run_mode; -+ -+void test_etmem_systemd_service_0001(void) -+{ -+ CU_ASSERT_EQUAL(system("../etmem_common_func_llt_test/test_systemd_service.sh"), 0); -+} -+ -+int main(int argc, const char **argv) -+{ -+ CU_pSuite suite; -+ CU_pTest pTest; -+ unsigned int num_failures; -+ cu_run_mode cunit_mode = CUNIT_SCREEN; -+ int error_num; -+ -+ if (argc > 1) { -+ cunit_mode = atoi(argv[1]); -+ } -+ -+ if (CU_initialize_registry() != CUE_SUCCESS) { -+ return -CU_get_error(); -+ } -+ -+ suite = CU_add_suite("etmem_common_func", NULL, NULL); -+ if (suite == NULL) { -+ goto ERROR; -+ } -+ -+ if (CU_ADD_TEST(suite, test_get_int_value_error) == NULL || -+ CU_ADD_TEST(suite, test_get_int_value_ok) == NULL || -+ CU_ADD_TEST(suite, test_get_uint_value_error) == NULL || -+ CU_ADD_TEST(suite, test_get_uint_value_ok) == NULL || -+ CU_ADD_TEST(suite, test_get_key_value_error) == NULL || -+ CU_ADD_TEST(suite, test_get_key_value_ok) == NULL || -+ CU_ADD_TEST(suite, test_parse_cmdline_error) == NULL || -+ CU_ADD_TEST(suite, test_parse_cmdline_ok) == NULL || -+ CU_ADD_TEST(suite, test_get_proc_file_error) == NULL || -+ CU_ADD_TEST(suite, test_get_proc_file_ok) == NULL || -+ CU_ADD_TEST(suite, test_etmem_systemd_service_0001) == NULL) { -+ printf("CU_ADD_TEST fail. \n"); -+ goto ERROR; -+ } -+ -+ switch (cunit_mode) { -+ case CUNIT_SCREEN: -+ CU_basic_set_mode(CU_BRM_VERBOSE); -+ CU_basic_run_tests(); -+ break; -+ case CUNIT_XMLFILE: -+ CU_set_output_filename("etmemd_common.c"); -+ CU_automated_run_tests(); -+ break; -+ case CUNIT_CONSOLE: -+ CU_console_run_tests(); -+ break; -+ default: -+ printf("not support cunit mode, only support: 0 or 1\n"); -+ goto ERROR; -+ } -+ -+ num_failures = CU_get_number_of_failures(); -+ CU_cleanup_registry(); -+ return num_failures; -+ -+ERROR: -+ error_num = CU_get_error(); -+ CU_cleanup_registry(); -+ return -error_num; -+} -diff --git a/etmem/test/etmem_common_func_llt_test/test_systemd_service.sh b/etmem/test/etmem_common_func_llt_test/test_systemd_service.sh -new file mode 100755 -index 0000000..852ad8c ---- /dev/null -+++ b/etmem/test/etmem_common_func_llt_test/test_systemd_service.sh -@@ -0,0 +1,35 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: liubo -+# * Create: 2021-12-07 -+# * Description: This is a shell script of the unit test for etmem commont functions -+# ******************************************************************************/ -+ -+test_start_as_service() -+{ -+ ./bin/etmemd -l 0 -s dt_socket -m & -+ etmemd_pid=$! -+ echo "etmemd_pid ${etmemd_pid}" -+ sleep 1 -+ ./bin/etmem obj add -f ../conf/conf_slide/config_file -s dt_socket -+ if [ "$?" != "0" ];then -+ echo "add config fail to etmemd service unexpected" -+ exit 1 -+ fi -+ ps -aux |grep -v grep |grep "etmemd -l 0 -s dt_socket -m" -+ if [ "$?" != "0" ];then -+ echo "etmemd service exit unexpected after add config" -+ exit 1 -+ fi -+ killall etmemd -+} -+ -+test_start_as_service -diff --git a/etmem/test/etmem_project_ops_llt_test/CMakeLists.txt b/etmem/test/etmem_project_ops_llt_test/CMakeLists.txt -new file mode 100644 -index 0000000..70cd530 ---- /dev/null -+++ b/etmem/test/etmem_project_ops_llt_test/CMakeLists.txt -@@ -0,0 +1,28 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: liubo -+# * Create: 2021-11-29 -+# * Description: CMakefileList for etmem_project_ops_llt to compile -+# ******************************************************************************/ -+ -+project(etmem) -+ -+INCLUDE_DIRECTORIES(../../inc/etmem_inc) -+INCLUDE_DIRECTORIES(../../inc/etmemd_inc) -+INCLUDE_DIRECTORIES(../common) -+INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -+ -+SET(EXE etmem_project_ops_llt) -+ -+add_executable(${EXE} -+etmem_project_ops_llt.c) -+ -+target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so ${BUILD_DIR}/lib/libtest.so pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_project_ops_llt_test/etmem_project_ops_llt.c b/etmem/test/etmem_project_ops_llt_test/etmem_project_ops_llt.c -new file mode 100644 -index 0000000..edd2330 ---- /dev/null -+++ b/etmem/test/etmem_project_ops_llt_test/etmem_project_ops_llt.c -@@ -0,0 +1,468 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liubo -+ * Create: 2021-11-29 -+ * Description: This is a source file of the unit test for project-related commands in etmem. -+ ******************************************************************************/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "etmemd_project.h" -+#include "etmemd_file.h" -+#include "etmemd_common.h" -+#include "securec.h" -+ -+#include "test_common.h" -+ -+#include -+#include -+#include -+ -+#define PROJECT_ADD_TEST_MAX_NUM 50 -+ -+static struct proj_test_param g_proj_test_param; -+ -+static void etmem_pro_add_name(void) -+{ -+ const char *project_name_long = "project name cannot longer than 32 ppmpppppppppppppppppppppppppppppppppppppppppppppp"; -+ GKeyFile *config = NULL; -+ struct proj_test_param param; -+ -+ init_proj_param(¶m); -+ -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_PRO_EXISTED); -+ destroy_proj_config(config); -+ -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.proj_name = ""; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.proj_name = project_name_long; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.proj_name = DEFAULT_PROJ; -+} -+ -+static void etmem_pro_add_interval(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ param.interval = "0"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.interval = "1"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.interval = "2"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.interval = "1199"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.interval = "1200"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.interval = "1201"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.interval = "abc"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+} -+ -+static void etmem_pro_add_loop(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ param.loop = "0"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.loop = "1"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.loop = "2"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.loop = "119"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.loop = "120"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.loop = "121"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.loop = "abc"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+} -+ -+static void etmem_pro_add_sleep(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ param.sleep = "0"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.sleep = "1"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.sleep = "2"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.sleep = "1199"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.sleep = "1200"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.sleep = "1201"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.sleep = "wrong sleep type"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+} -+ -+static void etmem_pro_lack_loop(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ param.loop = NULL; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+} -+ -+void test_etmem_prj_add_error(void) -+{ -+ etmem_pro_add_name(); -+ etmem_pro_add_interval(); -+ etmem_pro_add_loop(); -+ etmem_pro_add_sleep(); -+ etmem_pro_lack_loop(); -+} -+ -+void test_etmem_prj_del_error(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ param.proj_name = ""; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.proj_name = "noexist"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_PRO_NOEXIST); -+ destroy_proj_config(config); -+} -+ -+static void add_project_once(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ CU_ASSERT_EQUAL(etmemd_project_show(NULL, 0), OPT_PRO_NOEXIST); -+ -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ CU_ASSERT_EQUAL(etmemd_project_show(NULL, 0), OPT_SUCCESS); -+ -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ CU_ASSERT_EQUAL(etmemd_project_show("noexist", 0), OPT_PRO_NOEXIST); -+} -+ -+static int add_project_multiple(int proj_add_num) -+{ -+ char project_name_str[PROJECT_NAME_MAX_LEN] = {0}; -+ unsigned int project_num; -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ for (project_num = 0; project_num < proj_add_num; project_num++) { -+ if (snprintf_s(project_name_str, PROJECT_NAME_MAX_LEN, PROJECT_NAME_MAX_LEN - 1, "project_add_del_test_num%d", -+ project_num) <= 0) { -+ printf("get project_name wrong.\n"); -+ return -1; -+ } -+ param.proj_name = project_name_str; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ } -+ -+ CU_ASSERT_EQUAL(etmemd_project_show(NULL, 0), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_show("project_add_del_test_num5", 0), OPT_SUCCESS); -+ -+ for (project_num = 0; project_num < proj_add_num; project_num++) { -+ if (snprintf_s(project_name_str, PROJECT_NAME_MAX_LEN, PROJECT_NAME_MAX_LEN - 1, "project_add_del_test_num%d", -+ project_num) <= 0) { -+ printf("get project_name wrong.\n"); -+ return -1; -+ } -+ param.proj_name = project_name_str; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ } -+ -+ return 0; -+} -+ -+void test_etmem_project_add_ok(void) -+{ -+ add_project_once(); -+ CU_ASSERT_EQUAL(add_project_multiple(PROJECT_ADD_TEST_MAX_NUM), 0); -+} -+ -+void test_etmem_mig_start_error(void) -+{ -+ struct proj_test_param param; -+ -+ init_proj_param(¶m); -+ -+ CU_ASSERT_EQUAL(etmemd_migrate_start(NULL), OPT_INVAL); -+ CU_ASSERT_EQUAL(etmemd_migrate_start(""), OPT_PRO_NOEXIST); -+ CU_ASSERT_EQUAL(etmemd_migrate_start("etmem"), OPT_PRO_NOEXIST); -+ CU_ASSERT_EQUAL(etmemd_migrate_start("me^$%*mig"), OPT_PRO_NOEXIST); -+ -+ param.proj_name = "add_for_migrate_test"; -+ do_add_proj_test(¶m); -+ -+ CU_ASSERT_EQUAL(etmemd_migrate_start("add_for_migrate_test"), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_start("add_for_migrate_test"), OPT_PRO_STARTED); -+ -+ etmemd_stop_all_projects(); -+} -+ -+void test_etmem_mig_stop_error(void) -+{ -+ struct proj_test_param param; -+ -+ init_proj_param(¶m); -+ -+ CU_ASSERT_EQUAL(etmemd_migrate_stop(NULL), OPT_INVAL); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop(""), OPT_PRO_NOEXIST); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop("ETMEM"), OPT_PRO_NOEXIST); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop("ET^$%*MEM"), OPT_PRO_NOEXIST); -+ -+ param.proj_name = "add_for_migrate_stop_test"; -+ do_add_proj_test(¶m); -+ -+ CU_ASSERT_EQUAL(etmemd_migrate_start("add_for_migrate_stop_test"), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop("add_for_migrate_stop_test"), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop("add_for_migrate_stop_test"), OPT_PRO_STOPPED); -+ -+ etmemd_stop_all_projects(); -+} -+ -+static int start_project_multiple(int proj_add_num) -+{ -+ char project_name_str[PROJECT_NAME_MAX_LEN] = {0}; -+ unsigned int project_num; -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ for (project_num = 0; project_num < proj_add_num; project_num++) { -+ if (snprintf_s(project_name_str, PROJECT_NAME_MAX_LEN, PROJECT_NAME_MAX_LEN - 1, "project_add_del_test_num%d", -+ project_num) <= 0) { -+ printf("get project_name wrong.\n"); -+ return -1; -+ } -+ param.proj_name = project_name_str; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ CU_ASSERT_EQUAL(etmemd_migrate_start(project_name_str), OPT_SUCCESS); -+ } -+ -+ for (project_num = 0; project_num < proj_add_num; project_num++) { -+ if (snprintf_s(project_name_str, PROJECT_NAME_MAX_LEN, PROJECT_NAME_MAX_LEN - 1, "project_add_del_test_num%d", -+ project_num) <= 0) { -+ printf("get project_name wrong.\n"); -+ return -1; -+ } -+ param.proj_name = project_name_str; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop(project_name_str), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ } -+ -+ return 0; -+} -+ -+void test_etmem_mig_start_ok(void) -+{ -+ CU_ASSERT_EQUAL(start_project_multiple(1), 0); -+ CU_ASSERT_EQUAL(start_project_multiple(PROJECT_ADD_TEST_MAX_NUM), 0); -+} -+ -+typedef enum { -+ CUNIT_SCREEN = 0, -+ CUNIT_XMLFILE, -+ CUNIT_CONSOLE -+} cu_run_mode; -+ -+int main(int argc, const char **argv) -+{ -+ CU_pSuite suite; -+ CU_pTest pTest; -+ unsigned int num_failures; -+ cu_run_mode cunit_mode = CUNIT_SCREEN; -+ int error_num; -+ -+ if (argc > 1) { -+ cunit_mode = atoi(argv[1]); -+ } -+ -+ if (CU_initialize_registry() != CUE_SUCCESS) { -+ return -CU_get_error(); -+ } -+ -+ suite = CU_add_suite("etmem_project_ops", NULL, NULL); -+ if (suite == NULL) { -+ goto ERROR; -+ } -+ -+ if (CU_ADD_TEST(suite, test_etmem_prj_add_error) == NULL || -+ CU_ADD_TEST(suite, test_etmem_prj_del_error) == NULL || -+ CU_ADD_TEST(suite, test_etmem_project_add_ok) == NULL || -+ CU_ADD_TEST(suite, test_etmem_mig_start_error) == NULL || -+ CU_ADD_TEST(suite, test_etmem_mig_stop_error) == NULL || -+ CU_ADD_TEST(suite, test_etmem_mig_start_ok) == NULL) { -+ printf("CU_ADD_TEST fail. \n"); -+ goto ERROR; -+ } -+ -+ switch (cunit_mode) { -+ case CUNIT_SCREEN: -+ CU_basic_set_mode(CU_BRM_VERBOSE); -+ CU_basic_run_tests(); -+ break; -+ case CUNIT_XMLFILE: -+ CU_set_output_filename("etmemd_project.c"); -+ CU_automated_run_tests(); -+ break; -+ case CUNIT_CONSOLE: -+ CU_console_run_tests(); -+ break; -+ default: -+ printf("not support cunit mode, only support: 0 or 1\n"); -+ goto ERROR; -+ } -+ -+ num_failures = CU_get_number_of_failures(); -+ CU_cleanup_registry(); -+ return num_failures; -+ -+ERROR: -+ error_num = CU_get_error(); -+ CU_cleanup_registry(); -+ return -error_num; -+} -diff --git a/etmem/test/project/CMakeLists.txt b/etmem/test/project/CMakeLists.txt -deleted file mode 100644 -index 70cd530..0000000 ---- a/etmem/test/project/CMakeLists.txt -+++ /dev/null -@@ -1,28 +0,0 @@ --# /****************************************************************************** --# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. --# * etmem is licensed under the Mulan PSL v2. --# * You can use this software according to the terms and conditions of the Mulan PSL v2. --# * You may obtain a copy of Mulan PSL v2 at: --# * http://license.coscl.org.cn/MulanPSL2 --# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR --# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR --# * PURPOSE. --# * See the Mulan PSL v2 for more details. --# * Author: liubo --# * Create: 2021-11-29 --# * Description: CMakefileList for etmem_project_ops_llt to compile --# ******************************************************************************/ -- --project(etmem) -- --INCLUDE_DIRECTORIES(../../inc/etmem_inc) --INCLUDE_DIRECTORIES(../../inc/etmemd_inc) --INCLUDE_DIRECTORIES(../common) --INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -- --SET(EXE etmem_project_ops_llt) -- --add_executable(${EXE} --etmem_project_ops_llt.c) -- --target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so ${BUILD_DIR}/lib/libtest.so pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/project/etmem_project_ops_llt.c b/etmem/test/project/etmem_project_ops_llt.c -deleted file mode 100644 -index edd2330..0000000 ---- a/etmem/test/project/etmem_project_ops_llt.c -+++ /dev/null -@@ -1,468 +0,0 @@ --/****************************************************************************** -- * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -- * etmem is licensed under the Mulan PSL v2. -- * You can use this software according to the terms and conditions of the Mulan PSL v2. -- * You may obtain a copy of Mulan PSL v2 at: -- * http://license.coscl.org.cn/MulanPSL2 -- * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -- * PURPOSE. -- * See the Mulan PSL v2 for more details. -- * Author: liubo -- * Create: 2021-11-29 -- * Description: This is a source file of the unit test for project-related commands in etmem. -- ******************************************************************************/ -- --#include --#include --#include --#include --#include --#include --#include --#include -- --#include "etmemd_project.h" --#include "etmemd_file.h" --#include "etmemd_common.h" --#include "securec.h" -- --#include "test_common.h" -- --#include --#include --#include -- --#define PROJECT_ADD_TEST_MAX_NUM 50 -- --static struct proj_test_param g_proj_test_param; -- --static void etmem_pro_add_name(void) --{ -- const char *project_name_long = "project name cannot longer than 32 ppmpppppppppppppppppppppppppppppppppppppppppppppp"; -- GKeyFile *config = NULL; -- struct proj_test_param param; -- -- init_proj_param(¶m); -- -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_PRO_EXISTED); -- destroy_proj_config(config); -- -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- param.proj_name = ""; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -- destroy_proj_config(config); -- -- param.proj_name = project_name_long; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -- destroy_proj_config(config); -- -- param.proj_name = DEFAULT_PROJ; --} -- --static void etmem_pro_add_interval(void) --{ -- struct proj_test_param param; -- GKeyFile *config = NULL; -- -- init_proj_param(¶m); -- -- param.interval = "0"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -- destroy_proj_config(config); -- -- param.interval = "1"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- param.interval = "2"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- param.interval = "1199"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- param.interval = "1200"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- param.interval = "1201"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -- destroy_proj_config(config); -- -- param.interval = "abc"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -- destroy_proj_config(config); --} -- --static void etmem_pro_add_loop(void) --{ -- struct proj_test_param param; -- GKeyFile *config = NULL; -- -- init_proj_param(¶m); -- -- param.loop = "0"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -- destroy_proj_config(config); -- -- param.loop = "1"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- param.loop = "2"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- param.loop = "119"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- param.loop = "120"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- param.loop = "121"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -- destroy_proj_config(config); -- -- param.loop = "abc"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -- destroy_proj_config(config); --} -- --static void etmem_pro_add_sleep(void) --{ -- struct proj_test_param param; -- GKeyFile *config = NULL; -- -- init_proj_param(¶m); -- -- param.sleep = "0"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -- destroy_proj_config(config); -- -- param.sleep = "1"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- param.sleep = "2"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- param.sleep = "1199"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- param.sleep = "1200"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- param.sleep = "1201"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -- destroy_proj_config(config); -- -- param.sleep = "wrong sleep type"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -- destroy_proj_config(config); --} -- --static void etmem_pro_lack_loop(void) --{ -- struct proj_test_param param; -- GKeyFile *config = NULL; -- -- init_proj_param(¶m); -- -- param.loop = NULL; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -- destroy_proj_config(config); --} -- --void test_etmem_prj_add_error(void) --{ -- etmem_pro_add_name(); -- etmem_pro_add_interval(); -- etmem_pro_add_loop(); -- etmem_pro_add_sleep(); -- etmem_pro_lack_loop(); --} -- --void test_etmem_prj_del_error(void) --{ -- struct proj_test_param param; -- GKeyFile *config = NULL; -- -- init_proj_param(¶m); -- -- param.proj_name = ""; -- config = construct_proj_config(¶m); -- CU_ASSERT_NOT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- param.proj_name = "noexist"; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_PRO_NOEXIST); -- destroy_proj_config(config); --} -- --static void add_project_once(void) --{ -- struct proj_test_param param; -- GKeyFile *config = NULL; -- -- init_proj_param(¶m); -- -- CU_ASSERT_EQUAL(etmemd_project_show(NULL, 0), OPT_PRO_NOEXIST); -- -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- CU_ASSERT_EQUAL(etmemd_project_show(NULL, 0), OPT_SUCCESS); -- -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- -- CU_ASSERT_EQUAL(etmemd_project_show("noexist", 0), OPT_PRO_NOEXIST); --} -- --static int add_project_multiple(int proj_add_num) --{ -- char project_name_str[PROJECT_NAME_MAX_LEN] = {0}; -- unsigned int project_num; -- struct proj_test_param param; -- GKeyFile *config = NULL; -- -- init_proj_param(¶m); -- -- for (project_num = 0; project_num < proj_add_num; project_num++) { -- if (snprintf_s(project_name_str, PROJECT_NAME_MAX_LEN, PROJECT_NAME_MAX_LEN - 1, "project_add_del_test_num%d", -- project_num) <= 0) { -- printf("get project_name wrong.\n"); -- return -1; -- } -- param.proj_name = project_name_str; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- destroy_proj_config(config); -- } -- -- CU_ASSERT_EQUAL(etmemd_project_show(NULL, 0), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_project_show("project_add_del_test_num5", 0), OPT_SUCCESS); -- -- for (project_num = 0; project_num < proj_add_num; project_num++) { -- if (snprintf_s(project_name_str, PROJECT_NAME_MAX_LEN, PROJECT_NAME_MAX_LEN - 1, "project_add_del_test_num%d", -- project_num) <= 0) { -- printf("get project_name wrong.\n"); -- return -1; -- } -- param.proj_name = project_name_str; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- } -- -- return 0; --} -- --void test_etmem_project_add_ok(void) --{ -- add_project_once(); -- CU_ASSERT_EQUAL(add_project_multiple(PROJECT_ADD_TEST_MAX_NUM), 0); --} -- --void test_etmem_mig_start_error(void) --{ -- struct proj_test_param param; -- -- init_proj_param(¶m); -- -- CU_ASSERT_EQUAL(etmemd_migrate_start(NULL), OPT_INVAL); -- CU_ASSERT_EQUAL(etmemd_migrate_start(""), OPT_PRO_NOEXIST); -- CU_ASSERT_EQUAL(etmemd_migrate_start("etmem"), OPT_PRO_NOEXIST); -- CU_ASSERT_EQUAL(etmemd_migrate_start("me^$%*mig"), OPT_PRO_NOEXIST); -- -- param.proj_name = "add_for_migrate_test"; -- do_add_proj_test(¶m); -- -- CU_ASSERT_EQUAL(etmemd_migrate_start("add_for_migrate_test"), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_migrate_start("add_for_migrate_test"), OPT_PRO_STARTED); -- -- etmemd_stop_all_projects(); --} -- --void test_etmem_mig_stop_error(void) --{ -- struct proj_test_param param; -- -- init_proj_param(¶m); -- -- CU_ASSERT_EQUAL(etmemd_migrate_stop(NULL), OPT_INVAL); -- CU_ASSERT_EQUAL(etmemd_migrate_stop(""), OPT_PRO_NOEXIST); -- CU_ASSERT_EQUAL(etmemd_migrate_stop("ETMEM"), OPT_PRO_NOEXIST); -- CU_ASSERT_EQUAL(etmemd_migrate_stop("ET^$%*MEM"), OPT_PRO_NOEXIST); -- -- param.proj_name = "add_for_migrate_stop_test"; -- do_add_proj_test(¶m); -- -- CU_ASSERT_EQUAL(etmemd_migrate_start("add_for_migrate_stop_test"), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_migrate_stop("add_for_migrate_stop_test"), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_migrate_stop("add_for_migrate_stop_test"), OPT_PRO_STOPPED); -- -- etmemd_stop_all_projects(); --} -- --static int start_project_multiple(int proj_add_num) --{ -- char project_name_str[PROJECT_NAME_MAX_LEN] = {0}; -- unsigned int project_num; -- struct proj_test_param param; -- GKeyFile *config = NULL; -- -- init_proj_param(¶m); -- -- for (project_num = 0; project_num < proj_add_num; project_num++) { -- if (snprintf_s(project_name_str, PROJECT_NAME_MAX_LEN, PROJECT_NAME_MAX_LEN - 1, "project_add_del_test_num%d", -- project_num) <= 0) { -- printf("get project_name wrong.\n"); -- return -1; -- } -- param.proj_name = project_name_str; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -- destroy_proj_config(config); -- CU_ASSERT_EQUAL(etmemd_migrate_start(project_name_str), OPT_SUCCESS); -- } -- -- for (project_num = 0; project_num < proj_add_num; project_num++) { -- if (snprintf_s(project_name_str, PROJECT_NAME_MAX_LEN, PROJECT_NAME_MAX_LEN - 1, "project_add_del_test_num%d", -- project_num) <= 0) { -- printf("get project_name wrong.\n"); -- return -1; -- } -- param.proj_name = project_name_str; -- config = construct_proj_config(¶m); -- CU_ASSERT_EQUAL(etmemd_migrate_stop(project_name_str), OPT_SUCCESS); -- CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -- destroy_proj_config(config); -- } -- -- return 0; --} -- --void test_etmem_mig_start_ok(void) --{ -- CU_ASSERT_EQUAL(start_project_multiple(1), 0); -- CU_ASSERT_EQUAL(start_project_multiple(PROJECT_ADD_TEST_MAX_NUM), 0); --} -- --typedef enum { -- CUNIT_SCREEN = 0, -- CUNIT_XMLFILE, -- CUNIT_CONSOLE --} cu_run_mode; -- --int main(int argc, const char **argv) --{ -- CU_pSuite suite; -- CU_pTest pTest; -- unsigned int num_failures; -- cu_run_mode cunit_mode = CUNIT_SCREEN; -- int error_num; -- -- if (argc > 1) { -- cunit_mode = atoi(argv[1]); -- } -- -- if (CU_initialize_registry() != CUE_SUCCESS) { -- return -CU_get_error(); -- } -- -- suite = CU_add_suite("etmem_project_ops", NULL, NULL); -- if (suite == NULL) { -- goto ERROR; -- } -- -- if (CU_ADD_TEST(suite, test_etmem_prj_add_error) == NULL || -- CU_ADD_TEST(suite, test_etmem_prj_del_error) == NULL || -- CU_ADD_TEST(suite, test_etmem_project_add_ok) == NULL || -- CU_ADD_TEST(suite, test_etmem_mig_start_error) == NULL || -- CU_ADD_TEST(suite, test_etmem_mig_stop_error) == NULL || -- CU_ADD_TEST(suite, test_etmem_mig_start_ok) == NULL) { -- printf("CU_ADD_TEST fail. \n"); -- goto ERROR; -- } -- -- switch (cunit_mode) { -- case CUNIT_SCREEN: -- CU_basic_set_mode(CU_BRM_VERBOSE); -- CU_basic_run_tests(); -- break; -- case CUNIT_XMLFILE: -- CU_set_output_filename("etmemd_project.c"); -- CU_automated_run_tests(); -- break; -- case CUNIT_CONSOLE: -- CU_console_run_tests(); -- break; -- default: -- printf("not support cunit mode, only support: 0 or 1\n"); -- goto ERROR; -- } -- -- num_failures = CU_get_number_of_failures(); -- CU_cleanup_registry(); -- return num_failures; -- --ERROR: -- error_num = CU_get_error(); -- CU_cleanup_registry(); -- return -error_num; --} --- -1.8.3.1 - diff --git a/0059-add-code-of-testcase-for-etmem-log-ops.patch b/0059-add-code-of-testcase-for-etmem-log-ops.patch deleted file mode 100644 index 5ec7342..0000000 --- a/0059-add-code-of-testcase-for-etmem-log-ops.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 531e313796c9bddc1571f78e858c5bc431b65068 Mon Sep 17 00:00:00 2001 -From: liubo -Date: Tue, 14 Dec 2021 11:09:51 +0800 -Subject: [PATCH 08/33] add code of testcase for etmem log ops - ---- - .../test/etmem_common_func_llt_test/CMakeLists.txt | 3 +- - .../etmem_common_func_llt.c | 3 +- - etmem/test/etmem_log_ops_llt_test/CMakeLists.txt | 26 +++++ - .../etmem_log_ops_llt_test/etmem_log_ops_llt.c | 112 +++++++++++++++++++++ - .../test/etmem_project_ops_llt_test/CMakeLists.txt | 3 +- - .../etmem_project_ops_llt.c | 3 +- - etmem/test/etmem_scan_ops_llt_test/CMakeLists.txt | 4 +- - .../etmem_scan_ops_llt_test/etmem_scan_ops_llt.c | 3 +- - 8 files changed, 147 insertions(+), 10 deletions(-) - create mode 100644 etmem/test/etmem_log_ops_llt_test/CMakeLists.txt - create mode 100644 etmem/test/etmem_log_ops_llt_test/etmem_log_ops_llt.c - -diff --git a/etmem/test/etmem_common_func_llt_test/CMakeLists.txt b/etmem/test/etmem_common_func_llt_test/CMakeLists.txt -index be3b365..205d460 100644 ---- a/etmem/test/etmem_common_func_llt_test/CMakeLists.txt -+++ b/etmem/test/etmem_common_func_llt_test/CMakeLists.txt -@@ -21,7 +21,6 @@ INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) - - SET(EXE etmem_common_func_llt) - --add_executable(${EXE} --etmem_common_func_llt.c) -+add_executable(${EXE} etmem_common_func_llt.c) - - target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_common_func_llt_test/etmem_common_func_llt.c b/etmem/test/etmem_common_func_llt_test/etmem_common_func_llt.c -index 2bb5b11..f195d4d 100644 ---- a/etmem/test/etmem_common_func_llt_test/etmem_common_func_llt.c -+++ b/etmem/test/etmem_common_func_llt_test/etmem_common_func_llt.c -@@ -300,7 +300,8 @@ int main(int argc, const char **argv) - CU_console_run_tests(); - break; - default: -- printf("not support cunit mode, only support: 0 or 1\n"); -+ printf("not support cunit mode, only support: " -+ "0 for CUNIT_SCREEN, 1 for CUNIT_XMLFILE, 2 for CUNIT_CONSOLE\n"); - goto ERROR; - } - -diff --git a/etmem/test/etmem_log_ops_llt_test/CMakeLists.txt b/etmem/test/etmem_log_ops_llt_test/CMakeLists.txt -new file mode 100644 -index 0000000..322fe0f ---- /dev/null -+++ b/etmem/test/etmem_log_ops_llt_test/CMakeLists.txt -@@ -0,0 +1,26 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: liubo -+# * Create: 2021-12-10 -+# * Description: CMakefileList for etmem_log_ops_llt to compile -+# ******************************************************************************/ -+ -+project(etmem) -+ -+INCLUDE_DIRECTORIES(../../inc/etmem_inc) -+INCLUDE_DIRECTORIES(../../inc/etmemd_inc) -+INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -+ -+SET(EXE etmem_log_ops_llt) -+ -+add_executable(${EXE} etmem_log_ops_llt.c) -+ -+target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_log_ops_llt_test/etmem_log_ops_llt.c b/etmem/test/etmem_log_ops_llt_test/etmem_log_ops_llt.c -new file mode 100644 -index 0000000..e9a7402 ---- /dev/null -+++ b/etmem/test/etmem_log_ops_llt_test/etmem_log_ops_llt.c -@@ -0,0 +1,112 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liubo -+ * Create: 2021-12-10 -+ * Description: This is a source file of the unit test for log functions in etmem. -+ ******************************************************************************/ -+ -+#include -+#include -+#include -+#include -+ -+#include "etmemd_log.h" -+ -+#include -+#include -+#include -+ -+#define ETMEMD_LOG_WRONG (-1) -+ -+static void test_basic_log_level(void) -+{ -+ CU_ASSERT_EQUAL(etmemd_init_log_level(ETMEMD_LOG_WRONG), -1); -+ CU_ASSERT_EQUAL(etmemd_init_log_level(ETMEMD_LOG_DEBUG), 0); -+ CU_ASSERT_EQUAL(etmemd_init_log_level(ETMEMD_LOG_INFO), 0); -+ CU_ASSERT_EQUAL(etmemd_init_log_level(ETMEMD_LOG_WARN), 0); -+ CU_ASSERT_EQUAL(etmemd_init_log_level(ETMEMD_LOG_ERR), 0); -+ CU_ASSERT_EQUAL(etmemd_init_log_level(ETMEMD_LOG_INVAL), -1); -+} -+ -+static void test_etmem_log_print(void) -+{ -+ CU_ASSERT_EQUAL(etmemd_init_log_level(ETMEMD_LOG_DEBUG), 0); -+ etmemd_log(ETMEMD_LOG_DEBUG, "test_etmem_log_debug_level\n"); -+ CU_ASSERT_EQUAL(etmemd_init_log_level(ETMEMD_LOG_INFO), 0); -+ etmemd_log(ETMEMD_LOG_INFO, "test_etmem_log_info_level\n"); -+ CU_ASSERT_EQUAL(etmemd_init_log_level(ETMEMD_LOG_WARN), 0); -+ etmemd_log(ETMEMD_LOG_WARN, "test_etmem_log_warn_level\n"); -+ CU_ASSERT_EQUAL(etmemd_init_log_level(ETMEMD_LOG_ERR), 0); -+ etmemd_log(ETMEMD_LOG_ERR, "test_etmem_log_error_level\n"); -+ CU_ASSERT_EQUAL(etmemd_init_log_level(ETMEMD_LOG_INVAL), -1); -+ etmemd_log(ETMEMD_LOG_INVAL, "test_etmem_log_interval_level\n"); -+} -+ -+typedef enum { -+ CUNIT_SCREEN = 0, -+ CUNIT_XMLFILE, -+ CUNIT_CONSOLE -+} cu_run_mode; -+ -+int main(int argc, const char **argv) -+{ -+ CU_pSuite suite; -+ CU_pTest pTest; -+ unsigned int num_failures; -+ cu_run_mode cunit_mode = CUNIT_SCREEN; -+ int error_num; -+ -+ if (argc > 1) { -+ cunit_mode = atoi(argv[1]); -+ } -+ -+ if (CU_initialize_registry() != CUE_SUCCESS) { -+ return -CU_get_error(); -+ } -+ -+ suite = CU_add_suite("etmem_log_ops", NULL, NULL); -+ if (suite == NULL) { -+ goto ERROR; -+ } -+ -+ if (CU_ADD_TEST(suite, test_basic_log_level) == NULL || -+ CU_ADD_TEST(suite, test_etmem_log_print) == NULL) { -+ printf("CU_ADD_TEST fail. \n"); -+ goto ERROR; -+ } -+ -+ switch (cunit_mode) { -+ case CUNIT_SCREEN: -+ CU_basic_set_mode(CU_BRM_VERBOSE); -+ CU_basic_run_tests(); -+ break; -+ case CUNIT_XMLFILE: -+ CU_set_output_filename("etmemd_log.c"); -+ CU_automated_run_tests(); -+ break; -+ case CUNIT_CONSOLE: -+ CU_console_run_tests(); -+ break; -+ default: -+ printf("not support cunit mode, only support: " -+ "0 for CUNIT_SCREEN, 1 for CUNIT_XMLFILE, 2 for CUNIT_CONSOLE\n"); -+ goto ERROR; -+ } -+ -+ num_failures = CU_get_number_of_failures(); -+ CU_cleanup_registry(); -+ return num_failures; -+ -+ERROR: -+ error_num = CU_get_error(); -+ CU_cleanup_registry(); -+ return -error_num; -+} -diff --git a/etmem/test/etmem_project_ops_llt_test/CMakeLists.txt b/etmem/test/etmem_project_ops_llt_test/CMakeLists.txt -index 70cd530..ff3f310 100644 ---- a/etmem/test/etmem_project_ops_llt_test/CMakeLists.txt -+++ b/etmem/test/etmem_project_ops_llt_test/CMakeLists.txt -@@ -22,7 +22,6 @@ INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) - - SET(EXE etmem_project_ops_llt) - --add_executable(${EXE} --etmem_project_ops_llt.c) -+add_executable(${EXE} etmem_project_ops_llt.c) - - target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so ${BUILD_DIR}/lib/libtest.so pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_project_ops_llt_test/etmem_project_ops_llt.c b/etmem/test/etmem_project_ops_llt_test/etmem_project_ops_llt.c -index edd2330..a01e8e8 100644 ---- a/etmem/test/etmem_project_ops_llt_test/etmem_project_ops_llt.c -+++ b/etmem/test/etmem_project_ops_llt_test/etmem_project_ops_llt.c -@@ -453,7 +453,8 @@ int main(int argc, const char **argv) - CU_console_run_tests(); - break; - default: -- printf("not support cunit mode, only support: 0 or 1\n"); -+ printf("not support cunit mode, only support: " -+ "0 for CUNIT_SCREEN, 1 for CUNIT_XMLFILE, 2 for CUNIT_CONSOLE\n"); - goto ERROR; - } - -diff --git a/etmem/test/etmem_scan_ops_llt_test/CMakeLists.txt b/etmem/test/etmem_scan_ops_llt_test/CMakeLists.txt -index c6ff96c..b5378b8 100644 ---- a/etmem/test/etmem_scan_ops_llt_test/CMakeLists.txt -+++ b/etmem/test/etmem_scan_ops_llt_test/CMakeLists.txt -@@ -21,8 +21,6 @@ INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) - - SET(EXE etmem_scan_ops_llt) - --add_executable(etmem_scan_ops_llt -- etmem_scan_ops_llt.c -- ) -+add_executable(${EXE} etmem_scan_ops_llt.c) - - target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so pthread dl rt libboundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_scan_ops_llt_test/etmem_scan_ops_llt.c b/etmem/test/etmem_scan_ops_llt_test/etmem_scan_ops_llt.c -index 1856072..0cd2ecc 100644 ---- a/etmem/test/etmem_scan_ops_llt_test/etmem_scan_ops_llt.c -+++ b/etmem/test/etmem_scan_ops_llt_test/etmem_scan_ops_llt.c -@@ -368,7 +368,8 @@ int main(int argc, const char **argv) - CU_console_run_tests(); - break; - default: -- printf("not support cunit mode, only support: 0 or 1\n"); -+ printf("not support cunit mode, only support: " -+ "0 for CUNIT_SCREEN, 1 for CUNIT_XMLFILE, 2 for CUNIT_CONSOLE\n"); - goto ERROR; - } - --- -1.8.3.1 - diff --git a/0060-add-make-install-support-to-CMakeList.patch b/0060-add-make-install-support-to-CMakeList.patch deleted file mode 100644 index 220a010..0000000 --- a/0060-add-make-install-support-to-CMakeList.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 31731fdc3fbd8afd8daeba2138344568cbd6a238 Mon Sep 17 00:00:00 2001 -From: liubo -Date: Tue, 21 Dec 2021 21:16:52 +0800 -Subject: [PATCH 10/33] add make install support to CMakeList - ---- - etmem/CMakeLists.txt | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/etmem/CMakeLists.txt b/etmem/CMakeLists.txt -index b5eb83e..9fba791 100644 ---- a/etmem/CMakeLists.txt -+++ b/etmem/CMakeLists.txt -@@ -123,3 +123,12 @@ if( ${ARCHITECTURE} STREQUAL "aarch64" ) - else() - target_compile_options(etmemd_scan PRIVATE -march=core-avx-i -m64) - endif() -+ -+install(TARGETS etmem etmemd -+ PERMISSIONS OWNER_READ OWNER_EXECUTE -+ RUNTIME DESTINATION /usr/bin) -+ -+install(DIRECTORY ${PROJECT_SOURCE_DIR}/conf/ -+ DIRECTORY_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE -+ FILE_PERMISSIONS OWNER_READ OWNER_WRITE -+ DESTINATION /etc/etmem) --- -1.8.3.1 - diff --git a/0061-add-region-scan.patch b/0061-add-region-scan.patch deleted file mode 100644 index a2626f5..0000000 --- a/0061-add-region-scan.patch +++ /dev/null @@ -1,1315 +0,0 @@ -From caeab903170cd7745b9c8ab3c5ebbc4fd9d8b30d Mon Sep 17 00:00:00 2001 -From: geruijun -Date: Thu, 28 Oct 2021 15:45:40 +0800 -Subject: [PATCH 11/33] add region scan - -Signed-off-by: geruijun ---- - etmem/CMakeLists.txt | 3 +- - etmem/conf/cslide_conf.yaml | 1 + - etmem/conf/damon_conf.yaml | 26 ++ - etmem/conf/slide_conf.yaml | 1 + - etmem/conf/thirdparty_conf.yaml | 1 + - etmem/inc/etmemd_inc/etmemd_damon.h | 25 ++ - etmem/inc/etmemd_inc/etmemd_engine.h | 1 + - etmem/inc/etmemd_inc/etmemd_file.h | 10 + - etmem/inc/etmemd_inc/etmemd_project_exp.h | 24 +- - etmem/src/etmem_src/etmem_obj.c | 2 +- - etmem/src/etmemd_src/etmemd_common.c | 5 +- - etmem/src/etmemd_src/etmemd_cslide.c | 9 +- - etmem/src/etmemd_src/etmemd_damon.c | 573 +++++++++++++++++++++++++++++ - etmem/src/etmemd_src/etmemd_engine.c | 2 + - etmem/src/etmemd_src/etmemd_file.c | 2 +- - etmem/src/etmemd_src/etmemd_pool_adapter.c | 4 +- - etmem/src/etmemd_src/etmemd_project.c | 207 ++++++++++- - etmem/src/etmemd_src/etmemd_scan.c | 11 +- - etmem/src/etmemd_src/etmemd_slide.c | 6 +- - 19 files changed, 879 insertions(+), 34 deletions(-) - create mode 100644 etmem/conf/damon_conf.yaml - create mode 100644 etmem/inc/etmemd_inc/etmemd_damon.h - create mode 100644 etmem/src/etmemd_src/etmemd_damon.c - -diff --git a/etmem/CMakeLists.txt b/etmem/CMakeLists.txt -index b5eb83e..e067fe5 100644 ---- a/etmem/CMakeLists.txt -+++ b/etmem/CMakeLists.txt -@@ -40,7 +40,8 @@ set(ETMEMD_SRC - ${ETMEMD_SRC_DIR}/etmemd_threadpool.c - ${ETMEMD_SRC_DIR}/etmemd_threadtimer.c - ${ETMEMD_SRC_DIR}/etmemd_pool_adapter.c -- ${ETMEMD_SRC_DIR}/etmemd_migrate.c) -+ ${ETMEMD_SRC_DIR}/etmemd_migrate.c -+ ${ETMEMD_SRC_DIR}/etmemd_damon.c) - - set(ETMEM_SRC - ${ETMEM_SRC_DIR}/etmem.c -diff --git a/etmem/conf/cslide_conf.yaml b/etmem/conf/cslide_conf.yaml -index 6b6ecc3..6455065 100644 ---- a/etmem/conf/cslide_conf.yaml -+++ b/etmem/conf/cslide_conf.yaml -@@ -1,5 +1,6 @@ - [project] - name=test -+scan_type=page - loop=1 - interval=1 - sleep=1 -diff --git a/etmem/conf/damon_conf.yaml b/etmem/conf/damon_conf.yaml -new file mode 100644 -index 0000000..1a53a46 ---- /dev/null -+++ b/etmem/conf/damon_conf.yaml -@@ -0,0 +1,26 @@ -+[project] -+name=test -+scan_type=region -+sample_interval=5000 -+aggr_interval=100000 -+update_interval=1000000 -+min_nr_regions=10 -+max_nr_regions=1000 -+ -+[engine] -+name=damon -+project=test -+min_size=0 -+max_size=4294967295 -+min_acc=0 -+max_acc=2 -+min_age=0 -+max_age=4294967295 -+action=pageout -+ -+[task] -+project=test -+engine=damon -+name=background_damon -+type=name -+value=mysqld -diff --git a/etmem/conf/slide_conf.yaml b/etmem/conf/slide_conf.yaml -index b99ab50..75f0220 100644 ---- a/etmem/conf/slide_conf.yaml -+++ b/etmem/conf/slide_conf.yaml -@@ -1,5 +1,6 @@ - [project] - name=test -+scan_type=page - loop=1 - interval=1 - sleep=1 -diff --git a/etmem/conf/thirdparty_conf.yaml b/etmem/conf/thirdparty_conf.yaml -index 1e1e9ac..c488ed2 100644 ---- a/etmem/conf/thirdparty_conf.yaml -+++ b/etmem/conf/thirdparty_conf.yaml -@@ -1,5 +1,6 @@ - [project] - name=test -+scan_type=page - loop=1 - interval=1 - sleep=1 -diff --git a/etmem/inc/etmemd_inc/etmemd_damon.h b/etmem/inc/etmemd_inc/etmemd_damon.h -new file mode 100644 -index 0000000..cc9c36f ---- /dev/null -+++ b/etmem/inc/etmemd_inc/etmemd_damon.h -@@ -0,0 +1,25 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: geruijun -+ * Create: 2021-10-28 -+ * Description: This is a header file of damon engine. -+ ******************************************************************************/ -+ -+#ifndef ETMEMD_DAMON_H -+#define ETMEMD_DAMON_H -+ -+#include "etmemd_project.h" -+ -+int etmemd_start_damon(struct project *proj); -+int etmemd_stop_damon(void); -+int fill_engine_type_damon(struct engine *eng, GKeyFile *config); -+ -+#endif -diff --git a/etmem/inc/etmemd_inc/etmemd_engine.h b/etmem/inc/etmemd_inc/etmemd_engine.h -index 9a50e10..7750c8b 100644 ---- a/etmem/inc/etmemd_inc/etmemd_engine.h -+++ b/etmem/inc/etmemd_inc/etmemd_engine.h -@@ -25,6 +25,7 @@ enum eng_type { - SLIDE_ENGINE = 0, - CSLIDE_ENGINE, - MEMDCD_ENGINE, -+ DAMON_ENGINE, - DYNAMIC_FB_ENGINE, - HISTORICAL_FB_ENGINE, - THIRDPARTY_ENGINE, -diff --git a/etmem/inc/etmemd_inc/etmemd_file.h b/etmem/inc/etmemd_inc/etmemd_file.h -index 34ccaf9..de2d4ad 100644 ---- a/etmem/inc/etmemd_inc/etmemd_file.h -+++ b/etmem/inc/etmemd_inc/etmemd_file.h -@@ -44,4 +44,14 @@ static inline int parse_to_int(void *val) - return (int)(long long)val; - } - -+static inline unsigned int parse_to_uint(void *val) -+{ -+ return (unsigned int)(long long)val; -+} -+ -+static inline unsigned long parse_to_ulong(void *val) -+{ -+ return (unsigned long)(long long)val; -+} -+ - #endif -diff --git a/etmem/inc/etmemd_inc/etmemd_project_exp.h b/etmem/inc/etmemd_inc/etmemd_project_exp.h -index bcd5108..8740f7e 100644 ---- a/etmem/inc/etmemd_inc/etmemd_project_exp.h -+++ b/etmem/inc/etmemd_inc/etmemd_project_exp.h -@@ -19,15 +19,35 @@ - #include - #include - --struct project { -- char *name; -+enum scan_type { -+ PAGE_SCAN = 0, -+ REGION_SCAN, -+}; -+ -+struct page_scan { - int interval; - int loop; - int sleep; -+}; -+ -+struct region_scan { -+ unsigned long sample_interval; -+ unsigned long aggr_interval; -+ unsigned long update_interval; -+ unsigned long min_nr_regions; -+ unsigned long max_nr_regions; -+}; -+ -+struct project { -+ char *name; -+ enum scan_type type; -+ void *scan_param; - bool start; - struct engine *engs; - - SLIST_ENTRY(project) entry; - }; - -+int scan_fill_by_conf(GKeyFile *config, struct project *proj); -+ - #endif -diff --git a/etmem/src/etmem_src/etmem_obj.c b/etmem/src/etmem_src/etmem_obj.c -index a5517ea..1a05a47 100644 ---- a/etmem/src/etmem_src/etmem_obj.c -+++ b/etmem/src/etmem_src/etmem_obj.c -@@ -57,7 +57,7 @@ static int obj_parse_cmd(struct etmem_conf *conf, struct mem_proj *proj) - } - } - -- printf("obj cmd %s is not supportted.\n", cmd); -+ printf("obj cmd %s is not supported.\n", cmd); - return -1; - } - -diff --git a/etmem/src/etmemd_src/etmemd_common.c b/etmem/src/etmemd_src/etmemd_common.c -index 4595499..ebf6232 100644 ---- a/etmem/src/etmemd_src/etmemd_common.c -+++ b/etmem/src/etmemd_src/etmemd_common.c -@@ -198,16 +198,19 @@ int get_unsigned_int_value(const char *val, unsigned int *value) - int get_unsigned_long_value(const char *val, unsigned long *value) - { - char *pos = NULL; -+ unsigned long value_tmp; - - errno = 0; -- *value = strtoul(val, &pos, DECIMAL_RADIX); -+ value_tmp = strtoul(val, &pos, DECIMAL_RADIX); - if (check_str_format(pos[0])) { - etmemd_log(ETMEMD_LOG_ERR, "invalid value, must be type of unsigned long.\n"); - return -1; - } - -+ *value = value_tmp; - return 0; - } -+ - void etmemd_safe_free(void **ptr) - { - if (ptr == NULL || *ptr == NULL) { -diff --git a/etmem/src/etmemd_src/etmemd_cslide.c b/etmem/src/etmemd_src/etmemd_cslide.c -index ad3eff8..b3d1637 100644 ---- a/etmem/src/etmemd_src/etmemd_cslide.c -+++ b/etmem/src/etmemd_src/etmemd_cslide.c -@@ -1818,7 +1818,7 @@ static int cslide_engine_do_cmd(struct engine *eng, struct task *tk, char *cmd, - - item = find_cmd_item(g_task_cmd_items, ARRAY_SIZE(g_task_cmd_items), cmd); - if (item == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "cslide cmd %s is not supportted\n", cmd); -+ etmemd_log(ETMEMD_LOG_ERR, "cslide cmd %s is not supported\n", cmd); - return -1; - } - if (tk == NULL) { -@@ -2060,6 +2060,7 @@ static struct config_item cslide_eng_config_items[] = { - static int cslide_fill_eng(GKeyFile *config, struct engine *eng) - { - struct cslide_eng_params *params = calloc(1, sizeof(struct cslide_eng_params)); -+ struct page_scan *page_scan = (struct page_scan *)eng->proj->scan_param; - - if (params == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "alloc cslide engine params fail\n"); -@@ -2071,9 +2072,9 @@ static int cslide_fill_eng(GKeyFile *config, struct engine *eng) - goto free_eng_params; - } - -- params->loop = eng->proj->loop; -- params->interval = eng->proj->interval; -- params->sleep = eng->proj->sleep; -+ params->loop = page_scan->loop; -+ params->interval = page_scan->interval; -+ params->sleep = page_scan->sleep; - if (parse_file_config(config, ENG_GROUP, cslide_eng_config_items, - ARRAY_SIZE(cslide_eng_config_items), (void *)params) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "cslide fill engine params fail\n"); -diff --git a/etmem/src/etmemd_src/etmemd_damon.c b/etmem/src/etmemd_src/etmemd_damon.c -new file mode 100644 -index 0000000..aa6d1b3 ---- /dev/null -+++ b/etmem/src/etmemd_src/etmemd_damon.c -@@ -0,0 +1,573 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: geruijun -+ * Create: 2021-10-28 -+ * Description: Add etmemd damon engine. -+ ******************************************************************************/ -+ -+#include -+#include -+#include -+ -+#include "securec.h" -+#include "etmemd_log.h" -+#include "etmemd_common.h" -+#include "etmemd_file.h" -+#include "etmemd_engine.h" -+#include "etmemd_task.h" -+#include "etmemd_task_exp.h" -+#include "etmemd_scan.h" -+#include "etmemd_damon.h" -+ -+#define KERNEL_DAMON_PATH "/sys/kernel/debug/damon/" -+#define DAMON_PARAM_TARGET_IDS "target_ids" -+#define DAMON_PARAM_ATTRS "attrs" -+#define DAMON_PARAM_SCHEMES "schemes" -+#define DAMON_PARAM_MONITOR_ON "monitor_on" -+ -+#define ON_LEN 2 -+#define OFF_LEN 3 -+#define INT_MAX_LEN 10 -+#define NUM_OF_ATTRS 5 -+#define NUM_OF_SCHEMES 7 -+ -+enum damos_action { -+ DAMOS_WILLNEED, -+ DAMOS_COLD, -+ DAMOS_PAGEOUT, -+ DAMOS_HUGEPAGE, -+ DAMOS_NOHUGEPAGE, -+ DAMOS_STAT, -+}; -+ -+struct action_item { -+ char *action_str; -+ enum damos_action action_type; -+}; -+ -+struct damon_eng_params { -+ unsigned long min_sz_region; -+ unsigned long max_sz_region; -+ unsigned int min_nr_accesses; -+ unsigned int max_nr_accesses; -+ unsigned int min_age_region; -+ unsigned int max_age_region; -+ enum damos_action action; -+}; -+ -+static bool check_damon_exist(void) -+{ -+ if (access(KERNEL_DAMON_PATH, F_OK) != 0) { -+ return false; -+ } -+ return true; -+} -+ -+static FILE *get_damon_file(const char *file) -+{ -+ char *file_name = NULL; -+ size_t file_str_size; -+ FILE *fp = NULL; -+ -+ file_str_size = strlen(KERNEL_DAMON_PATH) + strlen(file) + 1; -+ file_name = (char *)calloc(file_str_size, sizeof(char)); -+ if (file_name == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "malloc for damon file %s fail\n", file); -+ return NULL; -+ } -+ -+ if (snprintf_s(file_name, file_str_size, file_str_size - 1, "%s%s", -+ KERNEL_DAMON_PATH, file) == -1) { -+ etmemd_log(ETMEMD_LOG_ERR, "snprintf for damon file %s fail\n", file); -+ goto out; -+ } -+ -+ fp = fopen(file_name, "r+"); -+ if (fp == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "open file %s fail\n", file_name); -+ } -+ -+out: -+ free(file_name); -+ return fp; -+} -+ -+static bool is_engs_valid(struct project *proj) -+{ -+ struct engine *eng = proj->engs; -+ -+ while (eng != NULL) { -+ if (strcmp(eng->name, "damon") != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "engine type %s not supported, only support damon engine in region scan\n", -+ eng->name); -+ return false; -+ } -+ eng = eng->next; -+ } -+ -+ return true; -+} -+ -+static int get_damon_pids_val_and_num(struct task *tk, int *nr_tasks) -+{ -+ while (tk != NULL) { -+ if (etmemd_get_task_pids(tk, false) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "damon fail to get task pids\n"); -+ *nr_tasks = 0; -+ return -1; -+ } -+ (*nr_tasks)++; -+ tk = tk->next; -+ } -+ -+ return 0; -+} -+ -+static char *get_damon_pids_str(struct task *tk, const int nr_tasks) -+{ -+ char *pids = NULL; -+ size_t pids_size; -+ char tmp_pid[PID_STR_MAX_LEN + 2] = {0}; // plus 2 for space and '\0' follow pid -+ -+ pids_size = (PID_STR_MAX_LEN + 1) * nr_tasks + 1; -+ pids = (char *)calloc(pids_size, sizeof(char)); -+ if (pids == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "malloc for pids in damon fail\n"); -+ return NULL; -+ } -+ -+ while (tk != NULL) { -+ if (snprintf_s(tmp_pid, PID_STR_MAX_LEN + 2, PID_STR_MAX_LEN + 1, -+ "%u ", tk->pids->pid) == -1) { -+ etmemd_log(ETMEMD_LOG_WARN, "snprintf pid %u in damon fail\n", tk->pids->pid); -+ tk = tk->next; -+ continue; -+ } -+ -+ if (strcat_s(pids, pids_size, tmp_pid) != EOK) { -+ etmemd_log(ETMEMD_LOG_WARN, "strcat pid %s fail\n", tmp_pid); -+ } -+ tk = tk->next; -+ } -+ -+ return pids; -+} -+ -+static int set_damon_target_ids(struct project *proj) -+{ -+ FILE *fp = NULL; -+ int nr_tasks = 0; -+ struct task *tk = proj->engs->tasks; -+ char *pids_str = NULL; -+ size_t pids_len; -+ int ret = -1; -+ -+ if (!is_engs_valid(proj)) { -+ goto out; -+ } -+ -+ fp = get_damon_file(DAMON_PARAM_TARGET_IDS); -+ if (fp == NULL) { -+ goto out; -+ } -+ -+ if (get_damon_pids_val_and_num(tk, &nr_tasks) != 0) { -+ goto out_close; -+ } -+ -+ pids_str = get_damon_pids_str(tk, nr_tasks); -+ if (pids_str == NULL) { -+ goto out_close; -+ } -+ -+ pids_len = strlen(pids_str); -+ if (pids_len == 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get all task pids fail in damon\n"); -+ goto out_free; -+ } -+ -+ if (fwrite(pids_str, sizeof(char), pids_len + 1, fp) != pids_len + 1) { -+ etmemd_log(ETMEMD_LOG_ERR, "write pids to damon fail\n"); -+ goto out_free; -+ } -+ ret = 0; -+ -+out_free: -+ free(pids_str); -+out_close: -+ fclose(fp); -+out: -+ return ret; -+} -+ -+static char *get_damon_attrs_str(struct project *proj) -+{ -+ char *attrs = NULL; -+ size_t attrs_size; -+ struct region_scan *reg_scan = (struct region_scan *)proj->scan_param; -+ -+ attrs_size = (INT_MAX_LEN + 1) * NUM_OF_ATTRS; -+ attrs = (char *)calloc(attrs_size, sizeof(char)); -+ if (attrs == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "malloc for attrs in damon fail\n"); -+ return NULL; -+ } -+ -+ if (snprintf_s(attrs, attrs_size, attrs_size - 1, "%lu %lu %lu %lu %lu", -+ reg_scan->sample_interval, reg_scan->aggr_interval, -+ reg_scan->update_interval, reg_scan->min_nr_regions, -+ reg_scan->max_nr_regions) == -1) { -+ etmemd_log(ETMEMD_LOG_ERR, "snprintf for attrs fail\n"); -+ free(attrs); -+ return NULL; -+ } -+ -+ return attrs; -+} -+ -+static int set_damon_attrs(struct project *proj) -+{ -+ FILE *fp = NULL; -+ char *attrs_str = NULL; -+ size_t attrs_len; -+ int ret = -1; -+ -+ fp = get_damon_file(DAMON_PARAM_ATTRS); -+ if (fp == NULL) { -+ goto out; -+ } -+ -+ attrs_str = get_damon_attrs_str(proj); -+ if (attrs_str == NULL) { -+ goto out_close; -+ } -+ -+ attrs_len = strlen(attrs_str); -+ if (fwrite(attrs_str, sizeof(char), attrs_len + 1, fp) != attrs_len + 1) { -+ etmemd_log(ETMEMD_LOG_ERR, "write attrs to damon fail\n"); -+ goto out_free; -+ } -+ ret = 0; -+ -+out_free: -+ free(attrs_str); -+out_close: -+ fclose(fp); -+out: -+ return ret; -+} -+ -+static char *get_damon_schemes_str(struct project *proj) -+{ -+ char *schemes = NULL; -+ size_t schemes_size; -+ struct damon_eng_params *params = (struct damon_eng_params *)proj->engs->params; -+ -+ schemes_size = (INT_MAX_LEN + 1) * NUM_OF_SCHEMES; -+ schemes = (char *)calloc(schemes_size, sizeof(char)); -+ if (schemes == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "malloc for schemes in damon fail\n"); -+ return NULL; -+ } -+ -+ if (snprintf_s(schemes, schemes_size, schemes_size - 1, "%lu %lu %u %u %u %u %d", -+ params->min_sz_region, params->max_sz_region, -+ params->min_nr_accesses, params->max_nr_accesses, -+ params->min_age_region, params->max_age_region, -+ params->action) == -1) { -+ etmemd_log(ETMEMD_LOG_ERR, "snprintf for schemes fail\n"); -+ free(schemes); -+ return NULL; -+ } -+ -+ return schemes; -+} -+ -+static int set_damon_schemes(struct project *proj) -+{ -+ FILE *fp = NULL; -+ char *schemes_str = NULL; -+ size_t schemes_len; -+ int ret = -1; -+ -+ fp = get_damon_file(DAMON_PARAM_SCHEMES); -+ if (fp == NULL) { -+ goto out; -+ } -+ -+ schemes_str = get_damon_schemes_str(proj); -+ if (schemes_str == NULL) { -+ goto out_close; -+ } -+ -+ schemes_len = strlen(schemes_str); -+ if (fwrite(schemes_str, sizeof(char), schemes_len + 1, fp) != schemes_len + 1) { -+ etmemd_log(ETMEMD_LOG_ERR, "write schemes to damon fail\n"); -+ goto out_free; -+ } -+ ret = 0; -+ -+out_free: -+ free(schemes_str); -+out_close: -+ fclose(fp); -+out: -+ return ret; -+} -+ -+static char *get_damon_monitor_on_str(bool start) -+{ -+ char *switch_str = NULL; -+ size_t switch_size; -+ -+ switch_size = start ? ON_LEN + 1 : OFF_LEN + 1; -+ switch_str = (char *)calloc(switch_size, sizeof(char)); -+ if (switch_str == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "malloc for switch in damon fail\n"); -+ return NULL; -+ } -+ if (snprintf_s(switch_str, switch_size, switch_size - 1, start ? "on" : "off") == -1) { -+ etmemd_log(ETMEMD_LOG_ERR, "snprintf for switch fail\n"); -+ free(switch_str); -+ return NULL; -+ } -+ -+ return switch_str; -+} -+ -+static int set_damon_monitor_on(bool start) -+{ -+ FILE *fp = NULL; -+ int ret = -1; -+ char *switch_str = NULL; -+ size_t switch_len; -+ -+ fp = get_damon_file(DAMON_PARAM_MONITOR_ON); -+ if (fp == NULL) { -+ goto out; -+ } -+ -+ switch_str = get_damon_monitor_on_str(start); -+ if (switch_str == NULL) { -+ goto out_close; -+ } -+ -+ switch_len = strlen(switch_str); -+ if (fwrite(switch_str, sizeof(char), switch_len + 1, fp) != switch_len + 1) { -+ etmemd_log(ETMEMD_LOG_ERR, "write monitor_on to damon fail\n"); -+ goto out_free; -+ } -+ ret = 0; -+ -+out_free: -+ free(switch_str); -+out_close: -+ fclose(fp); -+out: -+ return ret; -+} -+ -+int etmemd_start_damon(struct project *proj) -+{ -+ bool start = true; -+ -+ if (proj == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "proj should not be NULL\n"); -+ return -1; -+ } -+ -+ if (!check_damon_exist()) { -+ etmemd_log(ETMEMD_LOG_ERR, "kernel damon module not exist\n"); -+ return -1; -+ } -+ -+ if (set_damon_target_ids(proj) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "set damon pids fail\n"); -+ return -1; -+ } -+ -+ if (set_damon_attrs(proj) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "set damon attrs fail\n"); -+ return -1; -+ } -+ -+ if (set_damon_schemes(proj) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "set damon schemes fail\n"); -+ return -1; -+ } -+ -+ if (set_damon_monitor_on(start) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "set damon monitor_on to on fail\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+int etmemd_stop_damon(void) -+{ -+ bool start = false; -+ -+ if (!check_damon_exist()) { -+ etmemd_log(ETMEMD_LOG_ERR, "kernel damon module not exist\n"); -+ return -1; -+ } -+ -+ if (set_damon_monitor_on(start) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "set damon monitor_on to off fail\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static int fill_min_size(void *obj, void *val) -+{ -+ struct damon_eng_params *params = (struct damon_eng_params *)obj; -+ unsigned long min_size = parse_to_ulong(val); -+ -+ params->min_sz_region = min_size; -+ return 0; -+} -+ -+static int fill_max_size(void *obj, void *val) -+{ -+ struct damon_eng_params *params = (struct damon_eng_params *)obj; -+ unsigned long max_size = parse_to_ulong(val); -+ -+ params->max_sz_region = max_size; -+ return 0; -+} -+ -+static int fill_min_acc(void *obj, void *val) -+{ -+ struct damon_eng_params *params = (struct damon_eng_params *)obj; -+ unsigned int min_acc = parse_to_uint(val); -+ -+ params->min_nr_accesses = min_acc; -+ return 0; -+} -+ -+static int fill_max_acc(void *obj, void *val) -+{ -+ struct damon_eng_params *params = (struct damon_eng_params *)obj; -+ unsigned int max_acc = parse_to_uint(val); -+ -+ params->max_nr_accesses = max_acc; -+ return 0; -+} -+ -+static int fill_min_age(void *obj, void *val) -+{ -+ struct damon_eng_params *params = (struct damon_eng_params *)obj; -+ unsigned int min_age = parse_to_uint(val); -+ -+ params->min_age_region = min_age; -+ return 0; -+} -+ -+static int fill_max_age(void *obj, void *val) -+{ -+ struct damon_eng_params *params = (struct damon_eng_params *)obj; -+ unsigned int max_age = parse_to_uint(val); -+ -+ params->max_age_region = max_age; -+ return 0; -+} -+ -+static struct action_item damon_action_items[] = { -+ {"willneed", DAMOS_WILLNEED}, -+ {"cold", DAMOS_COLD}, -+ {"pageout", DAMOS_PAGEOUT}, -+ {"hugepage", DAMOS_HUGEPAGE}, -+ {"nohugepage", DAMOS_NOHUGEPAGE}, -+ {"stat", DAMOS_STAT}, -+}; -+ -+static int fill_action(void *obj, void *val) -+{ -+ struct damon_eng_params *params = (struct damon_eng_params *)obj; -+ char *action = (char *)val; -+ unsigned int i; -+ -+ for (i = 0; i < ARRAY_SIZE(damon_action_items); i++) { -+ if (strcmp(action, damon_action_items[i].action_str) == 0) { -+ params->action = damon_action_items[i].action_type; -+ free(action); -+ return 0; -+ } -+ } -+ -+ free(action); -+ return -1; -+} -+ -+static struct config_item damon_eng_config_items[] = { -+ {"min_size", INT_VAL, fill_min_size, false}, -+ {"max_size", INT_VAL, fill_max_size, false}, -+ {"min_acc", INT_VAL, fill_min_acc, false}, -+ {"max_acc", INT_VAL, fill_max_acc, false}, -+ {"min_age", INT_VAL, fill_min_age, false}, -+ {"max_age", INT_VAL, fill_max_age, false}, -+ {"action", STR_VAL, fill_action, false}, -+}; -+ -+static int damon_fill_eng(GKeyFile *config, struct engine *eng) -+{ -+ struct damon_eng_params *params = calloc(1, sizeof(struct damon_eng_params)); -+ -+ if (params == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "alloc damon engine params fail\n"); -+ return -1; -+ } -+ -+ if (parse_file_config(config, ENG_GROUP, damon_eng_config_items, -+ ARRAY_SIZE(damon_eng_config_items), (void *)params) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "damon fill engine params fail.\n"); -+ free(params); -+ return -1; -+ } -+ -+ eng->params = (void *)params; -+ return 0; -+} -+ -+static void damon_clear_eng(struct engine *eng) -+{ -+ struct damon_eng_params *eng_params = (struct damon_eng_params *)eng->params; -+ -+ if (eng_params == NULL) { -+ return; -+ } -+ -+ free(eng_params); -+ eng->params = NULL; -+} -+ -+struct engine_ops g_damon_eng_ops = { -+ .fill_eng_params = damon_fill_eng, -+ .clear_eng_params = damon_clear_eng, -+ .fill_task_params = NULL, -+ .clear_task_params = NULL, -+ .start_task = NULL, -+ .stop_task = NULL, -+ .alloc_pid_params = NULL, -+ .free_pid_params = NULL, -+ .eng_mgt_func = NULL, -+}; -+ -+int fill_engine_type_damon(struct engine *eng, GKeyFile *config) -+{ -+ eng->ops = &g_damon_eng_ops; -+ eng->engine_type = DAMON_ENGINE; -+ eng->name = "damon"; -+ return 0; -+} -diff --git a/etmem/src/etmemd_src/etmemd_engine.c b/etmem/src/etmemd_src/etmemd_engine.c -index 6a14ecb..de17db7 100644 ---- a/etmem/src/etmemd_src/etmemd_engine.c -+++ b/etmem/src/etmemd_src/etmemd_engine.c -@@ -19,6 +19,7 @@ - #include "etmemd_slide.h" - #include "etmemd_cslide.h" - #include "etmemd_memdcd.h" -+#include "etmemd_damon.h" - #include "etmemd_thirdparty.h" - #include "etmemd_log.h" - #include "etmemd_common.h" -@@ -38,6 +39,7 @@ static struct engine_add_item g_engine_add_items[] = { - {"slide", fill_engine_type_slide}, - {"cslide", fill_engine_type_cslide}, - {"memdcd", fill_engine_type_memdcd}, -+ {"damon", fill_engine_type_damon}, - {"thirdparty", fill_engine_type_thirdparty}, - }; - -diff --git a/etmem/src/etmemd_src/etmemd_file.c b/etmem/src/etmemd_src/etmemd_file.c -index 8b478c6..b7dc27f 100644 ---- a/etmem/src/etmemd_src/etmemd_file.c -+++ b/etmem/src/etmemd_src/etmemd_file.c -@@ -31,7 +31,7 @@ static int parse_item(GKeyFile *config, char *group_name, struct config_item *it - - switch (item->type) { - case INT_VAL: -- val = (void *)(long long)g_key_file_get_integer(config, group_name, item->key, &error); -+ val = (void *)(long long)g_key_file_get_int64(config, group_name, item->key, &error); - break; - case STR_VAL: - val = (void *)g_key_file_get_string(config, group_name, item->key, &error); -diff --git a/etmem/src/etmemd_src/etmemd_pool_adapter.c b/etmem/src/etmemd_src/etmemd_pool_adapter.c -index 8c0068e..dfda3f4 100644 ---- a/etmem/src/etmemd_src/etmemd_pool_adapter.c -+++ b/etmem/src/etmemd_src/etmemd_pool_adapter.c -@@ -18,6 +18,7 @@ - #include - #include "etmemd_pool_adapter.h" - #include "etmemd_engine.h" -+#include "etmemd_scan.h" - - static void push_ctrl_workflow(struct task_pid **tk_pid, void *(*exector)(void *)) - { -@@ -77,6 +78,7 @@ static void *launch_threadtimer_executor(void *arg) - int start_threadpool_work(struct task_executor *executor) - { - struct task *tk = executor->tk; -+ struct page_scan *page_scan = (struct page_scan *)tk->eng->proj->scan_param; - - etmemd_log(ETMEMD_LOG_DEBUG, "start etmem for Task_value %s, project_name %s\n", - tk->value, tk->eng->proj->name); -@@ -89,7 +91,7 @@ int start_threadpool_work(struct task_executor *executor) - return -1; - } - -- tk->timer_inst = thread_timer_create(tk->eng->proj->interval); -+ tk->timer_inst = thread_timer_create(page_scan->interval); - if (tk->timer_inst == NULL) { - threadpool_stop_and_destroy(&tk->threadpool_inst); - etmemd_log(ETMEMD_LOG_ERR, "Timer task creation failed for project <%s> task <%s>.\n", -diff --git a/etmem/src/etmemd_src/etmemd_project.c b/etmem/src/etmemd_src/etmemd_project.c -index f7f1885..fa4293b 100644 ---- a/etmem/src/etmemd_src/etmemd_project.c -+++ b/etmem/src/etmemd_src/etmemd_project.c -@@ -25,6 +25,7 @@ - #include "securec.h" - #include "etmemd_project.h" - #include "etmemd_engine.h" -+#include "etmemd_damon.h" - #include "etmemd_common.h" - #include "etmemd_file.h" - #include "etmemd_log.h" -@@ -34,6 +35,7 @@ - #define MAX_LOOP_VALUE 120 - - #define MAX_OBJ_NAME_LEN 64 -+#define MIN_NR_MIN_VAL 3 - - static SLIST_HEAD(project_list, project) g_projects = SLIST_HEAD_INITIALIZER(g_projects); - -@@ -452,9 +454,9 @@ static int fill_project_name(void *obj, void *val) - return 0; - } - --static int fill_project_loop(void *obj, void *val) -+static int fill_page_scan_loop(void *obj, void *val) - { -- struct project *proj = (struct project *)obj; -+ struct page_scan *scan = (struct page_scan *)obj; - int loop = parse_to_int(val); - if (loop < 1 || loop > MAX_LOOP_VALUE) { - etmemd_log(ETMEMD_LOG_ERR, "invalid project loop value %d, it must be between 1 and %d.\n", -@@ -462,13 +464,13 @@ static int fill_project_loop(void *obj, void *val) - return -1; - } - -- proj->loop = loop; -+ scan->loop = loop; - return 0; - } - --static int fill_project_interval(void *obj, void *val) -+static int fill_page_scan_interval(void *obj, void *val) - { -- struct project *proj = (struct project *)obj; -+ struct page_scan *scan = (struct page_scan *)obj; - int interval = parse_to_int(val); - if (interval < 1 || interval > MAX_INTERVAL_VALUE) { - etmemd_log(ETMEMD_LOG_ERR, "invalid project interval value %d, it must be between 1 and %d.\n", -@@ -476,13 +478,13 @@ static int fill_project_interval(void *obj, void *val) - return -1; - } - -- proj->interval = interval; -+ scan->interval = interval; - return 0; - } - --static int fill_project_sleep(void *obj, void *val) -+static int fill_page_scan_sleep(void *obj, void *val) - { -- struct project *proj = (struct project *)obj; -+ struct page_scan *scan = (struct page_scan *)obj; - int sleep = parse_to_int(val); - if (sleep < 1 || sleep > MAX_SLEEP_VALUE) { - etmemd_log(ETMEMD_LOG_ERR, "invalid project sleep value %d, it must be between 1 and %d.\n", -@@ -490,15 +492,147 @@ static int fill_project_sleep(void *obj, void *val) - return -1; - } - -- proj->sleep = sleep; -+ scan->sleep = sleep; -+ return 0; -+} -+ -+struct config_item g_page_scan_config_items[] = { -+ {"loop", INT_VAL, fill_page_scan_loop, false}, -+ {"interval", INT_VAL, fill_page_scan_interval, false}, -+ {"sleep", INT_VAL, fill_page_scan_sleep, false}, -+}; -+ -+static int fill_region_scan_samp_interval(void *obj, void *val) -+{ -+ struct region_scan *scan = (struct region_scan *)obj; -+ unsigned long samp_intvl = parse_to_ulong(val); -+ -+ scan->sample_interval = samp_intvl; -+ return 0; -+} -+ -+static int fill_region_scan_aggr_interval(void *obj, void *val) -+{ -+ struct region_scan *scan = (struct region_scan *)obj; -+ unsigned long aggr_intvl = parse_to_ulong(val); -+ -+ scan->aggr_interval = aggr_intvl; -+ return 0; -+} -+ -+static int fill_region_scan_updt_interval(void *obj, void *val) -+{ -+ struct region_scan *scan = (struct region_scan *)obj; -+ unsigned long updt_intvl = parse_to_ulong(val); -+ -+ scan->update_interval = updt_intvl; -+ return 0; -+} -+ -+static int fill_region_scan_min_nr(void *obj, void *val) -+{ -+ struct region_scan *scan = (struct region_scan *)obj; -+ unsigned long min_nr = parse_to_ulong(val); -+ -+ if (min_nr < MIN_NR_MIN_VAL) { -+ etmemd_log(ETMEMD_LOG_ERR, "invalid minimum nr value %d, it should not be smaller than %d.\n", -+ min_nr, MIN_NR_MIN_VAL); -+ return -1; -+ } -+ -+ scan->min_nr_regions = min_nr; -+ return 0; -+} -+ -+static int fill_region_scan_max_nr(void *obj, void *val) -+{ -+ struct region_scan *scan = (struct region_scan *)obj; -+ unsigned long max_nr = parse_to_ulong(val); -+ -+ if (max_nr < MIN_NR_MIN_VAL) { -+ etmemd_log(ETMEMD_LOG_ERR, "invalid maximum nr value %d, it should not be smaller than %d.\n", -+ max_nr, MIN_NR_MIN_VAL); -+ return -1; -+ } -+ -+ scan->max_nr_regions = max_nr; -+ return 0; -+} -+ -+struct config_item g_region_scan_config_items[] = { -+ {"sample_interval", INT_VAL, fill_region_scan_samp_interval, false}, -+ {"aggr_interval", INT_VAL, fill_region_scan_aggr_interval, false}, -+ {"update_interval", INT_VAL, fill_region_scan_updt_interval, false}, -+ {"min_nr_regions", INT_VAL, fill_region_scan_min_nr, false}, -+ {"max_nr_regions", INT_VAL, fill_region_scan_max_nr, false}, -+}; -+ -+int scan_fill_by_conf(GKeyFile *config, struct project *proj) -+{ -+ struct region_scan *rg_scan = NULL; -+ -+ if (proj->type == PAGE_SCAN) { -+ if (parse_file_config(config, PROJ_GROUP, g_page_scan_config_items, -+ ARRAY_SIZE(g_page_scan_config_items), proj->scan_param) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "parse page scan config fail.\n"); -+ return -1; -+ } -+ } else if (proj->type == REGION_SCAN) { -+ if (parse_file_config(config, PROJ_GROUP, g_region_scan_config_items, -+ ARRAY_SIZE(g_region_scan_config_items), proj->scan_param) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "parse region scan config fail.\n"); -+ return -1; -+ } -+ rg_scan = (struct region_scan *)proj->scan_param; -+ if (rg_scan->min_nr_regions >= rg_scan->max_nr_regions) { -+ etmemd_log(ETMEMD_LOG_ERR, "min_nr_regions %d should be smaller than max_nr_regions %d.\n", -+ rg_scan->min_nr_regions, rg_scan->max_nr_regions); -+ return -1; -+ } -+ } -+ -+ return 0; -+} -+ -+static int fill_project_scan_type(void *obj, void *val) -+{ -+ struct project *proj = (struct project *)obj; -+ char *scan_type = (char *)val; -+ -+ if (strcmp(scan_type, "page") != 0 && strcmp(scan_type, "region") != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "invalid scan type %s, must be page or region\n", -+ scan_type); -+ return -1; -+ } -+ -+ if (strcmp(scan_type, "page") == 0) { -+ struct page_scan *scan = NULL; -+ -+ scan = (struct page_scan *)calloc(1, sizeof(struct page_scan)); -+ if (scan == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "malloc fail\n"); -+ return -1; -+ } -+ proj->scan_param = (void *)scan; -+ proj->type = PAGE_SCAN; -+ } else { -+ struct region_scan *scan = NULL; -+ -+ scan = (struct region_scan *)calloc(1, sizeof(struct region_scan)); -+ if (scan == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "malloc fail\n"); -+ return -1; -+ } -+ proj->scan_param = (void *)scan; -+ proj->type = REGION_SCAN; -+ } -+ - return 0; - } - - static struct config_item g_project_config_items[] = { - {"name", STR_VAL, fill_project_name, false}, -- {"loop", INT_VAL, fill_project_loop, false}, -- {"interval", INT_VAL, fill_project_interval, false}, -- {"sleep", INT_VAL, fill_project_sleep, false}, -+ {"scan_type", STR_VAL, fill_project_scan_type, false}, - }; - - static void clear_project(struct project *proj) -@@ -507,6 +641,11 @@ static void clear_project(struct project *proj) - free(proj->name); - proj->name = NULL; - } -+ -+ if (proj->scan_param != NULL) { -+ free(proj->scan_param); -+ proj->scan_param = NULL; -+ } - } - - static int project_fill_by_conf(GKeyFile *config, struct project *proj) -@@ -555,6 +694,13 @@ enum opt_result etmemd_project_add(GKeyFile *config) - proj = NULL; - return OPT_INVAL; - } -+ if (scan_fill_by_conf(config, proj) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "fill scan parameter from configuration file fail\n"); -+ clear_project(proj); -+ free(proj); -+ proj = NULL; -+ return OPT_INVAL; -+ } - - SLIST_INSERT_HEAD(&g_projects, proj, entry); - return OPT_SUCCESS; -@@ -665,9 +811,22 @@ enum opt_result etmemd_migrate_start(const char *project_name) - return OPT_PRO_STARTED; - } - -- if (start_tasks(proj) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "some task of project %s start fail\n", project_name); -- return OPT_INTER_ERR; -+ switch (proj->type) { -+ case PAGE_SCAN: -+ if (start_tasks(proj) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "some task of project %s start fail\n", project_name); -+ return OPT_INTER_ERR; -+ } -+ break; -+ case REGION_SCAN: -+ if (etmemd_start_damon(proj) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "start damon of project %s fail\n", project_name); -+ return OPT_INTER_ERR; -+ } -+ break; -+ default: -+ etmemd_log(ETMEMD_LOG_ERR, "scan type %d not support\n", proj->type); -+ return OPT_INVAL; - } - - proj->start = true; -@@ -694,9 +853,23 @@ enum opt_result etmemd_migrate_stop(const char *project_name) - proj->name); - return OPT_PRO_STOPPED; - } -- stop_tasks(proj); -- proj->start = false; - -+ switch (proj->type) { -+ case PAGE_SCAN: -+ stop_tasks(proj); -+ break; -+ case REGION_SCAN: -+ if (etmemd_stop_damon() != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "stop damon of project %s fail\n", project_name); -+ return OPT_INTER_ERR; -+ } -+ break; -+ default: -+ etmemd_log(ETMEMD_LOG_ERR, "scan type %d not support\n", proj->type); -+ return OPT_INVAL; -+ } -+ -+ proj->start = false; - return OPT_SUCCESS; - } - -diff --git a/etmem/src/etmemd_src/etmemd_scan.c b/etmem/src/etmemd_src/etmemd_scan.c -index fec6373..3ee018e 100644 ---- a/etmem/src/etmemd_src/etmemd_scan.c -+++ b/etmem/src/etmemd_src/etmemd_scan.c -@@ -761,6 +761,8 @@ struct page_refs *etmemd_do_scan(const struct task_pid *tpid, const struct task - return NULL; - } - -+ struct page_scan *page_scan = (struct page_scan *)tk->eng->proj->scan_param; -+ - if (snprintf_s(pid, PID_STR_MAX_LEN, PID_STR_MAX_LEN - 1, "%u", tpid->pid) <= 0) { - etmemd_log(ETMEMD_LOG_ERR, "snprintf pid fail %u", tpid->pid); - return NULL; -@@ -774,7 +776,7 @@ struct page_refs *etmemd_do_scan(const struct task_pid *tpid, const struct task - } - - /* loop for scanning idle_pages to get result of memory access. */ -- for (i = 0; i < tk->eng->proj->loop; i++) { -+ for (i = 0; i < page_scan->loop; i++) { - ret = get_page_refs(vmas, pid, &page_refs, NULL, 0); - if (ret != 0) { - etmemd_log(ETMEMD_LOG_ERR, "scan operation failed\n"); -@@ -783,7 +785,7 @@ struct page_refs *etmemd_do_scan(const struct task_pid *tpid, const struct task - page_refs = NULL; - break; - } -- sleep((unsigned)tk->eng->proj->sleep); -+ sleep((unsigned)page_scan->sleep); - } - - free_vmas(vmas); -@@ -841,6 +843,7 @@ void clean_page_sort_unexpected(void *arg) - struct page_sort *alloc_page_sort(const struct task_pid *tpid) - { - struct page_sort *page_sort = NULL; -+ struct page_scan *page_scan = (struct page_scan *)tpid->tk->eng->proj->scan_param; - - page_sort = (struct page_sort *)calloc(1, sizeof(struct page_sort)); - if (page_sort == NULL) { -@@ -848,9 +851,9 @@ struct page_sort *alloc_page_sort(const struct task_pid *tpid) - return NULL; - } - -- page_sort->loop = tpid->tk->eng->proj->loop; -+ page_sort->loop = page_scan->loop; - -- page_sort->page_refs_sort = (struct page_refs **)calloc((tpid->tk->eng->proj->loop + 1), sizeof(struct page_refs *)); -+ page_sort->page_refs_sort = (struct page_refs **)calloc((page_scan->loop + 1), sizeof(struct page_refs *)); - if (page_sort->page_refs_sort == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "calloc page refs sort failed.\n"); - free(page_sort); -diff --git a/etmem/src/etmemd_src/etmemd_slide.c b/etmem/src/etmemd_src/etmemd_slide.c -index 45db00a..8362224 100644 ---- a/etmem/src/etmemd_src/etmemd_slide.c -+++ b/etmem/src/etmemd_src/etmemd_slide.c -@@ -35,6 +35,7 @@ static struct memory_grade *slide_policy_interface(struct page_sort **page_sort, - struct memory_grade *memory_grade = NULL; - unsigned long need_2_swap_num; - volatile uint64_t count = 0; -+ struct page_scan *page_scan = (struct page_scan *)tpid->tk->eng->proj->scan_param; - - if (slide_params == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "cannot get params for slide\n"); -@@ -65,7 +66,7 @@ static struct memory_grade *slide_policy_interface(struct page_sort **page_sort, - if (need_2_swap_num == 0) - goto count_out; - -- for (int i = 0; i < tpid->tk->eng->proj->loop + 1; i++) { -+ for (int i = 0; i < page_scan->loop + 1; i++) { - page_refs = &((*page_sort)->page_refs_sort[i]); - - while (*page_refs != NULL) { -@@ -201,6 +202,7 @@ static struct config_item g_slide_task_config_items[] = { - static int slide_fill_task(GKeyFile *config, struct task *tk) - { - struct slide_params *params = calloc(1, sizeof(struct slide_params)); -+ struct page_scan *page_scan = (struct page_scan *)tk->eng->proj->scan_param; - - if (params == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "alloc slide param fail\n"); -@@ -213,7 +215,7 @@ static int slide_fill_task(GKeyFile *config, struct task *tk) - goto free_params; - } - -- if (params->t > tk->eng->proj->loop * WRITE_TYPE_WEIGHT) { -+ if (params->t > page_scan->loop * WRITE_TYPE_WEIGHT) { - etmemd_log(ETMEMD_LOG_ERR, "engine param T must less than loop.\n"); - goto free_params; - } --- -1.8.3.1 - diff --git a/0062-fix-etmem-build-problem.patch b/0062-fix-etmem-build-problem.patch deleted file mode 100644 index dfdd669..0000000 --- a/0062-fix-etmem-build-problem.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 37264d5a2f7fe27092b0f8d2e834a70e3108a68d Mon Sep 17 00:00:00 2001 -From: liubo -Date: Sat, 15 Jan 2022 15:01:47 +0800 -Subject: [PATCH 12/33] fix etmem build problem - ---- - etmem/src/etmemd_src/etmemd_memdcd.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/etmem/src/etmemd_src/etmemd_memdcd.c b/etmem/src/etmemd_src/etmemd_memdcd.c -index 28590e2..7e2f657 100644 ---- a/etmem/src/etmemd_src/etmemd_memdcd.c -+++ b/etmem/src/etmemd_src/etmemd_memdcd.c -@@ -243,6 +243,7 @@ static struct page_refs *memdcd_do_scan(const struct task_pid *tpid, const struc - int ret = 0; - char pid[PID_STR_MAX_LEN] = {0}; - char *us = "us"; -+ struct page_scan *page_scan = NULL; - - if(tpid == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "task pid is null\n"); -@@ -254,6 +255,8 @@ static struct page_refs *memdcd_do_scan(const struct task_pid *tpid, const struc - return NULL; - } - -+ page_scan = (struct page_scan *)tk->eng->proj->scan_param; -+ - if (snprintf_s(pid, PID_STR_MAX_LEN, PID_STR_MAX_LEN - 1, "%u", tpid->pid) <= 0) { - etmemd_log(ETMEMD_LOG_ERR, "snprintf pid fail %u", tpid->pid); - return NULL; -@@ -266,7 +269,7 @@ static struct page_refs *memdcd_do_scan(const struct task_pid *tpid, const struc - } - - /* loop for scanning idle_pages to get result of memory access. */ -- for (i = 0; i < tk->eng->proj->loop; i++) { -+ for (i = 0; i < page_scan->loop; i++) { - ret = get_page_refs(vmas, pid, &page_refs, NULL, 0); - if (ret != 0) { - etmemd_log(ETMEMD_LOG_ERR, "scan operation failed\n"); -@@ -275,7 +278,7 @@ static struct page_refs *memdcd_do_scan(const struct task_pid *tpid, const struc - page_refs = NULL; - break; - } -- sleep((unsigned)tk->eng->proj->sleep); -+ sleep((unsigned)page_scan->sleep); - } - - free_vmas(vmas); -@@ -419,4 +422,4 @@ int fill_engine_type_memdcd(struct engine *eng, GKeyFile *config) - eng->engine_type = MEMDCD_ENGINE; - eng->name = "memdcd"; - return 0; --} -\ No newline at end of file -+} --- -1.8.3.1 - diff --git a/0063-etmem-add-code-of-testcase.patch b/0063-etmem-add-code-of-testcase.patch deleted file mode 100644 index b6cda34..0000000 --- a/0063-etmem-add-code-of-testcase.patch +++ /dev/null @@ -1,864 +0,0 @@ -From 95029b0ae49082d660330042c6c2becc9133124d Mon Sep 17 00:00:00 2001 -From: liubo -Date: Thu, 3 Mar 2022 10:25:08 +0800 -Subject: [PATCH 13/33] etmem: add code of testcase - -add code of testcase for etmem scan function -add code of testcase for etmem threadpool function -add code of testcase for etmem threadtimer function - -Signed-off-by: liubo ---- - .../etmem_scan_ops_export_llt_test/CMakeLists.txt | 26 ++ - .../etmem_scan_ops_export_llt.c | 279 +++++++++++++++++++++ - .../etmem_threadpool_ops_llt_test/CMakeLists.txt | 26 ++ - .../etmem_threadpool_ops_llt.c | 260 +++++++++++++++++++ - etmem/test/etmem_timer_ops_llt_test/CMakeLists.txt | 26 ++ - .../etmem_timer_ops_llt_test/etmem_timer_ops_llt.c | 183 ++++++++++++++ - 6 files changed, 800 insertions(+) - create mode 100644 etmem/test/etmem_scan_ops_export_llt_test/CMakeLists.txt - create mode 100644 etmem/test/etmem_scan_ops_export_llt_test/etmem_scan_ops_export_llt.c - create mode 100644 etmem/test/etmem_threadpool_ops_llt_test/CMakeLists.txt - create mode 100644 etmem/test/etmem_threadpool_ops_llt_test/etmem_threadpool_ops_llt.c - create mode 100644 etmem/test/etmem_timer_ops_llt_test/CMakeLists.txt - create mode 100644 etmem/test/etmem_timer_ops_llt_test/etmem_timer_ops_llt.c - -diff --git a/etmem/test/etmem_scan_ops_export_llt_test/CMakeLists.txt b/etmem/test/etmem_scan_ops_export_llt_test/CMakeLists.txt -new file mode 100644 -index 0000000..be68154 ---- /dev/null -+++ b/etmem/test/etmem_scan_ops_export_llt_test/CMakeLists.txt -@@ -0,0 +1,26 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: shikemeng -+# * Create: 2021-11-30 -+# * Description: CMakefileList for etmem_scan_ops_llt_test -+# ******************************************************************************/ -+ -+project(etmem) -+ -+INCLUDE_DIRECTORIES(../../inc/etmem_inc) -+INCLUDE_DIRECTORIES(../../inc/etmemd_inc) -+INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -+ -+SET(EXE etmem_scan_ops_export_llt) -+ -+add_executable(${EXE} etmem_scan_ops_export_llt.c) -+ -+target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so pthread dl rt libboundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_scan_ops_export_llt_test/etmem_scan_ops_export_llt.c b/etmem/test/etmem_scan_ops_export_llt_test/etmem_scan_ops_export_llt.c -new file mode 100644 -index 0000000..e8e6098 ---- /dev/null -+++ b/etmem/test/etmem_scan_ops_export_llt_test/etmem_scan_ops_export_llt.c -@@ -0,0 +1,279 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: yangkunlin -+ * Create: 2021-11-30 -+ * Description: test for the export scan library -+ ******************************************************************************/ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "etmemd_scan_export.h" -+ -+/* normal init and exit */ -+static void test_etmem_exp_scan_001(void) -+{ -+ /* for test of exit without init*/ -+ etmemd_scan_exit(); -+ -+ CU_ASSERT_EQUAL(etmemd_scan_init(), 0); -+ etmemd_scan_exit(); -+} -+ -+static void test_etmem_exp_scan_002(void) -+{ -+ /* for test of exit without init*/ -+ etmemd_scan_exit(); -+ -+ CU_ASSERT_EQUAL(etmemd_scan_init(), 0); -+ -+ /* init again before exit */ -+ CU_ASSERT_NOT_EQUAL(etmemd_scan_init(), 0); -+ etmemd_scan_exit(); -+} -+ -+static void check_vmas(struct vmas *vmas) -+{ -+ int i; -+ struct vma *curr_vma = NULL; -+ -+ CU_ASSERT_NOT_EQUAL(vmas->vma_cnt, 0); -+ -+ curr_vma = vmas->vma_list; -+ for (i = 0; i < vmas->vma_cnt; i++) { -+ CU_ASSERT_PTR_NOT_NULL(curr_vma); -+ curr_vma = curr_vma->next; -+ } -+} -+ -+/* test invalid get_vmas */ -+static void test_etmem_exp_scan_004(void) -+{ -+ const char *pid = "1"; -+ char *vmflags_array[10] = {"rd"}; -+ int vmflag_num = 1; -+ int is_anon_only = false; -+ struct vmas *vmas = NULL; -+ -+ CU_ASSERT_EQUAL(etmemd_scan_init(), 0); -+ -+ /* non-exist pid */ -+ vmas = etmemd_get_vmas("0", vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NULL(vmas); -+ -+ /* pid is NULL */ -+ vmas = etmemd_get_vmas(NULL, vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NULL(vmas); -+ -+ /* pid contains invalid characters */ -+ vmas = etmemd_get_vmas("1-", vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NULL(vmas); -+ -+ /* vmflags contains space */ -+ vmflags_array[0] = "r "; -+ vmas = etmemd_get_vmas(pid, vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NULL(vmas); -+ -+ /* vmflags length is not 2 */ -+ vmflags_array[0] = "rd "; -+ vmas = etmemd_get_vmas(pid, vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NULL(vmas); -+ -+ /* vmflags is NULL */ -+ vmflags_array[0] = NULL; -+ vmas = etmemd_get_vmas(pid, vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NULL(vmas); -+ -+ /* test free is NULL */ -+ vmas = NULL; -+ etmemd_free_vmas(vmas); -+ -+ etmemd_scan_exit(); -+} -+ -+ -+/* test valid get_vmas */ -+static void test_etmem_exp_scan_003(void) -+{ -+ const char *pid = "1"; -+ char *vmflags_array[10] = {"rd"}; -+ int vmflag_num = 1; -+ int is_anon_only = false; -+ struct vmas *vmas = NULL; -+ struct vma *curr_vma = NULL; -+ int i; -+ -+ /* get vmas without init */ -+ vmas = etmemd_get_vmas(pid, vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NOT_NULL(vmas); -+ check_vmas(vmas); -+ etmemd_free_vmas(vmas); -+ -+ /* get vmas with init */ -+ CU_ASSERT_EQUAL(etmemd_scan_init(), 0); -+ vmas = etmemd_get_vmas(pid, vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NOT_NULL(vmas); -+ check_vmas(vmas); -+ etmemd_free_vmas(vmas); -+ etmemd_scan_exit(); -+} -+ -+/* test invalid get_page_refs */ -+static void test_etmem_exp_scan_006(void) -+{ -+ const char *pid = "1"; -+ char *vmflags_array[10] = {"rd"}; -+ int vmflag_num = 1; -+ int is_anon_only = false; -+ struct vmas *vmas = NULL; -+ struct page_refs *page_refs = NULL; -+ int flags = SCAN_AS_HUGE | SCAN_IGN_HOST; -+ -+ CU_ASSERT_EQUAL(etmemd_scan_init(), 0); -+ -+ /* free null pointer */ -+ etmemd_free_page_refs(page_refs); -+ -+ /* vmas is NULL */ -+ CU_ASSERT_EQUAL(etmemd_get_page_refs(vmas, pid, &page_refs, flags), -1); -+ -+ /* vmas address range invalid*/ -+ vmas = (struct vmas *)calloc(1, sizeof(struct vmas)); -+ CU_ASSERT_PTR_NOT_NULL(vmas); -+ vmas->vma_cnt = 1; -+ -+ struct vma *vma = (struct vma *)calloc(1, sizeof(struct vma)); -+ CU_ASSERT_PTR_NOT_NULL(vma); -+ vma->start = 0x0ff; -+ vma->end = 0x000; -+ vma->next = NULL; -+ vmas->vma_list = vma; -+ -+ CU_ASSERT_EQUAL(etmemd_get_page_refs(vmas, pid, &page_refs, flags), -1); -+ etmemd_free_vmas(vmas); -+ -+ vmas = etmemd_get_vmas(pid, vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NOT_NULL(vmas); -+ check_vmas(vmas); -+ -+ /* pid not exist */ -+ CU_ASSERT_EQUAL(etmemd_get_page_refs(vmas, "0", &page_refs, flags), -1); -+ CU_ASSERT_PTR_NULL(page_refs); -+ -+ /* pid is NULL */ -+ CU_ASSERT_EQUAL(etmemd_get_page_refs(vmas, NULL, &page_refs, flags), -1); -+ CU_ASSERT_PTR_NULL(page_refs); -+ -+ /* pid contains invalid chars */ -+ CU_ASSERT_EQUAL(etmemd_get_page_refs(vmas, "--", &page_refs, flags), -1); -+ CU_ASSERT_PTR_NULL(page_refs); -+ -+ etmemd_free_page_refs(page_refs); -+ etmemd_free_vmas(vmas); -+ etmemd_scan_exit(); -+} -+ -+/* test valid get_page_refs */ -+static void test_etmem_exp_scan_005(void) -+{ -+ CU_ASSERT_EQUAL(etmemd_scan_init(), 0); -+ -+ const char *pid = "1"; -+ char *vmflags_array[10] = {"rd"}; -+ int vmflag_num = 1; -+ int is_anon_only = false; -+ struct vmas *vmas = NULL; -+ struct page_refs *page_refs = NULL; -+ int flags = SCAN_AS_HUGE | SCAN_IGN_HOST; -+ -+ vmas = etmemd_get_vmas(pid, vmflags_array, vmflag_num, is_anon_only); -+ CU_ASSERT_PTR_NOT_NULL(vmas); -+ check_vmas(vmas); -+ -+ CU_ASSERT_EQUAL(etmemd_get_page_refs(vmas, pid, &page_refs, flags), 0); -+ CU_ASSERT_PTR_NOT_NULL(page_refs); -+ -+ etmemd_scan_exit(); -+ -+ /* get_page_refs after exit */ -+ CU_ASSERT_NOT_EQUAL(etmemd_get_page_refs(vmas, pid, &page_refs, flags), 0); -+ -+ etmemd_free_page_refs(page_refs); -+ etmemd_free_vmas(vmas); -+} -+ -+typedef enum { -+ CUNIT_SCREEN = 0, -+ CUNIT_XMLFILE, -+ CUNIT_CONSOLE -+} cu_run_mode; -+ -+int main(int argc, const char **argv) -+{ -+ CU_pSuite suite; -+ CU_pTest pTest; -+ unsigned int num_failures; -+ cu_run_mode cunit_mode = CUNIT_SCREEN; -+ int error_num; -+ -+ if (argc > 1) { -+ cunit_mode = atoi(argv[1]); -+ } -+ -+ if (CU_initialize_registry() != CUE_SUCCESS) { -+ return CU_get_error(); -+ } -+ -+ suite = CU_add_suite("etmem_scan_ops_exp", NULL, NULL); -+ if (suite == NULL) { -+ goto ERROR; -+ } -+ -+ if (CU_ADD_TEST(suite, test_etmem_exp_scan_001) == NULL || -+ CU_ADD_TEST(suite, test_etmem_exp_scan_002) == NULL || -+ CU_ADD_TEST(suite, test_etmem_exp_scan_003) == NULL || -+ CU_ADD_TEST(suite, test_etmem_exp_scan_004) == NULL || -+ CU_ADD_TEST(suite, test_etmem_exp_scan_005) == NULL || -+ CU_ADD_TEST(suite, test_etmem_exp_scan_006) == NULL) { -+ goto ERROR; -+ } -+ -+ switch (cunit_mode) { -+ case CUNIT_SCREEN: -+ CU_basic_set_mode(CU_BRM_VERBOSE); -+ CU_basic_run_tests(); -+ break; -+ case CUNIT_XMLFILE: -+ CU_set_output_filename("etmemd_scan.c"); -+ CU_automated_run_tests(); -+ break; -+ case CUNIT_CONSOLE: -+ CU_console_run_tests(); -+ break; -+ default: -+ printf("not support cunit mode, only support: " -+ "0 for CUNIT_SCREEN, 1 for CUNIT_XMLFILE, 2 for CUNIT_CONSOLE\n"); -+ goto ERROR; -+ } -+ -+ num_failures = CU_get_number_of_failures(); -+ CU_cleanup_registry(); -+ return num_failures; -+ -+ERROR: -+ error_num = CU_get_error(); -+ CU_cleanup_registry(); -+ return -error_num; -+} -diff --git a/etmem/test/etmem_threadpool_ops_llt_test/CMakeLists.txt b/etmem/test/etmem_threadpool_ops_llt_test/CMakeLists.txt -new file mode 100644 -index 0000000..cb084cf ---- /dev/null -+++ b/etmem/test/etmem_threadpool_ops_llt_test/CMakeLists.txt -@@ -0,0 +1,26 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: liubo -+# * Create: 2021-11-30 -+# * Description: CMakefileList for etmem_threadpool_ops_llt_test -+# ******************************************************************************/ -+ -+project(etmem) -+ -+INCLUDE_DIRECTORIES(../../inc/etmem_inc) -+INCLUDE_DIRECTORIES(../../inc/etmemd_inc) -+INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -+ -+SET(EXE etmem_threadpool_ops_llt) -+ -+add_executable(${EXE} etmem_threadpool_ops_llt.c) -+ -+target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so pthread dl rt libboundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_threadpool_ops_llt_test/etmem_threadpool_ops_llt.c b/etmem/test/etmem_threadpool_ops_llt_test/etmem_threadpool_ops_llt.c -new file mode 100644 -index 0000000..9917954 ---- /dev/null -+++ b/etmem/test/etmem_threadpool_ops_llt_test/etmem_threadpool_ops_llt.c -@@ -0,0 +1,260 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liubo -+ * Create: 2020-08-13 -+ * Description: test for etmem threadpool operations -+ ******************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "etmemd_threadpool.h" -+#include "etmemd_pool_adapter.h" -+#include "etmemd_project.h" -+#include "etmemd_file.h" -+#include "etmemd_common.h" -+#include "etmemd_engine.h" -+#include "etmemd_slide.h" -+#include "etmemd_cslide.h" -+#include "securec.h" -+ -+#define ADD_WORKER_NUM 100 -+typedef void *(*add_worker_exector)(void *); -+ -+static struct task_executor g_test_exec; -+static int g_task_exe_time = 0; -+static struct engine_ops g_test_eng_ops = { -+ .alloc_pid_params = NULL, -+ .free_pid_params = NULL, -+}; -+ -+static void get_threadpool_create_num(int num, int exp) -+{ -+ thread_pool *pool = NULL; -+ -+ pool = threadpool_create(num); -+ CU_ASSERT_PTR_NOT_NULL(pool); -+ -+ CU_ASSERT_EQUAL(pool->max_thread_cap, exp); -+ threadpool_stop_and_destroy(&pool); -+} -+ -+static void test_threadpool_create(void) -+{ -+ int core = get_nprocs(); -+ -+ get_threadpool_create_num(1, 1); -+ get_threadpool_create_num(2, 2); -+ get_threadpool_create_num(2 * core, 2 * core); -+ get_threadpool_create_num(2 * core + 1, 2 * core + 1); -+ -+ threadpool_notify(NULL); -+ threadpool_reset_status(NULL); -+} -+ -+static void test_threadpool_delete(void) -+{ -+ thread_pool *pool = NULL; -+ threadpool_stop_and_destroy(&pool); -+ -+ pool = threadpool_create(1); -+ CU_ASSERT_PTR_NOT_NULL(pool); -+ -+ threadpool_stop_and_destroy(&pool); -+ CU_ASSERT_PTR_NULL(pool); -+} -+ -+static void *add_worker_fun(void *str) -+{ -+ char *temp_str = str; -+ printf("str: %s \n", temp_str); -+ return NULL; -+} -+ -+static unsigned int get_workerlist_num(const thread_pool *pool) -+{ -+ unsigned int num = 0; -+ thread_worker *worker = pool->worker_list; -+ -+ while (worker) { -+ num++; -+ worker = worker->next_node; -+ } -+ -+ return num; -+} -+ -+static void test_thpool_addwk_single(void) -+{ -+ char *args = "for add worker test.\n"; -+ thread_pool *pool = NULL; -+ add_worker_exector exector = add_worker_fun; -+ -+ pool = threadpool_create(1); -+ CU_ASSERT_PTR_NOT_NULL(pool); -+ -+ CU_ASSERT_EQUAL(threadpool_add_worker(pool, NULL, NULL), -1); -+ CU_ASSERT_EQUAL(threadpool_add_worker(pool, exector, NULL), -1); -+ CU_ASSERT_EQUAL(threadpool_add_worker(pool, NULL, args), -1); -+ CU_ASSERT_EQUAL(threadpool_add_worker(pool, exector, args), 0); -+ -+ CU_ASSERT_PTR_NOT_NULL(pool->worker_list); -+ CU_ASSERT_EQUAL(get_workerlist_num(pool), 1); -+ -+ threadpool_stop_and_destroy(&pool); -+ CU_ASSERT_PTR_NULL(pool); -+} -+ -+static void test_thpool_addwk_mul(void) -+{ -+ char *args = "for add worker test.\n"; -+ thread_pool *pool = NULL; -+ int add_num; -+ add_worker_exector exector = add_worker_fun; -+ -+ pool = threadpool_create(1); -+ CU_ASSERT_PTR_NOT_NULL(pool); -+ -+ for (add_num = 0; add_num < ADD_WORKER_NUM; add_num++) { -+ CU_ASSERT_EQUAL(threadpool_add_worker(pool, exector, args), 0); -+ } -+ -+ CU_ASSERT_PTR_NOT_NULL(pool->worker_list); -+ CU_ASSERT_EQUAL(__atomic_load_n(&pool->scheduing_size, __ATOMIC_SEQ_CST), ADD_WORKER_NUM); -+ -+ threadpool_stop_and_destroy(&pool); -+ CU_ASSERT_PTR_NULL(pool); -+} -+ -+static void init_thpool_objs(struct project *proj, struct engine *eng, struct task *tk) -+{ -+ proj->interval = 1; -+ proj->start = true; -+ proj->name = "test_project"; -+ eng->proj = proj; -+ eng->ops = &g_test_eng_ops; -+ tk->eng = eng; -+ tk->type = "pid"; -+ tk->value = "1"; -+ tk->max_threads = 10; -+} -+ -+static void test_thpool_start_error(void) -+{ -+ struct task tk; -+ struct engine eng; -+ struct project proj; -+ -+ init_thpool_objs(&proj, &eng, &tk); -+ -+ tk.max_threads = 0; -+ g_test_exec.tk = &tk; -+ -+ CU_ASSERT_EQUAL(start_threadpool_work(&g_test_exec), -1); -+} -+ -+static void *task_executor(void *arg) -+{ -+ g_task_exe_time++; -+ return NULL; -+} -+ -+static void test_thpool_start_stop(void) -+{ -+ struct task tk = {0}; -+ struct engine eng = {0}; -+ struct project proj = {0}; -+ -+ init_thpool_objs(&proj, &eng, &tk); -+ -+ g_test_exec.tk = &tk; -+ g_test_exec.func = task_executor; -+ -+ CU_ASSERT_EQUAL(start_threadpool_work(&g_test_exec), 0); -+ /* wait threadpool to work */ -+ sleep(2); -+ stop_and_delete_threadpool_work(&tk); -+} -+ -+typedef enum { -+ CUNIT_SCREEN = 0, -+ CUNIT_XMLFILE, -+ CUNIT_CONSOLE -+} cu_run_mode; -+ -+int main(int argc, const char **argv) -+{ -+ CU_pSuite suite; -+ CU_pTest pTest; -+ unsigned int num_failures; -+ cu_run_mode cunit_mode = CUNIT_SCREEN; -+ int error_num; -+ -+ if (argc > 1) { -+ cunit_mode = atoi(argv[1]); -+ } -+ -+ if (CU_initialize_registry() != CUE_SUCCESS) { -+ return CU_get_error(); -+ } -+ -+ suite = CU_add_suite("etmem_threadpool_ops", NULL, NULL); -+ if (suite == NULL) { -+ goto ERROR; -+ } -+ -+ if (CU_ADD_TEST(suite, test_threadpool_create) == NULL || -+ CU_ADD_TEST(suite, test_threadpool_delete) == NULL || -+ CU_ADD_TEST(suite, test_thpool_addwk_single) == NULL || -+ CU_ADD_TEST(suite, test_thpool_addwk_mul) == NULL || -+ CU_ADD_TEST(suite, test_thpool_start_stop) == NULL || -+ CU_ADD_TEST(suite, test_thpool_start_error) == NULL) { -+ goto ERROR; -+ } -+ -+ switch (cunit_mode) { -+ case CUNIT_SCREEN: -+ CU_basic_set_mode(CU_BRM_VERBOSE); -+ CU_basic_run_tests(); -+ break; -+ case CUNIT_XMLFILE: -+ CU_set_output_filename("etmemd_threadpool.c"); -+ CU_automated_run_tests(); -+ break; -+ case CUNIT_CONSOLE: -+ CU_console_run_tests(); -+ break; -+ default: -+ printf("not support cunit mode, only support: " -+ "0 for CUNIT_SCREEN, 1 for CUNIT_XMLFILE, 2 for CUNIT_CONSOLE\n"); -+ goto ERROR; -+ } -+ -+ num_failures = CU_get_number_of_failures(); -+ CU_cleanup_registry(); -+ return num_failures; -+ -+ERROR: -+ error_num = CU_get_error(); -+ CU_cleanup_registry(); -+ return -error_num; -+} -diff --git a/etmem/test/etmem_timer_ops_llt_test/CMakeLists.txt b/etmem/test/etmem_timer_ops_llt_test/CMakeLists.txt -new file mode 100644 -index 0000000..76aa48e ---- /dev/null -+++ b/etmem/test/etmem_timer_ops_llt_test/CMakeLists.txt -@@ -0,0 +1,26 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: liubo -+# * Create: 2021-11-30 -+# * Description: CMakefileList for etmem_timer_ops_llt_test -+# ******************************************************************************/ -+ -+project(etmem) -+ -+INCLUDE_DIRECTORIES(../../inc/etmem_inc) -+INCLUDE_DIRECTORIES(../../inc/etmemd_inc) -+INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -+ -+SET(EXE etmem_timer_ops_llt) -+ -+add_executable(${EXE} etmem_timer_ops_llt.c) -+ -+target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so pthread dl rt libboundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_timer_ops_llt_test/etmem_timer_ops_llt.c b/etmem/test/etmem_timer_ops_llt_test/etmem_timer_ops_llt.c -new file mode 100644 -index 0000000..c97cdf9 ---- /dev/null -+++ b/etmem/test/etmem_timer_ops_llt_test/etmem_timer_ops_llt.c -@@ -0,0 +1,183 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liubo -+ * Create: 2020-08-13 -+ * Description: test for etmem timer operations -+ ******************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "etmemd_threadtimer.h" -+ -+static int g_timer_exec_time = 0; -+ -+typedef void *(*timer_exector)(void *); -+ -+static void get_timer_expired_time(int time, int exp) -+{ -+ timer_thread *timer = NULL; -+ -+ timer = thread_timer_create(time); -+ CU_ASSERT_PTR_NOT_NULL(timer); -+ -+ CU_ASSERT_EQUAL(timer->expired_time, exp); -+ thread_timer_destroy(&timer); -+} -+ -+static void test_timer_create_delete(void) -+{ -+ timer_thread *timer = NULL; -+ thread_timer_destroy(&timer); -+ -+ get_timer_expired_time(1, 1); -+ get_timer_expired_time(2, 2); -+ get_timer_expired_time(50, 50); -+ get_timer_expired_time(1199, 1199); -+ get_timer_expired_time(1201, 1201); -+} -+ -+static void *threadtimer_exector(void *str) -+{ -+ char *temp_str = str; -+ printf("threadtimer_exector: %s\n", temp_str); -+ g_timer_exec_time++; -+ return NULL; -+} -+ -+static void test_timer_start_error(void) -+{ -+ char *timer_args = "for timer start test.\n"; -+ timer_exector exector = threadtimer_exector; -+ timer_thread *timer = NULL; -+ -+ timer = thread_timer_create(60); -+ CU_ASSERT_PTR_NOT_NULL(timer); -+ -+ CU_ASSERT_EQUAL(thread_timer_start(NULL, NULL, NULL), -1); -+ CU_ASSERT_EQUAL(thread_timer_start(timer, NULL, NULL), -1); -+ CU_ASSERT_EQUAL(thread_timer_start(timer, exector, NULL), -1); -+ CU_ASSERT_EQUAL(thread_timer_start(timer, NULL, timer_args), -1); -+ CU_ASSERT_EQUAL(thread_timer_start(timer, exector, timer_args), 0); -+ CU_ASSERT_FALSE(timer->down); -+ CU_ASSERT_EQUAL(thread_timer_start(timer, exector, timer_args), 0); -+ -+ thread_timer_destroy(&timer); -+ thread_timer_stop(timer); -+} -+ -+static void test_timer_start_ok(void) -+{ -+ char *timer_args = "for timer start test.\n"; -+ timer_exector exector = threadtimer_exector; -+ timer_thread *timer = NULL; -+ -+ timer = thread_timer_create(1); -+ CU_ASSERT_PTR_NOT_NULL(timer); -+ -+ CU_ASSERT_EQUAL(thread_timer_start(timer, exector, timer_args), 0); -+ CU_ASSERT_FALSE(timer->down); -+ -+ sleep(2); -+ CU_ASSERT_NOT_EQUAL(g_timer_exec_time, 0); -+ -+ thread_timer_stop(timer); -+ thread_timer_destroy(&timer); -+} -+ -+static void test_timer_stop(void) -+{ -+ char *timer_args = "for timer start test.\n"; -+ timer_exector exector = threadtimer_exector; -+ timer_thread *timer = NULL; -+ -+ thread_timer_stop(timer); -+ -+ timer = thread_timer_create(60); -+ CU_ASSERT_PTR_NOT_NULL(timer); -+ -+ CU_ASSERT_EQUAL(thread_timer_start(timer, exector, timer_args), 0); -+ CU_ASSERT_FALSE(timer->down); -+ -+ thread_timer_stop(timer); -+ CU_ASSERT_TRUE(timer->down); -+ thread_timer_destroy(&timer); -+} -+ -+typedef enum { -+ CUNIT_SCREEN = 0, -+ CUNIT_XMLFILE, -+ CUNIT_CONSOLE -+} cu_run_mode; -+ -+int main(int argc, const char **argv) -+{ -+ CU_pSuite suite; -+ CU_pTest pTest; -+ unsigned int num_failures; -+ cu_run_mode cunit_mode = CUNIT_SCREEN; -+ int error_num; -+ -+ if (argc > 1) { -+ cunit_mode = atoi(argv[1]); -+ } -+ -+ if (CU_initialize_registry() != CUE_SUCCESS) { -+ return CU_get_error(); -+ } -+ -+ suite = CU_add_suite("etmem_timer_ops", NULL, NULL); -+ if (suite == NULL) { -+ goto ERROR; -+ } -+ -+ if (CU_ADD_TEST(suite, test_timer_create_delete) == NULL || -+ CU_ADD_TEST(suite, test_timer_start_error) == NULL || -+ CU_ADD_TEST(suite, test_timer_start_ok) == NULL || -+ CU_ADD_TEST(suite, test_timer_stop) == NULL) { -+ goto ERROR; -+ } -+ -+ switch (cunit_mode) { -+ case CUNIT_SCREEN: -+ CU_basic_set_mode(CU_BRM_VERBOSE); -+ CU_basic_run_tests(); -+ break; -+ case CUNIT_XMLFILE: -+ CU_set_output_filename("etmemd_threadtimer.c"); -+ CU_automated_run_tests(); -+ break; -+ case CUNIT_CONSOLE: -+ CU_console_run_tests(); -+ break; -+ default: -+ printf("not support cunit mode, only support: " -+ "0 for CUNIT_SCREEN, 1 for CUNIT_XMLFILE, 2 for CUNIT_CONSOLE\n"); -+ goto ERROR; -+ } -+ -+ num_failures = CU_get_number_of_failures(); -+ CU_cleanup_registry(); -+ return num_failures; -+ -+ERROR: -+ error_num = CU_get_error(); -+ CU_cleanup_registry(); -+ return -error_num; -+} --- -1.8.3.1 - diff --git a/0064-etmem-add-code-of-testcase.patch b/0064-etmem-add-code-of-testcase.patch deleted file mode 100644 index 4d278bb..0000000 --- a/0064-etmem-add-code-of-testcase.patch +++ /dev/null @@ -1,1202 +0,0 @@ -From 51adb91840286ce1720a43ac7d756fa7d4e6234e Mon Sep 17 00:00:00 2001 -From: liubo -Date: Mon, 24 Jan 2022 01:34:44 +0800 -Subject: [PATCH 14/33] etmem: add code of testcase - -add code of testcase for etmem slide engine functions -and add conf file for test use. - -Signed-off-by: liubo ---- - etmem/test/conf/conf_cslide/eng.config | 7 + - etmem/test/conf/conf_cslide/proj.config | 5 + - etmem/test/conf/conf_cslide/task.config | 9 + - etmem/test/conf/conf_slide/config_file | 18 + - etmem/test/etmem_slide_ops_llt_test/CMakeLists.txt | 29 + - .../etmem_slide_ops_llt_test/etmem_slide_ops_llt.c | 648 +++++++++++++++++++++ - etmem/test/etmem_slide_ops_llt_test/mem_swaptest.c | 95 +++ - .../etmem_slide_ops_llt_test/test_slide_ops.sh | 309 ++++++++++ - 8 files changed, 1120 insertions(+) - create mode 100644 etmem/test/conf/conf_cslide/eng.config - create mode 100644 etmem/test/conf/conf_cslide/proj.config - create mode 100644 etmem/test/conf/conf_cslide/task.config - create mode 100644 etmem/test/conf/conf_slide/config_file - create mode 100644 etmem/test/etmem_slide_ops_llt_test/CMakeLists.txt - create mode 100644 etmem/test/etmem_slide_ops_llt_test/etmem_slide_ops_llt.c - create mode 100644 etmem/test/etmem_slide_ops_llt_test/mem_swaptest.c - create mode 100644 etmem/test/etmem_slide_ops_llt_test/test_slide_ops.sh - -diff --git a/etmem/test/conf/conf_cslide/eng.config b/etmem/test/conf/conf_cslide/eng.config -new file mode 100644 -index 0000000..4d0665b ---- /dev/null -+++ b/etmem/test/conf/conf_cslide/eng.config -@@ -0,0 +1,7 @@ -+[engine] -+name=cslide -+project=test -+node_pair=2,0;3,1 -+hot_threshold=1 -+node_mig_quota=256 -+node_hot_reserve=119600 -\ No newline at end of file -diff --git a/etmem/test/conf/conf_cslide/proj.config b/etmem/test/conf/conf_cslide/proj.config -new file mode 100644 -index 0000000..1174df3 ---- /dev/null -+++ b/etmem/test/conf/conf_cslide/proj.config -@@ -0,0 +1,5 @@ -+[project] -+name=test -+loop=3 -+interval=1 -+sleep=1 -\ No newline at end of file -diff --git a/etmem/test/conf/conf_cslide/task.config b/etmem/test/conf/conf_cslide/task.config -new file mode 100644 -index 0000000..336be39 ---- /dev/null -+++ b/etmem/test/conf/conf_cslide/task.config -@@ -0,0 +1,9 @@ -+[task] -+project=test -+engine=cslide -+name=background1 -+type=pid -+value=1 -+vm_flags=ht -+anon_only=no -+ign_host=yes -\ No newline at end of file -diff --git a/etmem/test/conf/conf_slide/config_file b/etmem/test/conf/conf_slide/config_file -new file mode 100644 -index 0000000..5d9f965 ---- /dev/null -+++ b/etmem/test/conf/conf_slide/config_file -@@ -0,0 +1,18 @@ -+[project] -+name=test -+loop=1 -+interval=1 -+sleep=1 -+ -+[engine] -+name=slide -+project=test -+ -+[task] -+project=test -+engine=slide -+name=background1 -+type=name -+value=sshd -+max_threads=10 -+T=2 -diff --git a/etmem/test/etmem_slide_ops_llt_test/CMakeLists.txt b/etmem/test/etmem_slide_ops_llt_test/CMakeLists.txt -new file mode 100644 -index 0000000..2162d9e ---- /dev/null -+++ b/etmem/test/etmem_slide_ops_llt_test/CMakeLists.txt -@@ -0,0 +1,29 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: liubo -+# * Create: 2021-11-29 -+# * Description: CMakefileList for etmem_slide_ops_llt to compile -+# ******************************************************************************/ -+ -+project(etmem) -+ -+INCLUDE_DIRECTORIES(../../inc/etmem_inc) -+INCLUDE_DIRECTORIES(../../inc/etmemd_inc) -+INCLUDE_DIRECTORIES(../common) -+INCLUDE_DIRECTORIES(../../src/etmemd_src) -+INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -+ -+SET(EXE etmem_slide_ops_llt) -+ -+add_executable(${EXE} etmem_slide_ops_llt.c) -+ -+target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so ${BUILD_DIR}/lib/libtest.so pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -+target_link_libraries(mem_swaptest pthread dl rt boundscheck) -diff --git a/etmem/test/etmem_slide_ops_llt_test/etmem_slide_ops_llt.c b/etmem/test/etmem_slide_ops_llt_test/etmem_slide_ops_llt.c -new file mode 100644 -index 0000000..3a04a86 ---- /dev/null -+++ b/etmem/test/etmem_slide_ops_llt_test/etmem_slide_ops_llt.c -@@ -0,0 +1,648 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liubo -+ * Create: 2021-11-29 -+ * Description: This is a source file of the unit test for project-related commands in etmem. -+ ******************************************************************************/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "etmemd_project.h" -+#include "etmemd_task.h" -+#include "etmemd_engine.h" -+#include "etmemd_slide.h" -+#include "etmemd_cslide.h" -+#include "etmemd_rpc.h" -+#include "securec.h" -+ -+#include "test_common.h" -+ -+#include "etmemd_slide.c" -+ -+#define PID_STR_MAX_LEN 10 -+#define PID_TEST_NUM 100 -+#define PID_PROCESS_MEM 5000 -+#define PID_PROCESS_SLEEP_TIME 60 -+#define WATER_LINT_TEMP 3 -+#define RAND_STR_ARRAY_LEN 62 -+ -+static void test_engine_name_invalid(void) -+{ -+ struct eng_test_param slide_param; -+ GKeyFile *config = NULL; -+ -+ init_slide_eng(&slide_param); -+ -+ slide_param.name = "engine no exist"; -+ config = construct_eng_config(&slide_param); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_engine(config), OPT_SUCCESS); -+ destroy_eng_config(config); -+ -+ slide_param.name = ""; -+ config = construct_eng_config(&slide_param); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_engine(config), OPT_SUCCESS); -+ destroy_eng_config(config); -+ -+ slide_param.name = NULL; -+ config = construct_eng_config(&slide_param); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_engine(config), OPT_SUCCESS); -+ destroy_eng_config(config); -+} -+ -+static void test_engine_proj_invalid(void) -+{ -+ struct eng_test_param slide_param; -+ GKeyFile *config = NULL; -+ -+ init_slide_eng(&slide_param); -+ -+ slide_param.proj = "proj no exist"; -+ config = construct_eng_config(&slide_param); -+ CU_ASSERT_EQUAL(etmemd_project_add_engine(config), OPT_PRO_NOEXIST); -+ destroy_eng_config(config); -+ -+ slide_param.proj = ""; -+ config = construct_eng_config(&slide_param); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_engine(config), OPT_SUCCESS); -+ destroy_eng_config(config); -+ -+ slide_param.proj = NULL; -+ config = construct_eng_config(&slide_param); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_engine(config), OPT_SUCCESS); -+ destroy_eng_config(config); -+} -+ -+void test_etmem_slide_engine_002(void) -+{ -+ struct proj_test_param proj_param; -+ struct eng_test_param slide_eng; -+ struct cslide_eng_test_param cslide_eng; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(&proj_param); -+ do_add_proj_test(&proj_param); -+ -+ init_cslide_eng(&cslide_eng); -+ config = construct_cslide_eng_config(&cslide_eng); -+ CU_ASSERT_EQUAL(etmemd_project_add_engine(config), OPT_SUCCESS); -+ destroy_cslide_eng_config(config); -+ -+ /* repeat add and remove engine */ -+ init_slide_eng(&slide_eng); -+ config = construct_eng_config(&slide_eng); -+ CU_ASSERT_EQUAL(etmemd_project_add_engine(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_add_engine(config), OPT_ENG_EXISTED); -+ CU_ASSERT_EQUAL(etmemd_project_remove_engine(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove_engine(config), OPT_ENG_NOEXIST); -+ destroy_eng_config(config); -+ -+ test_engine_name_invalid(); -+ test_engine_proj_invalid(); -+ -+ init_cslide_eng(&cslide_eng); -+ config = construct_cslide_eng_config(&cslide_eng); -+ CU_ASSERT_EQUAL(etmemd_project_remove_engine(config), OPT_SUCCESS); -+ destroy_cslide_eng_config(config); -+ -+ do_rm_proj_test(&proj_param); -+} -+ -+void test_etmem_slide_engine_001(void) -+{ -+ struct proj_test_param proj_param; -+ struct eng_test_param slide_eng; -+ struct slide_task_test_param slide_task; -+ GKeyFile *eng_config = NULL; -+ GKeyFile *task_config = NULL; -+ -+ init_proj_param(&proj_param); -+ do_add_proj_test(&proj_param); -+ -+ init_slide_eng(&slide_eng); -+ eng_config = construct_eng_config(&slide_eng); -+ CU_ASSERT_EQUAL(etmemd_project_add_engine(eng_config), OPT_SUCCESS); -+ -+ init_slide_task(&slide_task); -+ task_config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(task_config), OPT_SUCCESS); -+ destroy_slide_task_config(task_config); -+ -+ CU_ASSERT_EQUAL(etmemd_project_remove_engine(eng_config), OPT_SUCCESS); -+ destroy_eng_config(eng_config); -+ -+ do_rm_proj_test(&proj_param); -+} -+ -+static void task_test_init(void) -+{ -+ struct proj_test_param proj_param; -+ struct eng_test_param eng_param; -+ struct cslide_eng_test_param cslide_eng; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(&proj_param); -+ do_add_proj_test(&proj_param); -+ -+ init_cslide_eng(&cslide_eng); -+ config = construct_cslide_eng_config(&cslide_eng); -+ CU_ASSERT_EQUAL(etmemd_project_add_engine(config), OPT_SUCCESS); -+ destroy_cslide_eng_config(config); -+ -+ init_slide_eng(&eng_param); -+ config = construct_eng_config(&eng_param); -+ CU_ASSERT_EQUAL(etmemd_project_add_engine(config), OPT_SUCCESS); -+ destroy_eng_config(config); -+} -+ -+static void task_test_fini(void) -+{ -+ struct proj_test_param proj_param; -+ struct eng_test_param eng_param; -+ struct cslide_eng_test_param cslide_eng; -+ GKeyFile *config = NULL; -+ -+ init_cslide_eng(&cslide_eng); -+ config = construct_cslide_eng_config(&cslide_eng); -+ CU_ASSERT_EQUAL(etmemd_project_remove_engine(config), OPT_SUCCESS); -+ destroy_cslide_eng_config(config); -+ -+ init_slide_eng(&eng_param); -+ config = construct_eng_config(&eng_param); -+ CU_ASSERT_EQUAL(etmemd_project_remove_engine(config), OPT_SUCCESS); -+ destroy_eng_config(config); -+ -+ init_proj_param(&proj_param); -+ do_rm_proj_test(&proj_param); -+} -+ -+static void test_etmem_slide_task_001(void) -+{ -+ struct slide_task_test_param slide_task; -+ GKeyFile *config = NULL; -+ -+ task_test_init(); -+ -+ init_slide_task(&slide_task); -+ slide_task.task_param.name = "task1"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ init_slide_task(&slide_task); -+ slide_task.task_param.name = "task2"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ CU_ASSERT_EQUAL(etmemd_migrate_start(DEFAULT_PROJ), OPT_SUCCESS); -+ init_slide_task(&slide_task); -+ slide_task.task_param.name = "task1"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ CU_ASSERT_EQUAL(etmemd_migrate_stop(DEFAULT_PROJ), OPT_SUCCESS); -+ init_slide_task(&slide_task); -+ slide_task.task_param.name = "task2"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ task_test_fini(); -+} -+ -+static void test_etmem_task_swap_flag_error(void) -+{ -+ struct slide_task_test_param slide_task; -+ GKeyFile *config = NULL; -+ -+ task_test_init(); -+ -+ /* empty value of swap_flag */ -+ init_slide_task(&slide_task); -+ slide_task.swap_flag = ""; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* wrong value of swap_flag */ -+ init_slide_task(&slide_task); -+ slide_task.swap_flag = "wrong"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* wrong value of swap_flag */ -+ init_slide_task(&slide_task); -+ slide_task.swap_flag = "YES"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* wrong value of swap_flag */ -+ init_slide_task(&slide_task); -+ slide_task.swap_flag = "NO"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* wrong value of pid which is equal to 0 */ -+ init_slide_task(&slide_task); -+ slide_task.task_param.value = "0"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_start(DEFAULT_PROJ), OPT_SUCCESS); -+ /* sleep 10 seconds to run etmemd project for coverage of slide_executor */ -+ sleep(10); -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* run slide_policy_interface fail */ -+ CU_ASSERT_EQUAL(slide_policy_interface(NULL, NULL), NULL); -+ -+ /* run slide_do_migrate fail */ -+ CU_ASSERT_EQUAL(slide_do_migrate(1, NULL), -1); -+ -+ task_test_fini(); -+} -+ -+static void test_etmem_task_swap_flag_ok(void) -+{ -+ struct slide_task_test_param slide_task; -+ GKeyFile *config = NULL; -+ -+ task_test_init(); -+ -+ /* empty value of swap_flag */ -+ init_slide_task(&slide_task); -+ slide_task.task_param.name = "task1_swap_flag_yes"; -+ slide_task.swap_flag = "yes"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ init_slide_task(&slide_task); -+ slide_task.task_param.name = "task1_swap_flag_no"; -+ slide_task.swap_flag = "no"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ task_test_fini(); -+} -+ -+static void test_etmem_task_swap_threshold_error(void) -+{ -+ struct slide_task_test_param slide_task; -+ GKeyFile *config = NULL; -+ -+ task_test_init(); -+ -+ /* empty value of swap_threshold */ -+ init_slide_task(&slide_task); -+ slide_task.swap_threshold = ""; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* swap_threshold too long */ -+ init_slide_task(&slide_task); -+ slide_task.swap_threshold = "12345678910234g"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* swap_threshold para is wrong*/ -+ init_slide_task(&slide_task); -+ slide_task.swap_threshold = "12hhG"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* swap_threshold para is wrong*/ -+ init_slide_task(&slide_task); -+ slide_task.swap_threshold = "1234"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* wrong value of pid which is equal to 0 */ -+ init_slide_task(&slide_task); -+ slide_task.task_param.value = "0"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_start(DEFAULT_PROJ), OPT_SUCCESS); -+ /* sleep 10 seconds to run etmemd project for coverage of slide_executor */ -+ sleep(10); -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* run slide_policy_interface fail */ -+ CU_ASSERT_EQUAL(slide_policy_interface(NULL, NULL), NULL); -+ -+ /* run slide_do_migrate fail */ -+ CU_ASSERT_EQUAL(slide_do_migrate(1, NULL), -1); -+ -+ task_test_fini(); -+} -+ -+static void test_etmem_task_swap_threshold_ok(void) -+{ -+ struct slide_task_test_param slide_task; -+ GKeyFile *config = NULL; -+ -+ task_test_init(); -+ -+ init_slide_task(&slide_task); -+ slide_task.task_param.name = "task1_swap_threshold_5G"; -+ slide_task.swap_threshold = "5G"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ init_slide_task(&slide_task); -+ slide_task.task_param.name = "task1_swap_threshold_5g"; -+ slide_task.swap_threshold = "5g"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ init_slide_task(&slide_task); -+ slide_task.task_param.name = "task2_swap_threshold"; -+ slide_task.swap_threshold = "123456789g"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ init_slide_task(&slide_task); -+ slide_task.task_param.name = "task3_swap_threshold"; -+ slide_task.swap_threshold = "999999999g"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ task_test_fini(); -+} -+ -+static void test_task_common_invalid_config(void) -+{ -+ struct slide_task_test_param slide_task; -+ GKeyFile *config = NULL; -+ char *long_name = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; -+ -+ /* repeat add */ -+ init_slide_task(&slide_task); -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_TASK_EXISTED); -+ destroy_slide_task_config(config); -+ -+ /* no exist remove */ -+ slide_task.task_param.name = "task no exists"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(config), OPT_TASK_NOEXIST); -+ destroy_slide_task_config(config); -+ -+ /* repeat remove */ -+ init_slide_task(&slide_task); -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(config), OPT_TASK_NOEXIST); -+ destroy_slide_task_config(config); -+ -+ /* no project exist */ -+ init_slide_task(&slide_task); -+ slide_task.task_param.proj = "proj no exists"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_PRO_NOEXIST); -+ destroy_slide_task_config(config); -+ -+ /* not project set */ -+ slide_task.task_param.proj = NULL; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_INVAL); -+ destroy_slide_task_config(config); -+ -+ /* long project name */ -+ slide_task.task_param.proj = long_name; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_INVAL); -+ destroy_slide_task_config(config); -+ -+ /* no engine exist */ -+ init_slide_task(&slide_task); -+ slide_task.task_param.eng = "task no exists"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_ENG_NOEXIST); -+ destroy_slide_task_config(config); -+ -+ /* no engine set */ -+ slide_task.task_param.eng = NULL; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_INVAL); -+ destroy_slide_task_config(config); -+ -+ /* long engine name */ -+ slide_task.task_param.eng = long_name; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_INVAL); -+ destroy_slide_task_config(config); -+ -+ /* no name set for task */ -+ init_slide_task(&slide_task); -+ slide_task.task_param.name = NULL; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_INVAL); -+ destroy_slide_task_config(config); -+ -+ /* task name too long */ -+ slide_task.task_param.name = long_name; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_INVAL); -+ destroy_slide_task_config(config); -+ -+ /* type invalid */ -+ init_slide_task(&slide_task); -+ slide_task.task_param.type = "invalid"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+} -+ -+static void test_task_slide_invalid_config(void) -+{ -+ struct slide_task_test_param slide_task; -+ GKeyFile *config = NULL; -+ -+ init_slide_task(&slide_task); -+ -+ /* enpty value of T */ -+ slide_task.T = ""; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* wrong value of T which is bigger than WEIGHT * loop times */ -+ slide_task.T = "10"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* wrong value of T which is less than 0 */ -+ slide_task.T = "-1"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ init_slide_task(&slide_task); -+ /* wrong value of max_threads which is equal to 0, slide will correct it -+ * to valid value -+ */ -+ slide_task.max_threads = "0"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_start(DEFAULT_PROJ), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop(DEFAULT_PROJ), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* wrong value of max_threads which is equal to -1, slide will correct it -+ * to valid value -+ */ -+ slide_task.max_threads = "-1"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_start(DEFAULT_PROJ), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop(DEFAULT_PROJ), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* wrong value of max_threads which is too big, slide will correct it -+ * to valid value -+ */ -+ slide_task.max_threads = "10000"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_start(DEFAULT_PROJ), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop(DEFAULT_PROJ), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ init_slide_task(&slide_task); -+ /* wrong value of pid which is equal to 0 */ -+ slide_task.task_param.value = "0"; -+ config = construct_slide_task_config(&slide_task); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_start(DEFAULT_PROJ), OPT_SUCCESS); -+ /* sleep 10 seconds to run etmemd project for coverage of slide_executor */ -+ sleep(10); -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(config), OPT_SUCCESS); -+ destroy_slide_task_config(config); -+ -+ /* run slide_policy_interface fail */ -+ CU_ASSERT_EQUAL(slide_policy_interface(NULL, NULL), NULL); -+ -+ /* run slide_do_migrate fail */ -+ CU_ASSERT_EQUAL(slide_do_migrate(1, NULL), -1); -+} -+ -+void test_etmem_slide_task_002(void) -+{ -+ task_test_init(); -+ -+ test_task_common_invalid_config(); -+ test_task_slide_invalid_config(); -+ -+ task_test_fini(); -+} -+ -+typedef enum { -+ CUNIT_SCREEN = 0, -+ CUNIT_XMLFILE, -+ CUNIT_CONSOLE -+} cu_run_mode; -+ -+static void test_slide(void) -+{ -+ CU_ASSERT_EQUAL(system("../etmem_slide_ops_llt_test/test_slide_ops.sh"), 0); -+} -+ -+int main(int argc, const char **argv) -+{ -+ CU_pSuite suite; -+ CU_pTest pTest; -+ unsigned int num_failures; -+ cu_run_mode cunit_mode = CUNIT_SCREEN; -+ int error_num; -+ -+ if (argc > 1) { -+ cunit_mode = atoi(argv[1]); -+ } -+ -+ if (CU_initialize_registry() != CUE_SUCCESS) { -+ return -CU_get_error(); -+ } -+ -+ suite = CU_add_suite("etmem_slide_ops", NULL, NULL); -+ if (suite == NULL) { -+ goto ERROR; -+ } -+ -+ if (CU_ADD_TEST(suite, test_etmem_slide_task_002) == NULL || -+ CU_ADD_TEST(suite, test_etmem_slide_task_001) == NULL || -+ CU_ADD_TEST(suite, test_etmem_slide_engine_002) == NULL || -+ CU_ADD_TEST(suite, test_etmem_slide_engine_001) == NULL || -+ CU_ADD_TEST(suite, test_etmem_task_swap_flag_error) == NULL || -+ CU_ADD_TEST(suite, test_etmem_task_swap_flag_ok) == NULL || -+ CU_ADD_TEST(suite, test_etmem_task_swap_threshold_error) == NULL || -+ CU_ADD_TEST(suite, test_etmem_task_swap_threshold_ok) == NULL || -+ CU_ADD_TEST(suite, test_slide) == NULL) { -+ printf("CU_ADD_TEST fail. \n"); -+ goto ERROR; -+ } -+ -+ switch (cunit_mode) { -+ case CUNIT_SCREEN: -+ CU_basic_set_mode(CU_BRM_VERBOSE); -+ CU_basic_run_tests(); -+ break; -+ case CUNIT_XMLFILE: -+ CU_set_output_filename("etmemd_slide.c"); -+ CU_automated_run_tests(); -+ break; -+ case CUNIT_CONSOLE: -+ CU_console_run_tests(); -+ break; -+ default: -+ printf("not support cunit mode, only support: " -+ "0 for CUNIT_SCREEN, 1 for CUNIT_XMLFILE, 2 for CUNIT_CONSOLE\n"); -+ goto ERROR; -+ } -+ -+ num_failures = CU_get_number_of_failures(); -+ CU_cleanup_registry(); -+ return num_failures; -+ -+ERROR: -+ error_num = CU_get_error(); -+ CU_cleanup_registry(); -+ return -error_num; -+} -diff --git a/etmem/test/etmem_slide_ops_llt_test/mem_swaptest.c b/etmem/test/etmem_slide_ops_llt_test/mem_swaptest.c -new file mode 100644 -index 0000000..ab26f8e ---- /dev/null -+++ b/etmem/test/etmem_slide_ops_llt_test/mem_swaptest.c -@@ -0,0 +1,95 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liubo -+ * Create: 2021-11-29 -+ * Description: construct a progress test for etmemd slide engine -+ ******************************************************************************/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "securec.h" -+ -+#define VMA_FLAG 203 -+#define SLEEP_TIME 2 -+ -+int main(int argc, char *argv[]) -+{ -+ char *memory_with_flag = NULL; -+ char *memory_no_flag = NULL; -+ char i = 0; -+ int ret = -1; -+ /* get memory size: 1GB for test */ -+ size_t memory_len = (1UL * 1024) * 1024 * 1024; -+ -+ memory_with_flag = (char *)mmap(NULL, memory_len, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); -+ if (memory_with_flag == MAP_FAILED) { -+ perror("map mem"); -+ memory_with_flag = NULL; -+ return -1; -+ } -+ -+ ret = madvise(memory_with_flag, memory_len, VMA_FLAG); -+ if (ret != 0) { -+ printf("madvise error.\n"); -+ goto free_memory_with_flag; -+ } -+ -+ ret = memset_s(memory_with_flag, memory_len, '0', memory_len); -+ if (ret != EOK) { -+ printf("memset for memory_with flag fail, ret: %d err(%s)\n", ret, strerror(errno)); -+ goto free_memory_with_flag; -+ } -+ -+ memory_no_flag = (char *)mmap(NULL, memory_len, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); -+ if (memory_no_flag == MAP_FAILED) { -+ perror("map mem"); -+ goto free_memory_with_flag; -+ } -+ -+ ret = memset_s(memory_no_flag, memory_len, '0', memory_len); -+ if (ret != EOK) { -+ printf("memset for memory_no_flag flag fail, ret: %d err(%s)\n", ret, strerror(errno)); -+ goto free_all_memory; -+ } -+ -+ while (1) { -+ ret = memset_s(memory_no_flag, memory_len, i, memory_len); -+ if (ret != EOK) { -+ printf("memset for memory_no_flag flag fail\n"); -+ goto free_all_memory; -+ } -+ -+ sleep(SLEEP_TIME); -+ i++; -+ } -+ -+free_all_memory: -+ ret = munmap(memory_no_flag, memory_len); -+ if (ret != 0) { -+ printf("release memory for memory_no_flag failed.\n"); -+ return -1; -+ } -+ -+free_memory_with_flag: -+ ret = munmap(memory_with_flag, memory_len); -+ if (ret != 0) { -+ printf("release memory for memory_with_flag failed.\n"); -+ return -1; -+ } -+ -+ return 0; -+} -diff --git a/etmem/test/etmem_slide_ops_llt_test/test_slide_ops.sh b/etmem/test/etmem_slide_ops_llt_test/test_slide_ops.sh -new file mode 100644 -index 0000000..f763726 ---- /dev/null -+++ b/etmem/test/etmem_slide_ops_llt_test/test_slide_ops.sh -@@ -0,0 +1,309 @@ -+#!/bin/bash -+# -+#Level: 0 -+#Type: auto -+#Description: start 多个不同的project -+ -+set +e -+ -+config_file="../conf/conf_slide/config_file" -+config_file_bak="../conf/conf_slide/config_file_bak" -+Etmem_slide_test="slide_test" -+project_configfile=`pwd`/"slide_project_swap_test.yaml" -+task_configfile=`pwd`/"slide_task_test.yaml" -+ -+function rand_file_Str -+{ -+ j=0; -+ for i in {a..z};do array[$j]=$i;j=$(($j+1));done -+ for i in {A..Z};do array[$j]=$i;j=$(($j+1));done -+ for ((i=0;i<257;i++));do filestrs="$filestrs${array[$(($RANDOM%$j))]}";done -+} -+ -+function rand_pro_Str -+{ -+ j=0; -+ for i in {a..z};do array[$j]=$i;j=$(($j+1));done -+ for i in {A..Z};do array[$j]=$i;j=$(($j+1));done -+ for ((i=0;i<33;i++));do prostrs="$prostrs${array[$(($RANDOM%$j))]}";done -+} -+ -+function rand_sock_Str -+{ -+ j=0; -+ for i in {a..z};do array[$j]=$i;j=$(($j+1));done -+ for i in {A..Z};do array[$j]=$i;j=$(($j+1));done -+ for ((i=0;i<108;i++));do sockstrs="$sockstrs${array[$(($RANDOM%$j))]}";done -+} -+ -+function add_project() -+{ -+ touch $project_configfile -+ -+ echo "[project]" >> $project_configfile -+ echo "name=$Etmem_slide_test" >> $project_configfile -+ echo "loop=1" >> $project_configfile -+ echo "interval=1" >> $project_configfile -+ echo "sleep=1" >> $project_configfile -+ -+ echo "sysmem_threshold=100" >> $project_configfile -+ echo "swapcache_high_wmark=3" >> $project_configfile -+ echo "swapcache_low_wmark=1" >> $project_configfile -+ -+ echo "" >> $project_configfile -+ echo "#slide" >> $project_configfile -+ echo "[engine]" >> $project_configfile -+ echo "name=slide" >> $project_configfile -+ echo "project=$Etmem_slide_test" >> $project_configfile -+ -+ ./bin/etmem obj add -f ${project_configfile} -s sock_slide_name -+ -+ for i in $* -+ do -+ rm -f $task_configfile -+ touch $task_configfile -+ echo "[task]" >> $task_configfile -+ echo "project=$Etmem_slide_test" >> $task_configfile -+ echo "engine=slide" >> $task_configfile -+ echo "name=swap_test_$i" >> $task_configfile -+ echo "type=name" >> $task_configfile -+ echo "value = $i" >> $task_configfile -+ echo "max_threads=1" >> $task_configfile -+ echo "T=3" >> $task_configfile -+ echo $i -+ if [ $i = 'mem_swaptest' ];then -+ echo "swap_threshold=1g" >> $task_configfile -+ echo "swap_flag=yes" >> $task_configfile -+ fi -+ ./bin/etmem obj add -f ${task_configfile} -s sock_slide_name -+ done -+} -+ -+function start_project() -+{ -+ ./bin/etmem project start -n ${Etmem_slide_test} -s sock_slide_name -+ ./bin/etmem project show -s sock_slide_name -+} -+ -+function project_name_length_larger() -+{ -+ sed -i "s/name=test/name=project_name_length_larger_than_32/g" ${config_file_bak} -+} -+ -+function project_name_length_restore() -+{ -+ sed -i "s/name=project_name_length_larger_than_32/name=test/g" ${config_file_bak} -+} -+ -+cmd_test() -+{ -+ ./bin/etmem -+ ./bin/etmem -h -+ ./bin/etmem help -+ ./bin/etmem project -+ ./bin/etmem obj -+ ./bin/etmem project -h -+ ./bin/etmem obj -h -+ ./bin/etmem project help -+ ./bin/etmem obj help -+ ./bin/etmem project other -+ ./bin/etmem obj other -+ ./bin/etmem obj add -+ ./bin/etmem obj add -o other -+ ./bin/etmem project start -o other -+ ./bin/etmem project start -n project_name_length_larger_than_32 -+ project_name_length_larger -+ ./bin/etmem obj add -f ${config_file_bak} -s sock_slide_name -+ project_name_length_restore -+ ./bin/etmem obj add -s sock_cmd_name -+ ./bin/etmem obj add -f ${config_file} -+ ./bin/etmem obj add -f ${config_file} -s sock_cmd_name -+ ./bin/etmem obj add -f ${filestrs} -s sock_cmd_name -+ ./bin/etmem obj add -n ${prostrs} -s sock_cmd_name -+ ./bin/etmem obj add -f ${config_file} -s ${sockstrs} -+ ./bin/etmem obj add -f ${config_file} -s sock_cmd_name error -+ ./bin/etmem project start -n ${Etmem_slide_test} -s sock_cmd_name -+ ./bin/etmem project start -n ${Etmem_slide_test} -+ ./bin/etmem project start -s sock_cmd_name -+ ./bin/etmem engine -+ ./bin/etmem engine -h -+ ./bin/etmem engine --help -+ ./bin/etmem engine -s "" -+ ./bin/etmem engine -s sock_name -+ ./bin/etmem engine -s sock_name -n "" -+ ./bin/etmem engine -s sock_name -n proj_name -+ ./bin/etmem engine -s sock_name -n proj_name -e "" -t task_name -+ ./bin/etmem engine -s sock_name -n proj_name -e cslide -t "" -+ ./bin/etmem engine "" -s sock_name -n proj_name -e cslide -t task_name -+ ./bin/etmem engine showtaskpages -s sock_name -+ ./bin/etmem engine showtaskpages -s sock_name -n proj_name -+ ./bin/etmem engine showtaskpages -s sock_name -n proj_name -e -+ ./bin/etmem engine showtaskpages -s sock_name -n proj_name -e cslide -+ ./bin/etmem engine showtaskpages -s sock_name -n proj_name -e cslide -t task_name -+ ./bin/etmem engine showtaskpages -s sock_name -n proj_name -e slide -t task_name -+ ./bin/etmem engine showhostpages -s sock_name -n proj_name -e cslide -t task_name -+ ./bin/etmem engine showhostpages -s sock_name -n proj_name -e cslide -t "" -+ ./bin/etmemd error -+ ./bin/etmemd -s -+ ./bin/etmemd -h -+ ./bin/etmemd -l a -+ ./bin/etmemd -+ ./bin/etmemd -m -+ ./bin/etmemd -m A -+ ./bin/etmemd -h help -+ ./bin/etmemd -s test_socket socket -+ ./bin/etmemd -l 0 -s sock_slide_name & -+ sleep 1 -+ ./bin/etmem engine shownothing -n proj_name -e cslide -t task_name -s sock_slide_name -+ killall etmemd -+} -+ -+pre_test() -+{ -+ echo "keep the param_val unchanged" -+ cp ${config_file} ${config_file_bak} -+ if [ ! -d ./../build ];then -+ echo -e " directory \033[;31mnot exist\033[0m, pls check!" -+ exit 1; -+ fi -+ rm -f $project_configfile -+ cp ./bin/mem_swaptest ./bin/sysmem_swaptest -+ ./bin/mem_swaptest & -+ ./bin/sysmem_swaptest & -+} -+ -+do_test() -+{ -+ touch etmemd.log -+ ./bin/etmemd -l 0 -s sock_slide_name >etmemd.log 2>&1 & -+ sleep 1 -+ -+ add_project $1 $2 & -+ pidadd_project=$! -+ wait ${pidadd_project} -+ -+ echo "" -+ echo "start to test slide of etmemd" -+ -+ start_project & -+ pidstart_project=$! -+ wait ${pidstart_project} -+ -+ sleep 20 -+} -+ -+post_test() -+{ -+ pid_swap_test=`pidof mem_swaptest` -+ echo ${pid_swap_test} -+ pid_sysmem_swaptest=`pidof sysmem_swaptest` -+ echo ${pid_sysmem_swaptest} -+ mem_vmswap=$(cat /proc/${pid_swap_test}/status |grep VmSwap |awk '{print $2}') -+ echo ${mem_vmswap} -+ -+ kill -9 ${pid_swap_test} -+ kill -9 ${pid_sysmem_swaptest} -+ -+ echo "now to recover env" -+ rm -f ${config_file_bak} -+ rm -rf etmemd.log -+ killall etmemd -+} -+ -+test_empty_config() -+{ -+ ./bin/etmemd -l 0 -s dt_socket & -+ etmemd_pid=$! -+ sleep 1 -+ echo "[not_used_group]" > ../conf/conf_slide/empty_config -+ echo "aaa=bbb" >> ../conf/conf_slide/empty_config -+ ./bin/etmem obj add -f ../conf/conf_slide/empty_config -s dt_socket -+ if [ "$?" == "0" ];then -+ echo "add empty config success unexpected" -+ exit 1 -+ fi -+ ps -aux |grep -v grep |grep ${etmemd_pid} -+ if [ "$?" != "0" ];then -+ echo "etmemd exit unexpected after add empty config" -+ exit 1 -+ fi -+ killall etmemd -+ rm -f ../conf/conf_slide/empty_config -+} -+ -+test_error_config() -+{ -+ echo "[task]" > ../conf/error_proj.config -+ echo "type=xxxxx" >> ../conf/error_proj.config -+ -+ ./bin/etmemd -l 0 -s dt_socket & -+ etmemd_pid=$! -+ sleep 1 -+ ./bin/etmem obj del -f ../conf/error_proj.config -s dt_socket -+ if [ "$?" == "0" ];then -+ echo "add error config success unexpected" -+ exit 1 -+ fi -+ ps -aux |grep -v grep |grep ${etmemd_pid} -+ if [ "$?" != "0" ];then -+ echo "etmemd exit unexpected after add error config" -+ exit 1 -+ fi -+ killall etmemd -+ rm -f ../conf/error_proj.config -+} -+ -+test_noexist_config() -+{ -+ ./bin/etmemd -l 0 -s dt_socket & -+ etmemd_pid=$! -+ sleep 1 -+ ./bin/etmem obj add -f ../conf/noexist.config -s dt_socket -+ if [ "$?" == "0" ];then -+ echo "add noexist config success unexpected" -+ exit 1 -+ fi -+ ps -aux |grep -v grep |grep ${etmemd_pid} -+ if [ "$?" != "0" ];then -+ echo "etmemd exit unexpected after add noexist config" -+ exit 1 -+ fi -+ killall etmemd -+} -+ -+test_sig_pipe() -+{ -+ ./bin/etmemd -l 0 -s dt_socket & -+ etmemd_pid=$! -+ sleep 1 -+ kill -13 ${etmemd_pid} -+ ps -aux |grep -v grep |grep ${etmemd_pid} -+ if [ "$?" != "0" ];then -+ echo "etmemd exit unexpected after recv SIGPIPE" -+ exit 1 -+ fi -+ killall etmemd -+} -+ -+test_etmem_help() -+{ -+ ./bin/etmem help -+ if [ "$?" != "0" ];then -+ echo "etmem help return error unexpect" -+ exit 1 -+ fi -+} -+ -+rand_file_Str -+rand_pro_Str -+rand_sock_Str -+cmd_test -+pre_test -+do_test mem_swaptest sysmem_swaptest -+post_test -+ -+test_sig_pipe -+test_empty_config -+test_error_config -+test_noexist_config -+test_etmem_help --- -1.8.3.1 - diff --git a/0065-etmem-add-code-of-testcase.patch b/0065-etmem-add-code-of-testcase.patch deleted file mode 100644 index 8db85c9..0000000 --- a/0065-etmem-add-code-of-testcase.patch +++ /dev/null @@ -1,682 +0,0 @@ -From 9018988c20ce1ee49d2d4458d85b72993ee39283 Mon Sep 17 00:00:00 2001 -From: liubo -Date: Mon, 24 Jan 2022 03:02:41 +0800 -Subject: [PATCH 15/33] etmem: add code of testcase - -add code of testcase for etmem migrate functions -add testcase to etmem project function - -Signed-off-by: liubo ---- - etmem/test/common/test_common.c | 33 ++- - etmem/test/common/test_common.h | 72 ++++--- - etmem/test/etmem_migrate_ops_llt/CMakeLists.txt | 27 +++ - .../etmem_migrate_ops_llt/etmem_migrate_ops_llt.c | 226 +++++++++++++++++++++ - .../etmem_project_ops_llt.c | 161 ++++++++++++++- - .../etmem_scan_ops_llt_test/etmem_scan_ops_llt.c | 4 +- - 6 files changed, 484 insertions(+), 39 deletions(-) - create mode 100644 etmem/test/etmem_migrate_ops_llt/CMakeLists.txt - create mode 100644 etmem/test/etmem_migrate_ops_llt/etmem_migrate_ops_llt.c - -diff --git a/etmem/test/common/test_common.c b/etmem/test/common/test_common.c -index 4551177..4bd3fc3 100644 ---- a/etmem/test/common/test_common.c -+++ b/etmem/test/common/test_common.c -@@ -63,6 +63,18 @@ void construct_proj_file(struct proj_test_param *param) - if (param->sleep != NULL) { - CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_SLEEP, param->sleep), -1); - } -+ if (param->sysmem_threshold != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_SYSMEM_THRESHOLD, -+ param->sysmem_threshold), -1); -+ } -+ if (param->swapcache_high_wmark != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_SWAPCACHE_HIGH_WMARK, -+ param->swapcache_high_wmark), -1); -+ } -+ if (param->swapcache_low_wmark != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_SWAPCACHE_LOW_WMARK, -+ param->swapcache_low_wmark), -1); -+ } - fclose(file); - } - -@@ -83,12 +95,15 @@ void init_proj_param(struct proj_test_param *param) - param->sleep = "1"; - param->interval = "1"; - param->loop = "1"; -+ param->sysmem_threshold = NULL; -+ param->swapcache_high_wmark = NULL; -+ param->swapcache_low_wmark = NULL; - param->file_name = TMP_PROJ_CONFIG; - param->proj_name = DEFAULT_PROJ; - param->expt = OPT_SUCCESS; - } - --void do_add_proj_test(struct proj_test_param * param) -+void do_add_proj_test(struct proj_test_param *param) - { - GKeyFile *config = NULL; - -@@ -155,16 +170,16 @@ void construct_task_file(struct task_test_param *param) - CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_NAME, param->name), -1); - } - if (param->proj != NULL) { -- CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_PROJ, param->name), -1); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_PROJ, param->proj), -1); - } - if (param->eng != NULL) { -- CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_ENG, param->name), -1); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_ENG, param->eng), -1); - } - if (param->type != NULL) { -- CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_TYPE, param->name), -1); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_TYPE, param->type), -1); - } - if (param->value != NULL) { -- CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_VALUE, param->name), -1); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_VALUE, param->value), -1); - } - fclose(file); - } -@@ -174,6 +189,8 @@ void init_slide_task(struct slide_task_test_param *param) - init_task_param(¶m->task_param, "slide"); - param->max_threads = "1"; - param->T = "1"; -+ param->swap_flag = NULL; -+ param->swap_threshold = NULL; - } - - void add_slide_task(struct slide_task_test_param *param) -@@ -189,6 +206,12 @@ void add_slide_task(struct slide_task_test_param *param) - if (param->T != NULL) { - CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_T, param->T), -1); - } -+ if (param->swap_flag != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_SWAP_FLAG, param->swap_flag), -1); -+ } -+ if (param->swap_threshold != NULL) { -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_SWAP_THRESHOLD, param->swap_threshold), -1); -+ } - fclose(file); - } - -diff --git a/etmem/test/common/test_common.h b/etmem/test/common/test_common.h -index 009c458..1ba20c7 100644 ---- a/etmem/test/common/test_common.h -+++ b/etmem/test/common/test_common.h -@@ -20,43 +20,51 @@ - - #include "etmemd_project.h" - --#define CONFIG_NAME "name=%s\n" --#define CONFIG_INTERVAL "interval=%s\n" --#define CONFIG_LOOP "loop=%s\n" --#define CONFIG_SLEEP "sleep=%s\n" --#define TMP_PROJ_CONFIG "proj_tmp.config" --#define DEFAULT_PROJ "default_proj" -- --#define CONFIG_PROJ "project=%s\n" --#define TMP_ENG_CONFIG "eng_tmp.config" -- --#define CONFIG_ENG "engine=%s\n" --#define CONFIG_TYPE "type=%s\n" --#define CONFIG_VALUE "value=%s\n" --#define TMP_TASK_CONFIG "task_tmp.config" --#define DEFAULT_TASK "default_task" -- --#define CONFIG_MAX_THREADS "max_threads=%s\n" --#define CONFIG_T "T=%s\n" -- --#define CONFIG_NODE_PAIR "node_pair=%s\n" --#define CONFIG_THRESH "hot_threshold=%s\n" --#define CONFIG_QUOTA "node_mig_quota=%s\n" --#define CONFIG_RESV "node_hot_reserve=%s\n" -- --#define CONFIG_VM_FLAGS "vm_flags=%s\n" --#define CONFIG_ANON_ONLY "anon_only=%s\n" --#define CONFIG_IGN_HOST "igno_host=%s\n" -- --#define ONE_NODE_PAIR 2 --#define TWO_NODE_PAIR 4 --#define THREE_NODE_PAIR 5 -+#define CONFIG_NAME "name=%s\n" -+#define CONFIG_INTERVAL "interval=%s\n" -+#define CONFIG_LOOP "loop=%s\n" -+#define CONFIG_SLEEP "sleep=%s\n" -+#define CONFIG_SYSMEM_THRESHOLD "sysmem_threshold=%s\n" -+#define CONFIG_SWAPCACHE_HIGH_WMARK "swapcache_high_wmark=%s\n" -+#define CONFIG_SWAPCACHE_LOW_WMARK "swapcache_low_wmark=%s\n" -+#define TMP_PROJ_CONFIG "proj_tmp.config" -+#define DEFAULT_PROJ "default_proj" -+ -+#define CONFIG_PROJ "project=%s\n" -+#define TMP_ENG_CONFIG "eng_tmp.config" -+ -+#define CONFIG_ENG "engine=%s\n" -+#define CONFIG_TYPE "type=%s\n" -+#define CONFIG_VALUE "value=%s\n" -+#define TMP_TASK_CONFIG "task_tmp.config" -+#define DEFAULT_TASK "default_task" -+ -+#define CONFIG_MAX_THREADS "max_threads=%s\n" -+#define CONFIG_T "T=%s\n" -+#define CONFIG_SWAP_FLAG "swap_flag=%s\n" -+#define CONFIG_SWAP_THRESHOLD "swap_threshold=%s\n" -+ -+#define CONFIG_NODE_PAIR "node_pair=%s\n" -+#define CONFIG_THRESH "hot_threshold=%s\n" -+#define CONFIG_QUOTA "node_mig_quota=%s\n" -+#define CONFIG_RESV "node_hot_reserve=%s\n" -+ -+#define CONFIG_VM_FLAGS "vm_flags=%s\n" -+#define CONFIG_ANON_ONLY "anon_only=%s\n" -+#define CONFIG_IGN_HOST "ign_host=%s\n" -+ -+#define ONE_NODE_PAIR 2 -+#define TWO_NODE_PAIR 4 -+#define THREE_NODE_PAIR 6 - - - struct proj_test_param { - const char *sleep; - const char *interval; - const char *loop; -+ const char *sysmem_threshold; -+ const char *swapcache_high_wmark; -+ const char *swapcache_low_wmark; - const char *proj_name; - const char *file_name; - enum opt_result expt; -@@ -81,6 +89,8 @@ struct slide_task_test_param { - struct task_test_param task_param; - const char *max_threads; - const char *T; -+ const char *swap_flag; -+ const char *swap_threshold; - }; - - struct cslide_eng_test_param { -diff --git a/etmem/test/etmem_migrate_ops_llt/CMakeLists.txt b/etmem/test/etmem_migrate_ops_llt/CMakeLists.txt -new file mode 100644 -index 0000000..a9487af ---- /dev/null -+++ b/etmem/test/etmem_migrate_ops_llt/CMakeLists.txt -@@ -0,0 +1,27 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: liubo -+# * Create: 2021-12-10 -+# * Description: CMakefileList for etmem_migrate_ops_llt to compile -+# ******************************************************************************/ -+ -+project(etmem) -+ -+INCLUDE_DIRECTORIES(../../inc/etmem_inc) -+INCLUDE_DIRECTORIES(../../inc/etmemd_inc) -+INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -+ -+SET(EXE etmem_migrate_ops_llt) -+ -+add_executable(${EXE} etmem_migrate_ops_llt.c) -+ -+set_target_properties(${EXE} PROPERTIES LINK_FLAGS "-Wl,--wrap,get_mem_from_proc_file") -+target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_migrate_ops_llt/etmem_migrate_ops_llt.c b/etmem/test/etmem_migrate_ops_llt/etmem_migrate_ops_llt.c -new file mode 100644 -index 0000000..2758680 ---- /dev/null -+++ b/etmem/test/etmem_migrate_ops_llt/etmem_migrate_ops_llt.c -@@ -0,0 +1,226 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liubo -+ * Create: 2021-08-14 -+ * Description: This is a source file of the unit test for log functions in etmem. -+ ******************************************************************************/ -+ -+#include -+#include -+#include -+#include -+ -+#include "etmemd.h" -+#include "etmemd_migrate.h" -+#include "etmemd_scan.h" -+#include "etmemd_project_exp.h" -+#include "etmemd_engine_exp.h" -+#include "etmemd_task_exp.h" -+#include "etmemd_task.h" -+ -+#include -+#include -+#include -+ -+#define WATER_LINE_TEMP 2 -+ -+/* Function replacement used for mock test. This function is used only in dt. */ -+int get_mem_from_proc_file(const char *pid, const char *file_name, -+ unsigned long *data, const char *cmpstr) -+{ -+ *data = 100; -+ return 0; -+} -+ -+void init_task_pid_param(struct task_pid *param) -+{ -+ param->pid = 1; -+ param->rt_swapin_rate = 0.0; -+ param->params = NULL; -+ param->next = NULL; -+} -+ -+static struct memory_grade *get_memory_grade(void) -+{ -+ struct memory_grade *memory_grade = NULL; -+ struct vmas *vmas = NULL; -+ struct page_refs *page_refs = NULL; -+ const char *pid = "1"; -+ -+ init_g_page_size(); -+ vmas = get_vmas(pid); -+ CU_ASSERT_PTR_NOT_NULL(vmas); -+ CU_ASSERT_EQUAL(get_page_refs(vmas, pid, &page_refs, NULL, NULL), 0); -+ free(vmas); -+ vmas = NULL; -+ -+ memory_grade = (struct memory_grade *)calloc(1, sizeof(struct memory_grade)); -+ CU_ASSERT_PTR_NOT_NULL(memory_grade); -+ -+ while (page_refs != NULL) -+ { -+ if ((page_refs)->count >= WATER_LINE_TEMP) { -+ page_refs = add_page_refs_into_memory_grade(page_refs, &memory_grade->hot_pages); -+ continue; -+ } -+ page_refs = add_page_refs_into_memory_grade(page_refs, &memory_grade->cold_pages); -+ } -+ -+ return memory_grade; -+} -+ -+static void test_etmem_migrate_error(void) -+{ -+ struct memory_grade *memory_grade = NULL; -+ -+ memory_grade = (struct memory_grade *)calloc(1, sizeof(struct memory_grade)); -+ CU_ASSERT_PTR_NOT_NULL(memory_grade); -+ -+ CU_ASSERT_EQUAL(etmemd_grade_migrate("", memory_grade), 0); -+ CU_ASSERT_EQUAL(etmemd_grade_migrate("no123", memory_grade), 0); -+ -+ free(memory_grade); -+ -+ memory_grade = get_memory_grade(); -+ CU_ASSERT_PTR_NOT_NULL(memory_grade); -+ CU_ASSERT_EQUAL(etmemd_grade_migrate("", memory_grade), -1); -+ CU_ASSERT_EQUAL(etmemd_grade_migrate("no123", memory_grade), -1); -+ -+ clean_memory_grade_unexpected(&memory_grade); -+ CU_ASSERT_PTR_NULL(memory_grade); -+} -+ -+static void test_etmem_migrate_ok(void) -+{ -+ struct memory_grade *memory_grade = NULL; -+ -+ memory_grade = get_memory_grade(); -+ CU_ASSERT_PTR_NOT_NULL(memory_grade); -+ CU_ASSERT_EQUAL(etmemd_grade_migrate("1", memory_grade), -1); -+ -+ clean_memory_grade_unexpected(&memory_grade); -+ CU_ASSERT_PTR_NULL(memory_grade); -+} -+ -+static void test_etmemd_reclaim_swapcache_error(void) -+{ -+ struct project proj = {0}; -+ struct engine eng = {0}; -+ struct task tk = {0}; -+ struct task_pid tk_pid = {0}; -+ -+ proj.swapcache_high_wmark = 5; -+ proj.swapcache_low_wmark = 3; -+ tk_pid.tk = &tk; -+ tk.eng = ŋ -+ eng.proj = &proj; -+ -+ CU_ASSERT_EQUAL(etmemd_reclaim_swapcache(NULL), -1); -+ -+ init_task_pid_param(&tk_pid); -+ tk_pid.pid = 0; -+ proj.wmark_set = false; -+ CU_ASSERT_EQUAL(etmemd_reclaim_swapcache(&tk_pid), -1); -+ -+ tk_pid.pid = 0; -+ proj.wmark_set = true; -+ CU_ASSERT_EQUAL(etmemd_reclaim_swapcache(&tk_pid), -1); -+} -+ -+static void test_etmemd_reclaim_swapcache_ok(void) -+{ -+ struct project proj = {0}; -+ struct engine eng = {0}; -+ struct task tk = {0}; -+ struct task_pid tk_pid = {0}; -+ -+ tk_pid.tk = &tk; -+ tk.eng = ŋ -+ eng.proj = &proj; -+ -+ init_task_pid_param(&tk_pid); -+ proj.swapcache_high_wmark = -1; -+ proj.swapcache_low_wmark = -1; -+ CU_ASSERT_EQUAL(etmemd_reclaim_swapcache(&tk_pid), 0); -+ -+ proj.swapcache_high_wmark = 100; -+ proj.swapcache_low_wmark = 3; -+ CU_ASSERT_EQUAL(etmemd_reclaim_swapcache(&tk_pid), 0); -+ -+ init_task_pid_param(&tk_pid); -+ proj.swapcache_high_wmark = 5; -+ proj.swapcache_low_wmark = 3; -+ proj.wmark_set = false; -+ CU_ASSERT_EQUAL(etmemd_reclaim_swapcache(&tk_pid), 0); -+} -+ -+typedef enum { -+ CUNIT_SCREEN = 0, -+ CUNIT_XMLFILE, -+ CUNIT_CONSOLE -+} cu_run_mode; -+ -+int main(int argc, const char **argv) -+{ -+ CU_pSuite suite; -+ CU_pTest pTest; -+ unsigned int num_failures; -+ cu_run_mode cunit_mode = CUNIT_SCREEN; -+ int error_num; -+ -+ if (argc > 1) { -+ cunit_mode = atoi(argv[1]); -+ } -+ -+ if (CU_initialize_registry() != CUE_SUCCESS) { -+ return -CU_get_error(); -+ } -+ -+ suite = CU_add_suite("etmem_migrate_ops", NULL, NULL); -+ if (suite == NULL) { -+ goto ERROR; -+ } -+ -+ if (CU_ADD_TEST(suite, test_etmem_migrate_error) == NULL || -+ CU_ADD_TEST(suite, test_etmem_migrate_ok) == NULL || -+ CU_ADD_TEST(suite, test_etmemd_reclaim_swapcache_error) == NULL || -+ CU_ADD_TEST(suite, test_etmemd_reclaim_swapcache_ok) == NULL) { -+ printf("CU_ADD_TEST fail. \n"); -+ goto ERROR; -+ } -+ -+ switch (cunit_mode) { -+ case CUNIT_SCREEN: -+ CU_basic_set_mode(CU_BRM_VERBOSE); -+ CU_basic_run_tests(); -+ break; -+ case CUNIT_XMLFILE: -+ CU_set_output_filename("etmemd_migrate.c"); -+ CU_automated_run_tests(); -+ break; -+ case CUNIT_CONSOLE: -+ CU_console_run_tests(); -+ break; -+ default: -+ printf("not support cunit mode, only support: " -+ "0 for CUNIT_SCREEN, 1 for CUNIT_XMLFILE, 2 for CUNIT_CONSOLE\n"); -+ goto ERROR; -+ } -+ -+ num_failures = CU_get_number_of_failures(); -+ CU_cleanup_registry(); -+ return num_failures; -+ -+ERROR: -+ error_num = CU_get_error(); -+ CU_cleanup_registry(); -+ return -error_num; -+} -diff --git a/etmem/test/etmem_project_ops_llt_test/etmem_project_ops_llt.c b/etmem/test/etmem_project_ops_llt_test/etmem_project_ops_llt.c -index a01e8e8..65c1fc6 100644 ---- a/etmem/test/etmem_project_ops_llt_test/etmem_project_ops_llt.c -+++ b/etmem/test/etmem_project_ops_llt_test/etmem_project_ops_llt.c -@@ -117,6 +117,161 @@ static void etmem_pro_add_interval(void) - destroy_proj_config(config); - } - -+static void etmem_pro_add_sysmem_threshold_error(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ param.sysmem_threshold = "101"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.sysmem_threshold = "abc"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.sysmem_threshold = "a10b"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.sysmem_threshold = "10a"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.sysmem_threshold = "-1"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+} -+ -+static void etmem_pro_add_sysmem_threshold_ok(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ param.sysmem_threshold = "0"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.sysmem_threshold = "1"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.sysmem_threshold = "2"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.sysmem_threshold = "99"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.sysmem_threshold = "100"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+} -+ -+static void etmem_pro_add_swapcache_mark_error(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ param.swapcache_high_wmark = "-1"; -+ param.swapcache_low_wmark = "-1"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.swapcache_high_wmark = "1"; -+ param.swapcache_low_wmark = "-1"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.swapcache_high_wmark = "-1"; -+ param.swapcache_low_wmark = "1"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.swapcache_high_wmark = "1"; -+ param.swapcache_low_wmark = "2"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.swapcache_high_wmark = "101"; -+ param.swapcache_low_wmark = "100"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.swapcache_high_wmark = "100"; -+ param.swapcache_low_wmark = "101"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.swapcache_high_wmark = "101"; -+ param.swapcache_low_wmark = "101"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.swapcache_high_wmark = "5"; -+ param.swapcache_low_wmark = NULL; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+ -+ param.swapcache_high_wmark = NULL; -+ param.swapcache_low_wmark = "5"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_INVAL); -+ destroy_proj_config(config); -+} -+ -+static void etmem_pro_add_swapcache_mark_ok(void) -+{ -+ struct proj_test_param param; -+ GKeyFile *config = NULL; -+ -+ init_proj_param(¶m); -+ -+ param.swapcache_high_wmark = "2"; -+ param.swapcache_low_wmark = "1"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+ -+ param.swapcache_high_wmark = "100"; -+ param.swapcache_low_wmark = "99"; -+ config = construct_proj_config(¶m); -+ CU_ASSERT_EQUAL(etmemd_project_add(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), OPT_SUCCESS); -+ destroy_proj_config(config); -+} -+ - static void etmem_pro_add_loop(void) - { - struct proj_test_param param; -@@ -231,6 +386,8 @@ void test_etmem_prj_add_error(void) - etmem_pro_add_loop(); - etmem_pro_add_sleep(); - etmem_pro_lack_loop(); -+ etmem_pro_add_sysmem_threshold_error(); -+ etmem_pro_add_swapcache_mark_error(); - } - - void test_etmem_prj_del_error(void) -@@ -256,6 +413,8 @@ static void add_project_once(void) - struct proj_test_param param; - GKeyFile *config = NULL; - -+ etmem_pro_add_sysmem_threshold_ok(); -+ etmem_pro_add_swapcache_mark_ok(); - init_proj_param(¶m); - - CU_ASSERT_EQUAL(etmemd_project_show(NULL, 0), OPT_PRO_NOEXIST); -@@ -348,7 +507,7 @@ void test_etmem_mig_stop_error(void) - CU_ASSERT_EQUAL(etmemd_migrate_stop(""), OPT_PRO_NOEXIST); - CU_ASSERT_EQUAL(etmemd_migrate_stop("ETMEM"), OPT_PRO_NOEXIST); - CU_ASSERT_EQUAL(etmemd_migrate_stop("ET^$%*MEM"), OPT_PRO_NOEXIST); -- -+ - param.proj_name = "add_for_migrate_stop_test"; - do_add_proj_test(¶m); - -diff --git a/etmem/test/etmem_scan_ops_llt_test/etmem_scan_ops_llt.c b/etmem/test/etmem_scan_ops_llt_test/etmem_scan_ops_llt.c -index 0cd2ecc..84fcf69 100644 ---- a/etmem/test/etmem_scan_ops_llt_test/etmem_scan_ops_llt.c -+++ b/etmem/test/etmem_scan_ops_llt_test/etmem_scan_ops_llt.c -@@ -243,7 +243,7 @@ static void test_get_page_refs_valid() - - unsigned long use_rss; - -- CU_ASSERT_EQUAL(get_page_refs(vmas, pid, &page_refs, &use_rss, 0), 0); -+ CU_ASSERT_EQUAL(get_page_refs(vmas, pid, &page_refs, &use_rss, NULL), 0); - CU_ASSERT_PTR_NOT_NULL(page_refs); - CU_ASSERT_NOT_EQUAL(use_rss, 0); - -@@ -309,7 +309,7 @@ static void test_add_pg_to_mem_grade() - CU_ASSERT_EQUAL(etmemd_scan_init(), 0); - - vma = get_vmas(pid); -- CU_ASSERT_EQUAL(get_page_refs(vma, pid, &page_refs, NULL, 0), 0); -+ CU_ASSERT_EQUAL(get_page_refs(vma, pid, &page_refs, NULL, NULL), 0); - page_refs = add_page_refs_into_memory_grade(page_refs, &list); - CU_ASSERT_PTR_NOT_NULL(page_refs); - CU_ASSERT_PTR_NOT_NULL(list); --- -1.8.3.1 - diff --git a/0066-etmem-add-sysmem_threshold-and-swap_threshold-parame.patch b/0066-etmem-add-sysmem_threshold-and-swap_threshold-parame.patch deleted file mode 100644 index 5374d07..0000000 --- a/0066-etmem-add-sysmem_threshold-and-swap_threshold-parame.patch +++ /dev/null @@ -1,415 +0,0 @@ -From 9707219f4ec2b12012620a3e5cec90b61a3ca2c4 Mon Sep 17 00:00:00 2001 -From: liubo -Date: Tue, 18 Jan 2022 11:03:13 +0800 -Subject: [PATCH 16/33] etmem: add sysmem_threshold and swap_threshold - parameters to etmem - -As a memory expansion tool, etmem performs memory swap operation -for the target process by default after it is enabled. However, -in some specific scenarios, in order to obtain the ultimate -performance of the business, it is necessary to consider -the timing of memory swapping by etmem. - -Add the sysmem_threshold parameter to control the start and -stop of memory swap out when the system available memory -meets the requirements. - -Add the swap_threshold parameter to limit the absolute -value of the memory size reserved by the process in DRAM. -When the target process memory is lower than this value, do not -swap out any memory. - -Signed-off-by: liubo ---- - etmem/conf/slide_conf.yaml | 2 + - etmem/inc/etmemd_inc/etmemd_common.h | 10 +++ - etmem/inc/etmemd_inc/etmemd_project_exp.h | 1 + - etmem/inc/etmemd_inc/etmemd_slide.h | 1 + - etmem/src/etmemd_src/etmemd_common.c | 58 +++++++++++++- - etmem/src/etmemd_src/etmemd_project.c | 32 ++++++-- - etmem/src/etmemd_src/etmemd_slide.c | 123 ++++++++++++++++++++++++++++++ - 7 files changed, 220 insertions(+), 7 deletions(-) - -diff --git a/etmem/conf/slide_conf.yaml b/etmem/conf/slide_conf.yaml -index 75f0220..511d657 100644 ---- a/etmem/conf/slide_conf.yaml -+++ b/etmem/conf/slide_conf.yaml -@@ -4,6 +4,7 @@ scan_type=page - loop=1 - interval=1 - sleep=1 -+sysmem_threshold=50 - - [engine] - name=slide -@@ -17,3 +18,4 @@ type=name - value=mysql - T=1 - max_threads=1 -+swap_threshold=10g -diff --git a/etmem/inc/etmemd_inc/etmemd_common.h b/etmem/inc/etmemd_inc/etmemd_common.h -index 8d18f8a..576d38a 100644 ---- a/etmem/inc/etmemd_inc/etmemd_common.h -+++ b/etmem/inc/etmemd_inc/etmemd_common.h -@@ -21,6 +21,7 @@ - - #define PROC_PATH "/proc/" - #define STATUS_FILE "/status" -+#define PROC_MEMINFO "meminfo" - #define SWAPIN "SwapIN" - #define VMRSS "VmRSS" - #define VMSWAP "VmSwap" -@@ -30,14 +31,21 @@ - #define ETMEMD_MAX_PARAMETER_NUM 6 - #define BYTE_TO_KB(s) ((s) >> 10) - #define KB_TO_BYTE(s) ((s) << 10) -+#define CONVERT_GB_2_KB (1024 * 1024) - - #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) - - /* in some system the max length of pid may be larger than 5, so we use 10 herr */ - #define PID_STR_MAX_LEN 10 -+#define SWAP_THRESHOLD_MAX_LEN 10 - - #define PIPE_FD_LEN 2 - -+enum swap_type { -+ DONT_SWAP = 0, -+ DO_SWAP, -+}; -+ - /* - * function: parse cmdline passed to etmemd server. - * -@@ -65,4 +73,6 @@ int get_mem_from_proc_file(const char *pid, const char *file_name, unsigned long - - int dprintf_all(int fd, const char *format, ...); - -+int get_swap_threshold_inKB(char *string); -+ - #endif -diff --git a/etmem/inc/etmemd_inc/etmemd_project_exp.h b/etmem/inc/etmemd_inc/etmemd_project_exp.h -index 8740f7e..fc3c85e 100644 ---- a/etmem/inc/etmemd_inc/etmemd_project_exp.h -+++ b/etmem/inc/etmemd_inc/etmemd_project_exp.h -@@ -42,6 +42,7 @@ struct project { - char *name; - enum scan_type type; - void *scan_param; -+ int sysmem_threshold; - bool start; - struct engine *engs; - -diff --git a/etmem/inc/etmemd_inc/etmemd_slide.h b/etmem/inc/etmemd_inc/etmemd_slide.h -index 93de502..7c80502 100644 ---- a/etmem/inc/etmemd_inc/etmemd_slide.h -+++ b/etmem/inc/etmemd_inc/etmemd_slide.h -@@ -22,6 +22,7 @@ - struct slide_params { - struct task_executor *executor; - int t; /* watermark */ -+ int swap_threshold; - uint8_t dram_percent; - }; - -diff --git a/etmem/src/etmemd_src/etmemd_common.c b/etmem/src/etmemd_src/etmemd_common.c -index ebf6232..caa5826 100644 ---- a/etmem/src/etmemd_src/etmemd_common.c -+++ b/etmem/src/etmemd_src/etmemd_common.c -@@ -256,7 +256,7 @@ static char *etmemd_get_proc_file_str(const char *pid, const char *file) - char *file_name = NULL; - size_t file_str_size; - -- file_str_size = strlen(PROC_PATH) + strlen(pid) + strlen(file) + 1; -+ file_str_size = strlen(PROC_PATH) + strlen(file) + 1 + (pid == NULL ? 0 : strlen(pid)); - file_name = (char *)calloc(file_str_size, sizeof(char)); - if (file_name == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "malloc for %s path fail\n", file); -@@ -264,7 +264,7 @@ static char *etmemd_get_proc_file_str(const char *pid, const char *file) - } - - if (snprintf_s(file_name, file_str_size, file_str_size - 1, -- "%s%s%s", PROC_PATH, pid, file) == -1) { -+ "%s%s%s", PROC_PATH, pid ? pid : "", file) == -1) { - etmemd_log(ETMEMD_LOG_ERR, "snprintf for %s fail\n", file); - free(file_name); - return NULL; -@@ -495,3 +495,57 @@ unsigned long get_pagesize(void) - - return (unsigned long)pagesize; - } -+ -+int get_swap_threshold_inKB(char *string) -+{ -+ int len; -+ int i; -+ int ret = -1; -+ char *swap_threshold_string = NULL; -+ int swap_threshold_inGB; -+ int swap_threshold_inKB; -+ -+ if (string == NULL) { -+ goto out; -+ } -+ -+ len = strlen(string); -+ if (len > SWAP_THRESHOLD_MAX_LEN) { -+ etmemd_log(ETMEMD_LOG_ERR, "swap_threshold string is too long.\n"); -+ goto out; -+ } -+ -+ swap_threshold_string = (char *)calloc(len, sizeof(char)); -+ if (swap_threshold_string == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "calloc swap_threshold_string fail.\n"); -+ goto out; -+ } -+ -+ for (i = 0; i < len - 1; i++) { -+ if (isdigit(string[i])) { -+ swap_threshold_string[i] = string[i]; -+ continue; -+ } -+ etmemd_log(ETMEMD_LOG_ERR, "the swap_threshold contain wrong parameter.\n"); -+ goto free_out; -+ } -+ -+ if (string[i] != 'g' && string[i] != 'G') { -+ etmemd_log(ETMEMD_LOG_ERR, "the swap_threshold should in G or g.\n"); -+ goto free_out; -+ } -+ -+ if (get_int_value(swap_threshold_string, &swap_threshold_inGB) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get_int_value swap_threshold faild.\n"); -+ goto free_out; -+ } -+ -+ swap_threshold_inKB = swap_threshold_inGB * CONVERT_GB_2_KB; -+ ret = swap_threshold_inKB; -+ -+free_out: -+ free(swap_threshold_string); -+ -+out: -+ return ret; -+} -diff --git a/etmem/src/etmemd_src/etmemd_project.c b/etmem/src/etmemd_src/etmemd_project.c -index fa4293b..459e140 100644 ---- a/etmem/src/etmemd_src/etmemd_project.c -+++ b/etmem/src/etmemd_src/etmemd_project.c -@@ -30,12 +30,13 @@ - #include "etmemd_file.h" - #include "etmemd_log.h" - --#define MAX_INTERVAL_VALUE 1200 --#define MAX_SLEEP_VALUE 1200 --#define MAX_LOOP_VALUE 120 -+#define MAX_INTERVAL_VALUE 1200 -+#define MAX_SLEEP_VALUE 1200 -+#define MAX_LOOP_VALUE 120 -+#define MAX_SYSMEM_THRESHOLD_VALUE 100 - --#define MAX_OBJ_NAME_LEN 64 --#define MIN_NR_MIN_VAL 3 -+#define MAX_OBJ_NAME_LEN 64 -+#define MIN_NR_MIN_VAL 3 - - static SLIST_HEAD(project_list, project) g_projects = SLIST_HEAD_INITIALIZER(g_projects); - -@@ -630,9 +631,27 @@ static int fill_project_scan_type(void *obj, void *val) - return 0; - } - -+/* fill the project parameter: sysmem_threshold -+ * sysmem_threshold: [0, 100]. do not swap any memory out if system free memory is higher than sysmem_threshold */ -+static int fill_project_sysmem_threshold(void *obj, void *val) -+{ -+ struct project *proj = (struct project *)obj; -+ int sysmem_threshold = parse_to_int(val); -+ -+ if (sysmem_threshold < 0 || sysmem_threshold > MAX_SYSMEM_THRESHOLD_VALUE) { -+ etmemd_log(ETMEMD_LOG_WARN, "invaild project sysmem_threshold value %d, it must between 0 and 100.\n", -+ sysmem_threshold, MAX_SYSMEM_THRESHOLD_VALUE); -+ sysmem_threshold = -1; -+ } -+ -+ proj->sysmem_threshold = sysmem_threshold; -+ return 0; -+} -+ - static struct config_item g_project_config_items[] = { - {"name", STR_VAL, fill_project_name, false}, - {"scan_type", STR_VAL, fill_project_scan_type, false}, -+ {"sysmem_threshold", INT_VAL, fill_project_sysmem_threshold, true}, - }; - - static void clear_project(struct project *proj) -@@ -688,6 +707,9 @@ enum opt_result etmemd_project_add(GKeyFile *config) - etmemd_log(ETMEMD_LOG_ERR, "alloc memory for project fail\n"); - return OPT_INTER_ERR; - } -+ -+ proj->sysmem_threshold = -1; -+ - if (project_fill_by_conf(config, proj) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "fill project from configuration file fail\n"); - free(proj); -diff --git a/etmem/src/etmemd_src/etmemd_slide.c b/etmem/src/etmemd_src/etmemd_slide.c -index 8362224..cbc4b17 100644 ---- a/etmem/src/etmemd_src/etmemd_slide.c -+++ b/etmem/src/etmemd_src/etmemd_slide.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - - #include "securec.h" - #include "etmemd_log.h" -@@ -106,6 +107,104 @@ static int slide_do_migrate(unsigned int pid, const struct memory_grade *memory_ - return ret; - } - -+static int check_sysmem_lower_threshold(struct task_pid *tk_pid) -+{ -+ unsigned long mem_total; -+ unsigned long mem_free; -+ int vm_cmp; -+ int ret; -+ -+ ret = get_mem_from_proc_file(NULL, PROC_MEMINFO, &mem_total, "MemTotal"); -+ if (ret != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get memtotal fail\n"); -+ return DONT_SWAP; -+ } -+ -+ ret = get_mem_from_proc_file(NULL, PROC_MEMINFO, &mem_free, "MemFree"); -+ if (ret != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get memfree fail\n"); -+ return DONT_SWAP; -+ } -+ -+ /* Calculate the free memory percentage in 0 - 100 */ -+ vm_cmp = (mem_free * 100) / mem_total; -+ if (vm_cmp < tk_pid->tk->eng->proj->sysmem_threshold) { -+ return DO_SWAP; -+ } -+ -+ return DONT_SWAP; -+} -+ -+static int check_pid_should_swap(const char *pid, unsigned long vmrss, const struct task_pid *tk_pid) -+{ -+ unsigned long vmswap; -+ unsigned long vmcmp; -+ int ret; -+ -+ ret = get_mem_from_proc_file(pid, STATUS_FILE, &vmswap, "VmSwap"); -+ if (ret != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get VmSwap fail\n"); -+ return DONT_SWAP; -+ } -+ -+ /* Calculate the total amount of memory that can be swappout for the current process -+ * and check whether the memory is larger than the current swapout amount. -+ * If true, continue swap-out; otherwise, abort the swap-out process. */ -+ vmcmp = (vmrss + vmswap) / 100 * tk_pid->tk->eng->proj->sysmem_threshold; -+ if (vmcmp > vmswap) { -+ return DO_SWAP; -+ } -+ -+ return DONT_SWAP; -+} -+ -+static int check_pidmem_lower_threshold(struct task_pid *tk_pid) -+{ -+ struct slide_params *params = NULL; -+ unsigned long vmrss; -+ int ret; -+ char pid_str[PID_STR_MAX_LEN] = {0}; -+ -+ params = (struct slide_params *)tk_pid->tk->params; -+ if (params == NULL) { -+ return DONT_SWAP; -+ } -+ -+ if (snprintf_s(pid_str, PID_STR_MAX_LEN, PID_STR_MAX_LEN - 1, "%u", tk_pid->pid) <= 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "snprintf pid fail %u", tk_pid->pid); -+ return DONT_SWAP; -+ } -+ -+ ret = get_mem_from_proc_file(pid_str, STATUS_FILE, &vmrss, "VmRSS"); -+ if (ret != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get VmRSS fail\n"); -+ return DONT_SWAP; -+ } -+ -+ if (params->swap_threshold == 0) { -+ return check_pid_should_swap(pid_str, vmrss, tk_pid); -+ } -+ -+ if ((int)vmrss > params->swap_threshold) { -+ return DO_SWAP; -+ } -+ -+ return DONT_SWAP; -+} -+ -+static int check_should_swap(struct task_pid *tk_pid) -+{ -+ if (tk_pid->tk->eng->proj->sysmem_threshold == -1) { -+ return DO_SWAP; -+ } -+ -+ if (check_sysmem_lower_threshold(tk_pid) == DONT_SWAP) { -+ return DONT_SWAP; -+ } -+ -+ return check_pidmem_lower_threshold(tk_pid); -+} -+ - static void *slide_executor(void *arg) - { - struct task_pid *tk_pid = (struct task_pid *)arg; -@@ -113,6 +212,10 @@ static void *slide_executor(void *arg) - struct memory_grade *memory_grade = NULL; - struct page_sort *page_sort = NULL; - -+ if (check_should_swap(tk_pid) == DONT_SWAP) { -+ 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); -@@ -194,8 +297,28 @@ static int fill_task_dram_percent(void *obj, void *val) - return 0; - } - -+static int fill_task_swap_threshold(void *obj, void *val) -+{ -+ struct slide_params *params = (struct slide_params *)obj; -+ char *swap_threshold_string = (char *)val; -+ int swap_threshold = get_swap_threshold_inKB(swap_threshold_string); -+ -+ free(swap_threshold_string); -+ -+ if (swap_threshold < 0) { -+ etmemd_log(ETMEMD_LOG_WARN, -+ "parse swap_threshold failed.\n"); -+ return -1; -+ } -+ -+ params->swap_threshold = swap_threshold; -+ -+ return 0; -+} -+ - static struct config_item g_slide_task_config_items[] = { - {"T", INT_VAL, fill_task_threshold, false}, -+ {"swap_threshold", STR_VAL, fill_task_swap_threshold, true}, - {"dram_percent", INT_VAL, fill_task_dram_percent, true}, - }; - --- -1.8.3.1 - diff --git a/0067-etmem-add-swapcache-reclaim-to-etmem.patch b/0067-etmem-add-swapcache-reclaim-to-etmem.patch deleted file mode 100644 index 515a8f5..0000000 --- a/0067-etmem-add-swapcache-reclaim-to-etmem.patch +++ /dev/null @@ -1,552 +0,0 @@ -From 8a7c297694bfad83bdc826aea3c0fea84098a4fb Mon Sep 17 00:00:00 2001 -From: liubo -Date: Tue, 18 Jan 2022 15:21:13 +0800 -Subject: [PATCH 17/33] etmem: add swapcache reclaim to etmem - -When etmem performs the memory swap operation, it will -occupy part of the swapcache memory. To further save -memory, the swapcache memory recovery function is -added, which depends on etmem_swap.ko - -Add swapcache_high_wmark and swapcache_low_wmark field -to set the available watermark of swapcache memory. -When the swapcache memory usage is higher than high_wmark, -the swapcache memory recovery is triggered until it is less -than low wmark. - -Signed-off-by: liubo ---- - etmem/conf/slide_conf.yaml | 2 + - etmem/inc/etmemd_inc/etmemd_common.h | 50 ++++++++----- - etmem/inc/etmemd_inc/etmemd_migrate.h | 1 + - etmem/inc/etmemd_inc/etmemd_project_exp.h | 3 + - etmem/src/etmemd_src/etmemd_common.c | 48 +++++++------ - etmem/src/etmemd_src/etmemd_cslide.c | 12 +++- - etmem/src/etmemd_src/etmemd_migrate.c | 113 +++++++++++++++++++++++++++++- - etmem/src/etmemd_src/etmemd_project.c | 56 ++++++++++++++- - etmem/src/etmemd_src/etmemd_scan.c | 14 +++- - etmem/src/etmemd_src/etmemd_slide.c | 4 ++ - 10 files changed, 255 insertions(+), 48 deletions(-) - -diff --git a/etmem/conf/slide_conf.yaml b/etmem/conf/slide_conf.yaml -index 511d657..f55c508 100644 ---- a/etmem/conf/slide_conf.yaml -+++ b/etmem/conf/slide_conf.yaml -@@ -5,6 +5,8 @@ loop=1 - interval=1 - sleep=1 - sysmem_threshold=50 -+swapcache_high_wmark=10 -+swapcache_low_wmark=6 - - [engine] - name=slide -diff --git a/etmem/inc/etmemd_inc/etmemd_common.h b/etmem/inc/etmemd_inc/etmemd_common.h -index 576d38a..ced606e 100644 ---- a/etmem/inc/etmemd_inc/etmemd_common.h -+++ b/etmem/inc/etmemd_inc/etmemd_common.h -@@ -18,34 +18,47 @@ - - #include - #include -+#include - --#define PROC_PATH "/proc/" --#define STATUS_FILE "/status" --#define PROC_MEMINFO "meminfo" --#define SWAPIN "SwapIN" --#define VMRSS "VmRSS" --#define VMSWAP "VmSwap" --#define FILE_LINE_MAX_LEN 1024 --#define KEY_VALUE_MAX_LEN 64 --#define DECIMAL_RADIX 10 --#define ETMEMD_MAX_PARAMETER_NUM 6 --#define BYTE_TO_KB(s) ((s) >> 10) --#define KB_TO_BYTE(s) ((s) << 10) --#define CONVERT_GB_2_KB (1024 * 1024) -- --#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) -+#define PROC_PATH "/proc/" -+#define STATUS_FILE "/status" -+#define PROC_MEMINFO "meminfo" -+#define SWAPIN "SwapIN" -+#define VMRSS "VmRSS" -+#define VMSWAP "VmSwap" -+ -+#define FILE_LINE_MAX_LEN 1024 -+#define KEY_VALUE_MAX_LEN 64 -+#define DECIMAL_RADIX 10 -+#define ETMEMD_MAX_PARAMETER_NUM 6 -+ -+#define BYTE_TO_KB(s) ((s) >> 10) -+#define KB_TO_BYTE(s) ((s) << 10) -+#define CONVERT_GB_2_KB (1024 * 1024) -+ -+#define MAX_SWAPCACHE_WMARK_VALUE 100 -+ -+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) - - /* in some system the max length of pid may be larger than 5, so we use 10 herr */ --#define PID_STR_MAX_LEN 10 -+#define PID_STR_MAX_LEN 10 - #define SWAP_THRESHOLD_MAX_LEN 10 - --#define PIPE_FD_LEN 2 -+#define PIPE_FD_LEN 2 -+ -+#define IDLE_SCAN_MAGIC 0x66 -+#define IDLE_SCAN_ADD_FLAGS _IOW(IDLE_SCAN_MAGIC, 0x0, unsigned int) - - enum swap_type { - DONT_SWAP = 0, - DO_SWAP, - }; - -+struct ioctl_para { -+ unsigned long ioctl_cmd; -+ int ioctl_parameter; -+}; -+ - /* - * function: parse cmdline passed to etmemd server. - * -@@ -65,7 +78,8 @@ int get_unsigned_int_value(const char *val, unsigned int *value); - int get_unsigned_long_value(const char *val, unsigned long *value); - void etmemd_safe_free(void **ptr); - --FILE *etmemd_get_proc_file(const char *pid, const char *file, int flags, const char *mode); -+FILE *etmemd_get_proc_file(const char *pid, const char *file, const char *mode); -+int etmemd_send_ioctl_cmd(FILE *fp, struct ioctl_para *request); - - int get_keyword_and_value(const char *str, char *key, char *val); - unsigned long get_pagesize(void); -diff --git a/etmem/inc/etmemd_inc/etmemd_migrate.h b/etmem/inc/etmemd_inc/etmemd_migrate.h -index ef20bde..f8eb621 100644 ---- a/etmem/inc/etmemd_inc/etmemd_migrate.h -+++ b/etmem/inc/etmemd_inc/etmemd_migrate.h -@@ -27,5 +27,6 @@ - #define SWAP_ADDR_LEN 20 - - int etmemd_grade_migrate(const char* pid, const struct memory_grade *memory_grade); -+int etmemd_reclaim_swapcache(const struct task_pid *tk_pid); - unsigned long check_should_migrate(const struct task_pid *tk_pid); - #endif -diff --git a/etmem/inc/etmemd_inc/etmemd_project_exp.h b/etmem/inc/etmemd_inc/etmemd_project_exp.h -index fc3c85e..2fe8d90 100644 ---- a/etmem/inc/etmemd_inc/etmemd_project_exp.h -+++ b/etmem/inc/etmemd_inc/etmemd_project_exp.h -@@ -43,7 +43,10 @@ struct project { - enum scan_type type; - void *scan_param; - int sysmem_threshold; -+ int swapcache_high_wmark; -+ int swapcache_low_wmark; - bool start; -+ bool wmark_set; - struct engine *engs; - - SLIST_ENTRY(project) entry; -diff --git a/etmem/src/etmemd_src/etmemd_common.c b/etmem/src/etmemd_src/etmemd_common.c -index caa5826..bb72fd0 100644 ---- a/etmem/src/etmemd_src/etmemd_common.c -+++ b/etmem/src/etmemd_src/etmemd_common.c -@@ -32,9 +32,6 @@ - #include "etmemd_rpc.h" - #include "etmemd_log.h" - --#define IDLE_SCAN_MAGIC 0x66 --#define IDLE_SCAN_ADD_FLAGS _IOW(IDLE_SCAN_MAGIC, 0x0, unsigned int) -- - static void usage(void) - { - printf("\nusage of etmemd:\n" -@@ -273,10 +270,32 @@ static char *etmemd_get_proc_file_str(const char *pid, const char *file) - return file_name; - } - --FILE *etmemd_get_proc_file(const char *pid, const char *file, int flags, const char *mode) -+int etmemd_send_ioctl_cmd(FILE *fp, struct ioctl_para *request) - { -- char *file_name = NULL; - int fd = -1; -+ -+ if (fp == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "send ioctl cmd fail, fp is null\n"); -+ return -1; -+ } -+ -+ fd = fileno(fp); -+ if (fd < 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "send ioctl cmd fail, get fd fail\n"); -+ return -1; -+ } -+ -+ if (request == NULL || ioctl(fd, request->ioctl_cmd, &request->ioctl_parameter) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "send ioctl cmd fail, request is wrong\n"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+FILE *etmemd_get_proc_file(const char *pid, const char *file, const char *mode) -+{ -+ char *file_name = NULL; - FILE *fp = NULL; - - file_name = etmemd_get_proc_file_str(pid, file); -@@ -287,25 +306,8 @@ FILE *etmemd_get_proc_file(const char *pid, const char *file, int flags, const c - fp = fopen(file_name, mode); - if (fp == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "open file %s fail\n", file_name); -- goto free_file_name; -- } -- -- fd = fileno(fp); -- if (fd < 0) { -- etmemd_log(ETMEMD_LOG_ERR, "get fd of file %s fail\n", file_name); -- fclose(fp); -- fp = NULL; -- goto free_file_name; -- } -- -- if (flags != 0 && ioctl(fd, IDLE_SCAN_ADD_FLAGS, &flags) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "set idle flags for %s fail with %s\n", pid, strerror(errno)); -- fclose(fp); -- fp = NULL; -- goto free_file_name; - } - --free_file_name: - free(file_name); - return fp; - } -@@ -453,7 +455,7 @@ int get_mem_from_proc_file(const char *pid, const char *file_name, unsigned long - unsigned long val; - int ret = -1; - -- file = etmemd_get_proc_file(pid, file_name, 0, "r"); -+ file = etmemd_get_proc_file(pid, file_name, "r"); - if (file == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "cannot open %s for pid %s\n", file_name, pid); - return ret; -diff --git a/etmem/src/etmemd_src/etmemd_cslide.c b/etmem/src/etmemd_src/etmemd_cslide.c -index b3d1637..cbaa2e8 100644 ---- a/etmem/src/etmemd_src/etmemd_cslide.c -+++ b/etmem/src/etmemd_src/etmemd_cslide.c -@@ -1280,18 +1280,28 @@ static int cslide_scan_vmas(struct cslide_pid_params *params) - uint64_t i; - int fd; - struct cslide_task_params *task_params = params->task_params; -+ struct ioctl_para ioctl_para = { -+ .ioctl_cmd = IDLE_SCAN_ADD_FLAGS, -+ .ioctl_parameter = task_params->scan_flags, -+ }; - - if (snprintf_s(pid, PID_STR_MAX_LEN, PID_STR_MAX_LEN - 1, "%u", params->pid) <= 0) { - etmemd_log(ETMEMD_LOG_ERR, "snpintf pid %u fail\n", params->pid); - return -1; - } - -- scan_fp = etmemd_get_proc_file(pid, IDLE_SCAN_FILE, task_params->scan_flags, "r"); -+ scan_fp = etmemd_get_proc_file(pid, IDLE_SCAN_FILE, "r"); - if (scan_fp == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "open %s file for pid %u fail\n", IDLE_SCAN_FILE, params->pid); - return -1; - } - -+ if (task_params->scan_flags != 0 && etmemd_send_ioctl_cmd(scan_fp, &ioctl_para) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "etmemd send_ioctl_cmd %s file for pid %u fail\n", IDLE_SCAN_FILE, params->pid); -+ fclose(scan_fp); -+ return -1; -+ } -+ - fd = fileno(scan_fp); - if (fd == -1) { - fclose(scan_fp); -diff --git a/etmem/src/etmemd_src/etmemd_migrate.c b/etmem/src/etmemd_src/etmemd_migrate.c -index 639d570..87bfde0 100644 ---- a/etmem/src/etmemd_src/etmemd_migrate.c -+++ b/etmem/src/etmemd_src/etmemd_migrate.c -@@ -15,14 +15,24 @@ - - #include - #include -+#include -+#include -+#include -+#include -+#include - - #include "securec.h" - #include "etmemd.h" - #include "etmemd_migrate.h" -+#include "etmemd_project.h" - #include "etmemd_common.h" - #include "etmemd_slide.h" - #include "etmemd_log.h" - -+#define RECLAIM_SWAPCACHE_MAGIC 0x77 -+#define RECLAIM_SWAPCACHE_ON _IOW(RECLAIM_SWAPCACHE_MAGIC, 0x1, unsigned int) -+#define SET_SWAPCACHE_WMARK _IOW(RECLAIM_SWAPCACHE_MAGIC, 0x2, unsigned int) -+ - static char *get_swap_string(struct page_refs **page_refs, int batchsize) - { - char *swap_str = NULL; -@@ -70,7 +80,7 @@ static int etmemd_migrate_mem(const char *pid, const char *grade_path, struct pa - return 0; - } - -- fp = etmemd_get_proc_file(pid, grade_path, 0, "r+"); -+ fp = etmemd_get_proc_file(pid, grade_path, "r+"); - if (fp == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "cannot open %s for pid %s\n", grade_path, pid); - return -1; -@@ -98,6 +108,107 @@ static int etmemd_migrate_mem(const char *pid, const char *grade_path, struct pa - return 0; - } - -+static bool check_should_reclaim_swapcache(const struct task_pid *tk_pid) -+{ -+ struct project *proj = tk_pid->tk->eng->proj; -+ unsigned long mem_total; -+ unsigned long swapcache_total; -+ int ret; -+ -+ if (proj->swapcache_high_wmark == 0) { -+ return false; -+ } -+ -+ ret = get_mem_from_proc_file(NULL, PROC_MEMINFO, &mem_total, "MemTotal"); -+ if (ret != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get memtotal fail\n"); -+ return false; -+ } -+ -+ ret = get_mem_from_proc_file(NULL, PROC_MEMINFO, &swapcache_total, "SwapCached"); -+ if (ret != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get swapcache_total fail\n"); -+ return false; -+ } -+ -+ if ((swapcache_total / proj->swapcache_high_wmark) <= (mem_total / MAX_SWAPCACHE_WMARK_VALUE)) { -+ return false; -+ } -+ -+ return true; -+} -+ -+static int set_swapcache_wmark(const struct task_pid *tk_pid, const char *pid_str) -+{ -+ int swapcache_wmark; -+ struct project *proj = tk_pid->tk->eng->proj; -+ FILE *fp = NULL; -+ struct ioctl_para ioctl_para = { -+ .ioctl_cmd = SET_SWAPCACHE_WMARK, -+ }; -+ -+ swapcache_wmark = (proj->swapcache_low_wmark & 0x00ff) | (proj->swapcache_high_wmark << 8 & 0xff00); -+ ioctl_para.ioctl_parameter = swapcache_wmark; -+ -+ fp = etmemd_get_proc_file(pid_str, COLD_PAGE, "r+"); -+ if (fp == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "get proc file %s failed.\n", COLD_PAGE); -+ return -1; -+ } -+ -+ if (etmemd_send_ioctl_cmd(fp, &ioctl_para) != 0) { -+ fclose(fp); -+ etmemd_log(ETMEMD_LOG_ERR, "set_swapcache_wmark for pid %u fail\n", tk_pid->pid); -+ return -1; -+ } -+ -+ fclose(fp); -+ return 0; -+} -+ -+int etmemd_reclaim_swapcache(const struct task_pid *tk_pid) -+{ -+ char pid_str[PID_STR_MAX_LEN] = {0}; -+ FILE *fp = NULL; -+ struct ioctl_para ioctl_para = { -+ .ioctl_cmd = RECLAIM_SWAPCACHE_ON, -+ .ioctl_parameter = 0, -+ }; -+ -+ if (tk_pid == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "tk_pid is null.\n"); -+ return -1; -+ } -+ -+ if (!check_should_reclaim_swapcache(tk_pid)) { -+ return 0; -+ } -+ -+ if (snprintf_s(pid_str, PID_STR_MAX_LEN, PID_STR_MAX_LEN - 1, "%u", tk_pid->pid) <= 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "snprintf pid fail %u", tk_pid->pid); -+ return -1; -+ } -+ -+ if (!tk_pid->tk->eng->proj->wmark_set) { -+ set_swapcache_wmark(tk_pid, pid_str); -+ tk_pid->tk->eng->proj->wmark_set = true; -+ } -+ -+ fp = etmemd_get_proc_file(pid_str, COLD_PAGE, "r+"); -+ if (fp == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "get proc file %s fail.\n", COLD_PAGE); -+ return -1; -+ } -+ -+ if (etmemd_send_ioctl_cmd(fp, &ioctl_para) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "etmemd_reclaim_swapcache fail\n"); -+ fclose(fp); -+ return -1; -+ } -+ -+ fclose(fp); -+ return 0; -+} - - int etmemd_grade_migrate(const char *pid, const struct memory_grade *memory_grade) - { -diff --git a/etmem/src/etmemd_src/etmemd_project.c b/etmem/src/etmemd_src/etmemd_project.c -index 459e140..72d7335 100644 ---- a/etmem/src/etmemd_src/etmemd_project.c -+++ b/etmem/src/etmemd_src/etmemd_project.c -@@ -639,19 +639,64 @@ static int fill_project_sysmem_threshold(void *obj, void *val) - int sysmem_threshold = parse_to_int(val); - - if (sysmem_threshold < 0 || sysmem_threshold > MAX_SYSMEM_THRESHOLD_VALUE) { -- etmemd_log(ETMEMD_LOG_WARN, "invaild project sysmem_threshold value %d, it must between 0 and 100.\n", -- sysmem_threshold, MAX_SYSMEM_THRESHOLD_VALUE); -- sysmem_threshold = -1; -+ etmemd_log(ETMEMD_LOG_ERR, "invaild project sysmem_threshold value %d, it must between 0 and 100.\n", -+ sysmem_threshold); -+ return -1; - } - - proj->sysmem_threshold = sysmem_threshold; - return 0; - } - -+/* fill the project parameter: swapcache_low_wmark -+ * swapcache_low_wmark: [0, 100]. */ -+static int fill_project_swapcache_low_wmark(void *obj, void *val) -+{ -+ struct project *proj = (struct project *)obj; -+ int swapcache_low_wmark = parse_to_int(val); -+ -+ if (swapcache_low_wmark < 0 || swapcache_low_wmark > MAX_SWAPCACHE_WMARK_VALUE) { -+ etmemd_log(ETMEMD_LOG_ERR, "invaild project swapcache_low_wmark value %d, it must between 0 and 100.\n", -+ swapcache_low_wmark); -+ return -1; -+ } -+ -+ proj->swapcache_low_wmark = swapcache_low_wmark; -+ return 0; -+} -+ -+/* fill the project parameter: swapcache_high_wmark -+ * swapcache_high_wmark: (0, 100]. */ -+static int fill_project_swapcache_high_wmark(void *obj, void *val) -+{ -+ struct project *proj = (struct project *)obj; -+ int swapcache_high_wmark = parse_to_int(val); -+ -+ if (swapcache_high_wmark < 0 || swapcache_high_wmark > MAX_SWAPCACHE_WMARK_VALUE) { -+ etmemd_log(ETMEMD_LOG_ERR, "invaild project swapcache_high_wmark value %d, it must between 0 and 100.\n", -+ swapcache_high_wmark); -+ return -1; -+ } -+ -+ proj->swapcache_high_wmark = swapcache_high_wmark; -+ return 0; -+} -+ -+static bool check_swapcache_wmark_valid(struct project *proj) -+{ -+ if (proj->swapcache_low_wmark > proj->swapcache_high_wmark) { -+ return false; -+ } -+ -+ return true; -+} -+ - static struct config_item g_project_config_items[] = { - {"name", STR_VAL, fill_project_name, false}, - {"scan_type", STR_VAL, fill_project_scan_type, false}, - {"sysmem_threshold", INT_VAL, fill_project_sysmem_threshold, true}, -+ {"swapcache_high_wmark", INT_VAL, fill_project_swapcache_high_wmark, true}, -+ {"swapcache_low_wmark", INT_VAL, fill_project_swapcache_low_wmark, true}, - }; - - static void clear_project(struct project *proj) -@@ -675,6 +720,11 @@ static int project_fill_by_conf(GKeyFile *config, struct project *proj) - return -1; - } - -+ if (!check_swapcache_wmark_valid(proj)) { -+ etmemd_log(ETMEMD_LOG_ERR, "swapcache wmark is not valid, low wmark: %d, high wmark: %d", -+ proj->swapcache_low_wmark, proj->swapcache_high_wmark); -+ return -1; -+ } - return 0; - } - -diff --git a/etmem/src/etmemd_src/etmemd_scan.c b/etmem/src/etmemd_src/etmemd_scan.c -index 3ee018e..a1f8cdc 100644 ---- a/etmem/src/etmemd_src/etmemd_scan.c -+++ b/etmem/src/etmemd_src/etmemd_scan.c -@@ -359,7 +359,7 @@ struct vmas *get_vmas_with_flags(const char *pid, char *vmflags_array[], int vmf - return NULL; - } - -- fp = etmemd_get_proc_file(pid, maps_file, 0, "r"); -+ fp = etmemd_get_proc_file(pid, maps_file, "r"); - if (fp == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "open %s file of %s fail\n", maps_file, pid); - free(ret_vmas); -@@ -680,13 +680,23 @@ int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **p - struct vma *vma = vmas->vma_list; - struct page_refs **tmp_page_refs = NULL; - struct walk_address walk_address = {0, 0, 0}; -+ struct ioctl_para ioctl_para = { -+ .ioctl_cmd = IDLE_SCAN_ADD_FLAGS, -+ .ioctl_parameter = flags, -+ }; - -- scan_fp = etmemd_get_proc_file(pid, IDLE_SCAN_FILE, flags, "r"); -+ scan_fp = etmemd_get_proc_file(pid, IDLE_SCAN_FILE, "r"); - if (scan_fp == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "open %s file fail\n", IDLE_SCAN_FILE); - return -1; - } - -+ if (flags != 0 && etmemd_send_ioctl_cmd(scan_fp, &ioctl_para) != 0) { -+ fclose(scan_fp); -+ etmemd_log(ETMEMD_LOG_ERR, "etmemd_send_ioctl_cmd %s file for pid %s fail\n", IDLE_SCAN_FILE, pid); -+ return -1; -+ } -+ - fd = fileno(scan_fp); - if (fd == -1) { - etmemd_log(ETMEMD_LOG_ERR, "fileno file fail\n"); -diff --git a/etmem/src/etmemd_src/etmemd_slide.c b/etmem/src/etmemd_src/etmemd_slide.c -index cbc4b17..c478fbd 100644 ---- a/etmem/src/etmemd_src/etmemd_slide.c -+++ b/etmem/src/etmemd_src/etmemd_slide.c -@@ -256,6 +256,10 @@ scan_out: - etmemd_log(ETMEMD_LOG_DEBUG, "slide migrate for pid %u fail\n", tk_pid->pid); - } - -+ if (etmemd_reclaim_swapcache(tk_pid) != 0) { -+ etmemd_log(ETMEMD_LOG_DEBUG, "etmemd_reclaim_swapcache pid %u fail\n", tk_pid->pid); -+ } -+ - exit: - /* clean memory_grade here */ - pthread_cleanup_pop(1); --- -1.8.3.1 - diff --git a/0068-etmem-add-swap-flag-to-support-specified-page-swap-o.patch b/0068-etmem-add-swap-flag-to-support-specified-page-swap-o.patch deleted file mode 100644 index 5d37fcd..0000000 --- a/0068-etmem-add-swap-flag-to-support-specified-page-swap-o.patch +++ /dev/null @@ -1,434 +0,0 @@ -From d6e4942b34bbcbfaec8b0d4702f0e385f8d267f1 Mon Sep 17 00:00:00 2001 -From: liubo -Date: Tue, 18 Jan 2022 15:55:29 +0800 -Subject: [PATCH 18/33] etmem: add swap flag to support specified page swap out - -The existing memory expansion tool etmem swaps out -all pages that can be swapped out for the process by -default, unless the page is marked with lock flag. - -The function of swapping out specified pages is add. -The process adds special flag for pages to be swapped -out. This function depends on etmem_scan module. - -Added swap_flag field to indicate that a tagged swap -out is used for this process instead of the default -swap out. - -Signed-off-by: liubo ---- - etmem/conf/slide_conf.yaml | 1 + - etmem/inc/etmemd_inc/etmemd_common.h | 14 +++----------- - etmem/inc/etmemd_inc/etmemd_scan.h | 9 +++++++-- - etmem/inc/etmemd_inc/etmemd_scan_exp.h | 1 + - etmem/inc/etmemd_inc/etmemd_slide.h | 7 ++++++- - etmem/inc/etmemd_inc/etmemd_task_exp.h | 1 + - etmem/src/etmemd_src/etmemd_common.c | 34 +++++++++++++++++++--------------- - etmem/src/etmemd_src/etmemd_migrate.c | 8 ++++++-- - etmem/src/etmemd_src/etmemd_scan.c | 24 ++++++++++++++++-------- - etmem/src/etmemd_src/etmemd_slide.c | 12 ++++++------ - etmem/src/etmemd_src/etmemd_task.c | 23 +++++++++++++++++++++++ - 11 files changed, 89 insertions(+), 45 deletions(-) - -diff --git a/etmem/conf/slide_conf.yaml b/etmem/conf/slide_conf.yaml -index f55c508..8169b7d 100644 ---- a/etmem/conf/slide_conf.yaml -+++ b/etmem/conf/slide_conf.yaml -@@ -21,3 +21,4 @@ value=mysql - T=1 - max_threads=1 - swap_threshold=10g -+swap_flag=yes -diff --git a/etmem/inc/etmemd_inc/etmemd_common.h b/etmem/inc/etmemd_inc/etmemd_common.h -index ced606e..03792a7 100644 ---- a/etmem/inc/etmemd_inc/etmemd_common.h -+++ b/etmem/inc/etmemd_inc/etmemd_common.h -@@ -34,7 +34,7 @@ - - #define BYTE_TO_KB(s) ((s) >> 10) - #define KB_TO_BYTE(s) ((s) << 10) --#define CONVERT_GB_2_KB (1024 * 1024) -+#define GB_TO_KB(s) ((s) << 20) - - #define MAX_SWAPCACHE_WMARK_VALUE 100 - -@@ -46,17 +46,9 @@ - - #define PIPE_FD_LEN 2 - --#define IDLE_SCAN_MAGIC 0x66 --#define IDLE_SCAN_ADD_FLAGS _IOW(IDLE_SCAN_MAGIC, 0x0, unsigned int) -- --enum swap_type { -- DONT_SWAP = 0, -- DO_SWAP, --}; -- - struct ioctl_para { - unsigned long ioctl_cmd; -- int ioctl_parameter; -+ unsigned int ioctl_parameter; - }; - - /* -@@ -87,6 +79,6 @@ int get_mem_from_proc_file(const char *pid, const char *file_name, unsigned long - - int dprintf_all(int fd, const char *format, ...); - --int get_swap_threshold_inKB(char *string); -+int get_swap_threshold_inKB(const char *string, unsigned long *value); - - #endif -diff --git a/etmem/inc/etmemd_inc/etmemd_scan.h b/etmem/inc/etmemd_inc/etmemd_scan.h -index 9e5bcc4..7c25152 100644 ---- a/etmem/inc/etmemd_inc/etmemd_scan.h -+++ b/etmem/inc/etmemd_inc/etmemd_scan.h -@@ -20,6 +20,7 @@ - #include "etmemd.h" - #include "etmemd_task.h" - #include "etmemd_scan_exp.h" -+#include "etmemd_common.h" - - #define VMA_SEG_CNT_MAX 6 - #define VMA_PERMS_STR_LEN 5 -@@ -34,7 +35,10 @@ - #define SMAPS_FILE "/smaps" - #define VMFLAG_HEAD "VmFlags" - --#define ALL_SCAN_FLAGS (SCAN_AS_HUGE | SCAN_IGN_HOST) -+#define IDLE_SCAN_MAGIC 0x66 -+#define IDLE_SCAN_ADD_FLAGS _IOW(IDLE_SCAN_MAGIC, 0x0, unsigned int) -+#define VMA_SCAN_ADD_FLAGS _IOW(IDLE_SCAN_MAGIC, 0x2, unsigned int) -+#define ALL_SCAN_FLAGS (SCAN_AS_HUGE | SCAN_IGN_HOST | VMA_SCAN_FLAG) - - enum page_idle_type { - PTE_ACCESS = 0, /* 4k page */ -@@ -70,7 +74,8 @@ struct page_refs *etmemd_do_scan(const struct task_pid *tpid, const struct task - void free_vmas(struct vmas *vmas); - - struct page_refs **walk_vmas(int fd, struct walk_address *walk_address, struct page_refs **pf, unsigned long *use_rss); --int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **page_refs, unsigned long *use_rss, int flags); -+int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **page_refs, -+ unsigned long *use_rss, struct ioctl_para *ioctl_para); - - int split_vmflags(char ***vmflags_array, char *vmflags); - struct vmas *get_vmas_with_flags(const char *pid, char **vmflags_array, int vmflags_num, bool is_anon_only); -diff --git a/etmem/inc/etmemd_inc/etmemd_scan_exp.h b/etmem/inc/etmemd_inc/etmemd_scan_exp.h -index 1fd4379..7be925c 100644 ---- a/etmem/inc/etmemd_inc/etmemd_scan_exp.h -+++ b/etmem/inc/etmemd_inc/etmemd_scan_exp.h -@@ -25,6 +25,7 @@ - - #define SCAN_AS_HUGE 0100000000 /* treat normal vm page as vm hugepage */ - #define SCAN_IGN_HOST 0200000000 /* ignore host access when scan vm */ -+#define VMA_SCAN_FLAG 0x1000 /* scan the specifics vma with flag */ - - enum { - VMA_STAT_READ = 0, -diff --git a/etmem/inc/etmemd_inc/etmemd_slide.h b/etmem/inc/etmemd_inc/etmemd_slide.h -index 7c80502..726c721 100644 ---- a/etmem/inc/etmemd_inc/etmemd_slide.h -+++ b/etmem/inc/etmemd_inc/etmemd_slide.h -@@ -22,10 +22,15 @@ - struct slide_params { - struct task_executor *executor; - int t; /* watermark */ -- int swap_threshold; -+ unsigned long swap_threshold; - uint8_t dram_percent; - }; - -+enum swap_type { -+ DONT_SWAP = 0, -+ DO_SWAP, -+}; -+ - int fill_engine_type_slide(struct engine *eng, GKeyFile *config); - - #endif -diff --git a/etmem/inc/etmemd_inc/etmemd_task_exp.h b/etmem/inc/etmemd_inc/etmemd_task_exp.h -index 33d505a..6f775b6 100644 ---- a/etmem/inc/etmemd_inc/etmemd_task_exp.h -+++ b/etmem/inc/etmemd_inc/etmemd_task_exp.h -@@ -29,6 +29,7 @@ struct task { - char *value; - char *name; - int max_threads; -+ int swap_flag; - - struct task_pid *pids; - struct engine *eng; -diff --git a/etmem/src/etmemd_src/etmemd_common.c b/etmem/src/etmemd_src/etmemd_common.c -index bb72fd0..dfbae6d 100644 ---- a/etmem/src/etmemd_src/etmemd_common.c -+++ b/etmem/src/etmemd_src/etmemd_common.c -@@ -261,7 +261,7 @@ static char *etmemd_get_proc_file_str(const char *pid, const char *file) - } - - if (snprintf_s(file_name, file_str_size, file_str_size - 1, -- "%s%s%s", PROC_PATH, pid ? pid : "", file) == -1) { -+ "%s%s%s", PROC_PATH, pid == NULL ? "" : pid, file) == -1) { - etmemd_log(ETMEMD_LOG_ERR, "snprintf for %s fail\n", file); - free(file_name); - return NULL; -@@ -274,8 +274,8 @@ int etmemd_send_ioctl_cmd(FILE *fp, struct ioctl_para *request) - { - int fd = -1; - -- if (fp == NULL) { -- etmemd_log(ETMEMD_LOG_ERR, "send ioctl cmd fail, fp is null\n"); -+ if (fp == NULL || request == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "send ioctl cmd fail, para is null\n"); - return -1; - } - -@@ -285,8 +285,8 @@ int etmemd_send_ioctl_cmd(FILE *fp, struct ioctl_para *request) - return -1; - } - -- if (request == NULL || ioctl(fd, request->ioctl_cmd, &request->ioctl_parameter) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "send ioctl cmd fail, request is wrong\n"); -+ if (ioctl(fd, request->ioctl_cmd, &request->ioctl_parameter) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "ioctl failed\n"); - return -1; - } - -@@ -298,6 +298,11 @@ FILE *etmemd_get_proc_file(const char *pid, const char *file, const char *mode) - char *file_name = NULL; - FILE *fp = NULL; - -+ if (file == NULL) { -+ etmemd_log(ETMEMD_LOG_ERR, "etmemd_get_proc_file file should not be NULL\n"); -+ return NULL; -+ } -+ - file_name = etmemd_get_proc_file_str(pid, file); - if (file_name == NULL) { - return NULL; -@@ -498,22 +503,21 @@ unsigned long get_pagesize(void) - return (unsigned long)pagesize; - } - --int get_swap_threshold_inKB(char *string) -+int get_swap_threshold_inKB(const char *string, unsigned long *value) - { - int len; - int i; - int ret = -1; - char *swap_threshold_string = NULL; -- int swap_threshold_inGB; -- int swap_threshold_inKB; -+ unsigned long swap_threshold_inGB; - -- if (string == NULL) { -+ if (string == NULL || value == NULL) { - goto out; - } - - len = strlen(string); -- if (len > SWAP_THRESHOLD_MAX_LEN) { -- etmemd_log(ETMEMD_LOG_ERR, "swap_threshold string is too long.\n"); -+ if (len == 0 || len > SWAP_THRESHOLD_MAX_LEN) { -+ etmemd_log(ETMEMD_LOG_ERR, "swap_threshold string is invalid.\n"); - goto out; - } - -@@ -537,13 +541,13 @@ int get_swap_threshold_inKB(char *string) - goto free_out; - } - -- if (get_int_value(swap_threshold_string, &swap_threshold_inGB) != 0) { -- etmemd_log(ETMEMD_LOG_ERR, "get_int_value swap_threshold faild.\n"); -+ if (get_unsigned_long_value(swap_threshold_string, &swap_threshold_inGB) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "get_unsigned_long_value swap_threshold faild.\n"); - goto free_out; - } - -- swap_threshold_inKB = swap_threshold_inGB * CONVERT_GB_2_KB; -- ret = swap_threshold_inKB; -+ *value = GB_TO_KB(swap_threshold_inGB); -+ ret = 0; - - free_out: - free(swap_threshold_string); -diff --git a/etmem/src/etmemd_src/etmemd_migrate.c b/etmem/src/etmemd_src/etmemd_migrate.c -index 87bfde0..a5cce41 100644 ---- a/etmem/src/etmemd_src/etmemd_migrate.c -+++ b/etmem/src/etmemd_src/etmemd_migrate.c -@@ -131,7 +131,8 @@ static bool check_should_reclaim_swapcache(const struct task_pid *tk_pid) - return false; - } - -- if ((swapcache_total / proj->swapcache_high_wmark) <= (mem_total / MAX_SWAPCACHE_WMARK_VALUE)) { -+ if (swapcache_total == 0 || -+ (mem_total / swapcache_total) >= (unsigned long)(MAX_SWAPCACHE_WMARK_VALUE / proj->swapcache_high_wmark)) { - return false; - } - -@@ -190,7 +191,10 @@ int etmemd_reclaim_swapcache(const struct task_pid *tk_pid) - } - - if (!tk_pid->tk->eng->proj->wmark_set) { -- set_swapcache_wmark(tk_pid, pid_str); -+ if (set_swapcache_wmark(tk_pid, pid_str) != 0) { -+ etmemd_log(ETMEMD_LOG_ERR, "set_swapcache_wmark for pid %u fail\n", tk_pid->pid); -+ return -1; -+ } - tk_pid->tk->eng->proj->wmark_set = true; - } - -diff --git a/etmem/src/etmemd_src/etmemd_scan.c b/etmem/src/etmemd_src/etmemd_scan.c -index a1f8cdc..e06ba92 100644 ---- a/etmem/src/etmemd_src/etmemd_scan.c -+++ b/etmem/src/etmemd_src/etmemd_scan.c -@@ -672,7 +672,8 @@ struct page_refs **walk_vmas(int fd, - * this parameter is used only in the dynamic engine to calculate the swap-in rate. - * In other policies, NULL can be directly transmitted. - * */ --int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **page_refs, unsigned long *use_rss, int flags) -+int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **page_refs, -+ unsigned long *use_rss, struct ioctl_para *ioctl_para) - { - u_int64_t i; - FILE *scan_fp = NULL; -@@ -680,10 +681,6 @@ int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **p - struct vma *vma = vmas->vma_list; - struct page_refs **tmp_page_refs = NULL; - struct walk_address walk_address = {0, 0, 0}; -- struct ioctl_para ioctl_para = { -- .ioctl_cmd = IDLE_SCAN_ADD_FLAGS, -- .ioctl_parameter = flags, -- }; - - scan_fp = etmemd_get_proc_file(pid, IDLE_SCAN_FILE, "r"); - if (scan_fp == NULL) { -@@ -691,7 +688,8 @@ int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **p - return -1; - } - -- if (flags != 0 && etmemd_send_ioctl_cmd(scan_fp, &ioctl_para) != 0) { -+ if (ioctl_para != NULL && ioctl_para->ioctl_parameter != 0 -+ && etmemd_send_ioctl_cmd(scan_fp, ioctl_para) != 0) { - fclose(scan_fp); - etmemd_log(ETMEMD_LOG_ERR, "etmemd_send_ioctl_cmd %s file for pid %s fail\n", IDLE_SCAN_FILE, pid); - return -1; -@@ -734,6 +732,7 @@ int get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **p - - int etmemd_get_page_refs(const struct vmas *vmas, const char *pid, struct page_refs **page_refs, int flags) - { -+ struct ioctl_para ioctl_para; - if (!g_exp_scan_inited) { - etmemd_log(ETMEMD_LOG_ERR, "scan module is not inited before etmemd_get_page_refs\n"); - return -1; -@@ -744,7 +743,10 @@ int etmemd_get_page_refs(const struct vmas *vmas, const char *pid, struct page_r - return -1; - } - -- return get_page_refs(vmas, pid, page_refs, NULL, flags & ALL_SCAN_FLAGS); -+ ioctl_para.ioctl_parameter = flags & ALL_SCAN_FLAGS; -+ ioctl_para.ioctl_cmd = IDLE_SCAN_ADD_FLAGS; -+ -+ return get_page_refs(vmas, pid, page_refs, NULL, &ioctl_para); - } - - void etmemd_free_page_refs(struct page_refs *pf) -@@ -765,6 +767,7 @@ struct page_refs *etmemd_do_scan(const struct task_pid *tpid, const struct task - struct page_refs *page_refs = NULL; - int ret; - char pid[PID_STR_MAX_LEN] = {0}; -+ struct ioctl_para ioctl_para = {0}; - - if (tk == NULL) { - etmemd_log(ETMEMD_LOG_ERR, "task struct is null for pid %u\n", tpid->pid); -@@ -785,9 +788,14 @@ struct page_refs *etmemd_do_scan(const struct task_pid *tpid, const struct task - return NULL; - } - -+ ioctl_para.ioctl_cmd = VMA_SCAN_ADD_FLAGS; -+ if (tk->swap_flag != 0) { -+ ioctl_para.ioctl_parameter = VMA_SCAN_FLAG; -+ } -+ - /* loop for scanning idle_pages to get result of memory access. */ - for (i = 0; i < page_scan->loop; i++) { -- ret = get_page_refs(vmas, pid, &page_refs, NULL, 0); -+ ret = get_page_refs(vmas, pid, &page_refs, NULL, &ioctl_para); - if (ret != 0) { - etmemd_log(ETMEMD_LOG_ERR, "scan operation failed\n"); - /* free page_refs nodes already exist */ -diff --git a/etmem/src/etmemd_src/etmemd_slide.c b/etmem/src/etmemd_src/etmemd_slide.c -index c478fbd..236778a 100644 ---- a/etmem/src/etmemd_src/etmemd_slide.c -+++ b/etmem/src/etmemd_src/etmemd_slide.c -@@ -185,7 +185,7 @@ static int check_pidmem_lower_threshold(struct task_pid *tk_pid) - return check_pid_should_swap(pid_str, vmrss, tk_pid); - } - -- if ((int)vmrss > params->swap_threshold) { -+ if (vmrss > params->swap_threshold) { - return DO_SWAP; - } - -@@ -305,16 +305,16 @@ static int fill_task_swap_threshold(void *obj, void *val) - { - struct slide_params *params = (struct slide_params *)obj; - char *swap_threshold_string = (char *)val; -- int swap_threshold = get_swap_threshold_inKB(swap_threshold_string); -+ unsigned long swap_threshold; - -- free(swap_threshold_string); -- -- if (swap_threshold < 0) { -+ if (get_swap_threshold_inKB(swap_threshold_string, &swap_threshold) != 0) { - etmemd_log(ETMEMD_LOG_WARN, - "parse swap_threshold failed.\n"); -+ free(swap_threshold_string); - return -1; - } -- -+ -+ free(swap_threshold_string); - params->swap_threshold = swap_threshold; - - return 0; -diff --git a/etmem/src/etmemd_src/etmemd_task.c b/etmem/src/etmemd_src/etmemd_task.c -index 618245e..2a8cb3e 100644 ---- a/etmem/src/etmemd_src/etmemd_task.c -+++ b/etmem/src/etmemd_src/etmemd_task.c -@@ -470,10 +470,33 @@ static int fill_task_threads(void *obj, void *val) - return 0; - } - -+static int fill_task_swap_flag(void *obj, void *val) -+{ -+ struct task *tk = (struct task *)obj; -+ char *swap_flag = (char *)val; -+ -+ if (strcmp(swap_flag, "yes") == 0) { -+ tk->swap_flag = 1; -+ free(val); -+ return 0; -+ } -+ -+ if (strcmp(swap_flag, "no") == 0) { -+ tk->swap_flag = 0; -+ free(val); -+ return 0; -+ } -+ -+ free(val); -+ etmemd_log(ETMEMD_LOG_ERR, "swap_flag para is not valid.\n"); -+ return -1; -+} -+ - struct config_item g_task_config_items[] = { - {"name", STR_VAL, fill_task_name, false}, - {"type", STR_VAL, fill_task_type, false}, - {"value", STR_VAL, fill_task_value, false}, -+ {"swap_flag", STR_VAL, fill_task_swap_flag, true}, - {"max_threads", INT_VAL, fill_task_threads, true}, - }; - --- -1.8.3.1 - diff --git a/0069-etmem-fix-the-swapcache-wmark-configuration-parse-er.patch b/0069-etmem-fix-the-swapcache-wmark-configuration-parse-er.patch deleted file mode 100644 index 1b6a034..0000000 --- a/0069-etmem-fix-the-swapcache-wmark-configuration-parse-er.patch +++ /dev/null @@ -1,93 +0,0 @@ -From fff3255965293f42b9b6af79d0766110411c49d4 Mon Sep 17 00:00:00 2001 -From: liubo -Date: Sat, 12 Feb 2022 10:15:28 +0800 -Subject: [PATCH 19/33] etmem: fix the swapcache wmark configuration parse - error - -swapcache_high_wmark and swapcache_low_wmark should -appear in pairs, missing either part should report -an error. -In addition, swapcache_high_wmark should be greater -than swapcache_low_wmark. - -Signed-off-by: liubo ---- - etmem/src/etmemd_src/etmemd_migrate.c | 2 +- - etmem/src/etmemd_src/etmemd_project.c | 20 ++++++++++++++------ - 2 files changed, 15 insertions(+), 7 deletions(-) - -diff --git a/etmem/src/etmemd_src/etmemd_migrate.c b/etmem/src/etmemd_src/etmemd_migrate.c -index a5cce41..a143c5e 100644 ---- a/etmem/src/etmemd_src/etmemd_migrate.c -+++ b/etmem/src/etmemd_src/etmemd_migrate.c -@@ -115,7 +115,7 @@ static bool check_should_reclaim_swapcache(const struct task_pid *tk_pid) - unsigned long swapcache_total; - int ret; - -- if (proj->swapcache_high_wmark == 0) { -+ if (proj->swapcache_high_wmark == -1 || proj->swapcache_low_wmark == -1) { - return false; - } - -diff --git a/etmem/src/etmemd_src/etmemd_project.c b/etmem/src/etmemd_src/etmemd_project.c -index 72d7335..e238e66 100644 ---- a/etmem/src/etmemd_src/etmemd_project.c -+++ b/etmem/src/etmemd_src/etmemd_project.c -@@ -649,13 +649,13 @@ static int fill_project_sysmem_threshold(void *obj, void *val) - } - - /* fill the project parameter: swapcache_low_wmark -- * swapcache_low_wmark: [0, 100]. */ -+ * swapcache_low_wmark: (0, 100]. */ - static int fill_project_swapcache_low_wmark(void *obj, void *val) - { - struct project *proj = (struct project *)obj; - int swapcache_low_wmark = parse_to_int(val); - -- if (swapcache_low_wmark < 0 || swapcache_low_wmark > MAX_SWAPCACHE_WMARK_VALUE) { -+ if (swapcache_low_wmark <= 0 || swapcache_low_wmark > MAX_SWAPCACHE_WMARK_VALUE) { - etmemd_log(ETMEMD_LOG_ERR, "invaild project swapcache_low_wmark value %d, it must between 0 and 100.\n", - swapcache_low_wmark); - return -1; -@@ -672,7 +672,7 @@ static int fill_project_swapcache_high_wmark(void *obj, void *val) - struct project *proj = (struct project *)obj; - int swapcache_high_wmark = parse_to_int(val); - -- if (swapcache_high_wmark < 0 || swapcache_high_wmark > MAX_SWAPCACHE_WMARK_VALUE) { -+ if (swapcache_high_wmark <= 0 || swapcache_high_wmark > MAX_SWAPCACHE_WMARK_VALUE) { - etmemd_log(ETMEMD_LOG_ERR, "invaild project swapcache_high_wmark value %d, it must between 0 and 100.\n", - swapcache_high_wmark); - return -1; -@@ -684,11 +684,17 @@ static int fill_project_swapcache_high_wmark(void *obj, void *val) - - static bool check_swapcache_wmark_valid(struct project *proj) - { -- if (proj->swapcache_low_wmark > proj->swapcache_high_wmark) { -- return false; -+ if (proj->swapcache_high_wmark == -1 && proj->swapcache_low_wmark == -1) { -+ return true; - } - -- return true; -+ if ((proj->swapcache_high_wmark > 0) && -+ (proj->swapcache_low_wmark > 0) && -+ (proj->swapcache_high_wmark > proj->swapcache_low_wmark)) { -+ return true; -+ } -+ -+ return false; - } - - static struct config_item g_project_config_items[] = { -@@ -759,6 +765,8 @@ enum opt_result etmemd_project_add(GKeyFile *config) - } - - proj->sysmem_threshold = -1; -+ proj->swapcache_high_wmark = -1; -+ proj->swapcache_low_wmark = -1; - - if (project_fill_by_conf(config, proj) != 0) { - etmemd_log(ETMEMD_LOG_ERR, "fill project from configuration file fail\n"); --- -1.8.3.1 - diff --git a/0070-etmem-update-README.md.patch b/0070-etmem-update-README.md.patch deleted file mode 100644 index df263ee..0000000 --- a/0070-etmem-update-README.md.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 1ebeebf02a171d0029e70ee67270a8f7dab3e04e Mon Sep 17 00:00:00 2001 -From: liubo -Date: Thu, 24 Feb 2022 01:13:17 +0000 -Subject: [PATCH 20/33] etmem: update README.md. - -Add the usage constraints of etmem, -and introduce some added configuration file parameters - -Signed-off-by: liubo ---- - README.md | 45 ++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 40 insertions(+), 5 deletions(-) - -diff --git a/README.md b/README.md -index 93631a1..49287f9 100644 ---- a/README.md -+++ b/README.md -@@ -29,6 +29,30 @@ etmem内存分级扩展技术,通过DRAM+内存压缩/高性能存储新介质 - $ make - - -+## 注意事项 -+### 运行依赖 -+etmem作为内存扩展工具,需要依赖于内核态的特性支持,为了可以识别内存访问情况和支持主动将内存写入swap分区来达到内存垂直扩展的需求,etmem在运行时需要插入etmem_scan和etmem_swap模块: -+ -+``` -+modprobe etmem_scan -+modprobe etmem_swap -+``` -+openuler21.03、21.09、20.03 LTS SP2以及20.03 LTS SP3均支持etmem内存扩展相关特性,可以直接使用以上内核。 -+ -+### 权限限制 -+运行etmem进程需要root权限,root用户具有系统最高权限,在使用root用户进行操作时,请严格按照操作指导进行操作,避免其他操作造成系统管理及安全风险。 -+ -+### 使用约束 -+ -+- etmem的客户端和服务端需要在同一个服务器上部署,不支持跨服务器通信的场景。 -+- etmem仅支持扫描进程名小于或等于15个字符长度的目标进程。 -+- 在使用AEP介质进行内存扩展的时候,依赖于系统可以正确识别AEP设备并将AEP设备初始化为numa node。并且配置文件中的vm_flags字段只能配置为ht。 -+- 引擎私有命令仅针对对应引擎和引擎下的任务有效,比如cslide所支持的showhostpages和showtaskpages。 -+- 第三方策略实现代码中,eng_mgt_func接口中的fd不能写入0xff和0xfe字。 -+- 支持在一个工程内添加多个不同的第三方策略动态库,以配置文件中的eng_name来区分。 -+- 禁止并发扫描同一个进程。未加载etmem_scan和etmem_swap ko时,禁止使用/proc/xxx/idle_pages和/proc/xxx/swap_pages文件 -+ -+ - ## 使用说明 - - ### 启动etmemd进程 -@@ -63,7 +87,14 @@ options: - - 在运行etmem进程之前,需要管理员预先规划哪些进程需要做内存扩展,将进程信息配置到etmem配置文件中,并配置内存扫描的周期、扫描次数、内存冷热阈值等信息。 - --配置文件的示例文件在源码包中,放置在源码根目录的conf/example_conf.yaml,建议在使用时放置在/etc/etmem/目录下,示例内容为: -+配置文件的示例文件在源码包中,放置在/etc/etmem文件路径下,按照功能划分为3个示例文件, -+ -+``` -+/etc/etmem/cslide_conf.yaml -+/etc/etmem/slide_conf.yaml -+/etc/etmem/thirdparty_conf.yaml -+``` -+示例内容分别为: - - ``` - [project] -@@ -132,6 +163,9 @@ task_private_key=task_private_value - | loop | 内存扫描的循环次数 | 是 | 是 | 1~10 | loop=3 //扫描3次 | - | interval | 每次内存扫描的时间间隔 | 是 | 是 | 1~1200 | interval=5 //每次扫描之间间隔5s | - | sleep | 每个内存扫描+操作的大周期之间时间间隔 | 是 | 是 | 1~1200 | sleep=10 //每次大周期之间间隔10s | -+| sysmem_threshold| slide engine的配置项,系统内存换出阈值 | 否 | 是 | 0~100 | sysmem_threshold=50 //系统内存剩余量小于50%时,etmem才会触发内存换出| -+| swapcache_high_wmark| slide engine的配置项,swacache可以占用系统内存的比例,高水线 | 否 | 是 | 1~100 | swapcache_high_wmark=5 //swapcache内存占用量可以为系统内存的5%,超过该比例,etmem会触发swapcache回收
注: swapcache_high_wmark需要大于swapcache_low_wmark| -+| swapcache_low_wmark| slide engine的配置项,swacache可以占用系统内存的比例,低水线 | 否 | 是 | [1~swapcache_high_wmark) | swapcache_low_wmark=3 //触发swapcache回收后,系统会将swapcache内存占用量回收到低于3%| - | [engine] | engine公用配置段起始标识 | 否 | 否 | NA | engine参数的开头标识,表示下面的参数直到另外的[xxx]或文件结尾为止的范围内均为engine section的参数 | - | project | 声明所在的project | 是 | 是 | 64个字以内的字符串 | 已经存在名字为test的project,则可以写为project=test | - | engine | 声明所在的engine | 是 | 是 | slide/cslide/thridparty | 声明使用的是slide或cslide或thirdparty策略 | -@@ -155,7 +189,8 @@ task_private_key=task_private_value - | anon_only | engine为cslide的task配置项,标识是否只扫描匿名页 | 否 | 是 | yes/no | anon_only=no //配置为yes时只扫描匿名页,配置为no时非匿名页也会扫描 | - | ign_host | engine为cslide的task配置项,标识是否忽略host上的页表扫描信息 | 否 | 是 | yes/no | ign_host=no //yes为忽略,no为不忽略 | - | task_private_key | engine为thirdparty的task配置项,预留给第三方策略的task解析私有参数的配置项,选配 | 否 | 否 | 根据第三方策略私有参数自行限制 | 根据第三方策略私有task参数自行配置 | -- -+| swap_threshold |slide engine的配置项,进程内存换出阈值 | 否 | 是 | 进程可用内存绝对值 | swap_threshold=10g //进程占用内存在低于10g时不会触发换出。
当前版本下,仅支持g/G作为内存绝对值单位。与sysmem_threshold配合使用,仅系统内存低于阈值时,进行白名单中进程阈值判断 | -+| swap_flag|slide engine的配置项,进程指定内存换出 | 否 | 是 | yes/no | swap_flag=yes//使能进程指定内存换出 | - - - ### etmem project/engine/task对象的创建和删除 -@@ -172,11 +207,11 @@ task_private_key=task_private_value - - 添加对象: - --etmem obj add -f /etc/example_config.yaml -s etmemd_socket -+etmem obj add -f /etc/etmem/slide_conf.yaml -s etmemd_socket - - 删除对象: - --etmem obj del -f /etc/example_config.yaml -s etmemd_socket -+etmem obj del -f /etc/etmem/slide_conf.yaml -s etmemd_socket - - 打印帮助: - -@@ -491,4 +526,4 @@ etmem engine showhostpages -n proj_name -e cslide -s etmemd_socket - 1. Fork本仓库 - 2. 新建个人分支 - 3. 提交代码 --4. 新建Pull Request -\ No newline at end of file -+4. 新建Pull Request --- -1.8.3.1 - diff --git a/0071-etmem-add-code-of-testcase.patch b/0071-etmem-add-code-of-testcase.patch deleted file mode 100644 index 052bc2c..0000000 --- a/0071-etmem-add-code-of-testcase.patch +++ /dev/null @@ -1,520 +0,0 @@ -From 6847808d04c18a76db6bbf38ac6e421a5fac8b7c Mon Sep 17 00:00:00 2001 -From: liubo -Date: Mon, 24 Jan 2022 03:50:17 +0800 -Subject: [PATCH 21/33] etmem: add code of testcase - -add code of testcase of etmem socket functions. - -Signed-off-by: liubo ---- - etmem/test/conf/conf_cslide/task.config | 16 +- - etmem/test/etmem_migrate_ops_llt/CMakeLists.txt | 54 ++-- - .../etmem_migrate_ops_llt/etmem_migrate_ops_llt.c | 5 +- - .../test/etmem_socket_ops_llt_test/CMakeLists.txt | 26 ++ - .../etmem_socket_ops_llt.c | 356 +++++++++++++++++++++ - 5 files changed, 419 insertions(+), 38 deletions(-) - create mode 100644 etmem/test/etmem_socket_ops_llt_test/CMakeLists.txt - create mode 100644 etmem/test/etmem_socket_ops_llt_test/etmem_socket_ops_llt.c - -diff --git a/etmem/test/conf/conf_cslide/task.config b/etmem/test/conf/conf_cslide/task.config -index 336be39..9719cb6 100644 ---- a/etmem/test/conf/conf_cslide/task.config -+++ b/etmem/test/conf/conf_cslide/task.config -@@ -1,9 +1,9 @@ --[task] --project=test --engine=cslide --name=background1 --type=pid --value=1 --vm_flags=ht --anon_only=no -+[task] -+project=test -+engine=cslide -+name=background1 -+type=pid -+value=1 -+vm_flags=ht -+anon_only=no - ign_host=yes -\ No newline at end of file -diff --git a/etmem/test/etmem_migrate_ops_llt/CMakeLists.txt b/etmem/test/etmem_migrate_ops_llt/CMakeLists.txt -index a9487af..d998af7 100644 ---- a/etmem/test/etmem_migrate_ops_llt/CMakeLists.txt -+++ b/etmem/test/etmem_migrate_ops_llt/CMakeLists.txt -@@ -1,27 +1,27 @@ --# /****************************************************************************** --# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. --# * etmem is licensed under the Mulan PSL v2. --# * You can use this software according to the terms and conditions of the Mulan PSL v2. --# * You may obtain a copy of Mulan PSL v2 at: --# * http://license.coscl.org.cn/MulanPSL2 --# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR --# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR --# * PURPOSE. --# * See the Mulan PSL v2 for more details. --# * Author: liubo --# * Create: 2021-12-10 --# * Description: CMakefileList for etmem_migrate_ops_llt to compile --# ******************************************************************************/ -- --project(etmem) -- --INCLUDE_DIRECTORIES(../../inc/etmem_inc) --INCLUDE_DIRECTORIES(../../inc/etmemd_inc) --INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -- --SET(EXE etmem_migrate_ops_llt) -- --add_executable(${EXE} etmem_migrate_ops_llt.c) -- --set_target_properties(${EXE} PROPERTIES LINK_FLAGS "-Wl,--wrap,get_mem_from_proc_file") --target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: liubo -+# * Create: 2021-12-10 -+# * Description: CMakefileList for etmem_migrate_ops_llt to compile -+# ******************************************************************************/ -+ -+project(etmem) -+ -+INCLUDE_DIRECTORIES(../../inc/etmem_inc) -+INCLUDE_DIRECTORIES(../../inc/etmemd_inc) -+INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -+ -+SET(EXE etmem_migrate_ops_llt) -+ -+add_executable(${EXE} etmem_migrate_ops_llt.c) -+ -+set_target_properties(${EXE} PROPERTIES LINK_FLAGS "-Wl,--wrap,get_mem_from_proc_file") -+target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_migrate_ops_llt/etmem_migrate_ops_llt.c b/etmem/test/etmem_migrate_ops_llt/etmem_migrate_ops_llt.c -index 2758680..5c9b0d4 100644 ---- a/etmem/test/etmem_migrate_ops_llt/etmem_migrate_ops_llt.c -+++ b/etmem/test/etmem_migrate_ops_llt/etmem_migrate_ops_llt.c -@@ -65,8 +65,7 @@ static struct memory_grade *get_memory_grade(void) - memory_grade = (struct memory_grade *)calloc(1, sizeof(struct memory_grade)); - CU_ASSERT_PTR_NOT_NULL(memory_grade); - -- while (page_refs != NULL) -- { -+ while (page_refs != NULL) { - if ((page_refs)->count >= WATER_LINE_TEMP) { - page_refs = add_page_refs_into_memory_grade(page_refs, &memory_grade->hot_pages); - continue; -@@ -104,7 +103,7 @@ static void test_etmem_migrate_ok(void) - - memory_grade = get_memory_grade(); - CU_ASSERT_PTR_NOT_NULL(memory_grade); -- CU_ASSERT_EQUAL(etmemd_grade_migrate("1", memory_grade), -1); -+ CU_ASSERT_EQUAL(etmemd_grade_migrate("1", memory_grade), 0); - - clean_memory_grade_unexpected(&memory_grade); - CU_ASSERT_PTR_NULL(memory_grade); -diff --git a/etmem/test/etmem_socket_ops_llt_test/CMakeLists.txt b/etmem/test/etmem_socket_ops_llt_test/CMakeLists.txt -new file mode 100644 -index 0000000..7cc5343 ---- /dev/null -+++ b/etmem/test/etmem_socket_ops_llt_test/CMakeLists.txt -@@ -0,0 +1,26 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: liubo -+# * Create: 2021-12-10 -+# * Description: CMakefileList for etmem_log_ops_llt to compile -+# ******************************************************************************/ -+ -+project(etmem) -+ -+INCLUDE_DIRECTORIES(../../inc/etmem_inc) -+INCLUDE_DIRECTORIES(../../inc/etmemd_inc) -+INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -+ -+SET(EXE etmem_socket_ops_llt) -+ -+add_executable(${EXE} etmem_socket_ops_llt.c) -+ -+target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_socket_ops_llt_test/etmem_socket_ops_llt.c b/etmem/test/etmem_socket_ops_llt_test/etmem_socket_ops_llt.c -new file mode 100644 -index 0000000..387ffd1 ---- /dev/null -+++ b/etmem/test/etmem_socket_ops_llt_test/etmem_socket_ops_llt.c -@@ -0,0 +1,356 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liubo -+ * Create: 2021-08-14 -+ * Description: This is a source file of the unit test for rpc functions in etmem. -+ ******************************************************************************/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "etmem_common.h" -+#include "etmem_rpc.h" -+#include "etmemd_rpc.h" -+#include "securec.h" -+#include "etmem.h" -+ -+#define SOCK_NAME_MAX_LEN 108 -+#define RPC_SEND_FILE_MAX 512 -+#define SLEEP_TIME_ONE_T_US 1000 -+ -+static char *get_length_str(unsigned int length) -+{ -+ char *result = NULL; -+ unsigned char i = 'a'; -+ unsigned int j; -+ result = (char *)calloc(length + 1, sizeof(char)); -+ if (result == NULL) { -+ return NULL; -+ } -+ -+ for (j = 0; j < length; j++) { -+ result[j] = i; -+ } -+ -+ return result; -+} -+ -+static void test_sock_name_error(void) -+{ -+ char *name = NULL; -+ CU_ASSERT_EQUAL(etmemd_parse_sock_name(NULL), -1); -+ CU_ASSERT_EQUAL(etmemd_parse_sock_name(""), -1); -+ CU_ASSERT_EQUAL(etmemd_parse_sock_name("name"), 0); -+ -+ name = get_length_str(SOCK_NAME_MAX_LEN - 1); -+ CU_ASSERT_PTR_NOT_NULL(name); -+ CU_ASSERT_EQUAL(etmemd_parse_sock_name(name), -1); -+ free(name); -+ -+ name = get_length_str(SOCK_NAME_MAX_LEN); -+ CU_ASSERT_PTR_NOT_NULL(name); -+ CU_ASSERT_EQUAL(etmemd_parse_sock_name(name), -1); -+ free(name); -+ -+ name = get_length_str(SOCK_NAME_MAX_LEN + 1); -+ CU_ASSERT_PTR_NOT_NULL(name); -+ CU_ASSERT_EQUAL(etmemd_parse_sock_name(name), -1); -+ free(name); -+} -+ -+static void test_sock_name_ok(void) -+{ -+ char *name = NULL; -+ -+ CU_ASSERT_EQUAL(etmemd_parse_sock_name("name"), 0); -+ CU_ASSERT_EQUAL(etmemd_parse_sock_name("n"), 0); -+ -+ name = get_length_str(SOCK_NAME_MAX_LEN - 2); -+ CU_ASSERT_PTR_NOT_NULL(name); -+ CU_ASSERT_EQUAL(etmemd_parse_sock_name(name), 0); -+ free(name); -+} -+ -+void *etmemd_rpc_server_start(void *msg) -+{ -+ char *socket_name = (char *)msg; -+ CU_ASSERT_EQUAL(etmemd_parse_sock_name(socket_name), -1); -+ etmemd_rpc_server(); -+} -+ -+void *etmemd_rpc_server_start_ok(void *msg) -+{ -+ char *socket_name = (char *)msg; -+ CU_ASSERT_EQUAL(etmemd_parse_sock_name(socket_name), 0); -+ etmemd_rpc_server(); -+} -+ -+static struct mem_proj *alloc_proj(int cmd, char *proj_name, -+ char *file_name, char *sock_name) -+{ -+ struct mem_proj *proj = NULL; -+ proj = (struct mem_proj *)calloc(1, sizeof(struct mem_proj)); -+ CU_ASSERT_PTR_NOT_NULL(proj); -+ -+ proj->cmd = cmd; -+ proj->file_name = file_name; -+ proj->proj_name = proj_name; -+ proj->sock_name = sock_name; -+ -+ return proj; -+} -+ -+static int etmem_socket_client(int cmd, char *proj_name, -+ char *file_name, char *sock_name) -+{ -+ int ret; -+ struct mem_proj *proj = NULL; -+ proj = alloc_proj(cmd, proj_name, file_name, sock_name); -+ ret = etmem_rpc_client(proj); -+ free(proj); -+ if (ret == 0) { -+ return 0; -+ } -+ return -1; -+} -+ -+static void etmem_pro_add_error(void) -+{ -+ char *file_name = NULL; -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, NULL, NULL, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, NULL, "", ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, NULL, "file_name", ""), -1); -+ file_name = get_length_str(RPC_SEND_FILE_MAX); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, NULL, file_name, ""), -1); -+ free(file_name); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, NULL, "file_name", "sock_name"), -1); -+ -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, "", NULL, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, "", "", ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, "", "file_name", ""), -1); -+ file_name = get_length_str(RPC_SEND_FILE_MAX); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, "", file_name, ""), -1); -+ free(file_name); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, "", "file_name", "sock_name"), -1); -+ -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, "test", NULL, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, "test", "", ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, "test", "file_name", ""), -1); -+ file_name = get_length_str(RPC_SEND_FILE_MAX); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, "test", file_name, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, "test", "file_name", "sock_name"), -1); -+ free(file_name); -+} -+ -+static void etmem_pro_del_error(void) -+{ -+ char *file_name = NULL; -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, NULL, NULL, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, NULL, "", ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, NULL, "file_name", ""), -1); -+ file_name = get_length_str(RPC_SEND_FILE_MAX); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, NULL, file_name, ""), -1); -+ free(file_name); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, NULL, "file_name", "sock_name"), -1); -+ -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, "", NULL, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, "", "", ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, "", "file_name", ""), -1); -+ file_name = get_length_str(RPC_SEND_FILE_MAX); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, "", file_name, ""), -1); -+ free(file_name); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, "", "file_name", "sock_name"), -1); -+ -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, "test", NULL, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, "test", "", ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, "test", "file_name", ""), -1); -+ file_name = get_length_str(RPC_SEND_FILE_MAX); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, "test", file_name, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, "test", "file_name", "sock_name"), -1); -+ free(file_name); -+} -+ -+static void etmem_pro_start_error(void) -+{ -+ char *file_name = NULL; -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, NULL, NULL, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, NULL, "", ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, NULL, "file_name", ""), -1); -+ file_name = get_length_str(RPC_SEND_FILE_MAX); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, NULL, file_name, ""), -1); -+ free(file_name); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, NULL, "file_name", "sock_name"), -1); -+ -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, "", NULL, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, "", "", ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, "", "file_name", ""), -1); -+ file_name = get_length_str(RPC_SEND_FILE_MAX); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, "", file_name, ""), -1); -+ free(file_name); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, "", "file_name", "sock_name"), -1); -+ -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, "test", NULL, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, "test", "", ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, "test", "file_name", ""), -1); -+ file_name = get_length_str(RPC_SEND_FILE_MAX); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, "test", file_name, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, "test", "file_name", "sock_name"), -1); -+ free(file_name); -+} -+ -+static void etmem_pro_stop_error(void) -+{ -+ char *file_name = NULL; -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, NULL, NULL, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, NULL, "", ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, NULL, "file_name", ""), -1); -+ file_name = get_length_str(RPC_SEND_FILE_MAX); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, NULL, file_name, ""), -1); -+ free(file_name); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, NULL, "file_name", "sock_name"), -1); -+ -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, "", NULL, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, "", "", ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, "", "file_name", ""), -1); -+ file_name = get_length_str(RPC_SEND_FILE_MAX); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, "", file_name, ""), -1); -+ free(file_name); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, "", "file_name", "sock_name"), -1); -+ -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, "test", NULL, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, "test", "", ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, "test", "file_name", ""), -1); -+ file_name = get_length_str(RPC_SEND_FILE_MAX); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, "test", file_name, ""), -1); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, "test", "file_name", "sock_name"), -1); -+ free(file_name); -+} -+ -+static void test_socket_client_error(void) -+{ -+ struct mem_proj *proj = NULL; -+ char *project_name = NULL; -+ char *file_name = NULL; -+ char *sock_name = NULL; -+ char *msg = "etmem_error_sock"; -+ -+ pthread_t etmem_socket_test; -+ -+ CU_ASSERT_EQUAL(pthread_create(&etmem_socket_test, NULL, etmemd_rpc_server_start, NULL), EOK); -+ CU_ASSERT_EQUAL(pthread_create(&etmem_socket_test, NULL, -+ etmemd_rpc_server_start_ok, (void *)msg), EOK); -+ usleep(SLEEP_TIME_ONE_T_US); -+ etmem_pro_add_error(); -+ etmem_pro_del_error(); -+ etmem_pro_start_error(); -+ etmem_pro_stop_error(); -+ -+ etmemd_handle_signal(); -+} -+ -+static void test_socket_client_ok(void) -+{ -+ struct mem_proj *proj = NULL; -+ char *project_name = NULL; -+ char *file_name = NULL; -+ char *sock_name = NULL; -+ char *msg = "etmem_ok_sock"; -+ -+ pthread_t etmem_socket_test_ok; -+ -+ CU_ASSERT_EQUAL(pthread_create(&etmem_socket_test_ok, NULL, -+ etmemd_rpc_server_start_ok, (void *)msg), EOK); -+ usleep(SLEEP_TIME_ONE_T_US); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_ADD, "test", -+ "../conf/conf_slide/config_file", msg), 0); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_SHOW, "test", -+ "../conf/conf_slide/config_file", msg), 0); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_START, "test", -+ "../conf/conf_slide/config_file", msg), 0); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_STOP, "test", -+ "../conf/conf_slide/config_file", msg), 0); -+ CU_ASSERT_EQUAL(etmem_socket_client(ETMEM_CMD_DEL, "test", -+ "../conf/conf_slide/config_file", msg), 0); -+ -+ etmemd_handle_signal(); -+} -+ -+typedef enum { -+ CUNIT_SCREEN = 0, -+ CUNIT_XMLFILE, -+ CUNIT_CONSOLE -+} cu_run_mode; -+ -+int main(int argc, const char **argv) -+{ -+ CU_pSuite suite; -+ CU_pTest pTest; -+ unsigned int num_failures; -+ cu_run_mode cunit_mode = CUNIT_SCREEN; -+ int error_num; -+ -+ if (argc > 1) { -+ cunit_mode = atoi(argv[1]); -+ } -+ -+ if (CU_initialize_registry() != CUE_SUCCESS) { -+ return -CU_get_error(); -+ } -+ -+ suite = CU_add_suite("etmem_socket_ops", NULL, NULL); -+ if (suite == NULL) { -+ goto ERROR; -+ } -+ -+ if (CU_ADD_TEST(suite, test_sock_name_error) == NULL || -+ CU_ADD_TEST(suite, test_sock_name_ok) == NULL || -+ CU_ADD_TEST(suite, test_socket_client_error) == NULL || -+ CU_ADD_TEST(suite, test_socket_client_ok) == NULL) { -+ printf("CU_ADD_TEST fail. \n"); -+ goto ERROR; -+ } -+ -+ switch (cunit_mode) { -+ case CUNIT_SCREEN: -+ CU_basic_set_mode(CU_BRM_VERBOSE); -+ CU_basic_run_tests(); -+ break; -+ case CUNIT_XMLFILE: -+ CU_set_output_filename("etmemd_rpc.c"); -+ CU_automated_run_tests(); -+ break; -+ case CUNIT_CONSOLE: -+ CU_console_run_tests(); -+ break; -+ default: -+ printf("not support cunit mode, only support: " -+ "0 for CUNIT_SCREEN, 1 for CUNIT_XMLFILE, 2 for CUNIT_CONSOLE\n"); -+ goto ERROR; -+ } -+ -+ num_failures = CU_get_number_of_failures(); -+ CU_cleanup_registry(); -+ return num_failures; -+ -+ERROR: -+ error_num = CU_get_error(); -+ CU_cleanup_registry(); -+ return -error_num; -+} --- -1.8.3.1 - diff --git a/0072-etmem-add-code-of-testcase.patch b/0072-etmem-add-code-of-testcase.patch deleted file mode 100644 index bc6e608..0000000 --- a/0072-etmem-add-code-of-testcase.patch +++ /dev/null @@ -1,1040 +0,0 @@ -From 692c7b671b87dd6cc3748426ab22d07b5330ad79 Mon Sep 17 00:00:00 2001 -From: liubo -Date: Mon, 24 Jan 2022 06:42:23 +0800 -Subject: [PATCH 22/33] etmem: add code of testcase - -add code of testcase for etmem task function -add code of testcase for etmem thirdparty function - -Signed-off-by: liubo ---- - .../test/etmem_socket_ops_llt_test/CMakeLists.txt | 2 +- - etmem/test/etmem_task_ops_llt_test/CMakeLists.txt | 26 ++ - .../etmem_task_ops_llt_test/etmem_task_ops_llt.c | 334 ++++++++++++++++ - .../etmem_thirdparty_ops_llt_test/CMakeLists.txt | 30 ++ - .../etmem_thirdparty_ops_llt.c | 425 +++++++++++++++++++++ - .../test/etmem_thirdparty_ops_llt_test/my_engine.c | 156 ++++++++ - 6 files changed, 972 insertions(+), 1 deletion(-) - create mode 100644 etmem/test/etmem_task_ops_llt_test/CMakeLists.txt - create mode 100644 etmem/test/etmem_task_ops_llt_test/etmem_task_ops_llt.c - create mode 100644 etmem/test/etmem_thirdparty_ops_llt_test/CMakeLists.txt - create mode 100644 etmem/test/etmem_thirdparty_ops_llt_test/etmem_thirdparty_ops_llt.c - create mode 100644 etmem/test/etmem_thirdparty_ops_llt_test/my_engine.c - -diff --git a/etmem/test/etmem_socket_ops_llt_test/CMakeLists.txt b/etmem/test/etmem_socket_ops_llt_test/CMakeLists.txt -index 7cc5343..05239a0 100644 ---- a/etmem/test/etmem_socket_ops_llt_test/CMakeLists.txt -+++ b/etmem/test/etmem_socket_ops_llt_test/CMakeLists.txt -@@ -10,7 +10,7 @@ - # * See the Mulan PSL v2 for more details. - # * Author: liubo - # * Create: 2021-12-10 --# * Description: CMakefileList for etmem_log_ops_llt to compile -+# * Description: CMakefileList for etmem_socket_ops_llt to compile - # ******************************************************************************/ - - project(etmem) -diff --git a/etmem/test/etmem_task_ops_llt_test/CMakeLists.txt b/etmem/test/etmem_task_ops_llt_test/CMakeLists.txt -new file mode 100644 -index 0000000..ab22dd6 ---- /dev/null -+++ b/etmem/test/etmem_task_ops_llt_test/CMakeLists.txt -@@ -0,0 +1,26 @@ -+s# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: liubo -+# * Create: 2021-12-10 -+# * Description: CMakefileList for etmem_task_ops_llt to compile -+# ******************************************************************************/ -+ -+project(etmem) -+ -+INCLUDE_DIRECTORIES(../../inc/etmem_inc) -+INCLUDE_DIRECTORIES(../../inc/etmemd_inc) -+INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -+ -+SET(EXE etmem_task_ops_llt) -+ -+add_executable(${EXE} etmem_task_ops_llt.c) -+ -+target_link_libraries(${EXE} cunit ${BUILD_DIR}/lib/libetmemd.so pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_task_ops_llt_test/etmem_task_ops_llt.c b/etmem/test/etmem_task_ops_llt_test/etmem_task_ops_llt.c -new file mode 100644 -index 0000000..7997108 ---- /dev/null -+++ b/etmem/test/etmem_task_ops_llt_test/etmem_task_ops_llt.c -@@ -0,0 +1,334 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liubo -+ * Create: 2021-12-10 -+ * Description: This is a source file of the unit test for task functions in etmem. -+ ******************************************************************************/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "etmemd_project.h" -+#include "etmemd_task.h" -+#include "etmemd_engine.h" -+#include "etmemd_slide.h" -+#include "etmemd_cslide.h" -+#include "etmemd_rpc.h" -+#include "securec.h" -+ -+#define PID_STR_MAX_LEN 10 -+#define PID_TEST_NUM 100 -+#define PID_PROCESS_MEM 5000 -+#define PID_PROCESS_SLEEP_TIME 60 -+#define WATER_LINT_TEMP 3 -+ -+static void get_task_pids_errinput(char *pid_val, char *pid_type, int exp) -+{ -+ struct task *tk = NULL; -+ -+ tk = (struct task *)calloc(1, sizeof(struct task)); -+ CU_ASSERT_PTR_NOT_NULL(tk); -+ -+ tk->type = pid_type; -+ tk->value = pid_val; -+ CU_ASSERT_EQUAL(etmemd_get_task_pids(tk, true), exp); -+ -+ free(tk); -+} -+ -+static void test_get_task_pids_error(void) -+{ -+ get_task_pids_errinput("", "", -1); -+ get_task_pids_errinput("1", "", -1); -+ get_task_pids_errinput("no123", "pid", -1); -+ get_task_pids_errinput("1", "wrong", -1); -+ get_task_pids_errinput("wrong", "name", -1); -+ get_task_pids_errinput("-1", "pid", -1); -+} -+ -+static void add_process(int index) -+{ -+ int pid = fork(); -+ switch (pid) { -+ case 0: /* child process */ -+ { -+ char index_str[PID_PROCESS_MEM] = {0}; -+ if (snprintf_s(index_str, PID_PROCESS_MEM, PID_PROCESS_MEM - 1, "%d", index) <= 0) { -+ printf("get index error.\n"); -+ } -+ prctl(PR_SET_NAME, index_str, NULL, NULL, NULL); -+ sleep(PID_PROCESS_SLEEP_TIME); -+ exit(0); -+ } -+ case -1: /* create process wrong */ -+ { -+ printf("[Worker]: Fork failed!\n"); -+ exit(0); -+ } -+ -+ default: -+ break; -+ } -+} -+ -+static int get_pids(int index) -+{ -+ int pid = getpid(); -+ int i; -+ for (i = 0; i < index; i++) { -+ add_process(i); -+ } -+ return pid; -+} -+ -+static int init_ops(struct task *tk) -+{ -+ tk->eng->ops->fill_eng_params = NULL; -+ tk->eng->ops->clear_eng_params = NULL; -+ tk->eng->ops->fill_task_params = NULL; -+ tk->eng->ops->clear_task_params = NULL; -+ tk->eng->ops->start_task = NULL; -+ tk->eng->ops->stop_task = NULL; -+ tk->eng->ops->alloc_pid_params = NULL; -+ tk->eng->ops->free_pid_params = NULL; -+ tk->eng->ops->eng_mgt_func = NULL; -+} -+ -+static struct task *alloc_task(const char *pid_type, const char *pid_val) -+{ -+ size_t pid_type_len; -+ size_t pid_value_len; -+ struct task *tk = NULL; -+ -+ tk = (struct task *)calloc(1, sizeof(struct task)); -+ CU_ASSERT_PTR_NOT_NULL(tk); -+ -+ pid_type_len = strlen(pid_type) + 1; -+ pid_value_len = strlen(pid_val) + 1; -+ -+ tk->type = (char *)calloc(pid_type_len, sizeof(char)); -+ CU_ASSERT_PTR_NOT_NULL(tk->type); -+ if (strncpy_s(tk->type, pid_type_len, pid_type, pid_type_len - 1) != EOK) { -+ free(tk->type); -+ free(tk); -+ return NULL; -+ } -+ -+ tk->value = (char *)calloc(pid_value_len, sizeof(char)); -+ CU_ASSERT_PTR_NOT_NULL(tk->value); -+ if (strncpy_s(tk->value, pid_value_len, pid_val, pid_value_len - 1) != EOK) { -+ free(tk->type); -+ free(tk->value); -+ free(tk); -+ return NULL; -+ } -+ -+ tk->eng = (struct engine *)calloc(1, sizeof(struct engine)); -+ CU_ASSERT_PTR_NOT_NULL(tk->eng); -+ tk->eng->tasks = (void *)tk; -+ -+ tk->eng->ops = (struct engine_ops *)calloc(1, sizeof(struct engine_ops)); -+ CU_ASSERT_PTR_NOT_NULL(tk->eng->ops); -+ init_ops(tk); -+ -+ CU_ASSERT_EQUAL(fill_engine_type_slide(tk->eng, NULL), 0); -+ -+ return tk; -+} -+ -+static void test_get_task_withpid_ok(void) -+{ -+ char pid_val[PID_STR_MAX_LEN] = {0}; -+ char *pid_type = "pid"; -+ struct task *tk = NULL; -+ struct engine *eng = NULL; -+ int pid; -+ -+ pid = get_pids((int)PID_TEST_NUM); -+ if (snprintf_s(pid_val, PID_STR_MAX_LEN, PID_STR_MAX_LEN - 1, "%d", pid) <= 0) { -+ printf("snprintf pid fail %d", pid); -+ return; -+ } -+ tk = alloc_task(pid_type, pid_val); -+ CU_ASSERT_PTR_NOT_NULL(tk); -+ -+ CU_ASSERT_EQUAL(etmemd_get_task_pids(tk, true), 0); -+ CU_ASSERT_PTR_NOT_NULL(tk->pids); -+ -+ etmemd_free_task_pids(tk); -+ CU_ASSERT_PTR_NULL(tk->pids); -+ -+ etmemd_free_task_struct(&tk); -+ CU_ASSERT_PTR_NULL(tk); -+} -+ -+static void test_get_task_withname_ok(void) -+{ -+ char *pid_val = "systemd"; -+ char *pid_type = "name"; -+ struct task *tk = NULL; -+ -+ tk = alloc_task(pid_type, pid_val); -+ -+ CU_ASSERT_EQUAL(etmemd_get_task_pids(tk, true), 0); -+ CU_ASSERT_PTR_NOT_NULL(tk->pids); -+ -+ etmemd_free_task_pids(tk); -+ CU_ASSERT_PTR_NULL(tk->pids); -+ -+ etmemd_free_task_struct(&tk); -+ CU_ASSERT_PTR_NULL(tk); -+} -+ -+static int get_task_pid(char *type, char *value, struct task *tk) -+{ -+ char pid[PID_STR_MAX_LEN] = {0}; -+ tk->type = type; -+ tk->value = value; -+ return get_pid_from_task_type(tk, pid); -+} -+ -+static void test_get_pid_error(void) -+{ -+ struct task *tk = NULL; -+ -+ tk = (struct task *)calloc(1, sizeof(struct task)); -+ CU_ASSERT_PTR_NOT_NULL(tk); -+ -+ CU_ASSERT_EQUAL(get_task_pid("", "", tk), -1); -+ CU_ASSERT_EQUAL(get_task_pid("wrong", "", tk), -1); -+ CU_ASSERT_EQUAL(get_task_pid("", "no123", tk), -1); -+ CU_ASSERT_EQUAL(get_task_pid("pid", "no123", tk), 0); -+ CU_ASSERT_EQUAL(get_task_pid("name", "wrong", tk), -1); -+ free(tk); -+} -+ -+static void test_get_pid_ok(void) -+{ -+ struct task *tk = NULL; -+ -+ tk = (struct task *)calloc(1, sizeof(struct task)); -+ CU_ASSERT_PTR_NOT_NULL(tk); -+ -+ CU_ASSERT_EQUAL(get_task_pid("pid", "1", tk), 0); -+ CU_ASSERT_EQUAL(get_task_pid("name", "systemd", tk), 0); -+ free(tk); -+} -+ -+static void test_free_task_pids(void) -+{ -+ struct task *tk = NULL; -+ struct task_pid *tk_pid = NULL; -+ struct slide_params *s_param = NULL; -+ struct engine *eng = NULL; -+ -+ tk = (struct task *)calloc(1, sizeof(struct task)); -+ CU_ASSERT_PTR_NOT_NULL(tk); -+ -+ tk_pid = (struct task_pid *)calloc(1, sizeof(struct task_pid)); -+ CU_ASSERT_PTR_NOT_NULL(tk_pid); -+ tk_pid->pid = 1; -+ -+ s_param = (struct slide_params *)calloc(1, sizeof(struct slide_params)); -+ CU_ASSERT_PTR_NOT_NULL(s_param); -+ s_param->t = WATER_LINT_TEMP; -+ tk_pid->params = s_param; -+ tk_pid->tk = tk; -+ tk->pids = tk_pid; -+ -+ /* add engine */ -+ eng = (struct engine *)calloc(1, sizeof(struct engine)); -+ CU_ASSERT_PTR_NOT_NULL(eng); -+ tk->eng = eng; -+ -+ tk->eng->ops = (struct engine_ops *)calloc(1, sizeof(struct engine_ops)); -+ CU_ASSERT_PTR_NOT_NULL(tk->eng->ops); -+ init_ops(tk); -+ -+ etmemd_free_task_pids(tk); -+ CU_ASSERT_PTR_NULL(tk->pids); -+ free(tk); -+ tk = NULL; -+} -+ -+typedef enum { -+ CUNIT_SCREEN = 0, -+ CUNIT_XMLFILE, -+ CUNIT_CONSOLE -+} cu_run_mode; -+ -+int main(int argc, const char **argv) -+{ -+ CU_pSuite suite; -+ CU_pTest pTest; -+ unsigned int num_failures; -+ cu_run_mode cunit_mode = CUNIT_SCREEN; -+ int error_num; -+ -+ if (argc > 1) { -+ cunit_mode = atoi(argv[1]); -+ } -+ -+ if (CU_initialize_registry() != CUE_SUCCESS) { -+ return -CU_get_error(); -+ } -+ -+ suite = CU_add_suite("etmem_task_ops", NULL, NULL); -+ if (suite == NULL) { -+ goto ERROR; -+ } -+ -+ if (CU_ADD_TEST(suite, test_get_task_pids_error) == NULL || -+ CU_ADD_TEST(suite, test_get_task_withpid_ok) == NULL || -+ CU_ADD_TEST(suite, test_get_task_withname_ok) == NULL || -+ CU_ADD_TEST(suite, test_get_pid_error) == NULL || -+ CU_ADD_TEST(suite, test_get_pid_ok) == NULL || -+ CU_ADD_TEST(suite, test_free_task_pids) == NULL) { -+ printf("CU_ADD_TEST fail. \n"); -+ goto ERROR; -+ } -+ -+ switch (cunit_mode) { -+ case CUNIT_SCREEN: -+ CU_basic_set_mode(CU_BRM_VERBOSE); -+ CU_basic_run_tests(); -+ break; -+ case CUNIT_XMLFILE: -+ CU_set_output_filename("etmemd_task.c"); -+ CU_automated_run_tests(); -+ break; -+ case CUNIT_CONSOLE: -+ CU_console_run_tests(); -+ break; -+ default: -+ printf("not support cunit mode, only support: " -+ "0 for CUNIT_SCREEN, 1 for CUNIT_XMLFILE, 2 for CUNIT_CONSOLE\n"); -+ goto ERROR; -+ } -+ -+ num_failures = CU_get_number_of_failures(); -+ CU_cleanup_registry(); -+ return num_failures; -+ -+ERROR: -+ error_num = CU_get_error(); -+ CU_cleanup_registry(); -+ return -error_num; -+} -diff --git a/etmem/test/etmem_thirdparty_ops_llt_test/CMakeLists.txt b/etmem/test/etmem_thirdparty_ops_llt_test/CMakeLists.txt -new file mode 100644 -index 0000000..6e82870 ---- /dev/null -+++ b/etmem/test/etmem_thirdparty_ops_llt_test/CMakeLists.txt -@@ -0,0 +1,30 @@ -+# /****************************************************************************** -+# * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+# * etmem is licensed under the Mulan PSL v2. -+# * You can use this software according to the terms and conditions of the Mulan PSL v2. -+# * You may obtain a copy of Mulan PSL v2 at: -+# * http://license.coscl.org.cn/MulanPSL2 -+# * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# * PURPOSE. -+# * See the Mulan PSL v2 for more details. -+# * Author: liubo -+# * Create: 2021-12-10 -+# * Description: CMakefileList for etmem_thirdparty_ops_llt to compile -+# ******************************************************************************/ -+ -+project(etmem) -+ -+INCLUDE_DIRECTORIES(../../inc/etmem_inc) -+INCLUDE_DIRECTORIES(../../inc/etmemd_inc) -+INCLUDE_DIRECTORIES(../common) -+INCLUDE_DIRECTORIES(${GLIB2_INCLUDE_DIRS}) -+ -+SET(EXE etmem_thirdparty_ops_llt) -+SET(LIB thirdparty_engine) -+ -+add_library(${LIB} SHARED my_engine.c) -+add_executable(${EXE} etmem_thirdparty_ops_llt.c) -+ -+target_link_libraries(${EXE} ${LIB} ${LIBNULL} cunit ${BUILD_DIR}/lib/libetmemd.so -+ ${BUILD_DIR}/lib/libtest.so pthread dl rt boundscheck numa ${GLIB2_LIBRARIES}) -diff --git a/etmem/test/etmem_thirdparty_ops_llt_test/etmem_thirdparty_ops_llt.c b/etmem/test/etmem_thirdparty_ops_llt_test/etmem_thirdparty_ops_llt.c -new file mode 100644 -index 0000000..d7e7ae4 ---- /dev/null -+++ b/etmem/test/etmem_thirdparty_ops_llt_test/etmem_thirdparty_ops_llt.c -@@ -0,0 +1,425 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liubo -+ * Create: 2021-12-10 -+ * Description: This is a source file of the unit test for thirdparty functions in etmem. -+ ******************************************************************************/ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "test_common.h" -+#include "etmemd_thirdparty_export.h" -+#include "etmemd_project.h" -+ -+#define CONFIG_ENGINE_NAME "eng_name=%s\n" -+#define CONFIG_LIBNAME "libname=%s\n" -+#define CONFIG_OPS_NAME "ops_name=%s\n" -+#define CONFIG_ENGINE_PRIVATE_KEY "engine_private_key=%s\n" -+ -+#define CONFIG_TASK_PRIVATE_KEY "task_private_key=%s\n" -+ -+struct thirdparty_eng_param { -+ struct eng_test_param eng_param; -+ const char *engine_name; -+ const char *libname; -+ const char *ops_name; -+ const char *engine_private_key; -+}; -+ -+struct thirdparty_task_param { -+ struct task_test_param task_param; -+ const char *task_private_key; -+}; -+ -+static struct proj_test_param g_proj_param; -+ -+static void init_thirdparty_eng(struct thirdparty_eng_param *param, -+ const char *libname, const char *ops_name) -+{ -+ param->eng_param.name = "thirdparty"; -+ param->eng_param.proj = DEFAULT_PROJ; -+ param->eng_param.file_name = TMP_TASK_CONFIG; -+ param->engine_name = "my_engine"; -+ param->libname = libname; -+ param->ops_name = ops_name; -+ param->engine_private_key = "1024"; -+} -+ -+static void add_thirdparty_eng(struct thirdparty_eng_param *param) -+{ -+ FILE *file = NULL; -+ const char *file_name = param->eng_param.file_name; -+ -+ file = fopen(file_name, "a+"); -+ CU_ASSERT_PTR_NOT_NULL(file); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_ENGINE_NAME, param->engine_name), -1); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_LIBNAME, param->libname), -1); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_OPS_NAME, param->ops_name), -1); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_ENGINE_PRIVATE_KEY, param->engine_private_key), -1); -+ fclose(file); -+} -+ -+static GKeyFile *construct_thirdparty_eng_config(struct thirdparty_eng_param *param) -+{ -+ struct eng_test_param *eng_param = ¶m->eng_param; -+ -+ construct_eng_file(eng_param); -+ add_thirdparty_eng(param); -+ -+ return load_config(eng_param->file_name); -+} -+ -+static void destroy_thirdparty_eng_config(GKeyFile *config) -+{ -+ unload_config(config); -+} -+ -+static void init_thirdparty_task(struct thirdparty_task_param *param) -+{ -+ init_task_param(¶m->task_param, "my_engine"); -+ param->task_private_key = "2048"; -+} -+ -+static void add_thirdparty_task(struct thirdparty_task_param *param) -+{ -+ FILE *file = NULL; -+ const char *file_name = param->task_param.file_name; -+ -+ file = fopen(file_name, "a+"); -+ CU_ASSERT_PTR_NOT_NULL(file); -+ CU_ASSERT_NOT_EQUAL(fprintf(file, CONFIG_TASK_PRIVATE_KEY, param->task_private_key), -1); -+ fclose(file); -+} -+ -+static GKeyFile *construct_thirdparty_task_config(struct thirdparty_task_param *param) -+{ -+ struct task_test_param *task_param = ¶m->task_param; -+ -+ construct_task_file(task_param); -+ add_thirdparty_task(param); -+ -+ return load_config(task_param->file_name); -+} -+ -+static void destroy_thirdparty_task_config(GKeyFile *config) -+{ -+ unload_config(config); -+} -+ -+static void test_init(void) -+{ -+ init_proj_param(&g_proj_param); -+ do_add_proj_test(&g_proj_param); -+} -+ -+static void test_fini(void) -+{ -+ do_rm_proj_test(&g_proj_param); -+} -+ -+static void test_etmem_mgt_engine_error(void) -+{ -+ CU_ASSERT_EQUAL(etmemd_project_mgt_engine(NULL, NULL, NULL, DEFAULT_TASK, 0), OPT_INVAL); -+} -+ -+void test_etmem_user_engine_0001(void) -+{ -+ struct thirdparty_eng_param thirdparty_engine_param; -+ struct thirdparty_task_param thirdparty_task_param; -+ GKeyFile *eng_config = NULL; -+ GKeyFile *task_config = NULL; -+ -+ test_init(); -+ -+ init_thirdparty_eng(&thirdparty_engine_param, "./lib/libthirdparty_engine.so", "my_engine_ops"); -+ init_thirdparty_task(&thirdparty_task_param); -+ -+ eng_config = construct_thirdparty_eng_config(&thirdparty_engine_param); -+ CU_ASSERT_EQUAL(etmemd_project_add_engine(eng_config), OPT_SUCCESS); -+ -+ task_config = construct_thirdparty_task_config(&thirdparty_task_param); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(task_config), OPT_SUCCESS); -+ -+ CU_ASSERT_EQUAL(etmemd_migrate_start(DEFAULT_PROJ), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_mgt_engine(DEFAULT_PROJ, "my_engine", -+ "my_cmd", DEFAULT_TASK, 0), OPT_SUCCESS); -+ -+ /* test param NULL */ -+ CU_ASSERT_EQUAL(etmemd_project_mgt_engine(NULL, NULL, -+ NULL, DEFAULT_TASK, 0), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_mgt_engine(DEFAULT_PROJ, "no_exist_engine", -+ "my_cmd", DEFAULT_TASK, 0), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_mgt_engine(DEFAULT_PROJ, "my_engine", -+ "my_cmd", "no_exist_task", 0), OPT_SUCCESS); -+ -+ CU_ASSERT_EQUAL(etmemd_migrate_stop(DEFAULT_PROJ), OPT_SUCCESS); -+ -+ /* test for project not start */ -+ CU_ASSERT_EQUAL(etmemd_project_mgt_engine(DEFAULT_PROJ, "my_engine", -+ "my_cmd", DEFAULT_TASK, 0), OPT_INVAL); -+ -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(task_config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove_engine(eng_config), OPT_SUCCESS); -+ -+ destroy_thirdparty_task_config(task_config); -+ destroy_thirdparty_eng_config(eng_config); -+ -+ init_thirdparty_eng(&thirdparty_engine_param, "./lib/libthirdparty_engine.so", "start_error_ops"); -+ init_thirdparty_task(&thirdparty_task_param); -+ -+ eng_config = construct_thirdparty_eng_config(&thirdparty_engine_param); -+ CU_ASSERT_EQUAL(etmemd_project_add_engine(eng_config), OPT_SUCCESS); -+ -+ task_config = construct_thirdparty_task_config(&thirdparty_task_param); -+ /* start task fail when start projecct */ -+ CU_ASSERT_EQUAL(etmemd_project_add_task(task_config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_start(DEFAULT_PROJ), OPT_INTER_ERR); -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(task_config), OPT_SUCCESS); -+ -+ /* add task fail if project is already start */ -+ CU_ASSERT_EQUAL(etmemd_migrate_start(DEFAULT_PROJ), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(task_config), OPT_INTER_ERR); -+ -+ destroy_thirdparty_task_config(task_config); -+ destroy_thirdparty_eng_config(eng_config); -+ -+ test_fini(); -+} -+ -+static void test_etmem_user_engine_null(void) -+{ -+ struct thirdparty_eng_param thirdparty_engine_param; -+ struct thirdparty_task_param thirdparty_task_param; -+ GKeyFile *eng_config = NULL; -+ GKeyFile *task_config = NULL; -+ -+ test_init(); -+ -+ init_thirdparty_eng(&thirdparty_engine_param, "./lib/libthirdparty_engine.so", "start_not_null_ops"); -+ init_thirdparty_task(&thirdparty_task_param); -+ -+ eng_config = construct_thirdparty_eng_config(&thirdparty_engine_param); -+ task_config = construct_thirdparty_task_config(&thirdparty_task_param); -+ -+ /* only start task is not null to cover null mgt and stop */ -+ CU_ASSERT_EQUAL(etmemd_project_add_engine(eng_config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(task_config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_start(DEFAULT_PROJ), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_mgt_engine(DEFAULT_PROJ, "my_engine", -+ "my_cmd", DEFAULT_TASK, 0), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop(DEFAULT_PROJ), OPT_SUCCESS); -+ -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(task_config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove_engine(eng_config), OPT_SUCCESS); -+ -+ destroy_thirdparty_task_config(task_config); -+ destroy_thirdparty_eng_config(eng_config); -+ -+ test_fini(); -+ -+ test_init(); -+ -+ init_thirdparty_eng(&thirdparty_engine_param, "./lib/libthirdparty_engine.so", "start_null_ops"); -+ init_thirdparty_task(&thirdparty_task_param); -+ -+ eng_config = construct_thirdparty_eng_config(&thirdparty_engine_param); -+ task_config = construct_thirdparty_task_config(&thirdparty_task_param); -+ -+ /* start task manually */ -+ CU_ASSERT_EQUAL(etmemd_project_add_engine(eng_config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(task_config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_start(DEFAULT_PROJ), OPT_INTER_ERR); -+ CU_ASSERT_EQUAL(etmemd_project_remove_task(task_config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove_engine(eng_config), OPT_SUCCESS); -+ -+ /* start task auto (project is already start when add a task) */ -+ CU_ASSERT_EQUAL(etmemd_migrate_start(DEFAULT_PROJ), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_add_engine(eng_config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_add_task(task_config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove_engine(eng_config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_migrate_stop(DEFAULT_PROJ), OPT_SUCCESS); -+ -+ destroy_thirdparty_task_config(task_config); -+ destroy_thirdparty_eng_config(eng_config); -+ -+ test_fini(); -+} -+ -+static void test_etmem_invalid_config(void) -+{ -+ struct thirdparty_eng_param thirdparty_engine_param; -+ GKeyFile *eng_config = NULL; -+ -+ test_init(); -+ -+ /* test invalid so */ -+ init_thirdparty_eng(&thirdparty_engine_param, "./lib/invalid.so", "my_engine_ops"); -+ eng_config = construct_thirdparty_eng_config(&thirdparty_engine_param); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_engine(eng_config), OPT_SUCCESS); -+ destroy_thirdparty_eng_config(eng_config); -+ -+ /* test invalid engine name */ -+ init_thirdparty_eng(&thirdparty_engine_param, "./lib/libthirdparty_engine.so", "my_engine_ops"); -+ thirdparty_engine_param.engine_name = "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"; -+ eng_config = construct_thirdparty_eng_config(&thirdparty_engine_param); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_engine(eng_config), OPT_SUCCESS); -+ destroy_thirdparty_eng_config(eng_config); -+ -+ /* test invalid ops */ -+ init_thirdparty_eng(&thirdparty_engine_param, "./lib/libthirdparty_engine.so", "no_exist_ops"); -+ eng_config = construct_thirdparty_eng_config(&thirdparty_engine_param); -+ CU_ASSERT_NOT_EQUAL(etmemd_project_add_engine(eng_config), OPT_SUCCESS); -+ destroy_thirdparty_eng_config(eng_config); -+ -+ test_fini(); -+} -+ -+void test_etmem_user_engine_0002(void) -+{ -+ test_etmem_user_engine_null(); -+} -+ -+/* add correct thirdparty config */ -+void test_etmem_add_thirdparty_0001(void) -+{ -+ struct thirdparty_eng_param thirdparty_engine_param; -+ GKeyFile *config = NULL; -+ -+ test_init(); -+ -+ init_thirdparty_eng(&thirdparty_engine_param, "./lib/libthirdparty_engine.so", "my_engine_ops"); -+ config = construct_thirdparty_eng_config(&thirdparty_engine_param); -+ CU_ASSERT_EQUAL(etmemd_project_add_engine(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove_engine(config), OPT_SUCCESS); -+ destroy_thirdparty_eng_config(config); -+ -+ test_fini(); -+} -+ -+/* add wrong thirdparty config */ -+void test_etmem_add_thirdparty_0002(void) -+{ -+ test_etmem_invalid_config(); -+} -+ -+/* del correct thirdparty config */ -+void test_etmem_del_thirdparty_0001(void) -+{ -+ struct thirdparty_eng_param thirdparty_engine_param; -+ GKeyFile *config = NULL; -+ -+ test_init(); -+ -+ init_thirdparty_eng(&thirdparty_engine_param, "./lib/libthirdparty_engine.so", "my_engine_ops"); -+ config = construct_thirdparty_eng_config(&thirdparty_engine_param); -+ CU_ASSERT_EQUAL(etmemd_project_add_engine(config), OPT_SUCCESS); -+ CU_ASSERT_EQUAL(etmemd_project_remove_engine(config), OPT_SUCCESS); -+ destroy_thirdparty_eng_config(config); -+ -+ test_fini(); -+} -+ -+/* del wrong thirdparty config */ -+void test_etmem_del_thirdparty_0002(void) -+{ -+ struct thirdparty_eng_param thirdparty_engine_param; -+ GKeyFile *config = NULL; -+ -+ test_init(); -+ -+ /* del no exist engine */ -+ init_thirdparty_eng(&thirdparty_engine_param, "./lib/libthirdparty_engine.so", "my_engine_ops"); -+ config = construct_thirdparty_eng_config(&thirdparty_engine_param); -+ CU_ASSERT_EQUAL(etmemd_project_remove_engine(config), OPT_ENG_NOEXIST); -+ destroy_thirdparty_eng_config(config); -+ -+ test_fini(); -+} -+ -+void do_rm_proj_test(struct proj_test_param *param) -+{ -+ GKeyFile *config = NULL; -+ -+ config = load_config(param->file_name); -+ CU_ASSERT_EQUAL(etmemd_project_remove(config), param->expt); -+ unload_config(config); -+} -+ -+typedef enum { -+ CUNIT_SCREEN = 0, -+ CUNIT_XMLFILE, -+ CUNIT_CONSOLE -+} cu_run_mode; -+ -+int main(int argc, const char **argv) -+{ -+ CU_pSuite suite; -+ CU_pTest pTest; -+ unsigned int num_failures; -+ cu_run_mode cunit_mode = CUNIT_SCREEN; -+ int error_num; -+ -+ if (argc > 1) { -+ cunit_mode = atoi(argv[1]); -+ } -+ -+ if (CU_initialize_registry() != CUE_SUCCESS) { -+ return -CU_get_error(); -+ } -+ -+ suite = CU_add_suite("etmem_thirdparty_ops", NULL, NULL); -+ if (suite == NULL) { -+ goto ERROR; -+ } -+ -+ if (CU_ADD_TEST(suite, test_etmem_user_engine_0001) == NULL || -+ CU_ADD_TEST(suite, test_etmem_user_engine_0002) == NULL || -+ CU_ADD_TEST(suite, test_etmem_add_thirdparty_0001) == NULL || -+ CU_ADD_TEST(suite, test_etmem_add_thirdparty_0002) == NULL || -+ CU_ADD_TEST(suite, test_etmem_del_thirdparty_0001) == NULL || -+ CU_ADD_TEST(suite, test_etmem_del_thirdparty_0002) == NULL) { -+ printf("CU_ADD_TEST fail. \n"); -+ goto ERROR; -+ } -+ -+ switch (cunit_mode) { -+ case CUNIT_SCREEN: -+ CU_basic_set_mode(CU_BRM_VERBOSE); -+ CU_basic_run_tests(); -+ break; -+ case CUNIT_XMLFILE: -+ CU_set_output_filename("etmemd_thirdparty.c"); -+ CU_automated_run_tests(); -+ break; -+ case CUNIT_CONSOLE: -+ CU_console_run_tests(); -+ break; -+ default: -+ printf("not support cunit mode, only support: " -+ "0 for CUNIT_SCREEN, 1 for CUNIT_XMLFILE, 2 for CUNIT_CONSOLE\n"); -+ goto ERROR; -+ } -+ -+ num_failures = CU_get_number_of_failures(); -+ CU_cleanup_registry(); -+ return num_failures; -+ -+ERROR: -+ error_num = CU_get_error(); -+ CU_cleanup_registry(); -+ return -error_num; -+} -diff --git a/etmem/test/etmem_thirdparty_ops_llt_test/my_engine.c b/etmem/test/etmem_thirdparty_ops_llt_test/my_engine.c -new file mode 100644 -index 0000000..bd2a3bc ---- /dev/null -+++ b/etmem/test/etmem_thirdparty_ops_llt_test/my_engine.c -@@ -0,0 +1,156 @@ -+/****************************************************************************** -+ * Copyright (c) Huawei Technologies Co., Ltd. 2019-2021. All rights reserved. -+ * etmem is licensed under the Mulan PSL v2. -+ * You can use this software according to the terms and conditions of the Mulan PSL v2. -+ * You may obtain a copy of Mulan PSL v2 at: -+ * http://license.coscl.org.cn/MulanPSL2 -+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+ * PURPOSE. -+ * See the Mulan PSL v2 for more details. -+ * Author: liubo -+ * Create: 2021-12-10 -+ * Description: This is a source file of the unit test for task functions in etmem. -+ ******************************************************************************/ -+ -+#include -+#include -+#include -+ -+#include "etmemd_thirdparty_export.h" -+ -+char *get_private_value(GKeyFile *config, char *group, char *key) -+{ -+ if (g_key_file_has_key(config, group, key, NULL) == FALSE) { -+ return NULL; -+ } -+ -+ return g_key_file_get_string(config, group, key, NULL); -+} -+ -+char *get_params_str(void *str) -+{ -+ return str == NULL ? "NULL" : (char *)str; -+} -+ -+int fill_eng_params(GKeyFile *config, struct engine *eng) -+{ -+ /* engine_private_key is user defined key name in engine group in config file */ -+ eng->params = get_private_value(config, "engine", "engine_private_key"); -+ if (strcmp(eng->params, "1024") != 0) { -+ return -1; -+ } -+ -+ return 0; -+} -+ -+void clear_eng_params(struct engine *eng) -+{ -+ if (eng->params != NULL) { -+ free(eng->params); -+ eng->params = NULL; -+ } -+} -+ -+int fill_task_params(GKeyFile *config, struct task *task) -+{ -+ /* task_private_key is user defined key name in task group in config file */ -+ task->params = get_private_value(config, "task", "task_private_key"); -+ if (strcmp(task->params, "2048") != 0) { -+ return -1; -+ } -+ -+ return 0; -+} -+ -+void clear_task_params(struct task *task) -+{ -+ if (task->params != NULL) { -+ free(task->params); -+ task->params = NULL; -+ } -+} -+ -+int start_task(struct engine *eng, struct task *task) -+{ -+ return 0; -+} -+ -+static int my_start_task(struct engine *eng, struct task *tk) -+{ -+ return 0; -+} -+ -+int error_start_task(struct engine *eng, struct task *task) -+{ -+ return -1; -+} -+ -+void stop_task(struct engine *eng, struct task *task) -+{ -+} -+ -+int alloc_pid_params(struct engine *eng, struct task_pid **tk_pid) -+{ -+ return 0; -+} -+ -+void free_pid_params(struct engine *eng, struct task_pid **tk_pid) -+{ -+} -+ -+int eng_mgt_func(struct engine *eng, struct task *task, char *cmd, int fd) -+{ -+ char *msg = "msg to client\n"; -+ -+ write(fd, msg, strlen(msg)); -+ return 0; -+} -+ -+struct engine_ops my_engine_ops = { -+ .fill_eng_params = fill_eng_params, -+ .clear_eng_params = clear_eng_params, -+ .fill_task_params = fill_task_params, -+ .clear_task_params = clear_task_params, -+ .start_task = start_task, -+ .stop_task = stop_task, -+ .alloc_pid_params = alloc_pid_params, -+ .free_pid_params = free_pid_params, -+ .eng_mgt_func = eng_mgt_func, -+}; -+ -+struct engine_ops start_error_ops = { -+ .fill_eng_params = fill_eng_params, -+ .clear_eng_params = clear_eng_params, -+ .fill_task_params = fill_task_params, -+ .clear_task_params = clear_task_params, -+ .start_task = error_start_task, -+ .stop_task = stop_task, -+ .alloc_pid_params = alloc_pid_params, -+ .free_pid_params = free_pid_params, -+ .eng_mgt_func = eng_mgt_func, -+}; -+ -+struct engine_ops start_not_null_ops = { -+ .fill_eng_params = NULL, -+ .clear_eng_params = NULL, -+ .fill_task_params = NULL, -+ .clear_task_params = NULL, -+ .start_task = my_start_task, -+ .stop_task = NULL, -+ .alloc_pid_params = NULL, -+ .free_pid_params = NULL, -+ .eng_mgt_func = NULL, -+}; -+ -+struct engine_ops start_null_ops = { -+ .fill_eng_params = NULL, -+ .clear_eng_params = NULL, -+ .fill_task_params = NULL, -+ .clear_task_params = NULL, -+ .start_task = NULL, -+ .stop_task = NULL, -+ .alloc_pid_params = NULL, -+ .free_pid_params = NULL, -+ .eng_mgt_func = NULL, -+}; --- -1.8.3.1 - diff --git a/0073-etmem-add-testcode-script.patch b/0073-etmem-add-testcode-script.patch deleted file mode 100644 index 1369057..0000000 --- a/0073-etmem-add-testcode-script.patch +++ /dev/null @@ -1,308 +0,0 @@ -From 2d15999e02c34c2580bb8744a143806e4391338e Mon Sep 17 00:00:00 2001 -From: liubo -Date: Mon, 24 Jan 2022 07:52:02 +0800 -Subject: [PATCH 23/33] etmem: add testcode script - -add test.sh, the testcode compile and run script, for etmem. - -Signed-off-by: liubo ---- - etmem/test/test.sh | 286 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 286 insertions(+) - create mode 100644 etmem/test/test.sh - -diff --git a/etmem/test/test.sh b/etmem/test/test.sh -new file mode 100644 -index 0000000..55a8cd9 ---- /dev/null -+++ b/etmem/test/test.sh -@@ -0,0 +1,286 @@ -+#!/bin/bash -+ -+run_test_exit_value=0 -+usage() -+{ -+ echo "Usage: sh test.sh [OPTIONS]" -+ echo "Use test.sh to control test operation" -+ echo -+ echo "Misc:" -+ echo " -h, --help Print this help, then exit" -+ echo -+ echo "Compile Options:" -+ echo " -m, --cmake