2013 stellte Apple den kontrovers diskutierten neuen Mac Pro vor. Statt einer klassischen Workstation war dieser deutlich kleiner, hatte nur einen CPU-Sockel, keine wechselbaren Grafikkarten und keine Slots für herkömmliches Storage. Für Erweiterungen waren nur mehrere Thunderbolt-Ports vorgesehen. Dieses radikal neue Konzept löste bei einigen wenigen vielleicht Begeisterung aus, die Mehrheit war dem eher abgeneigt. Nicht nur war die CPU- und GPU-Power stark begrenzt, wer PCIe- oder Storage-Erweiterungen braucht, muss dies extern realisieren, was nicht nur deutlich teurer ist, sondern auch mehr Platz verbraucht und umständliche und hässliche Verkabelungen zur Folge hat.
Zusätzlich dazu hielt es Apple auch nicht für nötig, den Mac Pro zu updaten, obwohl Intel fleißig neue CPU-Generationen gebracht hat. Damit ist der Mac Pro mitlerweile völlig zum Witz geworden. Überteuert war er schon 2013 (im Vergleich mit anderen Workstations versteht sich), im Jahr 2017 hingegen ist es nur noch lächerlich, wenn man den alten Preis noch für veraltete Hardware zahlen muss.
Das hat nun auch Apple eingesehen. Zum einen haben sie geringfügig die Preise für das aktuelle Modell angepasst (natürlich immer noch lächerlich überteuert), zum anderen angekündigt, dass sie den Mac Pro komplett überdenken. Sie geben zu, dass das aktuelle Modell für viele Pro-User ungeeignet ist. In Zukunft soll der Mac Pro wieder ein modulares Design haben, so dass es auch für Apple deutlich einfacher ist, Upgrades zu liefern.
Interessant ist auch, dass laut Apple das Kühlungssystem, was das eigentlich Innovative am aktuellen Mac Pro sein sollte, nicht ordentlich funktioniert. Damit ist eigentlich auch der letzte Vorteil, den Fans der Apfel-Tonne immer betont haben, widerlegt.
Jetzt muss man natürlich warten, was Apple letztendlich entwickelt. Es besteht natürlich immer die Möglichkeit, dass sie eine noch schlechtere Idee haben.
Es ist möglich, dass mehrere Prozesse Zugriff auf die gleichen File-Deskriptoren haben. Beispielsweise werden bei einem Fork alle File-Deskriptoren kopiert. Der Kind-Prozess kann dann auf die selben Dateien oder Sockets zugreifen.
Man kann auch nach einem Fork oder mit nicht-verwandten Prozessen File-Deskriptoren austauschen. Dies geht über Unix Domain Sockets mit den Funktionen sendmsg und recvmsg.
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
Die Nachricht vom Typ struct msghdr
hat so einige Felder, die man erstmal ausfüllen muss.
struct msghdr {
void *msg_name; /* optional address */
socklen_t msg_namelen; /* size of address */
struct iovec *msg_iov; /* scatter/gather array */
size_t msg_iovlen; /* # elements in msg_iov */
void *msg_control; /* ancillary data, see below */
size_t msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags on received message */
};
Das Feld msg_name
wird hier nicht benötigt, daher setzen wir msg_name
und msg_namelen
auf 0.
struct msghdr msg;
msg.msg_name = NULL;
msg.msg_namelen = 0;
Die eigentlichen Daten überträgt man mit dem Feld msg_iov
, ein Array an Buffern, wie man es von writev kennt. Man erstellt ein Array mit struct iovec
Elementen und gibt jeweils einen Pointer auf die Daten und die Länge an. Es reicht natürlich, nur einen Buffer anzugeben.
struct iovec iov[1] ;
iov[0].iov_base = (void*)buf;
iov[0].iov_len = len;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
Jetzt wollen wir noch einen Filedescriptor übertragen. Für solche (und andere) Zwecke gibt es das Feld msg_control
für folgende struct:
struct cmsghdr {
size_t cmsg_len; /* Data byte count, including header
(type is socklen_t in POSIX) */
int cmsg_level; /* Originating protocol */
int cmsg_type; /* Protocol-specific type */
/* followed by
unsigned char cmsg_data[]; */
};
Nach den Feldern der struct müssen also noch zusätzliche Daten im Speicher liegen. Für den Fall, dass man Filedeskriptoren übertragen möchte, müssen ein oder mehrere Integer folgen. Es empfiehlt sich zunächst einen statischen Buffer mit der entsprechenden Größe anzulegen. Hierfür gibt es das Makro CMSG_SPACE
, was die Größe des Buffers liefert.
char cmsg_buf[CMSG_SPACE(sizeof(int))];
Anschließend setzen wir die Felder der struct.
struct cmsghdr *cmsg = (struct cmsghdr*)cmsg_buf;
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS; // indicates fd payload data
Jetzt fehlt nur noch der Filedescriptor. Dieser muss, wie schon erwähnt, hinter der struct liegen. Mit dem Makro CMSG_DATA
erhält man einen Pointer auf die Payload-Data.
int *data = (int*)CMSG_DATA(cmsg);
*data = fd;
Jetzt setzen wir nur noch msg_control
und msg_controllen
, sowie msg_flags
. Danach kann sendmsg
aufgerufen werden.
msg.msg_control = cmsg;
msg.msg_controllen = CMSG_LEN(sizeof(int));
msg.msg_flags = 0;
sendmsg(sock, &msg, 0);
Um einen Filedescriptor zu empfangen nutzt man recvmsg
, was in der Benutzung ähnlich ist. Dort kommt die selbe struct für die Message zum Einsatz und man muss die Felder auch genauso setzen.
Ich hab ein kleines Beispielprogramm geschrieben, welches nach einem Fork eine Datei im Elternprozess öffnet und anschließend den Filedescriptor dieser Datei an den Kindprozess sendet. Das Kind empfängt dann den Filedescriptor und schreibt etwas in diese Datei.
Software, die das GNU-Buildsystem verwendet, lässt sich mit ./configure
gefolgt von make
und make install
kompilieren und installieren. Mit diesem Artikel möchte ich auf ein paar Features dieses Buildsystems hinweisen.
Build-Verzeichnis
Anstatt das configure-Script im Root-Verzeichnis der Software auszuführen, geht dies auch von einem anderen aus. Dies hat den Vorteil, dass alle erstellten Dateien in einem anderen Verzeichnis landen, also z.B.:
mkdir build
cd build
../configure
make
Nicht nur alle von configure erstellten Dateien landen dann im build-Verzeichnis, sondern auch alle Objekt-Dateien und was sonst noch so durch make erstellt wird.
config.site
Ein weiteres interessante Feature ist, dass das configure-Script am Anfang die Datei prefix/share/config.site lädt. Diese kann normale Shell-Kommandos enthalten. Anstatt also immer per Hand die gewünschten Umgebungsvariablen zu setzen, oder Dinge wie das libdir anzupassen, kann man diese Einstellungen über die config.site erledigen. Siehe Setting Site Defaults.
Make Targets
Alle kompilierten und andere durch make erstellte Dateien entfernt man mit make clean
. Mit make distclean
kann man auch alle durch configure erstellte Dateien löschen. Desweiteren gibt es noch make maintainer-clean
, das alle reproduzierbaren Dateien löscht, bis auf das configure script und andere Dateien, die für configure erforderlich sind. Auch interessant ist make check
, was Tests für die Software ausführt (falls welche vorhanden sind).
Desweiteren möchte ich noch mal meinen Artikel über den DESTDIR-Parameter bei make install
erwähnen.
Als Fedora-User war RPM Fusion mein Repository der Wahl für Grafiktreiber, Codecs und andere Software, die nicht im offiziellen Fedora-Repo vorhanden war. Nach meinem Wechsel auf EL7 (erst Scientific Linux, dann CentOS) musste ich mir eine neue Quelle dafür suchen, denn RPM Fusion hat EL7 nicht unterstützt. Doch jetzt, mehr als 2 Jahre nach dem Erscheinen von RHEL7, ist RPM Fusion auch für EL7 verfügbar. Aber noch nicht so ganz, denn die Infrastruktur besteht zwar bereits, die Anzahl der Pakete ist hingegen sehr überschaubar. Das dürfte sich aber in den nächsten Wochen, Monaten oder Jahrhunderten hoffentlich ändern.
Okay, genug gelästert. Ich danke allen Beteiligten für ihre Arbeit.
Kommentare
Andreas | Artikel: Datenanalyse in der Shell Teil 1: Basis-Tools
Einfach und cool!
Danke Andreas
Rudi | Artikel: Raspberry Pi1 vs Raspberry Pi4 vs Fujitsu s920 vs Sun Ultra 45
Peter | Artikel: XNEdit - Mein NEdit-Fork mit Unicode-Support
Damit wird Nedit durch XNedit ersetzt.
Danke!
Olaf | Artikel: XNEdit - Mein NEdit-Fork mit Unicode-Support
Anti-Aliasing hängt von der Schriftart ab. Mit einem bitmap font sollte die Schrift klassisch wie in nedit aussehen.
Einfach unter Preferences -> Default Settings -> Text Fonts nach einer passenden Schriftart suchen.
Peter | Artikel: XNEdit - Mein NEdit-Fork mit Unicode-Support
Mettigel | Artikel: Raspberry Pi1 vs Raspberry Pi4 vs Fujitsu s920 vs Sun Ultra 45
Ich hatte gedacht, dass der GX-415 im s920 deutlich mehr Dampf hat als der Raspi4.
Mein Thinclient verbraucht mit 16 GB RAM ~11 W idle, das ist das Dreifache vom RP4. Das muss man dem kleinen echt lassen... Sparsam ist er.
Olaf | Artikel: Raspberry Pi1 vs Raspberry Pi4 vs Fujitsu s920 vs Sun Ultra 45
Ergebnisse von der Ultra 80 wären natürlich interessant, insbesondere im Vergleich mit dem rpi1.
kosta | Artikel: Raspberry Pi1 vs Raspberry Pi4 vs Fujitsu s920 vs Sun Ultra 45
ich hätt hier zugriff auf Ultra-80 4CPU 4GB 2x Elite3D.