LiMePlug Projekt

LiMePlug Logo

LiMePlug Logo

LiMeWas?!

LiMePlug steht für „Linux Media Plug“.

Das Bedürfnis

Die inzwischen bei uns in der Firma viel verwendete „Universalplattform“ mit der installierten Software „Carbon Coder“ (zur Umwandlung von Audio/Video jeglicher Art) läuft unter Windows. Dort werden angeschlossene Medien bekannter weise als Laufwerksbuchstaben in das Dateisystem eingebunden. Leider hat dieses System einige Schwächen, die man nun mit dem „LiMePlug“ elegant umgehen kann. Es kann beispielsweise vorkommen, dass Laufwerkbuchstaben mehrfach vergeben werden. Dies führt, erwartungsgemäss, zu komischen Effekten. Ausserdem können z.B. mehrere eingesteckte USB-Sticks nicht in jedem Fall einfach auseinander gehalten werden. Dann treten Fragen auf wie: „Welcher USB-Stick ist noch in Benutzung, welchen kann ich bereits abmelden und dem Kunden mitgeben?!“. Da wir Techniker möglichst Nerven schonend mit den Unmengen von Hardware/Software umgehen möchten, suchte ich eine Lösung. Ein interessantes, lehrreiches Projekt entstand schlussendlich daraus.

Die Lösung

Bei Linux (wie bei allen anderen Unix-Systemen) gibt es keine Laufwerk-Buchstaben. Der LiMePlug bindet die Datenträger nach einem eigens dafür definierten Verzeichnis-Muster in das System ein. Ein Programm Merkt sich, an welchem USB- oder Firewire-Anschluss ein Datenträger angeschlossen wurde. Anschliessend erkennt es die Partitionen auf dem Datenträger, ihre Dateisysteme und deren Namen. Aus diesen Informationen wird ein Ordner-Name generiert, über den die Partition dann zugänglich gemacht wird. Nun weiss man also immer, von welchem Datenträger man gerade etwas Kopiert, da man ja sehen kann, wo dieser angeschlossen ist. Die Anschlüsse sind darum natürlich auch entsprechend gekennzeichnet. Unter Windows wird dann nur noch ein Netzlaufwerk auf den LiMePlug verbunden, in dem die angeschlossenen Datenträger erscheinen und beim Entfernen wieder verschwinden (in Form von Verzeichnissen).

LiMePlug-Front-Anschluesse

Installiert wurde das System auf einem ASUS Barebone (AS S1-AT5NM10E), der bereits über USB/FW-Anschlüsse und ein SD-Card Reader auf der Frontseite verfügt.

LiMePlug-Front

Ich werde hier erst die wichtigen Facts zusammentragen und dann auf die konkrete Lösung eingehen. Zentral sind die Funktionen von Udev und die entsprechenden Udev-Rules. Zusätzlich werden vor allem Shell-Scripts verwendet, um Aufgaben zu erledigen, die nicht direkt mit Udev-Rules erledigt werden können. Die Scripte sind speziell auf diese Hardware angepasst – d.h. die Adressen für USB/FW-Ports werden ziemlich sicher bei Benutzung anderer Hardware nicht übereinstimmen.

USB3

Leider hatte ich noch keine Zeit, die Scripte USB3-Tauglich zu machen. Da USB3-Geräte komplett anders Adressiert werden, kann das Script solche Hardware momentan nicht erkennen! Wer eine Idee hat, darf mir das gerne mitteilen.

System und installierte Software-Packete

Ich verwende ein Debian GNU/Linux 4 (Etch) in einer Minimal-Variante (ohne grafische Oberfläche usw.). Die „Etch“-Release ist seid 2012 abgelöst und sollte nicht mehr verwendet werden. Jedoch sollte dieses Projekt ohne Probleme auf die aktuelle Debian-Version übernommen werden können.

Grundlegende Packete

hfsprogs gparted hal dosfstools modconf ntfs-3g ntfsprogs mc samba samba-common 
gpm lynx sg3-utils ssh autofs4 nodev nfs-kernel-server ntp ntpdate nodev 
sshfs curlftpfs pmount ivman

Kurze Beschreibung

gpm: Maus auf der Console (Server)
lynx: Kommandozeilen-Webbrowser (für Testzwecke praktisch)
ssh: MetaPacket SSH-Client/Server
curlftpfs: Möglichkeit zum Mounten von FTP-Shares (Achtung: Version 0.9.1-3 hat ein Bug:Grosse Dateien).

modconf (Kernel-Module)

Mit Hilfe von modconf sollten einige Kernel-Module geladen werden.

FS (Filesystems)

kernel/fs/msdos (DOS-FAT)
 kernel/fs/reiserfs
 kernel/fs/ext2
 kernel/fs/ext3
 kernel/fs/hfsplus (Mac OS X)
 kernel/fs/hfs (Mac vor OS X)
 kernel/fs/ntfs (Microsoft NTFS)
 kernel/fs/isofs (ISO-9660 CD-ROM Dateisystem)
 kernel/fs/udf (DVD)

Drivers

kernel/drivers/pcmcia/pcimcia_core
 kernel/drivers/block/loop
 kernel/drivers/usb/storage/usb-storage
 kernel/drivers/mmc/card/mmc_block (MMC Block-Device Driver)
 kernel/drivers/mmc/core/mmc_core
 kernel/drivers/memstick/core/memstick
 kernel/drivers/memstick/core/mspro_core
 scsi/sd_mod
 scsi/sg

Verzeichnisse

Root-Verzeichnis für LimePlug und die darunter liegenden Sub-Folder

/root/limeplug-script                               (LimePlug Scripts)
                     /config                        (Config für die Scripts)
                     /temp                         (8MB RamDisk unter /dev/ram0 8MB)
                     /web                           (Web-Root für die LiemePlug Seiten)
                         /config                    (Webseiten Config-Dateien)
                         /info-ramdisk            (XML-Files mit LimePlug Status /dev/ram1 8MB)
/media/LOGFILES                                     (Platz für Logfiles - Ohne das Verz. läuft das Script nicht!)

 /etc/samba/smb.conf

Natürlich braucht es auf dem LiMePlug die erwähnte Windows-Freigabe, damit auf den anderen PC’s ein Netzlaufwerk verbunden werden kann. Hier eine Idee für die Konfiguration.

#======================= Global Settings =======================

[global]

## Browsing/Identification ###

# Change this to the workgroup/NT-domain name your Samba server will part of
   workgroup = MYDOMAIN

# server string is the equivalent of the NT Description field
   server string = %h server on Linux

#### Debugging/Accounting ####

# This tells Samba to use a separate log file for each machine
# that connects
   log file = /var/log/samba/log.%m

# Cap the size of the individual log files (in KiB).
   max log size = 1000

# If you want Samba to only log through syslog then set the following
# parameter to 'yes'.
#   syslog only = no

# We want Samba to log a minimum amount of information to syslog. Everything
# should go to /var/log/samba/log.{smbd,nmbd} instead. If you want to log
# through syslog you should set the following parameter to something higher.
   syslog = 0

# Do something sensible when Samba crashes: mail the admin a backtrace
   panic action = /usr/share/samba/panic-action %d

####### Authentication #######

# "security = user" is always a good idea. This will require a Unix account
# in this server for every user accessing the server. See
# /usr/share/doc/samba-doc/htmldocs/Samba3-HOWTO/ServerType.html
# in the samba-doc package for details.
  security = user

# Enable Guest-Account (im SRG-Netzwerk ok)
;  guest account = nobody

# You may wish to use password encryption.  See the section on
# 'encrypt passwords' in the smb.conf(5) manpage before enabling.
   encrypt passwords = true

# If you are using encrypted passwords, Samba will need to know what
# password database type you are using. 
   passdb backend = tdbsam

   obey pam restrictions = yes

# This boolean parameter controls whether Samba attempts to sync the Unix
# password with the SMB password when the encrypted SMB password in the
# passdb is changed.
   unix password sync = yes

# For Unix password sync to work on a Debian GNU/Linux system, the following
# parameters must be set (thanks to Ian Kahan <<kahan@informatik.tu-muenchen.de> for
# sending the correct chat script for the passwd program in Debian Sarge).
   passwd program = /usr/bin/passwd %u
   passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .

# This boolean controls whether PAM will be used for password changes
# when requested by an SMB client instead of the program listed in
# 'passwd program'. The default is 'no'.
   pam password change = yes

#======================= Share Definitions =======================

[LiMePlug]
        comment = LiMePug MediaShare
        path = /media
        browseable = yes
        read only = no
        writable = yes
;       public = yes
        guest ok = yes
        create mask = 0777
        directory mask = 0777

