From: Sang Yan sangyan@huawei.com
Clean pin mem and netlink repair res when dump fail.
Conflict:NA Reference:https://gitee.com/src-openeuler/criu/pulls/21 Signed-off-by: Jingxian He hejingxian@huawei.com --- criu/cr-dump.c | 26 ++++++++++++++++++++++++++ criu/include/net.h | 1 + criu/sk-netlink.c | 40 +++++++++++++++++++++++++++++++++++----- 3 files changed, 62 insertions(+), 5 deletions(-)
diff --git a/criu/cr-dump.c b/criu/cr-dump.c index db8e01c..600bc4c 100644 --- a/criu/cr-dump.c +++ b/criu/cr-dump.c @@ -83,6 +83,7 @@ #include "memfd.h" #include "timens.h" #include "img-streamer.h" +#include "restorer.h"
/* * Architectures can overwrite this function to restore register sets that @@ -1706,6 +1707,23 @@ static int cr_lazy_mem_dump(void) return ret; }
+int clear_pin_mem(int pid) +{ + int fd, ret; + + fd = open(PIN_MEM_FILE, O_RDWR, 0); + if (fd < 0) { + pr_warn("error open file: %s\n", PIN_MEM_FILE); + return -1; + } + ret = ioctl(fd, CLEAR_PIN_MEM_AREA, (unsigned long) &pid); + if (ret < 0) { + pr_warn("clear pin mem fail: %d\n", pid); + } + close(fd); + return ret; +} + static enum notifier_state notifier_state = NOTHING_COMPLETE;
static int cr_dump_finish(int ret) @@ -1791,6 +1809,14 @@ static int cr_dump_finish(int ret) if (ret == 0 && opts.pin_memory) { pr_info("start restore_task_special_pages\n"); restore_task_special_pages(0); + } else if (ret != 0 && opts.pin_memory) { + pr_info("clear pin mem info\n"); + clear_pin_mem(0); + } + + if (ret != 0 && opts.with_notifier_kup) { + pr_info("repair off netlink fd\n"); + netlink_repair_off(); }
if (ret != 0 && opts.with_notifier_kup) { diff --git a/criu/include/net.h b/criu/include/net.h index 795d5e8..bda0ff3 100644 --- a/criu/include/net.h +++ b/criu/include/net.h @@ -54,5 +54,6 @@ extern void check_has_netns_ioc(int fd, bool *kdat_val, const char *name); extern int net_set_ext(struct ns_id *ns); extern struct ns_id *get_root_netns(void); extern int read_net_ns_img(void); +extern int netlink_repair_off(void);
#endif /* __CR_NET_H__ */ diff --git a/criu/sk-netlink.c b/criu/sk-netlink.c index 6d8ab2d..a6c56ff 100644 --- a/criu/sk-netlink.c +++ b/criu/sk-netlink.c @@ -68,15 +68,45 @@ int netlink_receive_one(struct nlmsghdr *hdr, struct ns_id *ns, void *arg) return sk_collect_one(m->ndiag_ino, PF_NETLINK, &sd->sd, ns); }
+struct netlink_repair_fd { + int netlink_fd; + struct list_head nlist; +}; + +static LIST_HEAD(netlink_repair_fds); + static int netlink_repair_on(int fd) { - int ret, aux = 1; + int ret, aux = 1; + struct netlink_repair_fd *nrf;
- ret = setsockopt(fd, SOL_NETLINK, TCP_REPAIR, &aux, sizeof(aux)); - if (ret < 0) - pr_err("Can't turn netlink repair mode ON, error: %d\n", ret); + ret = setsockopt(fd, SOL_NETLINK, TCP_REPAIR, &aux, sizeof(aux)); + if (ret < 0) { + pr_err("Can't turn netlink repair mode ON, error: %d\n", ret); + return ret; + } + nrf = malloc(sizeof(*nrf)); + if (!nrf) + return -ENOMEM; + nrf->netlink_fd = dup(fd); + list_add_tail(&nrf->nlist, &netlink_repair_fds); + return ret; +}
- return ret; +int netlink_repair_off(void) +{ + int aux = 0, ret; + struct netlink_repair_fd *nrf, *n; + + list_for_each_entry_safe(nrf, n, &netlink_repair_fds, nlist) { + ret = setsockopt(nrf->netlink_fd, SOL_NETLINK, TCP_REPAIR, &aux, sizeof(aux)); + if (ret < 0) + pr_err("Failed to turn off repair mode on netlink\n"); + close(nrf->netlink_fd); + list_del(&nrf->nlist); + free(nrf); + } + return 0; }
static bool can_dump_netlink_sk(int lfd)