VDR auf dem Seagate FreeAgent DockStar unter Arch Linux ARM

1 Einleitung

1.1 Hintergrund

Der Seagate FreeAgent DockStar ist ein Netzwerkadapter (NAS), der USB-Speichermedien im lokalen Netzwerk und - über den kostenpflichtigen Pogoplug-Service - auch per Internet zugänglich macht. Das Gerät verfügt über einen 1,2 GHz ARM Prozessor, 128 MB RAM, 1x GBit LAN und 4 USB 2.0 Schnittstellen, von denen eine zum Anschluss kompatibler Festplatten (FreeAgent Go) als Mini-USB-Stecker ausgeführt ist. Das Betriebssystem, ein angepasstes Linux - im folgenden Pogoplug Linux genannt -, befindet sich auf dem internen 256 MB Flash Speicher. Es können aber auch andere für die ARM-Architektur verfügbare Linux-Distributionen eingesetzt werden, wodurch sich der Verwendungszweck vielfältig erweitern lässt.

1.2 Überblick

Im folgenden dokumentiere ich die Einrichtung des Seagate FreeAgent DockStar als DVB-T Rekorder. Als Betriebssystem nutze ich Arch Linux ARM, das aus PlugApps Linux (vormals Plugbox Linux) und ArchMobile hervorgegangen ist und auf dem seit längerem für die i686- und x86_64-Architekturen verfügbaren Arch Linux basiert. Zur Programmierung und Aufnahme von TV-Sendungen dient der VDR. An den DockStar angeschlossen sind

Ein weiteres, sekundäres, Aufnahmeverzeichnis auf dem USB-Stick ermöglicht einen zeitweilig lautlosen Betrieb ohne Zugriff auf die Festplatte. Beide Verzeichnisse werden mit dem Aufs-Dateisystem übereinander gelegt und per NFS im lokalen Netzwerk freigegeben. Die VDR-Oberfläche ist dort per Remote Frontend (xineliboutput) zugänglich. Zum Anlegen von Aufnahmetimern, auch via Internet, dient ein Webinterface (vdradmin-am).

2 Vorbereitung des USB-Sticks

Die Installationsanleitung für Arch Linux ARM (Stand Juni 2011) beschreibt die Formatierung eines USB-Sticks mit Ext2 und das Aufspielen das Betriebssystem-Images am DockStar unter Pogoplug Linux. Von dieser Vorgehensweise weiche ich in einigen Punkten ab:

2.1 Formatierung

Die Formatierung eines Datenträgers birgt stets die Gefahr eines Datenverlustes durch irrtümliche Angabe eines falschen Devices. Es ist deshalb wichtig das Device des USB-Sticks zweifelsfrei zu identifizieren, etwa anhand der Ausgabe von dmesg. Im folgenden wird stellvertretend /dev/sdx verwendet. Mit fdisk lege ich auf dem Stick drei primäre Partitionen an. Man beachte, dass es Vorteile haben kann, stattdessen gdisk zu verwenden, dazu mehr im Forum und im Abschnitt 6.2.

[root@linux ~]# fdisk /dev/sdx

Neben Bootpartition (32 MB) und Rootpartition (1200 MB) nimmt eine dritte (Home-)Partition den Rest des 16 GB-Sticks ein. Sie wird das sekundäre VDR-Aufnahmeverzeichnis beherbergen. Auf eine Swap-Partition verzichte ich, 128 MB RAM sollten für den beschriebenen Verwendungszweck genügen. Hier das Ergebnis der Partitionierung:

Disk /dev/sdc: 16.0 GB, 16001269760 bytes
64 Köpfe, 32 Sektoren/Spur, 15260 Zylinder, zusammen 31252480 Sektoren
Einheiten = Sektoren von 1 × 512 = 512 Bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

   Gerät  boot.     Anfang        Ende     Blöcke   Id  System
/dev/sdx1            2048       67583       32768   83  Linux
/dev/sdx2           67584     2525183     1228800   83  Linux
/dev/sdx3         2525184    31252479    14363648   83  Linux

Beim Anlegen der Dateisysteme erhält jede Partition zur einfacheren Identifikation zugleich ein Label. Um keinen Speicherplatz zu verschwenden, wird auf der home-Partition der für root reservierte Speicherplatz (5% per Voreinstellung) auf 1% reduziert.

[root@linux ~]# mkfs.ext2 -L boot /dev/sdx1 
[root@linux ~]# mkfs.ext4 -L root /dev/sdx2 
[root@linux ~]# mkfs.ext4 -L home -m 1 /dev/sdx3

Um Schreibzugriffe zu minimieren, kann man das Journal der ext4-Partitionen mit der Option -O ^has_journal deaktivieren, riskiert damit bei Stromunterbrechung aber ein inkonsistentes Dateisystem.

2.2 Installation

Der Stick wird nun gemountet und das Image von Arch Linux ARM darauf entpackt. Man achte sorgsam darauf, dieses im richtigen Verzeichnis zu tun, um keine Dateien des laufenden Systems zu überschreiben.

[root@linux ~]# mount /dev/sdx2 /mnt/
[root@linux ~]# cd /mnt/
[root@linux mnt]# mkdir boot
[root@linux mnt]# mount /dev/sdx1 boot/
[root@linux mnt]# tar -xf /pfad/zu/ArchLinuxARM-armv5te-latest.tar.gz

Da der Bootloader uBoot das Kernel-Image auf der ersten Partition im Verzeichnis /boot erwartet (so wie es ohne separate Bootpartition wäre), legen wir einfach einen gleichnamigen Link auf das aktuelle Verzeichnis an. Das ist etwas einfacher als die Umgebungsvariablen des Bootloaders anzupassen (Abschnitt 3.2).

[root@linux mnt]# cd boot
[root@linux boot]# ln -s . boot

2.3 Vorkonfiguration

Es werden noch einige Konfigurationsdateien auf dem Stick - also unterhalb von /mnt - editiert. In /etc/fstab sind die Partitionen des USB-Sticks einzutragen, andernfalls wird nur die Rootpartition gemountet. Da sich die Zuordnung der Gerätedateien nach einen Reboot ändern kann, empfiehlt sich die Verwendung der oben vergebenen Label. Alternativ können UUIDs (laut blkid) genutzt werden, für die Rootpartition auch /dev/root. Die Optionen noatime und nodiratime unterbinden das unnötige Speichern von Lese-Zugriffszeiten auf dem Stick.

#/etc/fstab
LABEL=root  /       ext4  noatime,nodiratime  0 0
LABEL=boot  /boot   ext2  noatime,nodiratime  0 0
LABEL=home  /home   ext4  noatime,nodiratime  0 0

Temporäre Verzeichnisse wie /tmp, deren Inhalt nach einem Reboot ohnehin gelöscht wird, können in den RAM verlagert werden. Auch diverse Verzeichnisse unter /var/ bieten sich dafür an.1

#/etc/fstab (fortgesetzt)
tmp      /tmp       tmpfs nodev,nosuid,mode=1777,size=8M  0 0
varlock  /var/lock  tmpfs nodev,nosuid,mode=1777,size=1M  0 0
varrun   /var/run   tmpfs nodev,nosuid,mode=0755,size=2M  0 0
varlog   /var/log   tmpfs nodev,nosuid,mode=0755,size=8M  0 0

Unter Umständen kann es hilfreich sein, den DockStar per USB-Tastatur herunterfahren zu können. Die Tastenkombination Strg+Alt+Entf bewirkt dies zwar per Voreinstellung, ruft aber auch einen Neustart hervor, der sich durch folgende Änderung in /etc/inittab unterbinden lässt:

#/etc/inittab
ca::ctrlaltdel:/sbin/shutdown -t3 -h now

Nach diesen Vorbereitungen kann der USB Stick ausgehängt werden.

[root@linux mnt]# cd / && umount /mnt/boot/ /mnt

3 Anpassung des Bootloaders

Um Arch Linux ARM vom USB-Stick starten zu können, muss der Bootloader uBoot aktualisiert und angepasst werden. Dazu wird zunächst das auf dem internen Flash-Speicher befindliche Pogoplug-Linux gebootet. Um ein ungewolltes Firmwareupdate auszuschließen, das u.U. den SSH-Zugang deaktiviert, sollte man zuvor den Router physisch vom Internet trennen.

3.1 Update

Nach Stromzufuhr können einige Minuten vergehen, bis der DockStar vom Router eine IP Adresse anfordert und der Zugang per SSH (Login: root, Passwort: stxadmin) möglich ist. Als erstes beendet man dann den Pogoplug Client:

Pogoplug:$ killall hbwd 

Danach kann die Internetverbindung wieder hergestellt werden. Anschließend wird das Installationsscript von Jeff Doozan heruntergeladen und ausgeführt:

Pogoplug:~$ cd /tmp
Pogoplug:/tmp$ wget http://jeff.doozan.com/debian/uboot/install_uboot_mtd0.sh
Pogoplug:/tmp$ chmod +x install_uboot_mtd0.sh
Pogoplug:/tmp$ ./install_uboot_mtd0.sh

Bevor das Script eine neue Version von uBoot installiert, deaktiviert es den Pogoplug Client permanent durch Auskommentieren einer Zeile im Startscript /etc/init.d/rcS:

#Uncomment the line below to enable the pogoplug service
#/etc/init.d/hbmgr.sh start

3.2 Konfiguration

