Konfliktsituation WLan -> Netzwerkmounts -> Poweroff

Einrichten des lokalen Netzes, Verbindung zu anderen Computern und Diensten.
Antworten
TomL

Konfliktsituation WLan -> Netzwerkmounts -> Poweroff

Beitrag von TomL » 19.08.2015 17:32:04

Moin

Das bereits schon in diesem älteren Thread angesprochene Problem mit den Konflikten bei der Kombination Laptop + fstab + wlan0 + poweroff + wechselnde Netze mit oder ohne Home-Server hat mich jetzt doch einige Tage beschäftigt und war nicht so einfach zu lösen. Irgendwann ging es mir außerdem zusätzlich mächtig gegen den Strich, keine übertragbare Lösung für mehrere Plattformen zu haben und auf jede einzelne Maschine individuell reagieren zu müssen.

Am Ende haben sich dann diese Anforderungen für ein fehlerfreies Mounten der Netzlaufwerke wie von selber ergeben:
  • Eine Lösung (durch einfaches Kopieren) für alle Plattformen wie Desktops, Laptops/Notebooks, Raspberry Pi's, mehrere VM'S in unserer Netzwerkumgebung
  • Das Interface (eth0 oder wlan0) und die jeweils damit verbundenen eigenen Besonderheiten müssen berücksichtig werden
  • Keine Boot-Fehler-Nachrichten (mount failed), wenn die mobilen Geräte mit fremden öffentl. Netze verbunden sind und der Home-Server nicht oder noch nicht verfügbar ist
  • Kein minutenlanges Warten auf Stop-Jobs bei der Konflikt-Situation WLan + Poweroff, weil der umount nicht vor Close-WLan durchgeführt wird.
  • Keine mehrfachen Boot-Mount-Fehler in Journalctl wg. mehrerer Fehlversuche, weil die älteren PC mit ggf. langsamer älterer WiFi-HW ihre Zeit zum Verbinden brauchen
  • Behebung der fstab-Probleme beim Raspberry Pi, der manchmal via fstab gar nicht mountet, und manchmal doch
  • Lösung für fehlende _netdev-Unterstützung bei den Mount-Options (wg. CIFS)
  • Schnelles, unkompliziertes manuelles ein- und aushängen der mounts muss möglich sein, wenn der PC via öffentliches Netz und OpenVPN zum Homeserver verbunden ist/werden soll
Zusammengenommen haben sich da einige Probleme angesammelt, die mich schon einigermaßen gestört haben. Insbesondere bei den Raspberry's und dem alten Laptop habe ich festgestellt, dass das dort mit der fstab nicht so schnell klappt, wie es eigentlich notwendig wäre und das das dann öfter für viele Fehlermeldungen oder sogar vollständiges Fehlschlagen verantwortlich war. Bei dem hier folgenden Raspberry Pi 2 ist es fast verständlich (siehe Log-Zeiten), dass die mounts via fstab manchmal fehlschlugen und manchmal klappten. Vermutlich hängt das auch damit zusammen, dass der Server die Platten erst mal wecken muss, bevor der Client erfolgreich zum Zuge kommen kann. Gerade bei meinen PI's besteht dieser Umstand, weil /var/log zur Entlastung der SD-Card auf tmpfs gemountet und auf Platte gesichert wird. Gemäß der Anzeige aus "systemd-analyze plot" wird mountctrl so ziemlich als letztes gestartet, wenn das System idle ist, quasi unmittelbar vor multi-user.target... und trotzdem noch solche Zeiten. Aber erst jetzt mit mountctrl endet das Prozedere immer erfolgreich:

Code: Alles auswählen

