Subsections

8.4 Creating Scripts for fli4l

The following is not a general introduction to shell scripts, everyone can read about this topic on the Internet. It is only about the flil4-specific things. Further information is available in the various *nix/Linux help pages. The following links may be used as entry points to this topic:

8.4.1 Structure

In the *nix world, it is necessary to begin a script with the name of the interpreter, hence the first line is:

      #!/bin/sh

To easily recognize later what a script does and who created it, this line should now be followed by a short header, like so:

      #--------------------------------------------------------------------
      # /etc/rc.d/rc500.dummy - start my cool dummy server
      #
      # Creation:     19.07.2001 Sheldon Cooper  <sheldon@nerd.net>
      # Last Update:  11.11.2001 Howard Wolowitz <howard@nerd.net>
      #--------------------------------------------------------------------

Now for the real stuff to start...


8.4.2 Handling of Configuration Variables

Packages are configured via the file config/<PACKAGE>.txt. The active variables contained there are transferred to the file rc.cfg during creation of the medium. This file is processed during router boot before any rc-script (scripts under /etc/rc.d/) gets started. The script then may access all configuration variables by reading the content of $<variable name>.

If the values of configuration variables are needed after booting the may be extracted from /etc/rc.cfg to which the configuration of the boot medium was written during the boot process. If for example the value of the variable OPT_DNS should be processed in a script this can be achieved as follows:

    eval $(grep "^OPT_DNS=" /etc/rc.cfg)

This works efficiently also with multiple variables (with calling the grep program only once):

    eval $(grep "^\(HOSTNAME\|DOMAIN_NAME\|OPT_DNS\|DNS_LISTEN_N\)=" /etc/rc.cfg)


8.4.3 Persistent Data Storage

Occasionally a package needs the possibility to store data persistent, surviving the reboot of the router. For this purpose, the function map2persistent exists and can be called from a script in /etc/rc.d/. It expects a variable that contains a path and a subdirectory. The idea is that the variable is either describing an actual path - then this path is used because the user explicitely has done so, or the string ``auto'' - then a subdirectory on a persistent medium is created corresponding to the second parameter. The function returns the result in the variable passed by name as the first parameter. An example will make this clear. VBOX_SPOOLPATH is a variable, that 'contains a path or the string ``auto'' . The call

    begin_script VBOX "Configuring vbox ..."
    [...]
    map2persistent VBOX_SPOOLPATH /spool
    [...]
    end_script

results in the variable VBOX_SPOOLPATH either not being changed at all (if it contains a path), or being changed to /var/lib/persistent/vbox/spool (if it contains the string ``auto''). /var/lib/persistent then points8.6 to a directory on a non-volatile and writable storage medium, <SCRIPT> is the name of the calling script in lowercase (this name is derived from the first argument of the begin_script-call). If no suitable medium should exist (which may well be), /var/lib/persistent is a directory in the RAM disk.

Please note that the path returned by map2persistent is not created automatically - The caller has to do that by himself (ie. by calling mkdir -p <path>).

The file /var/run/persistent.conf allows for checking if persistent data storage is possible. Example:

    . /var/run/persistent.conf
    case $SAVETYPE in
    persistent)
        echo "persistent data storage is possible!"
        ;;
    transient)
        echo "persistent data storage is NOT possible!"
        ;;
    esac


8.4.4 Debugging

For startup scripts it is often useful to run them in debug mode in a shell when you are in need to determine where they fail. For this purpose, insert the following at the beginning and at the end:

      begin_script <OPT-Name> "start message"
      <script code>
      end_script

At the start and at the end of the script the specified text will now appear, preceded by ``finished''.

If you want to debug the scripts, you must do two things:

  1. You have to set DEBUG_STARTUP to ``yes''.
  2. You have to activate debugging for the OPT. This is usually done by the entry
          <OPT-Name>_DO_DEBUG='yes'
    
    in the config file.8.7 What happens during runtime is now displayed in detail on screen.

8.4.4.1 Further Variables helpful for Debugging

DEBUG_ENABLE_CORE

This variable allows the creation of ``Core-Dumps''. If a program crashes due to an error an image of the current state in the file system is stored which can be used to analyse the problem. The core dumps are stored under /var/log/dumps/.

DEBUG_IP

Activating this variable will log all calls of the program ip.

DEBUG_IPUP

Setting this variable to ``yes'' will log all executed instructions of the ip-up- and ip-down-scripts to syslog.

LOG_BOOT_SEQ

Setting this variable to ``yes'' will cause bootlogd to log all console output during boot to the file /var/tmp/boot.log. This variable has ``yes'' as a default value.

DEBUG_KEEP_BOOTLOGD

Normally bootlogd is terminated at the end of the boot process. Activating this variable prevents this and thus allows for logging console output during the whole runtime.

DEBUG_MDEV

Setting this variable generates a logfile for the mdev-daemon, which is responsible for creating device nodes under /dev.

8.4.5 Hints



Footnotes

... points8.6
by the use of a so-called ``bind''-mount
... file.8.7
Sometimes multiple start-scripts are used, which then have different names for their debug-variables. Have a quick look at the scripts for clarification.
© 2001-2019 The fli4l-Team - 28 April 2019