Zur Konfiguration von uBoot dienen Scripte und Umgebungsvariablen, die man sich mit fw_printenv anzeigen lassen und mit fw_setenv manipulieren kann. Das Script usb_set_bootargs generiert die Kernel-Bootparameter. Die dort verwendete Variable für die Rootpartition $usb_root wird im Script usb_scan ermittelt. Folgende Anpassungen habe ich vorgenommen, um sicherzustellen, dass hier nicht die erste, sondern die zweite Partition des USB-Sticks zugeordnet wird:

Pogoplug:/tmp$ fw_setenv usb_scan_1 'usb=0:1 dev=sda2'
Pogoplug:/tmp$ fw_setenv usb_scan_2 'usb=1:1 dev=sdb2'
Pogoplug:/tmp$ fw_setenv usb_scan_3 'usb=2:1 dev=sdc2'
Pogoplug:/tmp$ fw_setenv usb_scan_4 'usb=3:1 dev=sdd2'

Ist das Device der Rootpartition bekannt (z.B. bei fester Anordnung von USB-Datenträgern), kann stattdessen auch das Script usb_set_bootargs direkt editiert werden, siehe Abschnitt 6. Vorläufig behelfen wir uns aber wie beschrieben. Weiterhin müssen noch die Angaben betreffs des root-Dateisystems und der arcNumber (zur Ansteuerung der LEDs) angepasst werden:

Pogoplug:/tmp$ fw_setenv usb_rootfstype ext4
Pogoplug:/tmp$ fw_setenv arcNumber 2998

Idealerweise aktiviert man auch die Netzkonsole, um die Meldungen des Bootloaders mit netcat verfolgen zu können. Schließlich wird der vorbereitete USB-Stick angeschlossen und der DockStar neu gebootet:

Pogoplug:/tmp$ /sbin/reboot

Wie man ggf. den Bootmeldungen entnehmen kann, scheitert der Start von Arch Linux ARM u. U. zunächst. In diesem Fall wird spätestens nach einigen Minuten erneut das weiterhin auf dem internen Flash-Speicher residierende Pogoplug Linux geladen. Nach einem weiteren Neustart sollte es dann gelingen. Da sich der SSH-Schlüssel nun geändert hat, ist vor der nächsten Anmeldung (Login: root, Passwort: root) der alte Schlüssel zu löschen.

[user@linux ~]$ ssh-keygen -R <IP-Adresse>

Je nach verwendetem USB-Stick führt jede künftige Unterbrechnung der Stromzufuhr u.U. dazu, dass zunächst wieder Pogoplug Linux gestartet wird. Um einen Reboot per SSH herbeizuführen, muss der neue Schlüssel dann wieder gelöscht werden. Eine Möglichkeit diesen Zyklus zu unterbinden und zuverlässig auch nach einem Kaltstart Arch Linux ARM zu booten findet sich im Forum von Jeff Doozan.

Pogoplug:/tmp$ fw_setenv bootcmd 'usb start; usb stop; usb start; run force_rescue_bootcmd; run ubifs_bootcmd; run usb_bootcmd; usb stop; run rescue_bootcmd; run pogo_bootcmd; reset'

Bei Problemen kann man via Netzkonsole auch mit uBoot interagieren. Unter Arch Linux starte ich dazu netcat (Paket gnu-netcat) wie folgt. Nach Beginn des Countdowns gelangt man durch mehrmaliges Drücken der Tastenkombination Strg+J an den Marvell Bootprompt.

[root@linux ~]# netcat -l -u -p 6666
U-Boot 2010.09 (Oct 23 2010 - 11:49:22)
Marvell-Dockstar/Pogoplug by Jeff Doozan
Hit any key to stop autoboot:  9 
 8 

 0 
Marvell>> 

4 Einrichtung von Arch Linux ARM

Wurde Arch Linux ARM gebootet und Zugang per SSH gewährt, sind noch einige Konfigurationsdateien anzupassen, ich verweise dazu auf die First Steps und das Wiki von Arch Linux. Hier in kürze die zuerst von mir vorgenommenen Einstellungen:

4.1 Ansteuerung der LEDs

Die Steuerung der LEDs über das /sys-Verzeichnis erfordert root-Rechte, soll möglichst aber auch anderen Nutzern offenstehen. Der direkte Einsatz von sudo ist in diesem Zusammenhang etwas umständlich. Ich habe deshalb ein einfaches C-Programm geschrieben, das sich auf herkömmliche Weise mit sudo ausführen lässt. Auch kann es einfach innerhalb eines Scriptes genutzt werden, das seinerseits mit sudo aufgerufen wurde (Abschnitt 8.4). Das Programm wird mit gcc, der im gleichnamigen Paket enthalten ist, kompiliert:

[user@alarm ~]$ gcc -o led led.c

Es manipuliert jeweils nur eine der beiden LEDs und ermittelt diese anhand des Namens, unter dem das Programm aufgerufen wurde. Deshalb werden zwei Dateien erstellt, die auf denselben Inode zeigen (Hardlink):

[root@alarm ~]# cp led /usr/local/bin/led_green
[root@alarm ~]# ln /usr/local/bin/led_green /usr/local/bin/led_orange

Ohne Parameter werden verfügbare Zustände und aktueller Status angezeigt. Als erster Parameter kann der gewünschte Status angegeben werden. Der Status timer benötigt zusätzlich die Parameter delay_on und delay_off, hier ein Beispiel:

[root@alarm ~]# led_green 
none nand-disk timer heartbeat [default-on] 
[root@alarm ~]# led_green timer 1000 1000

4.2 Externe Festplatte

Die eingangs erwähnte USB-Festplatte ist bereits formatiert und bleibt (vorerst) permanent angeschlossen. Sie wird deshalb wie der USB-Stick fest über /etc/fstab eingebunden. Die verwendete Festplatte geht nach 30 Minuten ohne Zugriff automatisch in den Standby (unabhängig von mit sdparm oder hdparm eigenstellten Werten).

Neben ihrer eigentlichen Aufgabe nutze ich die Festplatte zur Erweiterung des Speicherplatzes für das Betriebssystem. Dazu werden Verzeichnisse auf der Festplatte mit der mount-Option --bind zusätzlich an geeigneter Stelle im Verzeichnisbaum eingebunden. Damit dennoch ein längerer Standby der Festplatte möglich bleibt, berücksichtige ich nur Verzeichnisse, auf die selten zugegriffen wird: Der Paket-Cache und das ABS-Wurzelverzeichnis (Abschnitt 4.3):

#/etc/fstab (fortgesetzt)
LABEL=usbhdd   /hdd                  ext4 defaults 0 0
/hdd/pkg       /var/cache/pacman/pkg none bind     0 0
/hdd/abs       /var/abs              none bind     0 0

Alternativ wären natürlich auch symbolische Links oder ein Anpassung der Pfade in /etc/pacman.conf und /etc/abs.conf möglich. Die Paketdatenbank /var/lib/pacman/sync verbleibt auf dem Stick, andernfalls würde jeder Aufruf von pacman die Festplatte aus dem Standby holen. Die angegebenen Verzeichnisse müssen, falls nicht bereits vorhanden, vor dem Mounten natürlich angelegt werden.

4.3 Repositories und Paketquellen

Mit der Paketverwaltung des Systems sollte man, wie bei jeder Linux-Distribution, vertraut sein. Arch Linux macht überdies auch das Erstellen von Software-Paketen relativ leicht. In den folgenden Abschnitten mache ich davon mehrfach gebrauch ohne auf das Vorgehen im Detail einzugehen, deshalb hier ein kurzer Überblick mit obligatorischen Links zum Wiki.

Als Git- und Paketbauverzeichnis bietet sich wiederum die Festplatte an. Die PKGBUILDs aus dem abs-Verzeichnis und dem AUR sind auf die von Arch Linux unterstützen Architekturen (i686/x86_64) abgestimmt. Zum Kompilieren auf dem DockStar kann man das arch-Array im PKGBUILD editieren oder einfacher mit der makepkg-Option -A ignorieren. Bei Paketen aus dem AUR sind u.U. weitere Anpassungen des PKGBUILD an die ARM-Architektur erforderlich.

Da keine Swap-Partition angelegt wurde, macht sich beim Paketbau mitunter der begrenzte RAM bemerkbar:

xz: /home/user/abs/foobar/foobar-0.1-1-arm.pkg.tar: Nicht genügend Hauptspeicher verfügbar

Zumeist genügt es dann Programme mit erhöhtem Bedarf an RAM (wie z.B. vdradmind, Abschnitt 8.2.1) vorübergehend zu beenden. Anschließend kann die Zusammenstellung und Komprimierung des betroffenen Paketes mit makepkg -Rf erneut veranlasst werden. Eine zusätzliche Maßnahme wäre die Verwendung einer Kompressionsart, die weniger Arbeitsspeicher beansprucht:

#/etc/makepkg.conf
PKGEXT='.pkg.tar.gz'

4.4 Komprimierter RAM

Die Fehlermeldung bei erschöpftem RAM ist selten so eindeutig wie im vorherigen Abschnitt, oft werden Programme, deren Bedarf an RAM nicht gestillt werden kann, einfach beendet. Die Ursache findet man dann mit dmesg, hier z.B. bei einer abgebrochenen Datensicherung mit rsync:

[ 3901.497857] Out of memory: Kill process 1262 (rsync) score 272 or sacrifice child
[ 3901.497872] Killed process 1263 (rsync) total-vm:74980kB, anon-rss:24844kB, file-rss:0kB

