aboutsummaryrefslogtreecommitdiffstats
path: root/lib/sasl/src/systools_rc.erl
diff options
context:
space:
mode:
authorSiri Hansen <[email protected]>2011-09-08 10:14:10 +0200
committerSiri Hansen <[email protected]>2011-11-17 16:47:27 +0100
commit19a46c5c9f4ed3f0f2bfb149fc1feb0b93d55379 (patch)
tree723e9e36d1e1078b244cc5698b7a8c54c8222c88 /lib/sasl/src/systools_rc.erl
parent5dc64cffb084e8abc6e5908025833481331f38de (diff)
downloadotp-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.erl25
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;