From 9ffd2c7c909ded5a27dde76b63ef272988ebc347 Mon Sep 17 00:00:00 2001 From: YangXin <245051644@qq.com> Date: Fri, 1 Oct 2021 00:16:53 +0800 Subject: [PATCH] add new features memRouter and userswap. Signed-off-by: YangXin <245051644@qq.com> --- 0049-Add-engine-memdcd-to-etmemd.patch | 481 ++++++++++++++++++ ...ists.txt-for-three-features-of-etmem.patch | 39 ++ etmem.spec | 25 +- 3 files changed, 539 insertions(+), 6 deletions(-) create mode 100644 0049-Add-engine-memdcd-to-etmemd.patch create mode 100644 0050-Add-CMakeLists.txt-for-three-features-of-etmem.patch diff --git a/0049-Add-engine-memdcd-to-etmemd.patch b/0049-Add-engine-memdcd-to-etmemd.patch new file mode 100644 index 0000000..ec8bc1f --- /dev/null +++ b/0049-Add-engine-memdcd-to-etmemd.patch @@ -0,0 +1,481 @@ +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 new file mode 100644 index 0000000..8cd6ac7 --- /dev/null +++ b/0050-Add-CMakeLists.txt-for-three-features-of-etmem.patch @@ -0,0 +1,39 @@ +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/etmem.spec b/etmem.spec index 46752a8..a014c9c 100644 --- a/etmem.spec +++ b/etmem.spec @@ -2,7 +2,7 @@ Name: etmem Version: 1.0 -Release: 6 +Release: 7 Summary: etmem License: Mulan PSL v2 Source0: etmem-%{version}.tar.gz @@ -55,11 +55,13 @@ Patch44: 0045-add-dram_percent-to-etmem.patch Patch45: 0046-Fix-memory-leak-in-slide-engine.patch Patch46: 0047-move-all-the-files-to-sub-directory-of-etmem.patch Patch47: 0048-Commit-new-features-memRouter-and-userswap-to-etmem.patch +Patch48: 0049-Add-engine-memdcd-to-etmemd.patch +Patch49: 0050-Add-CMakeLists.txt-for-three-features-of-etmem.patch #Dependency BuildRequires: cmake gcc gcc-c++ -BuildRequires: libboundscheck -Requires: libboundscheck +BuildRequires: libboundscheck numactl-devel libcap-devel json-c-devel +Requires: libboundscheck json-c libcap numactl %description etmem module @@ -76,23 +78,34 @@ make %install mkdir -p $RPM_BUILD_ROOT%{_bindir} +mkdir -p $RPM_BUILD_ROOT%{_libdir} +mkdir -p $RPM_BUILD_ROOT%{_includedir} install -d $RPM_BUILD_ROOT%{_sysconfdir}/etmem/ -install -m 0500 build/bin/etmem $RPM_BUILD_ROOT%{_bindir} -install -m 0500 build/bin/etmemd $RPM_BUILD_ROOT%{_bindir} -install -m 0600 conf/example_conf.yaml $RPM_BUILD_ROOT%{_sysconfdir}/etmem/ +install -m 0500 etmem/build/bin/etmem $RPM_BUILD_ROOT%{_bindir} +install -m 0500 etmem/build/bin/etmemd $RPM_BUILD_ROOT%{_bindir} +install -m 0600 etmem/conf/example_conf.yaml $RPM_BUILD_ROOT%{_sysconfdir}/etmem/ +install -m 0550 build/memRouter/memdcd $RPM_BUILD_ROOT%{_bindir} +install -m 0550 build/userswap/libuswap.a $RPM_BUILD_ROOT%{_libdir} +install -m 0644 userswap/include/uswap_api.h $RPM_BUILD_ROOT%{_includedir} %files %defattr(-,root,root,0750) %{_bindir}/etmem %{_bindir}/etmemd %dir %{_sysconfdir}/etmem %{_sysconfdir}/etmem/example_conf.yaml +%{_bindir}/memdcd +%{_libdir}/libuswap.a +%{_includedir}/uswap_api.h %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %changelog +* Thu Oct 30 2021 yangxin <245051644@qq.com> 1.0-7 +- Update etmem and add new features memRouter and userswap.= + * Mon Aug 1 2021 louhongxiang 1.0-6 - cancel write permission of root.