pos_cli 命令是如何运行起来的
追踪pos_cli --dump --dir /root/ckpt --pid [your program pid]
是如何运行的
pos_cli是通过mason,由sources包括的这些文件构建而来
#pos/cli/meson.build
project_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.py
kArgvIndex_module = 1
args = 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:
continue
print(i)
args[1]是./src(pos/cli/src),sources是src下的所有c、cpp、cc文件
也就是由上图这些文件最后构建出了pos_cli,入口函数是main函数
//pos/cli/src/main.cpp
inline 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具体是如何实现。这个留到下一篇文章讲
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 《HelloGitHub》第 108 期
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单
· C# 13 中的新增功能实操
· Supergateway:MCP服务器的远程调试与集成工具