代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/criu 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From a22542173083d2eeb5dde627c47452ea641c98c1 Mon Sep 17 00:00:00 2001
From: Sang Yan <sangyan@huawei.com>
Date: Mon, 12 Jul 2021 16:14:45 +0800
Subject: [PATCH 40/72] net: add shared socket recover method for criu
When the socket file is shared with another process,
it will not be freed during dumping process.
We can repair the socket file by installing it to
the old fd number.
Add new options: "--share-dst-ports" and "--share-src-ports"
for user to tell criu which socket ports are shared.
Conflict:NA
Reference:https://gitee.com/src-openeuler/criu/pulls/21
Signed-off-by: Jingxian He <hejingxian@huawei.com>
---
criu/config.c | 8 ++
criu/crtools.c | 3 +
criu/files.c | 18 ++++-
criu/include/cr_options.h | 2 +
criu/include/files.h | 4 +
criu/include/net.h | 1 +
criu/include/sk-inet.h | 3 +
criu/sk-inet.c | 151 ++++++++++++++++++++++++++++++++++++++
8 files changed, 189 insertions(+), 1 deletion(-)
diff --git a/criu/config.c b/criu/config.c
index 0a0623a..7e92731 100644
--- a/criu/config.c
+++ b/criu/config.c
@@ -706,6 +706,8 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd,
BOOL_OPT("mask-exit-notify", &opts.mask_exit_notify),
BOOL_OPT("weak-file-check", &opts.weak_file_check),
BOOL_OPT("file-locks-repair", &opts.file_locks_repair),
+ { "share-dst-ports", required_argument, 0, 2000 },
+ { "share-src-ports", required_argument, 0, 2001 },
{},
};
@@ -1041,6 +1043,12 @@ int parse_options(int argc, char **argv, bool *usage_error, bool *has_exec_cmd,
return 1;
}
break;
+ case 2000:
+ SET_CHAR_OPTS(share_dst_ports, optarg);
+ break;
+ case 2001:
+ SET_CHAR_OPTS(share_src_ports, optarg);
+ break;
case 'V':
pr_msg("Version: %s\n", CRIU_VERSION);
if (strcmp(CRIU_GITID, "0"))
diff --git a/criu/crtools.c b/criu/crtools.c
index 7358918..cfa149a 100644
--- a/criu/crtools.c
+++ b/criu/crtools.c
@@ -104,6 +104,9 @@ int main(int argc, char *argv[], char *envp[])
goto usage;
}
+ if (parse_share_ports())
+ goto usage;
+
log_set_loglevel(opts.log_level);
if (optind < argc && !strcmp(argv[optind], "swrk")) {
diff --git a/criu/files.c b/criu/files.c
index 1ec5281..1c52cf4 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -705,6 +705,8 @@ int dump_my_file(int lfd, u32 *id, int *type)
return 0;
}
+int dst_pid;
+
int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, struct parasite_drain_fd *dfds)
{
int *lfds = NULL;
@@ -728,7 +730,7 @@ int dump_task_files_seized(struct parasite_ctl *ctl, struct pstree_item *item, s
img = open_image(CR_FD_FDINFO, O_DUMP, item->ids->files_id);
if (!img)
goto err;
-
+ dst_pid = item->pid->real;
ret = 0; /* Don't fail if nr_fds == 0 */
for (off = 0; ret == 0 && off < dfds->nr_fds; off += nr_fds) {
if (nr_fds + off > dfds->nr_fds)
@@ -1237,6 +1239,20 @@ static int open_fd(struct fdinfo_list_entry *fle)
goto out;
}
+ if (d->ops->type == FD_TYPES__INETSK) {
+ if (check_need_repair(d)) {
+ ret = repair_share_socket(d->id);
+ if (!ret) {
+ new_fd = get_share_socket();
+ pr_info("get share socket:%d\n", new_fd);
+ if (new_fd <= 0 || setup_and_serve_out(fle, new_fd) < 0)
+ return -1;
+ fle->stage = FLE_RESTORED;
+ return 0;
+ }
+ }
+ }
+
/*
* Open method returns the following values:
* 0 -- restore is successfully finished;
diff --git a/criu/include/cr_options.h b/criu/include/cr_options.h
index 9ec8034..b7c1e34 100644
--- a/criu/include/cr_options.h
+++ b/criu/include/cr_options.h
@@ -198,6 +198,8 @@ struct cr_options {
int mask_exit_notify;
int weak_file_check;
int file_locks_repair;
+ char *share_dst_ports;
+ char *share_src_ports;
};
extern struct cr_options opts;
diff --git a/criu/include/files.h b/criu/include/files.h
index 1d979a9..0521c7e 100644
--- a/criu/include/files.h
+++ b/criu/include/files.h
@@ -201,4 +201,8 @@ extern int open_transport_socket(void);
extern int set_fds_event(pid_t virt);
extern void wait_fds_event(void);
+extern int repair_share_socket(int id);
+extern int check_need_repair(struct file_desc *d);
+extern int get_share_socket(void);
+
#endif /* __CR_FILES_H__ */
diff --git a/criu/include/net.h b/criu/include/net.h
index 718cc45..ec47b61 100644
--- a/criu/include/net.h
+++ b/criu/include/net.h
@@ -16,6 +16,7 @@ extern int dump_net_ns(struct ns_id *ns);
extern int prepare_net_namespaces(void);
extern void fini_net_namespaces(void);
extern int netns_keep_nsfd(void);
+extern int parse_share_ports(void);
struct pstree_item;
extern int restore_task_net_ns(struct pstree_item *current);
diff --git a/criu/include/sk-inet.h b/criu/include/sk-inet.h
index c832d63..27deceb 100644
--- a/criu/include/sk-inet.h
+++ b/criu/include/sk-inet.h
@@ -101,4 +101,7 @@ struct rst_tcp_sock {
union libsoccr_addr;
int restore_sockaddr(union libsoccr_addr *sa, int family, u32 pb_port, u32 *pb_addr, u32 ifindex);
+#define MAX_SHARE_PORT_NUM 64
+extern int dst_pid;
+
#endif /* __CR_SK_INET_H__ */
diff --git a/criu/sk-inet.c b/criu/sk-inet.c
index 05048c8..c7de793 100644
--- a/criu/sk-inet.c
+++ b/criu/sk-inet.c
@@ -431,6 +431,152 @@ static bool needs_scope_id(uint32_t *src_addr)
return false;
}
+#define ADD_SHARE_SOCKET_PATH "/sys/kernel/add_share_socket"
+#define REPAIR_SHARE_SOCKET_PATH "/sys/kernel/repair_share_socket"
+#define SHARE_SOCKET_PATH "/sys/kernel/share_socket"
+
+int add_share_socket(u32 id, int fd, int pid, int port)
+{
+ int retval;
+ char buf[256] = {0};
+
+ retval = snprintf(buf, 256, "%u,%d,%d,%d", id, fd, pid, port);
+ if (retval <= 0)
+ return -EFAULT;
+
+ fd = open(ADD_SHARE_SOCKET_PATH, O_WRONLY, 0);
+ if (fd < 0) {
+ pr_err("open file:%s fail\n", ADD_SHARE_SOCKET_PATH);
+ return fd;
+ }
+
+ retval = write(fd, buf, strlen(buf));
+ close(fd);
+ return retval < 0 ? -1 : 0;
+}
+
+
+int repair_share_socket(int id)
+{
+ int retval, fd;
+ char buf[256] = {0};
+
+ retval = snprintf(buf, 256, "%u", id);
+ if (retval <= 0)
+ return -EFAULT;
+
+ fd = open(REPAIR_SHARE_SOCKET_PATH, O_WRONLY, 0);
+ if (fd < 0) {
+ pr_err("open file:%s fail\n", REPAIR_SHARE_SOCKET_PATH);
+ return fd;
+ }
+ retval = write(fd, buf, strlen(buf));
+
+ close(fd);
+ return retval < 0 ? -1 : 0;
+}
+
+int get_share_socket(void)
+{
+ int fd;
+ ssize_t count;
+ int retval = -1;
+ char buf[32] = {0};
+
+ fd = open(SHARE_SOCKET_PATH, O_RDONLY, 0);
+ if (fd < 0) {
+ pr_err("open file:%s fail\n", SHARE_SOCKET_PATH);
+ return fd;
+ }
+
+ count = read(fd, buf, sizeof(buf));
+ if (count > 0)
+ retval = atoi(buf);
+
+ close(fd);
+ return retval;
+}
+
+int g_share_dst_ports[MAX_SHARE_PORT_NUM];
+int g_share_dst_port_num;
+int g_share_src_ports[MAX_SHARE_PORT_NUM];
+int g_share_src_port_num;
+
+int parse_share_ports(void)
+{
+ char *save, *p;
+
+ if (opts.share_dst_ports) {
+ p = strtok_r(opts.share_dst_ports, ",", &save);
+ while (p != NULL) {
+ if (g_share_dst_port_num >= MAX_SHARE_PORT_NUM)
+ return -1;
+ g_share_dst_ports[g_share_dst_port_num] = atoi(p);
+ if (!g_share_dst_ports[g_share_dst_port_num])
+ return -1;
+ g_share_dst_port_num++;
+ p = strtok_r(NULL, ",", &save);
+ }
+ }
+
+ if (opts.share_src_ports) {
+ p = strtok_r(opts.share_src_ports, ",", &save);
+ while (p != NULL) {
+ if (g_share_src_port_num >= MAX_SHARE_PORT_NUM)
+ return -1;
+ g_share_src_ports[g_share_src_port_num] = atoi(p);
+ if (!g_share_src_ports[g_share_src_port_num])
+ return -1;
+ g_share_src_port_num++;
+ p = strtok_r(NULL, ",", &save);
+ }
+ }
+ return 0;
+}
+
+int check_share_dst_port(int dst_port)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < g_share_dst_port_num; i++) {
+ if (dst_port == g_share_dst_ports[i]) {
+ ret = 1;
+ break;
+ }
+ }
+ return ret;
+}
+
+int check_share_src_port(int src_port)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < g_share_src_port_num; i++) {
+ if (src_port == g_share_src_ports[i]) {
+ ret = 1;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+int check_need_repair(struct file_desc *d)
+{
+ struct inet_sk_info *ii;
+ InetSkEntry *ie;
+
+ ii = container_of(d, struct inet_sk_info, d);
+ ie = ii->ie;
+ if (check_share_dst_port(ie->dst_port) ||
+ check_share_src_port(ie->src_port))
+ return 1;
+ else
+ return 0;
+}
+
static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int family)
{
struct inet_sk_desc *sk;
@@ -488,6 +634,11 @@ static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int fa
BUG_ON(sk->sd.already_dumped);
+ if (check_share_dst_port(sk->dst_port) || check_share_src_port(sk->src_port)) {
+ pr_info("Start add share prot:%d src %d\n", sk->dst_port, sk->src_port);
+ add_share_socket(id, lfd, dst_pid, sk->src_port);
+ }
+
ie.id = id;
ie.ino = sk->sd.ino;
if (sk->sd.sk_ns) {
--
2.34.1
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。