[CRIU] [PATCH 04/11] crtools: add ability to create and close a service fd (v3)
Andrey Vagin
avagin at openvz.org
Fri Jan 11 09:16:20 EST 2013
A service fd should be created, otherwise get_service_fd returns -1.
This patch removes this functionality from other subsystems and
allows to clone service descriptors.
v2: rename open_service_fd to install_service_fd
v3: two patches were merged for bisecting
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
image.c | 24 +++++++----------
include/crtools.h | 2 ++
log.c | 59 +++++++++++++----------------------------
tty.c | 8 ++----
util.c | 78 +++++++++++++++++++++++++++++++++++--------------------
5 files changed, 81 insertions(+), 90 deletions(-)
diff --git a/image.c b/image.c
index 2d13b1a..626aa83 100644
--- a/image.c
+++ b/image.c
@@ -228,10 +228,9 @@ struct cr_fdset *cr_glob_fdset_open(int mode)
return cr_fdset_open(-1 /* ignored */, _CR_FD_GLOB_FROM, _CR_FD_GLOB_TO, mode);
}
-static int image_dir_fd = -1;
-
int open_image(int type, unsigned long flags, ...)
{
+ int dfd = get_service_fd(IMG_FD_OFF);
char path[PATH_MAX];
va_list args;
int ret;
@@ -241,14 +240,14 @@ int open_image(int type, unsigned long flags, ...)
va_end(args);
if (flags & O_EXCL) {
- ret = unlinkat(image_dir_fd, path, 0);
+ ret = unlinkat(dfd, path, 0);
if (ret && errno != ENOENT) {
pr_perror("Unable to unlink %s", path);
goto err;
}
}
- ret = openat(image_dir_fd, path, flags, CR_FD_PERM);
+ ret = openat(dfd, path, flags, CR_FD_PERM);
if (ret < 0) {
pr_perror("Unable to open %s", path);
goto err;
@@ -279,13 +278,7 @@ err:
int open_image_dir(void)
{
- int fd;
-
- image_dir_fd = get_service_fd(IMG_FD_OFF);
- if (image_dir_fd < 0) {
- pr_perror("Can't get image fd");
- return -1;
- }
+ int fd, ret;
fd = open(".", O_RDONLY);
if (fd < 0) {
@@ -293,13 +286,14 @@ int open_image_dir(void)
return -1;
}
- pr_info("Image dir fd is %d\n", image_dir_fd);
+ ret = install_service_fd(IMG_FD_OFF, fd);
+
+ close(fd);
- return reopen_fd_as(image_dir_fd, fd);
+ return ret;
}
void close_image_dir(void)
{
- close(image_dir_fd);
- image_dir_fd = -1;
+ close_service_fd(IMG_FD_OFF);
}
diff --git a/include/crtools.h b/include/crtools.h
index 72b7699..3300542 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -125,6 +125,8 @@ enum sfd_type {
extern int clone_service_fd(int id);
extern int init_service_fd(void);
extern int get_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 bool is_service_fd(int fd, enum sfd_type type);
extern bool is_any_service_fd(int fd);
diff --git a/log.c b/log.c
index c02dff2..5882e9c 100644
--- a/log.c
+++ b/log.c
@@ -20,8 +20,6 @@
#define DEFAULT_LOGFD STDERR_FILENO
static unsigned int current_loglevel = DEFAULT_LOGLEVEL;
-static int current_logfd = DEFAULT_LOGFD;
-static int logdir = -1;
static char buffer[PAGE_SIZE];
static char buf_off = 0;
@@ -55,27 +53,22 @@ static void print_ts(void)
buffer[TS_BUF_OFF - 1] = ' '; /* kill the '\0' produced by snprintf */
}
-
-
int log_get_fd(void)
{
- return current_logfd;
+ int fd = get_service_fd(LOG_FD_OFF);
+
+ return fd < 0 ? DEFAULT_LOGFD : fd;
}
int log_init(const char *output)
{
- int new_logfd, sfd, dfd;
+ int new_logfd, dfd, fd;
gettimeofday(&start, NULL);
buf_off = TS_BUF_OFF;
dfd = get_service_fd(LOG_DIR_FD_OFF);
if (dfd < 0) {
- pr_msg("Can't obtain logfd");
- goto err;
- }
-
- if (logdir < 0) {
int tmp;
tmp = open(".", O_RDONLY);
if (tmp == -1) {
@@ -83,40 +76,26 @@ int log_init(const char *output)
return -1;
}
- if (reopen_fd_as(dfd, tmp) < 0)
+ dfd = install_service_fd(LOG_DIR_FD_OFF, tmp);
+ close(tmp);
+ if (dfd < 0)
return -1;
-
- logdir = dfd;
- }
-
- sfd = get_service_fd(LOG_FD_OFF);
- if (sfd < 0) {
- pr_msg("Can't obtain logfd");
- goto err;
}
if (output) {
- new_logfd = openat(logdir, output,
+ new_logfd = openat(dfd, output,
O_CREAT | O_TRUNC | O_WRONLY | O_APPEND, 0600);
if (new_logfd < 0) {
pr_perror("Can't create log file %s", output);
return -1;
}
+ } else
+ new_logfd = dup(DEFAULT_LOGFD);
- if (sfd == current_logfd)
- close(sfd);
-
- if (reopen_fd_as(sfd, new_logfd) < 0)
- goto err;
- } else {
- new_logfd = dup2(DEFAULT_LOGFD, sfd);
- if (new_logfd < 0) {
- pr_perror("Dup %d -> %d failed", DEFAULT_LOGFD, sfd);
- goto err;
- }
- }
-
- current_logfd = sfd;
+ fd = install_service_fd(LOG_FD_OFF, new_logfd);
+ close(new_logfd);
+ if (fd < 0)
+ goto err;
return 0;
@@ -151,15 +130,13 @@ int log_init_by_pid(void)
void log_fini(void)
{
- if (current_logfd > 2)
- close_safe(¤t_logfd);
-
- current_logfd = DEFAULT_LOGFD;
+ close_service_fd(LOG_FD_OFF);
+ log_closedir();
}
void log_closedir(void)
{
- close_safe(&logdir);
+ close_service_fd(LOG_DIR_FD_OFF);
}
void log_set_loglevel(unsigned int level)
@@ -186,7 +163,7 @@ void print_on_level(unsigned int loglevel, const char *format, ...)
} else {
if (loglevel > current_loglevel)
return;
- fd = current_logfd;
+ fd = log_get_fd();
print_ts();
off = 0;
}
diff --git a/tty.c b/tty.c
index 0f7c87a..5a78a0f 100644
--- a/tty.c
+++ b/tty.c
@@ -94,7 +94,6 @@ struct tty_dump_info {
static LIST_HEAD(all_tty_info_entries);
static LIST_HEAD(all_ttys);
-static int self_stdin = -1;
#define INHERIT_SID (-1)
@@ -1196,15 +1195,12 @@ int dump_tty(struct fd_parms *p, int lfd, const int fdinfo)
int tty_prep_fds(void)
{
- self_stdin = get_service_fd(SELF_STDIN_OFF);
-
if (!isatty(STDIN_FILENO)) {
pr_err("Standart stream is not a terminal, aborting\n");
return -1;
}
- if (dup2(STDIN_FILENO, self_stdin) < 0) {
- self_stdin = -1;
+ if (install_service_fd(SELF_STDIN_OFF, STDIN_FILENO) < 0) {
pr_perror("Can't dup stdin to SELF_STDIN_OFF");
return -1;
}
@@ -1214,5 +1210,5 @@ int tty_prep_fds(void)
void tty_fini_fds(void)
{
- close_safe(&self_stdin);
+ close_service_fd(SELF_STDIN_OFF);
}
diff --git a/util.c b/util.c
index e230f2d..82220ff 100644
--- a/util.c
+++ b/util.c
@@ -173,7 +173,6 @@ int move_img_fd(int *img_fd, int want_fd)
static pid_t open_proc_pid = 0;
static int open_proc_fd = -1;
-static int proc_dir_fd = -1;
int close_pid_proc(void)
{
@@ -191,30 +190,18 @@ int close_pid_proc(void)
void close_proc()
{
close_pid_proc();
- if (proc_dir_fd > 0)
- close(proc_dir_fd);
- proc_dir_fd = -1;
+
+ close_service_fd(PROC_FD_OFF);
}
int set_proc_fd(int fd)
{
- int sfd = get_service_fd(PROC_FD_OFF);
-
- sfd = dup2(fd, sfd);
- if (sfd < 0) {
- pr_perror("Can't set proc fd\n");
- return -1;
- }
-
- proc_dir_fd = sfd;
-
- return 0;
+ return install_service_fd(PROC_FD_OFF, fd);
}
int set_proc_mountpoint(char *path)
{
- int sfd = get_service_fd(PROC_FD_OFF), fd;
-
+ int fd, ret;
close_proc();
fd = open(path, O_DIRECTORY | O_RDONLY);
@@ -223,14 +210,10 @@ int set_proc_mountpoint(char *path)
return -1;
}
- sfd = dup2(fd, sfd);
+ ret = install_service_fd(PROC_FD_OFF, fd);
close(fd);
- if (sfd < 0) {
- pr_err("Can't set proc fd\n");
+ if (ret < 0)
return -1;
- }
-
- proc_dir_fd = sfd;
return 0;
}
@@ -239,20 +222,23 @@ inline int open_pid_proc(pid_t pid)
{
char path[18];
int fd;
+ int dfd;
if (pid == open_proc_pid)
return open_proc_fd;
close_pid_proc();
- if (proc_dir_fd == -1) {
- fd = set_proc_mountpoint("/proc");
- if (fd < 0)
- return fd;
+ dfd = get_service_fd(PROC_FD_OFF);
+ if (dfd < 0) {
+ if (set_proc_mountpoint("/proc") < 0)
+ return -1;
+
+ dfd = get_service_fd(PROC_FD_OFF);
}
snprintf(path, sizeof(path), "%d", pid);
- fd = openat(proc_dir_fd, path, O_RDONLY);
+ fd = openat(dfd, path, O_RDONLY);
if (fd < 0)
pr_perror("Can't open %s", path);
else {
@@ -307,12 +293,48 @@ static int __get_service_fd(enum sfd_type type, int service_fd_id)
return service_fd_rlim_cur - type - SERVICE_FD_MAX * service_fd_id;
}
+static DECLARE_BITMAP(sfd_map, SERVICE_FD_MAX);
+
+int install_service_fd(enum sfd_type type, int fd)
+{
+ int sfd = __get_service_fd(type, service_fd_id);
+
+ BUG_ON((int)type <= SERVICE_FD_MIN || (int)type >= SERVICE_FD_MAX);
+
+ if (dup2(fd, sfd) != sfd) {
+ pr_perror("Dup %d -> %d failed", fd, sfd);
+ return -1;
+ }
+
+ set_bit(type, sfd_map);
+ return sfd;
+}
+
int get_service_fd(enum sfd_type type)
{
BUG_ON((int)type <= SERVICE_FD_MIN || (int)type >= SERVICE_FD_MAX);
+
+ if (!test_bit(type, sfd_map))
+ return -1;
+
return __get_service_fd(type, service_fd_id);
}
+int close_service_fd(enum sfd_type type)
+{
+ int fd;
+
+ fd = get_service_fd(type);
+ if (fd < 0)
+ return 0;
+
+ if (close_safe(&fd))
+ return -1;
+
+ clear_bit(type, sfd_map);
+ return 0;
+}
+
int clone_service_fd(int id)
{
int ret = -1, i;
--
1.7.11.7
More information about the CRIU
mailing list