Zwar könnte man in dieser Situation vorübergehend ein swapfile, vorzugsweise auf der USB-Festplatte, einrichten. Alternativ - oder zusätzlich - gibt es aber auch die Möglichkeit, den verfügbaren RAM besser auszunutzen: Dazu wird mithilfe des Kernelmoduls zram eine virtuelle Swap-Partition /dev/zram0 angelegt und eingebunden. Die in diesen Swap ausgelagerten Daten werden komprimiert und im RAM gespeichert. Die Swap-Partition beansprucht dabei jederzeit nur die den komprimierten Daten entsprechende Menge das RAMs. Im Endeffekt werden also umso mehr Daten im RAM komprimiert, je höher der tatsächliche Bedarf an RAM ist. Der Preis dafür ist eine erhöhte CPU-Belastung.

Zur Konfiguration kann das im AUR verfügbare Paket compcache genutzt werden. Das Paket enthält ein Initscript, das die notwendigen Schritte vereinfacht. Die maximale Menge an unkomprimierten Daten, die /dev/zram0 aufnehmen soll, beträgt per Voreinstellung 25% des RAM, also 32 MB. Ich habe diesen Wert auf ca. 96 MB erhöht:

#/etc/conf.d/compcache
SIZE="96000"

Mit dieser Einstellung konnte ich auch große Pakete mit xz komprimieren und z.B. eine umfangreiche rsnapshot-Sicherung samt ihrer unzähligen Hardlinks mit rsync auf ein anderes, mit dm-crypt/LUKS verschlüsseltes Medium übertragen. Erstellt und eingebunden wird der virtuelle Swap mit dem erwähnten Initscript

[root@alarm ~]# /etc/rc.d/compcache start

Mit zram_stats lässt sich u.a. ermitteln, wieviele Daten momentan im Swap gespeichert werden (orig_data_size) und wieviel Platz diese Daten im RAM einnehmen (compr_data_size).

5 Kompilierung des Kernels

Zur Aufnahme von Fernsehsendungen soll ein vom Linux-Kernel unterstützter DVB-T Stick genutzt werden. Das Paket linux aus dem archlinuxarm-Repository enthält jedoch nur eine kleine Auswahl der im Kernel insgesamt verfügbaren dvb-usb Module. Wird der DVB-Stick nicht erkannt, kann man versuchen weitere Module nachträglich aus dem v4l-dvb Repository zu installieren, mehr dazu im Abschnitt 7.1.

Eine andere Möglichkeit besteht darin, die Kernelkonfiguration anzupassen: Das Vorgehen ist im Artikel Kernel Compilation beschrieben (das zu modifizierende Kernelpaket befindet sich jedoch im Git-Repository, siehe Abschnitt 4.3), hier das überarbeitete Paket:

Das Aufs-Dateisystem, das zur Verlagerung des VDR-Aufnahmeverzeichnisses zum Einsatz kommen soll, habe ich in das Kernelpaket integriert. Neben den Kernelquellen werden also auch die passenden Kernelpatches und Quelldateien aus dem Aufs-Git-Repository heruntergeladen. Damit erübrigt sich die Erstellung eines zusätzlichen Paketes für das aufs-Kernelmodul, es werden nur die aufs-utils benötigt:

Edit: Aufs ist mittlerweile im Paket linux als integraler Bestandteil des Kernels enthalten (CONFIG_AUFS_FS=y), es wird also auch für den vorinstallierten Kernel kein weiteres Modulpaket benötigt. Allerdings besteht aufgrund der zugrundegelegten Kernelkonfiguration keine Möglichkeit das Aufs-Verzeichnis per NFS zu exportieren (CONFIG_AUFS_EXPORT is not set).

5.1 Konfiguration

Um die Kompilierzeit zu reduzieren, verwende ich im PKGBUILD des Kernels das make-Target localmodconfig. Es deaktiviert in der Kernelkonfiguration sämtliche Module, die momentan nicht geladen sind 2. Als Basis dient die Konfiguration des laufenden Kernels aus /proc/config.gz. Im Anschluss werden neu hinzugekommene Kerneloptionen einzeln abgefragt. Man kann hier die Vorgaben zunächst bestätigen und hat dann im letzten Schritt via make menuconfig Gelegenheit in einer textbasierten Oberfläche die Konfigurationen zu überarbeiten (NFS, Aufs) und bislang nicht aktivierte Treiber auszuwählen (DVB).

5.1.1 NFS

Falls make localmodconfig ausgeführt wurde, sind ggf. die folgenden Optionen wieder zu aktivieren:

File systems  --->
  [*] Network File Systems  --->
    <M>   NFS server support 
    [*]     NFS server support for NFS version 4 (EXPERIMENTAL)

Das IPv6 Modul sollte automatisch geladen und folglich in jedem Fall ausgewählt sein, andernfalls findet man es unter

[*] Networking support  --->
  Networking options  --->
    [*] TCP/IP networking
    <M>   The IPv6 protocol  --->

5.1.2 Aufs

Hier die von mir gewählte Konfiguration. Wichtig ist, wie oben erwähnt, die Option “NFS-exportable aufs”.

File systems  --->
  [*] Miscellaneous filesystems  --->
    <M>   Aufs (Advanced multi layered unification filesystem) support
            Maximum number of branches (127)  ---> 
    [*]     Detect direct branch access (bypassing aufs)
              method (fsnotify)  ---> 
    [*]     NFS-exportable aufs
    [*]     Respect the attributes (mtime/ctime mainly) of special files
    [*]     Show whiteouts
    [*]     Ramfs (initramfs/rootfs) as an aufs branch

5.1.3 DVB

Die Einstellungen für DVB-Sticks findet man wie folgt. Der gewählte Treiber (letzte Zeile) muss natürlich zu dem verwendeten DVB-Stick passen. Bei hybriden Sticks befinden sich die nötigen Optionen auch im Menüpunkt “Video capture adapters”. Dieser steht nur dann zur Auswahl, wenn auch “Video For Linux” ausgewählt ist.

Device Drivers  --->
  <M> I2C support  --->
  <M> Multimedia support  --->
    <M>   DVB for Linux
    [*]   DVB/ATSC adapters (NEW)  --->
      <M>   Support for various USB DVB device
      <M>     WideView WT-200U and WT-220U (pen) DVB-T USB2.0 support (Yakumo/Hama/Typhoon/Yuan)

Sofern der benötigte Treiber nicht auszumachen ist, kann man diesen mithilfe eines Linux-PCs oder anhand seiner ID identifizieren und in den Kernelquellen die zugehörige CONFIG-Variable finden. Im Abschnitt 7.1 wird das Vorgehen an einem Beispiel gezeigt. Durch Eingabe eines Schrägstrichs startet man innerhalb der Kernelkonfiguration eine Suchmaske und gibt dort die Variable ein, im Beispiel DVB_USB_DTT200U. Das Ergebnis liefert den gesuchten Prompt.

5.1.4 Zram

Auch der angepasste Kernel soll das Komprimieren von Daten im RAM ermöglichen. Der Treiber befindet sich noch im Staging-Bereich.

Device Drivers  ---> 
  [*] Staging drivers  ---> 
    <M> Compressed RAM block device support

Das in dem Paket compcache enthaltene Initscript und die Konfigurationsdateien können auch mit dem angepassten Kernel genutzt werden. Mehr dazu im Abschnitt 4.4.

5.1.5 Devtmpfs

Im Standardkernel von Arch Linux ARM bis Version 3.1.4 war CONFIG_DEVTMPFS nicht gesetzt. Diese Option wird von udev ab Version 176 benötigt und muss natürlich auch im Custom Kernel aktiviert sein.

Device Drivers  --->
  Generic Driver Options  --->
    [*] Maintain a devtmpfs filesystem to mount at /dev
    [*]   Automount devtmpfs at /dev, after the kernel mounted the rootfs

5.2 Installation

Ist der Kernel konfiguriert, bestätigt man das Speichern der .config-Datei. Nach dem Kompilieren entstehen die Pakete linux-custom und linux-custom-headers, letzteres wird zum Bau von aufs2-util-git benötigt. Die Pakete lassen sich parallel zu linux und linux-headers installieren, das Kernelimage befindet sich unter /boot/uImage-custom. Um dieses Image zu booten, kann man behelfsweise /boot/uImage damit ersetzen3:

[root@alarm ~]# mv /boot/uImage /boot/uImage-alarm
[root@alarm ~]# cp /boot/uImage-custom /boot/uImage

Sollte nach einem Reboot der eigene Kernel nicht starten, stellt man das ursprüngliche Image wieder her (den Stick dazu an einen anderen PC anschließen) und kann so wieder den offiziellen Kernel nutzen. Ein unbeabsichtigtes Überschreiben von /boot/uImage durch ein Update - pacman geht ja davon aus, das diese Datei zum Paket linux gehört - lässt sich mit der Option NoUpgrade vermeiden, die neue Datei wird dann mit der Endung .pacnew versehen. Alternativ kann man natürlich auch die Kernelpakete vom Update ausschließen:

#/etc/pacman.conf
NoUpgrade = boot/uImage
#IgnorePkg = linux linux-headers

6 Alternative Bootloaderkonfiguration

Neben dem Erkennen und Laden des Kernelimages ist uBoot dafür verantwortlich dem Kernel das richtige Device der Rootpartition zu übergeben. Die in Abschnitt 3.2 beschriebene Methode schlägt u.U. fehl, wenn sich Anzahl und/oder Reihenfolge der von uBoot bzw. Kernel erkannten Speichermedien unterscheiden4. Solche Vermittlungsprobleme lassen sich ausschließen, indem der Kernel veranlasst wird, die Rootpartition anhand eindeutiger Merkmale eigenständig zu erkennen. Diese sind:

Beide Möglichkeiten werden nachfolgend beschrieben. Um die Bootloaderkonfiguration auch von Arch Linux ARM aus durchführen zu können, muss zunächst von dort aus wie in Abschnitt 3.1 beschrieben das Script install_uboot_mtd0.sh erneut aufgerufen werden. Die Frage Would you like to reset the uBoot environment? [N/y] beantworte man mit “Nein”.

6.1 Initial Ramdisk

Normalerweise wird eine initrd benötigt, um die zum Mounten der Rootpartition benötigten Treiber für Datenträger und Dateisysteme zur Verfügung zu stellen. Diese sind bei Arch Linux ARM jedoch fest in den Kernel integriert, weshalb das Kernelpaket keine initrd bereitstellt. Sie muss folglich nachträglich erstellt werden.

Unter Arch Linux (i686/x86_64) wird anstelle von initrd der Nachfolger initramfs genutzt, das mit mkinitcpio konfiguriert wird. Es werden nur zwei Hooks benötigt:

#/etc/mkinitcpio.conf
HOOKS="base udev"

Das initramfs für den angepassten Kernel wird wie folgt generiert:

[root@alarm ~]# mkinitcpio -v -k 3.0-custom -g /tmp/initramfs-linux.img

Es kann unter Arch Linux ARM nicht direkt genutzt werden, mit mkimage (aus dem Paket uboot-mkimage) lässt sich daraus aber die eigentliche initial ramdisk erstellen:

[root@alarm ~]# mkimage -A arm -O linux -T ramdisk -C gzip -a 0x00000000 -e 0x00000000 -n initramfs -d /tmp/initramfs-linux.img /boot/uInitrd 

Die Datei /boot/uInitrd wird von uBoot ohne weitere Konfiguration erkannt und eingebunden. Sodann sorgt udev für das Anlegen eines dem Label der Rootpartition (hier: root) entsprechenden Links unter /dev/disk/by-label/, der als Kernelparameter genutzt werden kann. Außerdem setze ich rootwait anstelle von rootdelay ein:

[root@alarm ~]# fw_setenv usb_set_bootargs 'setenv bootargs console=$console root=/dev/disk/by-label/root rootwait rootfstype=ext4 $mtdparts $usb_custom_params'

Anstelle des Labels sollte auch die UUID über den Link unter /dev/disk/by-uuid/ genutzt werden können, ich habe dies jedoch nicht ausprobiert. Problematisch ist dagegen die Verwendung der Schreibweisen root=LABEL=... und root=UUID=.... Beide haben nicht zuverlässig funktioniert, näheres im Forum.

6.2 GPT mit hybridem MBR

Speichermedien mit GPT können vom Linux Kernel ab Version 2.6.37 genutzt werden. Die notwendige Option CONFIG_EFI_PARTITION=y ist im ARCH-Kernel aktiviert und sollte natürlich auch beim Custom-Kernel ausgewählt sein.

Zum Anlegen einer GPT dient das Programm gdisk. Wurde der Stick bereits mit fdisk formatiert, kann gdisk die GPT unter Verwendung der im MBR vorhandenen Partitionstabelle auch nachträglich anlegen. Die notwendigen Schritte habe ich an meinem Linux-PC durchgeführt. Wie schon in Abschnitt 2.1 verwende ich wieder sdx stellvertretend als Device des USB-Sticks (von dem ich zuvor sicherheitshalber ein Backup angelegt habe).

[root@linux ~]# gdisk /dev/sdx

Warnhinweise sollte man beachten und das Programm ggf. mit 'q' abbrechen. Insgesamt gab es zwei Hürden zu nehmen, die ich hier genauer beschreibe:

6.2.1 Verkleinern der letzten Partition

Aus Redundanzgründen beansprucht die GPT auch einen Bereich am Ende des Speichermediums, der jedoch bereits Bestandteil der dritten Partition ist. Folglich vermeldet gdisk zunächst:

Warning! Secondary partition table overlaps the last partition by
33 blocks!
You will need to delete this partition or resize it in another utility.

Es war also erforderlich zunächst die letzte (dritte) Partition um 33 Blöcke (gemeint sind Sektoren á 512 Byte) zu verkürzen. Bei der Größenangabe für resize2fs ist die Blockgröße des Dateisystems zu berücksichtigen:

[root@linux ~]# dumpe2fs /dev/sdx3|grep "^Block"
dumpe2fs 1.41.14 (22-Dec-2010)
Block count:              3590912
Block size:               4096
Blocks per group:         32768

Die Anzahl der Blöcke muss folglich um 33*512/4096, also mindestens 5, reduziert werden5. Vor dem Verkleinern der Partition ist das Dateisystem zu überprüfen. Zuletzt kann schließlich mit fdisk auch die zugehörige Partition verkleinert werden.

[root@linux ~]# e2fsck -f /dev/sdx3
[root@linux ~]# resize2fs /dev/sdx3 3590907
[root@linux ~]# fdisk /dev/sdx

Das Verkleinern der Partition erfolgt einfach durch Löschen und erneutes Anlegen (d–3-n-p–3). Der vorgeschlagene Startsektor kann übernommen werden, der letzte Sektor ist jedoch um 33 auf 31252446 zu verringern, vgl. Abschnitt 2.1.

Anschließend genügt ein erneuter Aufruf von gdisk /dev/sdx zur Umwandlung des MBR in eine GPT. Sollten keine Warnungen erscheinen, beendet man dazu einfach mit 'w'.

6.2.2 Erstellung eines hybriden MBRs

Der Versuch den so manipulierten Stick nun testweise wieder am DockStar zu booten schlug fehl. Vermittels netcat stellte sich heraus, dass uBoot die Partitionen das Sticks nicht mehr zu lesen vermochte:

Loading file "/boot/uImage" from usb device 1:1 (usbdb1)
Failed to mount ext2 filesystem...
** Bad ext2 partition or disk - usb 1:1 **

Abhilfe sollte laut eines Forumsbeitrags das Erstellen eines hybriden MBR bringen, der nur die Bootpartition als erste Partition enhält. Hier die genaue Vorgehensweise mit gdisk unter Zuhilfenahmen der GPT Dokumentation.

Command (? for help): r

Recovery/transformation command (? for help): h

WARNING! Hybrid MBRs are flaky and dangerous! If you decide not to use one,
just hit the Enter key at the below prompt and your MBR partition table will
be untouched.

Type from one to three GPT partition numbers, separated by spaces, to be
added to the hybrid MBR, in sequence: 1
Place EFI GPT (0xEE) partition first in MBR (good for GRUB)? (Y/N): n

Creating entry for GPT partition #1 (MBR partition #1)
Enter an MBR hex code (default 83): 
Set the bootable flag? (Y/N): y

Unused partition space(s) found. Use one to protect more partitions? (Y/N): n

Recovery/transformation command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT).
The operation has completed successfully.

Erfreulicherweise erkannte uBoot den Stick nun wie bisher. Um den Vorteil der GPT zu nutzen brauchen wir noch die “Partition unique GUID” der Rootpartition. Diese bringt - unter Arch Linux ARM - ein erneuter Aufruf von gdisk nach Eingabe von 'i' und Partitionsnummer zu Vorschein:

Command (? for help): i           
Partition number (1-3): 2
Partition GUID code: 8EC76FBA-2272-45AF-A844-94ED164A1B86 (Unknown)
Partition unique GUID: 43152BE8-EA6D-47EE-A014-59C52C383DE0
First sector: 67584 (at 33.0 MiB)
Last sector: 2525183 (at 1.2 GiB)
Partition size: 2457600 sectors (1.2 GiB)
Attribute flags: 0000000000000000
Partition name: Linux filesystem

Mit dieser Information kann die Bootvariable wie folgt angepasst werden:

[root@alarm ~]# fw_setenv usb_set_bootargs 'setenv bootargs console=$console root=PARTUUID=43152BE8-EA6D-47EE-A014-59C52C383DE0 rootwait rootfstype=ext4 $mtdparts $usb_custom_params'

Vor dem Reboot sollte man eine etwaig vorhandene /boot/uInitrd wieder löschen oder umbenennen. Andernfalls wird der Bootvorgang nach Laden des Kernels nicht fortgesetzt.

7 Inbetriebnahme des DVB-Sticks

Ich betreibe am DockStar einen älteren DVB-T Stick von Freecom und beziehe mich im folgenden konkret auf diesen. Das Vorgehen bei anderen Sticks ist aber ähnlich, sofern im Linux-Kernel ein Treiber existiert.

7.1 Ermittlung des Treibers

Besteht Unsicherheit bezüglich des benötigten Treibers (Abschnitt 5.1.3), kann man den DVB-Stick zunächst an einen anderen Linux-PC anschließen 6. Falls dort ein geeigneter Treiber vorhanden ist, werden die benötigten Kernelmodule i.d.R. automatisch geladen und lassen sich z.B. mit lsusb|grep dvb aufzeigen, oder auch mit usb-devices:

P:  Vendor=14aa ProdID=0221 Rev=06.02
S:  Manufacturer=Digital TV Receiver
S:  Product=Digital TV Receiver
I:  If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=dvb_usb_dtt200u

Hier ist also dvb_usb_dtt200u das benötigte Modul. Danach lässt sich gezielt in den Quelldateien des Linux-Kernels Abschnitt 5 suchen, vgl. auch Linux Kernel in a Nutshell Kapitel 7. Man beachte die Ersetzung der Unterstriche durch Minuszeichen. In der Ausgabe findet man die gesuchte Kernelvariable CONFIG_DVB_USB_DTT200U.

[user@alarm linux-2.6.37]$ find -type f -name Makefile | xargs grep dvb-usb-dtt200u
./drivers/media/dvb/dvb-usb/Makefile:dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
./drivers/media/dvb/dvb-usb/Makefile:obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o

Möchte man keinen eigenen Kernel kompilieren, kann man auch die Treiber aus dem v4l-dvb Repository von linuxtv.org nutzen. Im AUR befindet sich ein Paket, das sämtliche Treiber installiert. Um die Auswahl auf die tatsächlich benötigten Treiber beschränken zu können, habe ich das PKGBUILD angepasst.

7.2 Firmware

Ob der (entsprechend konfigurierte) Kernel den DVB-Stick unterstützt, kann man z.B. anhand der (nachfolgend gekürzten) Ausgabe von dmesg feststellen. Wird nur eine (die oberste) Zeile ausgegeben, hat man entweder nicht den richtigen Treiber aktiviert oder dieser muss u.U. mit modprobe manuell geladen werden. Falls sich gar keine Module laden lassen, sollte ein Aufruf von depmod helfen.

 usb 1-1.4: new high speed USB device using orion-ehci and address 5
 dvb-usb: found a 'WideView WT-220U PenType Receiver (Typhoon/Freecom)' in cold state, will try to load a firmware
 dvb-usb: did not find the firmware file. (dvb-usb-wt220u-02.fw) Please see linux/Documentation/dvb/ for more details on firmware-problems. (-2)

Eine benötigte Firmwaredatei ist offensichtlich nicht vorhanden. Zwar enthält das Paket linux-firmware einige solcher Dateien, die hier gesuchte ist jedoch nicht dabei. Sie ist mit einer Suchmaschine schnell gefunden und wird im (ggf. zu erstellenden) Verzeichnis /lib/firmware/ gespeichert. Nach erneutem Anschluss des Sticks vermeldet dmesg

 dvb-usb: found a 'WideView WT-220U PenType Receiver (Typhoon/Freecom)' in warm state.
 dvb-usb: will use the device's hardware PID filter (table count: 15).
 DVB: registering new adapter (WideView WT-220U PenType Receiver (Typhoon/Freecom))
 DVB: registering adapter 0 frontend 0 (WideView USB DVB-T)...
 input: IR-receiver inside an USB DVB receiver as /devices/platform/orion-ehci.0/usb1/1-1/1-1.4/input/input0

7.3 Sendersuche

Um die hiesigen TV-Sender zu ermitteln, lässt sich scan aus dem Paket linuxtv-dvb-apps einsetzen.

[root@alarm ~]# scan /usr/share/dvb/dvb-t/de-Bundesland > channels.conf

Die im Paket enthaltenen Frequenzdateien sind u.U. nicht aktuell, ggf. findet man eine aktuellere Version hier. Alternativ kann man auch w_scan einsetzen, das ohne Frequenzdateien auskommt.

Die linuxtv-dvb-apps bieten auch eine primitive Möglichkeit der Aufnahme von Sendungen, dazu wird zunächst mit tzap im Hintergrund (z.B. via screen) ein Sender eingestellt

[root@alarm ~]# tzap -c channels.conf -r ZDF

Den Datenstrom leitet man dann einfach in eine Datei

[root@alarm ~]# cat /dev/dvb/adapter0/dvr0 > recording.ts

Komfortabler geht es mit dem VDR, mehr dazu in Abschnitt 8.

7.4 Fernbedienung

Wie die Ausgabe von dmesg in Abschnitt 7.2 zeigt, besitzt der Stick einen Infrarot-Empfänger. In /proc/bus/input/devices wird er als Eingabegerät (HID) aufgeführt:

I: Bus=0003 Vendor=14aa Product=0221 Version=0602
N: Name="IR-receiver inside an USB DVB receiver"
H: Handlers=kbd event0 

Folglich stehen die Chancen gut, dass sich die Fernbedienung mit dem devinput-Treiber von LIRC in Betrieb nehmen lässt. Die benötigte Konfigurationsdatei ist im dem Paket lirc-utils enthalten, muss aber noch an die richtige Stelle kopiert werden.

[root@alarm ~]# cp /usr/share/lirc/remotes/devinput/lircd.conf.devinput /etc/lirc/lircd.conf

Das Paket lirc-utils deckt eine Vielzahl von Fernbedienungen ab und setzt deshalb weitere Pakete voraus, die eigentlich nicht benötigt werden. Zur Kompilierzeit lässt sich LIRC aber durchaus auf einen einzelnen Treiber beschränken. Ich habe das PKGBUILD aus dem ABS entsprechend angepasst, /etc/lirc/lircd.conf ist in dem Paket dann bereits integriert.

Zur Konfiguration wird noch das Device des IR-Empfängers benötigt, gemäß obiger Ausgabe ist dies /dev/input/event0, langfristig wird man aber einen von udev erzeugten eindeutigen Link auf das Device nutzen wollen:

#/etc/udev/rules.d/99-lirc.rules
SUBSYSTEM=="input", ATTRS{idVendor}=="14aa", ATTRS{idProduct}=="0221", SYMLINK="input/ir"

Mit udevadm trigger --subsystem-match=input wird der gewünschte Symlink erzeugt. LIRC-Device und -Treiber sind in der Konfigurationsdatei einzutragen

#/etc/conf.d/lircd.conf
LIRC_DEVICE="/dev/input/ir"
LIRC_DRIVER="devinput"

Nach Start des LIRC-Daemons findet man mit irw die Tastencodes heraus. In einer lircrc-Datei können sie bestimmten Aktionen zuordnet7 werden.

[root@alarm ~]# /etc/rc.d/lircd start 
[root@alarm ~]# irw
0000000080010074 00 KEY_POWER devinput 

Die Codes lassen sich auch - unabhängig von LIRC - mit evtest ermitteln. Im Gegensatz zu irw listet es zunächst sämtliche Codes auf, die der IR-Empfänger erzeugen kann. U.U. sind dies mehr als die mitgelieferte Fernbedienung auszulösen vermag.

8 Einrichtung des VDR

Fertige PKGBUILDs für die aktuelle (Developer-)Version des VDR und eine Vielzahl an Plugins findet man im svn Repository des archvdr-Projekts. Diese sind jedoch relativ komplex und ziehen z.T. weit reichende Paketabhängigkeiten nach sich, um Funktionen zu realisieren, die auf dem DockStar nicht ohne weiteres genutzt werden können. Ich habe deshalb eigene, auf den gegebenen Einsatzzweck abgestimmte Pakete erstellt.

8.1 Konfiguration

Fürs erste genügt es, lediglich den VDR ohne weitere Plugins zu installieren. Auch die bereits integrierten Plugins werden nicht benötigt. Der Liemikuutio-Patch ermöglicht ein Umbenennen von Aufnahmen, ein weiterer Patch behebt ein Problem mit dem EPG Scan in Version 1.7.27.

In der Konfigurationsdatei /etc/conf.d/vdr sind die zu verwendenden Plugins (Abschnitt 8.3) und ggf. weitere Optionen einzutragen (siehe man vdr), nötigenfalls auch die Funktionen zum (Ent-)Laden der DVB-Treiber zu implementieren. Um VDR mit eingeschränkten Nutzerrechten zu betreiben und die regelmäßige Abspeicherung der EPG-Daten zu unterbinden8, habe ich folgende Optionen hinzugefügt:

#/etc/conf.d/vdr 
VDROPTIONS='... -E- -u vdr'

Soll VDR über eine am DockStar angeschlossene Fernbedienung gesteuert werden, fügt man noch die Option --lirc hinzu und erstellt im Verzeichnis /etc/vdr/ eine Datei remote.conf. Die Keycodes (zweite Spalte) müssen ggf. angepasst werden, vgl. Abschnitt 7.4.

Der User vdr muss noch angelegt werden. Als Mitglied der Gruppe video erhält er Zugriff auf die DVB-Devices unter /dev/dvb/adapter0/. Des weiteren benötigt er Schreibrechte auf die Konfigurationsdateien unter /etc/vdr.

[root@alarm ~]# useradd -m -G video -s /bin/bash vdr
[root@alarm ~]# chown -R vdr.vdr /etc/vdr

VDR legt Aufnahmen per Voreinstellung unter /video ab. Vorerst hängen wir dort das Homeverzeichnis des Users vdr ein. Dieser besitzt dort bereits die benötigten Schreibrechte. Zusätzlich erhalten andere Nutzer Lesezugriff.

[root@alarm ~]# chmod a+rx /home/vdr/
[root@alarm ~]# mkdir /video && mount -o bind /home/vdr/ /video

Die mitgelieferte DVB-S Kanalliste kann mit den linuxtv-dvb-apps (Abschnitt 7.3) durch eine lokal gültige ersetzt werden.

[root@alarm ~]# scan -o vdr /usr/share/dvb/dvb-t/de-Bundesland >  /etc/vdr/channels.conf

Damit VDR die Lokalisierung des Systems berücksichtigt, muss die Variable DAEMON_LOCALE auf 'yes' gesetzt sein.

#/etc/rc.conf
LOCALE="de_DE.UTF-8"
DAEMON_LOCALE="yes"

Anschließend wird VDR gestartet. Die Warnung aufgrund der fehlenden Fonts kann erst einmal ignoriert werden.

[root@alarm ~]# /etc/rc.d/vdr start
:: Starting vdr daemon                                                         [DONE] 
[root@alarm ~]# vdr: no fonts available - OSD will not show any text!