# Un-comment the following and create the profiles directory to store
# users profiles (see the "logon path" option above)
# (you need to configure Samba to act as a domain controller too.)
# The path below should be writable by all users so that their
# profile directory may be created the first time they log on
[profiles]
   comment = Users profiles
   path = /home/samba/profiles
   guest ok = no
   browseable = no
   create mask = 0600
   directory mask = 0700

/etc/init.d/mountall.sh

Dieses File wird beim booten aufgerufen und abgearbeitet. Hier können wir den Befehl zum erstellen eines Dateisystems integrieren. Zu Gunsten der Übersichtlichkeit, erledigen wird das Mounten über /etc/fstab.
Den Fett gedruckten Teil in die mountall.sh einfügen (ziemlich am Anfang – ab Zeile 18).

. /lib/lsb/init-functions
 . /lib/init/mount-functions.sh

# RamDisk mit ext2 Filesystem befüllen
 mke2fs /dev/ram0
 mke2fs /dev/ram1

 # for ntfs-3g to get correct file name encoding
 if [ -r /etc/default/locale ]; then
     . /etc/default/locale
     export LANG
 fi

Berechtigung wird nicht verwendet!

Ev. muss für eine Ramdisk die Berechtigung angepasst werden (direkt per Init-Script):

[root]# chown limeplug:root /mnt/rd
[root]# chmod 0770 /mnt/rd
[root]# ls -ald /mnt/rd
drwxrwx---    2 van     root         4096 Dec  8 11:09 /mnt/rd

fstab ergänzen

Folgende Zeilen in der fstab für das Mounten der RamDisks ergänzen:

/dev/ram0    /root/limeplug-script/temp    ext2    defaults    0    0
/dev/ram1    /root/limeplug-script/web/info-ramdisk    ext2    defaults    0    0

Das Resultat kontrollieren

mount | grep ram0
/dev/ram0 on /mnt/rd type ext2 (rw)
df -h | grep ram0
/dev/ram0              16M   13K   16M   1% /mnt/rd

ACPI

Da der PC voraussichtlich keine Tastatur hat, muss das problemlose Runterfahren per Power-Knopf gewährleistet werden.
acpid:

/etc/acpi/events/powerbtn 
/etc/acpi/powerbtn.sh

Die Scripte kann man mit eigenen Befehlen befüllen. z.B.:

shutdown -h now

Eventuell muss das richtige Event noch mit

/usr/bin/acpi_listen

ermittelt werden.

Achtung, dieser Testmodus hindert aber nicht den acpid am Ausführen der entsprechenden action-Skripte, zBsp Herunterfahren.

LimePlug Script Configuration

usb-port.conf

Da die Anschlüsse je nach Hardware variieren können, habe ich die Konfiguration für die USB-Ports ausgelagert. Die Adressierung beim verwendeten ASUS Barebone, sieht so aus:

USB-FRONT-PORT1            usb 5-6 (Oben)
USB-FRONT-PORT2            usb 5-5 (Unten)
USB-REAR-PORT1             usb 5-4 (links Oben)
USB-REAR-PORT2             usb 5-3 (links Unten)
USB-REAR-PORT3             usb 1-1 (rechts Oben bei Netzwerk) - Tastatur
USB-REAR-PORT4             usb 1-2 (rechts Unten bei Netzwerk) - Maus
CARD-FRONT                 usb 5-7
FW-FRONT-PORT1             scsi fw-host0

Hier das entsprechende Config-File (port.conf):

USBFRONTDEV01A="5-6:1.0" # USB-FRONT1 (oben) - Für USB-Medien (Stick, HDD's)
USBFRONTDEV01B="5-6"USBFRONTDEV02A="5-5:1.0" # USB-FRONT2 (unten) - Für USB-Medien (Stick, HDD's)
USBFRONTDEV02B="5-5"USBFRONTDEV03A="5-7:1.0" # USB-INTERN (front) - Card Reader intern
USBFRONTDEV03B="5-7"USBFRONTDEV04A="5-4:1.0" # USB-REAR1 (oben links)
USBFRONTDEV04B="5-4"USBFRONTDEV05A="5-3:1.0" # USB-REAR2 (unten links) - P2 CardReader (reserviert)
USBFRONTDEV05B="5-3"

Udev

Jetzt sollte man sich vertieft über die Möglichkeiten des Kernels im Zusammenhang mit Hardware informieren.

– Der Kernel lädt Treiber nach den Angaben der Hardware (VendoeID, DeviceID…)
– Udev wird per User-Event (Uevent) darüber informiert und lädt die Rules, die dazu passen.

Einbinden neuer Hardware und erstellen der Rules für Udev

Um zu erfahren, wo und wie neue Hardware eingebunden und erkannt wird, gibt es zu Udev diverse Hilfsmittel. Dazu gehört z.B. udevadm (Udev-Admin). Damit lassen sich u.A. in realtime die Events anzeigen:

udevadm monitor

Die übergebenen Atribute können dann mit dem Befehl

udevinfo -a -p /sys/devices/pci... ... ...

angezeigt werden. Der Pfad (sys/device…) kann dabei aus udevadm monitor entnommen werden.

Hardware-Beispiele aus udevinfo

Sony XDCAM (PDW-U1 USB-Laufwerk)

  looking at device '/devices/pci0000:00/0000:00:1d.7/usb5/5-5/5-5:1.0/host131/target131:0:0/131:0:0:0':
    KERNEL=="131:0:0:0"
    SUBSYSTEM=="scsi"
    DRIVER=="sd"
    ATTR{device_blocked}=="0"
    ATTR{type}=="7"
    ATTR{scsi_level}=="0"
    ATTR{vendor}=="SONY    "
    ATTR{model}=="PDW-U1          "
    ATTR{rev}=="2450"
    ATTR{state}=="running"
    ATTR{timeout}=="75"
    ATTR{iocounterbits}=="32"
    ATTR{iorequest_cnt}=="0x3"
    ATTR{iodone_cnt}=="0x3"
    ATTR{ioerr_cnt}=="0x2"
    ATTR{modalias}=="scsi:t-0x07"
    ATTR{evt_media_change}=="0"
    ATTR{queue_depth}=="1"
    ATTR{queue_type}=="none"
    ATTR{max_sectors}=="240"

 Panasonic P2 (AJ-PCD20)

 looking at device '/devices/pci0000:00/0000:00:1d.7/usb5/5-4/5-4:1.0/host130/target130:0:0/130:0:0:0':
    KERNEL=="130:0:0:0"
    SUBSYSTEM=="scsi"
    DRIVER=="sd"
    ATTR{device_blocked}=="0"
    ATTR{type}=="0"
    ATTR{scsi_level}=="0"
    ATTR{vendor}=="MATSHITA"
    ATTR{model}=="AJ-PCD20  #1    "
    ATTR{rev}=="1.00"
    ATTR{state}=="running"
    ATTR{timeout}=="30"
    ATTR{iocounterbits}=="32"
    ATTR{iorequest_cnt}=="0xc"
    ATTR{iodone_cnt}=="0xc"
    ATTR{ioerr_cnt}=="0x3"
    ATTR{modalias}=="scsi:t-0x00"
    ATTR{evt_media_change}=="0"
    ATTR{queue_depth}=="1"
    ATTR{queue_type}=="none"
    ATTR{max_sectors}=="240"

HAL-Events beim add/remove bei XDCAM und P2-Laufwerken

lshal --monitor
 

Start monitoring devicelist:
-------------------------------------------------
15:11:32.020: storage_model_PDW_U1 property storage.removable.media_available = false
15:11:32.024: storage_model_PDW_U1 property storage.partitioning_scheme = ''
15:11:32.101: volume_label_Sony_XDCAM removed
15:12:16.030: storage_model_PDW_U1 property storage.removable.media_available = true
15:12:19.896: storage_model_PDW_U1 property storage.partitioning_scheme = 'none'
15:12:19.949: volume_label_Sony_XDCAM added
15:12:56.069: storage_model_AJ_PCD20___1 property storage.removable.media_available = true
15:12:56.089: storage_model_AJ_PCD20___1 property storage.partitioning_scheme = 'mbr'
15:12:56.097: storage_model_AJ_PCD20___1 property storage.removable.media_size = 31675383808 (0x760000000) (new)
15:13:06.013: storage_model_AJ_PCD20___1 property storage.removable.media_available = false
15:13:06.015: storage_model_AJ_PCD20___1 property storage.partitioning_scheme = ''
15:13:32.069: storage_model_AJ_PCD20___2 property storage.removable.media_available = true
15:13:32.088: storage_model_AJ_PCD20___2 property storage.partitioning_scheme = 'mbr'
15:13:32.089: storage_model_AJ_PCD20___2 property storage.removable.media_size = 31675383808 (0x760000000) (new)
15:13:36.014: storage_model_AJ_PCD20___2 property storage.removable.media_available = false
15:13:36.019: storage_model_AJ_PCD20___2 property storage.partitioning_scheme = ''

