2
0
mirror of https://github.com/checkpoint-restore/criu synced 2025-08-30 05:48:05 +00:00

Revert "crtools: close all desriptors only for the root task"

We have a race. Consider we have 3 tasks, A, B and C. A and B
share fdtable, C -- does not. Then we might be in a situation
when A is restoring memory reading mem images, and B -- forking
the C child. In that case descriptors held by A (for mem restore)
will be inherited by C and will not get closed.

This reverts commit d36e07aabe073993d8ae9695e33f6e45b2eb6a21.
This commit is contained in:
Pavel Emelyanov 2014-04-21 14:48:05 +04:00
parent 4bd119ddf6
commit e8ac085af8
3 changed files with 9 additions and 25 deletions

View File

@ -1213,24 +1213,15 @@ static int restore_task_with_children(void *_arg)
current->pid.real, current->pid.virt);
}
if ( !(ca->clone_flags & CLONE_FILES))
close_safe(&ca->fd);
if (current->state != TASK_HELPER) {
ret = clone_service_fd(current->rst->service_fd_id);
if (ret)
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();
if (current->pid.virt != pid) {
pr_err("Pid %d do not match expected %d\n", pid, current->pid.virt);
@ -1286,6 +1277,12 @@ static int restore_task_with_children(void *_arg)
if (prepare_mappings(pid))
exit(1);
if (!(ca->clone_flags & CLONE_FILES)) {
ret = close_old_fds(current);
if (ret)
exit(1);
}
if (create_children_and_session())
exit(1);

View File

@ -26,7 +26,6 @@ extern int get_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 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_any_service_fd(int fd);

12
util.c
View File

@ -341,18 +341,6 @@ int close_service_fd(enum sfd_type type)
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 ret = -1, i;