Commit e6106956 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

util: clone service descriptors, if fd tables are shared for tasks (v3)

It looks like a namespace for service descriptors.
It will be used for restoring tasks with shared fd tables.
Service descriptors should be own for each process.

v2: clone_service_fd doesn't know about sub-systems like log, proc, etc
v3: Don't try to find a free name-space.
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent e12dad0a
...@@ -122,6 +122,7 @@ enum sfd_type { ...@@ -122,6 +122,7 @@ enum sfd_type {
SERVICE_FD_MAX SERVICE_FD_MAX
}; };
extern int clone_service_fd(int id);
extern int init_service_fd(void); extern int init_service_fd(void);
extern int get_service_fd(enum sfd_type type); extern int get_service_fd(enum sfd_type type);
extern bool is_service_fd(int fd, enum sfd_type type); extern bool is_service_fd(int fd, enum sfd_type type);
......
...@@ -280,6 +280,7 @@ int do_open_proc(pid_t pid, int flags, const char *fmt, ...) ...@@ -280,6 +280,7 @@ int do_open_proc(pid_t pid, int flags, const char *fmt, ...)
} }
static int service_fd_rlim_cur; static int service_fd_rlim_cur;
static int service_fd_id = 0;
int init_service_fd(void) int init_service_fd(void)
{ {
...@@ -301,21 +302,46 @@ int init_service_fd(void) ...@@ -301,21 +302,46 @@ int init_service_fd(void)
return 0; return 0;
} }
static int __get_service_fd(enum sfd_type type) static int __get_service_fd(enum sfd_type type, int service_fd_id)
{ {
return service_fd_rlim_cur - type; return service_fd_rlim_cur - type - SERVICE_FD_MAX * service_fd_id;
} }
int get_service_fd(enum sfd_type type) int get_service_fd(enum sfd_type type)
{ {
BUG_ON((int)type <= SERVICE_FD_MIN || (int)type >= SERVICE_FD_MAX); BUG_ON((int)type <= SERVICE_FD_MIN || (int)type >= SERVICE_FD_MAX);
return __get_service_fd(type); return __get_service_fd(type, service_fd_id);
}
int clone_service_fd(int id)
{
int ret = -1, i;
if (service_fd_id == id)
return 0;
for (i = SERVICE_FD_MIN + 1; i < SERVICE_FD_MAX; i++) {
int old = __get_service_fd(i, service_fd_id);
int new = __get_service_fd(i, id);
ret = dup2(old, new);
if (ret == -1) {
if (errno == EBADF)
continue;
pr_perror("Unalbe to clone %d->%d\n", old, new);
}
}
service_fd_id = id;
ret = 0;
return ret;
} }
bool is_any_service_fd(int fd) bool is_any_service_fd(int fd)
{ {
return fd > __get_service_fd(SERVICE_FD_MAX) && return fd > __get_service_fd(SERVICE_FD_MAX, service_fd_id) &&
fd < __get_service_fd(SERVICE_FD_MIN); fd < __get_service_fd(SERVICE_FD_MIN, service_fd_id);
} }
bool is_service_fd(int fd, enum sfd_type type) bool is_service_fd(int fd, enum sfd_type type)
......
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