"criu 命令行参数解析"

  "criu checkpoint二"

Posted by Xu on June 1, 2017

CRIU-命令参数解析

同样,执行criu命令后进入主函数入口进行参数解析再执行具体的函数流程:

int main(int argc, char *argv[], char *envp[]){}//argc表示参数个数,argv存放所有参数数据

主函数实现如下几个步骤:

(1) 定义所有可选默认的参数选项结构体option={{”tree”,required_argument,0,’t’},{”pid”,required_argument,0,’p’}(这只是其中的两个例子,还有其它所有的默认可选参数) }

(2) 循环遍历输入命令行的参数并解析对应操作

     while (1) {
		idx = -1;
		opt = getopt_long(argc, argv, short_opts, long_opts, &idx);//详见http://blog.csdn.net/cashey1991/article/details/7942809解析参数,每次获取一个参数的信息opt,包括参数名称,参数值,索引等,这里每分析一个参数将会把argv中的命令名称(如dump,restore等)往数组末端后移两位,所以分析完所有参数后,命令名称位于argv数组的最后一个位置。
		if (opt == -1)//都到命令行末尾
			break;
		if (!opt)
			continue;
		switch (opt) {
		case 's':
			opts.final_state = TASK_STOPPED;
			break;
		case 'R':
			opts.final_state = TASK_ALIVE;
			break;}
			...还有很多)
			}

通过循环解析参数来设置opts(包含所有可选参数的默认值),循环结束后,所有参数解析都已完成,且criu命令名称(dump,restore等)已经移到argv[]末位,所以直接分析argv[optind]即可以知道具体执行什么命令,如对dump命令的分析:

    if (!strcmp(argv[optind], "dump")) {//比较argv最后一个字符串是否匹配为dump,是则调用相关函数进行进程备份
		if (!tree_id)
			goto opt_pid_missing;
		return cr_dump_tasks(tree_id);//具体备份操作函数
	}
	
	if (!strcmp(argv[optind], "restore")) {//比较argv最后一个字符串是否匹配为restore,是则调用相关函数进行进程恢复
		if (tree_id)
			pr_warn("Using -t with criu restore is obsoleted\n");
		ret = cr_restore_tasks();//具体恢复操作函数
		if (ret == 0 && opts.exec_cmd) {
			close_pid_proc();
			execvp(opts.exec_cmd[0], opts.exec_cmd);
			pr_perror("Failed to exec command %s", opts.exec_cmd[0]);
			ret = 1;
		}
		return ret != 0;
	}

下一章节将研究criu dump命令具体的执行过程函数,分析criu对进程的备份过程