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)
if (criu_signals_setup() < 0)
goto err;
if (prepare_lazy_pages_socket() < 0)
goto err;
ret = restore_root_task(root_item);
err:
cr_plugin_fini(CR_PLUGIN_STAGE__RESTORE, ret);
......
......@@ -22,6 +22,7 @@ enum sfd_type {
TRANSPORT_FD_OFF, /* to transfer file descriptors */
RPC_SK_OFF,
FDSTORE_SK_OFF,
LAZY_PAGES_SK_OFF, /* socket for communication with lazy-pages daemon */
SERVICE_FD_MAX
};
......
......@@ -3,5 +3,6 @@
struct task_restore_args;
extern int setup_uffd(int pid, struct task_restore_args *task_args);
extern int prepare_lazy_pages_socket(void);
#endif /* __CR_UFFD_H_ */
......@@ -36,12 +36,16 @@
#include <compel/plugins/std/syscall-codes.h>
#include "restorer.h"
#include "page-xfer.h"
#include "common/lock.h"
#include "rst-malloc.h"
#undef LOG_PREFIX
#define LOG_PREFIX "lazy-pages: "
#define LAZY_PAGES_SOCK_NAME "lazy-pages.socket"
static mutex_t *lazy_sock_mutex;
struct lazy_pages_info {
int pid;
int uffd;
......@@ -144,25 +148,19 @@ static int prepare_sock_addr(struct sockaddr_un *saddr)
static int send_uffd(int sendfd, int pid)
{
int fd;
int len;
int ret = -1;
struct sockaddr_un sun;
if (sendfd < 0)
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;
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 FD for UFFD */
pr_debug("Sending PID %d\n", pid);
......@@ -175,6 +173,9 @@ static int send_uffd(int sendfd, int pid)
pr_perror("send_fd error:");
goto out;
}
mutex_unlock(lazy_sock_mutex);
ret = 0;
out:
close(fd);
......@@ -247,6 +248,42 @@ err:
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)
{
int fd;
......@@ -276,24 +313,12 @@ out:
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;
int client;
int ret = -1;
socklen_t len;
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();
if (!lpi)
goto out;
......@@ -313,7 +338,6 @@ static struct lazy_pages_info *ud_open(int listen, struct sockaddr_un *saddr)
goto out;
}
pr_debug("lpi->uffd %d\n", lpi->uffd);
close_safe(&client);
pr_debug("uffd is 0x%d\n", lpi->uffd);
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)
out:
lpi_fini(lpi);
close_safe(&client);
return NULL;
}
......@@ -816,6 +839,8 @@ static int prepare_uffds(int epollfd)
{
int i;
int listen;
int client;
socklen_t len;
struct sockaddr_un saddr;
if (prepare_sock_addr(&saddr))
......@@ -827,20 +852,31 @@ static int prepare_uffds(int epollfd)
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++) {
struct lazy_pages_info *lpi;
lpi = ud_open(listen, &saddr);
lpi = ud_open(client);
if (!lpi)
goto close_uffd;
if (epoll_add_fd(epollfd, lpi->uffd))
goto close_uffd;
}
close_safe(&client);
close(listen);
return 0;
close_uffd:
lpi_hash_fini();
close_safe(&client);
close(listen);
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