root@RaspiTestPC:/home/thomas# journalctl | grep mountctrl
Aug 16 20:12:42 RaspiTestPC systemd[1]: Starting mountctrl (avoid mount + umount + stop-job-errors)...
Aug 16 20:12:42 RaspiTestPC systemd[1]: Started mountctrl (avoid mount + umount + stop-job-errors).
Aug 16 20:12:51 RaspiTestPC logger[575]: mountctrl: Interface eth0 is up! (after 3 Seconds wait)
Aug 16 20:12:56 RaspiTestPC logger[598]: mountctrl: Network is reachable! (after 5 Seconds wait)
Ich habe also jetzt die Lösung gefunden, die im Moment bei mir alle fstab-Probleme vollständig beseitigt.... einfach dadurch, dass ich die fstab auf den Clients vollständig abgelöst habe. Ich spare mir jetzt auch das individuelle Anpassen der fstab auf den Endgeräten, ich kopiere einfach die benötigten Files an die passende Stelle und bin binnen kürzester Zeit fertig mit dem Einrichten. Alle unsere Endgeräte sind jetzt ganz unkompliziert und ohne produzierte Fehlermeldungen nach dem Systemstart mit allen individuell benötigten Laufwerken verbunden. Das Problem mit den 120-Sek-Timeout-Stop-Jobs bei den Wifi's ist ebenfalls gelöst. Natürlich geht das alles nicht ganz ohne Rumfummeln.... ein bisschen was muss man schon tun. Die "auf dieser Maschine" benötigten Mount-Points in /media müssen natürlich vorhanden sein. Ebenso die für einzelnen User geltenden individuellen ~/.smbcredentials für den geschützen Zugriff auf das persönliche Server-Homedir.

Darüber hinaus müssen nur noch die benötigten Files kopiert werden:

Code: Alles auswählen

mountctrl                               das eigentliche Sript, zuständig für mount und umount
mountctrl.service                       der systemd-Service, der mountctrl startet und beendet
und evtl. auf den WLan-Geräten:

Code: Alles auswählen

mountctrl_lanoff_helper                 für WLan-Geräte, um die Mounts zu schließen, bevor das Interface wlan0 "down" ist
mountctrl_poweroff_helper.desktop       ein Desktop-Starter für WLan-Geräte, um die ordentliche Shutdown-Reihenfolge zu gewährleisten.
Das Script mountctrl wird von Systemd natürlich bei Systemstart automatisch ausgeführt und sorgt dafür, dass nach Abschluß der Bootphase im Heimnetzwerk alle Laufwerke ohne Fehlermeldungen verfügbar sind. Darüber hinaus kann das Script auch jederzeit manuell (als root) mit mountctrl start oder mountctrl stop gestartet werden, um z.B. unterwegs via OpenVPN nachträglich die Home-Laufwerke ein- und auszuhängen.
Zuletzt geändert von TomL am 19.08.2015 17:55:39, insgesamt 1-mal geändert.

TomL

Re: Konfliktsituation WLan->Netzwerkmounts->Poweroff

Beitrag von TomL » 19.08.2015 17:32:34

Teil 2... die benötigen Scripte und Files:

/usr/local/bin/mountctrl

Code: Alles auswählen

#!/bin/bash
#=============================================================================================================================
# mountctrl by TommyLu*gmx.de
#
# Script-Name    : mountctrl
# Version, Date  : V.6.3, 29.12.2015
#
# Descripton     : Controlled mounting and unmounting of network drives in corporation with fstab for local drives. Considering
#                : the interfaces eth0 and wlan0, whether they are open or closed and whether the needed server is reachable. Also
#                : automatically unmount the Networkdrives, if Network-Interface will be logical closed (see mountctrl_lanoff_helper).
#
#                                                                                                                  U    G    O
# Main-Script    : /usr/local/bin/mountctrl                                                     root:root   755    RWX  R-X- R-X
#
# Companion-Files: /etc/systemd/system/mountctrl.service                                        root:root   644    RW-  R--  R--
#                : /etc/NetworkManager/dispatcher.d/pre-down.d/mountctrl_lanoff_helper          root:root   700    RWX  ---  ---
#                : ~/Schreibtisch/mountctrl_poweroff_helper.desktop                                         755    RWX  R-X- R-X
#
# Requirements   : Policykit-authorization for manually start as non-root
#
# Usage as root  : mountctrl { start | stop | poweroff | restart | suspend}
# as non-root    : pkexec mountctrl { start | stop | poweroff | restart | suspend}
#
# Setup systemd  : 1. Script mountctrl: Search and Change IP 172.10.1.2 to your Server-IP. Customize mount-Directives.
#                : 2. as root
#                       umount -a
#                       systemctl enable mountctrl.service
#                       systemctl start mountctrl.service
#                       df -h                                                                   Check, that the mounts are done
#                       journalctl | grep mountctrl                                             Check messages (if needed)
#
# Setup sysvinit : 1. Script mountctrl: Search and Change IP 172.10.1.2 to your Server-IP. Customize mount-Directives.
#                : 2. as root
#                       nano /etc/rc.local
#                               logger -p warn "`basename $0`: Start mountctrl"                 insert
#                               /usr/local/bin/mountctrl start                                  dto.
#                       cat /var/log/syslog | grep mountctrl                                    Check messages after reboot (if needed)
#
#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#
# group sambauser       = Permit Public-Shares on Multi-User-PC for regular Users
# group downloaduser    = Permit Download-Shares for regular Users and for virtual User 'inet' and 'google'
#
#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
# Debug
# [[ -d /sys/class/net/eth0 ]] && [[ $(</sys/class/net/eth0/operstate) == up ]] && echo eth0 is on || echo eth0 is off
# [[ -d /sys/class/net/wlan0 ]] && [[ $(</sys/class/net/wlan0/operstate) == up ]] && echo wlan is on || echo wlan is off
# [[ ! -z "$(uname -a | grep slitaz)" ]] && echo slitazfound || echo notfound
# exit 0
#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

