追踪pos_cli --dump --dir /root/ckpt --pid [your program pid]
是如何运行的
pos_cli是通过mason,由sources包括的这些文件构建而来
#pos/cli/meson.buildproject_name = 'phoenix_os_cli'
project_name_abbreviation = 'pos_cli'
scan_src_path = meson.current_source_dir() + '/../../scripts/utils/glob_src.py'
sources += run_command('python3', files(scan_src_path), './src', check: false).stdout().strip().split('\n')executable(project_name_abbreviation, sources, #入口文件cpp_args: c_args,link_args: ld_args,include_directories: inc_dirs,install: false
)
我们来看下sources
sources += run_command('python3', files(scan_src_path), './src', check: false).stdout().strip().split('\n')
sources是运行scan_src_path,也就是glob_src.py(参数是./src)的输出
#scripts/utils/glob_src.pykArgvIndex_module = 1args = sys.argv# add all local source files
sources = glob.glob(f"./{args[kArgvIndex_module]}/**/*.c", recursive=True) \+ glob.glob(f"./{args[kArgvIndex_module]}/**/*.cpp", recursive=True) \+ glob.glob(f"./{args[kArgvIndex_module]}/**/*.cc", recursive=True)for i in sources:if "__template__" in i or "__TEMPLATE__" in i:continueprint(i)
args[1]是./src(pos/cli/src),sources是src下的所有c、cpp、cc文件
也就是由上图这些文件最后构建出了pos_cli,入口函数是main函数
//pos/cli/src/main.cppinline void __readin_raw_cli(int argc, char *argv[], pos_cli_options_t &clio) {int opt_val;int option_index = 0;struct option *opt;char short_opt[1024] = {0};struct option long_opt[] = {{"dump", no_argument, NULL, kPOS_CliAction_Dump}, // 🧠 动作选项{"dir", required_argument, NULL, kPOS_CliMeta_Dir}, // 📂 元数据选项{"pid", required_argument, NULL, kPOS_CliMeta_Pid}, // 🔢 元数据选项{NULL, 0, NULL, 0}};while ((opt_val = getopt_long(argc, argv, short_opt, long_opt, &option_index)) != -1) {if (opt_val < kPOS_CliAction_PLACEHOLDER) {clio.action_type = static_cast<pos_cli_action>(opt_val); // 📝 设置动作类型} else if (opt_val < kPOS_CliMeta_PLACEHOLDER) {POS_CHECK_POINTER(opt);clio.record_raw(static_cast<pos_cli_meta>(opt_val), optarg); // 🌐 保存元数据参数}}
}int main(int argc, char *argv[]){pos_retval_t retval;pos_cli_options_t clio;__readin_raw_cli(argc, argv, clio); //处理命令行参数clio.local_oob_client = new POSOobClient(/* req_functions */ {{ kPOS_OOB_Msg_CLI_Ckpt_PreDump, oob_functions::cli_ckpt_predump::clnt },{ kPOS_OOB_Msg_CLI_Ckpt_Dump, oob_functions::cli_ckpt_dump::clnt },{ kPOS_OOB_Msg_CLI_Restore, oob_functions::cli_restore::clnt },{ kPOS_OOB_Msg_CLI_Trace_Resource, oob_functions::cli_trace_resource::clnt },},/* local_port */ 10086,/* local_ip */ CLIENT_IP);POS_CHECK_POINTER(clio.local_oob_client);retval = __dispatch(clio);switch (retval){case POS_SUCCESS:return 0;case POS_FAILED_NOT_IMPLEMENTED:POS_ERROR("unspecified action, use '-h' to check usage");default:POS_ERROR("CLI executed failed");}
}
命令解析过程:
在 __readin_raw_cli 中
--dump
匹配到 kPOS_CliAction_Dump
设置:clio.action_type = kPOS_CliAction_Dump--dir /root/ckpt
匹配到 kPOS_CliMeta_Dir
调用:clio.record_raw(kPOS_CliMeta_Dir, "/root/ckpt")--pid [your program pid]
匹配到 kPOS_CliMeta_Pid
调用:clio.record_raw(kPOS_CliMeta_Pid, "[your program pid]")
通过_dispatch分发工作,根据 clio.action_type 分发执行
inline pos_retval_t __dispatch(pos_cli_options_t &clio){switch (clio.action_type){case kPOS_CliAction_Dump:return handle_dump(clio);default:return POS_FAILED_NOT_IMPLEMENTED;}
}
此时我们会执行handle_dump,也就是我们的phos的checkpoint具体是如何实现。这个留到下一篇文章讲