Commit 96946ee9 authored by Kirill Tkhai's avatar Kirill Tkhai Committed by Pavel Emelyanov

files: Add new_fd parameter to file_desc_ops::open()

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

In next patches we will use return value "1" to indicate,
that open callback should be called once again, and restore
for this fle has not finished yet. So, we need to be able
to differ file descriptor with number 1 and "again" request.
We do not use negative value like -2 for this purpose,
because we want to allow fles to be served out before
they are completelly restored. So, if a fle is successefuly open,
but it's need one more call of open to complete its restore,
then we return 1 and populate new_fd in not negative value.
See "files: Kill struct file_desc_ops::post_open" for the details.

Also, export open_pipe()

v5: Use 0 and -1 for successful return and error.
v6: Rebase on new criu
Signed-off-by: 's avatarKirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 7395c486
......@@ -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 0;
err_close:
close(tmp);
......
......@@ -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 0;
err_close:
close(tmp);
return -1;
......
......@@ -106,11 +106,16 @@ out:
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 -1;
*new_fd = fd;
return 0;
}
static void collect_fifo_fd(struct file_desc *d,
......
......@@ -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 0;
}
static struct file_desc_ops ext_desc_ops = {
......
......@@ -1660,9 +1660,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 -1;
*new_fd = tmp;
return 0;
}
static char *reg_file_path(struct file_desc *d, char *buf, size_t s)
......
......@@ -1053,8 +1053,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))
......
......@@ -674,7 +674,7 @@ err:
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;
......@@ -699,10 +699,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 0;
}
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;
......@@ -734,7 +735,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 0;
}
static struct file_desc_ops inotify_desc_ops = {
......
......@@ -104,7 +104,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.
......
......@@ -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__ */
......@@ -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 0;
}
static struct file_desc_ops ns_desc_ops = {
......
......@@ -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 ? -1 : 0;
}
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 -1;
*new_fd = tmp;
return 0;
}
static struct file_desc_ops pipe_desc_ops = {
......
......@@ -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 0;
err_close:
close(tmp);
......
......@@ -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 @@ done:
if (restore_socket_opts(sk, ie->opts))
goto err;
return sk;
*new_fd = sk;
return 0;
err:
close(sk);
......
......@@ -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 0;
err:
close(sk);
return -1;
......
......@@ -405,7 +405,7 @@ static int restore_rings(int sk, PacketSockEntry *psk)
return 0;
}
static int open_packet_sk_spkt(PacketSockEntry *pse)
static int open_packet_sk_spkt(PacketSockEntry *pse, int *new_fd)
{
struct sockaddr addr_spkt;
int sk;
......@@ -447,14 +447,15 @@ static int open_packet_sk_spkt(PacketSockEntry *pse)
if (restore_socket_opts(sk, pse->opts))
goto err;
return sk;
*new_fd = sk;
return 0;
err:
close(sk);
return -1;
}
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;
......@@ -467,7 +468,7 @@ static int open_packet_sk(struct file_desc *d)
pr_info("Opening packet socket id %#x\n", pse->id);
if (pse->type == SOCK_PACKET)
return open_packet_sk_spkt(pse);
return open_packet_sk_spkt(pse, new_fd);
sk = socket(PF_PACKET, pse->type, pse->protocol);
if (sk < 0) {
......@@ -538,7 +539,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 0;
err_cl:
close(sk);
......
......@@ -1054,7 +1054,7 @@ done:
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 0;
}
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 0;
}
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 @@ out:
if (restore_socket_opts(sk, ui->ue->opts))
return -1;
return sk;
*new_fd = sk;
return 0;
}
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 ? 0 : -1;
} 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)
......
......@@ -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 0;
err_close:
close_safe(&tmp);
......
......@@ -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 -1;
*new_fd = ret;
return 0;
}
static void tty_collect_fd(struct file_desc *d, struct fdinfo_list_entry *fle,
......
......@@ -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 0;
err:
close(fd);
......
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