1.9 Booten, Rebooten, Einwählen und Auflegen unter fli4l-2.1

Unterabschnitte

- 1.9.1 Bootkonzept
- 1.9.2 Start-Scripts
  - 1.9.2.1 Hilfsfunktionen für Startupscripte
  - 1.9.2.2 opt/etc/boot.d/rc*.*
  - 1.9.2.3 opt/etc/prep/rc*.*
  - 1.9.2.4 opt/etc/rc.d/rc*.*
  - 1.9.2.5 Stop-Scripts
- 1.9.3 ttyI devices
- 1.9.4 Scripte beim Einwählen und Auflegen
  - 1.9.4.1 Variablen
  - 1.9.4.2 Default-Route

# 1.9 Booten, Rebooten, Einwählen und Auflegen unter fli4l-2.1

## 1.9.1 Bootkonzept

fli4l 2.0 sollte eine saubere Installation auf eine Festplatte oder ein CompactFlash(TM)-Medium bieten, aber auch eine Installation auf ein Zip-Medium oder die Erstellung einer bootfähigen CD-ROM sollte möglich sein. Zusätzlich sollte die Festplattenversion sich nicht grundlegend von einer Installation von Diskette unterscheiden.

Diese Anforderungen wurden realisiert, indem die Dateien des opt_tar.bz2 aus der bisherigen RAM-Disk auf eine anderes Medium verlagert werden können. Dies kann eine Partition auf einer Festplatte bzw. einem CF-Medium sein. Dieses zweite Volume wird nach /opt gemountet und von dort werden nur noch symbolische Links in das rootfs angelegt. Die Dateien in /opt/etc und /opt/var werden allerdings in das rootfs kopiert, damit hier keine Probleme auftreten können.

Die Anpassung betrifft aber noch weitere Details.

Die Dateien des opt.tgz (ab 2.1.5 opt_tar.bz2) werden nicht mehr direkt in das rootfs entpackt, sondern nach /opt. Damit kann man keine Dateien des rootfs mehr durch Dateien im opt.tgz (opt_tar.bz2) ersetzen lassen. Das opt_comfort für Fli4l-1.6.x nutzt diese Funktion um die Datei /.profile im rootfs durch eine eigene Version zu ersetzen. Dies ist bei einem opt-Paket für die 2.0 nur möglich, indem ein Script die Datei von /opt... an den gewünschten Ort kopiert. Im rootfs werden nur symbolische Links zu den Dateien in /opt erzeugt. Diese Links benötigen jeweils einen Inode (Index-Node, ein Dateiinformationsblock, kurz gesagt), von denen im rootfs ca. 500-900 verfügbar sind. Falls ein Verzeichnis im rootfs noch nicht existiert, wird es angelegt und im Verzeichnis werden Links auf die Dateien erzeugt.

## 1.9.2 Start-Scripts

Scripts, die beim booten des Systems ausgeführt werden sollen, befinden sich unter opt/etc/{boot.d,prep,rc.d} und werden auch in der Reihenfolge ausgeführt, also erst Dateien unter boot.d, dann unter prep (aus Kompatibilitätsgründen) und danach unter rc.d. Da zum Ausführen dieser Scripte kein separater Prozess erzeugt wird, dürfen sie nicht mit ``exit 0'' abgeschlossen werden. Ein exit würde zum Abbruch des Bootvorganges führen.

### 1.9.2.1 Hilfsfunktionen für Startupscripte

In /etc/boot.d/base-helper werden verschiedene Funktionen bereitgestellt, die von den Startup-Scripten verwendet werden können. Das betrifft Dinge wie Debug-Support, Module-Behandlung, Fehler-Meldungen oder Ersetzung symbolischer Referenzen. Die einzelnen Funktionen werden im folgenden aufgelistet und kurz beschrieben.

begin_script <symbol> <message>
  Gibt die Message aus und aktiviert das Script debugging mittels set -x, falls <symbol>_DO_DEBUG auf yes steht.
end_script
  Gibt eine Abschluss-Message aus und stellt den ursprünglichen Debug-Zustand wieder her.

do_insmod <module> <params>
  Laden das Moduls module mit den Parametern params
