[CRIU] [PATCH v3 24/26] files: Add new_fd parameter to file_desc_ops::open()

Kirill Tkhai ktkhai at virtuozzo.com
Mon Dec 5 06:11:23 PST 2016


Return results of work separate: a new fd is in a parameter,
a status is in return value.

Also, export open_pipe()

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 criu/eventfd.c       |    5 +++--
 criu/eventpoll.c     |    5 +++--
 criu/fifo.c          |    9 +++++++--
 criu/files-ext.c     |    5 +++--
 criu/files-reg.c     |   10 ++++++++--
 criu/files.c         |    3 +--
 criu/fsnotify.c      |   10 ++++++----
 criu/include/files.h |    2 +-
 criu/include/pipes.h |    1 +
 criu/namespaces.c    |    5 +++--
 criu/pipes.c         |   19 +++++++++++--------
 criu/signalfd.c      |    5 +++--
 criu/sk-inet.c       |    7 ++++---
 criu/sk-netlink.c    |    5 +++--
 criu/sk-packet.c     |    5 +++--
 criu/sk-unix.c       |   32 ++++++++++++++++++--------------
 criu/timerfd.c       |    5 +++--
 criu/tty.c           |   18 +++++++++++-------
 criu/tun.c           |    9 +++++----
 19 files changed, 97 insertions(+), 63 deletions(-)

diff --git a/criu/eventfd.c b/criu/eventfd.c
index 0aab428..3806168 100644
--- a/criu/eventfd.c
+++ b/criu/eventfd.c
@@ -79,7 +79,7 @@ const struct fdtype_ops eventfd_dump_ops = {
 	.dump		= dump_one_eventfd,
 };
 
-static int eventfd_open(struct file_desc *d)
+static int eventfd_open(struct file_desc *d, int *new_fd)
 {
 	struct eventfd_file_info *info;
 	int tmp;
@@ -99,7 +99,8 @@ static int eventfd_open(struct file_desc *d)
 		goto err_close;
 	}
 
-	return tmp;
+	*new_fd = tmp;
+	return ORV_OK;
 
 err_close:
 	close(tmp);
diff --git a/criu/eventpoll.c b/criu/eventpoll.c
index a65098d..4d34bee 100644
--- a/criu/eventpoll.c
+++ b/criu/eventpoll.c
@@ -114,7 +114,7 @@ const struct fdtype_ops eventpoll_dump_ops = {
 	.dump		= dump_one_eventpoll,
 };
 
-static int eventpoll_open(struct file_desc *d)
+static int eventpoll_open(struct file_desc *d, int *new_fd)
 {
 	struct eventpoll_file_info *info;
 	int tmp;
@@ -136,7 +136,8 @@ static int eventpoll_open(struct file_desc *d)
 		goto err_close;
 	}
 
-	return tmp;
+	*new_fd = tmp;
+	return ORV_OK;
 err_close:
 	close(tmp);
 	return -1;
diff --git a/criu/fifo.c b/criu/fifo.c
index 68f55b4..ebe2201 100644
--- a/criu/fifo.c
+++ b/criu/fifo.c
@@ -106,11 +106,16 @@ static int do_open_fifo(int ns_root_fd, struct reg_file_info *rfi, void *arg)
 	return new_fifo;
 }
 
