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

Pavel Emelyanov xemul at parallels.com
Thu May 30 06:48:45 EDT 2013


On 05/30/2013 03:36 AM, Pavel Tikhomirov wrote:
> 
> Signed-off-by: Pavel Tikhomirov <snorcht at gmail.com>
> ---
>  include/proc_parse.h |   19 ++++++++
>  proc_parse.c         |  121 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 140 insertions(+)
> 
> diff --git a/include/proc_parse.h b/include/proc_parse.h
> index 9459872..1ec9254 100644
> --- a/include/proc_parse.h
> +++ b/include/proc_parse.h
> @@ -117,6 +117,23 @@ struct mount_info {
>  	struct list_head siblings;
>  };
>  
> +struct proc_posix_timer {
> +	struct list_head list;
> +	int it_id;
> +	int clock_id;
> +	int si_signo;
> +	int it_sigev_notify;
> +	union{
> +		void * p;
> +		long unsigned int i;
> +	} sival_ptr;
> +};
> +
> +struct proc_posix_timers_stat {
> +	int timer_n;
> +	struct list_head timers; //[512];

What does this comment mean?

> +};
> +
>  extern struct mount_info *mnt_entry_alloc();
>  extern void mnt_entry_free(struct mount_info *mi);
>  
> @@ -141,4 +158,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/proc_parse.c b/proc_parse.c
> index 6434822..1254cb7 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 * str_path;
> +
> +	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;
> +
> +	str_path = malloc(snprintf(NULL, 0, "/proc/%d/timers", pid) + 1);

Please, don't be that pedantic. Just char path[128] on stack is OK.

> +	sprintf(str_path, "/proc/%d/timers", pid);
> +
> +	file = fopen(str_path, "r");
> +	if (file == NULL) {
> +		pr_perror("Can't open posix timers file!");
> +		free(str_path);
> +		ret = -1;
> +		goto end_posix;
> +	}
> +	free(str_path);
> +
> +	while (1) {
> +		get = getline(&line1, &len1, file);
> +		if (get == -1)
> +			goto end_posix;

You don't distinguish read error from EOF.

> +		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->it_id);
> +		if (ret != 2 || str_name[0] != 'I')
> +			goto parse_err_posix;
> +		ret = sscanf(line2, "%s %d%s", str_name, &timer->si_signo, siginfo_tmp);
> +		if (ret != 3 || str_name[0] != 's')
> +			goto parse_err_posix;
> +		siginfo=&siginfo_tmp[1];
> +		ret = sscanf(siginfo, "%p", &timer->sival_ptr.p);
> +		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->it_sigev_notify = SIGEV_THREAD_ID;
> +		} else {
> +			switch (sigpid[0]) {
> +				case 's' :
> +					timer->it_sigev_notify = SIGEV_SIGNAL;
> +					break;
> +				case 't' :
> +					timer->it_sigev_notify = SIGEV_THREAD;
> +					break;
> +				default :
> +					timer->it_sigev_notify = SIGEV_NONE;
> +					break;
> +			}
> +		}
> +
> +		ret = sscanf(line4, "%s %d", str_name, &timer->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 (line1)
> +		free(line1);
> +	if (line2)
> +		free(line2);
> +	if (line3)
> +		free(line3);
> +	line1 = line2 = line3 = NULL;

What is this = NULL for?

> +
> +	if (file != NULL)
> +		fclose(file);
> +	return ret;
> +}
> 




More information about the CRIU mailing list