[CRIU] Re: [PATCH 2/4] sockets: Restore unconnected dgram sockets

Cyrill Gorcunov gorcunov at openvz.org
Mon Apr 16 06:37:47 EDT 2012


On Mon, Apr 16, 2012 at 02:05:33PM +0400, Pavel Emelyanov wrote:
> On 04/16/2012 01:27 PM, Cyrill Gorcunov wrote:
> > On Mon, Apr 16, 2012 at 10:11:33AM +0400, Cyrill Gorcunov wrote:
> >> On Mon, Apr 16, 2012 at 10:07:41AM +0400, Pavel Emelyanov wrote:
> >>>> @@ -478,6 +481,7 @@ usage:
> >>>>  	pr_msg("  -s             leave tasks in stopped state after checkpoint instead of killing them\n");
> >>>>  	pr_msg("  -n             checkpoint/restore namespaces - values must be separated by comma\n");
> >>>>  	pr_msg("                 supported: uts, ipc\n");
> >>>> +	pr_msg("  -r             resolve unconnected socket peer connection by name\n");
> >>>
> >>> I'd make the option meaning "allow external unix connections".
> >>>
> >>
> >> OK. Maybe some another letter here, not 'r' but say 'x'?
> >>
> > 
> > What about below one? (Please don't pick it up though, it conflicts
> > with current @master so I need to rebase before sending a final version)
> > 
> > +
> > +			pt.id		= peer->sd.ino;
> > +			pt.peer		= peer->peer_ino;
> 
> pr.peer =<should be>= -1;
> 

Yes, and this drops problem with calling run_unix_connections.

