mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-05 08:45:49 +00:00
service: Add ability to inherit page server socket
The swrk action is turning out to be a cool thing. We can spawn criu with swrk action with some FD being open, then ask for dump/pre-dump/page-server telling it that some descriptor it needs is "out there". This patch lets us specify that the page server communication channel is already in criu's fdtable. TODO: teach regular service to accept fd via service socket. Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
@@ -288,6 +288,13 @@ static int setup_opts_from_req(int sk, CriuOpts *req)
|
||||
opts.use_page_server = true;
|
||||
opts.addr = req->ps->address;
|
||||
opts.ps_port = htons((short)req->ps->port);
|
||||
|
||||
if (req->ps->has_fd) {
|
||||
if (!opts.swrk_restore)
|
||||
return -1;
|
||||
|
||||
opts.ps_socket = req->ps->fd;
|
||||
}
|
||||
}
|
||||
|
||||
if (req->notify_scripts) {
|
||||
|
@@ -54,6 +54,7 @@ void init_opts(void)
|
||||
|
||||
opts.cpu_cap = CPU_CAP_ALL;
|
||||
opts.manage_cgroups = false;
|
||||
opts.ps_socket = -1;
|
||||
}
|
||||
|
||||
static int parse_ns_string(const char *ptr)
|
||||
|
@@ -51,6 +51,7 @@ struct cr_options {
|
||||
bool use_page_server;
|
||||
unsigned short ps_port;
|
||||
char *addr;
|
||||
int ps_socket;
|
||||
bool track_mem;
|
||||
char *img_parent;
|
||||
bool auto_dedup;
|
||||
|
42
page-xfer.c
42
page-xfer.c
@@ -40,6 +40,7 @@ static int open_page_local_xfer(struct page_xfer *xfer, int fd_type, long id);
|
||||
#define PS_IOV_OPEN 3
|
||||
|
||||
#define PS_IOV_FLUSH 0x1023
|
||||
#define PS_IOV_FLUSH_N_CLOSE 0x1024
|
||||
|
||||
#define PS_TYPE_BITS 8
|
||||
#define PS_TYPE_MASK ((1 << PS_TYPE_BITS) - 1)
|
||||
@@ -198,6 +199,7 @@ static int page_server_serve(int sk)
|
||||
ret = page_server_hole(sk, &pi);
|
||||
break;
|
||||
case PS_IOV_FLUSH:
|
||||
case PS_IOV_FLUSH_N_CLOSE:
|
||||
{
|
||||
int32_t status = 0;
|
||||
|
||||
@@ -220,7 +222,7 @@ static int page_server_serve(int sk)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
if (ret || (pi.cmd == PS_IOV_FLUSH_N_CLOSE))
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -254,12 +256,19 @@ static int get_sockaddr_in(struct sockaddr_in *addr)
|
||||
|
||||
int cr_page_server(bool daemon_mode)
|
||||
{
|
||||
int sk, ask = -1, ret;
|
||||
int sk = -1, ask = -1, ret;
|
||||
struct sockaddr_in saddr, caddr;
|
||||
socklen_t clen = sizeof(caddr);
|
||||
|
||||
up_page_ids_base();
|
||||
|
||||
if (opts.ps_socket != -1) {
|
||||
ret = 0;
|
||||
ask = opts.ps_socket;
|
||||
pr_info("Re-using ps socket %d\n", ask);
|
||||
goto no_server;
|
||||
}
|
||||
|
||||
pr_info("Starting page server on port %u\n", (int)ntohs(opts.ps_port));
|
||||
|
||||
sk = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
@@ -281,6 +290,7 @@ int cr_page_server(bool daemon_mode)
|
||||
goto out;
|
||||
}
|
||||
|
||||
no_server:
|
||||
if (daemon_mode) {
|
||||
ret = cr_daemon(1, 0);
|
||||
if (ret == -1) {
|
||||
@@ -298,11 +308,13 @@ int cr_page_server(bool daemon_mode)
|
||||
}
|
||||
}
|
||||
|
||||
ret = ask = accept(sk, (struct sockaddr *)&caddr, &clen);
|
||||
if (ask < 0)
|
||||
pr_perror("Can't accept connection to server");
|
||||
if (sk >= 0) {
|
||||
ret = ask = accept(sk, (struct sockaddr *)&caddr, &clen);
|
||||
if (ask < 0)
|
||||
pr_perror("Can't accept connection to server");
|
||||
|
||||
close(sk);
|
||||
close(sk);
|
||||
}
|
||||
|
||||
if (ask >= 0) {
|
||||
pr_info("Accepted connection from %s:%u\n",
|
||||
@@ -331,6 +343,12 @@ int connect_to_page_server(void)
|
||||
if (!opts.use_page_server)
|
||||
return 0;
|
||||
|
||||
if (opts.ps_socket != -1) {
|
||||
page_server_sk = opts.ps_socket;
|
||||
pr_info("Re-using ps socket %d\n", page_server_sk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_info("Connecting to server %s:%u\n",
|
||||
opts.addr, (int)ntohs(opts.ps_port));
|
||||
|
||||
@@ -353,7 +371,7 @@ int connect_to_page_server(void)
|
||||
|
||||
int disconnect_from_page_server(void)
|
||||
{
|
||||
struct page_server_iov pi = { .cmd = PS_IOV_FLUSH };
|
||||
struct page_server_iov pi = { };
|
||||
int32_t status = -1;
|
||||
int ret = -1;
|
||||
|
||||
@@ -366,6 +384,16 @@ int disconnect_from_page_server(void)
|
||||
pr_info("Disconnect from the page server %s:%u\n",
|
||||
opts.addr, (int)ntohs(opts.ps_port));
|
||||
|
||||
if (opts.ps_socket != -1)
|
||||
/*
|
||||
* The socket might not get closed (held by
|
||||
* the parent process) so we must order the
|
||||
* page-server to terminate itself.
|
||||
*/
|
||||
pi.cmd = PS_IOV_FLUSH_N_CLOSE;
|
||||
else
|
||||
pi.cmd = PS_IOV_FLUSH;
|
||||
|
||||
if (write(page_server_sk, &pi, sizeof(pi)) != sizeof(pi)) {
|
||||
pr_perror("Can't write the fini command to server");
|
||||
goto out;
|
||||
|
@@ -2,6 +2,7 @@ message criu_page_server_info {
|
||||
optional string address = 1;
|
||||
optional int32 port = 2;
|
||||
optional int32 pid = 3;
|
||||
optional int32 fd = 4;
|
||||
}
|
||||
|
||||
message criu_veth_pair {
|
||||
|
Reference in New Issue
Block a user