Beiträge anzeigen

Diese Sektion erlaubt es dir alle Beiträge dieses Mitglieds zu sehen. Beachte, dass du nur solche Beiträge sehen kannst, zu denen du auch Zugriffsrechte hast.


Nachrichten - FlashBurn

Seiten: 1 ... 4 5 [6] 7 8 ... 43
101
OS-Design / Re: Threads blockieren und wieder aufwecken
« am: 28. October 2011, 20:25 »
Zitat von: svenska
Ist (mehrfaches) präventiv-wecken sinnvoll?
Das ist ja meine Frage ;)

Zitat von: svenska
Ist es überhaupt sinnvoll, einen Thread aufzuwecken, der garnicht schläft?
Es kann eben den Fall geben das Thread A den wait Syscall (aus welchem Grund auch immer) macht und bevor dieser ausgeführt werden kann kommt der Scheduler und Thread B ist dran, Thread A soll laut Thread´s B infos auf das Aufwecken warten. Thread B erledigt seine Sachen und weckt Thread A auf, dieser schläft noch gar nicht und ein resume() ist in meiner Welt immer erfolgreich (hat keinen Rückgabewert) und damit ist die Sache für Thread B auch beendet. Thread A kommt wieder auf die CPU und legt sich endlich schlafen, dumm nur das es wohl für immer sein wird ;)

Das Problem existiert durchaus, deswegen mussten sich ja auch die Linuxer Gedanken darüber machen.

Zitat von: svenska
Um den Deadlock zu vermeiden, reicht ja ein einzelner erneuter Weckversuch, nachdem der betroffene Thread garantiert einmal dran gewesen ist (und die Möglichkeit hatte, endgültig einzuschlafen).
Was ist, wenn der Thread aber eine so niedrige Priorität hat das er ne Weile nicht mehr dran kommt bzw. eventuell gar nicht mehr, weil der andere Thread ne höhere Priorität hat?

Dann hätten wir da auch noch die Sache damit das man damit ja mehrmals in den Kernel muss, für einen Syscall der eigentlich immer klappen sollte.

Zitat von: svenska
Außerdem im Fall der Race Condition fällt mir jedenfalls kein Grund ein, warum ein grundloses Aufwecken sinnvoll sein sollte.
Ich bin mir nicht sicher ob ich verstanden habe was du damit meinst, aber mit meinem Counter würde der Thread B den Counter von Thread A erhöhen (resume() für Thread A) und wenn Thread A wieder an der Reihe ist (also den wait() Syscall ausführt), dann würde er nicht blockieren, sondern gleich wieder zurück gehen.
102
OS-Design / Re: Threads blockieren und wieder aufwecken
« am: 28. October 2011, 19:52 »
Zitat von: svenska
Wenn der aufweckende Thread weiß, dass der andere Thread eigentlich hätte schlafen müssen, dann kann er das Wecken ja später nochmal probieren und so den Deadlock vermeiden.
Das würde bei mir dann heißen das ich im Kernel so lange probiere den Thread aufzuwecken bis das geklappt hat (weil sowas überlässt man nicht dem User, zumal es dann noch unperformanter wird). Glaubst du wirklich dass das eine gute Idee ist?

Ich denke mit meinem Counter bin ich ganz gut dabei (entspricht auch in etwa der Lösung von Linux und co). Die Frage die ich mir da dann stelle ist halt, sollte man es zulassen das der Counter nen größeren Wert als 1 annimmt oder nicht?

Wie sollte man eigentlich entscheiden ob ein Thread A ein Thread B aufwecken darf?
103
OS-Design / Re: Threads blockieren und wieder aufwecken
« am: 28. October 2011, 18:56 »
@svenska

Ganz allgemein ist das Problem, wie geht man damit um, dass ein Thread blockiert und bevor er das erfolgreich abschließen kann, wird er von einem anderen Thread aufgeweckt. Da müssen keine Locks im Spiel sein.
104
OS-Design / Re: Threads blockieren und wieder aufwecken
« am: 28. October 2011, 17:55 »
Zitat von: jidder
Ich muss meine Aussage leider relativieren. Nach kurzem Googeln scheint es so, dass das in dem Umfang nie im offiziellen Kernel eingeführt wurde.
Im Linux-Kernel ist es drin und ich musste jetzt feststellen, dass die Futex´s doch auch für inter-process-communication genutzt werden und nicht nur für intra.
105
OS-Design / Re: Threads blockieren und wieder aufwecken
« am: 28. October 2011, 17:25 »
Das finde ich ja gut, genau die selbe Idee (Semaphore im SharedMem für IPC) wollte ich für meine Pipe´s nutzen :D So schlecht kann die also nicht sein.

Trägt nur leider nix zum Thema bei ;) Werde aber trotzdem mal gucken, ob die auch irgendwelche Race-Conditions haben und wie die gelöst wurden.

Edit::

@bluecode
Also soweit ich es verstanden und gefunden habe, machen sie genau dass, was ich in meiner Idee schon meinte. Nen Counter der bei jedem resume() erhöht wird und bei jedem wait() erniedrigt wird. So umgeht man diese Race-Condition.

OT::

Dazu habe ich mal wieder gesehen wieso ich den Linux-Kernel aus Design-Sicht nicht mag ;)
106
OS-Design / Re: Threads blockieren und wieder aufwecken
« am: 28. October 2011, 17:05 »
Zitat von: bluecode
Normalerweise werden Semaphores vollständig vom Kernel implementiert, da tritt das Problem wohl nicht auf.
Dumm nur das hier wir den Code dazu schreiben ;)

Mir geht es ja genau darum, wie man das Problem entweder vermeidet oder noch besser damit umgeht.

Zitat von: bluecode
Was du suchst ist das was man unter Linux Futex
Jap, die kenne ich, nur die Sachen mit den Race-Conditions habe ich mir noch nicht angeguckt, werde ich aber gleichmal machen.
107
OS-Design / Threads blockieren und wieder aufwecken
« am: 28. October 2011, 16:33 »
Also erstmal was gibt es alles, wo ein Thread blockiert?

Mir fallen spontan ein, sleep(), semaphoreAcquire() und wait(). Die ersten beiden machen mir keine Probleme, aber letzterer. ICh weiß gar nicht ob es normalerweise unterstützt wird, das ein Thread ein warten kann bis er wieder geweckt wird? Ich wollte das für eine UserSpace-Sachen nutzen.

Um mal ein ganz einfaches Bsp. für mein eigentliches Problem zu bringen.

CPU A:
Ein Thread will die Semaphore bekommen. Also holt er sich den Lock, dekrementiert den Counter und stellt fest das er warten muss. Der Lock wird wieder freigegeben und der Thread wird blockiert.

CPU B:
Ein Thread will die Semaphore freigeben. Also holt er sich den Lock (der auf CPU A gerade freigeben wurde), inkrementiert den Counter und stellt fest das er einen Thread aufwecken muss. Der Lock wird wieder freigegeben und der Thread wird aufgeweckt (genau der von CPU A).

Problem ist nun, dass es ja passieren könnte, dass CPU B den Thread schneller aufweckt als CPU A den Thread blockieren konnte. Lösung dafür wäre auch ne Art Semaphore, nämlich das Aufwecken wäre ein Freigeben und das Blockieren ein Anfordern.

Mit meinem wait() Syscall (und dem entsprechendem resume()) könnte es nun aber passieren, dass die Aktion resume() mehrmals aufgerufen wurde und der Thread also bei mehreren wait()´s nicht blockiert.

Daher meine Frage, was wäre besser, ne Semaphore zu nutzen wo der Counter beliebig groß werden kann oder ne Semaphore zu nutzen wo der Counter max 1 werden kann?

Oder ist das totaler Schmarrn?
108
OS-Design / Re: Flexibles und einfaches Prozess erzeugen
« am: 25. October 2011, 11:21 »
Zitat von: taljeth
Ich glaube, dafür suchen wir auch seit längerem erfolglos einen sinnvollen Anwendungsfall, aber POSIX erlaubt es halt.
Sprich wir könnten und also langsam mal darauf einigen das es eigentlich nicht nötig ist (sofern man nicht volle POSIX Kompatibilität anstrebt).

Zitat von: taljeth
Ja, dafür gibt es Anwendungsfälle. Ob du die in deinem OS unterstützt oder nicht, ist deine Sache.
Ok, das ist doch mal ein Wort. Wissen das dann die Anwendungen alle, dass da noch mehr zur gleichen Zeit drin rumpfuschen?

Wenn dem so ist, würde ich grundsätzlich sagen, jede Datei wird fürs Schreiben exklusiv geöffnet, will man das mehrere Anwendungen in eine Datei schreiben können, muss man das explizit angeben. Ich denke das ist der beste Kompromiss.

Zitat von: taljeth
"The  child  process  shall  have its own copy of the parent's file descriptors.  Each of the child's file descriptors shall refer to the same open file description with the corresponding file descriptor of the parent."
Ich tue mich schon immer mit Gesetzestexten schwer, aber wiederspricht sich das nicht?

Ich verstehe das so, das jedes Kind seine eigene Kopie == eigener FD mit Startwerten des originalen FDs. Der zweite Satz sagt dann aber wiederrum, dass die FD´s der Kinder auf die FD´s der Eltern zeigen sollen, was ja keine Kopie wäre. Was denn nun?
Zumal würde das nicht auch ne Kette geben der man folgen müsste, weil der FD der Eltern kann ja wieder auf den FD der Großeltern zeigen usw.
109
OS-Design / Re: Flexibles und einfaches Prozess erzeugen
« am: 24. October 2011, 16:35 »
Zitat von: svenska
Identische FDs in verschiedenen Anwendungen ist relativ schwierig hinzukriegen... und wenn du es schaffst, ist es außerdem kaputt.
Es ging z.B. um die Situation die bei einem fork() passiert und soweit ich es verstanden habe, nutzen dann Eltern und Kind-Prozess den gleichen FD mit dem gleichen Datei-Zeiger.

Zitat von: svenska
Wenn mehrere Prozesse bestimmte Daten aus einer Datei lesen, während mehrere andere Prozesse die gleichen Daten in die Datei reinschreiben - absolut gleichzeitig - wie verhält sich dein VFS dann? Werden die geschriebenen Daten in der endgültigen Datei schön durchmischt oder überlebt nur eine geschriebene Version, oder garkeine? Bekommen die Lesenden mal die eine, mal die andere Fassung der Daten oder bleibt für diese die Welt konsistent? Gelten die Daten als geschrieben, wenn die Datei geschlossen wurde, sie mit fsync() synchronisiert wurde, die Daten mit write() geschrieben wurden oder nach fünf Sekunden? Liest jeder Lesethread etwas anderes oder lesen alle immer das gleiche?
Sind alles durchaus Probleme, aber die eigentliche Frage ist doch, muss es wirklich möglich sein, dass mehrere Anwendungen in ein und die selbe Datei (mit dem gesharten Datei-Zeiger) schreiben können? Wo passiert das in der Praxis (bitte keine Log-Dateien)?

Selbst wenn mehrere Anwendung in ein und die selbe Datei schreiben (mit ihren eignen FDs), ist das irgendwo nötig? Zumal ich da ja sowieso sage, jedes write() gilt als eine atomare Einheit.
Wann die Daten wirklich in die Datei kommen, liegt doch am Programmierer. Denn in der libc wird ja gepuffert (wenn man es nicht abstellt).

Was das Lesen betrifft, kann ein vermischen alter und neuer Daten nur vermieden werden, wenn alles im VFS abläuft. Bei Memory-Mapped-Files wird es durchaus vorkommen, dass eine Anwendung einen Mix aus alten und neuen Daten liest.

Der einfachste Weg ist immernoch, nur exklusives Schreiben zuzulassen (mit der Ausnahme "APPEND_WRITE", obwohl sich auch diese Fälle auch mit exklusivem Schreiben lösen lassen). Denn mir erschließt sich immernoch nicht der Sinn hinter dem zeitgleichen Schreiben in eine Datei, das bringt doch nur Probleme mit sich.
110
OS-Design / Re: Flexibles und einfaches Prozess erzeugen
« am: 24. October 2011, 14:55 »
Zitat von: svenska
Bitte den Satz nochmal lesen. "Wo mehrere reinschreiben .... können."
Ich habe den Satz schon richtig gelesen, da steht aber auch was von mehreren die lesen und da ist es doch egal ob da nun einer und mehrere in die Datei schreiben, dass sollte immer kein Problem darstellen (es sei denn, mehrere die gleichzeitig mit dem selben FD, in verschiedenen Anwendungen, lesen).

Zitat von: svenska
Man kann das zwar verbieten, wie Windows das tut (eine zum Schreiben geöffnete Datei ist exklusiv geöffnet), aber "schön" ist das dann nicht.
Scheint aber zu funktionieren ;)

Aber die Frage bleibt, abgesehen von einem "APPEND_WRITE", wo wird das noch verwendet (Schreiben oder auch Lesen mit dem selben FD in unterschiedlichen Anwendungen)?
111
OS-Design / Re: Flexibles und einfaches Prozess erzeugen
« am: 24. October 2011, 13:49 »
Zitat von: svenska
Logfiles, wo mehrere reinschreiben und lesen können?
Was ist eigentlich das Problem, dass mehrere aus einer Datei lesen können (aber jeder sein eignen FD hat)? Ich sehe da erstmal keins. Was das Schreiben betrifft, muss das ganze im VFS serialisiert werden (und damit ist kein Mapping mehr möglich, sondern die zu schreibenden Daten müssen zuerst ins VFS).

Das 2 (oder mehr) Anwendungen den gleichen FD "sharen", damit z.B. immer am Ende der Datei geschrieben wird, könnte man doch dadurch "emulieren", dass man halt ne Art "APPEND_WRITE" Modus hat, der immer an das Dateiende anhängt, egal wo der Datei-Zeiger gerade ist, oder?

Was ich mir aber kaum vorstellen kann, ist dass es ein Szenario gibt, wo 2 (oder mehr) Anwendungen den gleichen FD "sharen" und aus der Datei lesen, weil da kommt ja nur Müll bei raus.
Das mehrere Threads daraus lesen kann ich mir noch vorstellen, aber da wäre ja nur ein FD in der libc (und die würde das serialisieren). Die Anwendung könnte z.B. mehrere Threads haben und alles lesen immer einen Block aus der Datei und verarbeiten den.

Sicherlich könnte man das Szenario auch auf mehrere Anwendungen ausdehnen, aber was soll das bringen, nur um die Ergebnisse dann wieder in eine neue Datei mit "APPEND_WRITE" zu schreiben?

Was Pipe´s betrifft, denke ich das sie so oder so ein Sicherheitsrisiko darstellen (genauso wie Semaphoren). Denn wenn der Reader blockiert und auf neue Daten wartet, braucht ja der Writer einfach keine mehr schicken und schon kann man nen Service "ärgern". Auch geht das ganze umgedreht, der Service will dem Clienten was schicken, der Client blockiert und wartet auf Daten und der Service schickt einfach keine.
Das ist aber nen Datenstruktur-Problem.

Ich musste dann auch feststellen, dass Futex´s nur für Intra-Process-Communication und nicht für Inter-Process-Communication sind und damit für meine Pipe´s eher ungeeignet. Bin mir nur nicht sicher, woran das liegt, ob daran das es so vllt einfacher ist oder zwecks irgendwelcher Sicherheitsprobleme.
112
OS-Design / Re: Flexibles und einfaches Prozess erzeugen
« am: 21. October 2011, 22:12 »
Zitat von: erik
Also bei meiner Idee würde der Kernel auch nichts kopieren, die Pipe (eigentlich ja nur ein bestimmter Bereich simplen Speichers) ist in beiden Prozessen identisch vorhanden (natürlich an unterschiedlichen virtuellen Adressen).
Mit Problemen meinte ich dann auch sowas wie einfach ignorieren was der Kernel sagt und die alten Daten einfach überschreiben auch bei Multithreading zugriff auf eine Pipe würde sowas nicht möglich sein. Diese Variante wäre halt einfach sicherer, aber langsamer.

Zitat von: erik
Und da sind wir wieder an dem Punkt wo Du versuchst alles so kompliziert wie irgend möglich zu machen.
Und ich sehe das halt anders ;) Für mich ist diese Variante einfacher als das irgendwie im Kernel zu machen und irgendwelche Lücken zu berechnen und sowas. Du hast einfach nen Counter wieviele Bytes in der Pipe sind und dadurch weißt du ob weiter reinschreiben/rauslesen kannst oder nicht.

Zitat von: erik
Nebst dessen das wenn die zwei Prozesse sich per Semaphore o.ä. nur im User-Space synchronisieren das dann wieder die Möglichkeit für ein DoS besteht weil einer den anderen dauerhaft blockieren kann, auch soetwas ist bei meiner Idee grundsätzlich ausgeschlossen.
Mal davon abgesehen das man sowas mit nem Timeout lösen kann (was ich aber grundsätzlich nicht mag), bin ich mir gerade nicht sicher wie das genau in Linux umgesetzt ist. Das werde ich mir morgen mal im Source-Code angucken. Ansonsten hast du recht.

Zitat von: erik
Wo würde man was sparen? Mit meiner Idee ist pro Message nur ein Syscall im Writer und nur ein Syscall im Reader erforderlich (also insgesamt nur 4 Ring-Wechsel), billiger wirst Du das bestimmt nicht bekommen.
Wenn ich nun aber mehrere Msgs da reinschreibe besteht bei meiner Variante die Möglichkeit das gar nicht in den Kernel gegangen werden muss und der Reader fängt muss nicht erst anfangen wenn die Msg komplett geschrieben ist (könnte man aber trotzdem so machen).
Es könnte ja die Situation geben, dass der Writer Daten reinschreibt, den Reader aufweckt und noch während der Reader die Daten ausliest/mit ihnen arbeitet, kann er schon neue Daten reinschreiben ohne das er den Reader benachrichtigen muss.

Der Vorteil deiner Variante sind die Popup-Threads, ansonsten finde ich das mit den "Lücken" verwalten wesentlich komplizierter als ne normale Pipe. Eigentlich wäre deine Pipe mehr nen SlabAllocator malloc() mit Hilfe des Kernels. Denn so wie ich es verstanden habe, bekommt der Writer den Pointer ja vom Kernel und es kann durchaus sein, dass davor und danach noch Bereiche sind die schon älter sind.
Bei einer klassischen Pipe liest/schreibt man immer nacheinander rein ohne das da Lücken entstehen oder man aufpassen müsste wo man jetzt hinschreiben kann und wie groß der Bereich ist. Das ist also schon wesentlich komplizierter als es sein müsste.

Zitat von: erik
PS.: Linux benutzt ja auch das Konzept eines monolithischen Kernels, also kann das nicht so schlimm sein. SCNR
Mal davon abgesehen, dass ein MikroKernel schöner vom Design her ist und theoretisch sicherer (wenn man denn ne IOMMU hat), aber auf jeden Fall stabiler (weil ein falscher Pointer im Treiber nicht im Kernel ist und das ganze System mitreißen muss) ist, kann man auch "schöne" Monolithen/Hybriden schreiben.
113
OS-Design / Re: Flexibles und einfaches Prozess erzeugen
« am: 21. October 2011, 21:25 »
Zitat von: erik
Es geht dabei auch nicht um Sicherheit sondern darum das der Kernel dem Writer quasie einen Bereich in der Pipe zusichert und der Writer diesen Bereich ungestört füllen kann ohne auf andere Threads im selben Prozess Rücksicht nehmen zu müssen
Achso. Bei einer Pipe denke ich immer nur an eine 1:1 Beziehung und nicht an 1:n oder m:n. Ich denke es sollte auch nicht so schlimm sein, wenn meine nur eine 1:1 Beziehung zulässt. Ist halt ne Beschränkung die aber die Sache einfacher machen kann.

Zitat von: erik
Einen expliziten Flush empfinde ich als unnötig weil ja jede geschriebene Message (durch den Send-Syscall) auch möglichst schnell zugestellt wird, der Kernel wartet nicht bis eine Menge X in der Pipe ist, das ergibt keinen Sinn.
Da habe ich mich dann wieder unglücklich ausgedrückt. Mit Flush war eigentlich das Senden (und damit den Reader "erstellen") gemeint.

Nur fällt mir auf, dass ich bei meiner Variante das Problem hätte, dass ich gar nicht mitbekomme wieviel nun in der Pipe noch frei ist, sprich ob der Reader auch schon fertig ist.
Diese ganzen Probleme hat man mit in den Kernel kopieren und wieder rauskopieren natürlich nicht ;)

Ich überlege gerade, ob man die Lese-/Schreibpointer nicht einfach dem Reader und Writer überlässt, aber die ersten 4byte der Pipe sind ne UserSpace Semaphore. Der Writer würde die Semaphore inkrementieren (und wenn diese am Größenlimit ist, würde er in den Kernel gehen und blockieren) und der Reader würde sie dekrementieren (und wenn sie kleiner 0 ist, würde er blockieren).
Der Reader würde immer dann in den Kernel gehen und den eventuell blockierten Writer wecken, wenn die Semaphore vom Maximum um eins dekrementiert wird und der Writer würde immer dann in den Kernel gehen und den eventuell blockierten Reader wecken, wenn die Semaphore 0 wird. Dadurch würde man sich einige Syscalls sparen und man müsste weniger in den Kernel.

Wo genau siehst du denn ein Problem wenn der Writer den Wert der Semaphore beeinflussen kann? Ich meine sowas gibt es ja auch für Linux, also kann es nicht so schlimm sein ;) Oder hängt es damit zusammen, weil man dadurch eventuell einen Service irgendwie schlecht beeinflussen kann?

Bei dieser Variante hätte man zwar keine Popup-Threads, aber ich würde meiner ursprünglichen Idee, dass 2 Threads parallel daran arbeiten können wieder näher bzw. hätte sie erreicht.
114
OS-Design / Re: Flexibles und einfaches Prozess erzeugen
« am: 21. October 2011, 20:38 »
Zitat von: erik
Das is ja mal tolles Deutsch. Sorry aber damit kann ich echt nüschtz anfangen.
Sorry, ich weiß auch nicht warum ich gerade sowas beim Nochmal-Drüber-Lesen immer übersehe. Sollte heißen, dass das VFS weiß welche Dateien ein Prozess alles geöffnet hat.

Zu deiner Pipe. Wow ;) Gutes Bsp. wie sehr es vom Betrachter abhängt, ob etwas einfach oder kompliziert ist.

Zitat von: erik
Ich denke ich würde so eine Pipe auf jeden Fall unidirektional machen und die Verwaltung der Schreib/Lese-Pointer dem Kernel überlassen.
Die Lese-/Schreibpointer hätte ich aber schon den Prozessen überlassen, weil nen Sicherheitsgewinn hast du dadurch das du es in den Kernel packst auch nicht, weil der Prozess sich ja nicht dran halten muss.
Wenn er anfängt und mehr als die Pipe-Größe schreiben möchte, muss er die Pipe-Flushen und würde dann schlafen gelegt werden bis der Reader entsprechend mitgeteilt hat, dass er die Pipe vollständig ausgelesen hat. Denn das eine Pipe voll ist geht ja nur, wenn ohne einen Flush Daten mit einer Größer der Pipe-größe geschrieben wurden.
Das Flushen würde dann einen Popup-Thread injezieren und wenn dieser Fertig ist, wird der Writer wieder aufgeweckt. Problem wäre dabei nur, dass es entweder nicht asynch wäre oder man einen weiteren Syscall bräuchte damit der Writer weiß ob der Reader schon fertig ist (und wenn nicht wird er schlafen gelegt).

Zitat von: erik
Also beim Erstellen so einer Pipe kann der Ersteller immer auch die Größe in Pages (1..n) angeben.
Jap, würde ich so auch mitgehen.

Zitat von: erik
deswegen pro Message auch maximal die Hälfte der Pipe-Größe damit Double-Buffering gut läuft, die Pipe-Größe kann ja passend großzügig gewählt werden
Da komme ich nicht mit, wieso und wofür Double-Buffering?
115
OS-Design / Re: Flexibles und einfaches Prozess erzeugen
« am: 21. October 2011, 19:08 »
Zitat von: erik
Und wenn der Elternprozess keine vorhandene Datei sondern was neues/eigenes mitgeben möchte? Oder wenn diese Handles gar nicht über das VFS laufen? (ich hatte Dich schon so verstanden das auch bei Dir nicht alles über das VFS geht)
Was meinst du mit neues/eigenes? Auch wenn der FD nicht im VFS ist, so weiß das VFS doch welcher Prozess welche Datei von welchen Prozessen geöffnet ist.

Zitat von: erik
Jaja, warum einfach wenn es auch kompliziert geht?
Jetzt bin ich verwirrt. Wie würdest du es denn performant (und ohne Segmente ;)) machen? Meine erste Variante hat halt so ihre Probleme und die jetzt beschriebene ist da schon robuster und umgeht halt das Kopieren in und aus dem Kernel und es muss nicht ständig neugemappt werden und ich denke das ist schon ein Vorteil. Aber wo siehst du denn die Nachteile?

Zumal sowas wie ASLR und andere "Sicherheitskonzepte" sind auch nicht gerade einfach oder KISS ;)
116
OS-Design / Re: Flexibles und einfaches Prozess erzeugen
« am: 21. October 2011, 18:02 »
Zitat von: erik
Hä, was denn nun, übergeben oder abholen? Beides geht IMHO nicht.
Der Ersteller ruft createProcess(strImage,fd0,fd1,fd2) auf. Damit weiß das VFS wie die ersten 3 FD´s im neuen Prozess aussehen sollen. Der neue Prozess muss diese 3 FD´s dann mappen und dazu fragt er das VFS welche Pipe´s (oder halt Dateien) das sind.

Zitat von: erik
Mit den Mitteln von POSIX fällt mir eigentlich auch nur fork() ein wenn man ein Datei-Handle an sein Kind geben will
Sprich fork() schafft sowieso mehr Probleme als es löst (welche das auch immer seien).

Zitat von: erik
Dazu muss dieser Prozess aber eventuell darüber informiert werden das er andere/neue Kinder hat
Hmm, wozu?

Zitat von: erik
Ich meine das Du eigentlich weißt das ich von aktivem Abholen gor nix halte.
Da reden wir mal wieder aneinander vorbei. Mir ist nicht ganz klar was du unter aktivem Abholen bei einer Pipe meinst.

Zitat von: erik
Das klingt für mich so als ob da eine Reihe von Race-Conditions drin sein könnten und verschiedene andere Probleme auch. Das Potential für DoS-Angriffe hatte ich ja schon erwähnt.
Race-Conditions auf jeden Fall, die hängen aber "nur" mit dem Schlafenlegen und Aufwecken von Threads zusammen. Was du dir unter DoS-Angriff vorstellst ist mir aber noch nicht klar.

Man könnte eine Pipe auch so gestalten, das die nur die Daten in die "Pipe" kommen (ist immer ne 4kb Page die in beide Prozesse gemappt ist) und der Empfänger wird per IPC benachrichtigt das Daten vorhanden sind und er kann diese dann auch gleich verarbeiten.
Damit dürften sich die Fälle <= 4kb und > 4kb (zumindest bei Dateioperationen wüsste ich wie ich das machen würde) ganz gut lösen. Zwar könnten die Daten wieder in einem ungünstigen Moment geändert werden, aber die Pipe wäre nicht mehr Thread, sondern Prozess "fixiert" und man hätte keine Race-Conditions mehr und die eigentliche Arbeitsgrundlage (Pointer und Flags) sind auch sicher.
117
OS-Design / Re: Flexibles und einfaches Prozess erzeugen
« am: 21. October 2011, 15:35 »
Zitat von: erik
Hm, das klingt nach einem ziemlichen Sicherheitsleck. Ich nehme mal an das beide auf diese eine Page Schreibzugriff haben (sonst könnten ja nicht beide ihren reweiligen Pointer aktualisieren). Was passiert den wenn einer von beiden den jeweils anderen Pointer manipuliert? Oder die Flags auf etwas ungültiges/unerwünschtes setzt? Bei den Pointern kann man sich so behelfen des jede Seite ihren Pointer in einer lokalen Variable verwaltet und den Pointer in dieser shared Page nur schreibt um den Anderen zu informieren aber niemals selber von dort ließt. Mit den Flags könnte man das ähnlich machen, wenn man 2 getrennte Flags hat. Trotzdem finde ich dass das immer noch ein tolles Einfallstor für DoS-Angriffe u.ä. darstellt.
Ich weiß dass das alles Probleme sind und mir sind diese auch bekannt, aber ist das nicht im Endeffekt das gleiche, als wenn die Daten einer Msg verändert werden (z.B. von nem anderen Thread)?

Zitat von: erik
Und wieso ausgerechnet das VFS fragen? Und was ist wenn ein Prozess stdin/stdout/stderr für sein Kind komplett selber anbieten will (um z.B. ein anders Programm selber interaktiv zu steuern)?
Wird mit fork() oder der durch spezielles Markieren der FD´s als shared (oder so) in Windows gemacht. Fork() ist ja so ne Sache ;), aber wie du es schon selbst beschreibt, wollte ich das dann irgendwie so machen, dass diese 3 FD´s bei einer Prozesserstellung mit übergeben werden können. Der Prozess halt sich diese dann vom VFS und damit müssten die lib´s auch nicht kompatibel sein. Was ist denn wenn du z.B. mehrere Sprachen mit unterschiedlichen libs hast?

Ich sehe das halt so, dass das VFS sowieso vorhanden sein muss, die libc aber nicht. Deswegen soll es darüber gelöst werden.

Gibt es praktisches Fälle wo nicht nur die ersten 3 sondern auch andere "normale" Dateien an das Kind weitervererbt werden (obwohl das ja wiederrum nur bei fork() Sinn machen würde, weil man sonst die FD Nummer gar nicht wüsste)?

Zitat von: erik
Hast Du auch an Fälle gedacht wo der Elternprozess in der Zwischenzeit beendet wird und stdin vom Kindprozess an dessen Großelternprozess (oder noch höher) zurückgegeben werden muss?
Sollte das nicht "einfach" gehen, indem man den Elternzeiger dann auf den Großeltern-Prozess zeigen lässt?

Zitat von: erik
Also für ein leeres stdin ist das IMHO ganz und gar nicht geeignet, da kommen ja Bytes raus und ich glaube nicht das es im Sinne der Prozesse ist wenn diese von stdin unbegrenzt viele 0x00-Bytes lesen können.
Jap, das ist wohl war, also EOF.

Zitat von: erik
Womit aktives Abholen dann auch Pflicht wird, aber dazu kennst Du meine Meinung ja bereits.
Gerade nicht oder was meinst du überhaupt ;)

Man hat anhand der Pointer und der Flags sehen können ob der Writer gerade schläft oder nicht und wenn ja, hat man ihn aufgeweckt und sich selber schlafen gelegt. Der Writer schreibt dann Daten und weckt gegebenenfalls (falls der Reader schlafen sollte) den Reader auf.
118
OS-Design / Re: Flexibles und einfaches Prozess erzeugen
« am: 20. October 2011, 19:16 »
Zitat von: erik
Da bin ich jetzt aber neugierig wie Du das umsetzen möchtest? Per Mapping?
Jap, per Mapping. Ich hatte das sogar schon umgesetzt, aber irgendwo war noch der Wurm drin und die Pipe war auf 4byte Blöcke beschränkt (schöner wären 1byte Blöcke).

Man hat nen Read-Ptr, nen Write-Ptr und nen Flag-Feld (jeweils 4byte groß). Eine Pipe besteht dann aus einer Page und der restliche Speicher der Page (4084bytes) wird als Ring-Buffer genutzt.

Problem daran ist das Thread-aufwecken und schlafen-legen. Es gibt da so ein paar Randsituationen die ich noch nicht im Griff habe und auch keine gute Lösung für weiß.

Zitat von: erik
Ich denke dass das nicht nur die ersten 3 FDs pro Prozess trifft sondern eine beliebige Anzahl, die libc sollte zu jeden FD wissen was für ein Typ das ist.
Ja, dachte ich mir auch schon. Damit würde ich dann beide Fälle, einmal den FD in der libc und einmal im VFS haben (jenachdem ob Pipe oder Mapping).

Zitat von: erik
Die Schwierigkeit bei den ersten 3 FDs ist eher das sie noch vor dem Aufruf von main() vorhanden sein müssen und da ist zu überlegen ob die libc sich diese 3 FDs irgendwo holt (indem bei irgendeiner zentralen Stelle die libc anfragt "ich bin Prozess XYZ und will meine 3 Standard-FDs") oder ob sie dem Prozess explizit mitgegeben werden (so ähnlich wie die Command-Line-Parameter).
Ich würde das vor main() so machen, dass die libc, einfach den VFS-Server nach den ersten 3 FD´s fragt und entsprechend einrichtet.

Zitat von: erik
Auch sehe ich ein Problem beim weitervererben von stdin, hier muss IMHO bei jedem ProcessCreate() eindeutig geklärt werden ob stdin vererbt werden soll (dann sollte der aktuelle Prozess nicht mehr auf stdin zugreifen können) oder ob der neue Prozess ein eigenes stdin bekommt (und der aktuelle Prozess sein stdin behalten kann).
Dafür wäre dann die Elter-Kind-Beziehung gut. Denn so könnte ich sagen, beim Weitervererben wird die Pipe (stdin) beim Eltern-Prozess geunmappt und im Kind-Prozess gemappt, so kann der Eltern-Prozess erst wieder auf stdin zugreifen, wenn das Kind beendet wurde oder stdin geschlossen hat.

Zitat von: erik
Auch wäre es eine Überlegung wert ob Hintergrundprozesse überhaupt ein stdin bekommen, da müsste dann gegebenenfalls die libc immer nur EOF o.ä. zurück liefern.
Dafür gibt es ja "/dev/null" und sowas würde ich auf jeden Fall in der libc haben wollen. Damit für solch einfache Sachen kein IPC notwendig ist (was ja auch quatsch wäre, wenn wahrscheinlich in dem konkreten Fall nicht weiter schlimm).

Zitat von: erik
Also ich muss ganz ehrlich sagen das mir persönlich dieses Umherreichen von Pipes ziemlich suspekt ist, ich hätte da Angst das da mal was verloren geht (weil einer der Prozesse genau in dem Moment aufgrund irgendeiner Exception in einem anderen Thread plötzlich gekillt wird o.ä.) und dann gar nix mehr geht. Da solltest Du IMHO auf jeden Fall noch mal gründlich drüber nachdenken.
So richtig perfekt ist das mit den Pipes nicht, das weiß ich aber. Das Problem was du beschreibst hatte ich so gelöst, dass der Writer/Reader bei einem Zugriff auf die Pipe nen Fehler zurück bekommt (kann durch die Flags geschehen), dass das Gegenüber nicht mehr existiert.
Ein Problem bei meinen Pipe´s war, dass sie auf Threads geeicht waren und nicht auf ganze Prozesse (war wegen dem Aufwachen und Schlafenlegen).

Ein anderes Problem ist wenn der Writer z.B. der Meinung ist er müsse die Flags und die Pointer ändern. Dann liest die andere Seite natürlich Müll, aber das Problem hätte man auch bei Zero-Copy-IPC (wenn man dem Caller nicht die Schreibrechte für den Bereich nimmt) und Multithreading.
119
OS-Design / Re: Flexibles und einfaches Prozess erzeugen
« am: 20. October 2011, 10:37 »
Zitat von: erik
Also Pipes sind da IMHO eher weniger geeignet, schon weil die oft doppeltes Kopieren erfordern (Sender>>Kernel und dann Kernel>>Empfänger).
Also meine Pipes laufen fast komplett im UserSpace (nur das eventuell ein Writer oder ein Reader aufgeweckt werden muss, dass passiert im/über den Kernel). Von daher kein doppeltes Kopieren.