-static int open_fifo_fd(struct file_desc *d)
+static int open_fifo_fd(struct file_desc *d, int *new_fd)
 {
 	struct fifo_info *info = container_of(d, struct fifo_info, d);
+	int fd;
 
-	return open_path(info->reg_d, do_open_fifo, info);
+	fd = open_path(info->reg_d, do_open_fifo, info);
+	if (fd < 0)
+		return ORV_ERR;
+	*new_fd = fd;
+	return ORV_OK;
 }
 
 static void collect_fifo_fd(struct file_desc *d,
diff --git a/criu/files-ext.c b/criu/files-ext.c
index 4c129fa..d5821e7 100644
--- a/criu/files-ext.c
+++ b/criu/files-ext.c
@@ -37,7 +37,7 @@ struct ext_file_info {
 	ExtFileEntry		*xfe;
 };
 
-static int open_fd(struct file_desc *d)
+static int open_fd(struct file_desc *d, int *new_fd)
 {
 	struct ext_file_info *xfi;
 	int fd;
@@ -53,7 +53,8 @@ static int open_fd(struct file_desc *d)
 	if (restore_fown(fd, xfi->xfe->fown))
 		return -1;
 
-	return fd;
+	*new_fd = fd;
+	return ORV_OK;
 }
 
 static struct file_desc_ops ext_desc_ops = {
diff --git a/criu/files-reg.c b/criu/files-reg.c
index 3834f38..2f6a14b 100644
--- a/criu/files-reg.c
+++ b/criu/files-reg.c
@@ -1643,9 +1643,15 @@ static void collect_reg_fd(struct file_desc *fdesc,
 	collect_gen_fd(fle, ri);
 }
 
-static int open_fe_fd(struct file_desc *fd)
+static int open_fe_fd(struct file_desc *fd, int *new_fd)
 {
-	return open_path(fd, do_open_reg, NULL);
+	int tmp;
+
+	tmp = open_path(fd, do_open_reg, NULL);
+	if (tmp < 0)
+		return ORV_ERR;
+	*new_fd = tmp;
+	return ORV_OK;
 }
 
 static char *reg_file_path(struct file_desc *d, char *buf, size_t s)
diff --git a/criu/files.c b/criu/files.c
index a5568cf..e226e71 100644
--- a/criu/files.c
+++ b/criu/files.c
@@ -1024,8 +1024,7 @@ static int open_fd(int pid, struct fdinfo_list_entry *fle)
 	if (fle != file_master(d))
 		return 0;
 
-	new_fd = d->ops->open(d);
-	if (new_fd < 0)
+	if (d->ops->open(d, &new_fd) < 0)
 		return -1;
 
 	if (reopen_fd_as(fle->fe->fd, new_fd))
diff --git a/criu/fsnotify.c b/criu/fsnotify.c
index a6e47a8..04e3cf1 100644
--- a/criu/fsnotify.c
+++ b/criu/fsnotify.c
@@ -680,7 +680,7 @@ static int restore_one_fanotify(int fd, struct fsnotify_mark_info *mark)
 	return ret;
 }
 
-static int open_inotify_fd(struct file_desc *d)
+static int open_inotify_fd(struct file_desc *d, int *new_fd)
 {
 	struct fsnotify_file_info *info;
 	struct fsnotify_mark_info *wd_info;
@@ -705,10 +705,11 @@ static int open_inotify_fd(struct file_desc *d)
 	if (restore_fown(tmp, info->ife->fown))
 		close_safe(&tmp);
 
-	return tmp;
+	*new_fd = tmp;
+	return ORV_OK;
 }
 
-static int open_fanotify_fd(struct file_desc *d)
+static int open_fanotify_fd(struct file_desc *d, int *new_fd)
 {
 	struct fsnotify_file_info *info;
 	struct fsnotify_mark_info *mark;
@@ -740,7 +741,8 @@ static int open_fanotify_fd(struct file_desc *d)
 	if (restore_fown(ret, info->ffe->fown))
 		close_safe(&ret);
 
-	return ret;
+	*new_fd = ret;
+	return ORV_OK;
 }
 
 static struct file_desc_ops inotify_desc_ops = {
diff --git a/criu/include/files.h b/criu/include/files.h
index 83f1cae..ca3eddc 100644
--- a/criu/include/files.h
+++ b/criu/include/files.h
@@ -111,7 +111,7 @@ struct file_desc_ops {
 	 * The returned descriptor may be closed (dup2-ed to another)
 	 * so it shouldn't be saved for any post-actions.
 	 */
-	int			(*open)(struct file_desc *d);
+	int			(*open)(struct file_desc *d, int *new_fd);
 	/*
 	 * Called on a file when all files of that type are opened
 	 * and with the fd being the "restored" one.
diff --git a/criu/include/pipes.h b/criu/include/pipes.h
index a16069b..47d98ae 100644
--- a/criu/include/pipes.h
+++ b/criu/include/pipes.h
@@ -58,5 +58,6 @@ struct pipe_info {
 
 extern int collect_one_pipe_ops(void *o, ProtobufCMessage *base,
 				struct file_desc_ops *ops);
+extern int open_pipe(struct file_desc *d, int *new_fd);
 
 #endif /* __CR_PIPES_H__ */
diff --git a/criu/namespaces.c b/criu/namespaces.c
index 26ccf13..2b38789 100644
--- a/criu/namespaces.c
+++ b/criu/namespaces.c
@@ -496,7 +496,7 @@ struct ns_file_info {
 	NsFileEntry		*nfe;
 };
 
-static int open_ns_fd(struct file_desc *d)
+static int open_ns_fd(struct file_desc *d, int *new_fd)
 {
 	struct ns_file_info *nfi = container_of(d, struct ns_file_info, d);
 	struct pstree_item *item, *t;
@@ -558,7 +558,8 @@ static int open_ns_fd(struct file_desc *d)
 		return fd;
 	}
 
-	return fd;
+	*new_fd = fd;
+	return ORV_OK;
 }
 
 static struct file_desc_ops ns_desc_ops = {
diff --git a/criu/pipes.c b/criu/pipes.c
index 08dd7d1..4aef0c5 100644
--- a/criu/pipes.c
+++ b/criu/pipes.c
@@ -227,7 +227,7 @@ static int reopen_pipe(int fd, int flags)
 	return ret;
 }
 
-static int recv_pipe_fd(struct pipe_info *pi)
+static int recv_pipe_fd(struct pipe_info *pi, int *new_fd)
 {
 	struct fdinfo_list_entry *fle;
 	int tmp, fd;
@@ -252,9 +252,10 @@ static int recv_pipe_fd(struct pipe_info *pi)
 			close(fd);
 			return -1;
 		}
+		*new_fd = fd;
 	}
 
-	return fd;
+	return fd < 0 ? ORV_ERR : ORV_OK;
 }
 
 static char *pipe_d_name(struct file_desc *d, char *buf, size_t s)