Im Problemfall nützliche Logmeldungen des VDR erscheinen in /var/log/user.log. Zur ersten Kontaktaufnahme kann man svdrpsend einsetzen.

8.2 Zusatzprogramme

8.2.1 Webinterface

Das in Perl geschriebene Programm Vdradmin-AM bietet eine komfortable Möglichkeit zur Interaktion mit dem VDR per Webbrowser

Das im AUR verfügbare Paket habe ich wie folgt überarbeitet:

Nach dem Start des Daemons ist die Weboberfläche im lokalen Netz unter http://ip.adresse.des.dockstar:8001 erreichbar (Benutzername: vdradmin, Passwort: vdradmin).

[root@alarm ~]# rc.d start vdradmind

Im Menüpunkt Konfiguration kann man die wichtigsten Einstellungen vornehmen, zumindest das Passwort sollte geändert werden. Innerhalb eines angegebenen lokalen Netzes, z.B. 172.16.1.0/24, erlaubt vdradmind einen Zugang ohne Passwort. Die Einstellungen werden in /etc/vdradmin/vdradmind.conf gespeichert. Man muss die Datei evtl. auch manuell editieren, z.B. um den in SERVERPORT definierten Port (Voreinstellung: 8001), auf den der Daemon lauscht, zu ändern. Für etwaige Kommandozeilenoptionen ist eine Datei im conf.d-Verzeichnis vorgesehen.

#/etc/conf.d/vdradmind
VDRADMIND_OPTS="--ssl --log 4 -L /var/log/vdradmind.log"

Die in diesem Beispiel aktivierte Beschränkung auf HTTPS-Verbindungen empfiehlt sich, wenn VDRAdmin-AM übers Internet erreichbar sein soll. Dazu muss das Paket perl-io-socket-ssl installiert, ein Verzeichnis /etc/vdradmin/certs angelegt und darin Zertifikat und Schlüssel hinterlegt werden. Letzteres ist in der Manpage von vdradmind anhand eines Beispiels beschrieben.

8.2.2 Werbeerkennung

Um zur Überbrückung von Werbung automatisch Schnittmarken setzen zu lassen, hat sich das das im AUR verfügbare Programm noad bewährt. Wird die Option --asd nicht benötigt (audio silence detection), kann man vor dem Paketbau im PKGBUILD ffmpeg aus der Liste der Abhängigkeiten (depends) herausnehmen und die configure-Option --with-ffmpeg entfernen. Die sonst unnötige Installation von ffmpeg würde samt weiterer Abhängigkeiten knapp 70 MB beanspruchen.

Damit das Programm schon während der Aufnahme seiner Tätigkeit nachkommen kann, lässt man es am besten direkt vom VDR starten. Dieser kennt für solche Zwecke die Option -r. Ein darüber angegebenes Script wird vor Aufnahmebeginn und nach der Aufnahme mit entsprechendem Parameter (before/after) aufgerufen.

#/etc/conf.d/vdr (fortgesetzt)
OPTIONS=" ... -r /usr/local/bin/vdrcmd.sh"

Der erste Parameter wird direkt weitergereicht, der zweite enthält das Aufnahmeverzeichnis, in dem noad auch die Datei marks, die die Schnittmarken enthält, ablegt.

#/usr/local/bin/vdrcmd.sh
#!/bin/bash
case "$1" in
  before) 
    noad before --online=2 --comments "$2" 
  ;;
esac

So aufgerufen, beginnt Noad seine Tätigkeit 60 Sekunden nach Aufnahmebeginn mit einem nice-Wert von 19.

8.3 Plugins

Bei der Installation von Plugins werden unter /etc/vdr/plugins weitere Konfigurationsdateien angelegt. Die Zugriffsrechte müssen dann erneut angepasst werden, auch nach einem Update bereits installierter Plugins:

[root@alarm ~]# chown -R vdr.vdr /etc/vdr

Außerdem müssen die Plugins explizit aktiviert werden, ggf. mit eigenen Optionen:

#/etc/conf.d/vdr (fortgesetzt)
VDRPLUGINS='-Pepgsearch -Pstreamdev-server -P"xineliboutput --primary --local=none --remote=37890" -P"graphlcd -d ax206dpf"'

8.3.1 Epgsearch

Mit dem Epgsearch-Plugin können Suchtimer erstellt werden. Aufnahmetimer werden dann automatisch angelegt, sobald ein passender Eintrag im EPG erscheint. Das Plugin informiert zudem per E-Mail über Timerkonflikte. Es wird auch von VDRAdmin-AM unterstützt.

8.3.2 Streamdev

Das Streamdev-Plugin stellt Live-TV als HTTP-Stream bereit, der z.B mit VLC oder MPlayer auf anderen Rechnern (Clients) im Netzwerk abgespielt werden kann. Auch Smartphones/Tablets können den Stream darstellen, auf Android-Geräten empfiehlt sich dafür VPlayer, der komfortabel aus AndroVDR heraus gestartet werden kann.

Auf dem DockStar wird nur das Streamdev-Server Plugin benötigt, das Streamdev-Client Plugin ist für andere Instanzen des VDR vorgesehen, die den Server als zusätzliche Empfangsquelle einbinden können.

Die IP-Adressen der Clients, die Zugriff auf den DockStar haben sollen, sind dort in der Datei streamdevhosts.conf im Unterverzeichnis des Plugins einzutragen. Dabei kann, wie in folgendem Beispiel, auch einfach das zugehörige Subnetz angegeben werden:

#/etc/vdr/plugins/streamdev-server/streamdevhosts.conf
172.16.1.0/24

Nach Aktivierung des Plugins findet man unter http://ip.adresse.des.dockstar:3000 ein spartanisches Interface mit URLs zu den verfügbaren Sendern. VDRAdmin-AM zeigt bei aktiviertem Plugin Links (m3u-Playlists) zu den Streams an.

Bei Bedarf kann der Stream on-the-fly in ein Format mit höherer Kompression umgewandelt werden, um trotz beschränkter Bandreite auch eine Übertragung via Internet zu realisieren, siehe Abschnitt 5 im README des Plugins.

8.3.3 Xineliboutput

Das Xineliboutput-Plugin generiert - ähnlich wie das Streamdev-Plugin - einen HTTP-Stream, erlaubt bei Verwendung spezieller Frontends wie vdr-sxfe aber auch eine Darstellung und Steuerung der kompletten Oberfläche des VDR samt OSD wie sie am TV-Ausgang einer DVB-Karte mit MPEG-Decoder erscheinen würde, so dass beispielsweise auch Einstellungen vorgenommen und Aufnahmen abgespielt werden können. VDRAdmin-AM unterstützt Xineliboutput seit Version 3.6.9.

Die Frontends sind normalerweise Bestandteile des Plugins. Da ein lokales Frontend auf dem DockStar mangels Monitorausgang nicht sinnvoll ist, habe ich dieses im Paket deaktiviert, die xine-lib wird daher nicht benötigt. Frontends (und folglich xine-lib) müssen nur auf den Clients installiert sein. Dazu lässt sich xineliboutput ggf. auch ohne VDR kompilieren:

Edit: Leider beendet sich vdr-sxfe bei einem ohne VDR kompiliertem Frontend seit geraumer Zeit mit einem Speicherzugriffsfehler.

Die Zugriffskontrolle erfolgt ähnlich wie beim Streamdev-Plugin.

#/etc/vdr/plugins/xineliboutput/allowed_hosts.conf
172.16.1.0/24

Um den VDR auf den Clients per Tastatur oder Fernbedienung9 steuern zu können, muss auf dem DockStar die Datei /etc/vdr/remote.conf angelegt bzw. erweitert werden. Für das OSD wird ferner ein Font benötigt, z.B. ttf-bitstream-vera. Auf einem Client startet man das Frontend beispielsweise mit

vdr-sxfe -A alsa -f --post tvtime:method=Linear,cheap_mode=1,pulldown=0,use_progressive_frame_flag=1 xvdr+tcp://ip.adresse.des.dockstar:37890

8.3.4 Graphlcd

Mit dem Graphlcd-Plugin lassen sich EPG und Menü des VDR auf einem graphischen Display darstellen. Ich nutze dafür diesen beliebten digitalen Bilderrahmen (DPF) und folgende Pakete.

Eine in graphlcd-base enthaltene udev-Regel sorgt dafür, dass Mitglieder der Gruppe uucp Schreibrecht auf die Devicedateien des DPF erhalten, vdr ist folglich dieser Gruppe hinzuzufügen.

[root@alarm ~]# usermod -a -G uucp vdr

Der Bilderrahmen muss vor dem Einsatz gehackt und in den Developer-Modus gebracht werden. Letzerer aktiviert sich 10 Minuten nach dem Anschließen auch selbständig, das Display kann also problemlos vorübergehend getrennt werden (z.B. per schaltbarem USB-Hub), das graphlcd-plugin greift dann beizeiten wieder darauf zu, ohne dass der VDR neu gestartet werden muss.

Das Display kann auch unabhängig vom VDR via lcd4linux bzw. lcdproc als Statusdisplay oder Konsole dienen, Einzelheiten siehe z.B. hier.

8.4 Weitere Aufnahmeverzeichnisse