Panasonic P2 / Sony XDCAM U-1

Leider hat die Integration deieser beiden Laufwerke nicht funktioniert. Aus Zeitgründen und mangels notwendigkeit habe ich weitere Nachforschungen abgebrochen. Folgendes kann ich jedoch zu den Datenträgern sagen:

Sony U-1

– Beim Einlegen/Eject wird ein „Change“ Event gesendet.
– XDCAM wird als UDF Filesystem erkannt und auch gemountet (wie Blu-Ray). Jedoch meldet mount: unknown partition table.

Panasonic P2

– Scheint keine Change/Add/Remove-Events zu senden.
– Die P2-Software scheint keine Sub-Folder zu unterstützen: Ev. muss jedes P2-Drive separat freigegeben werden: Z.B. /media/P2-DRIVE01/SLOT01 – SLOT02 – …

Das Script

Zum Script gibt es auch einiges zu sagen. Da es sich um ein „learning by doing“ Projekt handelt, ist der Code nicht wirklich schön geschrieben. Dafür sollte jedermann etwas damit anfange und ihn lesen können, der sich ein wenig damit befasst. Es gibt auch noch einige auskommentierte Zeilen Code, die ich gelassen habe. Z.T. schreiben diese nur zusätzliche Informationen in die Logfiles oder helfen zu verstehen, welche Wege ich versucht haben und von welchen ich wieder abgekommen bin.

#!/bin/bash
#-------------------------------------------------------------------
# limeplug-mount.sh
# Author:   Markus Gerber
# Date:     01.02.2011
# Release:  1.0
# Purpose:  
# Note:     All Notes in German
# Copyright (c) 2011 Markus Gerber
# RULE: ACTION=="add|change|remove", SUBSYSTEMS=="usb", 
RUN+="/root/limeplug-script/limeplug-mount.sh USB_GENERAL_RULE %n %k %M 
%m %b"
#-------------------------------------------------------------------
#-------------------------------------------------------------------
# **** Allgemeine Variablen ****
SCRIPTNAME="limeplug-mount.sh" # ---------------------------------------- Script-Name als Variable (vor allem für Logfile)
DATEFORMAT="`/bin/date +%Y-%m-%d_%T -u`" # ------------------------------ Datums-Format für Logfile
LOGFILE="/media/LOGFILES/full.log" # ------------------------------------ Vollständiger Pfad zum Logfile (Ausführliches LOG)
LOGFILEDEV="/media/LOGFILES/device.log" # ------------------------------- Vollständiger Pfad zum Logfile (Device-Info LOG)
UMOUNTCOUNT="6" # ------------------------------------------------------- Anzahl Versuche für umount
MEDIAROOT="/media" # 
---------------------------------------------------- Grundverzeichnis 
(Freigabe) für LimePlug - Hier wird gemounted
CDROM_DEVICE_CONF="/dev/sr0" # ------------------------------------------ CDROM internes Device
CDROM_SLEEP="4" # 
------------------------------------------------------- Nach dem 
Einlegen der CDROM X Sek. warten, bevor weiter
UDEVRULE="$1" # --------------------------------------------------------- Ausgeführe udev-Rule
PARTITIONNR="$2" # ------------------------------------------------------ Partitions-Nummer - Wird von udev/Rules-File übergeben
PARTITION="$3"
ANSCHLUSS="$5"
ADMINNAME="Vor Nachname (me@domain.com)" # ---------------------- Ansprechpartner (e-Mail)
SCRIPTROOT="/root/limeplug-script" # ------------------------------------ Script-Root-Verzeichnis
SCRIPTTEMP="temp" # ----------------------------------------------------- Temp-Verzeichnis für das Script (Schreib-Rechte!)
DEVNAMETEMP="" # -------------------------------------------------------- DEVNAMETEMP zurücksetzen
LABELDEFAULT="NoName" # ------------------------------------------------- Default-Wert für Label (sonst per vol_id)
LIMEDEVLABEL="" # ------------------------------------------------------- vol_id Variable oder Default-Wert (LABELDEFAULT)
BASH_ARGV0="${BASH_ARGV[0]}"
BASH_ARGV1="${BASH_ARGV[1]}"
BASH_ARGV2="${BASH_ARGV[2]}"
BASH_ARGV3="${BASH_ARGV[3]}"
BASH_ARGV4="${BASH_ARGV[4]}"
BASH_ARGV5="${BASH_ARGV[5]}"
# Soll-USB-DevPath (zum evaluieren des USB-Anschlusses) - In separate Datei ausgelagert!
. $SCRIPTROOT/config/ports/*.conf
if [ "`which vol_id`" = "" ]
then
    echo "$DATEFORMAT > ERROR > *DEVICE-INFO*: Das Programm vol_id wird zur Ausführung benötigt!" >> $LOGFILE
    exit 1
fi
echo "$DATEFORMAT > GENERAL > ACTION:$ACTION /DRIVER=$DRIVER 
/BASH_ARGV0=$BASH_ARGV0 /ID_CLASS=$ID_CLASS /SUBSYSTEM=$SUBSYSTEM 
/DEVPATH=$DEVPATH /PHYSDEVPATH=$PHYSDEVPATH /DEVICE=$DEVICE /" >> 
$LOGFILE
#-------------------------------------------------------------------
# Abschnitt *USB-FILTERING*
# Bei unvorteilhaften USB-Devices vorzeitig abbrechen
# ACHTUNG: Muss zur Zeit von Hand angepasst werden! Wird nicht über
# die Config-Files gesteuert!
#-------------------------------------------------------------------
if [ "$ID_CLASS" == "mouse" ] || [ "$ACTION" == "release"] || [ "$ID_CLASS" == "kbd" ]
then
    echo "$DATEFORMAT > INFO > *USB-FILTERING*: ID_CLASS ist 
$ID_CLASS und ACTION ist $ACTION -> Fruehzeitiger Abbruch!" >> 
$LOGFILE
    exit 0
fi
# USB-Ports ausschliessen
if [ "${BASH_ARGV[0]}" == "1-2:1.0" ] || [ "${BASH_ARGV[0]}" == "1-2" ]
then
    echo "$DATEFORMAT > INFO > *USB-FILTERING*: Ausgeschlossener 
USB-Port ist ${BASH_ARGV[0]} und ACTION ist $ACTION -> Fruehzeitiger 
Abbruch!" >> $LOGFILE
    exit 0
fi
if [ "${BASH_ARGV[0]}" == "2-1:1.0" ] || [ "${BASH_ARGV[0]}" == "2-1" ]
then
    echo "$DATEFORMAT > INFO > *USB-FILTERING*: Ausgeschlossener 
USB-Port ist ${BASH_ARGV[0]} und ACTION ist $ACTION -> Fruehzeitiger 
Abbruch!" >> $LOGFILE
    exit 0
fi
#-------------------------------------------------------------------
# ENDE Abschnitt *USB-FILTERING*
#-------------------------------------------------------------------
#-------------------------------------------------------------------
# Abschnitt *DEVICE-INFO*
# Hier werden grundlegende Infos der Devices zusammengestellt
#-------------------------------------------------------------------
#DEVICETEST=${DEVPATH##*/}
#CTRL=${device%%:*}
#BUS=${device#*:}; bus=${bus%%:*}
#TARGET=${device#*:*:}; target=${target%%:*}
#LUN=${device#*:*:*:}
#DEV_ID="$TARGET $BUS $target $LUN"
#echo "$DATEFORMAT > TEST > *DEVICE-INFO*: device=$DEVICETEST 
ctrl=$CTRL bus=$BUS target=$TARGET lun=$LUN DEV_ID=$DEV_ID" >> 
$LOGFILE
#-------------------------------------------------------------------
# ENDE Abschnitt *DEVICE-INFO*
#-------------------------------------------------------------------
#-------------------------------------------------------------------
# Abschnitt *DEVPATH-DEF*
# Hier werden DEVPATH-Variablen Überprüft und Vorbereitet.
#-------------------------------------------------------------------
# BEISPIEL: PHYSDEVPATH=/devices/pci0000:00/0000:00:1d.1/usb2/2-2/2-2:1.0/host27/target27:0:0/27:0:0:1
# Beim Herauffahren oder beim Anschliessen eines Devices, wird das /dev/xxx in eine Datei geschrieben.
# PHYSDEVPATH wird bei einem change-Event nicht übertragen. So kann weiter unten nach der Namensauflösung
# die Datei mit dem entsprechenden LIMEDEVNAME geschrieben werden.
# Unterscheiden ob Gerät am USB-BUS oder am FireWire-Bus (scsi) angschlossen ist.
# Beispiel zum Überprüfen des Inhalts der Variable PHYSDEVPATHSHORT2:
# if [ ! -z "$(echo $PHYSDEVPATHSHORT2|tr -d 'a-t06-9<>\+\-=')"; then
# echo "variable darf nur aus den Zeichen a-t,0,6-9,<,>,+,-,= bestehen"
if [ "$PHYSDEVPATH" != "" ] || [ "$DEVPATH" != "" ]
then
# Zuerst unterscheiden ob ACTION add,change oder remove ist. 
# Notwendig, da von udev verschiedene Variablen übergeben werden.
    if [ "$ACTION" == "add" ]
    then
        echo "$DATEFORMAT > INFO > *DEVPATH-DEF* add: ACTION ist add." >> $LOGFILE
        DEVPATHDEF="$PHYSDEVPATH"
        echo "$DATEFORMAT > INFO > *DEVPATH-DEF* add: DEVPATHDEF gesetzt auf: $DEVPATHDEF." >> $LOGFILE
    elif [ "$ACTION" == "remove" ]
    then