@@ -271,7 +272,7 @@ static char *pipe_d_name(struct file_desc *d, char *buf, size_t s)
 	return buf;
 }
 
-static int open_pipe(struct file_desc *d)
+int open_pipe(struct file_desc *d, int *new_fd)
 {
 	struct pipe_info *pi, *p;
 	int ret, tmp;
@@ -284,11 +285,11 @@ static int open_pipe(struct file_desc *d)
 			return tmp;
 
 		pi->reopen = 1;
-		goto out;
+		goto reopen;
 	}
 
 	if (!pi->create)
-		return recv_pipe_fd(pi);
+		return recv_pipe_fd(pi, new_fd);
 
 	if (pipe(pfd) < 0) {
 		pr_perror("Can't create pipe");
@@ -316,15 +317,17 @@ static int open_pipe(struct file_desc *d)
 	close(pfd[!(pi->pe->flags & O_WRONLY)]);
 	tmp = pfd[pi->pe->flags & O_WRONLY];
 
-out:
+reopen:
 	if (pi->reopen)
 		tmp = reopen_pipe(tmp, pi->pe->flags);
 
 	if (tmp >= 0)
 		if (rst_file_params(tmp, pi->pe->fown, pi->pe->flags))
 			return -1;
-
-	return tmp;
+	if (tmp < 0)
+		return ORV_ERR;
+	*new_fd = tmp;
+	return ORV_OK;
 }
 
 static struct file_desc_ops pipe_desc_ops = {
diff --git a/criu/signalfd.c b/criu/signalfd.c
index 2f5db58..9935216 100644
--- a/criu/signalfd.c
+++ b/criu/signalfd.c
@@ -72,7 +72,7 @@ static void sigset_fill(sigset_t *to, unsigned long long from)
 		}
 }
 
-static int signalfd_open(struct file_desc *d)
+static int signalfd_open(struct file_desc *d, int *new_fd)
 {
 	struct signalfd_info *info;
 	int tmp;
@@ -94,7 +94,8 @@ static int signalfd_open(struct file_desc *d)
 		goto err_close;
 	}
 
-	return tmp;
+	*new_fd = tmp;
+	return ORV_OK;
 
 err_close:
 	close(tmp);
diff --git a/criu/sk-inet.c b/criu/sk-inet.c
index b56c7e7..75979e9 100644
--- a/criu/sk-inet.c
+++ b/criu/sk-inet.c
@@ -484,7 +484,7 @@ int inet_collect_one(struct nlmsghdr *h, int family, int type)
 	return ret;
 }
 
