Problem mit dem Sichern von Verzeichnissen während der Ausführung von halt.local in OSS 12.1

Hallo sehr geehrte Damen und Herren,

ich weiß, dass die folgende Problembeschreibung etwas ausschweifend ist, aber ich habe keine Idee, wie ich es einfacher beschreiben soll. Das unten beschriebene Verfahren hatte unter OSS 11.4 tadellos funktioniert.

Ich habe OSS 12.1 auf eine CF-Karte installiert. Damit die Karte länger hält, liegen die Verzeichnisse, in denen periodisch geschrieben wird, jeweils in einem eigenen tmpfs. In der /etc/fstab sieht das dann so aus:


/dev/sda1 /                    ext2       acl,user_xattr        1 1
proc      /proc                proc       defaults              0 0
sysfs     /sys                 sysfs      noauto                0 0
debugfs   /sys/kernel/debug    debugfs    noauto                0 0
usbfs     /proc/bus/usb        usbfs      noauto                0 0
devpts    /dev/pts             devpts     mode=0620,gid=5       0 0

###############################################################################
# Temporäre Dateien werden im RAM angelegt
###############################################################################
tmpfs     /tmp                 tmpfs      rw,noexec,nosuid,nodev 0 0

###############################################################################
# Logdateien werden im RAM angelegt
###############################################################################
tmpfs     /var/log             tmpfs      rw,noexec,nosuid,nodev 0 0

###############################################################################
# Laufzeitinformationen verschiedener Prozesse im RAM ablegen
###############################################################################
tmpfs     /var/run             tmpfs      rw,noexec,nosuid,nodev 0 0

###############################################################################
# Daten, die für die Weiterverarbeitung vorgesehen sind, im RAM anlegen
###############################################################################
tmpfs     /var/spool           tmpfs      rw,noexec,nosuid,nodev 0 0

###############################################################################
# Drift der Echtzeituhr im RAM ablegen
###############################################################################
tmpfs     /var/lib/ntp/drift   tmpfs      rw,noexec,nosuid,nodev 0 0

###############################################################################
# Folding@Home
###############################################################################
tmpfs     /opt/folding@home    tmpfs      rw,nosuid,nodev        0 0

Der Inhalt dieser Verzeichnisse wird während des Bootens aus tar-Archiven entpackt. Das Skript zum Entpacken wird in /etc/init.d/boot.local aufgerufen.


#! /bin/sh
#
# Copyright (c) 2002 SuSE Linux AG Nuernberg, Germany.  All rights reserved.
#
# Author: Werner Fink, 1996
#         Burchard Steinbild, 1996
#
# /etc/init.d/boot.local
#
# script with local commands to be executed from init on system startup
#
# Here you should add things, that should happen directly after booting
# before we're going to the first run level.
#

/opt/dir_save_restore/bin/dir_restore_scr


Das Skript selbst sieht so aus:


#!/bin/bash

# Einstellungen laden #########################################################
source /opt/dir_save_restore/conf/dir_save_restore.conf

# dir_restore #################################################################
# Parameter 1 -> Quellpfad
# Parameter 2 -> Archivname
function dir_restore()
{
  # Das Archiv und Prüfsumme müssen vorhanden sein #######################
  if  -f "$ARCHIV_PFAD$2"  -a  -f "$ARCHIV_PFAD$2.md5" ]
  then
    # Prüfsumme muss stimmen #############################################
    /usr/bin/md5sum --quiet -c "$ARCHIV_PFAD$2.md5"
    if  0 -eq $? ]
    then
      # Archiv entpacken #################################################
      /bin/tar xzf "$ARCHIV_PFAD$2" --directory=/
      if  0 -eq $? ]
      then
        printf "%s --> %s
" "$2" "$1"
        return 0
      fi
    fi
  fi
  
  # Verzeichnis aus dem Backup-Archiv wiederherstellen ###################
  if  -f "$ARCHIV_PFAD$2.bak" ]
  then
    /bin/tar xzf "$ARCHIV_PFAD$2.bak" --directory=/
    if  0 -eq $? ]
    then
      printf "%s --> %s
" "$2.bak" "$1"
      return 0
    fi
  fi

  printf "Fehler bei der Wiederherstellung von:
  %s
" "$1"
  return 1
} # dir_restore

###############################################################################
RESULT=0

for EINTRAG in `echo ${QUELL_PFADE}`
do
  # Teil des Eintrags vor dem ':' ########################################
  QUELL_PFAD=`echo $EINTRAG | grep -o '^^:]*'`

  # Teil des Eintrags nach dem ':' #######################################
  ARCHIV=`echo $EINTRAG | grep -o '^:]*$'`

  dir_restore $QUELL_PFAD $ARCHIV
  if  0 -ne $? ]
  then
    RESULT=1
  fi
