From c65821b677b4ebbc05192da9b8a48d32e53b3cfe Mon Sep 17 00:00:00 2001 From: Siri Hansen Date: Wed, 19 Feb 2014 17:24:27 +0100 Subject: Add documentation about upgrade The example of how to create a first target system, which is located in the System Principles document, is now extended to also include an example of code upgrade. A new chapter is added to System Principles explaining different issues when upgrade includes new versions applications within Erlang/OTP. --- system/doc/system_principles/create_target.xmlsrc | 248 +++++++++++++++++++--- system/doc/system_principles/part.xml | 4 +- system/doc/system_principles/upgrade.xml | 118 ++++++++++ system/doc/system_principles/xmlfiles.mk | 3 +- 4 files changed, 345 insertions(+), 28 deletions(-) create mode 100644 system/doc/system_principles/upgrade.xml (limited to 'system/doc') diff --git a/system/doc/system_principles/create_target.xmlsrc b/system/doc/system_principles/create_target.xmlsrc index fbc935d708..b5f8d8ac4d 100644 --- a/system/doc/system_principles/create_target.xmlsrc +++ b/system/doc/system_principles/create_target.xmlsrc @@ -4,7 +4,7 @@
- 20022013 + 20022014 Ericsson AB. All Rights Reserved. @@ -21,7 +21,7 @@ - Creating a First Target System + Creating and Upgrading a Target System Peter Högfeldt @@ -71,23 +71,24 @@
+ Creating a Target System

It is assumed that you have a working Erlang/OTP system structured according to the OTP Design Principles.

-

Step 1. First create a .rel file (see - rel(4)) that specifies the erts version - and lists all applications that should be included in the new - basic target system. An example is the following +

Step 1. First create a .rel file (see rel(4)) that specifies the erts + version and lists all applications that should be included in the + new basic target system. An example is the following mysystem.rel file:

%% mysystem.rel {release, {"MYSYSTEM", "FIRST"}, - {erts, "5.1"}, - [{kernel, "2.7"}, - {stdlib, "1.10"}, - {sasl, "1.9.3"}, - {pea, "1.0"}]}. + {erts, "5.10.4"}, + [{kernel, "2.16.4"}, + {stdlib, "1.19.4"}, + {sasl, "2.3.4"}, + {pea, "1.0"}]}.