# PHYSDEVPATHTEMPFILE auf die Informationen des Temp-Files setzen.
        PHYSDEVPATHTEMPFILE1=$(cat $SCRIPTROOT/temp/$BASH_ARGV0.tmp)
        PHYSDEVPATHTEMPFILE2="${PHYSDEVPATHTEMPFILE1%-*}" # Slot-Nummer entfernen, wenn vorhanden
        echo "$DATEFORMAT > INFO > *DEVPATH-DEF* remove: 
PHYSDEVPATHTEMPFILE1:$PHYSDEVPATHTEMPFILE1 / 
PHYSDEVPATHTEMPFILE2:$PHYSDEVPATHTEMPFILE2." >> $LOGFILE
        if  [ "$SUBSYSTEM" == "usb" ] || [ "$SUBSYSTEM" == "scsi" ]
        then
            echo "$DATEFORMAT > INFO > *DEVPATH-DEF* remove: 
ACTION ist remove an $SUBSYSTEM - Setze DEVPATHDEF auf USB-REMOVE und 
PHYSDEVPATHTEMPFILE auf $PHYSDEVPATHTEMPFILE! " >> $LOGFILE
            DEVPATHDEF="USB-REMOVE" # Damit nachfolgend kein Port erkannt wird mit "tr".
        else
            echo "$DATEFORMAT > INFO > *DEVPATH-DEF* remove: ACTION ist remove (nicht USB)." >> $LOGFILE
            DEVPATHDEF="$DEVPATH"
        fi
    elif [ "$ACTION" == "change" ]
    then
        if [ "$DEVPATH" != "" ]
        then
            echo "$DATEFORMAT > INFO > *DEVPATH-DEF* change: ACTION ist change." >> $LOGFILE
            DEVPATHDEF="$DEVPATH"
            echo "$DATEFORMAT > INFO > *DEVPATH-DEF* change: DEVPATHDEF gesetzt auf: $DEVPATHDEF." >> $LOGFILE
        else
            echo "$DATEFORMAT > INFO > *DEVPATH-DEF* change: DEVPATH ist NULL." >> $LOGFILE
        fi
    else
        echo "$DATEFORMAT > INFO > *DEVPATH-DEF*: ACTION ist $ACTION. Nicht vorgesehen. Mache nichts!" >> $LOGFILE
    fi # [ "$ACTION" == "add" ]
        PHYSDEVPATHSHORT1USB="${DEVPATHDEF##*:}"
        PHYSDEVPATHSHORT2TEMP="${DEVPATHDEF#*/[1-99]-[1-99]/}"
        PHYSDEVPATHSHORT2USB="${PHYSDEVPATHSHORT2TEMP%/host*}"
        echo "$DATEFORMAT > INFO > *DEVPATH-DEF*: PHYSDEVPATHSHORT1USB: $PHYSDEVPATHSHORT1USB" >> $LOGFILE
        echo "$DATEFORMAT > INFO > *DEVPATH-DEF*: PHYSDEVPATHSHORT2USB: $PHYSDEVPATHSHORT2USB" >> $LOGFILE
# variable darf nur aus den Zeichen 0-9,:,- bestehen
        if [ ! -z "$(echo $PHYSDEVPATHSHORT2USB|tr -d '0-9\-:.')" ]; then
            echo "TEST > PHYSDEVPATHSHORT2USB: Sieht nicht nach einem
 USB-Anschluss aus ($PHYSDEVPATHSHORT2USB). Versuche FireWire..." 
>> $LOGFILE
            PHYSDEVPATHSHORT1FW="${DEVPATHDEF##*:}"
            PHYSDEVPATHSHORT2TEMP="${DEVPATHDEF#*/*/*/*/*/}"
            PHYSDEVPATHSHORT2FW="${PHYSDEVPATHSHORT2TEMP%/*/*/*/*/*}"
            echo "$DATEFORMAT > INFO > *DEVPATH-DEF*: PHYSDEVPATHSHORT1FW: $PHYSDEVPATHSHORT1FW" >> $LOGFILE
            echo "$DATEFORMAT > INFO > *DEVPATH-DEF*: PHYSDEVPATHSHORT2FW: $PHYSDEVPATHSHORT2FW" >> $LOGFILE
            if [ ! -z "$(echo $PHYSDEVPATHSHORT2FW|tr -d 'fwhost0-9\-')" ]; then
                echo "$DATEFORMAT > INFO > *DEVPATH-DEF*: Sieht 
nicht nach einem FW- oder USB-Anschluss aus ($PHYSDEVPATHSHORT2FW). Nach
 tr bleibt USB: $(echo $PHYSDEVPATHSHORT2USB|tr -d '0-9\-:') FW: $(echo 
$PHYSDEVPATHSHORT2FW|tr -d 'fwhost0-9\-'). Abbruch..." >> $LOGFILE
                echo "$DATEFORMAT > INFO > *DEVPATH-DEF*: Setzte 
nun PHYSDEVPATHSHORT2 auf BASH_ARGV0 (${BASH_ARGV[0]})." >> 
$LOGFILE
                PHYSDEVPATHSHORT1=""
                PHYSDEVPATHSHORT2="${BASH_ARGV[0]}"
            else
                PHYSDEVPATHSHORT1="$PHYSDEVPATHSHORT1FW"
                PHYSDEVPATHSHORT2="$PHYSDEVPATHSHORT2FW"
                echo "$DATEFORMAT > INFO > *DEVPATH-DEF*: PHYSDEVPATHSHORT1 (FW): $PHYSDEVPATHSHORT1" >> $LOGFILE
                echo "$DATEFORMAT > INFO > *DEVPATH-DEF*: PHYSDEVPATHSHORT2 (FW): $PHYSDEVPATHSHORT2" >> $LOGFILE
            fi    
        else
            echo "TEST > PHYSDEVPATHSHORT2USB: Sieht nach einem 
USB-Anschluss aus ($PHYSDEVPATHSHORT2USB). Nach tr bleibt $(echo 
$PHYSDEVPATHSHORT2USB|tr -d '0-9\-:')." >> $LOGFILE
            PHYSDEVPATHSHORT1="$PHYSDEVPATHSHORT1USB"
            PHYSDEVPATHSHORT2="$PHYSDEVPATHSHORT2USB"
            echo "$DATEFORMAT > INFO > *DEVPATH-DEF*: PHYSDEVPATHSHORT1 (USB): $PHYSDEVPATHSHORT1" >> $LOGFILE
            echo "$DATEFORMAT > INFO > *DEVPATH-DEF*: PHYSDEVPATHSHORT2 (USB): $PHYSDEVPATHSHORT2" >> $LOGFILE
        fi
fi
#-------------------------------------------------------------------
# ENDE Abschnitt *DEVPATH-DEF*
#-------------------------------------------------------------------
#-------------------------------------------------------------------
# Abschnitt *DEVNAME-TEMP*
# Temporäres File mit DEVNAME schreiben (ACTION=add).
#-------------------------------------------------------------------
if [ "$PHYSDEVPATH" != "" ] && [ "$ACTION" == "add" ]
then
    echo "$DATEFORMAT > INFO > *DEVNAME-TEMP*: Ueber PHYSDEVPATH 
wurde hat das Device ($DEVNAME) erkannt und eine Info-Datei unter 
$SCRIPTROOT/$SCRIPTTEMP/$PHYSDEVPATHSHORT2-$PHYSDEVPATHSHORT1.tmp 
erstellt." >> $LOGFILE
    echo "$DEVNAME" > $SCRIPTROOT/$SCRIPTTEMP/$PHYSDEVPATHSHORT2-$PHYSDEVPATHSHORT1.tmp