Das Aufs-Dateisystem ermöglicht das gleichzeitige Einbinden mehrerer Verzeichnisse unter einem einzigen Mountpunkt. So lässt sich neben dem auf dem USB-Stick befindlichen Verzeichnis /home/vdr zusätzlich ein Verzeichnis auf der externen Festplatte als Aufnahmeverzeichnis nutzen. Im Gegensatz zur VDR-eigenen Lösung mit nummerierten Verzeichnissen erlaubt diese Vorgehensweise in gewissen Grenzen eine Steuerung dahingehend, auf welchem Datenträger die einzelnen Aufnahmen jeweils tatsächlich abgelegt werden. Bei nur einem Verzeichnis entspricht des Mounten mit Aufs im Ergebnis dem oben verwendeten mount --bind:

[root@alarm ~]# umount /video
[root@alarm ~]# mount -v -t aufs -o br:/home/vdr/ none /video/
none on /video type aufs (rw,relatime,si=eb4b663e)

Ein Verzeichnis auf der Festplatte wird nun einfach als weitere Schicht darüber gelegt10.

[root@alarm ~]# mkdir /hdd/video
[root@alarm ~]# chown vdr.vdr /hdd/video
[root@alarm ~]# mount -o remount,prepend:/hdd/video,xino=/hdd/video/.aufs.xino none /video/

Unter /video erscheinen jetzt die Inhalte von /hdd/video und /home/vdr gemeinsam, wobei ersteres als oberste Schicht (Branch) gleichlautende Dateien und Verzeichnisse des letzteren ggf. überdeckt. Die aktuelle Zusammensetzung des Aufs-Verbundes kann man aus dem sys-Verzeichnis auslesen:

[root@alarm]# cat /sys/fs/aufs/si_eb4b663e/br[01]
/hdd/video=rw
/home/vdr=rw

Neue (Aufnahme)-Verzeichnisse werden stets auf der obersten beschreibbaren Schicht br0, hier nun also unter /hdd/video, angelegt11. Beide Branches sind schreibbar eingebunden, damit z.B. auch bestehende Aufnahmen auf dem USB-Stick per Webfrontend gelöscht werden können. Beim gleichzeitigen Mounten mehrerer Verzeichnisse ist per Voreinstellung nur die oberste Schicht beschreibbar, der den obigen Befehlen entsprechende fstab Eintrag erfordert deshalb die Angabe der rw-Option:

#/etc/fstab (fortgesetzt)
none /video aufs br:/hdd/video=rw:/home/vdr=rw 0 0

Sollen auf der Festplatte vorerst keine weiteren Aufnahmen gespeichert werden, damit diese in absehbarer Zeit in den Standby geht und verbleibt, kann man das Verzeichnis /hdd/video aus dem Aufs-Verbund wieder entfernen. Letzteres ist jedoch nicht möglich, wenn momentan (via Aufs) auf das Verzeichnis zugegriffen wird, z.B. weil gerade eine Aufnahme angefertigt wird. In diesem Fall kann man die Branches aber vertauschen. Eine entsprechende Option kennt aufs leider (noch?) nicht, man muss stattdessen den unteren Branch entfernen und als oberen Branch wieder einbinden.

[root@alarm ~]# mount -o remount,del:/home/vdr,prepend:/home/vdr=rw,xino=/home/vdr/.aufs.xino none /video

Die ggf. laufende Aufnahmen wird nun weiterhin unter /hdd/video gespeichert, die nächsten hingegen unter /home/vdr angefertigt. Überschneiden sich die Aufnahmen zeitlich (gleiches Bouquet oder Twin-Receiver), wird also auf beide Datenträger gleichzeitig geschrieben. Sind die Aufnahmen auf der Festplatte abgeschlossen, kann diese schließlich aus dem Verbund genommen werden:

[root@alarm ~]# mount -o remount,del:/hdd/video/,xino=/home/vdr/.aufs.xino none /video

Die ursprüngliche Reihenfolge wird dann später wieder durch Hinzufügen von /hdd/video als oberstem Branch (prepend) erreicht. Für die nötigen Schritte nutze ich ein Script aufs_switch.sh, das auch die LED dem Status entsprechend anpasst12. Letzteres erfolgt unter Zuhilfenahmen des C-Programms aus Abschnitt 4.1. Der optional zu übergebende Parameter des Scriptes impliziert die gewünschte Anzahl und Rangfolge der Branches:

Status–2–1012
br0/home/vdr/home/vdr-/hdd/video/hdd/video
br1/hdd/video---/home/vdr
LEDabwechselndgrüngrün heartbeatorange blinkendorange

Bei erfolgreichen Statuswechsel liefert das Script den Rückgabewert 0, andernfalls 1, den aktuellen Status gibt es auf /dev/stdout aus. Das Script wird per cron aufgerufen, hier meine derzeitigen (mit crontab -e) vorgenommenen Einträge:

@reboot    /usr/local/bin/aufs_switch.sh
0 21 * * * /usr/local/bin/aufs_switch.sh -1 || /usr/local/bin/aufs_switch.sh -2 
0 0  * * * /usr/local/bin/aufs_switch.sh -1
0 9  * * * /usr/local/bin/aufs_switch.sh 2

Die erste Zeile sorgt lediglich für eine Anpassung der LED. Lässt sich /hdd/video um 21 Uhr nicht aushängen (üblicherweise wegen einer laufenden Aufnahme), werden die Branches zunächst getauscht (–2). Um Mitternacht wird der beabsichtigte Zustand (–1) ggf. erneut in die Wege geleitet, zusätzlich aber auch schon direkt nach der Aufnahme: Dies lässt sich durch Erweiterung des in Abschnitt 8.2.2 angelegten Scriptes realisieren.

#/usr/local/bin/vdrcmd.sh (erweitert)
#!/bin/bash
case "$1" in
  before) 
    noad before --online=2 --comments "$2" 
  ;;
  after)
    h=$(date +%k)
    if [ $h -ge 21 -o $h -lt 9 ]; then
      if [ -e $2/noad.pid ]; then
        screen -dm bash -c "inotifywait -e delete $2/noad.pid ; $0 $@"
      else
        sudo /usr/local/bin/aufs_switch.sh -1
      fi
    fi
  ;;
esac

Das Script wird mit den Rechten des Users vdr ausgeführt, der Aufruf von aufs_switch.sh erfordert aber Rootrechte und erfolgt daher via sudo. Der zugehörige Eintrag in /etc/sudoers wird mit visudo angelegt:

vdr ALL=NOPASSWD: /usr/local/bin/aufs_switch.sh

Neben der Uhrzeit überprüft das Script vor Aufruf von aufs_switch.sh, ob im Aufnahmeverzeichnis eine Datei noad.pid existiert. Ist dies der Fall, greift noad noch auf den Branch zu, ein Aushängen würde also fehlschlagen. Das Script startet dann einen Hintergrundprozesses, der das Script mit denselben Parametern erneut aufruft, sobald die pid-Datei entfernt wurde. Zu diesem Zweck müssen die Pakete screen und inotify-tools installiert sein.13

8.5 Netzwerkfreigabe

Die Aufnahmen sollen im lokalen Netzwerk zur Weiterverarbeitung (ggf. demultiplexen, Schnitt) verfügbar sein. Die Einrichtung des NFSv4-Servers ist im Wiki ausführlich erklärt. Es wäre möglich die beiden Verzeichnisse separat per NFS freizugeben, man kann aber auch den Aufs-Mountpunkt /video insgesamt zur Verfügung stellen. Bei entsprechend dimensionierter Festplatte wird man gewiss auch weitere darauf befindliche Verzeichnisse freigeben wollen, nachfolgend als Beispiel /hdd/share. Die Freigaben werden zunächst an Verzeichnisse unter /export/ gebunden

#/etc/fstab (fortgesetzt)
/hdd/share     /export/share         none bind     0 0
/video         /export/video         none bind     0 0

und per /etc/exports konfiguriert. Da das Aufs-Dateisystem keine UUID besitzt, muss zur Identifizierung eine id>0 zugeordnet werden.

#/etc/exports
/export           172.16.1.0/24(rw,no_subtree_check,async,no_root_squash,fsid=0)
/export/share     172.16.1.0/24(rw,no_subtree_check,async,no_root_squash,nohide)
/export/video     172.16.1.0/24(rw,no_subtree_check,async,no_root_squash,nohide,fsid=1)

Danach kann der NFS-Server gestartet werden. Damit dies automatisch beim Booten geschieht, wird er schließlich, wie alle oben erwähnten Daemons, in /etc/rc.conf eingetragen:

#/etc/rc.conf
DAEMONS=(syslog-ng network openntpd sshd !netfs compcache crond vdr rpcbind nfs-common nfs-server lircd irexecd vdradmind)

Edit: In util-linux 2.20–2 gab es einen Bug, der das Exportieren verschiedener Dateisysteme, einschließlich Aufs, verunmöglicht. Der Fehler ist in Version 2.20–3 behoben.

9 Kontakt

Olaf Bauer <obauer (at) freenet (dot) de>

bbs.archlinux.de

