TLDR ;当启动erlang节点(仅对实例使用 erl
命令)时,我怎么能强制它不使用本地OTP库并获取 code:get_path()
空?
基本原理 .
我想触摸 erl_boot_server
. 不要做某些事情,只是玩 . 我已经构建了样本版本,并希望通过网络加载它 . 就这个 .
[vkovalev@t30nix foobar]$ tree -L 2
.
|-- bin
| |-- foobar
| |-- foobar-0.0.0+build.1.ref307ae38
| |-- install_upgrade.escript
| |-- nodetool
| `-- start_clean.boot
|-- erts-6.1
| |-- bin
| |-- doc
| |-- include
| |-- lib
| |-- man
| `-- src
|-- lib
| |-- foobar-0.1.0
| |-- kernel-3.0.1
| |-- sasl-2.4
| `-- stdlib-2.1
`-- releases
|-- 0.0.0+build.1.ref307ae38
|-- RELEASES
`-- start_erl.data
首先,我启动启动节点 .
[vkovalev@t30nix foobar]$ erl -sname boot -pa lib/*/ebin -pa releases/0.0.0+build.1.ref307ae38/ -s erl_boot_server start localhost
(boot@t30nix)1> {ok, _, _} = erl_prim_loader:get_file("foobar.boot").
(boot@t30nix)2> {ok, _, _} = erl_prim_loader:get_file("foobar_app.beam").
如你所见,一切都没问题 . 然后我启动从节点:
[vkovalev@t30nix ~]$ erl -sname slave -loader inet -hosts 127.0.0.1 -boot foobar
{"init terminating in do_boot",{'cannot get bootfile','foobar.boot'}}
Crash dump was written to: erl_crash.dump
init terminating in do_boot ()
我挖到了erl_prim_loader并找到了that stuff . 一个子句在Paths为空时执行(它只是将请求的文件名转发到引导服务器),另一个子句在Paths为非空时执行 . 在这种情况下(我想知道为什么)prim loader cripples请求文件名和它自己的(clientside)路径,然后要求SERVER提供此路径 . 根据我的理解,这是非常奇怪的事情,但没关系 . 然后我在slave节点上检查了 code:get_path()
,是的,它有本地otp安装的路径 .
所以,回到主题 . 我怎么能强制奴隶节点不使用任何本地OTP安装(如果它已经存在)?
UPD:添加了更多调查结果 .
-
第一件事 - https://github.com/erlang/otp/blob/maint/erts/preloaded/src/erl_prim_loader.erl#L669 . erl_prim_loader(在inet模式下)对某些人(我不清楚)的原因试图削弱任何请求的模块与本地(客户端)路径 .
-
似乎没有办法强制slave节点上的loader保持其路径为空:https://github.com/erlang/otp/blob/maint/erts/preloaded/src/init.erl#L697
-
我的bootscript中的路径看起来像{path,[“$ ROOT / lib / kernel-4.0 / ebin”,“$ ROOT / lib / stdlib-2.5 / ebin”]},所以看来,如果我得到bootscript加载,无论如何,我将无法用它启动系统 .
这是怎么回事? erlang网络启动功能是否已损坏?还是我的大脑?我怎样才能使节点成功进行网络启动?
3 回答
你认为奴隶类型的节点是由“奴隶”命名的吗?
以下代码来自项目tsung,文件名为“ts_os_mon_erlang.erl” .
另外,从模块限制如下:
如果要启动具有不同路径的节点,我认为您可以通过具有不同环境变量的脚本来实现,对于主节点而不是从节点 .
我认为螺纹钢项目可以帮助实现类似的目的 . 它包括如何操纵路径:
从
rebar_core.erl
file:process_dir1(Dir,Command,DirSet,Config,CurrentCodePath,{DirModules,ModuleSetFile}) - > Config0 = rebar_config:set(Config,current_command,Command),%%获取"any dir"的模块列表 . 这是除了与此目录类型相关联的%%模块之外,还处理的模块的全部列表%% . 这些any_dir模块被处理为%% FIRST . {ok,AnyDirModules} = application:get_env(rebar,any_dir_modules),确保使用
-setcookie
选项 . 从erl -man erl
页面: