[CRIU] [PATCH v3 2/2] compel: Add more arguments to compel_wait_task()

Kirill Tkhai ktkhai at virtuozzo.com
Wed May 3 05:48:25 PDT 2017


Some get_status() methods may allocate data, because
not all of the fields in /proc/[pid]/status file
have the fixed size. For example, NSpid, which
size may vary.

Introduce new method free_status() in counterweight
for such type get_status() methods. it will be called
in case of we go to try_again and need to free allocated
data.

Also, introduce data parameter for a use in the future.

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 compel/include/uapi/infect.h |    5 +++--
 compel/src/lib/infect.c      |   13 ++++++++-----
 criu/include/proc_parse.h    |    2 +-
 criu/proc_parse.c            |    2 +-
 criu/seize.c                 |    6 +++---
 5 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/compel/include/uapi/infect.h b/compel/include/uapi/infect.h
index 0d79f1346..3264e923f 100644
--- a/compel/include/uapi/infect.h
+++ b/compel/include/uapi/infect.h
@@ -24,8 +24,9 @@ struct seize_task_status {
 };
 
 extern int compel_wait_task(int pid, int ppid,
-		int (*get_status)(int pid, struct seize_task_status *),
-		struct seize_task_status *st);
+		int (*get_status)(int pid, struct seize_task_status *, void *data),
+		void (*free_status)(int pid, struct seize_task_status *, void *data),
+		struct seize_task_status *st, void *data);
 
 extern int compel_stop_task(int pid);
 extern int compel_resume_task(pid_t pid, int orig_state, int state);
diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c
index 7f6d2f3f1..07200a7a6 100644
--- a/compel/src/lib/infect.c
+++ b/compel/src/lib/infect.c
@@ -52,7 +52,7 @@ static inline void close_safe(int *pfd)
 	}
 }
 
-static int parse_pid_status(int pid, struct seize_task_status *ss)
+static int parse_pid_status(int pid, struct seize_task_status *ss, void *data)
 {
 	char aux[128];
 	FILE *f;
@@ -107,7 +107,7 @@ int compel_stop_task(int pid)
 
 	ret = compel_interrupt_task(pid);
 	if (ret == 0)
-		ret = compel_wait_task(pid, -1, parse_pid_status, &ss);
+		ret = compel_wait_task(pid, -1, parse_pid_status, NULL, &ss, NULL);
 	return ret;
 }
 
@@ -192,8 +192,9 @@ static int skip_sigstop(int pid, int nr_signals)
  * up with someone else.
  */
 int compel_wait_task(int pid, int ppid,
-		int (*get_status)(int pid, struct seize_task_status *),
-		struct seize_task_status *ss)
+		int (*get_status)(int pid, struct seize_task_status *, void *),
+		void (*free_status)(int pid, struct seize_task_status *, void *),
+		struct seize_task_status *ss, void *data)
 {
 	siginfo_t si;
 	int status, nr_sigstop;
@@ -220,7 +221,7 @@ int compel_wait_task(int pid, int ppid,
 		wait_errno = errno;
 	}
 
-	ret2 = get_status(pid, ss);
+	ret2 = get_status(pid, ss, data);
 	if (ret2)
 		goto err;
 
@@ -271,6 +272,8 @@ int compel_wait_task(int pid, int ppid,
 		}
 
 		ret = 0;
+		if (free_status)
+			free_status(pid, ss, data);
 		goto try_again;
 	}
 
diff --git a/criu/include/proc_parse.h b/criu/include/proc_parse.h
index 13b710926..2bdc7fd68 100644
--- a/criu/include/proc_parse.h
+++ b/criu/include/proc_parse.h
@@ -96,7 +96,7 @@ extern int parse_pid_stat(pid_t pid, struct proc_pid_stat *s);
 extern unsigned int parse_pid_loginuid(pid_t pid, int *err, bool ignore_noent);
 extern int parse_pid_oom_score_adj(pid_t pid, int *err);
 extern int prepare_loginuid(unsigned int value, unsigned int loglevel);
-extern int parse_pid_status(pid_t pid, struct seize_task_status *);
+extern int parse_pid_status(pid_t pid, struct seize_task_status *, void *data);
 extern int parse_file_locks(void);
 extern int get_fd_mntid(int fd, int *mnt_id);
 
diff --git a/criu/proc_parse.c b/criu/proc_parse.c
index e33da8d56..73ea7f648 100644
--- a/criu/proc_parse.c
+++ b/criu/proc_parse.c
@@ -993,7 +993,7 @@ static int cap_parse(char *str, unsigned int *res)
 	return 0;
 }
 
-int parse_pid_status(pid_t pid, struct seize_task_status *ss)
+int parse_pid_status(pid_t pid, struct seize_task_status *ss, void *data)
 {
 	struct proc_status_creds *cr = container_of(ss, struct proc_status_creds, s);
 	struct bfd f;
diff --git a/criu/seize.c b/criu/seize.c
index 450b83af5..5c0c00ef3 100644
--- a/criu/seize.c
+++ b/criu/seize.c
@@ -490,7 +490,7 @@ static int collect_children(struct pstree_item *item)
 			goto free;
 		}
 
-		ret = compel_wait_task(pid, item->pid->real, parse_pid_status, &creds->s);
+		ret = compel_wait_task(pid, item->pid->real, parse_pid_status, NULL, &creds->s, NULL);
 		if (ret < 0) {
 			/*
 			 * Here is a race window between parse_children() and seize(),
@@ -720,7 +720,7 @@ static int collect_threads(struct pstree_item *item)
 		if (!opts.freeze_cgroup && compel_interrupt_task(pid))
 			continue;
 
-		ret = compel_wait_task(pid, item_ppid(item), parse_pid_status, &t_creds.s);
+		ret = compel_wait_task(pid, item_ppid(item), parse_pid_status, NULL, &t_creds.s, NULL);
 		if (ret < 0) {
 			/*
 			 * Here is a race window between parse_threads() and seize(),
@@ -867,7 +867,7 @@ int collect_pstree(void)
 	if (!creds)
 		goto err;
 
-	ret = compel_wait_task(pid, -1, parse_pid_status, &creds->s);
+	ret = compel_wait_task(pid, -1, parse_pid_status, NULL, &creds->s, NULL);
 	if (ret < 0)
 		goto err;
 



More information about the CRIU mailing list