options_tom="credentials=/home/tom/.smbcredentials,uid=tom,gid=tom,rw,suid,dev,exec,async"
options_sambauser="credentials=/home/tom/.smbcredentials,uid=tom,gid=sambauser,rw,suid,dev,exec,async"
options_downloaduser="credentials=/home/tom/.smbcredentials,uid=tom,gid=downloaduser,rw,suid,dev,exec,async"
options_jessie="credentials=/home/jessie/.smbcredentials,uid=jessie,gid=jessie,rw,suid,dev,exec,async"
options_goofy="credentials=/home/goofy/.smbcredentials,uid=goofy,gid=goofy,rw,suid,dev,exec,async"
options_lupo="credentials=/home/lupo/.smbcredentials,uid=lupo,gid=lupo,rw,suid,dev,exec,async"

[ -z "$1" ] || JobToDo=$1

#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

case $JobToDo in
    start)
        InterfaceIsUp=""
        HomeNetIsConnect=-1

        i=0
        while [ "$InterfaceIsUp" == "" ]; do
            [[ -d /sys/class/net/eth0 ]] && [[ $(</sys/class/net/eth0/operstate) == up ]] && InterfaceIsUp="eth0"
            [[ -d /sys/class/net/wlan0 ]] && [[ $(</sys/class/net/wlan0/operstate) == up ]] && InterfaceIsUp="wlan0"

            [ $i -eq 10 ] || [ ! "$InterfaceIsUp" == "" ] && break

            i=$[$i+1]
            /bin/sleep 1
        done

        if [[ -z "$InterfaceIsUp" ]]; then
           logger -p warn "`basename $0`: No Network-Interface is started ($i Seconds wait)! Mount failed!"
           exit 1
        else
           logger -p warn "`basename $0`: Network-Interface is up! (IFCE:$InterfaceIsUp, after $i Seconds wait)"
        fi

        i=0
        while [ $HomeNetIsConnect -ne 0 ]; do
            ping -c1 -W1 -q 172.10.1.2 &>/dev/null
            HomeNetIsConnect=$?

            [ $i -eq 20 ] || [ $HomeNetIsConnect -eq 0 ] && break

            i=$[$i+1]
            /bin/sleep 1
        done

        if [[ $HomeNetIsConnect -eq 0 ]]; then
            logger -p warn "`basename $0`: Server is reachable! (RC:$HomeNetIsConnect, after $i Seconds wait)"
        else
            logger -p warn "`basename $0`: Can not handle mounts. Server is not reachable! (RC:$HomeNetIsConnect, after $i Seconds wait)"
            exit 1                                      # Offline
        fi

        #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        # Admin-Share's
        [ -d /media/HD_1 ] &&         [[ -z $(grep HD_1 /proc/mounts) ]] && mount //172.10.1.2/HD_1                 /media/HD_1          -t cifs  -o $options_tom
        [ -d /media/HD_2 ] &&         [[ -z $(grep HD_2 /proc/mounts) ]] && mount //172.10.1.2/HD_2                 /media/HD_2          -t cifs  -o $options_tom

        # Non-Public-Share's
        [ -d /media/Install ] &&      [[ -z $(grep Install /proc/mounts) ]] && mount //172.10.1.2/Install           /media/Install       -t cifs  -o $options_tom

        # Public Share's
        [ -d /media/var ] &&          [[ -z $(grep /media/var   /proc/mounts) ]] && mount //172.10.1.2/var          /media/var           -t cifs  -o $options_sambauser
        [ -d /media/DatenAlle ] &&    [[ -z $(grep DatenAlle    /proc/mounts) ]] && mount //172.10.1.2/DatenAlle    /media/DatenAlle     -t cifs  -o $options_sambauser
        [ -d /media/MailPublic ] &&   [[ -z $(grep MailPublic   /proc/mounts) ]] && mount //172.10.1.2/MailPublic   /media/MailPublic    -t cifs  -o $options_sambauser
        [ -d /media/MultiMedia ] &&   [[ -z $(grep MultiMedia   /proc/mounts) ]] && mount //172.10.1.2/MultiMedia   /media/MultiMedia    -t cifs  -o $options_sambauser
        [ -d /media/Downloads ] &&    [[ -z $(grep Downloads    /proc/mounts) ]] && mount //172.10.1.2/Downloads    /media/Downloads     -t cifs  -o $options_downloaduser

        # Private Share's
        [ -d /home/tom/SHome ] &&     [[ -z $(grep tom/SHome /proc/mounts) ]] && mount //172.10.1.2/homes/Daten     /home/tom/SHome      -t cifs  -o $options_tom
        [ -d /home/tom/SMail ] &&     [[ -z $(grep tom/SMail /proc/mounts) ]] && mount //172.10.1.2/homes/Mail      /home/tom/SMail      -t cifs  -o $options_tom

        [ -d /home/jessie/SHome ] &&  [[ -z $(grep jessie/SHome  /proc/mounts) ]] && mount //172.10.1.2/homes/Daten /home/jessie/SHome   -t cifs  -o $options_jessie
        [ -d /home/jessie/SMail ] &&  [[ -z $(grep jessie/SMail  /proc/mounts) ]] && mount //172.10.1.2/homes/Mail  /home/jessie/SMail   -t cifs  -o $options_jessie

        [ -d /home/goofy/SHome ] &&   [[ -z $(grep goofy/SHome   /proc/mounts) ]] && mount //172.10.1.2/homes/Daten /home/goofy/SHome    -t cifs  -o $options_goofy
        [ -d /home/goofy/SMail ] &&   [[ -z $(grep goofy/SMail   /proc/mounts) ]] && mount //172.10.1.2/homes/Mail  /home/goofy/SMail    -t cifs  -o $options_goofy

        [ -d /home/lupo/SHome ] &&    [[ -z $(grep lupo/SHome   /proc/mounts) ]] && mount //172.10.1.2/homes/Daten  /home/lupo/SHome     -t cifs  -o $options_goofy
        [ -d /home/lupo/SMail ] &&    [[ -z $(grep lupo/SMail   /proc/mounts) ]] && mount //172.10.1.2/homes/Mail   /home/lupo/SMail     -t cifs  -o $options_goofy

        exit 0
    ;;
