[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