aboutsummaryrefslogtreecommitdiffstats
path: root/system/doc/design_principles/release_handling.xml
diff options
context:
space:
mode:
Diffstat (limited to 'system/doc/design_principles/release_handling.xml')
-rw-r--r--system/doc/design_principles/release_handling.xml667
1 files changed, 667 insertions, 0 deletions
diff --git a/system/doc/design_principles/release_handling.xml b/system/doc/design_principles/release_handling.xml
new file mode 100644
index 0000000000..1d62c242c0
--- /dev/null
+++ b/system/doc/design_principles/release_handling.xml
@@ -0,0 +1,667 @@
+<?xml version="1.0" encoding="latin1" ?>
+<!DOCTYPE chapter SYSTEM "chapter.dtd">
+
+<chapter>
+ <header>
+ <copyright>
+ <year>2003</year><year>2009</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>Release Handling</title>
+ <prepared></prepared>
+ <docno></docno>
+ <date></date>
+ <rev></rev>
+ <file>release_handling.xml</file>
+ </header>
+
+ <section>
+ <title>Release Handling Principles</title>
+ <p>An important feature of the Erlang programming language is
+ the ability to change module code in run-time, <em>code replacement</em>, as described in <em>Erlang Reference Manual</em>.</p>
+ <p>Based on this feature, the OTP application SASL provides a
+ framework for upgrading and downgrading between different
+ versions of an entire release in run-time. This is what we call
+ <em>release handling</em>.</p>
+ <p>The framework consists of off-line support (<c>systools</c>) for
+ generating scripts and building release packages, and on-line
+ support (<c>release_handler</c>) for unpacking and installing
+ release packages.</p>
+ <p>Note that the minimal system based on Erlang/OTP, enabling
+ release handling, thus consists of Kernel, STDLIB and SASL.</p>
+ <list type="ordered">
+ <item>
+ <p>A release is created as described in the previous chapter
+ <seealso marker="release_structure">Releases</seealso>.
+ The release is transferred to and installed at target
+ environment. Refer to <em>System Principles</em> for
+ information of how to install the first target system.</p>
+ </item>
+ <item>
+ <p>Modifications, for example error corrections, are made to
+ the code in the development environment.</p>
+ </item>
+ <item>
+ <p>At some point it is time to make a new version of release.
+ The relevant <c>.app</c> files are updated and a new
+ <c>.rel</c> file is written.</p>
+ </item>
+ <item>
+ <p>For each modified application, an
+ <seealso marker="#appup">application upgrade file</seealso>,
+ <c>.appup</c>, is created. In this file, it is described how
+ to upgrade and/or downgrade between the old and new version of
+ the application.</p>
+ </item>
+ <item>
+ <p>Based on the <c>.appup</c> files, a
+ <seealso marker="#relup">release upgrade file</seealso> called
+ <c>relup</c>, is created. This file describes how to upgrade
+ and/or downgrade between the old and new version of
+ the entire release.</p>
+ </item>
+ <item>
+ <p>A new release package is made and transferred to
+ the target system.</p>
+ </item>
+ <item>
+ <p>The new release package is unpacked using the release
+ handler.</p>
+ </item>
+ <item>
+ <p>The new version of the release is installed, also using
+ the release handler. This is done by evaluating
+ the instructions in <c>relup</c>. Modules may be added,
+ deleted or re-loaded, applications may be started, stopped or
+ re-started etc. In some cases, it is even necessary to restart
+ the entire emulator.</p>
+ <p>If the installation fails, the system may be rebooted.
+ The old release version is then automatically used.</p>
+ </item>
+ <item>
+ <p>If the installation succeeds, the new version is made
+ the default version, which should now be used in case of a
+ system reboot.</p>
+ </item>
+ </list>
+ <p>The next chapter, <seealso marker="appup_cookbook">Appup Cookbook</seealso>, contains examples of <c>.appup</c> files
+ for typical cases of upgrades/downgrades that are normally easy
+ to handle in run-time. However, there are a many aspects that can
+ make release handling complicated. To name a few examples:</p>
+ <list type="bulleted">
+ <item>
+ <p>Complicated or circular dependencies can make it difficult
+ or even impossible to decide in which order things must be
+ done without risking run-time errors during an upgrade or
+ downgrade. Dependencies may be:</p>
+ <list type="bulleted">
+ <item>between nodes,</item>
+ <item>between processes, and</item>
+ <item>between modules.</item>
+ </list>
+ </item>
+ <item>
+ <p>During release handling, non-affected processes continue
+ normal execution. This may lead to timeouts or other problems.
+ For example, new processes created in the time window between
+ suspending processes using a certain module and loading a new
+ version of this module, may execute old code.</p>
+ </item>
+ </list>
+ <p>It is therefore recommended that code is changed in as small
+ steps as possible, and always kept backwards compatible.</p>
+ </section>
+
+ <section>
+ <marker id="req"></marker>
+ <title>Requirements</title>
+ <p>For release handling to work properly, the runtime system needs
+ to have knowledge about which release it is currently running. It
+ must also be able to change (in run-time) which boot script and
+ system configuration file should be used if the system is
+ rebooted, for example by <c>heart</c> after a failure.
+ Therefore, Erlang must be started as an embedded system, see
+ <em>Embedded System</em> for information on how to do this.</p>
+ <p>For system reboots to work properly, it is also required that
+ the system is started with heart beat monitoring, see
+ <c>erl(1)</c> and <c>heart(3)</c>.</p>
+ <p>Other requirements:</p>
+ <list type="bulleted">
+ <item>
+ <p>The boot script included in a release package must be
+ generated from the same <c>.rel</c> file as the release
+ package itself.</p>
+ <p>Information about applications are fetched from the script
+ when an upgrade or downgrade is performed.</p>
+ </item>
+ <item>
+ <p>The system must be configured using one and only one system
+ configuration file, called <c>sys.config</c>.</p>
+ <p>If found, this file is automatically included when a release
+ package is created.</p>
+ </item>
+ <item>
+ <p>All versions of a release, except the first one, must
+ contain a <c>relup</c> file.</p>
+ <p>If found, this file is automatically included when a release
+ package is created.</p>
+ </item>
+ </list>
+ </section>
+
+ <section>
+ <title>Distributed Systems</title>
+ <p>If the system consists of several Erlang nodes, each node may use
+ its own version of the release. The release handler is a locally
+ registered process and must be called at each node where an
+ upgrade or downgrade is required. There is a release handling
+ instruction that can be used to synchronize the release handler
+ processes at a number of nodes: <c>sync_nodes</c>. See
+ <c>appup(4)</c>.</p>
+ </section>
+
+ <section>
+ <marker id="instr"></marker>
+ <title>Release Handling Instructions</title>
+ <p>OTP supports a set of <em>release handling instructions</em>
+ that is used when creating <c>.appup</c> files. The release
+ handler understands a subset of these, the <em>low-level</em>
+ instructions. To make it easier for the user, there are also a
+ number of <em>high-level</em> instructions, which are translated
+ to low-level instructions by <c>systools:make_relup</c>.</p>
+ <p>Here, some of the most frequently used instructions are
+ described. The complete list of instructions is found in
+ <c>appup(4)</c>.</p>
+ <p>First, some definitions:</p>
+ <taglist>
+ <tag><em>Residence module</em></tag>
+ <item>
+ <p>The module where a process has its tail-recursive loop
+ function(s). If the tail-recursive loop functions are
+ implemented in several modules, all those modules are residence
+ modules for the process.</p>
+ </item>
+ <tag><em>Functional module</em></tag>
+ <item>
+ <p>A module which is not a residence module for any process.</p>
+ </item>
+ </taglist>
+ <p>Note that for a process implemented using an OTP behaviour,
+ the behaviour module is the residence module for that process.
+ The callback module is a functional module.</p>
+
+ <section>
+ <title>load_module</title>
+ <p>If a simple extension has been made to a functional module, it
+ is sufficient to simply load the new version of the module into
+ the system, and remove the old version. This is called
+ <em>simple code replacement</em> and for this the following
+ instruction is used:</p>
+ <code type="none">
+{load_module, Module}</code>
+ </section>
+
+ <section>
+ <title>update</title>
+ <p>If a more complex change has been made, for example a change
+ to the format of the internal state of a gen_server, simple code
+ replacement is not sufficient. Instead it is necessary to
+ suspend the processes using the module (to avoid that they try
+ to handle any requests before the code replacement is
+ completed), ask them to transform the internal state format and
+ switch to the new version of the module, remove the old version
+ and last, resume the processes. This is called <em>synchronized code replacement</em> and for this the following instructions
+ are used:</p>
+ <code type="none">
+{update, Module, {advanced, Extra}}
+{update, Module, supervisor}</code>
+ <p><c>update</c> with argument <c>{advanced,Extra}</c> is used
+ when changing the internal state of a behaviour as described
+ above. It will cause behaviour processes to call the callback
+ function <c>code_change</c>, passing the term <c>Extra</c> and
+ some other information as arguments. See the man pages for
+ the respective behaviours and
+ <seealso marker="appup_cookbook#int_state">Appup Cookbook</seealso>.</p>
+ <p><c>update</c> with argument <c>supervisor</c> is used when
+ changing the start specification of a supervisor. See
+ <seealso marker="appup_cookbook#sup">Appup Cookbook</seealso>.</p>
+ <p>The release handler finds the processes <em>using</em> a module
+ to update by traversing the supervision tree of each running
+ application and checking all the child specifications:</p>
+ <code type="none">
+{Id, StartFunc, Restart, Shutdown, Type, Modules}</code>
+ <p>A process is using a module if the name is listed in
+ <c>Modules</c> in the child specification for the process.</p>
+ <p>If <c>Modules=dynamic</c>, which is the case for event
+ managers, the event manager process informs the release handler
+ about the list of currently installed event handlers (gen_fsm)
+ and it is checked if the module name is in this list instead.</p>
+ <p>The release handler suspends, asks for code change, and
+ resumes processes by calling the functions
+ <c>sys:suspend/1,2</c>, <c>sys:change_code/4,5</c> and
+ <c>sys:resume/1,2</c> respectively.</p>
+ </section>
+
+ <section>
+ <title>add_module and delete_module</title>
+ <p>If a new module is introduced, the following instruction is
+ used:</p>
+ <code type="none">
+{add_module, Module}</code>
+ <p>The instruction loads the module and is absolutely necessary
+ when running Erlang in embedded mode. It is not strictly
+ required when running Erlang in interactive (default) mode,
+ since the code server automatically searches for and loads
+ unloaded modules.</p>
+ <p>The opposite of <c>add_module</c> is <c>delete_module</c> which
+ unloads a module:</p>
+ <code type="none">
+{delete_module, Module}</code>
+ <p>Note that any process, in any application, with <c>Module</c>
+ as residence module, is killed when the instruction is
+ evaluated. The user should therefore ensure that all such
+ processes are terminated before deleting the module, to avoid
+ a possible situation with failing supervisor restarts.</p>
+ </section>
+
+ <section>
+ <title>Application Instructions</title>
+ <p>Instruction for adding an application:</p>
+ <code type="none">
+{add_application, Application}</code>
+ <p>Adding an application means that the modules defined by
+ the <c>modules</c> key in the <c>.app</c> file are loaded using
+ a number of <c>add_module</c> instructions, then the application
+ is started.</p>
+ <p>Instruction for removing an application:</p>
+ <code type="none">
+{remove_application, Application}</code>
+ <p>Removing an application means that the application is stopped,
+ the modules are unloaded using a number of <c>delete_module</c>
+ instructions and then the application specification is unloaded
+ from the application controller.</p>
+ <p>Instruction for removing an application:</p>
+ <code type="none">
+{restart_application, Application}</code>
+ <p>Restarting an application means that the application is stopped
+ and then started again similar to using the instructions
+ <c>remove_application</c> and <c>add_application</c> in
+ sequence.</p>
+ </section>
+
+ <section>
+ <title>apply (low-level)</title>
+ <p>To call an arbitrary function from the release handler,
+ the following instruction is used:</p>
+ <code type="none">
+{apply, {M, F, A}}</code>
+ <p>The release handler will evalute <c>apply(M, F, A)</c>.</p>
+ </section>
+
+ <section>
+ <title>restart_new_emulator (low-level)</title>
+ <p>This instruction is used when changing to a new emulator
+ version, or if a system reboot is needed for some other reason.
+ Requires that the system is started with heart beat
+ monitoring, see <c>erl(1)</c> and <c>heart(3)</c>.</p>
+ <p>When the release handler encounters the instruction, it shuts
+ down the current emulator by calling <c>init:reboot()</c>, see
+ <c>init(3)</c>. All processes are terminated gracefully and
+ the system can then be rebooted by the heart program, using
+ the new release version. This new version must still be made
+ permanent when the new emulator is up and running. Otherwise,
+ the old version is used in case of a new system reboot.</p>
+ <p>On UNIX, the release handler tells the heart program which
+ command to use to reboot the system. Note that the environment
+ variable <c>HEART_COMMAND</c>, normally used by the heart
+ program, in this case is ignored. The command instead defaults
+ to <c>$ROOT/bin/start</c>. Another command can be set
+ by using the SASL configuration parameter <c>start_prg</c>, see
+ <c>sasl(6)</c>.</p>
+ </section>
+ </section>
+
+ <section>
+ <marker id="appup"></marker>
+ <title>Application Upgrade File</title>
+ <p>To define how to upgrade/downgrade between the current version
+ and previous versions of an application, we create an
+ <em>application upgrade file</em>, or in short <c>.appup</c> file.
+ The file should be called <c>Application.appup</c>, where
+ <c>Application</c> is the name of the application:</p>
+ <code type="none">
+{Vsn,
+ [{UpFromVsn1, InstructionsU1},
+ ...,
+ {UpFromVsnK, InstructionsUK}],
+ [{DownToVsn1, InstructionsD1},
+ ...,
+ {DownToVsnK, InstructionsDK}]}.</code>
+ <p><c>Vsn</c>, a string, is the current version of the application,
+ as defined in the <c>.app</c> file. Each <c>UpFromVsn</c>
+ is a previous version of the application to upgrade from, and each
+ <c>DownToVsn</c> is a previous version of the application to
+ downgrade to. Each <c>Instructions</c> is a list of release
+ handling instructions.</p>
+ <p>The syntax and contents of the <c>appup</c> file are described
+ in detail in <c>appup(4)</c>.</p>
+ <p>In the chapter <seealso marker="appup_cookbook">Appup Cookbook</seealso>, examples of <c>.appup</c> files for typical
+ upgrade/downgrade cases are given.</p>
+ <p>Example: Consider the release <c>ch_rel-1</c> from
+ the <seealso marker="release_structure#ch_rel">Releases</seealso>
+ chapter. Assume we want to add a function <c>available/0</c> to
+ the server <c>ch3</c> which returns the number of available
+ channels:</p>
+ <p>(Hint: When trying out the example, make the changes in a copy of
+ the original directory, so that the first versions are still
+ available.)</p>
+ <code type="none">
+-module(ch3).
+-behaviour(gen_server).
+
+-export([start_link/0]).
+-export([alloc/0, free/1]).
+-export([available/0]).
+-export([init/1, handle_call/3, handle_cast/2]).
+
+start_link() ->
+ gen_server:start_link({local, ch3}, ch3, [], []).
+
+alloc() ->
+ gen_server:call(ch3, alloc).
+
+free(Ch) ->
+ gen_server:cast(ch3, {free, Ch}).
+
+available() ->
+ gen_server:call(ch3, available).
+
+init(_Args) ->
+ {ok, channels()}.
+
+handle_call(alloc, _From, Chs) ->
+ {Ch, Chs2} = alloc(Chs),
+ {reply, Ch, Chs2};
+handle_call(available, _From, Chs) ->
+ N = available(Chs),
+ {reply, N, Chs}.
+
+handle_cast({free, Ch}, Chs) ->
+ Chs2 = free(Ch, Chs),
+ {noreply, Chs2}.</code>
+ <p>A new version of the <c>ch_app.app</c> file must now be created,
+ where the version is updated:</p>
+ <code type="none">
+{application, ch_app,
+ [{description, "Channel allocator"},
+ {vsn, "2"},
+ {modules, [ch_app, ch_sup, ch3]},
+ {registered, [ch3]},
+ {applications, [kernel, stdlib, sasl]},
+ {mod, {ch_app,[]}}
+ ]}.</code>
+ <p>To upgrade <c>ch_app</c> from <c>"1"</c> to <c>"2"</c> (and
+ to downgrade from <c>"2"</c> to <c>"1"</c>), we simply need to
+ load the new (old) version of the <c>ch3</c> callback module.
+ We create the application upgrade file <c>ch_app.appup</c> in
+ the <c>ebin</c> directory:</p>
+ <code type="none">
+{"2",
+ [{"1", [{load_module, ch3}]}],
+ [{"1", [{load_module, ch3}]}]
+}.</code>
+ </section>
+
+ <section>
+ <marker id="relup"></marker>
+ <title>Release Upgrade File</title>
+ <p>To define how to upgrade/downgrade between the new version and
+ previous versions of a release, we create a <em>release upgrade file</em>, or in short <c>relup</c> file.</p>
+ <p>This file does not need to be created manually, it can be
+ generated by <c>systools:make_relup/3,4</c>. The relevant versions
+ of the <c>.rel</c> file, <c>.app</c> files and <c>.appup</c> files
+ are used as input. It is deducted which applications should be
+ added and deleted, and which applications that need to be upgraded
+ and/or downgraded. The instructions for this is fetched from
+ the <c>.appup</c> files and transformed into a single list of
+ low-level instructions in the right order.</p>
+ <p>If the <c>relup</c> file is relatively simple, it can be created
+ manually. Remember that it should only contain low-level
+ instructions.</p>
+ <p>The syntax and contents of the release upgrade file are
+ described in detail in <c>relup(4)</c>.</p>
+ <p>Example, continued from the previous section. We have a new
+ version "2" of <c>ch_app</c> and an <c>.appup</c> file. We also
+ need a new version of the <c>.rel</c> file. This time the file is
+ called <c>ch_rel-2.rel</c> and the release version string is
+ changed changed from "A" to "B":</p>
+ <code type="none">
+{release,
+ {"ch_rel", "B"},
+ {erts, "5.3"},
+ [{kernel, "2.9"},
+ {stdlib, "1.12"},
+ {sasl, "1.10"},
+ {ch_app, "2"}]
+}.</code>
+ <p>Now the <c>relup</c> file can be generated:</p>
+ <pre>
+1> <input>systools:make_relup("ch_rel-2", ["ch_rel-1"], ["ch_rel-1"]).</input>
+ok</pre>
+ <p>This will generate a <c>relup</c> file with instructions for
+ how to upgrade from version "A" ("ch_rel-1") to version "B"
+ ("ch_rel-2") and how to downgrade from version "B" to version "A".</p>
+ <p>Note that both the old and new versions of the <c>.app</c> and
+ <c>.rel</c> files must be in the code path, as well as
+ the <c>.appup</c> and (new) <c>.beam</c> files. It is possible
+ to extend the code path by using the option <c>path</c>:</p>
+ <pre>
+1> <input>systools:make_relup("ch_rel-2", ["ch_rel-1"], ["ch_rel-1"],</input>
+<input>[{path,["../ch_rel-1",</input>
+<input>"../ch_rel-1/lib/ch_app-1/ebin"]}]).</input>
+ok</pre>
+ </section>
+
+ <section>
+ <marker id="rel_handler"></marker>
+ <title>Installing a Release</title>
+ <p>When we have made a new version of a release, a release package
+ can be created with this new version and transferred to the target
+ environment.</p>
+ <p>To install the new version of the release in run-time,
+ the <em>release handler</em> is used. This is a process belonging
+ to the SASL application, that handles unpacking, installation,
+ and removal of release packages. It is interfaced through
+ the module <c>release_handler</c>, which is described in detail in
+ <c>release_handler(3)</c>.</p>
+ <p>Assuming there is a target system up and running with
+ installation root directory <c>$ROOT</c>, the release package with
+ the new version of the release should be copied to
+ <c>$ROOT/releases</c>.</p>
+ <p>The first action is to <em>unpack</em> the release package,
+ the files are then extracted from the package:</p>
+ <code type="none">
+release_handler:unpack_release(ReleaseName) => {ok, Vsn}</code>
+ <p><c>ReleaseName</c> is the name of the release package except
+ the <c>.tar.gz</c> extension. <c>Vsn</c> is the version of
+ the unpacked release, as defined in its <c>.rel</c> file.</p>
+ <p>A directory <c>$ROOT/lib/releases/Vsn</c> will be created, where
+ the <c>.rel</c> file, the boot script <c>start.boot</c>,
+ the system configuration file <c>sys.config</c> and <c>relup</c>
+ are placed. For applications with new version numbers,
+ the application directories will be placed under <c>$ROOT/lib</c>.
+ Unchanged applications are not affected.</p>
+ <p>An unpacked release can be <em>installed</em>. The release
+ handler then evaluates the instructions in <c>relup</c>, step by
+ step:</p>
+ <code type="none">
+release_handler:install_release(Vsn) => {ok, FromVsn, []}</code>
+ <p>If an error occurs during the installation, the system is
+ rebooted using the old version of the release. If installation
+ succeeds, the system is afterwards using the new version of
+ the release, but should anything happen and the system is
+ rebooted, it would start using the previous version again. To be
+ made the default version, the newly installed release must be made
+ <em>permanent</em>, which means the previous version becomes
+ <em>old</em>:</p>
+ <code type="none">
+release_handler:make_permanent(Vsn) => ok</code>
+ <p>The system keeps information about which versions are old and
+ permanent in the files <c>$ROOT/releases/RELEASES</c> and
+ <c>$ROOT/releases/start_erl.data</c>.</p>
+ <p>To downgrade from <c>Vsn</c> to <c>FromVsn</c>,
+ <c>install_release</c> must be called again:</p>
+ <code type="none">
+release_handler:install_release(FromVsn) => {ok, Vsn, []}</code>
+ <p>An installed, but not permanent, release can be <em>removed</em>.
+ Information about the release is then deleted from
+ <c>$ROOT/releases/RELEASES</c> and the release specific code,
+ that is the new application directories and
+ the <c>$ROOT/releases/Vsn</c> directory, are removed.</p>
+ <code type="none">
+release_handler:remove_release(Vsn) => ok</code>
+ <p>Example, continued from the previous sections:</p>
+ <p>1) Create a target system as described in <em>System Principles</em> of the first version <c>"A"</c> of <c>ch_rel</c>
+ from
+ the <seealso marker="release_structure#ch_rel">Releases</seealso>
+ chapter. This time <c>sys.config</c> must be included in
+ the release package. If no configuration is needed, the file
+ should contain the empty list:</p>
+ <code type="none">
+[].</code>
+ <p>2) Start the system as a simple target system. Note that in
+ reality, it should be started as an embedded system. However,
+ using <c>erl</c> with the correct boot script and <c>.config</c>
+ file is enough for illustration purposes:</p>
+ <pre>
+% <input>cd $ROOT</input>
+% <input>bin/erl -boot $ROOT/releases/A/start -config $ROOT/releases/A/sys</input>
+...</pre>
+ <p><c>$ROOT</c> is the installation directory of the target system.</p>
+ <p>3) In another Erlang shell, generate start scripts and create a
+ release package for the new version <c>"B"</c>. Remember to
+ include (a possible updated) <c>sys.config</c> and
+ the <c>relup</c> file, see <seealso marker="#relup">Release Upgrade File</seealso> above.</p>
+ <pre>
+1> <input>systools:make_script("ch_rel-2").</input>
+ok
+2> <input>systools:make_tar("ch_rel-2").</input>
+ok</pre>
+ <p>The new release package now contains version "2" of <c>ch_app</c>
+ and the <c>relup</c> file as well:</p>
+ <code type="none">
+% tar tf ch_rel-2.tar
+lib/kernel-2.9/ebin/kernel.app
+lib/kernel-2.9/ebin/application.beam
+...
+lib/stdlib-1.12/ebin/stdlib.app
+lib/stdlib-1.12/ebin/beam_lib.beam
+...
+lib/sasl-1.10/ebin/sasl.app
+lib/sasl-1.10/ebin/sasl.beam
+...
+lib/ch_app-2/ebin/ch_app.app
+lib/ch_app-2/ebin/ch_app.beam
+lib/ch_app-2/ebin/ch_sup.beam
+lib/ch_app-2/ebin/ch3.beam
+releases/B/start.boot
+releases/B/relup
+releases/B/sys.config
+releases/ch_rel-2.rel</code>
+ <p>4) Copy the release package <c>ch_rel-2.tar.gz</c> to
+ the <c>$ROOT/releases</c> directory.</p>
+ <p>5) In the running target system, unpack the release package:</p>
+ <pre>
+1> <input>release_handler:unpack_release("ch_rel-2").</input>
+{ok,"B"}</pre>
+ <p>The new application version <c>ch_app-2</c> is installed under
+ <c>$ROOT/lib</c> next to <c>ch_app-1</c>. The <c>kernel</c>,
+ <c>stdlib</c> and <c>sasl</c> directories are not affected, as
+ they have not changed.</p>
+ <p>Under <c>$ROOT/releases</c>, a new directory <c>B</c> is created,
+ containing <c>ch_rel-2.rel</c>, <c>start.boot</c>,
+ <c>sys.config</c> and <c>relup</c>.</p>
+ <p>6) Check if the function <c>ch3:available/0</c> is available:</p>
+ <pre>
+2> <input>ch3:available().</input>
+** exception error: undefined function ch3:available/0</pre>
+ <p>7) Install the new release. The instructions in
+ <c>$ROOT/releases/B/relup</c> are executed one by one, resulting
+ in the new version of <c>ch3</c> being loaded. The function
+ <c>ch3:available/0</c> is now available:</p>
+ <pre>
+3> <input>release_handler:install_release("B").</input>
+{ok,"A",[]}
+4> <input>ch3:available().</input>
+3
+5> <input>code:which(ch3).</input>
+".../lib/ch_app-2/ebin/ch3.beam"
+6> <input>code:which(ch_sup).</input>
+".../lib/ch_app-1/ebin/ch_sup.beam"</pre>
+ <p>Note that processes in <c>ch_app</c> for which code have not
+ been updated, for example the supervisor, are still evaluating
+ code from <c>ch_app-1</c>.</p>
+ <p>8) If the target system is now rebooted, it will use version "A"
+ again. The "B" version must be made permanent, in order to be
+ used when the system is rebooted.</p>
+ <pre>
+7> <input>release_handler:make_permanent("B").</input>
+ok</pre>
+ </section>
+
+ <section>
+ <marker id="sys"></marker>
+ <title>Updating Application Specifications</title>
+ <p>When a new version of a release is installed, the application
+ specifications are automatically updated for all loaded
+ applications.</p>
+ <note>
+ <p>The information about the new application specifications are
+ fetched from the boot script included in the release package.
+ It is therefore important that the boot script is generated from
+ the same <c>.rel</c> file as is used to build the release
+ package itself.</p>
+ </note>
+ <p>Specifically, the application configuration parameters are
+ automatically updated according to (in increasing priority
+ order):</p>
+ <list type="ordered">
+ <item>The data in the boot script, fetched from the new
+ application resource file <c>App.app</c></item>
+ <item>The new <c>sys.config</c></item>
+ <item>Command line arguments <c>-App Par Val</c></item>
+ </list>
+ <p>This means that parameter values set in the other system
+ configuration files, as well as values set using
+ <c>application:set_env/3</c>, are disregarded.</p>
+ <p>When an installed release is made permanent, the system process
+ <c>init</c> is set to point out the new <c>sys.config</c>.</p>
+ <p>After the installation, the application controller will compare
+ the old and new configuration parameters for all running
+ applications and call the callback function:</p>
+ <code type="none">
+Module:config_change(Changed, New, Removed)</code>
+ <p><c>Module</c> is the application callback module as defined by
+ the <c>mod</c> key in the <c>.app</c> file. <c>Changed</c> and
+ <c>New</c> are lists of <c>{Par,Val}</c> for all changed and
+ added configuration parameters, respectively. <c>Removed</c> is
+ a list of all parameters <c>Par</c> that have been removed.</p>
+ <p>The function is optional and may be omitted when implementing an
+ application callback module.</p>
+ </section>
+</chapter>
+