#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    stop)
        sync
        sleep 3
        /etc/init.d/umountnfs.sh
        exit 0
    ;;
#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    poweroff)
        echo "Bitte warten! Der Computer wird in wenigen Sekunden ausgeschaltet."
        /usr/local/bin/mountctrl stop

        Shutdown=$(cat /proc/1/comm)

        if [[ "$Shutdown" == "init" ]]; then
            /sbin/shutdown -h now >/dev/null 2>&1

        else # if ["$Shutdown" == "systemd"]
#           read -p "weiter mit beliebiger Taste"
            /bin/systemctl poweroff -i >/dev/null 2>&1
        fi
        exit 0
    ;;
#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    restart)
        echo "Bitte warten! Der Computer wird in wenigen Sekunden neu gestartet."
        /usr/local/bin/mountctrl stop

        Shutdown=$(cat /proc/1/comm)

        if [[ "$Shutdown" == "init" ]]; then
            /sbin/shutdown -r now >/dev/null 2>&1

        else # if ["$Shutdown" == "systemd"]
            /bin/systemctl reboot -i >/dev/null 2>&1
        fi
        exit 0
    ;;
#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    suspend)
        echo "Bitte warten! Der Computer wird in wenigen Sekunden in den Ruhezustand versetzt."

        sync
        sleep 3

        Shutdown=$(cat /proc/1/comm)

        if [[ "$Shutdown" == "systemd" ]]; then
            /bin/systemctl suspend -i >/dev/null 2>&1