Ich dachte mir das dann so, dass die ersten 3 FD´s immer Pipe´s sind und von der Libc gesondert behandelt werden. Über das VFS holt man sich dann die Pipe´s ab und kann sie nutzen. Dadurch wäre es auch möglich, dass eine Datei am anderen Ende stecken kann, das wird dann aber im VFS gemacht. Wenn z.B. die Ausgabe von Prozess A auf die Eingabe von Prozess B umgeleitet werden soll, dann geht das so, dass das VFS das weiß und Prozess B mappt die Pipe von Prozess A. So ist das VFS auch nicht mehr involviert.

Zitat von: erik
ich denke mal das die einzelnen Datentransfers jeweils atomar abgearbeitet werden
Dafür müsste ich sagen, wenn eine Datei zum exklusiven Schreiben geöffnet wird, dann kann gemappt werden und ansonsten wird über Pipe´s gearbeitet und das VFS muss dann zusehen, wie es die Sachen halbwegs atomar aus den Pipe´s in die Datei bekommt.
120
OS-Design / Re: Flexibles und einfaches Prozess erzeugen
« am: 19. October 2011, 21:58 »
Zitat von: erik
Was meist Du denn mit "jeder Thread hat eine Messagebox"? Das man direkt an die Thread-ID (anstatt an einen Port) eine Message schicken kann? Wird das dann innerhalb dieses Threads verarbeitet (also wird der so unterbrochen wie bei einem klassischen Signal) oder muss der Thread die Message selber aktiv abholen?
Genau, die Thread-ID wäre dann gleich der Port-ID und wir wären wieder bei akivem Abholen.

Zitat von: erik
Bei mir hab ich vorgesehen das jeder Prozess ein Prozess-Message-Target kreieren kann so das man wirklich an eine Prozess-ID eine simple Message (per detached IPC) schicken kann, aber das muss der Prozess aktiv einrichten und es wird auch hier ein PopUp-Thread injiziert.
Klingt für mich nach dem selben Prinzip wie dein IPC, hat nur nen anderen Namen ;) Sprich du hättest also auch ein Port pro Prozess (wenn der es denn will) für Signale und ähnliche Sachen.

Zitat von: erik
Ich kann mir vorstellen das die meisten Programme die Dateien am Stück einlesen/speichern dafür auch größere read()/write()-Aktionen nutzen. Aus meiner Sicht wären das z.B. Text-Editoren u.ä., es gibt durchaus auch einige Anwendungen wo Dateien nicht wie ein Stream verarbeitet werden.
Naja, das meinte ich ja, da reden wir dann aber schon von wesentlich mehr Daten als nur ein oder zwei Pages.

Daher könnte man einfach sagen, alles < 4kb muss nicht ausgerichtet sein und wird kopiert und alles >= 4kb muss ausgerichtet sein und wird nicht kopiert, sondern per SHM gelöst.
Man könnte dann sogar soweit gehen, dass alles >= 4kb per Message-IPC gemacht wird und alles < 4kb per Pipe (die auch nur ne Einwege-Kommunikation wäre die in beide Prozesse gemappt ist).

Zitat von: erik
Über das Sharen von FDs bei echten Dateien hatten wir hier doch schon mal ausführlich diskutiert und ich erinnere mich nicht daran das da jemand ein reelles Beispiel genannt hat, von daher bleibe ich bei meiner Meinung das sich das bei echten Dateien eh nicht lohnt.
Richtig, das hätte vorallem den Vorteil das man die FD´s wunderbar in der libc lassen kann und ich brauche auch keinen read()-"Syscall" mehr anbieten, sondern nur noch Memory-Mapped-File.

Allerdings werden dadurch so Sachen wie Log-Dateien schwierig. Wo vllt mehrere Prozesse reinschreiben (ist das wirklich so?). Das mehrere Threads den gleichen FD nutzen um in eine Datei zu schreiben, wäre ja kein Problem und könnte per Locking gelöst werden.

Zitat von: erik
Anders ist das natürlich bei Character-Devices wie stdin/stdout/stderr wenn man diese weitervererben möchte aber das sind eben keine echten Dateien so das man den Datei-Pointer hier eh anders behandeln muss.
Ist meine Annahme richtig, das diese Character-Devices eh keinen ftell() und fseek() anbieten? Dann bräuchte man sich dort auch nicht um sowas kümmern. Das würde ich dann per Pipe lösen wollen, die auch in mehrere Prozesse gemappt sein kann und das Schreiben könnte dann z.B. per cmpxchg passieren.

Die Frage wäre dann nur, ist bei einem Character-Device ein String eine Einheit oder ein Character? Ich frage, weil ob es passieren kann das wenn 2 Prozesse da reinschreiben (einer "HELLO" und einer "WORLD"), dass dabei dann "HWEOLRLLOD" rauskommen kann (rein theoretisch)?

Was ich eher unglücklich finden würde (und das wolltest du >erik< doch machen wimre), wenn eine Pipe in Prozess A führt (stdin) die dann stdin weiter an Prozess B vererbt und dafür ne neue Pipe erstellt wird und jedes mal wenn etwas auf stdin geschrieben wird, wird erst Prozess A geweckt, holt die Daten ab und schreibt sie auf die Pipe an Prozess B.
Seiten: 1 ... 4 5 [6] 7 8 ... 43

Einloggen