<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html xmlns:fn="http://www.w3.org/2005/02/xpath-functions"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <link rel="stylesheet" href="../../../../doc/otp_doc.css" type="text/css"> <title>Erlang -- appup</title> </head> <body bgcolor="white" text="#000000" link="#0000ff" vlink="#ff00ff" alink="#ff0000"><div id="container"> <script id="js" type="text/javascript" language="JavaScript" src="../../../../doc/js/flipmenu/flipmenu.js"></script><script id="js2" type="text/javascript" src="../../../../doc/js/erlresolvelinks.js"></script><script language="JavaScript" type="text/javascript"> <!-- function getWinHeight() { var myHeight = 0; if( typeof( window.innerHeight ) == 'number' ) { //Non-IE myHeight = window.innerHeight; } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { //IE 6+ in 'standards compliant mode' myHeight = document.documentElement.clientHeight; } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) { //IE 4 compatible myHeight = document.body.clientHeight; } return myHeight; } function setscrollpos() { var objf=document.getElementById('loadscrollpos'); document.getElementById("leftnav").scrollTop = objf.offsetTop - getWinHeight()/2; } function addEvent(obj, evType, fn){ if (obj.addEventListener){ obj.addEventListener(evType, fn, true); return true; } else if (obj.attachEvent){ var r = obj.attachEvent("on"+evType, fn); return r; } else { return false; } } addEvent(window, 'load', setscrollpos); //--></script><div id="leftnav"><div class="innertube"> <img alt="Erlang logo" src="../../../../doc/erlang-logo.png"><br><small><a href="users_guide.html">User's Guide</a><br><a href="index.html">Reference Manual</a><br><a href="release_notes.html">Release Notes</a><br><a href="../pdf/sasl-2.2.1.pdf">PDF</a><br><a href="../../../../doc/index.html">Top</a></small><p><strong>System Application Support Libraries (SASL)</strong><br><strong>Reference Manual</strong><br><small>Version 2.2.1</small></p> <br><a href="javascript:openAllFlips()">Expand All</a><br><a href="javascript:closeAllFlips()">Contract All</a><p><small><strong>Table of Contents</strong></small></p> <ul class="flipMenu"> <li title="sasl (App)"><a href="sasl_app.html">sasl (App) </a></li> <li id="no" title="alarm_handler " expanded="false">alarm_handler<ul> <li><a href="alarm_handler.html"> Top of manual page </a></li> <li title="clear_alarm-1"><a href="alarm_handler.html#clear_alarm-1">clear_alarm/1</a></li> <li title="get_alarms-0"><a href="alarm_handler.html#get_alarms-0">get_alarms/0</a></li> <li title="set_alarm-1"><a href="alarm_handler.html#set_alarm-1">set_alarm/1</a></li> </ul> </li> <li id="no" title="overload " expanded="false">overload<ul> <li><a href="overload.html"> Top of manual page </a></li> <li title="request-0"><a href="overload.html#request-0">request/0</a></li> <li title="get_overload_info-0"><a href="overload.html#get_overload_info-0">get_overload_info/0</a></li> </ul> </li> <li id="no" title="rb " expanded="false">rb<ul> <li><a href="rb.html"> Top of manual page </a></li> <li title="filter-1"><a href="rb.html#filter-1">filter/1</a></li> <li title="filter-2"><a href="rb.html#filter-2">filter/2</a></li> <li title="grep-1"><a href="rb.html#grep-1">grep/1</a></li> <li title="h-0"><a href="rb.html#h-0">h/0</a></li> <li title="help-0"><a href="rb.html#help-0">help/0</a></li> <li title="list-0"><a href="rb.html#list-0">list/0</a></li> <li title="list-1"><a href="rb.html#list-1">list/1</a></li> <li title="rescan-0"><a href="rb.html#rescan-0">rescan/0</a></li> <li title="rescan-1"><a href="rb.html#rescan-1">rescan/1</a></li> <li title="show-0"><a href="rb.html#show-0">show/0</a></li> <li title="show-1"><a href="rb.html#show-1">show/1</a></li> <li title="start-0"><a href="rb.html#start-0">start/0</a></li> <li title="start-1"><a href="rb.html#start-1">start/1</a></li> <li title="start_log-1"><a href="rb.html#start_log-1">start_log/1</a></li> <li title="stop-0"><a href="rb.html#stop-0">stop/0</a></li> <li title="stop_log-0"><a href="rb.html#stop_log-0">stop_log/0</a></li> </ul> </li> <li id="no" title="release_handler " expanded="false">release_handler<ul> <li><a href="release_handler.html"> Top of manual page </a></li> <li title="check_install_release-1"><a href="release_handler.html#check_install_release-1">check_install_release/1</a></li> <li title="check_install_release-2"><a href="release_handler.html#check_install_release-2">check_install_release/2</a></li> <li title="create_RELEASES-4"><a href="release_handler.html#create_RELEASES-4">create_RELEASES/4</a></li> <li title="install_file-2"><a href="release_handler.html#install_file-2">install_file/2</a></li> <li title="install_release-1"><a href="release_handler.html#install_release-1">install_release/1</a></li> <li title="install_release-2"><a href="release_handler.html#install_release-2">install_release/2</a></li> <li title="make_permanent-1"><a href="release_handler.html#make_permanent-1">make_permanent/1</a></li> <li title="remove_release-1"><a href="release_handler.html#remove_release-1">remove_release/1</a></li> <li title="reboot_old_release-1"><a href="release_handler.html#reboot_old_release-1">reboot_old_release/1</a></li> <li title="set_removed-1"><a href="release_handler.html#set_removed-1">set_removed/1</a></li> <li title="set_unpacked-2"><a href="release_handler.html#set_unpacked-2">set_unpacked/2</a></li> <li title="unpack_release-1"><a href="release_handler.html#unpack_release-1">unpack_release/1</a></li> <li title="which_releases-0"><a href="release_handler.html#which_releases-0">which_releases/0</a></li> <li title="which_releases-1"><a href="release_handler.html#which_releases-1">which_releases/1</a></li> <li title="upgrade_app-2"><a href="release_handler.html#upgrade_app-2">upgrade_app/2</a></li> <li title="downgrade_app-2"><a href="release_handler.html#downgrade_app-2">downgrade_app/2</a></li> <li title="downgrade_app-3"><a href="release_handler.html#downgrade_app-3">downgrade_app/3</a></li> <li title="upgrade_script-2"><a href="release_handler.html#upgrade_script-2">upgrade_script/2</a></li> <li title="downgrade_script-3"><a href="release_handler.html#downgrade_script-3">downgrade_script/3</a></li> <li title="eval_appup_script-4"><a href="release_handler.html#eval_appup_script-4">eval_appup_script/4</a></li> </ul> </li> <li id="no" title="systools " expanded="false">systools<ul> <li><a href="systools.html"> Top of manual page </a></li> <li title="make_relup-3"><a href="systools.html#make_relup-3">make_relup/3</a></li> <li title="make_relup-4"><a href="systools.html#make_relup-4">make_relup/4</a></li> <li title="make_script-1"><a href="systools.html#make_script-1">make_script/1</a></li> <li title="make_script-2"><a href="systools.html#make_script-2">make_script/2</a></li> <li title="make_tar-1"><a href="systools.html#make_tar-1">make_tar/1</a></li> <li title="make_tar-2"><a href="systools.html#make_tar-2">make_tar/2</a></li> <li title="script2boot-1"><a href="systools.html#script2boot-1">script2boot/1</a></li> </ul> </li> <li title="appup"><a href="appup.html">appup</a></li> <li title="rel"><a href="rel.html">rel</a></li> <li title="relup"><a href="relup.html">relup</a></li> <li title="script"><a href="script.html">script</a></li> </ul> </div></div> <div id="content"> <div class="innertube"> <!-- refpage --><center><h1>appup</h1></center> <h3>FILE</h3> <div class="REFBODY">appup</div> <h3>FILE SUMMARY</h3> <div class="REFBODY">Application upgrade file.</div> <h3>DESCRIPTION</h3> <div class="REFBODY"><p> <p>The <strong>application upgrade file</strong> defines how an application is upgraded or downgraded in a running system.</p> <p>This file is used by the functions in <span class="code">systools</span> when generating a release upgrade file <span class="code">relup</span>.</p> </p></div> <h3><a name="id72925">FILE SYNTAX</a></h3> <div class="REFBODY"> <p>The application upgrade file should be called <span class="code">Application.appup</span> where <span class="code">Application</span> is the name of the application. The file should be located in the <span class="code">ebin</span> directory for the application.</p> <p>The <span class="code">.appup</span> file contains one single Erlang term, which defines the instructions used to upgrade or downgrade the application. The file has the following syntax:</p> <div class="example"><pre> {Vsn, [{UpFromVsn, Instructions}, ...], [{DownToVsn, Instructions}, ...]}. </pre></div> <ul> <li> <p><span class="code">Vsn = string()</span> is the current version of the application.</p> </li> <li> <p><span class="code">UpFromVsn = string() | binary()</span> is an earlier version of the application to upgrade from. If it is a string, it will be interpreted as a specific version number. If it is a binary, it will be interpreted as a regular expression which can match multiple version numbers.</p> </li> <li> <p><span class="code">DownToVsn = string() | binary()</span> is an earlier version of the application to downgrade to. If it is a string, it will be interpreted as a specific version number. If it is a binary, it will be interpreted as a regular expression which can match multiple version numbers.</p> </li> <li> <p><span class="code">Instructions</span> is a list of <strong>release upgrade instructions</strong>, see below. It is recommended to use high-level instructions only. These are automatically translated to low-level instructions by <span class="code">systools</span> when creating the <span class="code">relup</span> file.</p> </li> </ul> <p>In order to avoid duplication of upgrade instructions it is allowed to use regular expressions to specify the <span class="code">UpFromVsn</span> and <span class="code">DownToVsn</span>. To be considered a regular expression, the version identifier must be specified as a binary, e.g.</p> <div class="example"><pre><<"2\\.1\\.[0-9]+">></pre></div> <p>will match all versions <span class="code">2.1.x</span>, where x is any number.</p> </div> <h3><a name="id73053">RELEASE UPGRADE INSTRUCTIONS</a></h3> <div class="REFBODY"> <p>Release upgrade instructions are interpreted by the release handler when an upgrade or downgrade is made. For more information about release handling, refer to <strong>OTP Design Principles</strong>.</p> <p>A process is said to <strong>use</strong> a module <span class="code">Mod</span>, if <span class="code">Mod</span> is listed in the <span class="code">Modules</span> part of the child specification used to start the process, see <span class="code">supervisor(3)</span>. In the case of gen_event, an event manager process is said to use <span class="code">Mod</span> if <span class="code">Mod</span> is an installed event handler.</p> <p><strong>High-level instructions</strong></p> <div class="example"><pre> {update, Mod} {update, Mod, supervisor} {update, Mod, Change} {update, Mod, DepMods} {update, Mod, Change, DepMods} {update, Mod, Change, PrePurge, PostPurge, DepMods} {update, Mod, Timeout, Change, PrePurge, PostPurge, DepMods} {update, Mod, ModType, Timeout, Change, PrePurge, PostPurge, DepMods} Mod = atom() ModType = static | dynamic Timeout = int()>0 | default | infinity Change = soft | {advanced,Extra} Extra = term() PrePurge = PostPurge = soft_purge | brutal_purge DepMods = [Mod] </pre></div> <p>Synchronized code replacement of processes using the module <span class="code">Mod</span>. All those processes are suspended using <span class="code">sys:suspend</span>, the new version of the module is loaded and then the processes are resumed using <span class="code">sys:resume</span>.</p> <p><span class="code">Change</span> defaults to <span class="code">soft</span> and defines the type of code change. If it is set to <span class="code">{advanced,Extra}</span>, processes implemented using gen_server, gen_fsm or gen_event will transform their internal state by calling the callback function <span class="code">code_change</span>. Special processes will call the callback function <span class="code">system_code_change/4</span>. In both cases, the term <span class="code">Extra</span> is passed as an argument to the callback function.</p> <p><span class="code">PrePurge</span> defaults to <span class="code">brutal_purge</span> and controls what action to take with processes that are executing old code before loading the new version of the module. If the value is <span class="code">brutal_purge</span>, the processes are killed. If the value is <span class="code">soft_purge</span>, <span class="code">release_handler:install_release/1</span> returns <span class="code">{error,{old_processes,Mod}}</span>.</p> <p><span class="code">PostPurge</span> defaults to <span class="code">brutal_purge</span> and controls what action to take with processes that are executing old code when the new version of the module has been loaded. If the value is <span class="code">brutal_purge</span>, the code is purged when the release is made permanent and the processes are killed. If the value is <span class="code">soft_purge</span>, the release handler will purge the old code when no remaining processes execute the code.</p> <p><span class="code">DepMods</span> defaults to [] and defines which other modules <span class="code">Mod</span> is dependent on. In <span class="code">relup</span>, instructions for suspending processes using <span class="code">Mod</span> will come before instructions for suspending processes using modules in <span class="code">DepMods</span> when upgrading, and vice versa when downgrading. In case of circular dependencies, the order of the instructions in the <span class="code">appup</span> script is kept.</p> <p><span class="code">Timeout</span> defines the timeout when suspending processes. If no value or <span class="code">default</span> is given, the default value for <span class="code">sys:suspend</span> is used.</p> <p><span class="code">ModType</span> defaults to <span class="code">dynamic</span> and specifies if the code is "dynamic", that is if a process using the module does spontaneously switch to new code, or if it is "static". When doing an advanced update and upgrading, the new version of a dynamic module is loaded before the process is asked to change code. When downgrading, the process is asked to change code before loading the new version. For static modules, the new version is loaded before the process is asked to change code, both in the case of upgrading and downgrading. Callback modules are dynamic.</p> <p><span class="code">update</span> with argument <span class="code">supervisor</span> is used when changing the start specification of a supervisor.</p> <div class="example"><pre> {load_module, Mod} {load_module, Mod, DepMods} {load_module, Mod, PrePurge, PostPurge, DepMods} Mod = atom() PrePurge = PostPurge = soft_purge | brutal_purge DepMods = [Mod] </pre></div> <p>Simple code replacement of the module <span class="code">Mod</span>.</p> <p>See <span class="code">update</span> above for a description of <span class="code">PrePurge</span> and <span class="code">PostPurge</span>.</p> <p><span class="code">DepMods</span> defaults to [] and defines which other modules <span class="code">Mod</span> is dependent on. In <span class="code">relup</span>, instructions for loading these modules will come before the instruction for loading <span class="code">Mod</span> when upgrading, and vice versa when downgrading.</p> <div class="example"><pre> {add_module, Mod} Mod = atom() </pre></div> <p>Loads a new module <span class="code">Mod</span>.</p> <div class="example"><pre> {delete_module, Mod} Mod = atom() </pre></div> <p>Deletes a module <span class="code">Mod</span> using the low-level instructions <span class="code">remove</span> and <span class="code">purge</span>.</p> <div class="example"><pre> {add_application, Application} {add_application, Application, Type} Application = atom() Type = permanent | transient | temporary | load | none </pre></div> <p>Adding an application means that the modules defined by the <span class="code">modules</span> key in the <span class="code">.app</span> file are loaded using <span class="code">add_module</span>.</p> <p><span class="code">Type</span> defaults to <span class="code">permanent</span> and specifies the start type of the application. If <span class="code">Type = permanent | transient | temporary</span>, the application will be loaded and started in the corresponding way, see <span class="code">application(3)</span>. If <span class="code">Type = load</span>, the application will only be loaded. If <span class="code">Type = none</span>, the application will be neither loaded nor started, although the code for its modules will be loaded.</p> <div class="example"><pre> {remove_application, Application} Application = atom() </pre></div> <p>Removing an application means that the application is stopped, the modules are unloaded using <span class="code">delete_module</span> and then the application specification is unloaded from the application controller.</p> <div class="example"><pre> {restart_application, Application} Application = atom() </pre></div> <p>Restarting an application means that the application is stopped and then started again similar to using the instructions <span class="code">remove_application</span> and <span class="code">add_application</span> in sequence.</p> <p><strong>Low-level instructions</strong></p> <div class="example"><pre> {load_object_code, {App, Vsn, [Mod]}} App = Mod = atom() Vsn = string() </pre></div> <p>Reads each <span class="code">Mod</span> from the directory <span class="code">App-Vsn/ebin</span> as a binary. It does not load the modules. The instruction should be placed first in the script in order to read all new code from file to make the suspend-load-resume cycle less time consuming. After this instruction has been executed, the code server with the new version of <span class="code">App</span>.</p> <div class="example"><pre> point_of_no_return </pre></div> <p>If a crash occurs after this instruction, the system cannot recover and is restarted from the old version of the release. The instruction must only occur once in a script. It should be placed after all <span class="code">load_object_code</span> instructions.</p> <div class="example"><pre> {load, {Mod, PrePurge, PostPurge}} Mod = atom() PrePurge = PostPurge = soft_purge | brutal_purge </pre></div> <p>Before this instruction occurs, <span class="code">Mod</span> must have been loaded using <span class="code">load_object_code</span>. This instruction loads the module. <span class="code">PrePurge</span> is ignored. See the high-level instruction <span class="code">update</span> for a description of <span class="code">PostPurge</span>.</p> <div class="example"><pre> {remove, {Mod, PrePurge, PostPurge}} Mod = atom() PrePurge = PostPurge = soft_purge | brutal_purge </pre></div> <p>Makes the current version of <span class="code">Mod</span> old. <span class="code">PrePurge</span> is ignored. See the high-level instruction <span class="code">update</span> for a description of <span class="code">PostPurge</span>.</p> <div class="example"><pre> {purge, [Mod]} Mod = atom() </pre></div> <p>Purges each module <span class="code">Mod</span>, that is removes the old code. Note that any process executing purged code is killed.</p> <div class="example"><pre> {suspend, [Mod | {Mod, Timeout}]} Mod = atom() Timeout = int()>0 | default | infinity </pre></div> <p>Tries to suspend all processes using a module <span class="code">Mod</span>. If a process does not respond, it is ignored. This may cause the process to die, either because it crashes when it spontaneously switches to new code, or as a result of a purge operation. If no <span class="code">Timeout</span> is specified or <span class="code">default</span> is given, the default value for <span class="code">sys:suspend</span> is used.</p> <div class="example"><pre> {resume, [Mod]} Mod = atom() </pre></div> <p>Resumes all suspended processes using a module <span class="code">Mod</span>.</p> <div class="example"><pre> {code_change, [{Mod, Extra}]} {code_change, Mode, [{Mod, Extra}]} Mod = atom() Mode = up | down Extra = term() </pre></div> <p><span class="code">Mode</span> defaults to <span class="code">up</span> and specifies if it is an upgrade or downgrade.</p> <p>This instruction sends a <span class="code">code_change</span> system message to all processes using a module <span class="code">Mod</span> by calling the function <span class="code">sys:change_code</span>, passing the term <span class="code">Extra</span> as argument.</p> <div class="example"><pre> {stop, [Mod]} Mod = atom() </pre></div> <p>Stops all processes using a module <span class="code">Mod</span> by calling <span class="code">supervisor:terminate_child/2</span>. The instruction is useful when the simplest way to change code is to stop and restart the processes which run the code.</p> <div class="example"><pre> {start, [Mod]} Mod = atom() </pre></div> <p>Starts all stopped processes using a module <span class="code">Mod</span> by calling <span class="code">supervisor:restart_child/2</span>.</p> <div class="example"><pre> {sync_nodes, Id, [Node]} {sync_nodes, Id, {M, F, A}} Id = term() Node = node() M = F = atom() A = [term()] </pre></div> <p><span class="code">apply(M, F, A)</span> must return a list of nodes.</p> <p>The instruction synchronizes the release installation with other nodes. Each <span class="code">Node</span> must evaluate this command, with the same <span class="code">Id</span>. The local node waits for all other nodes to evaluate the instruction before execution continues. In case a node goes down, it is considered to be an unrecoverable error, and the local node is restarted from the old release. There is no timeout for this instruction, which means that it may hang forever.</p> <div class="example"><pre> {apply, {M, F, A}} M = F = atom() A = [term()] </pre></div> <p>Evaluates <span class="code">apply(M, F, A)</span>. If the instruction appears before the <span class="code">point_of_no_return</span> instruction, a failure is caught. <span class="code">release_handler:install_release/1</span> then returns <span class="code">{error,{'EXIT',Reason}}</span>, unless <span class="code">{error,Error}</span> is thrown or returned. Then it returns <span class="code">{error,Error}</span>.</p> <p>If the instruction appears after the <span class="code">point_of_no_return</span> instruction, and the function call fails, the system is restarted.</p> <div class="example"><pre> restart_new_emulator </pre></div> <p>This instruction is used when erts, kernel, stdlib or sasl is upgraded. It shuts down the current emulator and starts a new one. All processes are terminated gracefully, and the new version of erts, kernel, stdlib and sasl are used when the emulator restarts. Only one <span class="code">restart_new_emulator</span> instruction is allowed in the relup, and it shall be placed first. <span class="bold_code"><a href="systools.html#make_relup-3">systools:make_relup3,4</a></span> will ensure this when the relup is generated. The rest of the relup script is executed after the restart as a part of the boot script.</p> <p>An info report will be written when the upgrade is completed. To programatically find out if the upgrade is complete, call <span class="bold_code"><a href="release_handler.html#which_releases-0"> release_handler:which_releases</a></span> and check if the expected release has status <span class="code">current</span>.</p> <p>The new release must still be made permanent after the upgrade is completed. Otherwise, the old emulator is started in case of an emulator restart.</p> <div class="example"><pre> restart_emulator </pre></div> <p>This instruction is similar to <span class="code">restart_new_emulator</span>, except it shall be placed at the end of the relup script. It is not related to an upgrade of the emulator or the core applications, but can be used by any application when a complete reboot of the system is reqiured. When generating the relup, <span class="bold_code"><a href="systools.html#make_relup-3">systools:make_relup/3,4</a></span> ensures that there is only one <span class="code">restart_emulator</span> instruction and that it is the last instruction of the relup.</p> </div> <h3><a name="id73758">SEE ALSO</a></h3> <div class="REFBODY"> <p><span class="bold_code"><a href="relup.html">relup(4)</a></span>, <span class="bold_code"><a href="release_handler.html">release_handler(3)</a></span>, supervisor(3), <span class="bold_code"><a href="systools.html">systools(3)</a></span></p> </div> </div> <div class="footer"> <hr> <p>Copyright © 1997-2012 Ericsson AB. All Rights Reserved.</p> </div> </div> </div></body> </html>