archlinuxarm.org/forum


  1. In den aufgeführten Verzeichnissen befinden sich evtl. von einigen Programmen benötigte Unterverzeichnisse, die (von diesen Programmen) nach einem Reboot u.U. nicht erneut angelegt werden. Auch stehen die Logdateien ohne weitere Vorkehrungen nach einem Absturz nicht mehr zur Fehlersuche zur Verfügung.

    Die Gesamtgröße der Logdateien (und also der RAM-Bedarf) lässt sich durch geeignete Einstellungen in /etc/logrotate.conf reduzieren. Evtl. lohnt auch eine Modifizierung von /etc/syslog-ng/syslog-ng.conf. Ratsam ist in diesem Zusammenhang auch eine Änderung des SSH-Ports in /etc/ssh/sshd_config auf einen Wert oberhalb von 1024. Andernfalls wird /var/log/auth.log und evtl. /var/log/btmp bald vor Hinweisen auf fehlgeschlagene Login-Versuche bersten. Wohlgemerkt bringt diese Maßnahme keine Sicherheit, sie hält lediglich die Logdateien klein, spart beim Einsatz von tmpfs also wertvollen RAM.

    Falls erforderlich, lässt sich eine Sicherung der Logdateien vor und Wiederherstellung nach dem Reboot leicht mit ramlog realisieren. Das zugehörige Script übernimmt auch das Einrichten des temporären Dateisystems, der Eintrag für /var/log muss beim Einsatz von ramlog also aus /etc/fstab entfernt werden. Die Kopien der Logdateien werden unter /var/log.hdd abgelegt. ramlog versucht per Cronjob auch eine tägliche Abgleichung im laufenden Betrieb vorzunehmen, die jedoch regelmäßig fehlschlägt, da die Logdateien von den laufenden Daemons zum Schreiben geöffnet sind. Ich habe deshalb den Programmaufruf in /etc/cron.daily/ramlog auskommentiert.

  2. Man sollte also vor Aufruf von makepkg sämtliche Hardware, die man nutzen möchte, anschließen (ggf. nacheinander) und in Betrieb nehmen, sowie Programme und Daemons starten, die auf Kernelmodule angewiesen sind (z.B. der NFS Server). Möchte man diese Funktion nicht nutzen, kann man make localmodconfig auch auskommentieren. Das Abfragen neuer Optionen erfolgt dann über make prepare.

  3. Eine andere Möglichkeit den zu bootenen Kernel festzulegen, besteht darin die uBoot Umgebungsvariablen usb_scan und usb_boot anzupassen (Abschnitt 3.2). Ich habe dazu ein Script fw_setuimage erstellt, das als optionalen Parameter den Suffix des Kernelimages erwartet:

    [root@alarm ~]# fw_setuimage custom
    

    Ohne Parameter werden die Variablen zurückgesetzt. Das Script benötigt die Programme fw_printenv und fw_setenv, aus dem uBoot environment von Jeff Doozan, siehe Abschnitt 6.

  4. Nachdem ich jüngst eine der speziell für den Betrieb am oberen USB-Anschluss der DockStar vorgesehenen 2,5" Festplatten “FreeAgent Go” erworben hatte, musste ich mittels Netzkonsole festellen, dass diese von uBoot nicht zuverlässig erkannt wurde: War beispielsweise neben der Festplatte nur der USB-Stick angeschlossen, wurde dieser von uBoot als erstes/einziges Device erkannt und gemäß Abschnitt 3.2 folglich sda2 als Rootpartition übermittelt. Aus Kernelsicht stellte sda jedoch die Festplatte dar, so dass der Bootvorgang nicht fortgesetzt werden konnte.

  5. Es schadet nichts das Dateisystems zunächst stärker zu verkleinern. Nach Verkürzen der Partition mit resize2fs kann es automatisch auf die dann maximale Größe erweitert werden. Bei der beschriebenen Vorgehensweise erübrigt sich dies:

    [root@linux ~]# resize2fs /dev/sdx3
    resize2fs 1.41.14 (22-Dec-2010)
    Das Dateisystem ist schon 3590907 Blöcke groß. Nichts zu tun!
    
  6. Hat man keinen Linux-PC zur Verfügung, kann man auch Hersteller- und Produkt-ID als Anhaltspunkte nehmen:

    [user@alarm linux-2.6.37]$ lsusb
    Bus 001 Device 006: ID 14aa:0222 WideView Technology Inc.
    

    Die dvb-Treiber befinden sich im Unterverzeichnis drivers/media/dvb/dvb-usb/. In dvb-usb-ids.h werden den IDs symbolische Namen zugeordnet:

    [user@alarm linux-2.6.37]$ cd drivers/media/dvb/dvb-usb
    [user@alarm dvb-usb]$ grep -i -E "14aa|0222" dvb-usb-ids.h
    #define USB_VID_WIDEVIEW            0x14aa
    #define USB_PID_WT220U_COLD             0x0222
    #define USB_PID_PCTV_450E               0x0222
    

    Nun sucht man nach einer Datei, die den symbolischen Namen des Herstellers und eines der Produkte innerhalb einer Zeile enthält

    [user@alarm dvb-usb]$ grep -E "USB_VID_WIDEVIEW.*(USB_PID_WT220U_COLD|USB_PID_PCTV_450E)" *
    dtt200u.c:  { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD)  },
    

    und wiederum im Makefile nach dieser Datei (ohne Endung). Die Ausgabe beinhaltet die gesuchte CONFIG-Variable.

    [user@alarm dvb-usb]$ grep dtt200u Makefile
    dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o
    obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o
    
  7. Beispielsweise könnte der Power-Knopf genutzt werden, um via irexec einen anderen Rechner per Wake-on-LAN zu booten:

    #/etc/lirc/lircrc
    begin
    button = KEY_POWER
    prog   = irexec
    repeat = 0
    config = wol 00:11:22:33:44:55
    end
    

    Diese Datei ist noch in der Konfiguration von irexec anzugeben

    #/etc/conf.d/irexec.conf
    IREXEC_OPTS="/etc/lirc/lircrc"
    

    bevor der zugehörige Daemon gestartet wird

    [root@alarm ~]# /etc/rc.d/irexecd start
    
  8. Per Voreinstellung speichert VDR die EPG-Daten alle 30 Minuten in /video/epg.data. Diese Datei wird von VDR selbst nicht benötigt und ihre regelmäßige Aktualisierung würde den USB-Stick nur unnötig belasten bzw. die Festplatte regelmäßig wecken. Fehlt die Datei, stehen allerdings die EPG-Daten nach einem Neustart des VDR (der z.B. dann erforderlich ist, wenn man ein Plugin ausprobieren möchte) nicht sofort wieder zur Verfügung. Als Kompromiss kann man die Datei in den RAM verlegen (siehe Abschnitt 2.3):

    #/etc/conf.d/vdr 
    VDROPTIONS='... -E /tmp ...'
    

    Um die Datei /tmp/epg.data auch über einen Reboot hinaus zu bewahren, verwende ich einen custom hook, der sie beim Herunterfahren unter /home/vdr/epg.data sichert und beim Booten wiederherstellt:

    #/etc/rc.d/functions.d/epg_save
    epg_save() {
      [ -e /tmp/epg.data ] && install -o vdr -g vdr -m 644 -t /home/vdr/ /tmp/epg.data
    }
    epg_restore() {
      [ -e /home/vdr/epg.data ] && install -o vdr -g vdr -m 644 -p -t /tmp /home/vdr/epg.data
    }
    add_hook shutdown_postkillall epg_save
    add_hook multi_start epg_restore
    
  9. Zur Steuerung des VDR über einen am Client angeschlossenen IR-Empfänger sind in remote.conf die auf dem Client(!) ausgelösten Keycodes einzutragen. LIRC muss auf dem Client eingerichtet und gestartet sein. Außerdem ist dem Aufruf von vdr-sxfe die Option --lirc hinzuzufügen.

  10. Die Verlagerung der von Aufs intern zur Inode-Verwaltung genutzen xino-Datei muss jeweils explizit angegeben werden. Andernfalls würde diese Datei je nach Anfangsstatus permanent auf einem der beiden Datenträger verbleiben und folglich den USB-Stick auch dann mit Schreibvorgängen belasten, wenn die Festplatte verfügbar ist, bzw. die Festplatte auch dann in Rotation versetzen, wenn für Aufnahmen lediglich der USB-Stick vorgesehen ist. Die eigentlich überflüssige Angabe none soll einer Verwechslung mit dem letzten Eintrag in /etc/fstab (Abschnitt 8.5) vorbeugen.

  11. Genauer gesagt werden - gemäß der Default Policy von Aufs bei mehreren beschreibbaren Branches - neue Dateien und Verzeichnisse stets in dem höchsten Branch, in dem sich das zugehörige Unterverzeichnis befindet, geschrieben: Existiert also auf br1 bereits eine dem Titel der anzufertigenden Aufnahme entsprechendes Verzeichnis, unter br0 jedoch nicht, so wird diese Aufnahme auf br1 gespeichert. Dieser Fall kann leicht bei Wiederholungen und Serien eintreten.

  12. Zudem stellt das Script sicher, dass die Aufnahmen tatsächlich auf br0 angefertigt werden. Dazu legt es vor einer Rotation der Verzeichnisse auf dem unteren bzw. nicht eingebundenen Branch zunächst sämtliche Aufnahmeverzeichnisse des oberen Branches als leere Verzeichnisse an. Leere Verzeichnisse aus vorherigen Aktionen sowie Whiteout-Dateien werden entfernt. Letztere entstehen beim Löschen von (Aufnahme-)Verzeichnissen, die in beiden Branches existieren.

  13. Im Zusammenhang mit Aufs gibt es noch ein ungelöstes Problem: Weist man VDR an, eine Aufnahme zu löschen, markiert er diese zunächst nur als gelöscht, um sie erst später, wenn keine Aufnahme läuft, tatsächlich zu entfernen. Ist zu diesem Zeitpunkt der Branch, auf dem die Aufnahme liegt, nicht eingebunden, schlägt der Löschvorgang fehl und wird nicht wiederholt, die Aufnahme beansprucht also weiterhin unbemerkt Speicherplatz und muss manuell gelöscht werden.