External checkpoint patch

Oren Laadan orenl at cs.columbia.edu
Tue Oct 21 16:07:21 PDT 2008


> Oren,
> 
> Could you take a look over Cedric's external checkpoint patch?
> 
> http://git.kernel.org/?p=linux/kernel/git/daveh/linux-2.6-cr.git;a=commit;h=28ffabbc17d3641eee2a7eb66f714c266c400263
> 
> It seems pretty small to me.
> 
> --

I committed a couple of patches on top of ckpt-v7 that do this.
(the first one is actually a simple cleanup that is unrelated).

see:
http://git.ncl.cs.columbia.edu/?p=linux-cr-dev.git;a=shortlog;h=refs/heads/ckpt-v7
(or git://git.ncl.cs.columbia.edu/pub/git/linux-cr-dev.git ckpt-v7)

*  "Minor simplification of cr_ctx_alloc(), cr_ctx_free()"
*  "External checkpoint of a task other than ourself"

To checkpoint another task, you need to freeze that other task, or to
SIGSTOP it (if using a kernel without freezer cgroup).

Restart remains the same except the the original PID is not preserved
(because we haven't solved yet the fork-with-specific-pid issue).

In reality, you would create a new names space, and have the task running
in there call 'sys_restart()'.

Below are test1.c, ckpt.c (to checkpoint), and rstr.c (to restart), as
well as the two patches.

I tested it this way:
	$ ./test.1 &
	[1] 3493

	$ kill -STOP 3493
	$ ./ckpt 3493 > ckpt.image
	
	$ mv /tmp/cr-test.out /tmp/cr-test.out.orig
	$ cp /tmp/cr-test.out.orig /tmp/cr-test.out

	$ kill -CONT 3493

	$ ./rstr < ckpt.image
now compare the output of the two output files

Oren.

------------------------------------------------------------------------

#define _GNU_SOURCE        /* or _BSD_SOURCE or _SVID_SOURCE */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>
#include <asm/unistd.h>

#define OUTFILE  "/tmp/cr-test.out"

int main(int argc, char *argv[])
{
	FILE *file;
	float a;
	int i;

	close(0);
	close(1);
	close(2);

	unlink(OUTFILE);
	file = fopen(OUTFILE, "w+");
	if (!file) {
		perror("open");
		exit(1);
	}
	if (dup2(0,2) < 0) {
		perror("dup2");
		exit(1);
	}

	a = sqrt(2.53 * (getpid() / 1.21));

	fprintf(file, "hello, world (%.2f)!\n", a);
	fflush(file);

	for (i = 0; i < 1000; i++) {
		sleep(1);
		/* make the fpu work ->  a = a + i/10  */
		a = sqrt(a*a + 2*a*(i/10.0) + i*i/100.0);
		fprintf(file, "count %d (%.2f)!\n", i, a);
		fflush(file);
	}
		
	fprintf(file, "world, hello (%.2f) !\n", a);
	fflush(file);

	return 0;
}

------------------------------------------------------------------------

#define _GNU_SOURCE        /* or _BSD_SOURCE or _SVID_SOURCE */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <asm/unistd.h>
#include <sys/syscall.h>

int main(int argc, char *argv[])
{
	pid_t pid;
	int ret;

	if (argc != 2) {
		printf("usage: ckpt PID\n");
		exit(1);
	}

	pid = atoi(argv[1]);
	if (pid <= 0) {
		printf("invalid pid\n");
		exit(1);
	}

	ret = syscall(__NR_checkpoint, pid, STDOUT_FILENO, 0);

	if (ret < 0)
		perror("checkpoint");
	else
		printf("checkpoint id %d\n", ret);

	return (ret > 0 ? 0 : 1);
}

------------------------------------------------------------------------

#define _GNU_SOURCE        /* or _BSD_SOURCE or _SVID_SOURCE */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <asm/unistd.h>
#include <sys/syscall.h>

int main(int argc, char *argv[])
{
	pid_t pid = getpid();
	int ret;

	ret = syscall(__NR_restart, pid, STDIN_FILENO, 0);
	if (ret < 0)
		perror("restart");

	printf("should not reach here !\n");

	return 0;
}

------------------------------------------------------------------------



More information about the Containers mailing list