<?xml version="1.0" encoding="latin1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> <header> <copyright> <year>1996</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>Starting an Embedded System</title> <prepared>Martin Björklund</prepared> <responsible>Bjarne Däcker</responsible> <docno></docno> <approved>Bjarne Däcker</approved> <checked></checked> <date>1997-10-17</date> <rev>D</rev> <file>starting.sgml</file> </header> <section> <title>Introduction</title> <p>This chapter describes how an embedded system is started. There are four programs involved, and they all normally reside in the directory <c><![CDATA[<ERL_INSTALL_DIR>/bin]]></c>. The only exception is the program <c>start</c>, which may be located anywhere, and also is the only program that must be modified by the user. </p> <p>In an embedded system there usually is no interactive shell. However, it is possible for an operator to attach to the Erlang runtime system by giving the command <c>to_erl</c>. He is then connected to the Erlang shell, and may give ordinary Erlang commands. All interaction with the system through this shell is logged in a special directory. </p> <p>Basically, the procedure is as follows. The program <c>start</c> is called when the machine is started. It calls <c>run_erl</c>, which sets things up so the operator can attach to the system. It calls <c>start_erl</c> which calls the correct version of <c>erlexec</c> (which is located in <c><![CDATA[<ERL_INSTALL_DIR>/erts-EVsn/bin]]></c>) with the correct <c>boot</c> and <c>config</c> files. </p> </section> <section> <title>Programs</title> <section> <title>start</title> <p>This program is called when the machine is started. It may be modified or re-written to suit a special system. By default, it must be called <c>start</c> and reside in <c><![CDATA[<ERL_INSTALL_DIR>/bin]]></c>. Another start program can be used, by using the configuration parameter <c>start_prg</c> in the application <c>sasl</c>.</p> <p>The start program must call <c>run_erl</c> as shown below. It must also take an optional parameter which defaults to <c><![CDATA[<ERL_INSTALL_DIR>/bin/start_erl.data]]></c>. </p> <p>This program should set static parameters and environment variables such as <c>-sname Name</c> and <c>HEART_COMMAND</c> to reboot the machine. </p> <p>The <c><![CDATA[<RELDIR>]]></c> directory is where new release packets are installed, and where the release handler keeps information about releases. See <c>release_handler(3)</c> in the application <c>sasl</c> for further information. </p> <p>The following script illustrates the default behaviour of the program. </p> <code type="none"><![CDATA[ #!/bin/sh # Usage: start [DataFile] # ROOTDIR=/usr/local/otp if [ -z "$RELDIR" ] then RELDIR=$ROOTDIR/releases fi START_ERL_DATA=${1:-$RELDIR/start_erl.data} $ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl @@@ $ROOTDIR $RELDIR $START_ERL_DATA" > /dev/null 2>&1 &]]></code> <p>The following script illustrates a modification where the node is given the name <c>cp1</c>, and the environment variables <c>HEART_COMMAND</c> and <c>TERM</c> have been added to the above script. </p> <code type="none"><![CDATA[ #!/bin/sh # Usage: start [DataFile] # HEART_COMMAND=/usr/sbin/reboot TERM=sun export HEART_COMMAND TERM ROOTDIR=/usr/local/otp if [ -z "$RELDIR" ] then RELDIR=$ROOTDIR/releases fi START_ERL_DATA=${1:-$RELDIR/start_erl.data} $ROOTDIR/bin/run_erl /tmp/ $ROOTDIR/log "exec $ROOTDIR/bin/start_erl @@@ $ROOTDIR $RELDIR $START_ERL_DATA -heart -sname cp1" > /dev/null 2>&1 &]]></code> <p>If a diskless and/or read-only client node is about to start the <c>start_erl.data</c> file is located in the client directory at the master node. Thus, the <c>START_ERL_DATA</c> line should look like: </p> <code type="none"> CLIENTDIR=$ROOTDIR/clients/clientname START_ERL_DATA=${1:-$CLIENTDIR/bin/start_erl.data}</code> </section> <section> <title>run_erl</title> <p>This program is used to start the emulator, but you will not be connected to the shell. <c>to_erl</c> is used to connect to the Erlang shell. </p> <code type="none"> Usage: run_erl pipe_dir/ log_dir "exec command [parameters ...]"</code> <p>Where <c>pipe_dir/</c> should be <c>/tmp/</c> (<c>to_erl</c> uses this name by default) and <c>log_dir</c> is where the log files are written. <c>command [parameters]</c> is executed, and everything written to stdin and stdout is logged in the <c>log_dir</c>. </p> <p>In the <c>log_dir</c>, log files are written. Each logfile has a name of the form: <c>erlang.log.N</c> where N is a generation number, ranging from 1 to 5. Each logfile holds up to 100kB text. As time goes by the following logfiles will be found in the logfile directory</p> <code type="none"> erlang.log.1 erlang.log.1, erlang.log.2 erlang.log.1, erlang.log.2, erlang.log.3 erlang.log.1, erlang.log.2, erlang.log.3, erlang.log.4 erlang.log.2, erlang.log.3, erlang.log.4, erlang.log.5 erlang.log.3, erlang.log.4, erlang.log.5, erlang.log.1 ... </code> <p>with the most recent logfile being the right most in each row of the above list. That is, the most recent file is the one with the highest number, or if there are already four files, the one before the skip. </p> <p>When a logfile is opened (for appending or created) a time stamp is written to the file. If nothing has been written to the log files for 15 minutes, a record is inserted that says that we're still alive. </p> </section> <section> <title>to_erl</title> <p>This program is used to attach to a running Erlang runtime system, started with <c>run_erl</c>. </p> <code type="none"> Usage: to_erl [pipe_name | pipe_dir]</code> <p>Where <c>pipe_name</c> defaults to <c>/tmp/erlang.pipe.N</c>. </p> <p>To disconnect from the shell without exiting the Erlang runtime system, type <c>Ctrl-D</c>. </p> </section> <section> <title>start_erl</title> <p>This program starts the Erlang emulator with parameters <c>-boot</c> and <c>-config</c> set. It reads data about where these files are located from a file called <c>start_erl.data</c> which is located in the <c><![CDATA[<RELDIR>]]></c>. Each new release introduces a new data file. This file is automatically generated by the release handler in Erlang. </p> <p>The following script illustrates the behaviour of the program.</p> <code type="none"> #!/bin/sh # # This program is called by run_erl. It starts # the Erlang emulator and sets -boot and -config parameters. # It should only be used at an embedded target system. # # Usage: start_erl RootDir RelDir DataFile [ErlFlags ...] # ROOTDIR=$1 shift RELDIR=$1 shift DataFile=$1 shift ERTS_VSN=`awk '{print $1}' $DataFile` VSN=`awk '{print $2}' $DataFile` BINDIR=$ROOTDIR/erts-$ERTS_VSN/bin EMU=beam PROGNAME=`echo $0 | sed 's/.*\///'` export EMU export ROOTDIR export BINDIR export PROGNAME export RELDIR exec $BINDIR/erlexec -boot $RELDIR/$VSN/start -config $RELDIR/$VSN/sys $* </code> <p>If a diskless and/or read-only client node with the <c>sasl</c> configuration parameter <c>static_emulator</c> set to <c>true</c> is about to start the <c>-boot</c> and <c>-config</c> flags must be changed. As such a client can not read a new <c>start_erl.data</c> file (the file is not possible to change dynamically) the boot and config files is always fetched from the same place (but with a new contents if a new release has been installed). The <c>release_handler</c> copies this files to the <c>bin</c> directory in the client directory at the master nodes whenever a new release is made permanent. </p> <p>Assuming the same <c>CLIENTDIR</c> as above the last line should look like:</p> <code type="none"> exec $BINDIR/erlexec -boot $CLIENTDIR/bin/start @@@ -config $CLIENTDIR/bin/sys $* </code> </section> </section> </chapter>