[CRIU] [PATCH 04/12] posix-timer: Parse proc /proc/<pid>/timers and save info in list

Pavel Tikhomirov snorcht at gmail.com
Thu Jun 27 12:32:20 EDT 2013


Signed-off-by: Pavel Tikhomirov <snorcht at gmail.com>
---
 include/proc_parse.h |   13 ++++++
 include/restorer.h   |    8 ++++
 proc_parse.c         |  121 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 142 insertions(+)

diff --git a/include/proc_parse.h b/include/proc_parse.h
index 9459872..8c2c36e 100644
--- a/include/proc_parse.h
+++ b/include/proc_parse.h
@@ -3,6 +3,7 @@
 
 #include <sys/types.h>
 #include "asm/types.h"
+#include "restorer.h"
 #include "image.h"
 #include "list.h"
 
@@ -117,6 +118,16 @@ struct mount_info {
 	struct list_head siblings;
 };
 
+struct proc_posix_timer {
+	struct list_head list;
+	struct str_posix_timer spt;
+};
+
+struct proc_posix_timers_stat {
+	int timer_n;
+	struct list_head timers;
+};
+
 extern struct mount_info *mnt_entry_alloc();
 extern void mnt_entry_free(struct mount_info *mi);
 
@@ -141,4 +152,6 @@ extern int parse_fdinfo(int fd, int type,
 extern int parse_cpuinfo_features(int (*handler)(char *tok));
 extern int parse_file_locks(void);
 
+extern int parse_posix_timers(pid_t pid, struct proc_posix_timers_stat * args);
+
 #endif /* __CR_PROC_PARSE_H__ */
diff --git a/include/restorer.h b/include/restorer.h
index a5c0667..d97d741 100644
--- a/include/restorer.h
+++ b/include/restorer.h
@@ -61,6 +61,14 @@ struct rst_sched_param {
 	int prio;
 };
 
+struct str_posix_timer {
+	int it_id;
+	int clock_id;
+	int si_signo;
+	int it_sigev_notify;
+	void * sival_ptr;
+};
+
 struct task_restore_core_args;
 
 /* Make sure it's pow2 in size */
diff --git a/proc_parse.c b/proc_parse.c
index 6434822..e3a284a 100644
--- a/proc_parse.c
+++ b/proc_parse.c
@@ -1158,3 +1158,124 @@ err:
 	fclose(fl_locks);
 	return ret;
 }
+
+int parse_posix_timers(pid_t pid, struct proc_posix_timers_stat *args)
+{
+	int i;
+	int ret = 0;
+	int get = 0;
+	int pid_t;
+	char path[128];
+
+	FILE * file;
+	char * line1 = NULL;
+	char * line2 = NULL;
+	char * line3 = NULL;
+	char * line4 = NULL;
+	size_t len1 = 0;
+	size_t len2 = 0;
+	size_t len3 = 0;
+	size_t len4 = 0;
+
+	char * siginfo;
+	char siginfo_tmp[20];
+	char sigpid[7];
+	char tidpid[4];
+
+	char str_name[10];
+	struct proc_posix_timer *timer = NULL;
+
+	INIT_LIST_HEAD(&args->timers);
+	args->timer_n = 0;
+
+	sprintf(path, "/proc/%d/timers", pid);
+	file = fopen(path, "r");
+	if (file == NULL) {
+		pr_perror("Can't open posix timers file!");
+		ret = -1;
+		goto end_posix;
+	}
+
+	while (1) {
+		get = getline(&line1, &len1, file);
+		if (get == -1)
+			goto end_posix;
+		get = getline(&line2, &len2, file);
+		if (get == -1)
+			goto end_posix;
+		get = getline(&line3, &len3, file);
+		if (get == -1)
+			goto end_posix;
+		get = getline(&line4, &len4, file);
+		if (get == -1)
+			goto end_posix;
+
+		timer = xzalloc(sizeof(struct proc_posix_timer));
+
+		ret = sscanf(line1, "%s %d", str_name, &timer->spt.it_id);
+		if (ret != 2 || str_name[0] != 'I')
+			goto parse_err_posix;
+		ret = sscanf(line2, "%s %d%s", str_name, &timer->spt.si_signo, siginfo_tmp);
+		if (ret != 3 || str_name[0] != 's')
+			goto parse_err_posix;
+		siginfo=&siginfo_tmp[1];
+		ret = sscanf(siginfo, "%p", &timer->spt.sival_ptr);
+		if (ret != 1)
+			goto parse_err_posix;
+		for (i = 0; i<len3; i++) {
+			if (line3[i] == '/' || line3[i] == '.') {
+				line3[i] = ' ';
+			}
+		}
+		ret = sscanf(line3, "%s %s %s %d", str_name, sigpid, tidpid, &pid_t);
+		if (ret != 4 || str_name[0] != 'n')
+			goto parse_err_posix;
+
+		if ( tidpid[0] == 't') {
+			timer->spt.it_sigev_notify = SIGEV_THREAD_ID;
+		} else {
+			switch (sigpid[0]) {
+				case 's' :
+					timer->spt.it_sigev_notify = SIGEV_SIGNAL;
+					break;
+				case 't' :
+					timer->spt.it_sigev_notify = SIGEV_THREAD;
+					break;
+				default :
+					timer->spt.it_sigev_notify = SIGEV_NONE;
+					break;
+			}
+		}
+
+		ret = sscanf(line4, "%s %d", str_name, &timer->spt.clock_id);
+		if (ret != 2 || str_name[0] != 'C')
+			goto parse_err_posix;
+		list_add(&timer->list, &args->timers);
+		timer = NULL;
+		args->timer_n++;
+	}
+parse_err_posix:
+	while (!list_empty(&args->timers)) {
+		timer = list_first_entry(&args->timers, struct proc_posix_timer, list);
+		list_del(&timer->list);
+		xfree(timer);
+	}
+	pr_perror("Parse error in posix timers proc file!");
+	ret = -1;
+end_posix:
+	if (ferror(file)) {
+		ret = -1;
+		pr_perror("getline");
+	}
+
+	if (line1)
+		free(line1);
+	if (line2)
+		free(line2);
+	if (line3)
+		free(line3);
+
+	if (file != NULL)
+		fclose(file);
+	return ret;
+}
-- 
1.7.9.5



More information about the CRIU mailing list