Commit 4ea62143 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

crtools: add ability to create and close a service fd (v3)

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: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent e6106956
......@@ -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);
}
......@@ -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);
......
......@@ -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(&current_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;
}
......
......@@ -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);
}
......@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment