Hallo,
Es wäre eher ungeschickt (wenn nicht gar ein Sicherheitsrisiko) solche Dinge zu sharen. Ich will bei mir möglichst viele Dinge vom Zufall steuern lassen, in so eine Umgebung passt fork einfach nicht rein (egal ob Flat-Memory oder Segmentierung).
Einverstanden. Ein wirkliches Hindernis ist das also nur, weil du ein paar Designentscheidungen so triffst.
An BusyBox hab ich auch schon gedacht aber ich denke auch das basiert auf fork/exec, auch wenn man dort sicher einiges möglichst einfach gestaltet hat. Ich schätze ich sollte mir dessen Quellcode mal etwas genauer ansehen. Hat damit hier schon jemand Erfahrung?
Als ich mich damit befasst habe, ging es mir um meinen schon damals veralteten Palm IIIx (m68k-Kern), also Linux 2.0. Die NOMMU-Patches unterstützten damals ganz einfach kein fork(), sondern nur vfork(). Entsprechend sollte Busybox - wenn es für NOMMU kompiliert wurde - auch kein fork benutzen können.
Mein Plan war eigentlich die Kompatibilität auf der libc-Ebene zu erreichen, da ich einen Micro-Kernel realisieren möchte wird dort eh sehr vieles von dem drin sein was bei klassischen POSIX-Systemen im Kernel steckt.
Richtig, du kannst aber nicht alles komplett in der libc verstecken (zumindest nicht, wenn es ein bisschen performant sein soll), wenn der Kernel nicht ein paar Grundfunktionen unterstützt. Für fork() wäre das zumindest die Möglichkeit, einen Descriptor zu vererben; dann könnte die libc die Segmente kopieren/sharen und alles wäre gut. Wenn dein Kernel dieses Konzept auch nicht kennen soll, wirst du wohl ganz einfach ohne auskommen müssen.
Die libc sollte kein POSIX-Emulator sein.
Allerdings mache ich mir es da einfacher, indem mein gedachter (Mikro)kernel einfach die grundlegenden Unixkonzepte unterstützt (z.B. fork) und die libc das dann nur weitergibt. Der Kernel (und die Treiber, so es die betrifft) kennt also die Konzepte.
Ich denke ich kann fork schon aus technischen Gründen nicht im Kernel unterstützen und eigentlich will ich das auch nicht.
Dann lass es einfach sein und lebe mit den Konsequenzen.
In meinen Augen ist fork obsolet. Bei einzelnen Programmen die fork nutzen um mehrere Aufgaben parallel zu erledigen (z.B. ein HTTP-Server der für jede TCP-Connection forkt, ich weiß dass das ein doofes Beispiel ist weil es dafür eigentlich Async-IO gibt) sind Threads aus heutiger Sicht die bessere Wahl [...]
Ein fork-basierter HTTP-Server lässt sich extrem einfach implementieren, hat gute Performance und skaliert unter Linux recht gut. Laut einer älteren Analyse besser, als wenn man poll() nutzt. Und z.B. Apache nutzt mehrere Mechanismen (Threads, Forks, im Prozess ausgeführte Module) parallel, was sicherlich auch Gründe hat; den würde ich aber nicht als Performancemeister bezeichnen.
Ich möchte in meinem OS nicht nur deswegen kein fork haben weil ich es technisch nicht vernünftig umsetzen kann sondern auch weil ich es als Sicherheitsrisiko einstufe. Nebst dessen das für den ersten Fall Threads billiger sind als fork.
Dann lass auch die Emulation weg...
Du wirst mit einer unglaublich langsamen fork()-Emulation jedenfalls keinen Spaß haben
Wieso sollte die Variante in der libc "unglaublich langsam" sein? Klar wird dadurch jeder interessante libc-Aufruf um ein paar CPU-Takte ausgebremst aber das dürfte kaum spürbar sein solange kein fork aktiv ist und wenn fork aktiv ist dann wird zwar stärker gebremst aber es handelt sich ja auch nur um einen relativ kurzen Abschnitt im Programm.
Ein fork-basierter Webserver wird nicht nur ein paarmal forken, sondern ständig und sehr oft. Dann kommt neben dem ständigen Overhead auch noch der Aufruf von fork() selbst dazu - und der ist ziemlich teuer, besonders wenn du die betroffenen Segmente nicht gemeinsam nutzen möchtest.
In diesem Zusammenhang kann ich mir vorstellen das BusyBox ein schwieriges Programm ist weil es wahrscheinlich recht viele verschiedene Anwendungsszenarien für fork enthält.
Ich vermute, es gibt für die meisten Applets ein paar "#ifdef NOMMU"-Anweisungen und damit zwei verschiedene Implementationen. Ein paar Applets laufen aber nicht (wimre ist die ash nicht NOMMU-tauglich, sondern nur die hush).
Meiner Meinung nach dürfte die bash gerade in die Kategorie fallen die ich mit der libc-Emulation anvisiere.
Dann patche lieber die bash selbst, als ein per Design kaputtes Konzept in die libc zu schreiben (oder nimm eine externe lib_böse_routinen für sowas).
Wenn du es nebenbei schaffst, die bash gebrauchbar auf NOMMU-Systeme zu portieren, dann freut sich bestimmt auch Upstream.
Sicher? Davon bin ich nicht so überzeugt, immerhin würde das bedeuten das die bash von wesentlichen POSIX-Traditionen abweichen würde und damit würde man eventuell riskieren das sie auf anderen Plattformen nicht mehr so toll funktioniert.
Naja, wenn die Bash unter NOMMU-Linux vernünftig funktionieren kann, wäre das schon ne nette Sache. Nutzen wird es wohl eher niemand, weil an Speicherfragmentierung bei der Bash wohl niemand gedacht hat. Ansonsten wirst du sie wohl für deine Verhältnisse forken müssen.
Oder du guckst dir die Dash bzw. ähnliche Projekte an. Die sind meist eh schneller, fast komplett kompatibel und vermutlich mit saubereren Sourcen.
Ich könnte mir durchaus vorstellen das eine entsprechende Anfrage mit "entweder Du kannst POSIX oder Du lässt es" beantwortet wird. Ich hab mit so einer Antwort auch kein Problem, wenn die bash explizit ein POSIX-Programm sein soll dann ist das Okay für mich.
Dazu müsstest du erstmal einen minimalinvasiven Patch an die Entwickler schicken.
Gruß,
Svenska