[CRIU] [PATCH cr] files: rework a function for closing all
descriptors
Andrey Vagin
avagin at openvz.org
Fri Sep 28 14:34:58 EDT 2012
It reads /proc/PID/fd and close all descriptors except service fds.
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
files.c | 39 +++++++++++++++++++++++++++------------
include/crtools.h | 1 +
include/files.h | 1 +
util.c | 13 ++++++++++++-
4 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/files.c b/files.c
index 8c01f68..bd8a48b 100644
--- a/files.c
+++ b/files.c
@@ -496,20 +496,35 @@ static int open_fdinfos(int pid, struct list_head *list, int state)
return ret;
}
-static int close_old_fds(struct pstree_item *me)
+int close_old_fds(struct pstree_item *me)
{
- /*
- * FIXME -- The existing test_init implementation uses system()
- * which in turn doesn't work when all fds are closed
- */
- if (me->pid.virt == 1)
- return 0;
+ DIR *dir;
+ struct dirent *de;
+ int fd, ret;
+
+ dir = opendir_proc(getpid(), "fd");
+ if (dir == NULL)
+ return -1;
+
+ while ((de = readdir(dir))) {
+ if (!strcmp(de->d_name, "."))
+ continue;
+ if (!strcmp(de->d_name, ".."))
+ continue;
+
+ ret = sscanf(de->d_name, "%d", &fd);
+ if (ret != 1) {
+ pr_err("Can't parse %s\n", de->d_name);
+ return -1;
+ }
+
+ if ((!is_one_of_service_fds(fd)) && dirfd(dir) != fd)
+ close_safe(&fd);
+ }
+
+ closedir(dir);
+ close_pid_proc();
- /* FIXME -- wait for nextfd syscall (or read proc) */
- close(0);
- close(1);
- close(2);
- close(255); /* bash */
return 0;
}
diff --git a/include/crtools.h b/include/crtools.h
index dd67854..7d1c90f 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -123,6 +123,7 @@ enum sfd_type {
extern int init_service_fd(void);
extern int get_service_fd(enum sfd_type type);
extern bool is_service_fd(int fd, enum sfd_type type);
+extern bool is_one_of_service_fds(int fd);
/* file descriptors template */
struct cr_fd_desc_tmpl {
diff --git a/include/files.h b/include/files.h
index cc0e46f..b00d662 100644
--- a/include/files.h
+++ b/include/files.h
@@ -83,6 +83,7 @@ extern int rst_file_params(int fd, FownEntry *fown, int flags);
extern void show_saved_files(void);
+extern int close_old_fds(struct pstree_item *me);
extern int prepare_fds(struct pstree_item *me);
extern int prepare_fd_pid(int pid, struct rst_info *rst_info);
extern int prepare_ctl_tty(int pid, struct rst_info *rst_info, u32 ctl_tty_id);
diff --git a/util.c b/util.c
index 72d078d..3aba06d 100644
--- a/util.c
+++ b/util.c
@@ -281,10 +281,21 @@ int init_service_fd(void)
return 0;
}
+static int __get_service_fd(enum sfd_type type)
+{
+ return service_fd_rlim_cur - type;
+}
+
int get_service_fd(enum sfd_type type)
{
BUG_ON((int)type <= SERVICE_FD_MIN || (int)type >= SERVICE_FD_MAX);
- return service_fd_rlim_cur - type;
+ return __get_service_fd(type);
+}
+
+bool is_one_of_service_fds(int fd)
+{
+ return fd > __get_service_fd(SERVICE_FD_MAX) &&
+ fd < __get_service_fd(SERVICE_FD_MIN);
}
bool is_service_fd(int fd, enum sfd_type type)
--
1.7.1
More information about the CRIU
mailing list