## Auch ein File mit dem Device-Name wird erstellt - Dazu wird alles bis zum letzten "/" abgeschnitten.
DEVNAMEFILE="${DEVNAME##*/}"
    echo "$DATEFORMAT > INFO > *DEVNAME-TEMP*: Ueber PHYSDEVPATH 
wurde hat das Device ($DEVNAME) erkannt und eine Info-Datei unter 
$SCRIPTROOT/$SCRIPTTEMP/$DEVNAMEFILE.tmp 
($PHYSDEVPATHSHORT2-$PHYSDEVPATHSHORT1) erstellt." >> $LOGFILE
    echo "$PHYSDEVPATHSHORT2-$PHYSDEVPATHSHORT1" > $SCRIPTROOT/$SCRIPTTEMP/$DEVNAMEFILE.tmp
fi
#-------------------------------------------------------------------
# ENDE Abschnitt *DEVNAME-TEMP*
#-------------------------------------------------------------------
#-------------------------------------------------------------------
# Abschnitt *CARDREADER-DETECT*
# vol_id status:
# 0=OK, 1=Bereit, 2=error opening Volume, 3=?, 4=unknown Volume Type
#-------------------------------------------------------------------
if [ "$USBFRONTDEV03A" == "$PHYSDEVPATHSHORT2" ] || [ "$USBFRONTDEV03B" == "$PHYSDEVPATHSHORT2" ]
then
# CardReader Device ausfindig machen - Lesen aus Temp-File.
    DEVICE=$(cat $SCRIPTROOT/temp/$PHYSDEVPATHSHORT2-$PHYSDEVPATHSHORT1.tmp)
    echo "$DATEFORMAT > INFO > *CARDREADER-DETECT*: am Cardreader,
 Device $DEVICE (aus Temp-File) wurde ein $ACTION-Event erkannt." 
>> $LOGFILE
# vol_id scheint bei CardReader immer Status 1 auszugeben. testen.
    vol_id $DEVICE
    vol_id_status=$?
    if [ "$vol_id_status" == "2" ]
    then
        echo "$DATEFORMAT > INFO > *CARDREADER-DETECT*: Cardreader
 ist leer. vol_id Status: $vol_id_status." >> $LOGFILE
        #SUBACTION="remove"
    elif [ "$vol_id_status" == "4" ]
    then
        echo "$DATEFORMAT > INFO > *CARDREADER-DETECT*: Wurde eine
 leere Card eingelegt?! vol_id Status: $vol_id_status. Abbruch!" 
>> $LOGFILE
        exit 1
    elif [ "$vol_id_status" == "0" ]
    then
        if [ "$ID_FS_TYPE" != "" ]
        then
            echo "$DATEFORMAT > INFO > *CARDREADER-DETECT*: Filesystem: $ID_FS_TYPE wurde erkannt." >> $LOGFILE
            echo "$DATEFORMAT > INFO > *CARDREADER-DETECT*: LIMEDEVNAME wird gesetzt und SUBACTION=add." >> $LOGFILE
            #SUBACTION="add"
        else
            echo "$DATEFORMAT > WARN > *CARDREADER-DETECT*: Kein Filesystem erkannt!" >> $LOGFILE
        fi
    else
        echo "$DATEFORMAT > WARN > *CARDREADER-DETECT*: vol_id 
meldet Status $vol_id_status - Nicht vorgesehen!" >> $LOGFILE
    fi
# LIMEDEVNAME definieren und freischalten für mount über "General Storage".
    LIMEDEVNAME="CARD-INTERN"
    MORESLOTS="false"
    GOTODEV="GENERAL-STORAGE"
fi
#-------------------------------------------------------------------
# ENDE Abschnitt *CARDREADER-DETECT*
#-------------------------------------------------------------------
#-------------------------------------------------------------------
# Abschnitt *P2-DETECT*
# vol_id status:
# 0=OK, 1=Bereit, 2=error opening Volume, 3=?, 4=unknown Volume Type
#-------------------------------------------------------------------
if [ "$ACTION" == "change" ] && [ "$Product" == "P2 drive" ]
then
echo "$DATEFORMAT > INFO > *P2-DETECT*: am P2 Drive wurde ein $ACTION-Event erkannt." >> $LOGFILE
fi
#-------------------------------------------------------------------
# ENDE Abschnitt *P2-DETECT*
#-------------------------------------------------------------------
#-------------------------------------------------------------------
# Abschnitt *DVDROM-DETECT*
# vol_id status:
# 0=OK, 1=Bereit, 2=error opening Volume, 3=?, 4=unknown Volume Type
#-------------------------------------------------------------------
if [ "$ACTION" == "change" ] && [ "$DRIVER" == "sr" ]
then
# CDROM-DEVICE ausfindig machen
CDROM_DEVICE=/dev/`cat /proc/sys/dev/cdrom/info | grep "drive name:" | awk '{print $3}'`
# DEVNAME auch noch definieren
DEVNAME=$CDROM_DEVICE
if [ "$CDROM_DEVICE_CONF" == "$CDROM_DEVICE" ]
then
    echo "$DATEFORMAT > INFO > *DVDROM-DETECT*: am 
CD/DVD-Laufwerk, Device $CDROM_DEVICE (DRIVER=$DRIVER) wurde ein 
$ACTION-Event erkannt." >> $LOGFILE
    echo "$DATEFORMAT > INFO > *DVDROM-DETECT*: Warte $CDROM_SLEEP
 Sekunden und fahre dann weiter (Damit Laufwerk bereit)..." >> 
$LOGFILE
# Sleep, damit CDROM bereit für Abfrage von vol_id.
    sleep $CDROM_SLEEP
    vol_id $CDROM_DEVICE
    vol_id_status=$?
    if [ "$vol_id_status" == "2" ]
    then
        echo "$DATEFORMAT > INFO > *DVDROM-DETECT*: 
CD/DVD-Laufwerk ist leer. vol_id Status: $vol_id_status." >> 
$LOGFILE
    elif [ "$vol_id_status" == "4" ]
    then
        echo "$DATEFORMAT > INFO > *DVDROM-DETECT*: Wurde eine 
leere Disc in das CD/DVD-Laufwerk eingelegt?! vol_id Status: 
$vol_id_status. EJECT!" >> $LOGFILE
        eject $CDROM_DEVICE
    elif [ "$vol_id_status" == "0" ]
    then
        echo "$DATEFORMAT > INFO > *DVDROM-DETECT*: 
CD/DVD-Laufwerk ist bereit. vol_id Status: $vol_id_status." >> 
$LOGFILE
        echo "$DATEFORMAT > INFO > *DVDROM-DETECT*: Filesystem: $ID_FS_TYPE wurde erkannt." >> $LOGFILE
        LIMEDEVNAME="DVDROM-INTERN"
        GOTODEV="GENERAL-STORAGE"
        echo "$DATEFORMAT > INFO > *DVDROM-DETECT*: LIMEDEVNAME 
auf $LIMEDEVNAME gesetzt: Gehe zu $GOTODEV." >> $LOGFILE
    else
        echo "$DATEFORMAT > INFO > *DVDROM-DETECT*: vol_id meldet 
Status $vol_id_status - Nicht vorgesehen!" >> $LOGFILE
    fi
fi
fi
#CDROMLABEL=$(isoinfo -d -i /dev/cdrom | awk -F": " '/Volume id/{print $2}') #isoinfo nicht installiert
# Ev. Udev-Rule (high Rule - z.b. 99) SUBSYSTEM=="block", KERNEL=="sr0",
 ENV{DKD_MEDIA_AVAIABLE}=="1", RUN+="/usr/local/bin/detectdisc"
if [ "$DKD_MEDIA_AVAIABLE" == "1" ] && [ "$PHYSDEVDRIVER" == "sr" ]
then
    echo "$DATEFORMAT > INFO > *DVDROM-DETECT-OLD*: am 
CD/DVD-Laufwerk (PHYSDEVDRIVER=$PHYSDEVDRIVER) wurde ein $ACTION-Event 
erkannt." >> $LOGFILE
fi
#-------------------------------------------------------------------
# ENDE Abschnitt *DVDROM-DETECT*
#-------------------------------------------------------------------
#-------------------------------------------------------------------
# Abschnitt *PORT-DEF*
# Uebersetzung der Anschlüsse und definieren des Mountpoints (Name)
# MORESLOTS sagt aus, ob noch mehreren Ports (z.B. Slots bei P2) ge-
# sucht werden soll.
#-------------------------------------------------------------------
#GOTODEV="UNKNOWN" # ----------------------------------------------------- GOTODEV wird per default auf "UNKNOWN" gesetzt. 
#
#--> USB-Anschluss Front1
if [ "$PHYSDEVPATHSHORT2" == "$USBFRONTDEV01A" ] || [ "$PHYSDEVPATHSHORT2" == "$USBFRONTDEV01B" ]
then
LIMEDEVNAME="USB-FRONT1"
MORESLOTS="false"
GOTODEV="GENERAL-STORAGE"
#--> USB-Anschluss Front2
elif [ "$PHYSDEVPATHSHORT2" == "$USBFRONTDEV02A" ] || [ "$PHYSDEVPATHSHORT2" == "$USBFRONTDEV02B" ]
then
LIMEDEVNAME="USB-FRONT2"
MORESLOTS="false"
GOTODEV="GENERAL-STORAGE"
#--> USB-Anschluss für P2 Cardreader
elif [ "$PHYSDEVPATHSHORT2" == "$USBFRONTDEV05A" ] || [ 
"$PHYSDEVPATHSHORT2" == "$USBFRONTDEV05B" ] || [ "$PHYSDEVPATHTEMPFILE2"
 == "$USBFRONTDEV05A" ]
