CRIU(Checkpoint/Restore In Userspace)是运行在linux操作系统上的一个开源软件,其功能是在用户空间实现Checkpoint/Restore功能。
github地址如下:https://github.com/checkpoint-restore/criu
本人选取的版本是3.12,本人的操作系统是centos7.6
先写一个简单的程序代码(criutest.c):
#include <stdio.h>
#include <unistd.h>
#include <string.h>int main()
{int i = 0;FILE *fp = NULL;char szWrite[50] = {0};fp = fopen("/chkpnt/criutest.txt", "a");if(fp==NULL){printf("fopen failed\n");return -1;}while(1){printf("[%d], Hello world!\n", i);sprintf(szWrite, "[%d], Hello world!\n", i);fwrite(szWrite, strlen(szWrite), 1, fp);fflush(fp);sleep(3);i++;}return 0;
}
该程序会往控制台以及文件中写入字符串,
现在开始dump该进程,代码如下(libcriudumptest.c):
#include "criu.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <fcntl.h>int main(int argc, char **argv)
{int pid = 0;int fd = 0;int ret = 0;int childpid = 0;if(argc < 2){printf("argc is 1\n");return -1;}pid = atoi(argv[1]);criu_init_opts();criu_set_pid(pid);criu_set_leave_running(false);fd = open("/chkpnt/img/", O_DIRECTORY);criu_set_images_dir_fd(fd);criu_set_shell_job(true);ret = criu_dump();if(ret < 0){printf("criu_dump failed\n");return -1;}printf("criu_dump succeed\n");return 0;
}
其中该程序运行时,需要输入一个参数,待dump的进程pid,dump路径代码中写死了,为/chkpnt/img。
可以看到,显示dump成功,在/chkpnt/img目录下,可以看到生成的dump文件
代码中criu_set_leave_running(false)表示dump后杀死进程,criutest最后的运行结果如下:
可以看到,criutest在打印到98后,被dump然后接着被杀死。
恢复运行时,就应该从99开始。
现在编写restore功能,代码如下(libcriurestoretest.c):
#include "criu.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <fcntl.h>int main(int argc, char **argv)
{int fd = 0;int ret = 0;char *dumpdir;if(argc < 2){printf("argc is 1\n");return -1;}dumpdir = argv[1];criu_init_opts();fd = open(dumpdir, O_DIRECTORY);criu_set_images_dir_fd(fd);criu_set_shell_job(true);ret = criu_restore();if(ret < 0){printf("criu_restore failed\n");return -1;}printf("criu_restore succeed\n");return 0;
}
很明显,该程序需要一个输入参数,dump路径,运行该程序,如下图所示:
很明显,打印从99开始。