[CRIU] [PATCH 2/4] unix: link a socket to its peer
Andrey Vagin
avagin at openvz.org
Sat Nov 30 09:43:54 PST 2013
We are going to add callback-s for dumping external sockets.
All external sockets are added into unix_list, but for dumping we need
to know all peers.
And one more thing is that a socket is not closed before its peer is
not be dumped. We are going to transfer the socket decriptor in the
callback.
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
sk-unix.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/sk-unix.c b/sk-unix.c
index b6255ba..7e0bea7 100644
--- a/sk-unix.c
+++ b/sk-unix.c
@@ -45,6 +45,10 @@ struct unix_sk_desc {
gid_t gid;
struct list_head list;
+
+ int fd;
+ struct list_head peer_list;
+ struct list_head peer_node;
};
static LIST_HEAD(unix_sockets);
@@ -121,7 +125,7 @@ static int can_dump_unix_sk(const struct unix_sk_desc *sk)
static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
{
- struct unix_sk_desc *sk;
+ struct unix_sk_desc *sk, *peer;
UnixSkEntry ue = UNIX_SK_ENTRY__INIT;
SkOptsEntry skopts = SK_OPTS_ENTRY__INIT;
FilePermsEntry perms = FILE_PERMS_ENTRY__INIT;
@@ -172,8 +176,6 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
sk_encode_shutdown(&ue, sk->shutdown);
if (ue.peer) {
- struct unix_sk_desc *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",
@@ -197,9 +199,18 @@ static int dump_one_unix_fd(int lfd, u32 id, const struct fd_parms *p)
* It can be external socket, so we defer dumping
* until all sockets the program owns are processed.
*/
- if (!peer->sd.already_dumped && list_empty(&peer->list)) {
- show_one_unix("Add a peer", peer);
- list_add_tail(&peer->list, &unix_sockets);
+ if (!peer->sd.already_dumped) {
+ if (list_empty(&peer->list)) {
+ show_one_unix("Add a peer", peer);
+ list_add_tail(&peer->list, &unix_sockets);
+ }
+
+ list_add(&sk->peer_node, &peer->peer_list);
+ sk->fd = dup(lfd);
+ if (sk->fd < 0) {
+ pr_perror("Unable to dup(%d)", lfd);
+ goto err;
+ }
}
if ((ue.type != SOCK_DGRAM) && (
@@ -284,6 +295,9 @@ dump:
list_del_init(&sk->list);
sk->sd.already_dumped = 1;
+ list_for_each_entry(peer, &sk->peer_list, peer_node)
+ close_safe(&peer->fd);
+
return 0;
err:
@@ -311,6 +325,9 @@ static int unix_collect_one(const struct unix_diag_msg *m,
d->state = m->udiag_state;
INIT_LIST_HEAD(&d->list);
+ INIT_LIST_HEAD(&d->peer_list);
+ d->fd = -1;
+
if (tb[UNIX_DIAG_SHUTDOWN])
d->shutdown = *(u8 *)RTA_DATA(tb[UNIX_DIAG_SHUTDOWN]);
else
--
1.8.3.1
More information about the CRIU
mailing list