do_insmod_once <module> <params>
  Wie do_insmod, nur das sichergestellt wird, daß das Module nur einmal geladen wird.
do_insmod_if_exists module_path <module> <params>
  Prüft, ob das Module existiert (/usr/lib/<kernel version>/<module path>/module) existiert und führt wenn es da ist, do_insmod aus.
do_insmod_if_exists_once <module_path> <module> <params>
  Prüft, ob das Module existiert (/usr/lib/<kernel version>/<module path>/module) existiert und führt wenn es da ist und noch nicht geladen wurde, do_insmod aus.
mk_writable <file>
  Stellt sicher, daß die Dateil file schreibbar ist. Befindet sich das File auf einem Read-Only Dateisystem und ist lediglich über einen Softlink ins Dateisystem eingebunden, wird eine lokale Kopie angelegt, die dann schreibbar ist.
unique <elements>
  Erzeugt aus den Parametern eine Liste, in der Elemente nur einmal auftauchen. Die Liste wird in der Variable list zurückgegeben.
log_error <error message>
  Schreibt die Fehlermeldung auf die Konsole und nach /boot_messages.txt. Wird keine Fehlermeldung als Parameter übergeben, liest log_error von stdin.
set_error <error_message>
  Gibt die Fehlermeldung aus und setzt ein Fehlerflag, das später via is_error geprüft werden kann.
is_error
  Setzt das Error-Flag zurück und liefert wahr zurück, falls es gesetzt war.
translate_ip_net <value>
  Ersetzt symbolische Referenzen in Parametern. Momentan finden folgende Übersetzungen statt:
  ip adresse, netzwerk, none, default, pppoe, dynamic, Zahl
    Keine Übersetzung
  any
    Wird nach 0.0.0.0/0 übersetzt
  IP_NET_*
    wird durch das in der Konfiguration stehende Netzwerk ersetzt
  IP_NET_*_IPADDR
    wird durch die in der Konfiguration stehende IP-Adresse ersetzt
  IP_ROUTE_*
    wird durch die in der Konfiguration stehende Route ersetzt
  @<host name>
    wird durch die in der Konfiguration für den angegeben Host spezifizierte IP-Adresse ersetzt

  Nach dem Aufruf von translate_ip_net sollte man mit is_error prüfen, ob die Übersetzung korrekt erfolgt ist.

### 1.9.2.2 opt/etc/boot.d/rc*.*

Dateien, die in diesem Verzeichnis liegen, werden als erstes ausgeführt. Ihre Aufgabe ist es, das Boot-Device zu mounten, die rc.cfg einzulesen und das opt-Archive zu entpacken. Je nach Bootyp sind diese Scripte mehr oder weniger kompliziert und tun die folgenden Dinge:

- load drivers (optional)
- mount boot medium (optional)
- read rc.cfg
- extract/mount opt files (optional)
- run prep scripts (optional, for compatibility reasons)

### 1.9.2.3 opt/etc/prep/rc*.*

Wichtig: Prep-Scripts werden nur noch aus Kompatibilitätsgründen unterstützt und müssen bei Gelegenheit ersetzt werden (siehe rc.d).
Alle Dateien in opt/etc/prep werden nach dem Entpacken des opt_tar.bz2 aufgerufen. Damit können Dateien, die später auf der eventuell schreibgeschützten Partition liegen (/opt/), nach dem Entpacken bearbeitet werden. Dies betrifft zum Beispiel das Anlegen von Links, Umbenennen von Dateien und ähnliches. Die Dateinamen der prep-Scripts sollten dem OPT-Namen entsprechen, wobei hier die Startreihenfolge in der Regel nicht wichtig ist. Daher sollten Prep-Scripte rc400.<Opt-Name> heißen. Eine Verarbeitung der Konfiguration sollte hier jedoch noch nicht erfolgen, da sonst das Umkonfigurieren von OPTs ohne Austausch des opt_tar.bz2 (nur eine Bearbeitung der rc.cfg) unmöglich gemacht wird.

### 1.9.2.4 opt/etc/rc.d/rc*.*

Befehle, die immer beim Starten des Routers ausgeführt werden müssen, können in Scripts im Verzeichnis opt/etc/rc.d abgelegt werden. Hierbei gelten folgende Konventionen:

1. Es gilt folgende Namenskonvention: rc<dreistellige Zahl>.<Name des Opt's> Die Scripts werden in der Reihenfolge der Zahlen gestartet. Haben mehrere Scripts die gleiche Zahl, entscheidet die alphabetische Sortierung nach dem Punkt. Falls der Start eines Paketes erst nach einem anderen erfolgen darf, wird das durch die Zahl festgelegt.

   Hier eine ungefähre Richtlinie, welche Nummern für welche Aufgaben verwendet werden sollten:

   Nummer | Aufgabe
   000-099 | Grundsystem (mounten, Zeitzone)
   100-199 | Kernel-Module (Treiber)
   200-299 | externe Verbindungen (PPPoE, I4L, PPtP)
   300-399 | Netzwerk (Routing, Interfaces, Paketfilter)
   400-499 | Server (DHCP, HTTPD, Proxy, etc.)
   500-900 | Freeform, use as you wish
   900-997 | Alles, was eine Einwahl hervorrufen könnte
   998-999 | reserved (don't use)

2. In diesen Scripts müssen alle Funktionen, die das rootfs verändern hinterlegt werden. (z.B. das Anlegen eines Verzeichnisses /var/log/lpd)

3. In diesen Scripts dürfen keine Schreibzugriffe auf den Dateien erfolgen, die Teil des des opt-Archives sein können, da diese Dateien auf einem Read-Only-Medium liegen können. Muß man eine solche Datei modifizieren, muß man sie vorher via mk_writable file schreibbar machen. Durch den Aufruf der Funktion wird die Datei wenn nötig als schreibbare Kopie im rootfs abgelegt. Ist die Datei bereits schreibbar, bewirkt der mk_writable-Aufruf nichts.

   Wichtig: mk_writable muß direkt auf den Files im rootfs angewendet werden, nicht über den Umweg /opt. Will man also /usr/local/bin/foo modifizieren, ruft man mk_writable /usr/local/bin/foo auf und nicht mk_writable /opt/usr/local/bin/foo.

4. Diese Scripte müssen vor der Ausführung der eigentlichen Befehle prüfen, ob das dazugehörige OPT auch aktiv ist. Das ist normalerweise durch eine einfache if-Abfrage erledigt:

           if [ "$OPT_<OPT-Name>" = "yes" ]
           then
               ...
               # Hier OPT starten!
               ...
           fi

5. Um das debuggen zu erleichtern, sollten die Scripte mit begin_script name message und end_script geklammert werden:

           if [ "$OPT_<OPT-Name>" = "yes" ]
           then
               begin_script FOO ``configuring foo ...''
               ...
               end_script
           fi

   Das debuggen einzelner Startupscripte kann man dann einfach via FOO_DO_DEBUG='yes' aktivieren.

6. Diese Scripte dürfen nicht direkt auf die Datei rc.cfg zugreifen. Dies ist auch nicht notwendig, weil alle Variablen aus dieser Datei direkt verfügbar sind bis der Startvorgang beendet wurde. Im Abschnitt ``Umgang mit Konfigurationsvariablen'' wurde erklärt, wie man Variablen für eine spätere Nutzung abspeichern kann.

7. Der Pfad /opt darf auch nicht als Speicherplatz für Datenbestände des Opts benutzt werden. Falls zusätzlicher Speicherplatz benötigt wird ist eine eigene Ramdisk zu erstellen oder die Angabe eines Pfades über eine Variable zu ermöglichen.

### 1.9.2.5 Stop-Scripts

Jeder Rechner muss mal heruntergefahren oder neu gestartet werden. Nun kann es vorkommen, dass man noch etwas durchführen muss, bevor der Rechner heruntergefahren oder neu gestartet wird. Zum herunterfahren und neu starten sind die Befehle halt und reboot zuständig. Diese Befehle werden auch aufgerufen, wenn man im IMONC auf die entsprechenden Buttons klickt.

Alle Stop-Scripts liegen im Verzeichnis opt/etc/rc0.d/. Ihre Dateinamen werden analog zu den Startscripten gebildet.

## 1.9.3 ttyI devices

Für die ttyI devices (/dev/ttyI0 ... /dev/ttyI15), über die die ``Modem- Emulation'' der ISDN-Karte genutzt werden kann, existiert ein Zähler, um Konflikte zwischen verschiedenen Paketen, die diese Devices nutzen, zu vermeiden. Hierzu wird beim Start des Routers die Datei /var/run/next_ttyI angelegt, die von den verschiedenen Addons abgefragt und fortgezählt werden muß. Mit dem folgenden Beispielscript kann dieser Wert abgefragt, um eins erhöht und wieder für das als nächstes startende Addon exportiert werden.

    ttydev=`cat /var/run/next_ttyI`
    if [ "$ttydev" -le 16 ]
    then                                    # ttyI device available? yes
        ttydev=`/usr/bin/expr $ttydev + 1`  # ttyI device + 1
        echo $ttydev >/var/run/next_ttyI    # und wieder abspeichern
    else                                    # ttyI device available? no
        /usr/local/bin/colecho "*** ERROR: no ttyI device for \
        <Name deines Addons> available ! ***" br x br
        sleep 10                            # wait, so user can read message
        ttydev_error=true                   # set error for later use
    fi

    if [ "$ttydev_error" != true ]          # start addon only if next tty device
                                            # was available to minimize error
    then                                    # messages and minimize the
        ....                                # risk of uncomplete boot
    fi

## 1.9.4 Scripte beim Einwählen und Auflegen

Nach dem Herstellen einer Dial-Up-Verbindung werden die Scripte unter /etc/ppp abgearbeitet. Hier können Opt-Pakete als Aktionen ausführen, die nach dem Herstellen der Verbindung bzw. nach dem Auflegen nötig sind. Benannt werden die Dateien wie folgt:

ip-up<dreistelligenummer>.<OPT-Name> | Wird beim Verbinden ausgeführt
ip-down<dreistelligenummer>.<OPT-Name> | Wird nach dem Trennen der Verbindung ausgeführt

In den ip-down-Scripts dürfen keine Aktionen ausgeführt werden, die zu einer erneuten Internet-Einwahl führen würden, da dadurch nur ein Dauer-Online-Zustand erreicht wird, was für Nicht-Flatrate-Benutzer ein teures Unterfangen ist.

Da für die einzelnen Scripte kein eigener Prozeß erzeugt wird, dürfen auch diese Scripts nicht mit ``exit 0'' abgeschlossen werden.

Hinweis: Wenn ein Script prüfen will ob überhaupt die ip-up Skripte ausgeführt werden kann es ab rc321 die Variable ''ip_up_events'' prüfen. Steht diese auf ''yes'' laufen die ip-up Skripte. Steht dort ein ''no'' laufen keine ip-up Skripte.

### 1.9.4.1 Variablen

Durch das spezielle Aufrufkonzept stehen alle Variablen aus der ip-up/ip-down auch in den einzelnen Scripts zur Verfügung. Folgende Variablen sind verfügbar:

$real_interface | Das aktuelle Interface, also z.B. ppp0, ippp0, ...
$interface | Das IMOND-Interface, also pppoe, ippp0, ...
$tty | Verbundenes Terminal... Möglicherweise leer!
$speed | Die Verbindunggeschwindigkeit, bei ISDN Z.B. 64000
$local | Die eigene IP-Adresse
$remote | Die IP-Adresse des Point-To-Point-Partners
$is_default_route | Gibt an, ob das aktuelle ip-up/down für das Interface durchgeführt wird, welches gerade die Default-Route hat (kann ``yes'' oder ``no'' sein)

### 1.9.4.2 Default-Route

Seit Version 2.1.0 werden die ip-up/down-Scripts nicht nur für das Default- Route-Interface gestartet, sondern für alle Verbindungen, die die ip-up/down- Scripts aufrufen. Um das alte Verhalten zu simulieren, muß in ip-up/down Scripts eine solche Abfrage eingefügt werden:

            # is a default-route-interface going up?
            if [ "$is_default_route" = "yes" ]
            then
                    # die eigentlichen Aktionen
            fi

Natürlich darf das neue Verhalten auch für spezielle Aktionen ausgenutzt werden.

Das Fli4l-Team
23. Februar 2006