UNIXwork

File Locking - flock vs fcntl

2017-12-19 17:57:24.0

Wer sich mit File-Locking beschäftigt, der wird vermutlich auf zwei Möglichkeiten stoßen: die Funktion flock und Locking mit fcntl. Es gibt zwei wichtige Unterschiede zwischen diesen beiden Funktionen.

Locks, die mit flock erstellt wurden, werden bei einem fork an den Kind-Prozess weitergegeben. Es wird jedoch nicht der Lock kopiert, wenn durch fork oder dup der Filedescriptor dupliziert wird, denn jeder Filedescriptor auf die gelockte Datei enthält nur eine Referenz auf den selben Lock. Der Lock bleibt bestehen bis entweder alle Filedeskriptoren geschlossen sind, oder explizit eine Unlock-Operation auf einen Filedescriptor mit diesem Lock, egal in welchem Prozess, ausgeführt wird.

Mit fcntl erstellte Locks werden bei einem fork hingegen gar nicht weitergegeben. Der Lock gilt immer nur für den Prozess, der ihn erstellt hat. Außerdem wird ein Lock entfernt, wenn auch nur ein Filedescriptor der gelockten Datei geschlossen wird.

Der andere große Unterschied ist, dass nur Locking mit fcntl Posix-spezifiziert ist. Die Funktion flock hingegen ist eine BSD-Erfindung, die jedoch auch von Linux übernommen wurde. Andere Unixe, wie z.B. Solaris, unterstützen flock gar nicht.

Außerdem unterscheidet sich auch das Interface der beiden Funktionen deutlich. Mit fcntl hat man ein bisschen mehr Schreibarbeit, dafür ist es auch möglich nur einen Bereich einer Datei zu locken, wärend flock etwas primitiver ist.

Locking mit fcntl:

int fd = open(path, O_RDWR);