done

exit $RESULT


Die eingebundene Konfigurationsdatei gestaltet sich wie folgt:


###############################################################################
#            /opt/dir_save_restore/conf/dir_save_restore.conf                 #
###############################################################################
#                                                                             #
# In dieser Datei werden die Einstellungen für das Sichern und Wiederherstel- #
# len verschiedener Verzeichnisse festgelegt.                                 #
#                                                                             #
# Diese Datei wird jeweis von den Skripten dir_save_scr und dir_restore_scr   #
# eingebunden.                                                                #
#                                                                             #
# Das Skript /etc/init.d/dir_save_scr wird beim Herunterfahren des Systems    #
# von /etc/init.d/halt.local aufgerufen und sichert die angegebenen Verzeich- #
# nisse in den ebenfalls jeweils angegebenen tar-gz-Archiven.                 #
# Für die einzelnen Einträge werden jeweils folgende Aktionen ausgeführt:     #
#   - altes Archiv umbenennen durch Anhängen des Suffixes '.bak'              #
#   - Löschen der alten Prüfsummendatei                                       #
#   - Sichern des Verzeichnisses in das tar-gz-Archiv                         #
#   - Anlegen der neuen Prüfsummendatei                                       #
#                                                                             #
# Das Skript /etc/init.d/dir_restore_scr wird beim Start des Systems von      #
# /etc/init.d/boot.local aufgerufen und stellt den Inhalt der angegebenen     #
# Verzeichnisse aus dem Inhalt der tar-gz-Archive wieder her.                 #
# Für die einzelnen Einträge werden jeweils folgende Aktionen ausgeführt:     #
#   - Prüfsumme des Archivs prüfen                                            #
#   - Archiv entpacken                                                        #
# Wenn die Prüfsummendatei oder das Archiv nicht vorhanden sind oder die      #
# Prüfsumme nicht stimmt, wird versucht, das Verzeichnis aus dem Backuparchiv #
# wiederherzustellen.                                                         #
#                                                                             #
###############################################################################


###############################################################################
# Liste der Verzeichnisse. Jeder Eintrag steht in einer neuen Zeile und hat   #
# das folgende Format:                                                        #
#                                                                             #
#   VERZEICHNIS:ARCHIVNAME                                                    #
###############################################################################

QUELL_PFADE="\
  /var/log:var_log.tgz
  /var/spool:var_spool.tgz
  /var/lib/ntp/drift:var_lib_ntp_drift.tgz
  /opt/folding@home:folding@home.tgz"

###############################################################################
# In diesem Pfad werden die tar-gz-Archive abgelegt.                          #
###############################################################################

ARCHIV_PFAD="/opt/dir_save_restore/archives/"


Das Entpacken funktioniert einwandfrei.

Wenn das System heruntergefahren oder neugestartet wird, soll der Inhalt der Verzeichnisse wieder in ein tar-Archiv auf die CF-Karte zurückgeschrieben werden. Dazu wird ein Skript in /etc/init.d/halt.local aufgerufen:


#! /bin/sh
#
# Copyright (c) 2002 SuSE Linux AG Nuernberg, Germany.  All rights reserved.
#
# Author: Werner Fink, 1998
#         Burchard Steinbild, 1998
#
# /etc/init.d/halt.local
#
# script with local commands to be executed from init on system shutdown
#
# Here you should add things, that should happen directly before shuting
# down.
#

/opt/dir_save_restore/bin/dir_save_scr


Das Skript sieht so aus:


#!/bin/bash

# Einstellungen laden #########################################################
source /opt/dir_save_restore/conf/dir_save_restore.conf

# dir_save ####################################################################
# Parameter 1 -> Quellpfad
# Parameter 2 -> Archivname
function dir_save()
{
  printf "%s --> %s
" "$1" "$2"

  # Wenn das Archiv existiert, wird es mit dem Suffix '.bak' gesichert ###
  if  -f "$ARCHIV_PFAD$2" ]
  then
    mv "$ARCHIV_PFAD$2" "$ARCHIV_PFAD$2.bak"
  fi

  # Alte MD5 Prüfsumme löschen ###########################################
  if  -f "$ARCHIV_PFAD$2.md5" ]
  then
    rm "$ARCHIV_PFAD$2.md5"
  fi

  # Verzeichnis packen ###################################################
  /bin/tar cfz "$ARCHIV_PFAD$2" $1 --directory=/ 2> /dev/null

  # MD5 Prüfsumme erstellen ##############################################
  /usr/bin/md5sum "$ARCHIV_PFAD$2" > "$ARCHIV_PFAD$2.md5"

} # dir_save

