[CRIU] [PATCH cr] files: rework a function for closing all
descriptors (v2)
Andrey Vagin
avagin at openvz.org
Fri Sep 28 18:42:19 EDT 2012
It reads /proc/PID/fd and close all descriptors except service fds.
v2: s/is_one_of_service_fds/is_any_service_fd
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
files.c | 37 ++++++++++++++++++++++++++-----------
include/crtools.h | 1 +
util.c | 13 ++++++++++++-
3 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/files.c b/files.c
index 8c01f68..bccb9a5 100644
--- a/files.c
+++ b/files.c
@@ -498,18 +498,33 @@ static int open_fdinfos(int pid, struct list_head *list, int state)
static 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_any_service_fd(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..3c31b88 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_any_service_fd(int fd);
/* file descriptors template */
struct cr_fd_desc_tmpl {
diff --git a/util.c b/util.c
index 72d078d..f1f0155 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_any_service_fd(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