then
# P2 Device ausfindig machen - Lesen aus Temp-File.
    DEVICE=$(cat $SCRIPTROOT/temp/$PHYSDEVPATHSHORT2-$PHYSDEVPATHSHORT1.tmp)
    echo "$DATEFORMAT > INFO > *P2-DETECT*: am Cardreader, Device 
$DEVICE (aus Temp-File $PHYSDEVPATHSHORT2-$PHYSDEVPATHSHORT1.tmp) wurde 
ein $ACTION-Event erkannt." >> $LOGFILE
# Den Status des Devices ermitteln und SUBACTION setzen (für mount/umount)
    vol_id $DEVICE
    vol_id_status=$?
    if [ "$vol_id_status" == "2" ]
    then
        echo "$DATEFORMAT > INFO > *P2-DETECT*: Cardreader ist 
leer. vol_id Status: $vol_id_status. SUBACTION=remove." >> 
$LOGFILE
        SUBACTION="remove"
    elif [ "$vol_id_status" == "4" ]
    then
        echo "$DATEFORMAT > INFO > *P2-DETECT*: Wurde eine leere 
Card eingelegt?! vol_id Status: $vol_id_status. Abbruch!" >> 
$LOGFILE
        exit 1
    elif [ "$vol_id_status" == "0" ]
    then
        echo "$DATEFORMAT > INFO > *P2-DETECT*: Cardreader ist bereit. vol_id Status: $vol_id_status." >> $LOGFILE
        if [ "$ID_FS_TYPE" != "" ]
        then
            echo "$DATEFORMAT > INFO > *P2-DETECT*: Filesystem: $ID_FS_TYPE wurde erkannt." >> $LOGFILE
            echo "$DATEFORMAT > INFO > *P2-DETECT*: LIMEDEVNAME wird gesetzt und SUBACTION=add." >> $LOGFILE
            SUBACTION="add"
        else
            echo "$DATEFORMAT > WARN > *P2-DETECT*: Kein Filesystem erkannt!" >> $LOGFILE

        fi
    else
        echo "$DATEFORMAT > INFO > *P2-DETECT*: vol_id meldet Status $vol_id_status - Nicht vorgesehen!" >> $LOGFILE

    fi
LIMEDEVNAME="P2-CARD"
MORESLOTS="true"
GOTODEV="GENERAL-STORAGE"
#--> FireWire-Anschluss Front
elif [ "$PHYSDEVPATHSHORT2" == "fw-host0" ]
then
LIMEDEVNAME="FW-FRONT1"
MORESLOTS="false"
GOTODEV="GENERAL-STORAGE"
fi
#--------------------------------------------------
# Abschnitt *P2-SLOT*
# Unter-Routine zum definieren des P2-Slots
#--------------------------------------------------
if [ "$LIMEDEVNAME" == "P2-CARD" ]
then
    SLOTOFFSET="+ 1" # Kann + 0, + X oder - X sein
    if [ "$ACTION" == "add" ] || [ "$ACTION" == "change" ]
    then
        P2DEVICEPORTTEMP3=$(expr $PHYSDEVPATHSHORT1 $SLOTOFFSET)
        PORTNR="$P2DEVICEPORTTEMP3"
        echo "$DATEFORMAT > INFO > *P2-SLOT* add|change: Slotname 
ist: $PORTNR (mit Offset $SLOTOFFSET)." >> $LOGFILE
    elif [ "$ACTION" == "remove" ]
    then
        P2DEVICEPORTTEMP=$(cat $SCRIPTROOT/temp/$BASH_ARGV0.tmp)
        P2DEVICEPORTTEMP2="${P2DEVICEPORTTEMP##*-}"
        P2DEVICEPORTTEMP3=$(expr $P2DEVICEPORTTEMP2 $SLOTOFFSET)
        PORTNR="$P2DEVICEPORTTEMP3"
        echo "$DATEFORMAT > INFO > *P2-SLOT* remove: 
P2DEVICEPORTTEMP: $P2DEVICEPORTTEMP / P2DEVICEPORTTEMP2: 
$P2DEVICEPORTTEMP2 / P2DEVICEPORTTEMP3: $P2DEVICEPORTTEMP3 / BASH_ARGV0:
 $BASH_ARGV0 / " >> $LOGFILE
        echo "$DATEFORMAT > INFO > *P2-SLOT* remove: Slotname ist: $PORTNR (mit Offset $SLOTOFFSET)." >> $LOGFILE
    else
        echo "$DATEFORMAT > WARN > *P2-SLOT*: Fehler beim erkennen des Slot-Namen. Breche ab!" >> $LOGFILE
        exit 1
    fi
#    P2USBDEVICE="$USBFRONTDEV05A"
#    P2DEVICEPORT1=$(cat $SCRIPTROOT/temp/$P2USBDEVICE-0.tmp)
#    P2DEVICEPORT2=$(cat $SCRIPTROOT/temp/$P2USBDEVICE-1.tmp)
#    P2DEVICEPORT3=$(cat $SCRIPTROOT/temp/$P2USBDEVICE-2.tmp)
#    P2DEVICEPORT4=$(cat $SCRIPTROOT/temp/$P2USBDEVICE-3.tmp)
#    P2DEVICEPORT5=$(cat $SCRIPTROOT/temp/$P2USBDEVICE-4.tmp)
#    echo "$DATEFORMAT > INFO > *P2-SLOT*: Gefundene Slots: 
1:$P2DEVICEPORT1 / 2:$P2DEVICEPORT2 / 3:$P2DEVICEPORT3 / 4:   
 $P2DEVICEPORT4 / 5:$P2DEVICEPORT5" >> $LOGFILE
#    P2DEVICEPORTTEMP=$(cat $SCRIPTROOT/temp/$DEVICE.tmp)
#    P2DEVICEPORTTEMP2="${P2DEVICEPORTTEMP##*-}"
#    P2DEVICEPORTTEMP3=$(expr $P2DEVICEPORTTEMP2 $SLOTOFFSET)
#    SLOTNAME="SLOT$P2DEVICEPORTTEMP3"
#echo "$DATEFORMAT > INFO > *P2-SLOT*: Device: $DEVICE 
/Temp1:$P2DEVICEPORTTEMP /Temp2:$P2DEVICEPORTTEMP2 
/Temp3:$P2DEVICEPORTTEMP3 /SLOTNAME:$SLOTNAME (mit Offset: $SLOTOFFSET)"
 >> $LOGFILE
fi
#--------------------------------------------------
# ENDE Abschnitt *P2-SLOT*
#--------------------------------------------------
#-------------------------------------------------------------------
# ENDE Abschnitt *PORT-DEF*
#-------------------------------------------------------------------

#-------------------------------------------------------------------
# Abschnitt *DEVICE-INFO*
# Benötigte Infos mit vol_id auslesen und auswerten
#-------------------------------------------------------------------
# Testen ob das Programm vol_id vorhanden ist.
if [ "`which vol_id`" = "" ]
then
    echo "$DATEFORMAT > ERROR > *DEVICE-INFO*: Das Programm vol_id wird zur Ausführung benötigt!" >> $LOGFILE
    exit 1
else
# vol_id auslesen
    eval $(vol_id $DEVNAME)
    if [ "$DEVNAME" != "" ] || [ "$ACTION" == "remove" ]
    then
        if [ "$ACTION" == "remove" ]
        then
            echo "$DATEFORMAT > INFO > *DEVICE-INFO*: ACTION ist remove." >> $LOGFILE
        else
            echo "$DATEFORMAT > INFO > *DEVICE-INFO*: vol_id hat das Device $DEVNAME erkannt." >> $LOGFILE
        fi
        #echo "$DATEFORMAT > INFO > *DEVICE-INFO*: vol_id Setze 
