diff options
author | Siri Hansen <[email protected]> | 2011-09-08 10:14:10 +0200 |
---|---|---|
committer | Siri Hansen <[email protected]> | 2011-11-17 16:47:27 +0100 |
commit | 19a46c5c9f4ed3f0f2bfb149fc1feb0b93d55379 (patch) | |
tree | 723e9e36d1e1078b244cc5698b7a8c54c8222c88 /lib/sasl/src/systools_rc.erl | |
parent | 5dc64cffb084e8abc6e5908025833481331f38de (diff) | |
download | otp-19a46c5c9f4ed3f0f2bfb149fc1feb0b93d55379.tar.gz otp-19a46c5c9f4ed3f0f2bfb149fc1feb0b93d55379.tar.bz2 otp-19a46c5c9f4ed3f0f2bfb149fc1feb0b93d55379.zip |
Restart emulator before running upgrade script when erts is upgraded
If the version of erts differs between two releases, the release
handler automatically adds a 'restart_new_emulator' instruction to the
upgrade script (relup). Earlier, this instruction was always added at
the end of the upgrade script, causing the following sequence of
operations during an upgrade (a bit simplified):
1. suspend processes
2. load new code
3. execute code_change functions
4. resume processes
5. restart emulator with new erts version
Obviously, this caused the new code to be loaded into the old emulator
and this would fail if the beam format had been changed in the new
version of the emulator.
To overcome this problem, this commit changes the order of the
instructions, so for upgrade with changed erts version we now have:
1. restart emulator with new erts, kernel, stdlib and sasl versions,
but old versions of all other applications.
2. suspend processes
3. load new code
4. execute code_change functions
5. resume processes
This is implemented by creating a temporary release, including new
erts, kernel, stdlib and sasl from the new release and all other
applications from the old release. A new boot file for this temporary
release is created, which includes a new 'apply' instruction to run
release_handler:new_emulator_upgrade/2. Then the emulator is restarted
using this boot file - and release_handler:new_emulator_upgrade/2
executes the rest of the upgrade script.
For downgrade, the order will be as before:
1. suspend processes
2. execute code_change functions with 'down'-indication
3. load old code
4. resume processes
5. restart emulator with old erts version
Diffstat (limited to 'lib/sasl/src/systools_rc.erl')
-rw-r--r-- | lib/sasl/src/systools_rc.erl | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/lib/sasl/src/systools_rc.erl b/lib/sasl/src/systools_rc.erl index daadb79967..6f01901fbc 100644 --- a/lib/sasl/src/systools_rc.erl +++ b/lib/sasl/src/systools_rc.erl @@ -144,7 +144,10 @@ translate_merged_script(Mode, Script, Appls, PreAppls) -> {Before2, After2} = translate_dependent_instrs(Mode, Before1, After1, Appls), Before3 = merge_load_object_code(Before2), - NewScript = Before3 ++ [point_of_no_return | After2], + + {Before4,After4} = sort_restart_new_emulator(Mode,Before3,After2), + NewScript = Before4 ++ [point_of_no_return | After4], + check_syntax(NewScript), {ok, NewScript}. @@ -699,6 +702,25 @@ mlo([{load_object_code, {Lib, LibVsn, Mods}} | T]) -> mlo([]) -> []. %%----------------------------------------------------------------- +%% RESTART DIFF EMULATOR +%% ----------------------------------------------------------------- +%% ----------------------------------------------------------------- +%% Check if a diff_vsn_restart_new_emulator instruction exists (i.e. if the +%% emulator version is changed). If so, this must be done first for +%% upgrade and last for downgrade. +%% ----------------------------------------------------------------- +sort_restart_new_emulator(Mode,Before,After) -> + case lists:delete(diff_vsn_restart_new_emulator,After) of + After -> + {Before,After}; + NewAfter when Mode==up -> + {[restart_new_emulator|Before],NewAfter}; + NewAfter when Mode==dn -> + {Before,NewAfter++[restart_new_emulator]} + end. + + +%%----------------------------------------------------------------- %% SYNTAX CHECK %%----------------------------------------------------------------- %%----------------------------------------------------------------- @@ -817,6 +839,7 @@ check_op({apply, {M, F, A}}) -> check_func(F), check_args(A); check_op(restart_new_emulator) -> ok; +check_op(diff_vsn_restart_new_emulator) -> ok; check_op(X) -> throw({error, {bad_instruction, X}}). check_mod(Mod) when is_atom(Mod) -> ok; |