[CRIU] [PATCH CRIU 6/7] log_dirty: add log_dirty_total - get total amount of dirty memory pages

Pavel Emelyanov xemul at virtuozzo.com
Tue Apr 12 04:14:39 PDT 2016


On 04/07/2016 04:28 PM, Pavel Tikhomirov wrote:
> iterate through all processes in dump tree and update total_pages,
> and total_dirty_pages counters, write summs for all tree in format:
> <timestamp in sec> <total memory pages> <total memory dirty pages>
> 
> do not continuously iterate, add sleep to increase iteration
> time by say 1.5 every step
> 
> Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
> ---
>  criu/dirty-logger.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 95 insertions(+)
> 
> diff --git a/criu/dirty-logger.c b/criu/dirty-logger.c
> index b17b2c2..6b7cbf4 100644
> --- a/criu/dirty-logger.c
> +++ b/criu/dirty-logger.c
> @@ -1,8 +1,10 @@
>  #include <stdio.h>
>  #include <unistd.h>
>  #include <pthread.h>
> +#include <sys/time.h>
>  
>  #include "imgset.h"
> +#include "pstree.h"
>  
>  #define NSEC_PER_USEC	1000L
>  #define USEC_PER_SEC	1000000L
> @@ -20,13 +22,62 @@ static int sleep_us(long us) {
>  	return 0;
>  }
>  
> +static int pid_log_dirty_total(pid_t pid, long *total_pages, long *total_dirty_pages)
> +{
> +	return 0;
> +}
> +
> +static int log_dirty_total(FILE *fp, struct timeval *start)
> +{
> +	struct pstree_item *item;
> +	long total_pages = 0;
> +	long total_dirty_pages = 0;
> +	struct timeval tv;
> +	int ret;
> +
> +	/*
> +	 * Calculate dirty pages total cout across the tree
> +	 */
> +	for_each_pstree_item(item) {
> +		if (pid_log_dirty_total(item->pid.real, &total_pages, &total_dirty_pages))
> +			return -1;
> +	}
> +
> +	ret = gettimeofday(&tv, NULL);
> +	if (ret == -1) {
> +		pr_perror("Failed gettimeofday");
> +		return -1;
> +	}
> +	timediff(start, &tv);
> +
> +	ret = fprintf(fp, "%02u.%06u %ld %ld\n", (unsigned)tv.tv_sec, (unsigned)tv.tv_usec, total_pages, total_dirty_pages);

No no, no text log even for this. This is pretty much like irmap cache, so use __its__
semantics in where the file itself sits (it can be in work dir, rather than image dir)
and the protobuf entry for records.

> +	if (ret == -1) {
> +		pr_perror("Failed printf");
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
>  #define CR_DIRTY_LOG "dirty-log.img"
>  
> +#define INC_ITER_TIME 1.5
> +
>  void *dirty_logger_pthread(void *arg)
>  {
>  	int fd;
>  	FILE *fp;
>  	int *pret = (int *)arg;
> +	long double next_iter_time = 0;
> +	struct timeval start;
> +	int ret;
> +
> +	ret = gettimeofday(&start, NULL);
> +	if (ret == -1) {
> +		pr_perror("Failed gettimeofday");
> +		*pret = -1;
> +		pthread_exit(NULL);
> +	}
>  
>  	fd = openat(get_service_fd(IMG_FD_OFF), CR_DIRTY_LOG, O_DUMP);
>  	if (fd == -1) {
> @@ -46,6 +97,50 @@ void *dirty_logger_pthread(void *arg)
>  
>  	fprintf(fp, "==== Dirty Log ====\n");
>  
> +	while(1) {
> +		struct timeval iter_start, iter_end;
> +		long sleep_time;
> +
> +		ret = gettimeofday(&iter_start, NULL);
> +		if (ret == -1) {
> +			pr_perror("Failed gettimeofday");
> +			*pret = -1;
> +			pthread_exit(NULL);
> +		}
> +
> +		ret = log_dirty_total(fp, &start);
> +		if (ret == -1) {
> +			*pret = -1;
> +			pthread_exit(NULL);
> +		}
> +
> +		ret = gettimeofday(&iter_end, NULL);
> +		if (ret == -1) {
> +			pr_perror("Failed gettimeofday");
> +			*pret = -1;
> +			pthread_exit(NULL);
> +		}
> +
> +		timediff(&iter_start, &iter_end);
> +
> +		if (!next_iter_time)
> +			next_iter_time = iter_end.tv_sec * USEC_PER_SEC
> +				+ iter_end.tv_usec;
> +
> +		sleep_time = next_iter_time - (iter_end.tv_sec * USEC_PER_SEC
> +				+ iter_end.tv_usec);
> +		if (sleep_time <= 0)
> +			continue;
> +
> +		ret = sleep_us((long)sleep_time);
> +		if (ret == -1) {
> +			pr_perror("Failed sleep_us");
> +			*pret = -1;
> +			pthread_exit(NULL);
> +		}
> +		next_iter_time *= INC_ITER_TIME;
> +	}
> +
>  	*pret = 0;
>  	pthread_cleanup_pop(1);
>  	pthread_cleanup_pop(1);
> 



More information about the CRIU mailing list