[CRIU] [PATCH 2/9] sk-unix/dump: allocate UnixSkEntry dynamically
Andrey Vagin
avagin at openvz.org
Thu Dec 19 09:34:58 PST 2013
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
sk-unix.c | 134 +++++++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 85 insertions(+), 49 deletions(-)
diff --git a/sk-unix.c b/sk-unix.c
index 25ea1bb..9fe3ef3 100644
--- a/sk-unix.c
+++ b/sk-unix.c
@@ -49,6 +49,8 @@ struct unix_sk_desc {
int fd;
struct list_head peer_list;
struct list_head peer_node;
+
+ UnixSkEntry *ue;
};
static LIST_HEAD(unix_sockets);
@@ -123,12 +125,46 @@ static int can_dump_unix_sk(const struct unix_sk_desc *sk)
return 1;
}
+static int write_unix_entry(struct unix_sk_desc *sk)
+{
+ int ret;
+
+ ret = pb_write_one(fdset_fd(glob_fdset, CR_FD_UNIXSK), sk->ue, PB_UNIX_SK);
+
+ show_one_unix_img("Dumped", sk->ue);
+
+ release_skopts(sk->ue->opts);
+ xfree(sk->ue);
+
+ sk->ue = NULL;
+
+ return ret;
+}
+
static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
{
struct unix_sk_desc *sk, *peer;
- UnixSkEntry ue = UNIX_SK_ENTRY__INIT;
- SkOptsEntry skopts = SK_OPTS_ENTRY__INIT;
- FilePermsEntry perms = FILE_PERMS_ENTRY__INIT;
+ UnixSkEntry *ue;
+ SkOptsEntry *skopts;
+ FilePermsEntry *perms;
+ FownEntry *fown;
+
+ ue = xmalloc(sizeof(UnixSkEntry) +
+ sizeof(SkOptsEntry) +
+ sizeof(FilePermsEntry) +
+ sizeof(FownEntry));
+ if (ue == NULL)
+ return -1;
+
+ skopts = (SkOptsEntry *) ue + sizeof(UnixSkEntry);
+ perms = (FilePermsEntry *) skopts + sizeof(SkOptsEntry);
+ fown = (FownEntry *) perms + sizeof(FilePermsEntry);
+
+ unix_sk_entry__init(ue);
+ sk_opts_entry__init(skopts);
+ file_perms_entry__init(perms);
+
+ *fown = p->fown;
sk = (struct unix_sk_desc *)lookup_socket(p->stat.st_ino, PF_UNIX, 0);
if (IS_ERR_OR_NULL(sk)) {
@@ -141,45 +177,45 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
BUG_ON(sk->sd.already_dumped);
- ue.name.len = (size_t)sk->namelen;
- ue.name.data = (void *)sk->name;
+ ue->name.len = (size_t)sk->namelen;
+ ue->name.data = (void *)sk->name;
- ue.id = id;
- ue.ino = sk->sd.ino;
- ue.type = sk->type;
- ue.state = sk->state;
- ue.flags = p->flags;
- ue.backlog = sk->wqlen;
- ue.peer = sk->peer_ino;
- ue.fown = (FownEntry *)&p->fown;
- ue.opts = &skopts;
- ue.uflags = 0;
+ ue->id = id;
+ ue->ino = sk->sd.ino;
+ ue->type = sk->type;
+ ue->state = sk->state;
+ ue->flags = p->flags;
+ ue->backlog = sk->wqlen;
+ ue->peer = sk->peer_ino;
+ ue->fown = fown;
+ ue->opts = skopts;
+ ue->uflags = 0;
/*
* Check if this socket is connected to criu service.
* Dump it like closed one and mark it for restore.
*/
- if (unlikely(ue.peer == service_sk_ino)) {
- ue.state = TCP_CLOSE;
- ue.peer = 0;
- ue.uflags |= USK_SERVICE;
+ if (unlikely(ue->peer == service_sk_ino)) {
+ ue->state = TCP_CLOSE;
+ ue->peer = 0;
+ ue->uflags |= USK_SERVICE;
}
if (sk->namelen && *sk->name) {
- ue.file_perms = &perms;
+ ue->file_perms = perms;
- perms.mode = sk->mode;
- perms.uid = sk->uid;
- perms.gid = sk->gid;
+ perms->mode = sk->mode;
+ perms->uid = sk->uid;
+ perms->gid = sk->gid;
}
- sk_encode_shutdown(&ue, sk->shutdown);
+ sk_encode_shutdown(ue, sk->shutdown);
- if (ue.peer) {
- peer = (struct unix_sk_desc *)lookup_socket(ue.peer, PF_UNIX, 0);
+ if (ue->peer) {
+ peer = (struct unix_sk_desc *)lookup_socket(ue->peer, PF_UNIX, 0);
if (IS_ERR_OR_NULL(peer)) {
pr_err("Unix socket %#x without peer %#x\n",
- ue.ino, ue.peer);
+ ue->ino, ue->peer);
goto err;
}
@@ -187,10 +223,10 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
* Peer should have us as peer or have a name by which
* we can access one.
*/
- if (peer->peer_ino != ue.ino) {
+ if (peer->peer_ino != ue->ino) {
if (!peer->name) {
pr_err("Unix socket %#x with unreachable peer %#x (%#x/%s)\n",
- ue.ino, ue.peer, peer->peer_ino, peer->name);
+ ue->ino, ue->peer, peer->peer_ino, peer->name);
goto err;
}
}
@@ -213,25 +249,25 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
}
}
- if ((ue.type != SOCK_DGRAM) && (
- ((ue.shutdown == SK_SHUTDOWN__READ) &&
+ if ((ue->type != SOCK_DGRAM) && (
+ ((ue->shutdown == SK_SHUTDOWN__READ) &&
(peer->shutdown != SK_SHUTDOWN__WRITE)) ||
- ((ue.shutdown == SK_SHUTDOWN__WRITE) &&
+ ((ue->shutdown == SK_SHUTDOWN__WRITE) &&
(peer->shutdown != SK_SHUTDOWN__READ)) ||
- ((ue.shutdown == SK_SHUTDOWN__BOTH) &&
+ ((ue->shutdown == SK_SHUTDOWN__BOTH) &&
(peer->shutdown != SK_SHUTDOWN__BOTH)) )) {
/*
* On restore we assume, that stream pairs must
* be shut down from one end only
*/
pr_err("Shutdown mismatch %u:%d -> %u:%d\n",
- ue.ino, ue.shutdown, peer->sd.ino, peer->shutdown);
+ ue->ino, ue->shutdown, peer->sd.ino, peer->shutdown);
goto err;
}
- } else if (ue.state == TCP_ESTABLISHED) {
+ } else if (ue->state == TCP_ESTABLISHED) {
const struct unix_sk_listen_icon *e;
- e = lookup_unix_listen_icons(ue.ino);
+ e = lookup_unix_listen_icons(ue->ino);
if (!e) {
/*
* ESTABLISHED socket without peer and without
@@ -239,12 +275,12 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
* connection.
*/
- if (ue.shutdown == SK_SHUTDOWN__BOTH) {
+ if (ue->shutdown == SK_SHUTDOWN__BOTH) {
pr_info("Dumping semi-closed connection\n");
goto dump;
}
- pr_err("Dangling connection %#x\n", ue.ino);
+ pr_err("Dangling connection %#x\n", ue->ino);
goto err;
}
@@ -260,22 +296,20 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
/* e->sk_desc is _never_ NULL */
if (e->sk_desc->state != TCP_LISTEN) {
pr_err("In-flight connection on "
- "non-listening socket %d\n", ue.ino);
+ "non-listening socket %d\n", ue->ino);
goto err;
}
- ue.peer = e->sk_desc->sd.ino;
+ ue->peer = e->sk_desc->sd.ino;
pr_debug("\t\tFixed inflight socket %#x peer %#x)\n",
- ue.ino, ue.peer);
+ ue->ino, ue->peer);
}
dump:
- if (dump_socket_opts(lfd, &skopts))
- goto err;
-
- if (pb_write_one(fdset_fd(glob_fdset, CR_FD_UNIXSK), &ue, PB_UNIX_SK))
+ if (dump_socket_opts(lfd, skopts))
goto err;
+ sk->ue = ue;
/*
* If a stream listening socket has non-zero rqueue, this
* means there are in-flight connections waiting to get
@@ -284,13 +318,14 @@ dump:
*/
if (sk->rqlen != 0 && !(sk->type == SOCK_STREAM &&
sk->state == TCP_LISTEN))
- if (dump_sk_queue(lfd, ue.id))
+ if (dump_sk_queue(lfd, ue->id))
goto err;
pr_info("Dumping unix socket at %d\n", p->fd);
show_one_unix("Dumping", sk);
- show_one_unix_img("Dumped", &ue);
- release_skopts(&skopts);
+
+ if (write_unix_entry(sk))
+ goto err;
list_del_init(&sk->list);
sk->sd.already_dumped = 1;
@@ -305,7 +340,8 @@ dump:
return 0;
err:
- release_skopts(&skopts);
+ release_skopts(skopts);
+ xfree(ue);
return -1;
}
--
1.8.3.1
More information about the CRIU
mailing list