UNIXwork

Tags

c dav unix shell linux xattr solaris links x11 java rant fun webdav sync gnome apple benchmark network ldap oracle analytics xnedit macos windows graalvm bsd curl mac apache wtf virtualbox microsoft zfs sparc tomcat rhel freebsd arm

Spezielle Dateisystemattribute

10. Dezember 2016

Diesmal geht es nicht um Extended Attributes, jedoch um eine andere Art von Dateiattributen, die auch für den Kernel von Bedeutung sind. Mit diesen kann man beispielsweise Dateien unveränderbar machen oder einstellen, dass an die Datei nur neue Daten angehangen werden können, aber nicht der bisherige Inhalt überschrieben werden kann. Das ganze ist völlig unabhängig von den eigentlichen Rechten der Datei.

Beispiel unter Linux:

# chattr +i myfile

Danach ist die Datei unveränderbar. Selbst root kann die Datei nicht verändern, solange das Attribut gesetzt ist. Natürlich könnte root es entfernen und danach die Datei verändern.

Unter Solaris verändert man diese Attribute mit chmod. Interessant ist da z.B. das nounlink-Attribut.

# chmod S+vnounlink myfile
rm: myfile not removed: Not owner
# echo newcontent > myfile
# chmod S-vnounlink myfile
# rm myfile
# 

Das verhindert effektiv, dass man sich wichtige Dateien versehentlich löscht.

Applying Special Attributes to ZFS Files chattr (ubuntuusers Wiki)

progress - Fortschrittsanzeige in der Shell

09. Dezember 2016

Dauert cp mal wieder länger? Hat ja leider auch nicht mal eine Fortschrittsanzeige.

Mit dem Tool progress kann man sich jedoch für Programme wie cp, dd und andere den Fortschritt und Kopiergeschwindigkeit anzeigen lassen. Das Programm durchsucht /proc nach bestimmten Programmen und schaut für diese jeweils welche Dateien geöffnet sind und zeigt dann den Fortschritt für die größte Datei. Also wärend cp läuft einfach in einem 2. Terminal progress -w aufrufen:

$ progress -w
[25534] cp /storage/bigfile
	67.4% (673.8 MiB / 1000 MiB) 22.2 MiB/s remaining 0:00:14

Kopiert man allerdings mehrere Dateien mit cp, dann wird natürlich nur der Fortschritt der aktuellen Datei angezeigt.

Extended Attributes Teil 4: FreeBSD Syscalls

08. Dezember 2016

Um auf Extended Attributes in C zuzugreifen gibt es unter FreeBSD die extattr_*-Syscalls. Auch hier gibt es Varianten, die mit Pfaden arbeiten, welche für Filedeskriptoren und welche die im Falle eines symbolischen Links den Link selber betreffen.

Alle Funktionen erwarten als 2. Parameter ein int für den Namespace. Hierfür gibt es die Makros EXTATTR_NAMESPACE_USER und EXTATTR_NAMESPACE_SYSTEM.

Um an alle Namen der Attribute zu kommen gibt es die Funktion extattr_list_file (und noch die beiden anderen Varianten). Im Gegensatz zu Linux werden hier die Namen nicht einfach Null-terminiert hintereinander in den Buffer geschrieben, sondern vor jedem Namen steht zunächst ein einzelnes Bytes, welches die Länge des Namens angibt. Danach folgt der Name, jedoch ist dieser nicht Null-terminiert. Die anderen Funktionen sind alle recht trivial zu benutzen.

Da FreeBSD keine Tools hat, um Dateien mit ihren Extended Attributes zu kopieren, hab ich ein kleines Beispielprogramm geschrieben, dass alle Attribute aus dem User-Namespace von einer Datei auf eine andere kopiert.

Extended Attributes Teil 3: FreeBSD Commandline Tools

07. Dezember 2016

Extended Attributes sind auch unter FreeBSD name/value-Paare, die man beliebig für alle Dateien setzen kann. Im Unterschied zu Linux ist die Größe nicht auf wenige Kilobyte beschränkt. Desweiteren gibt es auch hier Namespaces (user und system), diese sind jedoch nicht Teil des Attribut-Namen.

Unter FreeBSD gibt es 4 Tools für den Zugriff auf Extended Attributes: getextattr, lsextattr, rmextattr, setextattr. Diese erwarten nach den optionalen Flags als erstes Argument immer den Namespace. Hier ein kleines Beispiel:

$ echo "hello" > test.txt
$ setextattr user test "xattr test string" test.txt
$ setextattr user mime_type "text/plain" test.txt
$ lsextattr user test.txt
test.txt        mime_type       test
$ getextattr user test test.txt
test.txt        xattr test string

Leider unterstützen die Userland-Tools wie cp und tar keine Extended Attributes.

Extended Attributes Teil 2: Linux Syscalls

06. Dezember 2016

Im vorherigen Teil ging es darum, wie man unter Linux Extended Attributes auf der Kommandozeile bearbeitet. Das Thema diesmal ist, mit welchen Syscalls man dies in C erledigen kann.

Für die 4 verschiedenen Operationen die man benötigt, nämlich listxattr, getxattr, setxattr und removexattr, gibt es jeweils 3 Syscalls.

#include <sys/types.h>
#include <sys/xattr.h>

ssize_t listxattr(const char *path, char *list, size_t size);
ssize_t llistxattr(const char *path, char *list, size_t size);
ssize_t flistxattr(int fd, char *list, size_t size);

ssize_t getxattr(const char *path, const char *name,
	             void *value, size_t size);
ssize_t lgetxattr(const char *path, const char *name,
	             void *value, size_t size);
ssize_t fgetxattr(int fd, const char *name,
	             void *value, size_t size);

int setxattr(const char *path, const char *name,
	             const void *value, size_t size, int flags);
int lsetxattr(const char *path, const char *name,
	             const void *value, size_t size, int flags);
int fsetxattr(int fd, const char *name,
	             const void *value, size_t size, int flags);

int removexattr(const char *path, const char *name);
int lremovexattr(const char *path, const char *name);
int fremovexattr(int fd, const char *name);

Die Syscalls mit dem l-Prefix liefern für den Fall dass path ein Symlink ist die Attribute des Symlinks selber, und nicht von der Datei, auf die der Symlink zeigt.

Bei den Syscalls mit dem f-Prefix übergibt man statt des Pfades einen Filedescriptor, den man mit open erhält.

Mit listxattr erhält man eine komplette Liste aller Extended Attributes für die Datei. Man muss einen vorher allozierten Buffer und seine Größe übergeben. Die Namen der Extended Attributes werden dann in diesen Buffer geschrieben, getrennt immer durch ein 0-Byte. Falls der Buffer zu klein ist, liefert die Funktion -1 zurück und setzt errno auf ERANGE. Man kann auch abfragen, wie groß der Buffer sein müsste, in dem man als size 0 übergibt. Der Rückgabewert ist dann die benötigte Größe des Buffers.

Hier ist ein Beispielprogramm, dass alle Extended Attributes einer Datei auflistet. Der Code um die Liste der Namen zu erhalten ist:

char *list = malloc(BUF_LEN);
ssize_t len = listxattr(path, list, BUF_LEN);

Wenn wir die Namen der Attribute haben, können wir den Wert mit getxattr erhalten. Diese Funktion erwartet ebenfalls einen Buffer, in den der Wert dann geschrieben wird. Auch hier kann man für size 0 angeben, um die Länge des Attributwerts zu erhalten.

Um das Beispielprogramm zu erweitern, dass es auch die Werte der Attribute ausgibt, könnte man die for-Schleife am Ende durch diesen Code ersetzen:

// print attributes
int begin = 0;
for(int i=0;i<len;i++) {
    if(list[i] == '\0') {
        char *xattr_name = list + begin;
        
        char value[0x10000];
        ssize_t vallen = getxattr(path, xattr_name, value, 0x10000);
        
        printf("%s: %.*s\n", xattr_name, (int)vallen, value);
        
        begin = i + 1;
    }
}

Es fehlt zwar die Fehlerbehandlung, es sollte jedoch immer funktionieren. Die Größe ist eh auf 64kb beschränkt, bei vielen Dateisystemen sogar noch weniger.

Kommen wir zu setxattr, mit dem man ein Extended Attribute setzt. Die Funktion erwartet als letzten Parameter ein flag. Ist dies 0, wird der Wert gesetzt, egal ob er schon existiert oder nicht. Bei XATTR_CREATE liefert die Funktion einen Fehler, wenn das Attribut schon existiert und bei XATTR_REPLACE gibt es einen Fehler, wenn der Wert nicht existiert.

xsetattr(path, "user.myattrname", value, valuelen, 0);

Bleibt zuletzt noch removexattr, dem man einfach nur den Dateipfad und den Attribut-Namen gibt, und der wird dann entfernt.

Zurück Weiter