diff options
author | Siri Hansen <[email protected]> | 2014-02-19 17:24:27 +0100 |
---|---|---|
committer | Siri Hansen <[email protected]> | 2014-04-03 12:17:52 +0200 |
commit | c65821b677b4ebbc05192da9b8a48d32e53b3cfe (patch) | |
tree | 863ccc36f0f3d93be0f6e5210a2088b7b8091726 | |
parent | 8eb20d1fb0eb3a3b96d5e80e2e2617f893ef6986 (diff) | |
download | otp-c65821b677b4ebbc05192da9b8a48d32e53b3cfe.tar.gz otp-c65821b677b4ebbc05192da9b8a48d32e53b3cfe.tar.bz2 otp-c65821b677b4ebbc05192da9b8a48d32e53b3cfe.zip |
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.
-rw-r--r-- | lib/sasl/examples/src/target_system.erl | 16 | ||||
-rw-r--r-- | system/doc/system_principles/create_target.xmlsrc | 248 | ||||
-rw-r--r-- | system/doc/system_principles/part.xml | 4 | ||||
-rw-r--r-- | system/doc/system_principles/upgrade.xml | 118 | ||||
-rw-r--r-- | system/doc/system_principles/xmlfiles.mk | 3 |
5 files changed, 359 insertions, 30 deletions
diff --git a/lib/sasl/examples/src/target_system.erl b/lib/sasl/examples/src/target_system.erl index fb9e9aaaaf..a0ae016791 100644 --- a/lib/sasl/examples/src/target_system.erl +++ b/lib/sasl/examples/src/target_system.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2011-2013. All Rights Reserved. +%% Copyright Ericsson AB 2011-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 @@ -65,7 +65,7 @@ create(RelFileName,SystoolsOpts) -> [RelFileName, RelFileName]), make_script(RelFileName,SystoolsOpts), - TarFileName = filename:join(Dir,RelFileName ++ ".tar.gz"), + TarFileName = RelFileName ++ ".tar.gz", io:fwrite("Creating tar file ~tp ...~n", [TarFileName]), make_tar(RelFileName,SystoolsOpts), @@ -100,6 +100,12 @@ create(RelFileName,SystoolsOpts) -> copy_file(filename:join([ErtsBinDir, "to_erl"]), filename:join([TmpBinDir, "to_erl"]), [preserve]), + %% This is needed if 'start' script created from 'start.src' shall + %% be used as it points out this directory as log dir for 'run_erl' + TmpLogDir = filename:join([TmpDir, "log"]), + io:fwrite("Creating temporary directory ~tp ...~n", [TmpLogDir]), + ok = file:make_dir(TmpLogDir), + StartErlDataFile = filename:join([TmpDir, "releases", "start_erl.data"]), io:fwrite("Creating ~tp ...~n", [StartErlDataFile]), StartErlData = io_lib:fwrite("~s ~s~n", [ErtsVsn, RelVsn]), @@ -115,6 +121,7 @@ create(RelFileName,SystoolsOpts) -> erl_tar:add(Tar, filename:join(TmpDir,ErtsDir), ErtsDir, []), erl_tar:add(Tar, filename:join(TmpDir,"releases"), "releases", []), erl_tar:add(Tar, filename:join(TmpDir,"lib"), "lib", []), + erl_tar:add(Tar, filename:join(TmpDir,"log"), "log", []), erl_tar:close(Tar), %% file:set_cwd(Cwd), io:fwrite("Removing directory ~tp ...~n",[TmpDir]), @@ -136,6 +143,11 @@ install(RelFileName, RootDir) -> subst_src_scripts(["erl", "start", "start_erl"], ErtsBinDir, BinDir, [{"FINAL_ROOTDIR", RootDir}, {"EMU", "beam"}], [preserve]), + %%! Workaround for pre OTP 17.0: start.src and start_erl.src did + %%! not have correct permissions, so the above 'preserve' option did not help + ok = file:change_mode(filename:join(BinDir,"start"),8#0755), + ok = file:change_mode(filename:join(BinDir,"start_erl"),8#0755), + io:fwrite("Creating the RELEASES file ...\n"), create_RELEASES(RootDir, filename:join([RootDir, "releases", filename:basename(RelFileName)])). 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 @@ <chapter> <header> <copyright> - <year>2002</year><year>2013</year> + <year>2002</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -21,7 +21,7 @@ </legalnotice> - <title>Creating a First Target System</title> + <title>Creating and Upgrading a Target System</title> <prepared>Peter Högfeldt</prepared> <responsible></responsible> <docno></docno> @@ -71,23 +71,24 @@ </section> <section> + <marker id="create"/> <title>Creating a Target System</title> <p>It is assumed that you have a working Erlang/OTP system structured according to the OTP Design Principles.</p> - <p><em>Step 1.</em> First create a <c>.rel</c> file (see - <c>rel(4)</c>) that specifies the <c>erts</c> version - and lists all applications that should be included in the new - basic target system. An example is the following + <p><em>Step 1.</em> First create a <c>.rel</c> file (see <seealso + marker="sasl:rel">rel(4)</seealso>) that specifies the <c>erts</c> + version and lists all applications that should be included in the + new basic target system. An example is the following <c>mysystem.rel</c> file:</p> <code type="none"> %% mysystem.rel {release, {"MYSYSTEM", "FIRST"}, - {erts, "5.1"}, - [{kernel, "2.7"}, - {stdlib, "1.10"}, - {sasl, "1.9.3"}, - {pea, "1.0"}]}. </code> + {erts, "5.10.4"}, + [{kernel, "2.16.4"}, + {stdlib, "1.19.4"}, + {sasl, "2.3.4"}, + {pea, "1.0"}]}.</code> <p>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> <input>erl -pa /home/user/target_system/myapps/pea-1.0/ebin</input></pre> <c>systools:make_tar/2</c>. That file has the following contents:</p> <code type="none"> -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/ </code> <p>The file <c>releases/FIRST/start.boot</c> is a copy of our <c>mysystem.boot</c></p> @@ -142,16 +143,19 @@ lib/pea-1.0/ </code> <item>Creates the temporary directory <c>tmp</c> and extracts the tar file <c>mysystem.tar.gz</c> into that directory. </item> <item>Deletes the <c>erl</c> and <c>start</c> files from - <c>tmp/erts-5.1/bin</c>. These files will be created again from + <c>tmp/erts-5.10.4/bin</c>. These files will be created again from source when installing the release.</item> <item>Creates the directory <c>tmp/bin</c>.</item> <item>Copies the previously created file <c>plain.boot</c> to <c>tmp/bin/start.boot</c>.</item> <item>Copies the files <c>epmd</c>, <c>run_erl</c>, and - <c>to_erl</c> from the directory <c>tmp/erts-5.1/bin</c> to + <c>to_erl</c> from the directory <c>tmp/erts-5.10.4/bin</c> to the directory <c>tmp/bin</c>.</item> + <item>Creates the directory <c>tmp/log</c>, which will be used + if the system is started as embedded with the <c>bin/start</c> + script.</item> <item>Creates the file <c>tmp/releases/start_erl.data</c> 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 <c>start_erl</c> script. </item> <item>Recreates the file <c>mysystem.tar.gz</c> from the directories @@ -171,11 +175,11 @@ lib/pea-1.0/ </code> <item>Extracts the tar file <c>mysystem.tar.gz</c> into the target directory <c>/usr/local/erl-target</c>.</item> <item>In the target directory reads the file <c>releases/start_erl.data</c> - in order to find the Erlang runtime system version ("5.1").</item> + in order to find the Erlang runtime system version ("5.10.4").</item> <item>Substitutes <c>%FINAL_ROOTDIR%</c> and <c>%EMU%</c> for <c>/usr/local/erl-target</c> and <c>beam</c>, respectively, in the files <c>erl.src</c>, <c>start.src</c>, and - <c>start_erl.src</c> of the target <c>erts-5.1/bin</c> + <c>start_erl.src</c> of the target <c>erts-5.10.4/bin</c> directory, and puts the resulting files <c>erl</c>, <c>start</c>, and <c>run_erl</c> in the target <c>bin</c> directory.</item> @@ -185,6 +189,7 @@ lib/pea-1.0/ </code> </section> <section> + <marker id="start"/> <title>Starting a Target System</title> <p>Now we have a target system that can be started in various ways.</p> <p>We start it as a <em>basic target system</em> by invoking</p> @@ -193,7 +198,7 @@ os> <input>/usr/local/erl-target/bin/erl</input></pre> <p>where only the <c>kernel</c> and <c>stdlib</c> 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: - <c>bin/erl</c> file (obtained from <c>erts-5.1/bin/erl.src</c>) + <c>bin/erl</c> file (obtained from <c>erts-5.10.4/bin/erl.src</c>) and the <c>bin/start.boot</c> file (a copy of <c>plain.boot</c>).</p> <p>We can also start a distributed system (requires <c>bin/epmd</c>).</p> <p>To start all applications specified in the original @@ -208,9 +213,10 @@ os> <input>/usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI <c>bin/run_erl</c>, which in turn calls <c>bin/start_erl</c> (roughly, <c>start_erl</c> is an embedded variant of <c>erl</c>). </p> - <p>The shell script <c>start</c> is only an example. You should - edit it to suite your needs. Typically it is executed when the - UNIX system boots.</p> + <p>The shell script <c>start</c>, 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.</p> <p><c>run_erl</c> 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 (<c>to_erl</c>).</p> @@ -218,7 +224,7 @@ os> <input>/usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI (<c>"/usr/local/erl-target"</c>), the releases directory (<c>"/usr/local/erl-target/releases"</c>), and the location of the <c>start_erl.data</c> file. It reads the run-time system - version (<c>"5.1"</c>) and release version (<c>"FIRST"</c>) from + version (<c>"5.10.4"</c>) and release version (<c>"FIRST"</c>) from the <c>start_erl.data</c> file, starts the run-time system of the version found, and provides <c>-boot</c> flag specifying the boot file of the release version found @@ -258,6 +264,198 @@ os> <input>/usr/local/erl-target/bin/erl -boot /usr/local/erl-target/releases/FI </section> <section> + <title>Creating the Next Version</title> + + <p> + In this example the <c>pea</c> application has been changed, and + so are <c>erts</c>, <c>kernel</c>, <c>stdlib</c> and + <c>sasl</c>. + </p> + + <p> + <em>Step 1.</em> Create the <c>.rel</c> file: + </p> + <code type="none"> +%% mysystem2.rel +{release, + {"MYSYSTEM", "SECOND"}, + {erts, "6.0"}, + [{kernel, "3.0"}, + {stdlib, "2.0"}, + {sasl, "2.4"}, + {pea, "2.0"}]}.</code> + <p> + <em>Step 2.</em> Create the application upgrade file (see + <seealso marker="sasl:appup">appup(4)</seealso>) for <c>pea</c>, + for example: + </p> + <code type="none"> +%% pea.appup +{"2.0", + [{"1.0",[{load_module,pea_lib}]}], + [{"1.0",[{load_module,pea_lib}]}]}.</code> + <p> + <em>Step 3.</em> From the directory where the + <c>mysystem2.rel</c> file reside, start the Erlang/OTP system: + </p> + <pre> +os> <input>erl -pa /home/user/target_system/myapps/pea-2.0/ebin</input></pre> + <p>giving the path to the new version of <c>pea</c>. </p> + + <p> + <em>Step 4.</em> Create the release upgrade file (see <seealso + marker="sasl:relup">relup(4)</seealso>): + </p> + <pre> +1> <input>systools:make_relup("mysystem2",["mysystem"],["mysystem"],[{path,["/home/user/target_system/myapps/pea-1.0/ebin","/my/old/erlang/lib/*/ebin"]}]).</input></pre> + <p> + where <c>"mysystem"</c> is the base release and + <c>"mysystem2"</c> is the release to upgrade to. + </p> + <p> + Note that the <c>path</c> 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.) + </p> + <p> + <em>Step 5.</em> Create the new release: + </p> + <pre> +2> <input>target_system:create("mysystem2").</input></pre> + <p> + Given that the <c>relup</c> file generated in step 4 above is + now located in the current directory, it will automatically be + included in the release package. + </p> + </section> + + <section> + <title>Upgrading the Target System</title> + <p> + 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 + <c>-heart</c> option, allowing automatic restart of the + node. See <seealso marker="#start">Starting a Target + System</seealso> above for more information. + </p> + <p> + We add <c>-heart</c> to <c>bin/start</c>: + </p> + <code type="none"> +#!/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</code> + <p> + And we use the simplest possible <c>sys.config</c>, which we + store in <c>releases/FIRST</c>: + </p> + <code type="none"> +%% sys.config +[].</code> + <p> + Finally, in order to prepare the upgrade, we need to put the new + release package in the <c>releases</c> directory of the first + target system: + </p> + <pre> +os> <input>cp mysystem2.tar.gz /usr/local/erl-target/releases</input></pre> + <p> + And assuming that the node has been started like this: + </p> + <pre> +os> <input>/usr/local/erl-target/bin/start</input></pre> + <p> + it can be accessed like this: + </p> + <pre> +os> <input>/usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.1</input></pre> + <p> + Also note that logs can be found in + <c>/usr/local/erl-target/log</c>. This directory is specified as + an argument to <c>run_erl</c>in the start script listed above. + </p> + <p> + <em>Step 1.</em> Unpack the release: + </p> + <pre> +1> <input>{ok,Vsn} = release_handler:unpack_release("mysystem2").</input></pre> + <p> + <em>Step 2.</em> Install the release: + </p> + <pre> +2> <input>release_handler:install_release(Vsn).</input> +<output>{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]</output></pre> + <p> + The above return value and output after the call to + <c>release_handler:install_release/1</c> means that the + <c>release_handler</c> has restarted the node by using + <c>heart</c>. This will always be done when the upgrade involves + a change of <c>erts</c>, <c>kernel</c>, <c>stdlib</c> or + <c>sasl</c>. See <seealso marker="upgrade">Upgrade when + Erlang/OTP has Changed</seealso> for more infomation about this. + </p> + <p> + The node will be accessable via a new pipe: + </p> + <pre> +os> <input>/usr/local/erl-target/bin/to_erl /tmp/erlang.pipe.2</input></pre> + <p> + Let's see which releases we have in our system: + </p> + <pre> +1> <input>release_handler:which_releases().</input> +<output>[{"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}]</output></pre> + <p> + 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. + </p> + <p> + <em>Step 3.</em> Make the new release permanent: + </p> + <pre> +2> <input>release_handler:make_permanent("SECOND").</input></pre> + + <p> + Now look at the releases again: + </p> + + <pre> +3> <input>release_handler:which_releases().</input> +<output>[{"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}]</output></pre> + + <p> + Here we see that the new release version is <c>permanent</c>, so + it would be safe to restart the node. + </p> + + </section> + + <section> <title>Listing of target_system.erl</title> <p>This module can also be found in the <c>examples</c> directory of the <c>sasl</c> application.</p> 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 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1997</year><year>2013</year> + <year>1997</year><year>2014</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -31,6 +31,6 @@ <xi:include href="system_principles.xml"/> <xi:include href="error_logging.xml"/> <xi:include href="create_target.xml"/> + <xi:include href="upgrade.xml"/> <xi:include href="versions.xml"/> </part> - 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 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE chapter SYSTEM "chapter.dtd"> + +<chapter> + <header> + <copyright> + <year>2014</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + 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. + + </legalnotice> + + <title>Upgrade when Erlang/OTP has Changed</title> + <prepared></prepared> + <responsible></responsible> + <docno></docno> + <approved></approved> + <checked></checked> + <date>2014-02-19</date> + <rev></rev> + <file>upgrade.xml</file> + </header> + + <section> + <title>Introduction</title> + <p> + As of Erlang/OTP 17, most applications deliver a valid + application upgrade (<c>appup</c>) file. In earlier releases, a + majority of the applications in Erlang/OTP did not support + upgrade at all. Many of the applications use the + <c>restart_application</c> instruction. These are applications + for which it is not crucial to support real soft upgrade, for + instance tools and library applications. The + <c>restart_application</c> instruction + ensures that all modules in the application are reloaded and + thereby running the new code. + </p> + </section> + + <section> + <title>Upgrade of core applications</title> + <p> + 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 + <c>release_handler</c> by the upgrade instruction + <c>restart_new_emulator</c>. 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. + </p> + + <p> + 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 + <c>code_change</c> 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. + </p> + + <p> + If, however, the more brutal variant is preferred, it is + possible to handwrite the release upgrade file using only the + single upgrade instruction <c>restart_emulator</c>. This + instruction, in contrast to <c>restart_new_emulator</c>, will + cause the emulator to restart with the new versions of + <em>all</em> applications. + </p> + + <p> + <em>Note</em> that if other instructions are included before + <c>restart_emulator</c> in the handwritten <c>relup</c> 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 + <c>restart_emulator</c> has no effect as the + <c>release_handler</c> will not do any attempt at executing + them. + </p> + + <p> + See <seealso marker="sasl:relup">relup(4)</seealso> for + information about the release upgrade file, and <seealso + marker="sasl:appup">appup(4)</seealso> for further information + about upgrade instructions. + </p> + </section> + + <section> + <title>Applications that still do not allow code upgrade</title> + <p> + A few applications, for instance HiPE do not support + upgrade at all. This is indicated by an application upgrade file + containing only <c>{Vsn,[],[]}</c>. 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 <c>relup</c> file, preferably as described above + with only the <c>restart_emulator</c> instruction. + </p> + + </section> +</chapter> 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 |