Commit d36e07aa authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

crtools: close all desriptors only for the root task

For all other tasks only unsed service descriptors will be closed.

This change allows to have file descriptors, which may be used for
restoring namespaces. All non-server descriptors must be closed before
restoring files.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent bb5bba53
...@@ -1213,15 +1213,24 @@ static int restore_task_with_children(void *_arg) ...@@ -1213,15 +1213,24 @@ static int restore_task_with_children(void *_arg)
current->pid.real, current->pid.virt); current->pid.real, current->pid.virt);
} }
if ( !(ca->clone_flags & CLONE_FILES))
close_safe(&ca->fd);
if (current->state != TASK_HELPER) { if (current->state != TASK_HELPER) {
ret = clone_service_fd(current->rst->service_fd_id); ret = clone_service_fd(current->rst->service_fd_id);
if (ret) if (ret)
exit(1); exit(1);
} }
if (!(ca->clone_flags & CLONE_FILES)) {
close_safe(&ca->fd);
if (current->parent && current->parent->rst->fdt)
/*
* We're the first child with our own fdtable of
* a parent which had it shared. From that parent
* we have extra service file descriptors left.
*/
close_old_servie_fd(current->parent->rst->fdt->nr);
}
pid = getpid(); pid = getpid();
if (current->pid.virt != pid) { if (current->pid.virt != pid) {
pr_err("Pid %d do not match expected %d\n", pid, current->pid.virt); pr_err("Pid %d do not match expected %d\n", pid, current->pid.virt);
...@@ -1237,6 +1246,9 @@ static int restore_task_with_children(void *_arg) ...@@ -1237,6 +1246,9 @@ static int restore_task_with_children(void *_arg)
if (restore_finish_stage(CR_STATE_RESTORE_NS) < 0) if (restore_finish_stage(CR_STATE_RESTORE_NS) < 0)
exit(1); exit(1);
if (close_old_fds(current))
exit(1);
if (collect_mount_info(getpid())) if (collect_mount_info(getpid()))
exit(1); exit(1);
...@@ -1271,12 +1283,6 @@ static int restore_task_with_children(void *_arg) ...@@ -1271,12 +1283,6 @@ static int restore_task_with_children(void *_arg)
if (prepare_mappings(pid)) if (prepare_mappings(pid))
exit(1); exit(1);
if (!(ca->clone_flags & CLONE_FILES)) {
ret = close_old_fds(current);
if (ret)
exit(1);
}
if (create_children_and_session()) if (create_children_and_session())
exit(1); exit(1);
......
...@@ -25,6 +25,7 @@ extern int get_service_fd(enum sfd_type type); ...@@ -25,6 +25,7 @@ extern int get_service_fd(enum sfd_type type);
extern int reserve_service_fd(enum sfd_type type); extern int reserve_service_fd(enum sfd_type type);
extern int install_service_fd(enum sfd_type type, int fd); extern int install_service_fd(enum sfd_type type, int fd);
extern int close_service_fd(enum sfd_type type); extern int close_service_fd(enum sfd_type type);
extern void close_old_servie_fd(int nr);
extern bool is_service_fd(int fd, enum sfd_type type); extern bool is_service_fd(int fd, enum sfd_type type);
extern bool is_any_service_fd(int fd); extern bool is_any_service_fd(int fd);
......
...@@ -341,6 +341,18 @@ int close_service_fd(enum sfd_type type) ...@@ -341,6 +341,18 @@ int close_service_fd(enum sfd_type type)
return 0; return 0;
} }
/* Close all unused service descriptors on a depth of nr. */
void close_old_servie_fd(int nr)
{
int level, i;
BUG_ON(service_fd_id != 0);
for (level = 1; level < nr; level++) {
for (i = SERVICE_FD_MIN + 1; i < SERVICE_FD_MAX; i++) {
close(__get_service_fd(i, level));
}
}
}
int clone_service_fd(int id) int clone_service_fd(int id)
{ {
int ret = -1, i; int ret = -1, i;
......
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