Partitions-Name (safe), wenn vorhanden. Sonst Default wert 
$LABELDEFAULT." >> $LOGFILE
        if [ "$ID_FS_LABEL_SAFE" != "" ]
        then
            echo "$DATEFORMAT > INFO > *DEVICE-INFO*: 
vol_id-Info:ID_FS_LABEL_SAFE wurde erkannt: $ID_FS_LABEL_SAFE." >>
 $LOGFILE
            LIMEDEVLABEL=$ID_FS_LABEL_SAFE
        else
            if [ "$ACTION" != "remove" ]
            then
                echo "$DATEFORMAT > INFO > *DEVICE-INFO*: 
vol_id-Info:ID_FS_LABEL_SAFE wurde NICHT erkannt! Setze Default-Wert 
($LABELDEFAULT)." >> $LOGFILE
            LIMEDEVLABEL=$LABELDEFAULT
            else
                echo "$DATEFORMAT > INFO > *DEVICE-INFO*: vol_id muss bei (remove) kein Label setzen." >> $LOGFILE
            fi
        fi
    else
        echo "$DATEFORMAT > WARN > *DEVICE-INFO*: vol_id hat KEIN 
Device erkannt und ACTION ist nicht (remove)." >> $LOGFILE
    fi
fi # if [ "`which vol_id`" = "" ]
#-------------------------------------------------------------------
# ENDE Abschnitt *DEVICE-INFO*
#-------------------------------------------------------------------
#-------------------------------------------------------------------
# Abschnitt *MORESLOT-SEARCH*
#-------------------------------------------------------------------
if [ "$MORESLOTS" == "true" ]
then
#PORT-Name zusammensetzen
SLOTNAME="-SLOT$PORTNR"
echo "$DATEFORMAT > INFO > *MORESLOT-SEARCH*: $DEVNAME > 
Slotname wurde auf $SLOTNAME gesetzt (PortNr: $PORTNR)." >> 
$LOGFILE
else
echo "$DATEFORMAT > INFO > *MORESLOT-SEARCH*: $DEVNAME > MORESLOTS steht für Device auf $MORESLOTS." >> $LOGFILE
SLOTNAME=""
fi

#-------------------------------------------------------------------
# ENDE Abschnitt *MORESLOT-SEARCH*
#-------------------------------------------------------------------
#-------------------------------------------------------------------
# Abschnitt *MOUNT-VAR*
#-------------------------------------------------------------------
# **** Variablen generieren ****
LIMEMOUNTP="$MEDIAROOT/$LIMEDEVNAME$SLOTNAME-PART$2-$LIMEDEVLABEL" 
#-------------- Zusammensetzung des Mountpoints (Namens-Auflösung)
PARTLIST="`ls -al $MEDIAROOT | grep $LIMEDEVNAME$SLOTNAME`" # -------------------- Abfragen aller Partitionen eines Anschlusses
# **** mount Befehle mit den nötigen Optionen ****
MOUNTVFAT="/bin/mount -v -t vfat -o sync,rw,users,umask=000,uid=0,gid=46,noexec,codepage=437,iocharset=iso8859-1"
MOUNTNTFS="/bin/mount -v -t ntfs-3g -o sync,rw,users,umask=000,uid=0,gid=46,noexec"
MOUNTNTFSFORCEOPT="-o force"
MOUNTHFSPLUS="/bin/mount -v -t hfsplus -o sync,rw,users,umask=000,uid=0,gid=46,noexec,force"
MOUNTEXT2="/bin/mount -v -t ext2 -o sync,grpid,nouser_xattr"
MOUNTEXT3="/bin/mount -v -t ext3 -o sync,grpid,nouser_xattr"
MOUNTISO9660="mount -t iso9660 -o ro"
# **** umount variablen und Verzeichnisse löschen ****
UMOUNT="umount -l $MEDIAROOT/$LIMEDEVNAME$SLOTNAME-PART*"
RMDIR="/bin/rmdir $MEDIAROOT/$LIMEDEVNAME$SLOTNAME-PART*"
#-------------------------------------------------------------------
# ENDE Abschnitt *MOUNT-VAR*
#-------------------------------------------------------------------
# Wenn bis hier LIMEDEVNAME nicht definiert werden konnte, dann abbrechen.
if [ "$LIMEDEVNAME" == "" ]
then
    echo "$DATEFORMAT > WARN > Es konnte kein Device Name (LIMEDEVNAME) abgeleitet werden. Breche ab!" >> $LOGFILE
    exit 1
fi
# Genereller Logfile-Eintrag zur Info, an welchem Anschluss etwas geändert wurde.
#echo "$DATEFORMAT > INFO > $SCRIPTNAME > Udev-Event an 
Anschluss $ANSCHLUSS - ${BASH_ARGV[0]} festgestellt. LIMEDEVNAME ist 
$LIMEDEVNAME" >> $LOGFILE
#echo "$DATEFORMAT > INFO > $SCRIPTNAME > Udev-Event an DEVPATH $DEVPATH erkannt." >> $LOGFILE
# Log-Einträge (vor allem zu Test-Zwecken
#echo "$DATEFORMAT > **INFO ALLG** > udev-Event empfangen... 
ACTION: $ACTION am LimePlug-Anschluss $LIMEDEVNAME" >> $LOGFILE
#echo "$DATEFORMAT > **INFO ALLG** > Sprung-Adresse intern: 
$GOTODEV - Verwendung: $ID_FS_USAGE - FS-Typ: $ID_FS_TYPE Version: 
$ID_FS_VERSION" >> $LOGFILE
#echo "$DATEFORMAT > **INFO ALLG** > DEVTYPE: $DEVTYPE - Phys.Path: $PHYSDEVPATH" >> $LOGFILE
#echo "$DATEFORMAT > **INFO ALLG** > DEVNAME: $DEVNAME - SubSystem: $SUBSYSTEM ID-Typ: $ID_TYPE" >> $LOGFILE
#echo "$DATEFORMAT > **INFO ALLG** > ID_PATH: $ID_PATH" >> $LOGFILE

#-------------------------------------------------------------------
# Abschnitt *GENERAL-STORAGE*
#-------------------------------------------------------------------
echo "$DATEFORMAT > INFO > Abgeleiteter LIMEDEVNAME: $LIMEDEVNAME." >> $LOGFILE
# Geräte-Art aus den Variablen ableiten. 
if [ "$GOTODEV" == "GENERAL-STORAGE" ] && [ "$ID_FS_TYPE" != "" ]
then
# Wenn ein Gerät (USB-STORAGE) angeschlossen wurde (ADD),dann diese Schleiffe starten.
if [ "$ACTION" == "add" ] || [ "$SUBACTION" == "add" ]
then
echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME > Bin 
bei Sprungadresse für $GOTODEV gelandet." >> $LOGFILE
# Hier beginnt das Abfragen und Einbinden der Partitionen
    if [ "$DEVTYPE" == "partition" ]
    then
    echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME > 
Partition erkannt - $DEVNAME. ACTION=$ACTION / SUBACTION=$SUBACTION." 
>> $LOGFILE
# Verzeichnisse (MountPoints) erstellen und Filesystem mounten.
# VFAT
        if [ "$ID_FS_TYPE" == "vfat" ]
        then
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME
 > Mountpoint wird erstellt: $LIMEMOUNTP." >> $LOGFILE
            /bin/mkdir -p $LIMEMOUNTP >> $LOGFILE
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME > wird mit $ID_FS_TYPE gemounted." >> $LOGFILE
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME
 > Verwendeter Mountbefehl: $MOUNTVFAT $DEVNAME $LIMEMOUNTP." 
>> $LOGFILE
            $MOUNTVFAT $DEVNAME $LIMEMOUNTP >> $LOGFILE
# NTFS
        elif [ "$ID_FS_TYPE" == "ntfs" ]
        then
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME
 > Mountpoint wird erstellt: $LIMEMOUNTP." >> $LOGFILE
            /bin/mkdir -p $LIMEMOUNTP >> $LOGFILE
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME > wird mit $ID_FS_TYPE gemounted." >> $LOGFILE
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME
 > Verwendeter Mountbefehl: $MOUNTNTFS $DEVNAME $LIMEMOUNTP." 
>> $LOGFILE
            $MOUNTNTFS $DEVNAME $LIMEMOUNTP >> $LOGFILE
            if [ "$?" != "0" ]
            then
                echo "$DATEFORMAT > WARN > *GENERAL-STORAGE*: 
$DEVNAME > Es gab Probleme mit der $ID_FS_TYPE Partition! Ev. wurde 
nicht sauber unmounted?!" >> $LOGFILE
                echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: 