#       else if [[ "$Shutdown" == "init" ]]
#           /sbin/shutdown -r now >/dev/null 2>&1
        fi
        exit 0
    ;;
#--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    *)
        echo "Aufruf: $0 {start | stop | poweroff | restart | suspend}"
        echo "Job abgebrochen! Falsche oder fehlende Parameter"
        logger -p warn "`basename $0`: Job canceled! Wrong or missing parameters"
        exit 1
    ;;
esac

exit 0
#==========================================================================================================================================================================
Die systemd-Unit, die Start und Beenden von "mountctrl" durchführt
/etc/system/system/mountctrl.service

Code: Alles auswählen

[Unit]
Description=mountctrl (avoid mount + umount + stop-job-errors)

# Regular Clients (set as latest after smbd.service)
  After=network-online.target local-fs.target remote-fs.target smbd.service

# Raspberry Pi Client (without smbd.service)
# After=network-online.target local-fs.target remote-fs.target lightdm.service

Wants=network-online.target
Conflicts=shutdown.target

[Service]
RemainAfterExit=yes
Type=idle
ExecStart=/usr/local/bin/mountctrl start
ExecStop=/usr/local/bin/mountctrl stop
ExecReload=/usr/local/bin/mountctrl start

[Install]
WantedBy=multi-user.target
Für die Wlan-Clients noch die beiden zusätzlichen Files:
/etc/NetworkManager/dispatcher.d/pre-down.d/mountctrl_lanoff_helper

Code: Alles auswählen

#!/bin/bash

INTERFACE=$1
ACTION=$2

#Debug
#d=`date +%d-%m-%Y-%H-%M-%S`
#log=/var/log/MyDebugLog.txt
#echo $d    "mountctrl.helper: "$1 $2 >>$log

if [ "$INTERFACE" == "wlan0" ] || [ "$INTERFACE" == "eth0" ]; then
    case "${ACTION}" in
            up)
                    ;;
            down)
                    ;;
	    pre-down)
                    /usr/local/bin/mountctrl stop
                    ;;
            pre-up)
                    ;;

            post-down)
                    ;;

            *)
                    echo $"Usage: $0 {up | down | pre-up | pre-down | post-down}"
                    exit 1
    esac
else
    logger -p err "`basename $0`: Unknown Interface: $INTERFACE. Skip doing for mountctrl!"
fi

exit 0
#========================================================================================
Und der Desktop-Starter (der Icon-Verweis muss angepasst werden):
~/Schreibtisch/mountctrl_poweroff_helper.desktop

Code: Alles auswählen

[Desktop Entry]
Version=1.0
Type=Application
Exec=[sudo] /usr/local/bin/mountctrl poweroff
Icon=/usr/local/share/Icons/poweroff.jpg
StartupNotify=true
Terminal=true
Categories=Utility;
Name=Shutdown-Helper
Comment=Helper for Umount NFS-Shares before Wlan close
Path=
Die rc.local (etwas eingekürzt), falls sysvinit das Startsystem ist.

Code: Alles auswählen

#!/bin/sh -e

logger -p err "`basename $0`: Start mountctrl"
/usr/local/bin/mountctrl start

exit 0
Zuletzt geändert von TomL am 29.12.2015 19:47:35, insgesamt 21-mal geändert.

TomL

Re: Konfliktsituation WLan->Netzwerkmounts->Poweroff

Beitrag von TomL » 19.08.2015 17:35:04

Ich würde mich sehr freuen, wenn vielleicht jemand dazu eine Meinung hat, oder was sagt, wenn er einen Fehler bemerkt ... mit konstruktiver Kritik kann es nur besser werden. :wink:

TomL

Re: Konfliktsituation WLan -> Netzwerkmounts -> Poweroff

Beitrag von TomL » 09.09.2015 16:44:04

Moin

Wegen der fast 500 Lesezugriffe und keine "Mecker" scheint das Script ja nicht voll daneben zu sein. :hail: Nun ja, wegen aktuell veränderter Bedingungen auf meinem PC (kein systemd mehr und stattdessen der Schritt zurück auf sysvinit) lief das Script natürlich erst mal nicht mehr. Ich habs also noch mal angepackt und ein paar Dinge verändert, so das es jetzt sowohl mit systemd und auch mit sysvinit klar kommt.

Antworten