Commit d74073a5 authored by Ruslan Kuprieiev's avatar Ruslan Kuprieiev Committed by Pavel Emelyanov

unix: Handle service socket on dump and restore

Service connection is actually an 'external' one from unix sockets engine POV,
but we don't want to dump it as such. Thus, we explicitly find one and dump it
as half-closed connection. On restore we push an artificial message into it
to report to the program that the dump-request was served, but the program is
restored.
Signed-off-by: 's avatarRuslan Kuprieiev <kupruser@gmail.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 8fddfd2f
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
*/ */
#define USK_EXTERN (1 << 0) #define USK_EXTERN (1 << 0)
#define USK_SERVICE (1 << 1)
#define VMA_AREA_NONE (0 << 0) #define VMA_AREA_NONE (0 << 0)
#define VMA_AREA_REGULAR (1 << 0) /* Dumpable area */ #define VMA_AREA_REGULAR (1 << 0) /* Dumpable area */
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "sockets.h" #include "sockets.h"
#include "sk-queue.h" #include "sk-queue.h"
#include "mount.h" #include "mount.h"
#include "cr-service.h"
#include "protobuf.h" #include "protobuf.h"
#include "protobuf/sk-unix.pb-c.h" #include "protobuf/sk-unix.pb-c.h"
...@@ -89,8 +90,14 @@ static void show_one_unix_img(const char *act, const UnixSkEntry *e) ...@@ -89,8 +90,14 @@ static void show_one_unix_img(const char *act, const UnixSkEntry *e)
static int can_dump_unix_sk(const struct unix_sk_desc *sk) static int can_dump_unix_sk(const struct unix_sk_desc *sk)
{ {
/*
* The last case in this "if" is seqpacket socket,
* that is connected to cr_service. We will dump
* it properly below.
*/
if (sk->type != SOCK_STREAM && if (sk->type != SOCK_STREAM &&
sk->type != SOCK_DGRAM) { sk->type != SOCK_DGRAM &&
sk->peer_ino != cr_service_client->sk_ino) {
pr_err("Only stream/dgram sockets for now\n"); pr_err("Only stream/dgram sockets for now\n");
return 0; return 0;
} }
...@@ -138,6 +145,16 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p) ...@@ -138,6 +145,16 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
ue.opts = &skopts; ue.opts = &skopts;
ue.uflags = 0; ue.uflags = 0;
/*
* Check if this socket is connected to criu service.
* Dump it like closed one and mark it for restore.
*/
if (ue.peer == cr_service_client->sk_ino) {
ue.state = TCP_CLOSE;
ue.peer = 0;
ue.uflags |= USK_SERVICE;
}
if (sk->namelen && *sk->name) { if (sk->namelen && *sk->name) {
ue.file_perms = &perms; ue.file_perms = &perms;
...@@ -722,7 +739,29 @@ static int open_unixsk_standalone(struct unix_sk_info *ui) ...@@ -722,7 +739,29 @@ static int open_unixsk_standalone(struct unix_sk_info *ui)
pr_info("Opening standalone socket (id %#x ino %#x peer %#x)\n", pr_info("Opening standalone socket (id %#x ino %#x peer %#x)\n",
ui->ue->id, ui->ue->ino, ui->ue->peer); ui->ue->id, ui->ue->ino, ui->ue->peer);
if ((ui->ue->state == TCP_ESTABLISHED) && !ui->ue->peer) { /*
* Check if this socket was connected to criu service.
* If so, put response, that dumping and restoring
* was successful.
*/
if (ui->ue->uflags & USK_SERVICE) {
int sks[2];
CriuDumpResp resp = CRIU_DUMP_RESP__INIT;
resp.success = true;
resp.restored = true;
if (socketpair(PF_UNIX, ui->ue->type, 0, sks)) {
pr_perror("Can't create socketpair");
return -1;
}
if (send_criu_dump_resp(sks[1], &resp) == -1)
return -1;
close(sks[1]);
sk = sks[0];
} else if ((ui->ue->state == TCP_ESTABLISHED) && !ui->ue->peer) {
int ret, sks[2]; int ret, sks[2];
if (ui->ue->type != SOCK_STREAM) { if (ui->ue->type != SOCK_STREAM) {
......
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