[v3,07/10] files: Prepare clone_service_fd() for overlaping ranges.

Submitted by Kirill Tkhai on Dec. 29, 2017, 9:36 a.m.

Details

Message ID 151454016953.19480.6443765251013918774.stgit@localhost.localdomain
State New
Series "Introduce custom per-task service fds placement"
Headers show

Commit Message

Kirill Tkhai Dec. 29, 2017, 9:36 a.m.
In normal life this is impossible. But in case of big
fdt::nr number (many processes, sharing the same files),
and custom service_fd_base, normal (!CLONE_FILES) child
of such process may have overlaping service fds with
parent's fdt. This patch introduces "memmove()" behavior
(currently there is "memcpy()" behavior) and this will
be used in next patch.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
---
 criu/util.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/util.c b/criu/util.c
index ec16cffee..d45bb7d61 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -550,8 +550,13 @@  int clone_service_fd(struct pstree_item *me)
 	if (service_fd_id == id)
 		return 0;
 
-	for (i = SERVICE_FD_MIN + 1; i < SERVICE_FD_MAX; i++)
-		move_service_fd(me, i, id, new_base);
+	/* Dup sfds in memmove() style: they may overlap */
+	if (get_service_fd(LOG_FD_OFF) > __get_service_fd(LOG_FD_OFF, id))
+		for (i = SERVICE_FD_MIN + 1; i < SERVICE_FD_MAX; i++)
+			move_service_fd(me, i, id, new_base);
+	else
+		for (i = SERVICE_FD_MAX - 1; i > SERVICE_FD_MIN; i--)
+			move_service_fd(me, i, id, new_base);
 
 	service_fd_id = id;
 	ret = 0;