###############################################################################

# Gegebenenfalls den Archivpfad anlegen #######################################
test -d "$ARCHIV_PFAD"
if  0 -ne $? ]
then
  mkdir $ARCHIV_PFAD
fi

# Verzeichnisse sichern #######################################################
for EINTRAG in `echo ${QUELL_PFADE}`
do
  # Teil des Eintrags vor dem ':' ########################################
  QUELL_PFAD=`echo $EINTRAG | grep -o '^^:]*'`

  # Teil des Eintrags nach dem ':' #######################################
  ARCHIV=`echo $EINTRAG | grep -o '^:]*$'`

  dir_save $QUELL_PFAD $ARCHIV
done


Wie bereits gesagt, hatte dieses Verfahren unter OSS 11.4 problemlos funktioniert. Unter OSS 12.1 enthalten die Archive nur den Zielpfad, aber keine Dateien mehr. Das Sichern der Verzeichnisse funktioniert aber erwartungsgemäß, wenn das Skript als Benutzer root aus einer Konsole aufgerufen wird.

Ich habe zwei Vermutungen. Erstens könnte es sein, dass zu dem Zeitpunkt wenn halt.local ausgeführt wird, die temporären Filesysteme nicht mehr zur Verfügung stehen. Der zweite Grund könnte ein Rechte-Problem sein.

Ich würde mich sehr darüber freuen, wenn mir jemand ein paar helfende Hinweise geben könnte.

Viele Grüße
Andreas

Hi Andreas,

mach doch mal ein “ls” in Dein halt.local script rein, um den Inhalt zum Zeitpunkt der Ausführung zu sehen, als debugging.
Krasse Konstruktion auf jeden Fall :wink:

Hallo matchi,

vielen Dank für Deine Antwort. Ich habe jetzt mal, so wie Du vorgeschlagen hattest, in boot.local und halt.local ein paar Debugzeilen eingefügt.
Die Ausgaben werden in Dateien umgeleitet.

boot.local:


/bin/ls -la /opt/folding@home > /vor_dem_entpacken.txt

/opt/dir_save_restore/bin/dir_restore_scr

/bin/ls -la /opt/folding@home > /nach_dem_entpacken.txt

und halt.local:


/bin/ls -la /opt/folding@home > /vor_dem_packen.txt

/opt/dir_save_restore/bin/dir_save_scr

Damit es etwas zu entpacken gibt, hatte ich die Backup-Archive auf die CF-Karte zurückkopiert.
Nach dem Booten und Anhalten des Systems habe ich dann folgende Dateien:

vor_dem_entpacken.txt


insgesamt 4
drwxrwxrwt 2 root root   40  2. Jul 14:15 .
drwxr-xr-x 4 root root 4096 28. Jun 08:55 ..

nach_dem_entpacken.txt


insgesamt 3792
drwxr-xr-x 3 root root     280 22. Jun 06:45 .
drwxr-xr-x 4 root root    4096 28. Jun 08:55 ..
-rwxr-x--- 1 root root     140 20. Jun 10:59 client.cfg
-rwx------ 1 root root  252676  5. Jul 2011  fah6
-rwxr-x--- 1 root root 3435296  5. Jul 2011  FahCore_78.exe
-rw-r--r-- 1 root root   51559 21. Jun 18:08 FAHlog-Prev.txt
-rw-r--r-- 1 root root   16263 29. Jun 15:31 FAHlog.txt
-rwxr-xr-x 1 root root      91 13. Jul 2011  folding
-rw-r--r-- 1 root root   89496 29. Jun 15:31 folding.log
-rw-r--r-- 1 root root       8  5. Jul 2011  machinedependent.dat
-rw-r--r-- 1 root root    1491  5. Jul 2011  MyFolding.html
-rw-r--r-- 1 root root    7168 20. Jun 10:59 queue.dat
-rw-r--r-- 1 root root     162 29. Jun 15:24 unitinfo.txt
drwxr-x--- 2 root root     480 29. Jun 15:31 work

und vor_dem_packen.txt


insgesamt 8
drwxr-xr-x 2 root root 4096  5. Jul 2011  .
drwxr-xr-x 4 root root 4096 28. Jun 08:55 ..

Ich kann mir das nur so erklären, dass das mit der Umstellung von SystemVInit in 11.4 auf systemd in 12.1 zusammenhängt. Der Inhalt der Pfade, welche in den RAM-Laufwerken liegen, ist während der Ausführung von halt.local nicht mehr vorhanden. Wenn man als Benutzer den Befehl ‘halt’ eingibt, wird nicht direkt das Skript /etc/init.d/halt sondern das Programm /bin/systemctl aufgerufen.