The listed applications are not only original Erlang/OTP applications but possibly also new applications that you have written yourself (here examplified by the application @@ -116,13 +117,13 @@ os> erl -pa /home/user/target_system/myapps/pea-1.0/ebin systools:make_tar/2. That file has the following contents:

-erts-5.1/bin/ +erts-5.10.4/bin/ releases/FIRST/start.boot releases/FIRST/mysystem.rel releases/mysystem.rel -lib/kernel-2.7/ -lib/stdlib-1.10/ -lib/sasl-1.9.3/ +lib/kernel-2.16.4/ +lib/stdlib-1.19.4/ +lib/sasl-2.3.4/ lib/pea-1.0/

The file releases/FIRST/start.boot is a copy of our mysystem.boot

@@ -142,16 +143,19 @@ lib/pea-1.0/ Creates the temporary directory tmp and extracts the tar file mysystem.tar.gz into that directory. Deletes the erl and start files from - tmp/erts-5.1/bin. These files will be created again from + tmp/erts-5.10.4/bin. These files will be created again from source when installing the release. Creates the directory tmp/bin. Copies the previously created file plain.boot to tmp/bin/start.boot. Copies the files epmd, run_erl, and - to_erl from the directory tmp/erts-5.1/bin to + to_erl from the directory tmp/erts-5.10.4/bin to the directory tmp/bin. + Creates the directory tmp/log, which will be used + if the system is started as embedded with the bin/start + script. Creates the file tmp/releases/start_erl.data with - the contents "5.1 FIRST". This file is to be passed as data + the contents "5.10.4 FIRST". This file is to be passed as data file to the start_erl script. Recreates the file mysystem.tar.gz from the directories @@ -171,11 +175,11 @@ lib/pea-1.0/ Extracts the tar file mysystem.tar.gz into the target directory /usr/local/erl-target. In the target directory reads the file releases/start_erl.data - in order to find the Erlang runtime system version ("5.1"). + in order to find the Erlang runtime system version ("5.10.4"). Substitutes %FINAL_ROOTDIR% and %EMU% for /usr/local/erl-target and beam, respectively, in the files erl.src, start.src, and - start_erl.src of the target erts-5.1/bin + start_erl.src of the target erts-5.10.4/bin directory, and puts the resulting files erl, start, and run_erl in the target bin directory. @@ -185,6 +189,7 @@ lib/pea-1.0/
+ Starting a Target System

Now we have a target system that can be started in various ways.

We start it as a basic target system by invoking

@@ -193,7 +198,7 @@ os> /usr/local/erl-target/bin/erl

where only the kernel and stdlib applications are started, i.e. the system is started as an ordinary development system. There are only two files needed for all this to work: - bin/erl file (obtained from erts-5.1/bin/erl.src) + bin/erl file (obtained from erts-5.10.4/bin/erl.src) and the bin/start.boot file (a copy of plain.boot).

We can also start a distributed system (requires bin/epmd).

To start all applications specified in the original @@ -208,9 +213,10 @@ os> /usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI bin/run_erl, which in turn calls bin/start_erl (roughly, start_erl is an embedded variant of erl).

-

The shell script start is only an example. You should - edit it to suite your needs. Typically it is executed when the - UNIX system boots.

+

The shell script start, which is generated from + erts-5.10.4/bin/start.src during installation, is only an + example. You should edit it to suite your needs. Typically it is + executed when the UNIX system boots.

run_erl is a wrapper that provides logging of output from the run-time system to file. It also provides a simple mechanism for attaching to the Erlang shell (to_erl).

@@ -218,7 +224,7 @@ os> /usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI ("/usr/local/erl-target"), the releases directory ("/usr/local/erl-target/releases"), and the location of the start_erl.data file. It reads the run-time system - version ("5.1") and release version ("FIRST") from + version ("5.10.4") and release version ("FIRST") from the start_erl.data file, starts the run-time system of the version found, and provides -boot flag specifying the boot file of the release version found @@ -257,6 +263,198 @@ os> /usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI dependent files.

+
+ Creating the Next Version + +

+ In this example the pea application has been changed, and + so are erts, kernel, stdlib and + sasl. +

+ +

+ Step 1. Create the .rel file: +

+ +%% mysystem2.rel +{release, + {"MYSYSTEM", "SECOND"}, + {erts, "6.0"}, + [{kernel, "3.0"}, + {stdlib, "2.0"}, + {sasl, "2.4"}, + {pea, "2.0"}]}. +

+ Step 2. Create the application upgrade file (see + appup(4)) for pea, + for example: +

+ +%% pea.appup +{"2.0", + [{"1.0",[{load_module,pea_lib}]}], + [{"1.0",[{load_module,pea_lib}]}]}. +

+ Step 3. From the directory where the + mysystem2.rel file reside, start the Erlang/OTP system: +

+
+os> erl -pa /home/user/target_system/myapps/pea-2.0/ebin
+

giving the path to the new version of pea.

+ +

+ Step 4. Create the release upgrade file (see relup(4)): +

+
+1> systools:make_relup("mysystem2",["mysystem"],["mysystem"],[{path,["/home/user/target_system/myapps/pea-1.0/ebin","/my/old/erlang/lib/*/ebin"]}]).
+

+ where "mysystem" is the base release and + "mysystem2" is the release to upgrade to. +

+

+ Note that the path option is used for pointing out the + old version of all applications. (The new versions are already + in the code path - assuming of course that the erlang node on + which this is executed is running the correct version of + Erlang/OTP.) +

+

+ Step 5. Create the new release: +

+
+2> target_system:create("mysystem2").
+

+ Given that the relup file generated in step 4 above is + now located in the current directory, it will automatically be + included in the release package. +

+
+ +
+ Upgrading the Target System +

+ This part is done on the target node, and for this example we + want the node to be running as an embedded system with the + -heart option, allowing automatic restart of the + node. See Starting a Target + System above for more information. +

+

+ We add -heart to bin/start: +

+ +#!/bin/sh +ROOTDIR=/usr/local/erl-target/ + +if [ -z "$RELDIR" ] +then + RELDIR=$ROOTDIR/releases +fi + +START_ERL_DATA=${1:-$RELDIR/start_erl.data} + +$ROOTDIR/bin/run_erl -daemon /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl $ROOTDIR $RELDIR $START_ERL_DATA -heart +

+ And we use the simplest possible sys.config, which we + store in releases/FIRST: +

+ +%% sys.config +[]. +

+ Finally, in order to prepare the upgrade, we need to put the new + release package in the releases directory of the first + target system: +

+
+os> cp mysystem2.tar.gz /usr/local/erl-target/releases
+

+ And assuming that the node has been started like this: +

+
+os> /usr/local/erl-target/bin/start
+

+ it can be accessed like this: +

+
+os> /usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.1
+

+ Also note that logs can be found in + /usr/local/erl-target/log. This directory is specified as + an argument to run_erlin the start script listed above. +

+

+ Step 1. Unpack the release: +

+
+1> {ok,Vsn} = release_handler:unpack_release("mysystem2").
+

+ Step 2. Install the release: +

+
+2> release_handler:install_release(Vsn).
+{continue_after_restart,"FIRST",[]}
+heart: Tue Apr  1 12:15:10 2014: Erlang has closed.
+heart: Tue Apr  1 12:15:11 2014: Executed "/usr/local/erl-target/bin/start /usr/local/erl-target/releases/new_start_erl.data" -> 0. Terminating.
+[End]
+

+ The above return value and output after the call to + release_handler:install_release/1 means that the + release_handler has restarted the node by using + heart. This will always be done when the upgrade involves + a change of erts, kernel, stdlib or + sasl. See Upgrade when + Erlang/OTP has Changed for more infomation about this. +

+

+ The node will be accessable via a new pipe: +

+
+os> /usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.2
+

+ Let's see which releases we have in our system: +

+
+1> release_handler:which_releases().
+[{"MYSYSTEM","SECOND",
+  ["kernel-3.0","stdlib-2.0","sasl-2.4","pea-2.0"],
+  current},
+ {"MYSYSTEM","FIRST",
+  ["kernel-2.16.4","stdlib-1.19.4","sasl-2.3.4","pea-1.0"],
+  permanent}]
+

+ Our new release, "SECOND", is now the current release, but we + can also see that our "FIRST" release is still permanent. This + means that if the node would be restarted at this point, it + would come up running the "FIRST" release again. +

+

+ Step 3. Make the new release permanent: +

+
+2> release_handler:make_permanent("SECOND").
+ +

+ Now look at the releases again: +

+ +
+3> release_handler:which_releases().
+[{"MYSYSTEM","SECOND",
+  ["kernel-3.0","stdlib-2.0","sasl-2.4","pea-2.0"],
+  permanent},
+ {"MYSYSTEM","FIRST",
+  ["kernel-2.16.4","stdlib-1.19.4","sasl-2.3.4","pea-1.0"],
+  old}]
+ +

+ Here we see that the new release version is permanent, so + it would be safe to restart the node. +

+ +
+
Listing of target_system.erl

This module can also be found in the examples directory diff --git a/system/doc/system_principles/part.xml b/system/doc/system_principles/part.xml index 811428baae..d05c89fde8 100644 --- a/system/doc/system_principles/part.xml +++ b/system/doc/system_principles/part.xml @@ -4,7 +4,7 @@

- 19972013 + 19972014 Ericsson AB. All Rights Reserved. @@ -31,6 +31,6 @@ + - diff --git a/system/doc/system_principles/upgrade.xml b/system/doc/system_principles/upgrade.xml new file mode 100644 index 0000000000..68e48da0b8 --- /dev/null +++ b/system/doc/system_principles/upgrade.xml @@ -0,0 +1,118 @@ + + + + +
+ + 2014 + Ericsson AB. All Rights Reserved. + + + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + + + Upgrade when Erlang/OTP has Changed + + + + + + 2014-02-19 + + upgrade.xml +
+ +
+ Introduction +

+ As of Erlang/OTP 17, most applications deliver a valid + application upgrade (appup) file. In earlier releases, a + majority of the applications in Erlang/OTP did not support + upgrade at all. Many of the applications use the + restart_application instruction. These are applications + for which it is not crucial to support real soft upgrade, for + instance tools and library applications. The + restart_application instruction + ensures that all modules in the application are reloaded and + thereby running the new code. +

+
+ +
+ Upgrade of core applications +

+ The core applications ERTS, Kernel, STDLIB + and SASL never allow real soft upgrade, but require the + Erlang emulator to be restarted. This is indicated to the + release_handler by the upgrade instruction + restart_new_emulator. This instruction will always be the + very first instruction executed, and it will restart the + emulator with the new versions of the above mentioned core + applications and the old versions of all other + applications. When the node is back up all other upgrade instructions are + executed, making sure each application is finally running its + new version. +

+ +

+ It might seem strange to do a two-step upgrade instead of + just restarting the emulator with the new version of all + applications. The reason for this design decision is to allow + code_change functions to have side effects, for example changing + data on disk. It also makes sure that the upgrade mechanism for + non-core applications does not differ depending on whether or not + core applications are changed at the same time. +

+ +

+ If, however, the more brutal variant is preferred, it is + possible to handwrite the release upgrade file using only the + single upgrade instruction restart_emulator. This + instruction, in contrast to restart_new_emulator, will + cause the emulator to restart with the new versions of + all applications. +

+ +

+ Note that if other instructions are included before + restart_emulator in the handwritten relup file, + they will be executed in the old emulator. This is a big risk + since there is no guarantee that new beam code can be loaded + into the old emulator. Adding instructions after + restart_emulator has no effect as the + release_handler will not do any attempt at executing + them. +

+ +

+ See relup(4) for + information about the release upgrade file, and appup(4) for further information + about upgrade instructions. +

+
+ +
+ Applications that still do not allow code upgrade +

+ A few applications, for instance HiPE do not support + upgrade at all. This is indicated by an application upgrade file + containing only {Vsn,[],[]}. Any attempt at creating a release + upgrade file with such input will fail. + The only way to force an upgrade involving applications like this is to + handwrite the relup file, preferably as described above + with only the restart_emulator instruction. +

+ +
+
diff --git a/system/doc/system_principles/xmlfiles.mk b/system/doc/system_principles/xmlfiles.mk index 9743949798..c60ffbad28 100644 --- a/system/doc/system_principles/xmlfiles.mk +++ b/system/doc/system_principles/xmlfiles.mk @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 2009. All Rights Reserved. +# Copyright Ericsson AB 2009-2014. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in @@ -20,4 +20,5 @@ SYSTEM_PRINCIPLES_CHAPTER_FILES = \ system_principles.xml \ error_logging.xml \ create_target.xml \ + upgrade.xml \ versions.xml -- cgit v1.2.3