[CRIU] [PATCH v2] files: don't create a transport socket for each file
Andrew Vagin
avagin at virtuozzo.com
Tue Aug 2 13:37:03 PDT 2016
On Tue, Aug 02, 2016 at 03:11:16PM +0300, Pavel Emelyanov wrote:
> On 07/29/2016 09:41 AM, Andrey Vagin wrote:
> > From: Andrew Vagin <avagin at virtuozzo.com>
> >
> > This is an unix dgram socket which doesn't have an address and
> > isn't connected to somewhere, so we can use one socket for all processes.
> >
> > v2: return non-zero code in error cases
> > Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
> > ---
> > criu/cr-restore.c | 6 ++++++
> > criu/files.c | 25 +++++++++++++++++++------
> > criu/include/files.h | 2 ++
> > criu/include/servicefd.h | 1 +
> > 4 files changed, 28 insertions(+), 6 deletions(-)
> >
> > diff --git a/criu/cr-restore.c b/criu/cr-restore.c
> > index 9bd1747..6c83d7f 100644
> > --- a/criu/cr-restore.c
> > +++ b/criu/cr-restore.c
> > @@ -271,6 +271,10 @@ static int root_prepare_shared(void)
> > if (ret)
> > goto err;
> >
> > + ret = open_transport_socket();
>
> It has to be per-netns, I guess, and thus -- sit on struct ns_id
> in the struct { } net?
No, it has not. All namespaces will be restored from the root task
and then the root task will have file descriptros for all of them.
So any task is able to switch between network namespaces via
/proc/ROOT_PID/fd/ns_fd_X.
We need this to restore sockets, because a task can have sockets from
several network namespaces.
And it allows us to create all transport sockets in the root network
namespace. We have a stage where a receiving transport sockets are
created, so we will need to switch a network namespace only once to
create all this sockets.
>
> > + if (ret)
> > + goto err;
> > +
> > show_saved_files();
> > err:
> > return ret;
> > @@ -711,6 +715,8 @@ static int restore_one_alive_task(int pid, CoreEntry *core)
> > if (prepare_vmas(current, ta))
> > return -1;
> >
> > + close_service_fd(TRANSPORT_FD_OFF);
> > +
> > if (setup_uffd(pid, ta))
> > return -1;
> >
> > diff --git a/criu/files.c b/criu/files.c
> > index a66a142..a29d317 100644
> > --- a/criu/files.c
> > +++ b/criu/files.c
> > @@ -1000,11 +1000,7 @@ static int serve_out_fd(int pid, int fd, struct file_desc *d)
> > int sock, ret;
> > struct fdinfo_list_entry *fle;
> >
> > - sock = socket(PF_UNIX, SOCK_DGRAM, 0);
> > - if (sock < 0) {
> > - pr_perror("Can't create socket");
> > - return -1;
> > - }
> > + sock = get_service_fd(TRANSPORT_FD_OFF);
> >
> > pr_info("\t\tCreate fd for %d\n", fd);
> >
> > @@ -1022,7 +1018,6 @@ static int serve_out_fd(int pid, int fd, struct file_desc *d)
> >
> > ret = 0;
> > out:
> > - close(sock);
> > return ret;
> > }
> >
> > @@ -1672,3 +1667,21 @@ char *external_lookup_by_key(char *key)
> > }
> > return NULL;
> > }
> > +
> > +int open_transport_socket()
> > +{
> > + int sock;
> > +
> > + sock = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
> > + if (sock < 0) {
> > + pr_perror("Can't create socket");
> > + return -1;
> > + }
> > + if (install_service_fd(TRANSPORT_FD_OFF, sock) < 0) {
> > + close(sock);
> > + return -1;
> > + }
> > + close(sock);
> > +
> > + return 0;
> > +}
> > diff --git a/criu/include/files.h b/criu/include/files.h
> > index e0b853d..7513b21 100644
> > --- a/criu/include/files.h
> > +++ b/criu/include/files.h
> > @@ -201,4 +201,6 @@ extern FdinfoEntry *dup_fdinfo(FdinfoEntry *old, int fd, unsigned flags);
> > int dup_fle(struct pstree_item *task, struct fdinfo_list_entry *ple,
> > int fd, unsigned flags);
> >
> > +extern int open_transport_socket(void);
> > +
> > #endif /* __CR_FILES_H__ */
> > diff --git a/criu/include/servicefd.h b/criu/include/servicefd.h
> > index e133752..a35f25a 100644
> > --- a/criu/include/servicefd.h
> > +++ b/criu/include/servicefd.h
> > @@ -19,6 +19,7 @@ enum sfd_type {
> > CGROUP_YARD,
> > USERNSD_SK, /* Socket for usernsd */
> > NS_FD_OFF, /* Node's net namespace fd */
> > + TRANSPORT_FD_OFF, /* to transfer file descriptors */
> >
> > SERVICE_FD_MAX
> > };
> >
>
More information about the CRIU
mailing list