$DEVNAME > Verwendeter Mountbefehl (mit force): $MOUNTNTFS $DEVNAME 
$LIMEMOUNTP $MOUNTNTFSFORCEOPT." >> $LOGFILE
                $MOUNTNTFS $DEVNAME $LIMEMOUNTP $MOUNTNTFSFORCEOPT >> $LOGFILE
                if [ "$?" != "0" ]
                then
                    echo "$DATEFORMAT > *GENERAL-STORAGE*: ERROR >
 $DEVNAME > Die $ID_FS_TYPE Partition konnte auch mit FORCE nicht 
eingebunden werden!" >> $LOGFILE
# Hier müsste die Force-Option auch noch abgefragt werden - wenn missglückt, dann Verzeichnis direkt wieder löschen und ERROR!
                fi
            fi
# HFSplus        
        elif [ "$ID_FS_TYPE" == "hfsplus" ]
        then
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME
 > Mountpoint wird erstellt: $LIMEMOUNTP." >> $LOGFILE
            /bin/mkdir -p $LIMEMOUNTP >> $LOGFILE
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME > wird mit $ID_FS_TYPE gemounted." >> $LOGFILE
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME
 > Verwendeter Mountbefehl: $MOUNTHFSPLUS $DEVNAME $LIMEMOUNTP." 
>> $LOGFILE
            $MOUNTHFSPLUS $DEVNAME $LIMEMOUNTP >> $LOGFILE

# ext2        
        elif [ "$ID_FS_TYPE" == "ext2" ]
        then
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME
 > Mountpoint wird erstellt: $LIMEMOUNTP." >> $LOGFILE
            /bin/mkdir -p $LIMEMOUNTP >> $LOGFILE
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME > wird mit $ID_FS_TYPE gemounted." >> $LOGFILE
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME
 > Verwendeter Mountbefehl: $MOUNTEXT2 $DEVNAME $LIMEMOUNTP." 
>> $LOGFILE
            $MOUNTEXT2 $DEVNAME $LIMEMOUNTP >> $LOGFILE

# ext3        
        elif [ "$ID_FS_TYPE" == "ext3" ]
        then
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME
 > Mountpoint wird erstellt: $LIMEMOUNTP." >> $LOGFILE
            /bin/mkdir -p $LIMEMOUNTP >> $LOGFILE
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME > wird mit $ID_FS_TYPE gemounted." >> $LOGFILE
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME
 > Verwendeter Mountbefehl: $MOUNTEXT3 $DEVNAME $LIMEMOUNTP." 
>> $LOGFILE
            $MOUNTEXT3 $DEVNAME $LIMEMOUNTP >> $LOGFILE
# iso9660        
        elif [ "$ID_FS_TYPE" == "iso9660" ]
        then
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME
 > Mountpoint wird erstellt: $LIMEMOUNTP." >> $LOGFILE
            /bin/mkdir -p $LIMEMOUNTP >> $LOGFILE
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME > wird mit $ID_FS_TYPE gemounted." >> $LOGFILE
            echo "$DATEFORMAT > INFO > *GENERAL-STORAGE*: $DEVNAME
 > Verwendeter Mountbefehl: $MOUNTISO9660 $DEVNAME $LIMEMOUNTP." 
>> $LOGFILE
            $MOUNTISO9660 $DEVNAME $LIMEMOUNTP >> $LOGFILE
        else
            echo "$DATEFORMAT > WARN > *GENERAL-STORAGE*: $DEVNAME
 > $ID_FS_TYPE wird nicht unterstützt! Bitte $ADMINNAME informieren."
 >> $LOGFILE
        fi # if [ "$ID_FS_TYPE" == "vfat" ]
# Abfragen ob mount erfolgreich oder nicht
        if [ "$?" != "0" ]
        then
            echo "$DATEFORMAT > WARN > *GENERAL-STORAGE*: $DEVNAME
 > Konnte Filesystem nicht mounten! Mount gab Error $? aus." >>
 $LOGFILE
            echo "$DATEFORMAT > WARN > *GENERAL-STORAGE*: $DEVNAME
 > Bitte Device nicht verwenden (Nichts in das Verzeichnis 
kopieren)." >> $LOGFILE

        fi
    else
        echo "$DATEFORMAT > WARN > *GENERAL-STORAGE*: $DEVNAME 
> Keine Partition - Keine Regel für DEVTYPE $DEVTYPE - Abbruch." 
>> $LOGFILE
    exit 5

    fi # if [ "$DEVTYPE" == "partition" ]
fi # if [ "$ACTION" == "add" ]
fi # if [ "$GOTODEV" == "USB-STORAGE" ]
#-------------------------------------------------------------------
# ENDE Abschnitt *GENERAL-STORAGE*
#-------------------------------------------------------------------
#-------------------------------------------------------------------
# Abschnitt *REMOVE*
#-------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------------
# Hier kommen weitere Geräte rein... ENTFERNT für das temporäre System (in use)
# ------------------------------------------------------------------------------------------------------------
# Wenn ein Gerät entfernt (REMOVE), dann diese Schleiffe starten.
if [ "$ACTION" == "remove" ] || [ "$SUBACTION" == "remove" ] && [ "$LIMEDEVNAME" != "" ]
then
    echo "$DATEFORMAT > INFO > *REMOVE*: $LIMEDEVNAME > Gerät 
am Anschluss wurde entfernt. ACTION=$ACTION / SUBACTION=$SUBACTION." 
>> $LOGFILE
# INSERT Hier sollte überprüft werden, ob MountPoints überhaupt vorhanden sind.
        echo "$DATEFORMAT > INFO > *REMOVE*: $LIMEDEVNAME > Umount wird ausgeführt. Befehl: $UMOUNT." >> $LOGFILE
        $UMOUNT >> $LOGFILE
            if mount | grep $MEDIAROOT/$LIMEDEVNAME; then
                echo "$DATEFORMAT > WARN > *REMOVE*: $LIMEDEVNAME 
> Scheinbar konnten nicht alle (oder keine) Partition(en) am 
Anschluss $LIMEDEVNAME unmounted werden!" >> $LOGFILE
                until [ $COUNT -gt $UMOUNTCOUNT ]; do
                echo "$DATEFORMAT > WARN > *REMOVE*: $LIMEDEVNAME 
> Versuche ein weiteres Mal. Versuch $COUNT von $UMOUNTCOUNT" 
>> $LOGFILE
                $UMOUNT >> $LOGFILE
                        let COUNT=COUNT+1
                done
                echo "$DATEFORMAT > ERROR > *REMOVE*: $LIMEDEVNAME
 > Unmount auch nach $UMOUNTCOUNT Versuchen erfolglos! Abbruch!" 
>> $LOGFILE
                UMOUNTSTAT="Fehler"
            else
                UMOUNTSTAT="Erfolg"
                echo "$DATEFORMAT > INFO > *REMOVE*: $LIMEDEVNAME 
> Alle Partitionen am Anschluss $LIMEDEVNAME$SLOTNAME wurden 
erfolgreich unmounted." >> $LOGFILE
            fi # if mount
        if [ "$UMOUNTSTAT" == "Erfolg" ]
        then
            echo "$DATEFORMAT > INFO > *REMOVE*: $LIMEDEVNAME >
 Verzeichnisse $MEDIAROOT/$LIMEDEVNAME$SLOTNAME-PART* werden nun 
entfernt." >> $LOGFILE
            $RMDIR >> $LOGFILE
        else
            echo "$DATEFORMAT > ERROR > *REMOVE*: $LIMEDEVNAME 
> Verzeichnisse $MEDIAROOT/$LIMEDEVNAME$SLOTNAME-PART* wurden NICHT 
entfernt." >> $LOGFILE
            echo "### START :: Liste der Verbleibenden Verzeichnisse: ###" >> $LOGFILE
            echo "$PARTLIST" >> $LOGFILE
            echo "### END   :: Liste der Verbleibenden Verzeichnisse: ###" >> $LOGFILE
            exit 1
        fi
fi # if [ "$ACTION" == "remove" ]
#-------------------------------------------------------------------
# ENDE Abschnitt *REMOVE*
#-------------------------------------------------------------------
#-------------------------------------------------------------------
# Abschnitt *LOGFILEDEV*
#-------------------------------------------------------------------
if [ "$ACTION" == "add" ] && [ "$SUBSYSTEM" == "block" ]
then
echo "$DATEFORMAT > $ACTION: $DEVNAME: $LIMEDEVNAME" >> $LOGFILEDEV
elif [ "$ACTION" == "remove" ]
then
echo "$DATEFORMAT > $ACTION: $DEVNAME: $LIMEDEVNAME" >> $LOGFILEDEV
fi
#-------------------------------------------------------------------
# ENDE Abschnitt *LOGFILEDEV*
#-------------------------------------------------------------------
echo "$DATEFORMAT > INFO > $SCRIPTNAME > ENDE erreicht." >> $LOGFILE
exit 0

Flattr this!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.