diff --git a/0001-ipc-uds_event.c-remove-unused-variables.patch b/0001-ipc-uds_event.c-remove-unused-variables.patch new file mode 100644 index 0000000000000000000000000000000000000000..3bc1b02b16b44d60a4beeb8090510b1f551d9f15 --- /dev/null +++ b/0001-ipc-uds_event.c-remove-unused-variables.patch @@ -0,0 +1,27 @@ +From 565eac4e23c72a7a1c72f3b7e099685cfc18233a Mon Sep 17 00:00:00 2001 +From: zhujun2 +Date: Sun, 26 Nov 2023 23:00:59 -0800 +Subject: [PATCH 1/8] ipc/uds_event.c: remove unused variables + +These variables are never referenced in the code, just remove them + +Signed-off-by: zhujun2 +--- + qtfs/ipc/uds_event.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/qtfs/ipc/uds_event.c b/qtfs/ipc/uds_event.c +index 591b03f..4253deb 100644 +--- a/qtfs/ipc/uds_event.c ++++ b/qtfs/ipc/uds_event.c +@@ -504,7 +504,6 @@ int uds_event_remote_build(void *arg, int epfd, struct uds_event_global_var *p_e + static inline mode_t uds_msg_file_mode(int fd) + { + struct stat st; +- char path[32] = {0}; + if (fstat(fd, &st) != 0) { + uds_err("get fd:%d fstat failed, errno:%d", fd, errno); + } +-- +2.42.0.windows.2 + diff --git a/0002-qtfs-rexec-rexec_shim.c-remove-unused-variable.patch b/0002-qtfs-rexec-rexec_shim.c-remove-unused-variable.patch new file mode 100644 index 0000000000000000000000000000000000000000..eaa5526c5aa07d2651b57fb69a5ef7a3672ec900 --- /dev/null +++ b/0002-qtfs-rexec-rexec_shim.c-remove-unused-variable.patch @@ -0,0 +1,27 @@ +From 2def5c1fb5e9693d3cd8eb628b548f0ca9fb4ec1 Mon Sep 17 00:00:00 2001 +From: zhujun2 +Date: Mon, 27 Nov 2023 01:43:14 -0800 +Subject: [PATCH 2/8] qtfs/rexec/rexec_shim.c: remove unused variable + +The variable is never referenced in the code, just remove them + +Signed-off-by: zhujun2 +--- + qtfs/rexec/rexec_shim.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/qtfs/rexec/rexec_shim.c b/qtfs/rexec/rexec_shim.c +index 5bd8a19..6c62d3d 100644 +--- a/qtfs/rexec/rexec_shim.c ++++ b/qtfs/rexec/rexec_shim.c +@@ -100,7 +100,6 @@ void rshim_reg_file_resume(const char * const json_buf) + struct json_object *obj_offset; + int fd, perm, offset; + const char *path = NULL; +- int curfd = 3; // begin from 3 + struct json_object *fd_json = json_tokener_parse(json_buf); + if (fd_json == NULL) { + fprintf(stderr, "parse json error\n"); +-- +2.42.0.windows.2 + diff --git a/0003-qtfs_debug.patch b/0003-qtfs_debug.patch new file mode 100644 index 0000000000000000000000000000000000000000..ac9038c88071a950e22c76451503b30b4bac8e1f --- /dev/null +++ b/0003-qtfs_debug.patch @@ -0,0 +1,32 @@ +From bd7d13cba0246808ccf22eabcd118d9452b40703 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= +Date: Wed, 29 Nov 2023 08:46:01 +0000 +Subject: [PATCH 3/8] =?UTF-8?q?=E6=AD=A3=E5=B8=B8=E8=B7=AF=E5=BE=84?= + =?UTF-8?q?=E7=9A=84=E8=B0=83=E8=AF=95=E4=BF=A1=E6=81=AF=E6=94=B9=E4=B8=BA?= + =?UTF-8?q?qtfs=5Fdebug=EF=BC=8C=E9=81=BF=E5=85=8D=E5=A4=A7=E9=87=8F?= + =?UTF-8?q?=E6=89=93=E5=8D=B0=E6=AD=A3=E5=B8=B8=E4=BF=A1=E6=81=AF?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: 李强 +--- + qtfs/qtfs/syscall.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/qtfs/qtfs/syscall.c b/qtfs/qtfs/syscall.c +index 61a0de0..adebeaf 100644 +--- a/qtfs/qtfs/syscall.c ++++ b/qtfs/qtfs/syscall.c +@@ -56,7 +56,7 @@ static inline int qtfs_fstype_judgment(char __user *dir) + return 1; + } + path_put(&path); +- qtfs_info("qtfs fstype judge <%s> is not qtfs.\n", path.dentry->d_iname); ++ qtfs_debug("qtfs fstype judge <%s> is not qtfs.\n", path.dentry->d_iname); + + return 0; + } +-- +2.42.0.windows.2 + diff --git a/0004-rewrite-fifo-server-for-docker-offload.patch b/0004-rewrite-fifo-server-for-docker-offload.patch new file mode 100644 index 0000000000000000000000000000000000000000..8fcfa52198527ecc32086b7763da3e68e0a2be1c --- /dev/null +++ b/0004-rewrite-fifo-server-for-docker-offload.patch @@ -0,0 +1,350 @@ +From 3977b3e7e617577ebaa4d3c5682ee3a0c0df0cc4 Mon Sep 17 00:00:00 2001 +From: liqiang +Date: Fri, 1 Dec 2023 10:05:15 +0800 +Subject: [PATCH 4/8] rewrite fifo server for docker offload + +Signed-off-by: liqiang +--- + qtfs/qtfs_common/conn.c | 2 - + qtfs/qtfs_common/libsocket.c | 175 +++++++++++++++++++++++++++++++++ + qtfs/qtfs_common/libsocket.h | 29 ++++++ + qtfs/qtfs_common/misc.c | 5 + + qtfs/qtfs_common/user_engine.c | 40 ++++++++ + 5 files changed, 249 insertions(+), 2 deletions(-) + create mode 100644 qtfs/qtfs_common/libsocket.c + create mode 100644 qtfs/qtfs_common/libsocket.h + +diff --git a/qtfs/qtfs_common/conn.c b/qtfs/qtfs_common/conn.c +index ca9104d..99809d2 100644 +--- a/qtfs/qtfs_common/conn.c ++++ b/qtfs/qtfs_common/conn.c +@@ -894,8 +894,6 @@ struct qtfs_conn_var_s *qtfs_fifo_get_param(void) + // initialize conn_pvar here + pvar->recv_max = QTFS_FIFO_REQ_LEN; + pvar->send_max = QTFS_FIFO_REQ_LEN; +- pvar->magic_send = QTFS_FIFO_MAGIC_SEND; +- pvar->magic_recv = QTFS_FIFO_MAGIC_RECV; + pvar->user_type = QTFS_CONN_TYPE_FIFO; + g_pvar_ops->pvar_init(&pvar->conn_var, &pvar->conn_ops, pvar->user_type); + if (QTFS_OK != pvar->conn_ops->conn_var_init(pvar)) { +diff --git a/qtfs/qtfs_common/libsocket.c b/qtfs/qtfs_common/libsocket.c +new file mode 100644 +index 0000000..72151f1 +--- /dev/null ++++ b/qtfs/qtfs_common/libsocket.c +@@ -0,0 +1,175 @@ ++/****************************************************************************** ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. ++ * qtfs 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: Liqiang ++ * Create: 2023-11-23 ++ * Description: socket api in user-mode ++ *******************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "log.h" ++#include "libsocket.h" ++ ++struct lib_sock_arg { ++ int cs; // client(1) or server(2) ++ int sfamily; // vsock or tcp or uds ++ int stype; // SOCK_DGRAM or SOCK_STREAM ++ ++ struct sockaddr_storage saddr; ++}; ++ ++static inline int check_sock_arg(struct lib_sock_arg *arg) ++{ ++ if (arg->cs != LIBSOCK_CLIENT && arg->cs != LIBSOCK_SERVER) { ++ log_err("build new connection role invalid(%d) must be CLIENT(%d) or SERVER(%d)", arg->cs, LIBSOCK_CLIENT, LIBSOCK_SERVER); ++ return -1; ++ } ++ if (arg->sfamily != AF_VSOCK && arg->sfamily != AF_INET && arg->sfamily != AF_UNIX) { ++ log_err("build new connection family invalid(%d), just support AF_UNIX(%d)/AF_INET(%d)/AF_VSOCK(%d).", ++ arg->sfamily, AF_UNIX, AF_INET, AF_VSOCK); ++ return -1; ++ } ++ if (arg->stype != SOCK_DGRAM && arg->stype != SOCK_STREAM) { ++ log_err("build new connection type invalid(%d), just support SOCK_DGRAM or SOCK_STREAM.", ++ arg->stype, SOCK_DGRAM, SOCK_STREAM); ++ return -1; ++ } ++ return 0; ++} ++ ++static inline int get_sock_len(int family) ++{ ++ switch (family) { ++ case AF_VSOCK: ++ return sizeof(struct sockaddr_vm); ++ case AF_INET: ++ return sizeof(struct sockaddr_in); ++ case AF_UNIX: ++ return sizeof(struct sockaddr_un); ++ default: ++ break; ++ } ++ log_err("invalid family:%d", family); ++ return -1; ++} ++ ++static int libsock_build_connection(struct lib_sock_arg *arg) ++{ ++ int ret; ++#define MAX_LISTEN_NUM 64 ++ if (check_sock_arg(arg) != 0) { ++ log_err("Arg error, please check!"); ++ return -1; ++ } ++ ++ int sockfd = socket(arg->sfamily, arg->stype, 0); ++ if (sockfd < 0) { ++ log_err("As %s failed, socket fd:%d, errno:%d.", ++ (arg->cs == LIBSOCK_CLIENT) ? "client" : "server", sockfd, errno); ++ return -1; ++ } ++ ++ if (arg->cs == LIBSOCK_SERVER) { ++ if ((ret = bind(sockfd, (struct sockaddr *)&arg->saddr, get_sock_len(arg->sfamily))) < 0) { ++ log_err("As server failed socklen:%d, bind ret:%d error:%d", get_sock_len(arg->sfamily), ret, errno); ++ goto err_ret; ++ } ++ if ((ret = listen(sockfd, MAX_LISTEN_NUM)) < 0) { ++ log_err("As server listen failed ret:%d errno:%d", ret, errno); ++ goto err_ret; ++ } ++ } else { ++ if ((ret = connect(sockfd, (struct sockaddr *)&arg->saddr, get_sock_len(arg->sfamily))) < 0) { ++ log_err("As client failed socklen:%d, connect ret:%d errno:%d", get_sock_len(arg->sfamily), ret, errno); ++ goto err_ret; ++ } ++ } ++ return sockfd; ++ ++err_ret: ++ close(sockfd); ++ return -1; ++} ++ ++int libsock_accept(int sockfd, int family) ++{ ++ struct sockaddr_storage saddr; ++ socklen_t len = get_sock_len(family); ++ int connfd = accept(sockfd, (struct sockaddr *)&saddr, &len); ++ if (connfd <= 0) { ++ log_err("Accept failed sockfd:%d family:%d ret:%d errno:%d", sockfd, family, connfd, errno); ++ return -1; ++ } ++ return connfd; ++} ++ ++int libsock_build_inet_connection(char *ip, unsigned short port, enum libsock_cs_e cs) ++{ ++ struct lib_sock_arg arg; ++ struct sockaddr_in *in; ++ in = (struct sockaddr_in *)&arg.saddr; ++ ++ memset(&arg, 0, sizeof(struct lib_sock_arg)); ++ in->sin_family = AF_INET; ++ in->sin_port = htons(port); ++ in->sin_addr.s_addr = inet_addr(ip); ++ arg.cs = cs; ++ arg.sfamily = AF_INET; ++ arg.stype = SOCK_STREAM; ++ ++ int sockfd = libsock_build_connection(&arg); ++ if (sockfd < 0) { ++ log_err("build inet connection failed, ip:%s port:%u", ip, port); ++ return -1; ++ } ++ return sockfd; ++} ++ ++int libsock_build_vsock_connection(unsigned int cid, unsigned int port, enum libsock_cs_e cs) ++{ ++ struct lib_sock_arg arg; ++ struct sockaddr_vm *vm; ++ vm = (struct sockaddr_vm *)&arg.saddr; ++ ++ memset(&arg, 0, sizeof(struct lib_sock_arg)); ++ vm->svm_family = AF_VSOCK; ++ vm->svm_port = port; ++ vm->svm_cid = cid; ++ arg.cs = cs; ++ arg.sfamily = AF_VSOCK; ++ arg.stype = SOCK_STREAM; ++ ++ int sockfd = libsock_build_connection(&arg); ++ if (sockfd < 0) { ++ log_err("build vsock connection failed, cid:%u port:%u", cid, port); ++ return -1; ++ } ++ return sockfd; ++} ++ +diff --git a/qtfs/qtfs_common/libsocket.h b/qtfs/qtfs_common/libsocket.h +new file mode 100644 +index 0000000..b3f4074 +--- /dev/null ++++ b/qtfs/qtfs_common/libsocket.h +@@ -0,0 +1,29 @@ ++/****************************************************************************** ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. ++ * qtfs 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: Liqiang ++ * Create: 2023-11-23 ++ * Description: socket api in user-mode ++ *******************************************************************************/ ++ ++#ifndef __LIB_SOCKET_H__ ++#define __LIB_SOCKET_H__ ++ ++enum libsock_cs_e { ++ LIBSOCK_CLIENT = 1, ++ LIBSOCK_SERVER, ++}; ++ ++int libsock_accept(int sockfd, int family); ++int libsock_build_inet_connection(char *ip, unsigned short port, enum libsock_cs_e cs); ++int libsock_build_vsock_connection(unsigned int cid, unsigned int port, enum libsock_cs_e cs); ++ ++#endif ++ +diff --git a/qtfs/qtfs_common/misc.c b/qtfs/qtfs_common/misc.c +index 6f84b95..e1c3520 100644 +--- a/qtfs/qtfs_common/misc.c ++++ b/qtfs/qtfs_common/misc.c +@@ -277,6 +277,11 @@ long qtfs_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + } + qtfs_req_size(); + qtfs_diag_info->log_level = log_level; ++#ifdef QTFS_TEST_MODE ++ qtfs_diag_info->port = qtfs_server_port; ++#else ++ qtfs_diag_info->port = qtfs_server_vsock_port; ++#endif + qtfs_misc_flush_threadstate(); + qtfs_conn_list_cnt(); + if (copy_to_user((void *)arg, qtfs_diag_info, sizeof(struct qtinfo))) { +diff --git a/qtfs/qtfs_common/user_engine.c b/qtfs/qtfs_common/user_engine.c +index 4ce8b8e..90707c0 100644 +--- a/qtfs/qtfs_common/user_engine.c ++++ b/qtfs/qtfs_common/user_engine.c +@@ -39,6 +39,7 @@ + + #include "comm.h" + #include "ipc/uds_main.h" ++#include "qtfs_fifo.h" + + char wl_type_str[QTFS_WHITELIST_MAX][16] = { + "Open", +@@ -434,6 +435,26 @@ err: + return -1; + } + ++static unsigned int engine_get_kernel_port(int fd) ++{ ++ unsigned int port; ++ struct qtinfo *diag = (struct qtinfo *)malloc(sizeof(struct qtinfo)); ++ if (diag == NULL) { ++ engine_err("malloc failed."); ++ return -1; ++ } ++ memset(diag, 0, sizeof(struct qtinfo)); ++ int ret = ioctl(fd, QTFS_IOCTL_ALLINFO, diag); ++ if (ret != QTOK) { ++ engine_err("ioctl failed, ret:%d.", ret); ++ free(diag); ++ return -1; ++ } ++ port = diag->port; ++ free(diag); ++ return port; ++} ++ + #define QTFS_ENGINE_FD_LIMIT 65536 + static void engine_rlimit() + { +@@ -490,6 +511,7 @@ int main(int argc, char *argv[]) + + pthread_t texec[QTFS_MAX_THREADS]; + pthread_t tepoll; ++ pthread_t tfifo; + if (thread_nums < 0 || thread_nums > QTFS_MAX_THREADS) { + engine_err("qtfs engine parm invalid, thread_nums:%d(must <= %d).", + thread_nums, QTFS_MAX_THREADS); +@@ -506,6 +528,7 @@ int main(int argc, char *argv[]) + goto end; + } + struct engine_arg arg[QTFS_MAX_THREADS]; ++ struct fifo_server_arg_t fifo_arg; + for (int i = 0; i < thread_nums; i++) { + arg[i].psize = QTFS_USERP_SIZE; + arg[i].fd = fd; +@@ -513,6 +536,22 @@ int main(int argc, char *argv[]) + (void)pthread_create(&texec[i], NULL, qtfs_engine_kthread, &arg[i]); + } + (void)pthread_create(&tepoll, NULL, qtfs_engine_epoll_thread, &arg[0]); ++ ++#ifdef QTFS_TEST_MODE ++ fifo_arg.addr = argv[3]; ++ fifo_arg.family = AF_INET; ++#else ++ fifo_arg.cid = atoi(argv[3]); ++ fifo_arg.family = AF_VSOCK; ++#endif ++ fifo_arg.port = engine_get_kernel_port(fd); ++ if (fifo_arg.port < 0) { ++ engine_err("failed to get qtfs port."); ++ goto end; ++ } ++ engine_out("qtfs server port:%d set to fifo is:%d", fifo_arg.port, fifo_arg.port + 2); ++ fifo_arg.port += 2; // 默认约定epoll+1,fifo+2 ++ (void)pthread_create(&tfifo, NULL, fifo_server_main_thread, &fifo_arg); + // 必须放在这个位置,uds main里面最终也有join + if (uds_proxy_main(6, &argv[1]) != 0) { + engine_out("uds proxy start failed."); +@@ -524,6 +563,7 @@ int main(int argc, char *argv[]) + engine_out("qtfs engine join thread %d.", i); + } + pthread_join(tepoll, NULL); ++ pthread_join(tfifo, NULL); + engine_free: + qtfs_engine_userp_free(userp, thread_nums); + engine_out("qtfs engine join epoll thread."); +-- +2.42.0.windows.2 + diff --git a/0005-rewrite-fifo-server-for-docker-offload-part-2.patch b/0005-rewrite-fifo-server-for-docker-offload-part-2.patch new file mode 100644 index 0000000000000000000000000000000000000000..bdc7c2b0a9ae75715bc9cfca2c8a3b199e6f2597 --- /dev/null +++ b/0005-rewrite-fifo-server-for-docker-offload-part-2.patch @@ -0,0 +1,1180 @@ +From 8fbc4b3cc629c4856aec5283d34758f8514524cf Mon Sep 17 00:00:00 2001 +From: liqiang +Date: Fri, 1 Dec 2023 10:06:31 +0800 +Subject: [PATCH 5/8] rewrite fifo server for docker offload part 2 + +Signed-off-by: liqiang +--- + qtfs/include/comm.h | 1 + + qtfs/include/log.h | 43 +- + qtfs/include/qtfs_fifo.h | 14 + + qtfs/include/req.h | 54 ++- + qtfs/qtfs/fifo.c | 61 +-- + qtfs/qtfs/syscall.c | 2 +- + qtfs/qtfs_server/Makefile | 106 ++--- + qtfs/qtfs_server/server_fifo.c | 727 +++++++++++++++++++++++++++++++++ + 8 files changed, 906 insertions(+), 102 deletions(-) + create mode 100644 qtfs/include/qtfs_fifo.h + create mode 100644 qtfs/qtfs_server/server_fifo.c + +diff --git a/qtfs/include/comm.h b/qtfs/include/comm.h +index b275a1d..faa8ce3 100644 +--- a/qtfs/include/comm.h ++++ b/qtfs/include/comm.h +@@ -201,6 +201,7 @@ struct qtinfo { + int epoll_state; + int pvar_vld; // valid param's number + int pvar_busy; // busy param's number ++ unsigned int port; // qtfs port + }; + + #define QTINFO_STATE(state) ((state == QTCONN_INIT) ? "INIT" : \ +diff --git a/qtfs/include/log.h b/qtfs/include/log.h +index eaf3517..4df42b3 100644 +--- a/qtfs/include/log.h ++++ b/qtfs/include/log.h +@@ -14,7 +14,6 @@ + #ifndef __QTFS_LOG_H__ + #define __QTFS_LOG_H__ + +-#include + #include "comm.h" + + enum level { +@@ -25,6 +24,46 @@ enum level { + LOG_DEBUG + }; + ++#ifndef __KERNEL__ ++#include ++#define true 1 ++#define log_info(info, ...) \ ++ if (true) {\ ++ time_t t; \ ++ struct tm p; \ ++ time(&t); \ ++ localtime_r(&t, &p); \ ++ fprintf(stdout, "[%d/%02d/%02d %02d:%02d:%02d][LOG:%s:%3d]"info"\n", \ ++ p.tm_year + 1900, p.tm_mon+1, p.tm_mday, \ ++ p.tm_hour, p.tm_min, p.tm_sec, __func__, __LINE__, ##__VA_ARGS__); \ ++ } ++ ++#define log_warn(info, ...) \ ++ if (true) {\ ++ time_t t; \ ++ struct tm p; \ ++ time(&t); \ ++ localtime_r(&t, &p); \ ++ fprintf(stdout, "[%d/%02d/%02d %02d:%02d:%02d][WARN:%s:%3d]"info"\n", \ ++ p.tm_year + 1900, p.tm_mon+1, p.tm_mday, \ ++ p.tm_hour, p.tm_min, p.tm_sec, __func__, __LINE__, ##__VA_ARGS__); \ ++ } ++ ++#define log_err(info, ...) \ ++ if (true) {\ ++ time_t t; \ ++ struct tm p; \ ++ time(&t); \ ++ localtime_r(&t, &p); \ ++ fprintf(stderr, "[%d/%02d/%02d %02d:%02d:%02d][ERROR:%s:%3d]"info"\n", \ ++ p.tm_year + 1900, p.tm_mon+1, p.tm_mday, \ ++ p.tm_hour, p.tm_min, p.tm_sec, __func__, __LINE__, ##__VA_ARGS__); \ ++ } ++ ++#endif ++ ++#ifdef __KERNEL__ ++#include + extern int log_level; + + #define qtfs_crit(fmt, ...) \ +@@ -121,6 +160,6 @@ static inline int qtfs_log_init(char *level, int len) { + } \ + } \ + ) +- ++#endif + + #endif +diff --git a/qtfs/include/qtfs_fifo.h b/qtfs/include/qtfs_fifo.h +new file mode 100644 +index 0000000..f50a693 +--- /dev/null ++++ b/qtfs/include/qtfs_fifo.h +@@ -0,0 +1,14 @@ ++#ifndef __QTFS_FIFO_H__ ++#define __QTFS_FIFO_H__ ++ ++ ++struct fifo_server_arg_t { ++ char *addr; ++ unsigned int port; ++ unsigned int cid; ++ unsigned int family; // AF_VSOCK or AF_INET ++}; ++void *fifo_server_main_thread(void *arg); ++ ++#endif ++ +diff --git a/qtfs/include/req.h b/qtfs/include/req.h +index 70a6bf7..3591bd6 100644 +--- a/qtfs/include/req.h ++++ b/qtfs/include/req.h +@@ -14,12 +14,24 @@ + #ifndef __QTFS_REQ_STRUCT_DEF_H__ + #define __QTFS_REQ_STRUCT_DEF_H__ + ++#ifdef __KERNEL__ + #include + #include + #include ++#endif ++ ++#ifndef __KERNEL__ ++#define PATH_MAX 4096 ++typedef unsigned int u32; ++typedef int s32; ++typedef unsigned long u64; ++typedef long s64; ++#endif ++ + #include "comm.h" + #include "log.h" + ++ + enum qtreq_type { + QTFS_REQ_NULL, + QTFS_REQ_MOUNT, +@@ -100,8 +112,6 @@ struct qtfs_dirent64 { + #define MAX_ELSE_LEN (1024 * 128) + #define QTFS_REQ_MAX_LEN (MAX_PATH_LEN + MAX_ELSE_LEN) + +-#define MAX_BUF 4096 +- + // QTFS_TAIL_LEN解释: + // 私有数据结构最大长度为QTFS_REQ_MAX_LEN,超出就越界了 + // 一般有变长buf要求的,把变长buf放在末尾 +@@ -136,6 +146,7 @@ struct qtreq { + #define QTFS_FIFO_HEAD_LEN 32 // fifo只用很少的额外头,32应该足够了 + #define QTFS_FIFO_REQ_LEN (QTFS_MSG_HEAD_LEN + QTFS_FIFO_HEAD_LEN) + ++#ifdef __KERNEL__ + struct qtreq_ioctl { + struct qtreq_ioctl_len { + unsigned int cmd; +@@ -560,3 +571,42 @@ struct qtrsp_sc_sched_affinity { + unsigned long user_mask_ptr[0]; + }; + #endif ++ ++// fifo ++struct qtreq_fifo_open { ++ u32 flags; ++ u32 mode; ++ char path[MAX_PATH_LEN]; ++}; ++ ++struct qtrsp_fifo_open { ++ s32 err; ++}; ++ ++struct qtreq_fifo_read { ++ u64 len; ++}; ++ ++struct qtrsp_fifo_read { ++ s32 err; // same as kernel errcode, 0 is ok, < 0 is errcode ++ u64 len; ++}; ++ ++struct qtreq_fifo_write { ++ u64 len; ++}; ++ ++struct qtrsp_fifo_write { ++ s32 err; ++ u64 len; ++}; ++ ++struct qtreq_fifo_close { ++ // nothing ++}; ++ ++struct qtrsp_fifo_close { ++ // nothing ++}; ++ ++#endif +diff --git a/qtfs/qtfs/fifo.c b/qtfs/qtfs/fifo.c +index 2bf772b..ec68337 100644 +--- a/qtfs/qtfs/fifo.c ++++ b/qtfs/qtfs/fifo.c +@@ -24,45 +24,6 @@ + #include "req.h" + #include "log.h" + +-// 对接rust,长度对齐1字节 +-#pragma pack(1) +-struct qtreq_fifo_open { +- u32 flags; +- u32 mode; +- char path[MAX_PATH_LEN]; +-}; +- +-struct qtrsp_fifo_open { +- s32 errno; +-}; +- +-struct qtreq_fifo_read { +- u64 len; +-}; +- +-struct qtrsp_fifo_read { +- s32 errno; // same as kernel errcode, 0 is ok, < 0 is errcode +- u64 len; +-}; +- +-struct qtreq_fifo_write { +- u64 len; +-}; +- +-struct qtrsp_fifo_write { +- s32 errno; +- u64 len; +-}; +- +-struct qtreq_fifo_close { +- // nothing +-}; +- +-struct qtrsp_fifo_close { +- // nothing +-}; +-#pragma pack() +- + static void qtfs_fifo_put_file(struct file *file) + { + struct qtfs_conn_var_s *pvar = file->private_data; +@@ -109,7 +70,7 @@ int qtfs_fifo_open(struct inode *inode, struct file *file) + + fiforeq->flags = file->f_flags; + fiforeq->mode = file->f_mode; +- qtfs_debug("fifo open path:%s size req:%lu size open:%lu, flags:%llu mode%u", ++ qtfs_debug("fifo open path:%s size req:%lu size open:%lu, flags:%u mode%u", + fiforeq->path, sizeof(struct qtreq), QTFS_SEND_SIZE(struct qtreq_fifo_open, fiforeq->path), + fiforeq->flags, fiforeq->mode); + vec_save = pvar->vec_send; +@@ -120,10 +81,10 @@ int qtfs_fifo_open(struct inode *inode, struct file *file) + pvar->vec_send = vec_save; + pvar->send_max = sendmax_save; + +- if (IS_ERR_OR_NULL(rsp) || rsp->errno != 0) { +- ret = IS_ERR_OR_NULL(rsp) ? -EFAULT : -rsp->errno; ++ if (IS_ERR_OR_NULL(rsp) || rsp->err != 0) { ++ ret = IS_ERR_OR_NULL(rsp) ? -EFAULT : -rsp->err; + qtfs_fifo_put_param(pvar); +- qtfs_err("qtfs fifo open :%s failed mode:%o flag:%llx", fiforeq->path, fiforeq->mode, fiforeq->flags); ++ qtfs_err("qtfs fifo open :%s failed mode:%o flag:%x", fiforeq->path, fiforeq->mode, fiforeq->flags); + kfree(req); + return ret; + } +@@ -148,20 +109,26 @@ ssize_t qtfs_fifo_readiter(struct kiocb *kio, struct iov_iter *iov) + req = pvar->conn_ops->get_conn_msg_buf(pvar, QTFS_SEND); + req->len = iov_iter_count(iov); + pvar->vec_recv.iov_len = QTFS_MSG_HEAD_LEN + sizeof(struct qtrsp_fifo_read); ++ qtfs_info("fifo readiter len:%llu", req->len); + rsp = qtfs_remote_run(pvar, QTFS_REQ_READITER, sizeof(struct qtreq_fifo_read)); +- if (IS_ERR_OR_NULL(rsp) || rsp->errno != 0) { +- qtfs_err("remote run failed. or errno:%d", (rsp == NULL) ? -1 : rsp->errno); ++ if (IS_ERR_OR_NULL(rsp) || rsp->err != 0) { ++ qtfs_err("remote run failed. or errno:%d", (rsp == NULL) ? -1 : rsp->err); + return -EFAULT; + } + + while (total < rsp->len) { + ret = pvar->conn_ops->conn_recv_iter(&pvar->conn_var, iov, false); ++ if (ret == -EAGAIN) ++ continue; ++ + if (ret <= 0) { + qtfs_err("recv iter from conn module ret:%d", ret); + break; + } ++ iov->iov_offset += ret; + total += ret; + } ++ qtfs_info("fifo readiter over, total:%d, rsplen:%llu", total, rsp->len); + return total; + } + +@@ -180,8 +147,8 @@ ssize_t qtfs_fifo_writeiter(struct kiocb *kio, struct iov_iter *iov) + pvar->vec_recv.iov_len = QTFS_MSG_HEAD_LEN + sizeof(struct qtrsp_fifo_write); + pvar->iov_send = iov; + rsp = qtfs_remote_run(pvar, QTFS_REQ_WRITE, sizeof(struct qtreq_fifo_write)); +- if (IS_ERR_OR_NULL(rsp) || rsp->errno != 0) { +- qtfs_err("fifo write remote run failed, or errno:%d", (rsp == NULL) ? -1 : rsp->errno); ++ if (IS_ERR_OR_NULL(rsp) || rsp->err != 0) { ++ qtfs_err("fifo write remote run failed, or errno:%d", (rsp == NULL) ? -1 : rsp->err); + return -EFAULT; + } + return rsp->len; +diff --git a/qtfs/qtfs/syscall.c b/qtfs/qtfs/syscall.c +index adebeaf..61a0de0 100644 +--- a/qtfs/qtfs/syscall.c ++++ b/qtfs/qtfs/syscall.c +@@ -56,7 +56,7 @@ static inline int qtfs_fstype_judgment(char __user *dir) + return 1; + } + path_put(&path); +- qtfs_debug("qtfs fstype judge <%s> is not qtfs.\n", path.dentry->d_iname); ++ qtfs_info("qtfs fstype judge <%s> is not qtfs.\n", path.dentry->d_iname); + + return 0; + } +diff --git a/qtfs/qtfs_server/Makefile b/qtfs/qtfs_server/Makefile +index 08b70f5..4608365 100644 +--- a/qtfs/qtfs_server/Makefile ++++ b/qtfs/qtfs_server/Makefile +@@ -1,50 +1,56 @@ +-ifdef QTFS_TEST_MODE +-ccflags-y += -I$(src)/../ -I$(src) -I$(src)/../ipc/ -I$(src)/../include/ -DQTFS_SERVER -DQTFS_TEST_MODE +-CFLAGS += -DUDS_TEST_MODE +-else +-ccflags-y += -I$(src)/../ -I$(src) -I$(src)/../ipc/ -I$(src)/../include/ -DQTFS_SERVER +-endif +- +-CFLAGS += -g -O2 +-CFLAGS += -fstack-protector-strong +-CFLAGS += -fPIE -pie -fPIC +-CFLAGS += -D_FORTIFY_SOURCE=2 +-LDFLAGS += -Wl,-z,now +-LDFLAGS += -Wl,-z,noexecstack +-LDFLAGS += -fPIE -pie +- +-KBUILD=/lib/modules/$(shell uname -r)/build/ +-COMM=../qtfs_common/ +-COMMO=$(COMM)/conn.o $(COMM)/misc.o $(COMM)/symbol_wrapper.o $(COMM)/socket.o $(COMM)/qtfs_check.o +- +-obj-m:=qtfs_server.o +-qtfs_server-objs:=fsops.o qtfs-server.o $(COMMO) +- +-DEPGLIB=-lglib-2.0 -I../ -I../include/ -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include +- +-all: qtfs_server engine +- +-qtfs_server: +- make -C $(KBUILD) M=$(PWD) modules +- @test -z $(QTFS_TEST_MODE) || echo "Important risk warning: The test mode is turned on,\ +- and qtfs will expose the network port, which will bring security risks and is only for\ +- testing! If you do not understand the risks, please don't use or compile again without\ +- QTFS_TEST_MODE." +- +-engine: uds_event.o uds_main.o user_engine.o +- gcc $(LDFLAGS) -o engine $^ -lpthread $(DEPGLIB) -I../ -I../ipc/ -DQTFS_SERVER +- +-user_engine.o: +- cc $(CFLAGS) -c -o user_engine.o ../qtfs_common/user_engine.c $(DEPGLIB) -I../ -DQTFS_SERVER +- +-uds_event.o: +- cc $(CFLAGS) -c -o uds_event.o ../ipc/uds_event.c -DQTFS_SERVER $(DEPGLIB) +- +-uds_main.o: +- cc $(CFLAGS) -c -o uds_main.o ../ipc/uds_main.c -DQTFS_SERVER $(DEPGLIB) +- +-clean: +- make -C $(KBUILD) M=$(PWD) clean +- rm -rf engine +- rm -rf ../*.o +- rm -rf $(COMMO) $(COMM).*.o.cmd ++ifdef QTFS_TEST_MODE ++ccflags-y += -I$(src)/../ -I$(src) -I$(src)/../ipc/ -I$(src)/../include/ -DQTFS_SERVER -DQTFS_TEST_MODE ++CFLAGS += -DUDS_TEST_MODE -DQTFS_TEST_MODE ++else ++ccflags-y += -I$(src)/../ -I$(src) -I$(src)/../ipc/ -I$(src)/../include/ -DQTFS_SERVER ++endif ++ ++CFLAGS += -g -O2 ++CFLAGS += -fstack-protector-strong ++CFLAGS += -fPIE -pie -fPIC ++CFLAGS += -D_FORTIFY_SOURCE=2 ++LDFLAGS += -Wl,-z,now ++LDFLAGS += -Wl,-z,noexecstack ++LDFLAGS += -fPIE -pie ++ ++KBUILD=/lib/modules/$(shell uname -r)/build/ ++COMM=../qtfs_common/ ++COMMO=$(COMM)/conn.o $(COMM)/misc.o $(COMM)/symbol_wrapper.o $(COMM)/socket.o $(COMM)/qtfs_check.o ++ ++obj-m:=qtfs_server.o ++qtfs_server-objs:=fsops.o qtfs-server.o $(COMMO) ++ ++DEPGLIB=-lglib-2.0 -I../ -I../include/ -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include ++ ++all: qtfs_server engine ++ ++qtfs_server: ++ make -C $(KBUILD) M=$(PWD) modules ++ @test -z $(QTFS_TEST_MODE) || echo "Important risk warning: The test mode is turned on,\ ++ and qtfs will expose the network port, which will bring security risks and is only for\ ++ testing! If you do not understand the risks, please don't use or compile again without\ ++ QTFS_TEST_MODE." ++ ++engine: uds_event.o uds_main.o user_engine.o server_fifo.o libsocket.o ++ gcc $(LDFLAGS) -o engine $^ -lpthread $(DEPGLIB) -I../ -I../ipc/ -DQTFS_SERVER ++ ++libsocket.o: ++ cc $(CFLAGS) -c -o libsocket.o ../qtfs_common/libsocket.c -I../qtfs_common/ -I../include ++ ++server_fifo.o: ++ cc $(CFLAGS) -c -o server_fifo.o server_fifo.c -I../include/ -I../qtfs_common/ ++ ++user_engine.o: ++ cc $(CFLAGS) -c -o user_engine.o ../qtfs_common/user_engine.c $(DEPGLIB) -I../ -DQTFS_SERVER ++ ++uds_event.o: ++ cc $(CFLAGS) -c -o uds_event.o ../ipc/uds_event.c -DQTFS_SERVER $(DEPGLIB) ++ ++uds_main.o: ++ cc $(CFLAGS) -c -o uds_main.o ../ipc/uds_main.c -DQTFS_SERVER $(DEPGLIB) ++ ++clean: ++ make -C $(KBUILD) M=$(PWD) clean ++ rm -rf engine fifo_server ++ rm -rf ../*.o ++ rm -rf $(COMMO) $(COMM).*.o.cmd +diff --git a/qtfs/qtfs_server/server_fifo.c b/qtfs/qtfs_server/server_fifo.c +new file mode 100644 +index 0000000..a195304 +--- /dev/null ++++ b/qtfs/qtfs_server/server_fifo.c +@@ -0,0 +1,727 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "req.h" ++#include "log.h" ++#include "libsocket.h" ++#include "qtfs_fifo.h" ++ ++ ++/* ++ 总体架构 ++ 主线程:epoll所有fifo的读或写, ++ open线程:被epoll线程创建,阻塞打开fifo,打开后将fd加入epoll监听列表后退出。 ++ ++ 关于线程资源回收:open线程拉起时被设置为PTHREAD_CREATE_DETACHED属性,不进行主动回收。 ++ ++ open线程正常打开fd后,自己退出;还未打开fd,主线程收到对端关闭管道消息时会直接调用pthread_cancel杀死。 ++ 此处有可能有低概率并发资源泄漏问题:open线程刚好打开了fd,还没加入主线程时被主线程杀死。 ++*/ ++ ++static int epollfd = -1; ++static int sockfamily = AF_VSOCK; // 默认vsock ++static pthread_mutex_t fifomutex = PTHREAD_MUTEX_INITIALIZER; ++#define EPOLL_MAX_EVENT_NUMS 64 ++ ++enum { ++ FIFO_RET_OK, ++ FIFO_RET_ERR, ++ FIFO_RET_DEL, // only delete myself ++ FIFO_RET_DEL_BOTH, // delete myself and peer ++ FIFO_RET_SUSPEND, // 将此fd的事件挂起,不删除fd,只从epoll中去掉监听 ++}; ++ ++enum { ++ FIFO_INV, // 初始无效 ++ FIFO_READ, ++ FIFO_WRITE, ++ FIFO_BLOCK, ++ FIFO_NONBLOCK, ++}; ++ ++enum { ++ FIFO_PEER_PRE, ++ FIFO_PEER_ADD, ++ FIFO_PEER_POST, ++}; ++// 主线程epoll关键数据结构 ++struct fifo_event_t { ++ int fd; ++ struct fifo_event_t *peerevt; ++ ++ /* 触发时的操作函数 */ ++ int (*handler)(struct fifo_event_t *event); ++ // 仅在open阻塞状态有效,open完成后应该置空 ++ union { ++ void *priv; ++ int len; // valid read or write len ++ int peerfd; // priv fd ++ }; ++ unsigned long seq_num; ++ int block; // block fifo or nonblock ++}; ++ ++struct open_arg_t { ++ struct qtreq_fifo_open *req; ++ /* 此fifo对应在epoll主线程中的event结构, ++ 用于open成功后将fd加入main_event */ ++ struct fifo_event_t *main_evt; ++ /* open与主线程有竞争资源,因为open ++ 是临时的少量线程,放在open结构里少占用资源, ++ 只有在open线程中需要用锁,以及epoll线程中 ++ 在open状态的fd需要用锁,epoll线程非open状态 ++ 不需要加锁 */ ++ pthread_mutex_t mutex; ++ pthread_t *t; ++}; ++ ++static int fifo_rw_flags(unsigned int flags) ++{ ++ if (flags & O_WRONLY) ++ return FIFO_WRITE; ++ return FIFO_READ; ++} ++ ++static int fifo_block_flags(unsigned int flags) ++{ ++ if (flags & O_NONBLOCK) ++ return FIFO_NONBLOCK; ++ return FIFO_BLOCK; ++} ++ ++static int fifo_recv_with_timeout(int fd, char *msg, int len) ++{ ++#define TMOUT_BLOCK_SIZE 1024 ++#define TMOUT_UNIT_MS 20 ++#define TMOUT_INTERVAL 1 ++#define TMOUT_MAX_MS 1000 ++ int total_recv = 0; ++ int ret; ++ int tmout_ms = ((len / TMOUT_BLOCK_SIZE) + 1) * TMOUT_UNIT_MS; ++ if (len <= 0 || msg == NULL || fd < 0) { ++ log_err("invalid param fd:%d len:%d or %s", fd, len, (msg == NULL) ? "msg is NULL" : "msg is not NULL"); ++ return 0; ++ } ++ if (tmout_ms > TMOUT_MAX_MS) ++ tmout_ms = TMOUT_MAX_MS; ++ do { ++ ret = recv(fd, &msg[total_recv], len - total_recv, 0); ++ if (ret < 0) { ++ log_err("recv failed ret:%d errno:%d", ret, errno); ++ return ret; ++ } ++ total_recv += ret; ++ if (total_recv > len) { ++ log_err("fatal error total recv:%d longger than target len:%d", total_recv, len); ++ return 0; ++ } ++ if (total_recv == len) { ++ return total_recv; ++ } ++ usleep(TMOUT_INTERVAL * 1000); ++ tmout_ms -= TMOUT_INTERVAL; ++ } while (tmout_ms > 0); ++ log_err("Fatal error, the target recv len:%d and only %d length is received when it time out", len, total_recv); ++ return 0; ++} ++ ++struct fifo_event_t *fifo_add_event(int fd, struct fifo_event_t *peerevt, int (*handler)(struct fifo_event_t *), void *priv, unsigned int events) ++{ ++ struct epoll_event evt; ++ struct fifo_event_t *fifoevt = (struct fifo_event_t *)malloc(sizeof(struct fifo_event_t)); ++ if (fifoevt == NULL) { ++ log_err("failed to malloc event, fd:%d peer:%d errno:%d", fd, peerevt->fd, errno); ++ return NULL; ++ } ++ memset(fifoevt, 0, sizeof(struct fifo_event_t)); ++ fifoevt->fd = fd; ++ fifoevt->peerevt = peerevt; ++ fifoevt->handler = handler; ++ fifoevt->priv = priv; ++ evt.data.ptr = (void *)fifoevt; ++ evt.events = events; ++ if (-1 == epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &evt)) { ++ log_err("epoll add fd:%d peer:%d failed, errno:%d", fd, peerevt->fd, errno); ++ free(fifoevt); ++ return NULL; ++ } ++ return fifoevt; ++} ++ ++void fifo_del_event(struct fifo_event_t *evt) ++{ ++ // close fd, 内核会回收epoll资源 ++ close(evt->fd); ++ free(evt); ++ return; ++} ++ ++void fifo_suspend_event(struct fifo_event_t *evt) ++{ ++ struct epoll_event event; ++ event.data.ptr = (void *)evt; ++ if (epoll_ctl(epollfd, EPOLL_CTL_DEL, evt->fd, &event) == -1) { ++ log_err("suspend event fd:%d failed, errno:%d", evt->fd, errno); ++ } ++ free(evt); ++ return; ++} ++ ++static int fifo_peer_index; ++static struct fifo_event_t *fifo_peer_evt[EPOLL_MAX_EVENT_NUMS]; ++static int fifo_del_peer(int flag, struct fifo_event_t *peer) ++{ ++ switch (flag) { ++ case FIFO_PEER_PRE: ++ fifo_peer_index = 0; ++ memset(fifo_peer_evt, 0, sizeof(struct fifo_event_t *) * EPOLL_MAX_EVENT_NUMS); ++ break; ++ case FIFO_PEER_ADD: ++ fifo_peer_evt[fifo_peer_index] = peer; ++ break; ++ case FIFO_PEER_POST: ++ for (int i = 0; i < fifo_peer_index; i++) { ++ fifo_del_event(fifo_peer_evt[i]); ++ } ++ break; ++ default: ++ log_err("invalid flag:%d", flag); ++ break; ++ } ++ return 0; ++} ++ ++int fifo_mod_event(struct fifo_event_t *evt, unsigned int events) ++{ ++ struct epoll_event event; ++ event.data.ptr = (void *)evt; ++ event.events = events; ++ if (-1 == epoll_ctl(epollfd, EPOLL_CTL_MOD, evt->fd, &event)) { ++ log_err("modify event fd:%d failed, errno:%d", evt->fd, errno); ++ return -1; ++ } ++ return 0; ++} ++ ++static void fifo_proc_ack(struct fifo_event_t *evt, int type, int sockfd, char *arg, int arglen) ++{ ++ int ret; ++ struct qtreq rsp; ++ ++ rsp.type = type; ++ rsp.err = 0; ++ rsp.seq_num = evt->seq_num; ++ rsp.len = arglen; ++ ++ ret = write(sockfd, &rsp, sizeof(struct qtreq)); ++ if (ret < 0) { ++ log_err("fifo ack type:%d failed, sockfd:%d err:%d", type, sockfd, errno); ++ return; ++ } ++ ret = write(sockfd, arg, arglen); ++ if (ret < 0) { ++ log_err("fifo ack arg type:%d failed, sockfd:%d err:%d", type, sockfd, errno); ++ return; ++ } ++ log_info("Type:%d ack successed, sockfd:%d.", type, sockfd); ++ return; ++} ++ ++ ++int fifo_proc_unknown(struct fifo_event_t *evt) ++{ ++ struct open_arg_t *oarg; ++ log_info("unknown read/write event fd:%d happend, open event not complete!", evt->fd); ++ // 这不是预期的事件,直接删除此事件,且关联删除open线程 ++ pthread_mutex_lock(&fifomutex); ++ if (evt->priv) { ++ oarg = (struct open_arg_t *)evt->priv; ++ pthread_cancel(*oarg->t); ++ free(oarg->t); ++ free(oarg->req); ++ free(oarg); ++ evt->priv = NULL; ++ } ++ pthread_mutex_unlock(&fifomutex); ++ return FIFO_RET_DEL; ++} ++ ++// reverse是处理异常事件,正常情况下不会接受反向事件, ++// 如果有反向事件则说明是断连事件 ++int fifo_proc_reverse(struct fifo_event_t *evt) ++{ ++ log_info("reverse event happend."); ++ return FIFO_RET_OK; ++} ++ ++// 当读请求发生时,有可能阻塞,此时将fifo端加入监听,等到可读时 ++// 再触发处理,不在主线程中阻塞读 ++int fifo_proc_readable(struct fifo_event_t *evt) ++{ ++ // 读完立即将自己置为EPOLLHUP,不连续读取 ++ int ret; ++ char *msg; ++ struct qtrsp_fifo_read *rsp; ++ int readlen = evt->len; ++ if (readlen > QTFS_REQ_MAX_LEN) { ++ log_err("Read rsp len:%d too large!", readlen); ++ ret = EINVAL; ++ goto err_ack; ++ } ++ ++ msg = (char *)malloc(readlen + sizeof(struct qtrsp_fifo_read)); ++ if (msg == NULL) { ++ log_err("malloc memory failed, errno:%d", errno); ++ ret = ENOMEM; ++ goto err_ack; ++ } ++ ++ rsp = (struct qtrsp_fifo_read *)msg; ++ ret = read(evt->fd, &msg[sizeof(struct qtrsp_fifo_read)], readlen); ++ if (ret <= 0) { ++ log_err("read from fifo:%d failed, readlen:%d, errno:%d", evt->fd, readlen, errno); ++ ret = errno; ++ free(msg); ++ goto err_ack; ++ } ++ rsp->err = 0; ++ rsp->len = ret; ++ fifo_proc_ack(evt, QTFS_REQ_READITER, evt->peerevt->fd, msg, ret + sizeof(struct qtrsp_fifo_read)); ++ ++ log_info("readable event fd:%d peerfd:%d, readfromfd:%s, errno:%d", evt->fd, evt->peerevt->fd, &msg[sizeof(struct qtrsp_fifo_read)], errno); ++ free(msg); ++ evt->peerevt->peerevt = NULL; ++ // 读完立即删除本监听,如果继续读后面再添加进来 ++ return FIFO_RET_SUSPEND; ++ ++err_ack: ++ do { ++ struct qtrsp_fifo_read errrsp; ++ errrsp.err = ret; ++ errrsp.len = 0; ++ fifo_proc_ack(evt, QTFS_REQ_READITER, evt->peerevt->fd, (char *)&errrsp, sizeof(errrsp)); ++ } while (0); ++ evt->peerevt->peerevt = NULL; ++ return FIFO_RET_SUSPEND; ++} ++ ++int fifo_proc_writeable(struct fifo_event_t *evt) ++{ ++ // 写完立即将自己置为EPOLLHUP,不连续写 ++ int ret; ++ char *msg; ++ struct qtrsp_fifo_write rsp; ++ int writelen = evt->len; ++ if (writelen > QTFS_REQ_MAX_LEN) { ++ log_err("Read rsp len:%d too large!", writelen); ++ ret = EINVAL; ++ goto err_ack; ++ } ++ msg = (char *)malloc(writelen + sizeof(struct qtrsp_fifo_write)); ++ if (msg == NULL) { ++ log_err("malloc memory failed, errno:%d", errno); ++ ret = errno; ++ goto err_ack; ++ } ++ ret = fifo_recv_with_timeout(evt->peerevt->fd, msg, evt->len); ++ if (ret <= 0) { ++ log_err("recv socket write failed, fd:%d peer:%d, errno:%d.", evt->peerevt->fd, evt->fd, errno); ++ // 主线程是串行的,peerevt如果是空,则没有readable监听,直接close peerfd即可 ++ ret = errno; ++ free(msg); ++ goto err_ack; ++ } ++ ret = write(evt->fd, msg, ret); ++ if (ret <= 0) { ++ log_err("write to fifo failed, ret:%d errno:%d", ret, errno); ++ ret = errno; ++ free(msg); ++ goto err_ack; ++ } ++ rsp.err = 0; ++ rsp.len = ret; ++ fifo_proc_ack(evt, QTFS_REQ_WRITE, evt->peerevt->fd, (char *)&rsp, sizeof(struct qtrsp_fifo_write)); ++ ++ log_info("writeable event fd:%d peerfd:%d, writelen:%lu, errno:%d", evt->fd, evt->peerevt->fd, rsp.len, errno); ++ free(msg); ++ evt->peerevt->peerevt = NULL; ++ return FIFO_RET_SUSPEND; ++ ++err_ack: ++ do { ++ struct qtrsp_fifo_write errrsp; ++ errrsp.err = ret; ++ errrsp.len = 0; ++ fifo_proc_ack(evt, QTFS_REQ_WRITE, evt->peerevt->fd, (char *)&errrsp, sizeof(errrsp)); ++ } while (0); ++ return FIFO_RET_SUSPEND; ++} ++ ++// 处理读请求,读可能阻塞,因为打开时已经确定是否阻塞型, ++// 这里直接将peer改成监听状态去等待触发 ++int fifo_proc_read_req(struct fifo_event_t *evt) ++{ ++ struct qtreq_fifo_read req; ++ int ret; ++ ret = fifo_recv_with_timeout(evt->fd, (char *)&req, sizeof(req)); ++ if (ret <= 0) { ++ log_err("recv fifo read head failed, errno:%d.", errno); ++ // 主线程是串行的,peerevt如果是空,则没有readable监听,直接close peerfd即可 ++ if (evt->peerevt == NULL) { ++ close(evt->peerfd); ++ return FIFO_RET_DEL; ++ } ++ // 如果peerevt非空则要同时删除peer事件 ++ return FIFO_RET_DEL_BOTH; ++ } ++ log_info("recv read req len:%d", req.len); ++ if (evt->block == FIFO_NONBLOCK) { ++ struct fifo_event_t rd; ++ rd.fd = evt->peerfd; ++ rd.peerevt = evt; ++ rd.len = req.len; ++ rd.seq_num = evt->seq_num; ++ fifo_proc_readable(&rd); ++ return FIFO_RET_OK; ++ } ++ ++ // if fifo is block, dont block on main thread ++ struct fifo_event_t *newevt = fifo_add_event(evt->peerfd, evt, fifo_proc_readable, NULL, EPOLLIN); ++ if (newevt == NULL) { ++ log_err("add readable event failed, fd:%d socketfd:%d", evt->peerfd, evt->fd); ++ return FIFO_RET_ERR; ++ } ++ evt->peerevt = newevt; ++ newevt->len = req.len; ++ newevt->seq_num = evt->seq_num; ++ ++ return FIFO_RET_OK; ++} ++ ++// 写 ++int fifo_proc_write_req(struct fifo_event_t *evt) ++{ ++ struct qtreq_fifo_write req; ++ int ret; ++ ret = fifo_recv_with_timeout(evt->fd, (char *)&req, sizeof(req)); ++ if (ret <= 0) { ++ log_err("recv fifo write head failed, errno:%d.", errno); ++ // 主线程是串行的,peerevt如果是空,则没有readable监听,直接close peerfd即可 ++ if (evt->peerevt == NULL) { ++ close(evt->peerfd); ++ return FIFO_RET_DEL; ++ } ++ // 如果peerevt非空则要同时删除peer事件 ++ return FIFO_RET_DEL_BOTH; ++ } ++ log_info("recv write req len:%d", req.len); ++ if (evt->block == FIFO_NONBLOCK) { ++ struct fifo_event_t wr; ++ wr.fd = evt->peerfd; ++ wr.peerevt = evt; ++ wr.len = req.len; ++ wr.seq_num = evt->seq_num; ++ fifo_proc_writeable(&wr); ++ return FIFO_RET_OK; ++ } ++ // if fifo is block, dont block on main thread ++ struct fifo_event_t *newevt = fifo_add_event(evt->peerfd, evt, fifo_proc_writeable, NULL, EPOLLOUT); ++ if (newevt == NULL) { ++ log_err("add writeable event failed, fd:%d socketfd:%d", evt->peerfd, evt->fd); ++ return FIFO_RET_ERR; ++ } ++ evt->peerevt = newevt; ++ newevt->len = req.len; ++ newevt->seq_num = evt->seq_num; ++ ++ return FIFO_RET_OK; ++} ++ ++// read/write/close req ++int fifo_proc_new_req(struct fifo_event_t *evt) ++{ ++ struct qtreq head; ++ int ret; ++ ret = fifo_recv_with_timeout(evt->fd, (char *)&head, sizeof(struct qtreq)); ++ if (ret <= 0) { ++ log_err("recv qtreq head failed, errno:%d.", errno); ++ // 主线程是串行的,peerevt如果是空,则没有readable监听,直接close peerfd即可 ++ if (evt->peerevt == NULL) { ++ close(evt->peerfd); ++ return FIFO_RET_DEL; ++ } ++ // 如果peerevt非空则要同时删除peer事件 ++ return FIFO_RET_DEL_BOTH; ++ } ++ switch (head.type) { ++ case QTFS_REQ_CLOSE: ++ log_info("recv close req, close tcp fd:%d fifofd:%d", evt->fd, evt->peerfd); ++ evt->seq_num = head.seq_num; ++ fifo_proc_ack(evt, QTFS_REQ_CLOSE, evt->fd, NULL, 0); ++ if (evt->peerevt == NULL) { ++ close(evt->peerfd); ++ return FIFO_RET_DEL; ++ } ++ // 如果peerevt非空则要同时删除peer事件 ++ return FIFO_RET_DEL_BOTH; ++ ++ case QTFS_REQ_READITER: ++ log_info("recv readiter req, fd:%d peerfd:%d", evt->fd, evt->peerfd); ++ evt->seq_num = head.seq_num; ++ return fifo_proc_read_req(evt); ++ ++ case QTFS_REQ_WRITE: ++ log_info("recv write req, fd:%d peerfd:%d", evt->fd, evt->peerfd); ++ evt->seq_num = head.seq_num; ++ return fifo_proc_write_req(evt); ++ ++ default: ++ log_info("recv invalid req:%u fd:%d peerfd:%d", head.type, evt->fd, evt->peerfd); ++ break; ++ } ++ ++ return FIFO_RET_ERR; ++} ++ ++void *fifo_open_thread(void *arg) ++{ ++ int fd; ++ struct open_arg_t *oarg = (struct open_arg_t *)arg; ++ int rw; ++ int err = 0; ++ struct fifo_event_t *newevt; ++ struct qtrsp_fifo_open rsp = {.err = 0}; ++ ++ fd = open(oarg->req->path, oarg->req->flags, oarg->req->mode); ++ if (fd < 0) { ++ log_err("open fifo:%s failed, fd:%d errno:%d", oarg->req->path, fd, errno); ++ goto err_end; ++ } ++ rw = fifo_rw_flags(oarg->req->flags); ++ log_info("Recv open request fifo:%s flags:%x mode:%x rw:%d", oarg->req->path, oarg->req->flags, oarg->req->mode, rw); ++ ++ // read和write,代表的是向server端fifofd的操作方向,在初始状态,本 ++ // 代理不应该主动,只监听挂断事件,在通信对端发来read/write消息才 ++ // 改为监听可读/可写状态并进行实际读写。 ++ pthread_mutex_lock(&fifomutex); ++ if (rw == FIFO_READ) { ++ oarg->main_evt->peerevt = NULL; ++ oarg->main_evt->peerfd = fd; ++ oarg->main_evt->handler = fifo_proc_new_req; ++ } else { ++ oarg->main_evt->peerevt = NULL; ++ oarg->main_evt->handler = fifo_proc_new_req; ++ oarg->main_evt->peerfd = fd; ++ } ++ oarg->main_evt->block = fifo_block_flags(oarg->req->flags); ++ ++ // 按理说每个fifo的链接只有自己串行使用,不需要考虑两个线程竞争 ++ fifo_proc_ack(oarg->main_evt, QTFS_REQ_OPEN, oarg->main_evt->fd, (char *)&rsp, sizeof(rsp)); ++ ++ goto end; ++ ++err_end: ++ rsp.err = errno; ++ fifo_proc_ack(oarg->main_evt, QTFS_REQ_OPEN, oarg->main_evt->fd, (char *)&rsp, sizeof(rsp)); ++ ++end: ++ free(oarg->t); ++ free(oarg->req); ++ free(oarg); ++ pthread_mutex_unlock(&fifomutex); ++ return NULL; ++} ++ ++int fifo_proc_open_req(struct fifo_event_t *evt) ++{ ++ struct open_arg_t *oarg; ++ struct qtreq_fifo_open *req; ++ struct qtreq head; ++ pthread_t *t; ++ pthread_attr_t attr; ++ int ret; ++ ret = fifo_recv_with_timeout(evt->fd, (char *)&head, sizeof(head)); ++ if (ret <= 0) { ++ log_err("recv open head failed."); ++ return FIFO_RET_ERR; ++ } ++ log_info("recv head type:%u seq:%lu len:%d", head.type, head.seq_num, head.len); ++ if (head.len > sizeof(struct qtreq_fifo_open)) { ++ log_err("open head len:%d is too big", head.len); ++ return FIFO_RET_ERR; ++ } ++ // 按需申请path长度 ++ req = (struct qtreq_fifo_open *)malloc(head.len + 1); ++ if (req == NULL) { ++ // todo: 既然没有成功,要清理掉后面的消息体 ++ log_err("alloc memory failed, errno:%d", errno); ++ return FIFO_RET_ERR; ++ } ++ oarg = (struct open_arg_t *)malloc(sizeof(struct open_arg_t)); ++ if (oarg == NULL) { ++ log_err("alloc open arg memory failed, errno:%d", errno); ++ free(req); ++ return FIFO_RET_ERR; ++ } ++ memset(req, 0, head.len + 1); ++ ret = fifo_recv_with_timeout(evt->fd, (char *)req, head.len); ++ if (ret <= 0) { ++ log_err("recv req failed."); ++ free(req); ++ free(oarg); ++ return FIFO_RET_ERR; ++ } ++ pthread_mutex_init(&oarg->mutex, NULL); ++ oarg->main_evt = evt; ++ oarg->req = req; ++ evt->seq_num = head.seq_num; ++ ++ // create new open thread ++ pthread_attr_init(&attr); ++ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); ++ ++ t = (pthread_t *)malloc(sizeof(pthread_t)); ++ if (t == NULL) { ++ log_err("alloc memory failed, errno:%d", errno); ++ free(req); ++ free(oarg); ++ return FIFO_RET_ERR; ++ } ++ pthread_create(t, &attr, fifo_open_thread, oarg); ++ oarg->t = t; ++ ++ // 临时状态机,暂时不知道是读是写 ++ evt->priv = oarg; ++ evt->handler = fifo_proc_unknown; ++ ++ log_info("Start new fifo open thread head:%u, len:%d", head.type, head.len); ++ return FIFO_RET_OK; ++} ++ ++// mainsock 仅处理新连接建联,添加事件, ++// 单线程不能阻塞等消息,必须尽快让出线程使用权 ++int fifo_proc_main_sock(struct fifo_event_t *evt) ++{ ++ int ret; ++ struct qtreq headreq; ++ int connfd = libsock_accept(evt->fd, sockfamily); ++ if (connfd < 0) { ++ log_err("accept new connection failed, ret:%d errno:%d", connfd, errno); ++ return FIFO_RET_ERR; ++ } ++ // 新建联肯定是open请求了 ++ if (fifo_add_event(connfd, NULL, fifo_proc_open_req, NULL, EPOLLIN|EPOLLHUP) < 0) { ++ log_err("add new connection event failed."); ++ return FIFO_RET_ERR; ++ } ++ ++ return FIFO_RET_OK; ++} ++ ++void *fifo_server_main_thread(void *arg) ++{ ++ int indx = 0; ++ ++ int sockfd; ++ struct fifo_server_arg_t *parg = (struct fifo_server_arg_t *)arg; ++ struct epoll_event *evts = NULL; ++ ++ // init socket server ++ if (parg->family == AF_INET) { ++ sockfd = libsock_build_inet_connection(parg->addr, parg->port, LIBSOCK_SERVER); ++ } else { ++ sockfd = libsock_build_vsock_connection(parg->cid, parg->port, LIBSOCK_SERVER); ++ } ++ if (sockfd < 0) { ++ log_err("fifo server main thread start failed, please check input argument!"); ++ return NULL; ++ } ++ sockfamily = parg->family; ++ ++ // create epoll ++ epollfd = epoll_create1(0); ++ if (epollfd == -1) { ++ log_err("fifo server epoll create failed, errno:%d", errno); ++ goto epoll_create_err; ++ } ++ evts = calloc(EPOLL_MAX_EVENT_NUMS, sizeof(struct fifo_event_t)); ++ if (evts == NULL) { ++ log_err("fifo server calloc events failed, errno:%d", errno); ++ goto evts_calloc_err; ++ } ++ ++ fifo_add_event(sockfd, NULL, fifo_proc_main_sock, NULL, EPOLLIN); ++ ++ while (1) { ++ int ret; ++ struct fifo_event_t *event; ++ int n = epoll_wait(epollfd, evts, EPOLL_MAX_EVENT_NUMS, 1000); ++ if (n == 0) ++ continue; ++ if (n < 0) { ++ log_err("epoll wait err:%d, errno:%d", n, errno); ++ continue; ++ } ++ fifo_del_peer(FIFO_PEER_PRE, NULL); ++ for (int i = 0; i < n; i ++) { ++ event = (struct fifo_event_t *)evts[i].data.ptr; ++ log_info("new event fd:%d events:0x%x", event->fd, evts[i].events); ++ ret = event->handler(event); ++ if (ret == FIFO_RET_SUSPEND) { ++ fifo_suspend_event(event); ++ } else if (ret == FIFO_RET_DEL) { ++ fifo_del_event(event); ++ } else if (ret == FIFO_RET_DEL_BOTH) { ++ fifo_del_peer(FIFO_PEER_ADD, event->peerevt); ++ fifo_del_event(event); ++ } ++ } ++ fifo_del_peer(FIFO_PEER_POST, NULL); ++ } ++ ++ return NULL; ++ ++evts_calloc_err: ++ close(epollfd); ++ epollfd = -1; ++epoll_create_err: ++ close(sockfd); ++ log_err("fifo server error exit."); ++ return NULL; ++} ++ ++#ifdef TEST_FIFO ++int main() ++{ ++ struct fifo_server_arg_t arg; ++ pthread_t tfifo; ++ arg.addr = "10.44.142.32"; ++ arg.port = 12347; ++ arg.family = AF_INET; ++ pthread_create(&tfifo, NULL, fifo_server_main_thread, &arg); ++ pthread_join(tfifo, NULL); ++ ++ return 0; ++} ++#endif ++ +-- +2.42.0.windows.2 + diff --git a/0006-remove-rust-fifo-server.patch b/0006-remove-rust-fifo-server.patch new file mode 100644 index 0000000000000000000000000000000000000000..53b57074c3f875f2456cb9febcfd9176e92d1d31 --- /dev/null +++ b/0006-remove-rust-fifo-server.patch @@ -0,0 +1,458 @@ +From 1671ce937fc209ff12b45041df45559201f2c32d Mon Sep 17 00:00:00 2001 +From: liqiang +Date: Fri, 1 Dec 2023 11:17:12 +0800 +Subject: [PATCH 6/8] remove rust fifo server + +Signed-off-by: liqiang +--- + qtfs/qtfs_server/qtfs_fifo_server/Cargo.toml | 9 - + .../qtfs_fifo_server/src/cofifo.rs | 338 ------------------ + qtfs/qtfs_server/qtfs_fifo_server/src/main.rs | 72 ---- + 3 files changed, 419 deletions(-) + delete mode 100644 qtfs/qtfs_server/qtfs_fifo_server/Cargo.toml + delete mode 100644 qtfs/qtfs_server/qtfs_fifo_server/src/cofifo.rs + delete mode 100644 qtfs/qtfs_server/qtfs_fifo_server/src/main.rs + +diff --git a/qtfs/qtfs_server/qtfs_fifo_server/Cargo.toml b/qtfs/qtfs_server/qtfs_fifo_server/Cargo.toml +deleted file mode 100644 +index 803b5ed..0000000 +--- a/qtfs/qtfs_server/qtfs_fifo_server/Cargo.toml ++++ /dev/null +@@ -1,9 +0,0 @@ +-[package] +-name = "qtfs_fifo_server" +-version = "1.0.0" +-edition = "2021" +- +-[dependencies] +-tokio = { version = "1.29.1", features = ["full"]} +-libc = "0.2" +-rlimit = "0.10.1" +\ No newline at end of file +diff --git a/qtfs/qtfs_server/qtfs_fifo_server/src/cofifo.rs b/qtfs/qtfs_server/qtfs_fifo_server/src/cofifo.rs +deleted file mode 100644 +index db6805e..0000000 +--- a/qtfs/qtfs_server/qtfs_fifo_server/src/cofifo.rs ++++ /dev/null +@@ -1,338 +0,0 @@ +-/****************************************************************************** +- * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. +- * qtfs 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: Liqiang +- * Create: 2023-07-26 +- * Description: +- *******************************************************************************/ +- +-use tokio::net::TcpStream; +-use std::mem; +-use tokio::fs::File; +-use tokio::fs; +-use std::os::unix::fs::FileTypeExt; +-use tokio::fs::OpenOptions; +-use libc::{O_RDONLY, O_RDWR, O_WRONLY, O_ACCMODE}; +- +-use tokio::io::{AsyncReadExt, AsyncWriteExt}; +- +-#[derive(Debug, Clone, Copy)] +-#[repr(C, packed)] +-struct Qtreq { +- // magic: [u8; 4], //magic: 0x5aa55aa5 +- msgtype: u32, +- error: u32, +- seq_num: u64, +- len: usize, +-} +- +-const QTFS_REQ_OPEN: u32 = 2; +-const QTFS_REQ_CLOSE: u32 = 3; +-const QTFS_REQ_READ: u32 = 5; +-const QTFS_REQ_WRITE: u32 = 6; +-pub async fn qtfs_fifo_server(stream: TcpStream, idx: usize) { +- let mut conn = Conn {stream}; +- let mut head: Qtreq; +- +- match conn.qtfs_req_head(idx.clone()).await { +- Ok(h) => head = h, +- Err(e) => { +- println!("Recv invalid head exit this proc :{}.", e); +- return; +- } +- } +- if head.msgtype != QTFS_REQ_OPEN { +- println!("first msg type is invalid"); +- return; +- } +- let file = match conn.qtfs_fifo_open(head.clone()).await { +- Ok(f) => { +- head.len = mem::size_of::(); +- conn.req_head_ack(head).await; +- conn.open_ack(0).await; +- f +- } +- Err(e) => { +- head.len = mem::size_of::(); +- println!("Open fifo error:{}", e); +- conn.req_head_ack(head).await; +- conn.open_ack(1).await; +- return; +- } +- }; +- +- 'main: loop { +- let mut head: Qtreq; +- match conn.qtfs_req_head(idx.clone()).await { +- Ok(h) => head = h, +- Err(e) => { +- println!("head recv failed, {}.", e); +- return; +- } +- } +- match head.msgtype { +- QTFS_REQ_OPEN => { +- println!("Fifo is opened and recv open request again!"); +- head.len = mem::size_of::(); +- conn.req_head_ack(head).await; +- conn.open_ack(1).await; +- } +- QTFS_REQ_CLOSE => { +- println!("Close req idx:{}", idx.clone()); +- head.len = 0; +- conn.req_head_ack(head).await; +- break 'main; +- } +- QTFS_REQ_READ => { +- println!("Read req idx:{}", idx.clone()); +- conn.qtfs_fifo_read(file.try_clone().await.unwrap(), head).await; +- } +- QTFS_REQ_WRITE => { +- println!("Write req idx:{}", idx.clone()); +- conn.qtfs_fifo_write(file.try_clone().await.unwrap(), head).await; +- } +- _ => { +- println!("Recv invalid msg type"); +- } +- } +- } +- println!("Fifo server idx:{} is closed.", idx); +-} +- +-#[derive(Debug, Clone, Copy)] +-#[repr(C, packed)] +-struct Qtreqopen { +- flags: u32, +- mode: u32, +-} +-#[repr(C, packed)] +-struct Qtrspopen { +- ret: i32, +-} +- +-#[repr(C, packed)] +-struct Qtreqread { +- len: u64, +-} +- +-#[repr(C, packed)] +-struct Qtrspread { +- errno: i32, +- len: u64, +-} +- +- +- +-#[repr(C, packed)] +-struct Qtreqwrite { +- len: u64, +-} +-#[repr(C, packed)] +-struct Qtrspwrite { +- errno: i32, +- len: u64, +-} +- +-struct Conn { +- stream: TcpStream, +-} +- +-impl Conn { +- // sync head magic bytes sequence: 0x5a 0xa5 0x5a 0xa5 +- // 逐字节读取magic,连续匹配的四个字节即视为同步包头 +- async fn package_sync(&mut self) { +- let mut byte: [u8; 1] = [0; 1]; +- loop { +- self.stream.read_exact(&mut byte).await.unwrap(); +- if byte[0] != 0x5a {continue;} +- self.stream.read_exact(&mut byte).await.unwrap(); +- if byte[0] != 0xa5 {continue;} +- self.stream.read_exact(&mut byte).await.unwrap(); +- if byte[0] != 0x5a {continue;} +- self.stream.read_exact(&mut byte).await.unwrap(); +- if byte[0] != 0xa5 {continue;} +- break; +- } +- } +- +- async fn send_magic_head(&mut self) { +- const MAGIC: [u8; 4] = [0x5a, 0xa5, 0x5a, 0xa5]; +- let _ = self.stream.write_all(&MAGIC[0..4]).await; +- } +- +- async fn qtfs_req_head(&mut self, _idx: usize) -> Result { +- const HEADSIZE: usize = mem::size_of::(); +- self.package_sync().await; +- let mut msghead = [0; HEADSIZE]; +- self.stream.read_exact(&mut msghead).await?; +- let head = Qtreq { +- msgtype: u32::from_le_bytes(msghead[0..4].try_into().unwrap()), +- error: u32::from_le_bytes(msghead[4..8].try_into().unwrap()), +- seq_num: u64::from_le_bytes(msghead[8..16].try_into().unwrap()), +- len: usize::from_le_bytes(msghead[16..16+mem::size_of::()].try_into().unwrap()), +- }; +- let reqtype: String = match head.msgtype { +- QTFS_REQ_OPEN => String::from("Open"), +- QTFS_REQ_CLOSE => String::from("Close"), +- QTFS_REQ_READ => String::from("Read"), +- QTFS_REQ_WRITE => String::from("Write"), +- _ => String::from("Unknown"), +- }; +- println!("Recv new head type:{} msg:{:?}", reqtype, head); +- Ok(head) +- } +- +- async fn qtfs_fifo_open(&mut self, head: Qtreq) -> Result { +- const HEADSIZE: usize = mem::size_of::(); +- let mut openhead = [0; HEADSIZE]; +- +- if head.len >= 4096 + HEADSIZE { +- println!("qtfs fifo len invalid"); +- return Err(1); +- } +- self.stream.read_exact(&mut openhead).await.unwrap(); +- let openhead1 = Qtreqopen { +- flags: u32::from_le_bytes(openhead[0..4].try_into().unwrap()), +- mode: u32::from_le_bytes(openhead[4..8].try_into().unwrap()), +- }; +- println!("open head:{:?}", openhead1); +- let mut path = Vec::with_capacity(head.len - HEADSIZE); +- path.resize(head.len - HEADSIZE, 0); +- self.stream.read_exact(&mut path).await.unwrap(); +- +- let getstr = String::from_utf8(path).unwrap(); +- let pathstr = getstr.trim_end_matches('\0').trim(); +- match fs::metadata(pathstr.clone()).await { +- Ok(meta) => { +- if meta.file_type().is_fifo() == false { +- println!("Requst path:{} not fifo!", pathstr); +- return Err(1); +- } +- } +- Err(_) => { +- println!("path:{} check failed.", pathstr); +- return Err(1); +- } +- }; +- println!("Recv open path:{}", pathstr); +- let file = OpenOptions::new() +- .read((openhead1.flags as i32 & O_ACCMODE == O_RDONLY) || (openhead1.flags as i32 & O_ACCMODE == O_RDWR)) +- .write((openhead1.flags as i32 & O_ACCMODE == O_WRONLY) || (openhead1.flags as i32 & O_ACCMODE == O_RDWR)) +- .custom_flags(openhead1.flags as i32) +- .open(pathstr).await.unwrap(); +- +- Ok(file) +- } +- +- async fn qtfs_fifo_read(&mut self, mut file: File, mut reqhead: Qtreq) { +- let mut head = [0; mem::size_of::()]; +- self.stream.read_exact(&mut head).await.unwrap(); +- let req = Qtreqread { +- len: u64::from_le_bytes(head[0..8].try_into().unwrap()), +- }; +- let len = std::cmp::min(req.len, 4096); +- +- let mut rsp = Qtrspread { +- errno: 0, +- len: 0, +- }; +- +- let mut buf = Vec::with_capacity(len.try_into().unwrap()); +- buf.resize(len.try_into().unwrap(), 0); +- +- match file.read(&mut buf).await { +- Ok(n) => { +- rsp.len = n as u64; +- let send = unsafe { +- let ptr = &rsp as *const Qtrspread as *const u8; +- std::slice::from_raw_parts(ptr, mem::size_of::()) +- }; +- println!("Read {} bytes from fifo", n.clone()); +- reqhead.len = mem::size_of::(); +- self.req_head_ack(reqhead).await; +- self.stream.write_all(&send[..mem::size_of::()]).await.unwrap(); +- let _ = self.stream.write_all(&buf[..n]).await.unwrap(); +- } +- Err(e) => { +- rsp.errno = -1; +- rsp.len = 0; +- let send = unsafe { +- let ptr = &rsp as *const Qtrspread as *const u8; +- std::slice::from_raw_parts(ptr, mem::size_of::()) +- }; +- reqhead.len = mem::size_of::(); +- self.req_head_ack(reqhead).await; +- self.stream.write_all(&send[..mem::size_of::()]).await.unwrap(); +- println!("Read from fifo error:{}", e); +- } +- } +- } +- +- async fn qtfs_fifo_write(&mut self, mut file: File, mut reqhead: Qtreq) { +- let mut whead = [0; mem::size_of::()]; +- self.stream.read_exact(&mut whead).await.unwrap(); +- let len = u64::from_le_bytes(whead[0..8].try_into().unwrap()); +- +- // 最大接收一次性写入4k +- let len = std::cmp::min(len, 4096); +- +- let mut rsp = Qtrspwrite { +- errno: 0, +- len: 0, +- }; +- +- let mut buf = Vec::with_capacity(len.try_into().unwrap()); +- buf.resize(len.try_into().unwrap(), 0); +- self.stream.read_exact(&mut buf).await.unwrap(); +- +- match file.write_all(&mut buf[..len as usize]).await { +- Ok(_) => { +- rsp.len = len as u64; +- reqhead.len = mem::size_of::(); +- self.req_head_ack(reqhead).await; +- self.write_ack(rsp).await; +- println!("Write fifo ok, send ack."); +- } +- Err(e) => { +- rsp.len = 0; +- reqhead.len = mem::size_of::(); +- self.req_head_ack(reqhead).await; +- self.write_ack(rsp).await; +- println!("Write failed {}.", e); +- } +- } +- } +- +- async fn req_head_ack(&mut self, head: Qtreq) { +- let send = unsafe { +- let ptr = &head as *const Qtreq as *const u8; +- std::slice::from_raw_parts(ptr, mem::size_of::()) +- }; +- self.send_magic_head().await; +- self.stream.write_all(&send[..mem::size_of::()]).await.expect("req head ack failed"); +- } +- +- async fn open_ack(&mut self, retcode: i32) { +- let rsp = Qtrspopen {ret: retcode,}; +- let send = unsafe { +- let ptr = &rsp as *const Qtrspopen as *const u8; +- std::slice::from_raw_parts(ptr, mem::size_of::()) +- }; +- self.stream.write_all(&send[..mem::size_of::()]).await.expect("Response open failed"); +- } +- +- async fn write_ack(&mut self, rsp: Qtrspwrite) { +- let send = unsafe { +- let ptr = &rsp as *const Qtrspwrite as *const u8; +- std::slice::from_raw_parts(ptr, mem::size_of::()) +- }; +- self.stream.write_all(&send[..mem::size_of::()]).await.expect("Response write failed"); +- } +-} +\ No newline at end of file +diff --git a/qtfs/qtfs_server/qtfs_fifo_server/src/main.rs b/qtfs/qtfs_server/qtfs_fifo_server/src/main.rs +deleted file mode 100644 +index 4f8c0c4..0000000 +--- a/qtfs/qtfs_server/qtfs_fifo_server/src/main.rs ++++ /dev/null +@@ -1,72 +0,0 @@ +-/****************************************************************************** +- * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. +- * qtfs 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: Liqiang +- * Create: 2023-07-26 +- * Description: +- *******************************************************************************/ +- +-use std::env; +-use std::net::TcpListener; +-use tokio::net::TcpListener as AsyncTcpListener; +-use tokio::runtime::Builder; +- +-extern crate rlimit; +-use rlimit::Resource; +-use rlimit::setrlimit; +-mod cofifo; +- +-async fn set_rlimit_fd(){ +- let rlimit = Resource::NOFILE; +- let fd_limit = 65536; +- match setrlimit(rlimit, fd_limit, fd_limit) { +- Ok(_) => {}, +- Err(e) => println!("Set file rlimit to {} failed {}.", fd_limit, e), +- } +-} +- +-#[tokio::main] +-async fn main() { +- let args: Vec = env::args().collect(); +- if args.len() != 3 { +- let bin: String = args[0].trim().parse().expect("Binary name error"); +- println!("Usage example:"); +- println!(" {} 192.168.1.10:12310 10", bin); +- return; +- } +- set_rlimit_fd().await; +- let addr: String = args[1].trim().parse().expect("Input address: '192.168.1.10:12310'"); +- let max_block_threads: usize = args[2].trim().parse().expect("Input max blocking threads number in arg 2: like '10'"); +- let listener = TcpListener::bind(addr.clone()).unwrap(); +- let async_listener = AsyncTcpListener::from_std(listener).unwrap(); +- let runtime = Builder::new_multi_thread() +- .max_blocking_threads(max_block_threads) +- .enable_all() +- .build() +- .unwrap(); +- +- println!("Ready to listen addr:{}, max blocking threads:{}", addr, max_block_threads); +- +- let mut coroutine_idx: usize = 1; +- loop { +- let (s, _) = async_listener.accept().await.unwrap(); +- let cur_idx = coroutine_idx.clone(); +- coroutine_idx += 1; +- match Some(s) { +- Some(stream) => { +- // 收到一个新的fifo连接请求,拉起新的协程处理函数 +- runtime.spawn(cofifo::qtfs_fifo_server(stream, cur_idx)); +- } +- _ => { +- eprintln!("Accept error!"); +- } +- } +- } +-} +\ No newline at end of file +-- +2.42.0.windows.2 + diff --git a/0007-remove-unuse-test-code.patch b/0007-remove-unuse-test-code.patch new file mode 100644 index 0000000000000000000000000000000000000000..7c4d0dd4974af27194749419a095a92dd4581fa6 --- /dev/null +++ b/0007-remove-unuse-test-code.patch @@ -0,0 +1,37 @@ +From 2cd7dc685370771566df4c231f2e9c47a78f043c Mon Sep 17 00:00:00 2001 +From: liqiang +Date: Fri, 1 Dec 2023 11:18:21 +0800 +Subject: [PATCH 7/8] remove unuse test code + +Signed-off-by: liqiang +--- + qtfs/qtfs_server/server_fifo.c | 16 ---------------- + 1 file changed, 16 deletions(-) + +diff --git a/qtfs/qtfs_server/server_fifo.c b/qtfs/qtfs_server/server_fifo.c +index a195304..5a5b054 100644 +--- a/qtfs/qtfs_server/server_fifo.c ++++ b/qtfs/qtfs_server/server_fifo.c +@@ -709,19 +709,3 @@ epoll_create_err: + log_err("fifo server error exit."); + return NULL; + } +- +-#ifdef TEST_FIFO +-int main() +-{ +- struct fifo_server_arg_t arg; +- pthread_t tfifo; +- arg.addr = "10.44.142.32"; +- arg.port = 12347; +- arg.family = AF_INET; +- pthread_create(&tfifo, NULL, fifo_server_main_thread, &arg); +- pthread_join(tfifo, NULL); +- +- return 0; +-} +-#endif +- +-- +2.42.0.windows.2 + diff --git a/0008-support-fifo-epoll.patch b/0008-support-fifo-epoll.patch new file mode 100644 index 0000000000000000000000000000000000000000..e7551ebdbc40ecb1e412d7c40bcf09bb09ff1360 --- /dev/null +++ b/0008-support-fifo-epoll.patch @@ -0,0 +1,231 @@ +From f440f10fe5a1281bf1bb552a2f2d6a074b2b1029 Mon Sep 17 00:00:00 2001 +From: liqiang +Date: Fri, 1 Dec 2023 18:33:41 +0800 +Subject: [PATCH 8/8] support fifo epoll + +Signed-off-by: liqiang +--- + qtfs/include/req.h | 1 + + qtfs/qtfs/fifo.c | 68 ++++++++++++++++++++++++++++++---- + qtfs/qtfs/qtfs-mod.h | 1 + + qtfs/qtfs/sb.c | 1 + + qtfs/qtfs_common/user_engine.c | 4 ++ + qtfs/qtfs_server/server_fifo.c | 3 +- + 6 files changed, 70 insertions(+), 8 deletions(-) + +diff --git a/qtfs/include/req.h b/qtfs/include/req.h +index 3591bd6..a00b59e 100644 +--- a/qtfs/include/req.h ++++ b/qtfs/include/req.h +@@ -581,6 +581,7 @@ struct qtreq_fifo_open { + + struct qtrsp_fifo_open { + s32 err; ++ int fd; + }; + + struct qtreq_fifo_read { +diff --git a/qtfs/qtfs/fifo.c b/qtfs/qtfs/fifo.c +index ec68337..2b636bb 100644 +--- a/qtfs/qtfs/fifo.c ++++ b/qtfs/qtfs/fifo.c +@@ -26,7 +26,8 @@ + + static void qtfs_fifo_put_file(struct file *file) + { +- struct qtfs_conn_var_s *pvar = file->private_data; ++ struct private_data *priv = file->private_data; ++ struct qtfs_conn_var_s *pvar = (struct qtfs_conn_var_s *)priv->priv; + if (pvar == NULL) { + qtfs_err("fifo private data invalid to put"); + return; +@@ -44,11 +45,19 @@ int qtfs_fifo_open(struct inode *inode, struct file *file) + struct qtreq_fifo_open *fiforeq; + struct qtrsp_fifo_open *rsp; + struct qtfs_conn_var_s *pvar = NULL; ++ struct private_data *priv; + int ret; +- ++ ++ priv = (struct private_data *)kmalloc(sizeof(struct private_data), GFP_KERNEL); ++ if (priv == NULL) { ++ qtfs_err("qtfs fifo open kmalloc failed."); ++ return -ENOMEM; ++ } ++ + req = (struct qtreq *)kmalloc(sizeof(struct qtreq) + sizeof(struct qtreq_fifo_open), GFP_KERNEL); + if (req == NULL) { + qtfs_err("get fifo open memory failed."); ++ kfree(priv); + return -ENOMEM; + } + memset(req, 0, sizeof(struct qtreq) + sizeof(struct qtreq_fifo_open)); +@@ -57,6 +66,7 @@ int qtfs_fifo_open(struct inode *inode, struct file *file) + if (pvar == NULL) { + qtfs_err("fifo get param failed."); + kfree(req); ++ kfree(priv); + return -EINVAL; + } + fiforeq = (struct qtreq_fifo_open *)req->data; +@@ -64,6 +74,7 @@ int qtfs_fifo_open(struct inode *inode, struct file *file) + if (qtfs_fullname(fiforeq->path, file->f_path.dentry, sizeof(fiforeq->path)) < 0) { + qtfs_err("qtfs fifo fullname failed"); + kfree(req); ++ kfree(priv); + qtfs_fifo_put_param(pvar); + return -EINVAL; + } +@@ -86,17 +97,21 @@ int qtfs_fifo_open(struct inode *inode, struct file *file) + qtfs_fifo_put_param(pvar); + qtfs_err("qtfs fifo open :%s failed mode:%o flag:%x", fiforeq->path, fiforeq->mode, fiforeq->flags); + kfree(req); ++ kfree(priv); + return ret; + } + kfree(req); ++ priv->fd = rsp->fd; ++ priv->priv = pvar; + WARN_ON(file->private_data); +- file->private_data = pvar; ++ file->private_data = priv; + return 0; + } + + ssize_t qtfs_fifo_readiter(struct kiocb *kio, struct iov_iter *iov) + { +- struct qtfs_conn_var_s *pvar = kio->ki_filp->private_data; ++ struct private_data *priv = kio->ki_filp->private_data; ++ struct qtfs_conn_var_s *pvar = (struct qtfs_conn_var_s *)priv->priv; + struct qtreq_fifo_read *req; + struct qtrsp_fifo_read *rsp; + int total = 0; +@@ -134,7 +149,8 @@ ssize_t qtfs_fifo_readiter(struct kiocb *kio, struct iov_iter *iov) + + ssize_t qtfs_fifo_writeiter(struct kiocb *kio, struct iov_iter *iov) + { +- struct qtfs_conn_var_s *pvar = kio->ki_filp->private_data; ++ struct private_data *priv = kio->ki_filp->private_data; ++ struct qtfs_conn_var_s *pvar = (struct qtfs_conn_var_s *)priv->priv; + struct qtreq_fifo_write *req; + struct qtrsp_fifo_write *rsp; + +@@ -156,7 +172,8 @@ ssize_t qtfs_fifo_writeiter(struct kiocb *kio, struct iov_iter *iov) + + int qtfs_fifo_release(struct inode *inode, struct file *file) + { +- struct qtfs_conn_var_s *pvar = file->private_data; ++ struct private_data *priv = file->private_data; ++ struct qtfs_conn_var_s *pvar = (struct qtfs_conn_var_s *)priv->priv; + struct qtrsp_fifo_close *rsp = NULL; + if (pvar == NULL) { + qtfs_err("invalid fifo write req, private data is invalid"); +@@ -174,7 +191,44 @@ int qtfs_fifo_release(struct inode *inode, struct file *file) + static __poll_t + qtfs_fifo_poll(struct file *filp, poll_table *wait) + { +- return 0; ++ struct qtfs_inode_priv *priv = filp->f_inode->i_private; ++ __poll_t mask = 0; ++ struct list_head *p; ++ struct qtfs_conn_var_s *pvar; ++ struct qtreq_poll *req; ++ struct qtrsp_poll *rsp; ++ struct private_data *fpriv = (struct private_data *)filp->private_data; ++ ++ poll_wait(filp, &priv->readq, wait); ++ ++ p = &priv->readq.head; ++ ++ if (fpriv->fd < 0) { ++ qtfs_err("fifo poll priv file invalid."); ++ return 0; ++ } ++ pvar = qtfs_conn_get_param(); ++ if (pvar == NULL) { ++ qtfs_err("qtfs fifo poll get param failed."); ++ return 0; ++ } ++ req = pvar->conn_ops->get_conn_msg_buf(pvar, QTFS_SEND); ++ req->fd = fpriv->fd; ++ rsp = qtfs_remote_run(pvar, QTFS_REQ_FIFOPOLL, sizeof(struct qtreq_poll)); ++ if (IS_ERR_OR_NULL(rsp)) { ++ qtfs_conn_put_param(pvar); ++ return 0; ++ } ++ if (rsp->ret == QTFS_ERR) { ++ qtfs_err("qtfs fifo poll remote run error."); ++ qtfs_conn_put_param(pvar); ++ return 0; ++ } ++ mask = rsp->mask; ++ ++ qtfs_info("fifo poll success mask:%x", mask); ++ qtfs_conn_put_param(pvar); ++ return mask; + } + + struct file_operations qtfsfifo_ops = { +diff --git a/qtfs/qtfs/qtfs-mod.h b/qtfs/qtfs/qtfs-mod.h +index 3939e0f..cecce11 100644 +--- a/qtfs/qtfs/qtfs-mod.h ++++ b/qtfs/qtfs/qtfs-mod.h +@@ -48,6 +48,7 @@ extern struct kmem_cache *qtfs_inode_priv_cache; + + struct private_data { + int fd; ++ void *priv; + }; + + struct qtfs_inode_priv { +diff --git a/qtfs/qtfs/sb.c b/qtfs/qtfs/sb.c +index 88a8265..79f1f89 100644 +--- a/qtfs/qtfs/sb.c ++++ b/qtfs/qtfs/sb.c +@@ -263,6 +263,7 @@ int qtfs_open(struct inode *inode, struct file *file) + } + + data->fd = rsp->fd; ++ data->priv = NULL; + WARN_ON(file->private_data); + file->private_data = data; + qtfs_conn_put_param(pvar); +diff --git a/qtfs/qtfs_common/user_engine.c b/qtfs/qtfs_common/user_engine.c +index 90707c0..a3edac2 100644 +--- a/qtfs/qtfs_common/user_engine.c ++++ b/qtfs/qtfs_common/user_engine.c +@@ -322,6 +322,10 @@ int qtfs_whitelist_init(int fd) + FILE *fwl; + + fwl = fopen(WHITELIST_FILE, "r"); ++ if (fwl == NULL) { ++ engine_err("open white list file:%s failed, errno:%d", WHITELIST_FILE, errno); ++ return -1; ++ } + ret = fstat(fileno(fwl), &stats); + if (ret) { + engine_err("open white list file:%s failed.", WHITELIST_FILE); +diff --git a/qtfs/qtfs_server/server_fifo.c b/qtfs/qtfs_server/server_fifo.c +index 5a5b054..e1d9bd1 100644 +--- a/qtfs/qtfs_server/server_fifo.c ++++ b/qtfs/qtfs_server/server_fifo.c +@@ -308,7 +308,7 @@ int fifo_proc_readable(struct fifo_event_t *evt) + rsp->len = ret; + fifo_proc_ack(evt, QTFS_REQ_READITER, evt->peerevt->fd, msg, ret + sizeof(struct qtrsp_fifo_read)); + +- log_info("readable event fd:%d peerfd:%d, readfromfd:%s, errno:%d", evt->fd, evt->peerevt->fd, &msg[sizeof(struct qtrsp_fifo_read)], errno); ++ log_info("readable event fd:%d peerfd:%d, errno:%d", evt->fd, evt->peerevt->fd, errno); + free(msg); + evt->peerevt->peerevt = NULL; + // 读完立即删除本监听,如果继续读后面再添加进来 +@@ -535,6 +535,7 @@ void *fifo_open_thread(void *arg) + } + oarg->main_evt->block = fifo_block_flags(oarg->req->flags); + ++ rsp.fd = fd; + // 按理说每个fifo的链接只有自己串行使用,不需要考虑两个线程竞争 + fifo_proc_ack(oarg->main_evt, QTFS_REQ_OPEN, oarg->main_evt->fd, (char *)&rsp, sizeof(rsp)); + +-- +2.42.0.windows.2 + diff --git a/README.en.md b/README.en.md index 18d6d0ea32b0aa9a7857212eb4282cb2b4410048..8b1a3640454dbb1287f891457d98221f7fdd996e 100644 --- a/README.en.md +++ b/README.en.md @@ -1,7 +1,7 @@ # dpu-utilities #### Description -contain DPU utilities, like qtfs etc. +dpu-utilities is DPU customized software utility based on openEuler #### Software Architecture Software architecture description diff --git a/README.md b/README.md index 02e6d622f4f5193af4abb28f5baabb8fd567e7ca..2bf24d108819c61f19f7bfcc4b7829204a45fd3b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # dpu-utilities #### 介绍 -contain DPU utilities, like qtfs etc. +dpu-utilities is DPU customized software utility based on openEuler #### 软件架构 软件架构说明 diff --git a/dpu-utilities-1.0.tar.gz b/dpu-utilities-1.0.tar.gz deleted file mode 100644 index fce3c521161c73da1a9e93686e57baf0126076f8..0000000000000000000000000000000000000000 Binary files a/dpu-utilities-1.0.tar.gz and /dev/null differ diff --git a/dpu-utilities.spec b/dpu-utilities.spec index 2fa3cc59c537c5208cc8041287bb54bd22b05389..d2166fa71e74d7fc38007bd8d3a33b1933d0204a 100644 --- a/dpu-utilities.spec +++ b/dpu-utilities.spec @@ -1,18 +1,26 @@ Name: dpu-utilities Summary: openEuler dpu utilities -Version: 1.0 +Version: 1.5 Release: 2 License: GPL-2.0 -Source: %{name}-%{version}.tar.gz +Source: https://gitee.com/openeuler/dpu-utilities/repository/archive/v%{version}.tar.gz ExclusiveOS: linux +ExclusiveArch: x86_64 aarch64 URL: https://gitee.com/openeuler/dpu-utilities BuildRoot: %{_tmppath}/%{name}-%{version}-root Conflicts: %{name} < %{version}-%{release} Provides: %{name} = %{version}-%{release} %define kernel_version %(ver=`rpm -qa|grep kernel-devel`;echo ${ver#*kernel-devel-}) -BuildRequires: kernel-devel >= 5.10, gcc, make - +BuildRequires: kernel-devel >= 5.10, gcc, make, json-c-devel, glib2-devel +Patch1: 0001-ipc-uds_event.c-remove-unused-variables.patch +Patch2: 0002-qtfs-rexec-rexec_shim.c-remove-unused-variable.patch +Patch3: 0003-qtfs_debug.patch +Patch4: 0004-rewrite-fifo-server-for-docker-offload.patch +Patch5: 0005-rewrite-fifo-server-for-docker-offload-part-2.patch +Patch6: 0006-remove-rust-fifo-server.patch +Patch7: 0007-remove-unuse-test-code.patch +Patch8: 0008-support-fifo-epoll.patch %description This package contains the software utilities on dpu. @@ -26,34 +34,67 @@ imageTailor configration files for dpuos %package -n qtfs-client Summary: Client of qtfs +Requires: json-c, glib2 %description -n qtfs-client qtfs is a shared file system, this is the client of qtfs. %package -n qtfs-server Summary: Server of qtfs +Requires: json-c, glib2 %description -n qtfs-server qtfs is a shared file system, this is the server of qtfs. %prep -%autosetup -n %{name}-%{version} -p1 +%autosetup -n %{name}-v%{version} -p1 %build -cd %_builddir/%{name}-%{version}/qtfs/qtfs +sed -i "s#KBUILD=.*#KBUILD=/lib/modules/%{kernel_version}/build#" %_builddir/%{name}-v%{version}/qtfs/qtfs/Makefile +sed -i "s#KBUILD=.*#KBUILD=/lib/modules/%{kernel_version}/build#" %_builddir/%{name}-v%{version}/qtfs/qtfs_server/Makefile +cd %_builddir/%{name}-v%{version}/qtfs/qtfs +make +cd %_builddir/%{name}-v%{version}/qtfs/qtfs_server +make +cd %_builddir/%{name}-v%{version}/qtfs/rexec make -cd %_builddir/%{name}-%{version}/qtfs/qtfs_server +cd %_builddir/%{name}-v%{version}/qtfs/ipc make +cd %_builddir/%{name}-v%{version}/qtfs/qtinfo +export role=client +make qtcfg +mv qtcfg qtcfg_client +make clean +export role=server +make qtcfg %install mkdir -p $RPM_BUILD_ROOT/lib/modules/%{kernel_version}//extra mkdir -p $RPM_BUILD_ROOT/usr/bin/ -install %_builddir/%{name}-%{version}/qtfs/qtfs/qtfs.ko $RPM_BUILD_ROOT/lib/modules/%{kernel_version}/extra -install %_builddir/%{name}-%{version}/qtfs/qtfs_server/qtfs_server.ko $RPM_BUILD_ROOT/lib/modules/%{kernel_version}/extra -install -m 0700 %_builddir/%{name}-%{version}/qtfs/qtfs_server/engine $RPM_BUILD_ROOT/usr/bin/ +mkdir -p $RPM_BUILD_ROOT/usr/lib/ +mkdir -p $RPM_BUILD_ROOT/usr/local/bin +mkdir -p $RPM_BUILD_ROOT/etc/qtfs +mkdir -p $RPM_BUILD_ROOT/etc/rexec +install %_builddir/%{name}-v%{version}/qtfs/qtfs/qtfs.ko $RPM_BUILD_ROOT/lib/modules/%{kernel_version}/extra +install %_builddir/%{name}-v%{version}/qtfs/qtfs_server/qtfs_server.ko $RPM_BUILD_ROOT/lib/modules/%{kernel_version}/extra +install -m 0700 %_builddir/%{name}-v%{version}/qtfs/qtfs_server/engine $RPM_BUILD_ROOT/usr/bin/ +install -m 0700 %_builddir/%{name}-v%{version}/qtfs/rexec/rexec ${RPM_BUILD_ROOT}/usr/bin/ +install -m 0700 %_builddir/%{name}-v%{version}/qtfs/rexec/rexec_server ${RPM_BUILD_ROOT}/usr/bin/ +install -m 0700 %_builddir/%{name}-v%{version}/qtfs/ipc/udsproxyd ${RPM_BUILD_ROOT}/usr/bin/ +install -m 0700 %_builddir/%{name}-v%{version}/qtfs/ipc/libudsproxy.so ${RPM_BUILD_ROOT}/usr/lib/ +install -m 0700 %_builddir/%{name}-v%{version}/qtfs/qtinfo/qtcfg ${RPM_BUILD_ROOT}/usr/bin/ +install -m 0700 %_builddir/%{name}-v%{version}/qtfs/qtinfo/qtcfg_client ${RPM_BUILD_ROOT}/usr/local/bin/qtcfg +install -m 0400 %_builddir/%{name}-v%{version}/qtfs/config/rexec/whitelist ${RPM_BUILD_ROOT}/etc/rexec +install -m 0400 %_builddir/%{name}-v%{version}/qtfs/config/qtfs/whitelist ${RPM_BUILD_ROOT}/etc/qtfs mkdir -p $RPM_BUILD_ROOT/opt/imageTailor -cp -rf %_builddir/%{name}-%{version}/dpuos/image_tailor_cfg/custom $RPM_BUILD_ROOT/opt/imageTailor -cp -rf %_builddir/%{name}-%{version}/dpuos/image_tailor_cfg/kiwi $RPM_BUILD_ROOT/opt/imageTailor +%ifarch x86_64 +cp -rf %_builddir/%{name}-v%{version}/dpuos/image_tailor_cfg/x86_64/custom $RPM_BUILD_ROOT/opt/imageTailor +cp -rf %_builddir/%{name}-v%{version}/dpuos/image_tailor_cfg/x86_64/kiwi $RPM_BUILD_ROOT/opt/imageTailor +%endif +%ifarch aarch64 +cp -rf %_builddir/%{name}-v%{version}/dpuos/image_tailor_cfg/aarch64/custom $RPM_BUILD_ROOT/opt/imageTailor +cp -rf %_builddir/%{name}-v%{version}/dpuos/image_tailor_cfg/aarch64/kiwi $RPM_BUILD_ROOT/opt/imageTailor +%endif %clean rm -rf ${RPM_BUILD_ROOT} @@ -80,11 +121,22 @@ fi %files -n qtfs-client -/lib/modules/%{kernel_version}/extra/qtfs.ko +%attr(0644, root, root) /lib/modules/%{kernel_version}/extra/qtfs.ko +%attr(0500, root, root) /usr/bin/rexec_server +%attr(0500, root, root) /usr/bin/rexec +%attr(0500, root, root) /usr/lib/libudsproxy.so +%attr(0500, root, root) /usr/bin/udsproxyd +%attr(0500, root, root) /usr/local/bin/qtcfg +%attr(0400, root, root) /etc/rexec/whitelist %files -n qtfs-server -/lib/modules/%{kernel_version}/extra/qtfs_server.ko -%attr(0700, root, root) /usr/bin/engine +%attr(0644, root, root) /lib/modules/%{kernel_version}/extra/qtfs_server.ko +%attr(0500, root, root) /usr/bin/engine +%attr(0500, root, root) /usr/bin/rexec_server +%attr(0500, root, root) /usr/bin/rexec +%attr(0500, root, root) /usr/bin/qtcfg +%attr(0400, root, root) /etc/qtfs/whitelist +%attr(0400, root, root) /etc/rexec/whitelist %files -n dpuos-imageTailor-config /opt/imageTailor/custom/* @@ -96,6 +148,35 @@ sed -i '/# product cut_conf/a\dpuos kiwi/minios/cfg_dpuos yes' /opt/imageT sed -i '//a\dpuos 1 rpm-dir euler_base' /opt/imageTailor/repos/RepositoryRule.conf %changelog +* Thu Dec 1 2023 Guangxing Deng 1.5-2 +- Sync patches from source repo + +* Thu Nov 23 2023 Guangxing Deng 1.5-1 +- Upgrade dpu-utilities version to 1.5 + +* Mon Aug 21 2023 Weifeng Su 1.4-3 +- Adapt for kernel 6.4 + +* Mon Jun 12 2023 Weifeng Su 1.4-2 +- Sync patches from source + +* Fri Jun 2 2023 Weifeng Su 1.4-1 +- Upgrade dpu-utilities version to 1.4 + +* Tue Mar 21 2023 Weifeng Su 1.3-1 +- Upgrade dpu-utilities version to 1.3 + +* Thu Dec 15 2022 YangXin <245051644@qq.com> 1.1-4 +- Fix inode sync error between client and server. +* Thu Dec 8 2022 Weifeng Su 1.1-3 +- Sync patches from master + +* Thu Dec 1 2022 Weifeng Su 1.1-2 +- add path put in xattr set + +* Mon Nov 28 2022 Weifeng Su 1.1-1 +- Upgrade dpu-utilities version to 1.1 + * Wed Aug 17 2022 yangxin <245051644@qq.com> 1.0-2 - Split dpu-utilities into three packages. * Fri Aug 12 2022 yangxin <245051644@qq.com> 1.0-1 diff --git a/v1.5.tar.gz b/v1.5.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..c3edaded445d91d67b3ce01d0ab994d900fca25f Binary files /dev/null and b/v1.5.tar.gz differ