Commit c9522605 authored by Mike Rapoport's avatar Mike Rapoport Committed by Andrei Vagin

criu: lazy-pages: refactor UNIX socket initialization

Create the socket early so that it will be available after restoring the
namespaces
Signed-off-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 4bb1272b
...@@ -2212,6 +2212,9 @@ int cr_restore_tasks(void) ...@@ -2212,6 +2212,9 @@ int cr_restore_tasks(void)
if (criu_signals_setup() < 0) if (criu_signals_setup() < 0)
goto err; goto err;
if (prepare_lazy_pages_socket() < 0)
goto err;
ret = restore_root_task(root_item); ret = restore_root_task(root_item);
err: err:
cr_plugin_fini(CR_PLUGIN_STAGE__RESTORE, ret); cr_plugin_fini(CR_PLUGIN_STAGE__RESTORE, ret);
......
...@@ -22,6 +22,7 @@ enum sfd_type { ...@@ -22,6 +22,7 @@ enum sfd_type {
TRANSPORT_FD_OFF, /* to transfer file descriptors */ TRANSPORT_FD_OFF, /* to transfer file descriptors */
RPC_SK_OFF, RPC_SK_OFF,
FDSTORE_SK_OFF, FDSTORE_SK_OFF,
LAZY_PAGES_SK_OFF, /* socket for communication with lazy-pages daemon */
SERVICE_FD_MAX SERVICE_FD_MAX
}; };
......
...@@ -3,5 +3,6 @@ ...@@ -3,5 +3,6 @@
struct task_restore_args; struct task_restore_args;
extern int setup_uffd(int pid, struct task_restore_args *task_args); extern int setup_uffd(int pid, struct task_restore_args *task_args);
extern int prepare_lazy_pages_socket(void);
#endif /* __CR_UFFD_H_ */ #endif /* __CR_UFFD_H_ */
...@@ -36,12 +36,16 @@ ...@@ -36,12 +36,16 @@
#include <compel/plugins/std/syscall-codes.h> #include <compel/plugins/std/syscall-codes.h>
#include "restorer.h" #include "restorer.h"
#include "page-xfer.h" #include "page-xfer.h"
#include "common/lock.h"
#include "rst-malloc.h"
#undef LOG_PREFIX #undef LOG_PREFIX
#define LOG_PREFIX "lazy-pages: " #define LOG_PREFIX "lazy-pages: "
#define LAZY_PAGES_SOCK_NAME "lazy-pages.socket" #define LAZY_PAGES_SOCK_NAME "lazy-pages.socket"
static mutex_t *lazy_sock_mutex;
struct lazy_pages_info { struct lazy_pages_info {
int pid; int pid;
int uffd; int uffd;
...@@ -144,25 +148,19 @@ static int prepare_sock_addr(struct sockaddr_un *saddr) ...@@ -144,25 +148,19 @@ static int prepare_sock_addr(struct sockaddr_un *saddr)
static int send_uffd(int sendfd, int pid) static int send_uffd(int sendfd, int pid)
{ {
int fd; int fd;
int len;
int ret = -1; int ret = -1;
struct sockaddr_un sun;
if (sendfd < 0) if (sendfd < 0)
return -1; return -1;
if (prepare_sock_addr(&sun)) fd = get_service_fd(LAZY_PAGES_SK_OFF);
if (fd < 0) {
pr_err("%s: get_service_fd\n", __func__);
return -1; return -1;
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
return -1;
len = offsetof(struct sockaddr_un, sun_path) + strlen(sun.sun_path);
if (connect(fd, (struct sockaddr *) &sun, len) < 0) {
pr_perror("connect to %s failed", sun.sun_path);
goto out;
} }
mutex_lock(lazy_sock_mutex);
/* The "transfer protocol" is first the pid as int and then /* The "transfer protocol" is first the pid as int and then
* the FD for UFFD */ * the FD for UFFD */
pr_debug("Sending PID %d\n", pid); pr_debug("Sending PID %d\n", pid);
...@@ -175,6 +173,9 @@ static int send_uffd(int sendfd, int pid) ...@@ -175,6 +173,9 @@ static int send_uffd(int sendfd, int pid)
pr_perror("send_fd error:"); pr_perror("send_fd error:");
goto out; goto out;
} }
mutex_unlock(lazy_sock_mutex);
ret = 0; ret = 0;
out: out:
close(fd); close(fd);
...@@ -247,6 +248,42 @@ err: ...@@ -247,6 +248,42 @@ err:
return -1; return -1;
} }
int prepare_lazy_pages_socket(void)
{
int fd, new_fd;
int len;
struct sockaddr_un sun;
if (!opts.lazy_pages)
return 0;
if (prepare_sock_addr(&sun))
return -1;
lazy_sock_mutex = shmalloc(sizeof(*lazy_sock_mutex));
if (!lazy_sock_mutex)
return -1;
mutex_init(lazy_sock_mutex);
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
return -1;
new_fd = install_service_fd(LAZY_PAGES_SK_OFF, fd);
close(fd);
if (new_fd < 0)
return -1;
len = offsetof(struct sockaddr_un, sun_path) + strlen(sun.sun_path);
if (connect(new_fd, (struct sockaddr *) &sun, len) < 0) {
pr_perror("connect to %s failed", sun.sun_path);
close(new_fd);
return -1;
}
return 0;
}
static int server_listen(struct sockaddr_un *saddr) static int server_listen(struct sockaddr_un *saddr)
{ {
int fd; int fd;
...@@ -276,24 +313,12 @@ out: ...@@ -276,24 +313,12 @@ out:
static int find_vmas(struct lazy_pages_info *lpi); static int find_vmas(struct lazy_pages_info *lpi);
static struct lazy_pages_info *ud_open(int listen, struct sockaddr_un *saddr) static struct lazy_pages_info *ud_open(int client)
{ {
struct lazy_pages_info *lpi; struct lazy_pages_info *lpi;
int client;
int ret = -1; int ret = -1;
socklen_t len;
int uffd_flags; int uffd_flags;
/* accept new client request */
len = sizeof(struct sockaddr_un);
if ((client = accept(listen, (struct sockaddr *)saddr, &len)) < 0) {
pr_perror("server_accept error: %d", client);
close(listen);
return NULL;
}
pr_debug("client fd %d\n", client);
lpi = lpi_init(); lpi = lpi_init();
if (!lpi) if (!lpi)
goto out; goto out;
...@@ -313,7 +338,6 @@ static struct lazy_pages_info *ud_open(int listen, struct sockaddr_un *saddr) ...@@ -313,7 +338,6 @@ static struct lazy_pages_info *ud_open(int listen, struct sockaddr_un *saddr)
goto out; goto out;
} }
pr_debug("lpi->uffd %d\n", lpi->uffd); pr_debug("lpi->uffd %d\n", lpi->uffd);
close_safe(&client);
pr_debug("uffd is 0x%d\n", lpi->uffd); pr_debug("uffd is 0x%d\n", lpi->uffd);
uffd_flags = fcntl(lpi->uffd, F_GETFD, NULL); uffd_flags = fcntl(lpi->uffd, F_GETFD, NULL);
...@@ -332,7 +356,6 @@ static struct lazy_pages_info *ud_open(int listen, struct sockaddr_un *saddr) ...@@ -332,7 +356,6 @@ static struct lazy_pages_info *ud_open(int listen, struct sockaddr_un *saddr)
out: out:
lpi_fini(lpi); lpi_fini(lpi);
close_safe(&client);
return NULL; return NULL;
} }
...@@ -816,6 +839,8 @@ static int prepare_uffds(int epollfd) ...@@ -816,6 +839,8 @@ static int prepare_uffds(int epollfd)
{ {
int i; int i;
int listen; int listen;
int client;
socklen_t len;
struct sockaddr_un saddr; struct sockaddr_un saddr;
if (prepare_sock_addr(&saddr)) if (prepare_sock_addr(&saddr))
...@@ -827,20 +852,31 @@ static int prepare_uffds(int epollfd) ...@@ -827,20 +852,31 @@ static int prepare_uffds(int epollfd)
return -1; return -1;
} }
/* accept new client request */
len = sizeof(struct sockaddr_un);
if ((client = accept(listen, (struct sockaddr *) &saddr, &len)) < 0) {
pr_perror("server_accept error: %d", client);
close(listen);
return -1;
}
pr_debug("client fd %d\n", client);
for (i = 0; i < task_entries->nr_tasks; i++) { for (i = 0; i < task_entries->nr_tasks; i++) {
struct lazy_pages_info *lpi; struct lazy_pages_info *lpi;
lpi = ud_open(listen, &saddr); lpi = ud_open(client);
if (!lpi) if (!lpi)
goto close_uffd; goto close_uffd;
if (epoll_add_fd(epollfd, lpi->uffd)) if (epoll_add_fd(epollfd, lpi->uffd))
goto close_uffd; goto close_uffd;
} }
close_safe(&client);
close(listen); close(listen);
return 0; return 0;
close_uffd: close_uffd:
lpi_hash_fini(); lpi_hash_fini();
close_safe(&client);
close(listen); close(listen);
return -1; return -1;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment