UNIXwork

Extended Attributes Teil 5: Solaris Commandline Tools

12. Dezember 2016

In Solaris sind Extended Attributes keine Key/Value-Paare, sondern werden als Dateien repräsentiert. Hinter jeder Datei im Dateisystem steckt eine weitere Datei-Hierarchie, die jedoch auf normale Dateien beschränkt ist, also keine Unterverzeichnisse oder Links erlaubt. Attribute sind somit nur Dateien, für die die selben Limits für die Dateigröße oder Namen gelten. Außerdem haben sie eigene Zugriffsrechte. Nur einen absoluten Pfad haben sie nicht.

Für den Zugriff auf Attribute über die Shell gibt es das runat Tool. Dieses macht nichts weiter als das Working-Directory auf das versteckte Attributverzeichnis zu setzen und dann ein gewünschtes Kommando auszuführen. Man kann auch einfach eine Shell für dieses Verzeichnis starten. Um die Attribute dann zu lesen, schreiben oder aufzulisten können prinzipiell alle Programme verwendet werden.

$ touch test.txt
$ runat test.txt sh
$ echo "xattr test string" > testattribute
$ echo "text/plain" > mime_type
$ ls
mime_type      SUNWattr_ro    SUNWattr_rw    testattribute
$ cat testattribute
xattr test string
$ exit

Kommen wir zu der Unterstützung für Extended Attributes in den Standard-Unix-Tools.

Dateisysteme werden nicht nur ZFS und UFS unterstützt, sondern auch NFS. Und betreibt man einen Solaris smb-Server werden die Extended Attributes dort auch über smb als NTFS Alternate Data Stream zur Verfügung gestellt.

Siehe auch: fsattr(5)

Autor: Olaf | 0 Kommentare | Tags: solaris, xattr, shell

Programme anhalten und fortsetzen

11. Dezember 2016

Es ist möglich Programme einfach anzuhalten, und zu einem beliebigen Zeitpunkt fortzusetzen. Zum stoppen schickt man das SIGSTOP-Signal an den Prozess, zum fortsetzen SIGCONT.

Kleine Demonstration, in der der Sekundenzeiger von xclock angehalten wird.

$ xclock -update 1 &
$ kill -STOP $!
$ kill -CONT $!
Autor: Olaf | 0 Kommentare | Tags: unix

Extended Attributes Teil 1: Linux Commandline Tools

05. Dezember 2016

Normale Attribute einer Datei sind Dinge wie der Besitzer und einfache Unix-Zugriffsrechte. Es gibt daneben aber noch erweiterte Dateisystemattribute. Das sind beliebige name/value-Paare, die man für Dateien setzen kann.

Linux unterstützt Extended Attributes in der Regel. Der Kernel muss das Feature aktiviert haben, was per Default der Fall ist, und das Dateisystem muss es ebenfalls unterstützen und gegebenenfalls mit einer bestimmten Option gemountet sein. Dies ist in gängigen Distributionen alles der Fall. Ich hab es unter CentOS, Debian, Ubuntu und openSUSE getestet und es ging alles. Die üblichen Dateisysteme (ext*, xfs, jfs, btrfs, f2fs) unterstützen Extended Attributes. Mit ZFS on Linux geht es auch. Allerdings unterstützt NFS unter Linux keine Extended Attributes.

Wie schon erwähnt hat jedes Extended Attribute einen Namen und einen Wert. Der Name besteht aus einem Namespace gefolgt von einem Punkt und dem eigentlichen Namen. Es gibt 4 Namespaces: user, trusted, security und system. Der user Namespace ist frei für alles benutzbar. Die anderen Namespaces werden unter anderem für SELinux (security) oder für Posix-ACLs (system) genutzt.

Um Extended Attributes zu modifizieren oder anzuschauen gibt es die beiden Commandline-Tools getfattr und setfattr. Unter Debian und Ubuntu müssen diese erst mit dem Paket attr nachinstalliert werden. CentOS und openSUSE haben die Tools out of the box dabei. Die Benutzung ist recht einfach.

$ echo "hello" > test.txt
$ setfattr -n user.test -v "xattr test string" test.txt
$ setfattr -n user.mime_type -v "text/plain" test.txt
$ getfattr test.txt
# file: test.txt
user.mime_type
user.test

$ getfattr -n user.test test.txt
# file: test.txt
user.test="xattr test string"

Auch einige andere Tools unterstützen Extended Attributes, leider jedoch nicht alle, oder sie können es, aber machen einen das Leben etwas schwerer. Verschiebt man eine Datei mit mv bleiben die Extended Attributes erhalten, falls das Zieldateisystem diese unterstützt. Wenn nicht werden diese heimlich ohne Warnung entsorgt. GNU cp kopiert sie standardmäßig nicht mit, allerdings mit der Option --preserve=xattr werden sie mitkopiert. Mit GNU tar muss man sowohl beim Packen als auch Entpacken die Option --xattrs angeben. Und wenn man mit Gnome über die GUI ein Archiv erstellt, werden keine Extended Attributes gespeichert. Nautilus hingegen kopiert sie brav mit.

Ich finde es ist eigentlich ein interessantes Feature, was erstaunlich wenig von Anwendungen genutzt wird. Eins der wenigen Beispiele wo Extended Attributes eingesetzt werden ist bei Apache, wo damit Mime-Types oder Charsets für Dateien festgelegt werden können.

Autor: Olaf | 0 Kommentare | Tags: linux, xattr, shell

Unbekannter Terminal-Typ

04. Dezember 2016

Beim Zugriff über ssh auf ein etwas älteres Unix wie z.B. Solaris 10 erhält man in vi oder manchen anderen Terminal-Anwendungen eine Fehlermeldung wie xterm-256color: Unknown terminal type Die Anwendung ist dann meistens nicht oder nur eingeschränkt benutzbar.

Die triviale Lösung ist einfach die TERM-Umgebungsvariable auf xterm zu setzen. Wenn man das nicht immer manuell machen will, kann man das einfach in der .profile Datei (oder .bash_profile, wenn die Login-Shell die bash ist) folgendes hinzufügen:

if [ $TERM = "xterm-256color" ]; then
	TERM=xterm
	export TERM
fi

Wenn man root-Rechte auf dem Server hat, gibt es auch noch eine andere Lösung. Es gibt eine Terminfo-Datenbank, die für die verschiedenen Terminal-Typen die Fähigkeiten enthält. Den fehlenden Eintrag für das xterm-256color Terminal kann man einfach hinzufügen.

Unter Solaris 10 finden sich die Terminfo-Dateien unter /usr/share/lib/terminfo. Dort gibt es für jeden möglichen Anfangsbuchstaben ein Verzeichnis, die xterm Einträge sind daher unter /usr/share/lib/terminfo/x. Dort muss eine Datei xterm-256color rein. Die ganz einfache Lösung wäre einfach die xterm-Datei zu kopieren. Ich hab hingegen die xterm-256color-Datei von einem Solaris 11 dort eingefügt. Beides funktioniert und sobald diese Datei da ist, erkennen Anwendungen auch das xterm-256color-Terminal.

Autor: Olaf | 0 Kommentare | Tags: unix, solaris, shell

Mehrere Wege führen zur FILE

15. September 2016

Die libc-Streams, repräsentiert durch FILE-Pointer, können nicht nur mit fopen erzeugt werden. Eine ganze Reihe an Funktionen erstellt ebenfalls diese Streams, die dann auch mit den stdio-Funktionen wie z.B. fprintf genutzt werden können.

fdopen

FILE *fdopen(int fd, const char *mode);

Mit fdopen erstellt man aus einem Unix-Filedescriptor ein FILE. Diese Funktion steht unter jedem POSIX-kompatiblen Betriebsystem zur Verfügung.

fmemopen

FILE *fmemopen(void *buf, size_t size, const char *mode);

Diese Funktion erstellt aus einem Buffer ein Stream. Der Buffer hat eine feste Größe, und gelangt der Stream an dessen Ende, wird nicht weiter geschrieben. Diese Funktion wurde durch die glibc eingeführt. Sie ist mitlerweile zwar im Posix-Standard, aber noch nicht überall verfügbar.

open_memstream

FILE *open_memstream(char **bufp, size_t *sizep);

Wie bei fmemopen erhält man mit dieser Funktion einen Stream für den Zugriff auf einen Buffer, allerdings wird dieser dynamisch mit malloc erstellt. Wenn nötig wird der Buffer auch automatisch vergrößert. Auch diese Funktion ist mitlerweile Posix-Standardisiert.

Beispiel:

#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
	char *buf;
	size_t len;

	FILE *f = open_memstream(&buf, &len);

	fprintf(f, "test\n");
	fprintf(f, "%d\n", 5);
	fprintf(f, "%s\n", "hello world");

	fclose(f);

	printf("%s", buf);
	free(buf);

	return 0;
}

funopen (BSD)

FILE *
funopen(void *cookie, int (*readfn)(void *, char *, int),
	int (*writefn)(void *, const char *, int),
	off_t (*seekfn)(void *, off_t, int), int (*closefn)(void *));

Die BSDs haben die sehr mächtige Funktion funopen, die einen Stream anhand eigener I/O-Funktionen erstellt. Die I/O-Operationen, die durch die libc-Funktionen, wie z.B. fgetc, fputc, fprintf, usw., erzeugt werden, werden dann an die eigenen I/O-Funktionen, die man funopen übergeben hat, weitergeleitet. So kann man für praktisch alles was man sich vorstellen kann ein FILE*-kompatibles Interfaces erstellen.

Diese Funktion ist nur unter den BSD-Betriebsystemen verfügbar. NetBSD hat sogar die noch mächtigere Funktion funopen2.

fopencookie (glibc)

FILE *fopencookie(void *cookie, const char *mode,
                     cookie_io_functions_t io_funcs);

Die glibc folgt dem BSD-Vorbild, leider waren sie natürlich nicht in der Lage, das bereits bestehende Interface zu übernehmen. Trotzdem macht fopencookie genau das gleiche wie funopen. Man erzeugt einen Stream mit eigenen I/O-Funktionen. Der Unterschied ist hier, dass die Funktionspointer nicht einzelnd übergeben werden, sondern es wird eine Struct, die die Pointer enthält, übergeben.

Autor: Olaf | 0 Kommentare | Tags: c, unix
Zurück Weiter