diff options
author | Siri Hansen <[email protected]> | 2011-11-08 12:07:23 +0100 |
---|---|---|
committer | Siri Hansen <[email protected]> | 2011-11-17 16:59:09 +0100 |
commit | abae78750427c8696c89e57869b4bcebef168fe5 (patch) | |
tree | 65d8c324f4e47e0db1d6127edb64ecc761bd8748 /lib/sasl/src | |
parent | ae1c361f797a104a35aef967cc694b457217f488 (diff) | |
download | otp-abae78750427c8696c89e57869b4bcebef168fe5.tar.gz otp-abae78750427c8696c89e57869b4bcebef168fe5.tar.bz2 otp-abae78750427c8696c89e57869b4bcebef168fe5.zip |
Add syntax check of relup to check_install_release and install_release
This commit adds a check that all instructions in the relup are
valid. Earlier, the last part (after point_of_no_return) was not
checked before the actual installation started, meaning that if the
relup was hand written, there was a potential for crashing the upgrade
here.
Diffstat (limited to 'lib/sasl/src')
-rw-r--r-- | lib/sasl/src/release_handler_1.erl | 86 |
1 files changed, 67 insertions, 19 deletions
diff --git a/lib/sasl/src/release_handler_1.erl b/lib/sasl/src/release_handler_1.erl index 3a64e10185..b4b288646f 100644 --- a/lib/sasl/src/release_handler_1.erl +++ b/lib/sasl/src/release_handler_1.erl @@ -60,21 +60,25 @@ check_script(Script, LibDirs) -> end. do_check_script(Script, LibDirs, PurgeMods) -> - {Before, _After} = split_instructions(Script), + {Before, After} = split_instructions(Script), case catch lists:foldl(fun(Instruction, EvalState1) -> eval(Instruction, EvalState1) end, #eval_state{libdirs = LibDirs}, Before) of EvalState2 when is_record(EvalState2, eval_state) -> - {ok,PurgeMods}; + case catch syntax_check_script(After) of + ok -> + {ok,PurgeMods}; + Other -> + {error,Other} + end; {error, Error} -> {error, Error}; Other -> {error, Other} end. - %% eval_script/1 - For testing only - no apps added, just testing instructions eval_script(Script) -> eval_script(Script, [], [], [], []). @@ -91,22 +95,30 @@ eval_script(Script, Apps, LibDirs, NewLibs, Opts) -> newlibs = NewLibs, opts = Opts}, Before) of - EvalState2 when is_record(EvalState2, eval_state) -> - case catch lists:foldl(fun(Instruction, EvalState3) -> - eval(Instruction, EvalState3) - end, - EvalState2, - After) of - EvalState4 when is_record(EvalState4, eval_state) -> - {ok, EvalState4#eval_state.unpurged}; - restart_emulator -> - restart_emulator; - Error -> - {'EXIT', Error} - end; - {error, Error} -> {error, Error}; - Other -> {error, Other} - end; + EvalState2 when is_record(EvalState2, eval_state) -> + case catch syntax_check_script(After) of + ok -> + case catch lists:foldl( + fun(Instruction, EvalState3) -> + eval(Instruction, + EvalState3) + end, + EvalState2, + After) of + EvalState4 + when is_record(EvalState4, eval_state) -> + {ok, EvalState4#eval_state.unpurged}; + restart_emulator -> + restart_emulator; + Error -> + {'EXIT', Error} + end; + Other -> + {error,Other} + end; + {error, Error} -> {error, Error}; + Other -> {error, Other} + end; {error, Mod} -> {error, {old_processes, Mod}} end. @@ -182,6 +194,42 @@ do_check_old_code(Mod,Procs) -> [Mod]. +%% Check the last part of the script, i.e. the part after point_of_no_return. +%% More or less a syntax check in case the script was handwritten. +syntax_check_script([point_of_no_return | Script]) -> + syntax_check_script(Script); +syntax_check_script([{load, {_,_,_}} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{remove, {_,_,_}} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{purge, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{suspend, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{resume, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{code_change, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{code_change, _, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{stop, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{start, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{sync_nodes, _, {_,_,_}} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{sync_nodes, _, _} | Script]) -> + syntax_check_script(Script); +syntax_check_script([{apply, {_,_,_}} | Script]) -> + syntax_check_script(Script); +syntax_check_script([restart_emulator | Script]) -> + syntax_check_script(Script); +syntax_check_script([Illegal | _Script]) -> + throw({illegal_instruction_after_point_of_no_return,Illegal}); +syntax_check_script([]) -> + ok. + + %%----------------------------------------------------------------- %% An unpurged module is a module for which there exist an old %% version of the code. This should only be the case if there are |