[CRIU] [PATCH 03/14] util: clone service descriptors, if fd tables are shared for tasks (v3)

Andrey Vagin avagin at openvz.org
Fri Jan 11 04:22:34 EST 2013


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: Andrey Vagin <avagin at openvz.org>
---
 include/crtools.h |  1 +
 util.c            | 37 ++++++++++++++++++++++++++++++++-----
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/include/crtools.h b/include/crtools.h
index 08c9655..64e11dd 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -121,6 +121,7 @@ enum sfd_type {
 	SERVICE_FD_MAX
 };
 
+extern int clone_service_fd(int id);
 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);
diff --git a/util.c b/util.c
index 90c82f7..af191d4 100644
--- a/util.c
+++ b/util.c
@@ -33,6 +33,7 @@
 #include "asm/types.h"
 #include "list.h"
 #include "util.h"
+#include "lock.h"
 
 #include "crtools.h"
 
@@ -280,6 +281,7 @@ int do_open_proc(pid_t pid, int flags, const char *fmt, ...)
 }
 
 static int service_fd_rlim_cur;
+static int service_fd_id = 0;
 
 int init_service_fd(void)
 {
@@ -301,21 +303,46 @@ int init_service_fd(void)
 	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)
 {
 	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)
 {
-	return fd > __get_service_fd(SERVICE_FD_MAX) &&
-		fd < __get_service_fd(SERVICE_FD_MIN);
+	return fd > __get_service_fd(SERVICE_FD_MAX, service_fd_id) &&
+		fd < __get_service_fd(SERVICE_FD_MIN, service_fd_id);
 }
 
 bool is_service_fd(int fd, enum sfd_type type)
-- 
1.7.11.7



More information about the CRIU mailing list