Commit 54c1979c authored by Pavel Emelyanov's avatar Pavel Emelyanov

unix: Collect unix sockets early on restore

Same as prev 2 patches now for the unix sockets. They are still in per-pid image files, but
this is going to change soon (I hope).
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 94a11df0
......@@ -424,6 +424,10 @@ static int prepare_shared(int ps_fd)
if (ret <= 0)
break;
ret = collect_unix_sockets(e.pid);
if (ret < 0)
return -1;
ret = prepare_shmem_pid(e.pid);
if (ret < 0)
break;
......
......@@ -12,6 +12,7 @@ extern int dump_socket(struct fd_parms *p, int lfd,
extern int collect_sockets(void);
extern int collect_inet_sockets(void);
extern int collect_unix_sockets(int pid);
extern int prepare_sockets(int pid);
struct fdinfo_entry;
extern int open_inet_sk(struct fdinfo_entry *fe);
......
......@@ -1071,7 +1071,7 @@ err:
return -1;
}
static int bind_unix_sk(int sk, const struct unix_sk_entry *ue, int img_fd)
static int bind_unix_sk(int sk, const struct unix_sk_entry *ue, char *name)
{
struct sockaddr_un addr;
......@@ -1082,9 +1082,7 @@ static int bind_unix_sk(int sk, const struct unix_sk_entry *ue, int img_fd)
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
if (read_img_buf(img_fd, &addr.sun_path, ue->namelen) < 0)
return -1;
memcpy(&addr.sun_path, name, ue->namelen);
if (addr.sun_path[0] != '\0')
unlink(addr.sun_path);
......@@ -1094,13 +1092,12 @@ static int bind_unix_sk(int sk, const struct unix_sk_entry *ue, int img_fd)
ue->id, ue->type);
}
static int open_unix_sk_dgram(int sk, const struct unix_sk_entry *ue,
int img_fd)
static int open_unix_sk_dgram(int sk, const struct unix_sk_entry *ue, char *name)
{
int ret = 0;
if (ue->namelen)
ret = bind_unix_sk(sk, ue, img_fd);
ret = bind_unix_sk(sk, ue, name);
else if (ue->peer) {
struct sockaddr_un addr;
int addrlen;
......@@ -1122,13 +1119,12 @@ static int open_unix_sk_dgram(int sk, const struct unix_sk_entry *ue,
return ret;
}
static int open_unix_sk_stream(int sk, const struct unix_sk_entry *ue,
int img_fd)
static int open_unix_sk_stream(int sk, const struct unix_sk_entry *ue, char *name)
{
int ret;
if (ue->state == TCP_LISTEN) {
ret = bind_unix_sk(sk, ue, img_fd);
ret = bind_unix_sk(sk, ue, name);
if (ret < 0)
goto out;
......@@ -1161,7 +1157,7 @@ out:
return ret;
}
static int open_unix_sk(const struct unix_sk_entry *ue, int *img_fd)
static int open_unix_sk(const struct unix_sk_entry *ue, char *name)
{
int sk;
......@@ -1175,11 +1171,11 @@ static int open_unix_sk(const struct unix_sk_entry *ue, int *img_fd)
switch (ue->type) {
case SOCK_STREAM:
if (open_unix_sk_stream(sk, ue, *img_fd))
if (open_unix_sk_stream(sk, ue, name))
goto err;
break;
case SOCK_DGRAM:
if (open_unix_sk_dgram(sk, ue, *img_fd))
if (open_unix_sk_dgram(sk, ue, name))
goto err;
break;
default:
......@@ -1187,9 +1183,6 @@ static int open_unix_sk(const struct unix_sk_entry *ue, int *img_fd)
goto err;
}
if (move_img_fd(img_fd, ue->fd))
return -1;
return reopen_fd_as(ue->fd, sk);
err:
......@@ -1197,30 +1190,35 @@ err:
return -1;
}
struct unix_sk_info {
struct unix_sk_entry ue;
struct list_head list;
char *name;
int pid;
};
static LIST_HEAD(unix_sockets);
static int prepare_unix_sockets(int pid)
{
int usk_fd, ret = -1;
int ret = 0;
struct sk_packets_pool unix_pool = {
.packets_list = LIST_HEAD_INIT(unix_pool.packets_list),
};
struct unix_sk_info *ui, *n;
usk_fd = open_image_ro(CR_FD_UNIXSK, pid);
if (usk_fd < 0)
return -1;
while (1) {
struct unix_sk_entry ue;
ret = read_img_eof(usk_fd, &ue);
if (ret <= 0)
break;
list_for_each_entry_safe(ui, n, &unix_sockets, list) {
if (ui->pid != pid)
continue;
ret = open_unix_sk(&ue, &usk_fd);
ret = open_unix_sk(&ui->ue, ui->name);
if (ret)
break;
list_del(&ui->list);
xfree(ui->name);
xfree(ui);
}
err:
close(usk_fd);
if (ret)
return ret;
......@@ -1524,3 +1522,52 @@ void show_sk_queues(int fd, struct cr_options *o)
}
pr_img_tail(CR_FD_SK_QUEUES);
}
int collect_unix_sockets(int pid)
{
int fd, ret;
pr_info("Reading unix sockets in\n");
fd = open_image_ro(CR_FD_UNIXSK, pid);
if (fd < 0) {
if (errno == ENOENT)
return 0;
else
return -1;
}
while (1) {
struct unix_sk_info *ui;
ui = xmalloc(sizeof(*ui));
ret = -1;
if (ui == NULL)
break;
ret = read_img_eof(fd, &ui->ue);
if (ret <= 0) {
xfree(ui);
break;
}
if (ui->ue.namelen) {
ui->name = xmalloc(ui->ue.namelen);
ret = -1;
if (ui->name == NULL)
break;
ret = read_img_buf(fd, ui->name, ui->ue.namelen);
if (ret < 0)
break;
} else
ui->name = NULL;
ui->pid = pid;
pr_info(" `- Got %u peer %u\n", ui->ue.id, ui->ue.peer);
list_add_tail(&ui->list, &unix_sockets);
}
close(fd);
return ret;
}
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