>which halt
/sbin/halt

>file /sbin/halt
/sbin/halt: symbolic link to `/bin/systemctl'

Da /etc/init.d/halt.local ziemlich vorn in /etc/init.d/halt aufgerufen wird, werden die temporären Verzeichnisse also schon vor der Ausführung von /etc/init.d/halt ausgehängt.
Ich denke mal, dass das ein Bug ist und habe einen Bugreport abgeschickt. Bin mal gespannt, was dabei herauskommt. In der Zwischenzeit begnüge ich mich mit 11.4.

Viele Grüße,
Andreas

Ich habe im systemd etwas gefunden:

systemctl -a|grep halt
halt-local.service        loaded inactive dead          /etc/init.d/halt.local Compatibility

Der Service ist deaktiviert (inactive)…
Probiere doch mal, diesen Service zu aktivieren (als root):

systemctl start halt-local.service

Hallo matchi,

zwischenzeitlich hatte mich ein wenig mit systemd beschäftigt. Die “alten” SystemV-Skripte werden zwar aus Kompatibilitätsgründen noch aufgerufen, aber die Umsetzung der zeitlichen Abhängigkeiten ist wahrscheinlich nicht so einfach. Das der “halt-local.service” nicht aktiv ist, ist richtig. Diese *.service Dateien sind Konfigurationsdateien des systemd und sind, von der Syntax her, vergleichbar mit INI-Dateien. Der “halt-local.service” wird beim Anhalten oder Neustarten des Systems einmalig ausgeführt. Wenn man mal in die Datei “/lib/systemd/system/halt-local.service” reinschaut, wird es schon etwas klarer.

Mein nächster Versuch wird sein, einen eigenen “service” für das Sichern meiner Verzeichnisse in “/lib/systemd/system/shutdown.target.wants” oder besser noch “/etc/systemd/system/shutdown.target.wants” zu hinterlegen. Wenn die tmpfs-Pfade dort auch schon nicht mehr zugreifbar sein sollten, dann hangle ich mich eben immer weiter nach oben.

Ich denke mal, über kurz oder lang werde ich mich mal intensiv mit dem Bootkonzept und systemd beschäftigen müssen.

Viele Grüße,
Andreas

Hallo Leute,

ich habe mein Problem lösen können. Das ursprüngliche Problem, dass die tmpfs-Pfade vor der Ausführung von /etc/init.d/halt.local ausgehängt werden, bleibt bestehen. Das scheint aber außer mir niemanden gestört zu haben. :wink:

Für den Fall, dass es jemanden interessiert, beschreibe ich noch kurz meine Lösung.

  • Die Datei /etc/init.d/halt.local ist jetzt wieder im Auslieferungszustand. Das heißt, ich habe meinen Code entfernt.
  • In “/etc/systemd/system” habe ich die beiden Verzeichnisse “shutdown.target.wants” und “reboot.target.wants” angelegt.
  • In “/etc/systemd/system/shutdown.target.wants/” habe ich eine Textdatei “tmpfs-folder-save.service” und einen gleichnamigen symbolischen Link auf diese Datei in “/etc/systemd/system/reboot.target.wants/” angelegt.

Die Datei “tmpfs-folder-save.service” hat folgenden Inhalt:


[Unit]
Description=Sichert den Inhalt der tmpfs-Verzeichnisse.
ConditionFileIsExecutable=/opt/dir_save_restore/bin/dir_save_scr
DefaultDependencies=no
Before=shutdown.target

[Service]
Type=oneshot
ExecStart=/opt/dir_save_restore/bin/dir_save_scr
StandardOutput=tty
TimeoutSec=0
RemainAfterExit=yes

Das war’s. Jetzt werden die Verzeichnisse, bevor der Rechner angehalten oder neugestartet wird, wieder korrekt in Archive gesichert. Als nächstes wäre dann mal das “/etc/init.d/boot.local”-Skript zu ersetzen, aber das funktioniert ja noch.

Viele Grüße,
Andreas

Hallo nochmal,

abschließend möchte ich noch mitteilen, dass mein Bug-Report erfolgreich bearbeitet wurde. In einer der nächsten Versionen des systemd-Pakets werden die Abhängigkeiten berichtigt sein. Dann werden die Laufwerke erst nach der Ausführung von “/etc/init.d/halt.local” ausgehängt werden. Vielen Dank nochmal an Herrn https://www.google.com/images/cleardot.gifFrederic Crozat vom SUSE-Team.

Viele Grüße,
Andreas

…und hier der Link zum Bug: https://bugzilla.novell.com/show_bug.cgi?id=769235