struct flock lock;
memset(&lock, 0, sizeof(struct flock);
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
fcntl(fd, F_GETLK, &lock);

Locking mit flock:

int fd = open(path, O_RDWR);

flock(fd, LOCK_EX);

Die Verlockung ist vielleicht groß, flock zu nutzen, wenn man nur schnell und einfach eine ganze Datei locken möchte. Ich würde aber empfehlen, immer fcntl zu nutzen, außer man möchte wirklich Locks mit mehreren Prozessen teilen.

Autor: Olaf | 0 Kommentare | Tags: unix, c

Dateihierarchie-Überprüfung mit mtree

2017-12-18 19:19:03.0

Mit dem BSD-Tool mtree kann eine Datei-Hierarchie mit einer Spezifikation verglichen werden, wobei diese Spezifikation ebenfalls mit mtree erstellt werden kann. So kann man mit mtree geänderte Dateien finden, es ist jedoch auch möglich, Dateien, die nicht der Spezifikation entsprechen, zu löschen oder geänderte Dateirechte wiederherzustellen.

Nehmen wir mal an, man hat ein paar Dateien:

$ find .
.
./file2
./dir
./dir/abc
./dir/ccc
./file1

Bevor man mit mtree etwas vergleichen kann, benötigt man eine Spezifikation der Dateien. Diese erstellen wir mit mtree -c.

$ mtree -c > ../spec
$ cat ../spec
#      user: olaf
#   machine: m2.fritz.box
#      tree: /Users/olaf/Desktop/test
#      date: Mon Dec 18 18:50:28 2017

# .
/set type=file uid=501 gid=20 mode=0644 nlink=1 flags=none
.               type=dir mode=0755 nlink=5 size=160 \
                time=1513618591.304192231
    file1       size=6 time=1513619185.055667000
    file2       size=13 time=1513619203.579709605

# ./dir
dir             type=dir mode=0755 nlink=4 size=128 \
                time=1513618608.749249207
    abc         size=6 time=1513618604.803276546
    ccc         size=5 time=1513618611.066866426
# ./dir
..

..

Nun hat man eine Spezifikation, mit der man später die Dateien vergleichen kann.

$ touch dir/abc
$ echo "Hello World" > file1
$ mtree < ../spec 
dir/abc changed
    modification time expected Mon Dec 18 18:36:44 2017.803276546 found Mon Dec 18 18:56:22 2017.582045000
file1 changed
    size expected 6 found 12
    modification time expected Mon Dec 18 18:46:25 2017.055667000 found Mon Dec 18 18:57:03 2017.596168115

Wie man sieht, werden standardmäßig nur wenige Eigenschaften im der Spezifikation gespeichert, man hat jedoch eine große Auswahl an sogenannten keywords, die pro Datei gespeichert werden sollen. Diese können mit der -K-Option angegeben werden.

$ mtree -c -K sha256digest

Das Tool ist zwar ein BSD-Tool und unter Linux standardmäßig nicht anzutreffen, ich habe aber zumindestens einen Port gefunden. Und unter Ubuntu gibt es das Paket freebsd-buildutils, welches das Tool fmtree enthält.

Autor: Olaf | 0 Kommentare | Tags: bsd, shell

Das TAR-Format

2017-12-17 21:27:17.0

Eine tar-Datei besteht immer aus 512 Bytes großen Blöcken. Jede Datei im Archiv hat einen Header-Block gefolgt von weiteren Blöcken für den Dateiinhalt. Verzeichnisse oder Links haben logischerweise keine Content-Blöcke sondern nur den Header-Block. Am Ende des Archivs werden dann zwei 512 Bytes Blöcke mit Null-Bytes angehängt, die das Ende markieren.

Der Header besteht fast nur aus Plain-Text, nur ein paar Null-Bytes kommen vor. Integer-Werte werden als Oktal-Strings gespeichert. Auch sind alle Felder des Headers an fixen Adressen, was das parsen vereinfacht. Eine Beschreibung des Headers findet sich auf der Open Group Webseite.

Da der Header nur begrenzt viel Platz hat, hat das Original UStar-Format (Unix Standard TAR) ein paar Limitierungen. Z.B. können Dateinamen oder Pfade nicht beliebig lang sein. Auch die Größe einzelner Dateien ist durch die spezielle Kodierung auf 8 Gb begrenzt. Erweiterungen dieses Formats, wie das neue POSIX Format pax oder auch GNU tar und star, haben diese Begrenzung nicht.

Wer tar-Dateien im alten UStar-Format in seinem eigenen Programm erstellen will, für den habe ich dieses Beispielprogramm, welches als Argument ein oder mehrere Dateipfade erwartet und dann eine tar-Datei daraus erstellt, die auf stdout ausgegeben wird.

Autor: Olaf | 0 Kommentare | Tags: tar, c

Tearing-Problem unter Gnome

2017-12-16 18:36:06.0

Es ist manchmal ein Trauerspiel mit Linux. Viel zu oft hab ich schon nerviges Tearing erlebt, mit verschiedenen Ursachen. Aktuell mit Intel iGPU und der Gnome Shell. Ich bin mir nicht sicher, ob das Problem auch mit anderen GPUs auftritt. Sicher bin ich mir dabei, dass bei mir die Gnome Shell der Schuldige ist.

Daher hier ein (temporärer) Fix für eins der vielen Tearing-Probleme.

  1. Öffnen des Gnome Shell Debugger (Looking Glass): Drücke Alt-F2 und gib lg ein

  2. Dort muss folgender Befehl eingegeben werden:

    Meta.disable_unredirect_for_screen(global.screen)

Eine Alternative ist diese Gnome Extension.

Autor: Olaf | 0 Kommentare | Tags: gnome, linux

gdb unter macOS installieren und signieren

2017-12-15 18:58:07.0

Wer unter macOS den Debugger gdb benötigt, muss ein paar Hindernisse überwinden. Zur Zeit meiner ersten Bekanntschaft mit OS X war gdb noch bei Xcode dabei, dieser wurde dort jedoch durch lldb ersetzt.

Installieren kann man gdb am einfachsten mit Homebrew.

$ brew install gdb

Das Sicherheitssystem in macOS erlaubt es gdb jedoch nicht, seine Aufgabe zu erfüllen, daher muss man gdb erst noch signieren und die System Integrity Protection muss deaktiviert werden.

Da ich nicht einfach die Anleitung, die ich selber befolgt habe, klauen möchte, verlinke ich einfach darauf.

Autor: Olaf | 0 Kommentare | Tags: macos, gdb
Zurück Weiter