> > +			pt.type		= SOCK_DGRAM;
> > +			pt.state	= SOCK_STATE_XTRN;
> 
> TCP_LISTEN
> 
> "Externness" should be encoded in flags (yes, we should return them back on the
> unix sk image.
> 

Like this one (still not for merging)
-------------- next part --------------
>From ddcc9f5b9d9037de6cd2e9dec1888dffbd1bae16 Mon Sep 17 00:00:00 2001
From: Cyrill Gorcunov <gorcunov at openvz.org>
Date: Mon, 16 Apr 2012 14:35:48 +0400
Subject: [PATCH] sockets: Restore unconnected dgram sockets v3

In case if dgram socket peer is not connected back
we can try to resolve peer by name and connect there.

For security reason this happens only if '-x' option
is passed at restore time.

In particular this is needed for crond checkpoint/restore,
since it uses dgram socket to send messages to /dev/log.

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 crtools.c         |    8 ++++++--
 include/crtools.h |    2 ++
 sockets.c         |   45 +++++++++++++++++++++++++++++++++++++++------
 3 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/crtools.c b/crtools.c
index 9f6b415..5229c1e 100644
--- a/crtools.c
+++ b/crtools.c
@@ -23,7 +23,7 @@
 #include "uts_ns.h"
 #include "ipc_ns.h"
 
-static struct cr_options opts;
+struct cr_options opts;
 
 /*
  * The cr fd set is the set of files where the information
@@ -336,7 +336,7 @@ int main(int argc, char *argv[])
 	int log_inited = 0;
 	int log_level = 0;
 
-	static const char short_opts[] = "dsf:p:t:hcD:o:n:v";
+	static const char short_opts[] = "dsf:p:t:hcD:o:n:vx";
 
 	BUILD_BUG_ON(PAGE_SIZE != PAGE_IMAGE_SIZE);
 
@@ -354,6 +354,9 @@ int main(int argc, char *argv[])
 		case 's':
 			opts.final_state = TASK_STOPPED;
 			break;
+		case 'x':
+			opts.allow_external_unix_connections = true;
+			break;
 		case 'p':
 			pid = atoi(optarg);
 			opts.leader_only = true;
@@ -478,6 +481,7 @@ usage:
 	pr_msg("  -s             leave tasks in stopped state after checkpoint instead of killing them\n");
 	pr_msg("  -n             checkpoint/restore namespaces - values must be separated by comma\n");
 	pr_msg("                 supported: uts, ipc\n");
+	pr_msg("  -x             allow external unix connections\n");
 
 	pr_msg("\nAdditional common parameters:\n");
 	pr_msg("  -D dir         specifis directory where checkpoint files are/to be located\n");
diff --git a/include/crtools.h b/include/crtools.h
index d79878f..77bd8cf 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -67,6 +67,7 @@ struct cr_options {
 	bool			leader_only;
 	bool			show_pages_content;
 	bool			restore_detach;
+	bool			allow_external_unix_connections;
 	unsigned int		namespaces_flags;
 };
 
@@ -160,6 +161,7 @@ static inline int fdset_fd(const struct cr_fdset *fdset, int type)
 }
 
 extern struct cr_fdset *glob_fdset;
+extern struct cr_options opts;
 
 int cr_dump_tasks(pid_t pid, const struct cr_options *opts);
 int cr_restore_tasks(pid_t pid, struct cr_options *opts);
diff --git a/sockets.c b/sockets.c
index 4825821..f00ffe8 100644
--- a/sockets.c
+++ b/sockets.c
@@ -38,6 +38,8 @@ static char buf[4096];
 #define SOCKFS_MAGIC	0x534F434B
 #endif
 
+#define O_EXTERN	020000000000
+
 struct socket_desc {
 	unsigned int		family;
 	unsigned int		ino;
@@ -412,10 +414,37 @@ static int dump_one_unix(const struct socket_desc *_sk, struct fd_parms *p,
 		 * Peer should have us as peer or have a name by which
 		 * we can access one.
 		 */
-		if (!peer->name && (peer->peer_ino != ue.id)) {
-			pr_err("Unix socket %x with unreachable peer %x (%x/%s)\n",
-					ue.id, ue.peer, peer->peer_ino, peer->name);
-			goto err;
+		if (peer->peer_ino != ue.id) {
+			if (!peer->name) {
+				pr_err("Unix socket %x with unreachable peer %x (%x/%s)\n",
+				       ue.id, ue.peer, peer->peer_ino, peer->name);
+				goto err;
+			}
+
+			struct unix_sk_entry pt = { };
+
+			/*
+			 * Socket is not connected back but have a name,
+			 * so at restore time we will find it here. Note
+			 * the id is set to impossible value by purpose.
+			 */
+
+			pt.id		= peer->sd.ino;
+			pt.type		= SOCK_DGRAM;
+			pt.state	= TCP_LISTEN;
+			pt.namelen	= peer->namelen;
+			pt.flags	= O_EXTERN;
+			pt.peer		= -1u;
+
+			show_one_unix("Dumping", peer);
+
+			if (write_img(fdset_fd(glob_fdset, CR_FD_UNIXSK), &pt))
+				goto err;
+			if (write_img_buf(fdset_fd(glob_fdset, CR_FD_UNIXSK),
+					  peer->name, pt.namelen))
+				goto err;
+
+			show_one_unix_img("Dumped", &pt);
 		}
 	} else if (ue.state == TCP_ESTABLISHED) {
 		const struct unix_sk_listen_icon *e;
@@ -1239,6 +1268,7 @@ try_again:
 		if (set_fd_flags(fle->fd, ui->ue.flags))
 			return -1;
 
+next:
 		cj = cj->next;
 	}
 
@@ -1484,9 +1514,12 @@ int resolve_unix_peers(void)
 			continue;
 
 		peer = find_unix_sk(ui->ue.peer);
-		if (!peer) {
+		pr_debug("peer %p\n", peer);
+		if (!peer ||
+		    (peer && (peer->ue.flags & O_EXTERN)  &&
+		     !opts.allow_external_unix_connections)) {
 			pr_err("FATAL: Peer %x unresolved for %x\n",
-					ui->ue.peer, ui->ue.id);
+			       ui->ue.peer, ui->ue.id);
 			return -1;
 		}
 
-- 
1.7.7.6



More information about the CRIU mailing list