[CRIU] [PATCH 01/13] crtools: close all desriptors only for the root task
Andrey Vagin
avagin at openvz.org
Tue Apr 8 17:13:29 PDT 2014
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: Andrey Vagin <avagin at openvz.org>
---
cr-restore.c | 19 ++++++++++---------
include/servicefd.h | 1 +
util.c | 12 ++++++++++++
3 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/cr-restore.c b/cr-restore.c
index aa0ae83..0895c1c 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1213,15 +1213,19 @@ 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)
+ 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);
@@ -1237,6 +1241,9 @@ static int restore_task_with_children(void *_arg)
if (restore_finish_stage(CR_STATE_RESTORE_NS) < 0)
exit(1);
+ if (close_old_fds(current))
+ exit(1);
+
if (collect_mount_info(getpid()))
exit(1);
@@ -1271,12 +1278,6 @@ 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);
diff --git a/include/servicefd.h b/include/servicefd.h
index 2a2542c..f855fe8 100644
--- a/include/servicefd.h
+++ b/include/servicefd.h
@@ -25,6 +25,7 @@ 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);
diff --git a/util.c b/util.c
index 32860d3..425b267 100644
--- a/util.c
+++ b/util.c
@@ -341,6 +341,18 @@ 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;
--
1.8.5.3
More information about the CRIU
mailing list