-static int open_inet_sk(struct file_desc *d);
+static int open_inet_sk(struct file_desc *d, int *new_fd);
 static int post_open_inet_sk(struct file_desc *d, int sk);
 
 static struct file_desc_ops inet_desc_ops = {
@@ -604,7 +604,7 @@ int restore_ip_opts(int sk, IpOptsEntry *ioe)
 
 	return ret;
 }
-static int open_inet_sk(struct file_desc *d)
+static int open_inet_sk(struct file_desc *d, int *new_fd)
 {
 	struct inet_sk_info *ii;
 	InetSkEntry *ie;
@@ -701,7 +701,8 @@ static int open_inet_sk(struct file_desc *d)
 	if (restore_socket_opts(sk, ie->opts))
 		goto err;
 
-	return sk;
+	*new_fd = sk;
+	return ORV_OK;
 
 err:
 	close(sk);
diff --git a/criu/sk-netlink.c b/criu/sk-netlink.c
index dc5c4a1..7e11824 100644
--- a/criu/sk-netlink.c
+++ b/criu/sk-netlink.c
@@ -155,7 +155,7 @@ struct netlink_sock_info {
 	struct file_desc d;
 };
 
-static int open_netlink_sk(struct file_desc *d)
+static int open_netlink_sk(struct file_desc *d, int *new_fd)
 {
 	struct netlink_sock_info *nsi;
 	NetlinkSkEntry *nse;
@@ -206,7 +206,8 @@ static int open_netlink_sk(struct file_desc *d)
 	if (restore_socket_opts(sk, nse->opts))
 		goto err;
 
-	return sk;
+	*new_fd = sk;
+	return ORV_OK;
 err:
 	close(sk);
 	return -1;
diff --git a/criu/sk-packet.c b/criu/sk-packet.c
index bcd4ff3..9e56702 100644
--- a/criu/sk-packet.c
+++ b/criu/sk-packet.c
@@ -403,7 +403,7 @@ static int restore_rings(int sk, PacketSockEntry *psk)
 	return 0;
 }
 
-static int open_packet_sk(struct file_desc *d)
+static int open_packet_sk(struct file_desc *d, int *new_fd)
 {
 	struct packet_sock_info *psi;
 	PacketSockEntry *pse;
@@ -484,7 +484,8 @@ static int open_packet_sk(struct file_desc *d)
 	if (restore_socket_opts(sk, pse->opts))
 		goto err_cl;
 
-	return sk;
+	*new_fd = sk;
+	return ORV_OK;
 
 err_cl:
 	close(sk);
diff --git a/criu/sk-unix.c b/criu/sk-unix.c
index cb7a04d..9791f16 100644
--- a/criu/sk-unix.c
+++ b/criu/sk-unix.c
@@ -1054,7 +1054,7 @@ static int bind_unix_sk(int sk, struct unix_sk_info *ui)
 	return ret;
 }
 
-static int open_unixsk_pair_master(struct unix_sk_info *ui)
+static int open_unixsk_pair_master(struct unix_sk_info *ui, int *new_fd)
 {
 	int sk[2];
 	struct unix_sk_info *peer = ui->peer;
@@ -1093,10 +1093,11 @@ static int open_unixsk_pair_master(struct unix_sk_info *ui)
 
 	close(sk[1]);
 
-	return sk[0];
+	*new_fd = sk[0];
+	return ORV_OK;
 }
 
-static int open_unixsk_pair_slave(struct unix_sk_info *ui)
+static int open_unixsk_pair_slave(struct unix_sk_info *ui, int *new_fd)
 {
 	struct fdinfo_list_entry *fle;
 	int sk;
@@ -1124,10 +1125,11 @@ static int open_unixsk_pair_slave(struct unix_sk_info *ui)
 	if (shutdown_unix_sk(sk, ui))
 		return -1;
 
-	return sk;
+	*new_fd = sk;
+	return ORV_OK;
 }
 
-static int open_unixsk_standalone(struct unix_sk_info *ui)
+static int open_unixsk_standalone(struct unix_sk_info *ui, int *new_fd)
 {
 	int sk;
 
@@ -1264,26 +1266,28 @@ static int open_unixsk_standalone(struct unix_sk_info *ui)
 	if (restore_socket_opts(sk, ui->ue->opts))
 		return -1;
 
-	return sk;
+	*new_fd = sk;
+	return ORV_OK;
 }
 
-static int open_unix_sk(struct file_desc *d)
+static int open_unix_sk(struct file_desc *d, int *new_fd)
 {
 	struct unix_sk_info *ui;
+	int ret;
 
 	ui = container_of(d, struct unix_sk_info, d);
 
-	int unixsk_fd = -1;
-
-	if (inherited_fd(d, &unixsk_fd)) {
+	if (inherited_fd(d, new_fd)) {
 		ui->ue->uflags |= USK_INHERIT;
-		return unixsk_fd;
+		ret = *new_fd >= 0 ? ORV_OK : ORV_ERR;
 	} else if (ui->flags & USK_PAIR_MASTER)
-		return open_unixsk_pair_master(ui);
+		ret = open_unixsk_pair_master(ui, new_fd);
 	else if (ui->flags & USK_PAIR_SLAVE)
-		return open_unixsk_pair_slave(ui);
+		ret = open_unixsk_pair_slave(ui, new_fd);
 	else
-		return open_unixsk_standalone(ui);
+		ret = open_unixsk_standalone(ui, new_fd);
+
+	return ret;
 }
 
 static char *socket_d_name(struct file_desc *d, char *buf, size_t s)
diff --git a/criu/timerfd.c b/criu/timerfd.c
index a18588c..0f64d9a 100644
--- a/criu/timerfd.c
+++ b/criu/timerfd.c
@@ -122,7 +122,7 @@ int prepare_timerfds(struct task_restore_args *ta)
 	return 0;
 }
 
-static int timerfd_open(struct file_desc *d)
+static int timerfd_open(struct file_desc *d, int *new_fd)
 {
 	struct timerfd_info *info;
 	TimerfdEntry *tfe;
@@ -150,7 +150,8 @@ static int timerfd_open(struct file_desc *d)
 	info->t_fd = file_master(d)->fe->fd;
 	list_add_tail(&info->rlist, &rst_timerfds);
 
-	return tmp;
+	*new_fd = tmp;
+	return ORV_OK;
 
 err_close:
 	close_safe(&tmp);
diff --git a/criu/tty.c b/criu/tty.c
index 97443e8..89a370a 100644
--- a/criu/tty.c
+++ b/criu/tty.c
@@ -1093,19 +1093,23 @@ static int open_ext_tty(struct tty_info *info)
 	return fd;
 }
 
-static int tty_open(struct file_desc *d)
+static int tty_open(struct file_desc *d, int *new_fd)
 {
 	struct tty_info *info = container_of(d, struct tty_info, d);
+	int ret;
 
 	tty_show_pty_info("open", info);
 
 	if (!info->create)
-		return receive_tty(info);
-
-	if (is_pty(info->driver) && !tty_is_master(info))
-		return pty_open_unpaired_slave(d, info);
-
-	return info->driver->open(info);
+		ret = receive_tty(info);
+	else if (is_pty(info->driver) && !tty_is_master(info))
+		ret = pty_open_unpaired_slave(d, info);
+	else
+		ret = info->driver->open(info);
+	if (ret < 0)
+		return ORV_ERR;
+	*new_fd = ret;
+	return ORV_OK;
 }
 
 static void tty_collect_fd(struct file_desc *d, struct fdinfo_list_entry *fle,
diff --git a/criu/tun.c b/criu/tun.c
index 391f968..ce35dfa 100644
--- a/criu/tun.c
+++ b/criu/tun.c
@@ -320,7 +320,7 @@ struct tunfile_info {
 	TunfileEntry *tfe;
 };
 
-static int tunfile_open(struct file_desc *d)
+static int tunfile_open(struct file_desc *d, int *new_fd)
 {
 	int fd;
 	struct tunfile_info *ti;
@@ -334,7 +334,7 @@ static int tunfile_open(struct file_desc *d)
 
 	if (!ti->tfe->netdev)
 		/* just-opened tun file */
-		return fd;
+		goto ok;;
 
 	tl = find_tun_link(ti->tfe->netdev);
 	if (!tl) {
@@ -367,8 +367,9 @@ static int tunfile_open(struct file_desc *d)
 			goto err;
 		}
 	}
-
-	return fd;
+ok:
+	*new_fd = fd;
+	return ORV_OK;
 
 err:
 	close(fd);



More information about the CRIU mailing list