<h1>09/02 - Dämon Prozesse<aclass="headerlink"href="#damon-prozesse"title="Permalink to this headline">¶</a></h1>
<hrclass="docutils"/>
<p><imgalt=""src="../_images/daemon.png"/></p>
<hrclass="docutils"/>
<sectionid="ubersicht">
<h2>1. Übersicht<aclass="headerlink"href="#ubersicht"title="Permalink to this headline">¶</a></h2>
<p>Dieser Teil des Praktikums behandelt spezielle Prozesse: die Dämon Prozesse («daemon pro-cesses»). Es ist gedacht als Zusatz zum Basis Praktikum über Prozesse und Threads.</p>
<p>Auch dieser Teil ist ein «Analyse»- und «Experimentier»-Praktikum.</p>
<hrclass="docutils"/>
<sectionid="nachweis">
<h3>1.1 Nachweis<aclass="headerlink"href="#nachweis"title="Permalink to this headline">¶</a></h3>
<p>Dieses Praktikum ist eine leicht abgewandelte Variante des ProcThreads Praktikum des Moduls BSY, angepasst an die Verhältnisse des SNP Moduls. Die Beispiele und Beschreibungen wurden, wo möglich, eins-zu-ein übernommen.</p>
<p>Als Autoren des BSY Praktikums sind genannt: M. Thaler, J. Zeman.</p>
</section>
</section>
<hrclass="docutils"/>
<sectionid="lernziele">
<h2>2. Lernziele<aclass="headerlink"href="#lernziele"title="Permalink to this headline">¶</a></h2>
<p>In diesem Praktikum werden Sie sich mit Dämon Prozessen beschäftigen.</p>
<ulclass="simple">
<li><p>Sie können die Problemstellung der Dämon Prozesse erklären</p></li>
<li><p>Sie können einen Dämon Prozess kreieren</p></li>
<li><p>Sie können aus dem Dämon Prozess mit der Umgebung kommunizieren</p></li>
<li></li>
</ul>
</section>
<hrclass="docutils"/>
<sectionid="aufgabe-damon-prozesse">
<h2>3. Aufgabe: Dämon Prozesse<aclass="headerlink"href="#aufgabe-damon-prozesse"title="Permalink to this headline">¶</a></h2>
<p><strong>Ziele</strong></p>
<ulclass="simple">
<li><p>Problemstellungen um Daemons kennenlernen:</p>
<ul>
<li><p>wie wird ein Prozess zum Daemon?</p></li>
<li><p>wie erreicht man, dass nur ein Daemon vom gleichen Typ aktiv ist?</p></li>
<li><p>wie teilt sich ein Daemon seiner Umwelt mit?</p></li>
<li><p>wo “lebt” ein Daemon?</p></li>
</ul>
</li>
</ul>
<p><strong>Einleitung</strong></p>
<p>Für diese Aufgabe haben wir einen Daemon implementiert: <strong>MrTimeDaemon</strong> gibt auf Anfrage die Systemzeit Ihres Rechners bekannt. Abfragen können Sie diese Zeit mit dem Programm <codeclass="docutils literal notranslate"><spanclass="pre">WhatsTheTimeMr</span><spanclass="pre">localhost</span></code>. Die Kommunikation zwischen den beiden Prozessen haben wir mit TCP/IP Sockets implementiert. Weitere Infos zum Daemon finden Sie nach den Aufgaben.</p>
<p>Im Abschnitt 4 finden Sie Zusatzinformationen über diese Implementation eines Dämon Prozesses plus weiterführende Informationen.</p>
<li><p>Für die folgende Aufgabe benötigen Sie mindestens zwei Fenster (Kommandozeilen-Konsolen). Übersetzen Sie die Programme mit <codeclass="docutils literal notranslate"><spanclass="pre">make</span></code> und starten Sie das Programm <strong>PlapperMaul</strong> in einem der Fenster. Das Programm schreibt (ca.) alle 0.5 Sekunden <em>Hallo, ich bins… Pidi</em> plus seine Prozess-ID auf den Bildschirm. Mit dem Shell Befehl <codeclass="docutils literal notranslate"><spanclass="pre">ps</span></code> können Sie Ihre aktiven Prozesse auflisten, auch <strong>PlapperMaul</strong>. Überlegen Sie sich zuerst, was mit <strong>PlapperMaul</strong> geschieht, wenn Sie das Fenster schliessen: läuft <strong>PlapperMaul</strong> weiter? Was geschieht mit <strong>PlapperMaul</strong> wenn Sie sich ausloggen und wieder einloggen? Testen Sie Ihre Überlegungen, in dem Sie die entsprechenden Aktionen durchführen. Stimmen Ihre Überlegungen?</p></li>
<li><p>Starten Sie nun das Programm bzw. den Daemon <strong>MrTimeDaemon</strong>. Stellen Sie die gleichen Überlegungen an wie mit <strong>PlapperMaul</strong> und testen Sie wiederum, ob Ihre Überlegungen stimmen. Ob <strong>MrTimeDaemon</strong> noch läuft können Sie feststellen, indem Sie die Zeit abfragen oder den Befehl <codeclass="docutils literal notranslate"><spanclass="pre">ps</span><spanclass="pre">ajx</span><spanclass="pre">|</span><spanclass="pre">grep</span><spanclass="pre">MrTimeDaemon</span></code> eingeben: was fällt Ihnen am Output auf? Was schliessen Sie aus Ihren Beobachtungen?</p></li>
<li><p>Stoppen Sie nun <strong>MrTimeDaemon</strong> mit <codeclass="docutils literal notranslate"><spanclass="pre">killall</span><spanclass="pre">MrTimeDaemon</span></code>.</p></li>
<li><p>Starten Sie <strong>MrTimeDaemon</strong> und fragen Sie mit <codeclass="docutils literal notranslate"><spanclass="pre">WhatsTheTimeMr</span><spanclass="pre">localhost</span></code> oder mit <codeclass="docutils literal notranslate"><spanclass="pre">WhatsTheTimeMr</span><spanclass="pre">127.0.0.1</span></code> die aktuelle Zeit auf Ihrem Rechner ab.</p></li>
</ol>
<p><strong>Optional:</strong>
Fragen Sie die Zeit bei einem Ihrer Kollegen ab. Dazu muss beim Server (dort wo <strong>MrTimeDaemon</strong> läuft) ev. die Firewall angepasst werden. Folgende Befehle müssen dazu mit <strong>root-Privilegien</strong> ausgeführt werden:</p>
<divclass="highlight-bash notranslate"><divclass="highlight"><pre><span></span>iptables-save > myTables.txt <spanclass="c1"># sichert die aktuelle Firewall</span>
<p>Nun sollten Sie über die IP-Nummer oder über den Rechner-Namen auf den <strong>TimeServer</strong> mit <codeclass="docutils literal notranslate"><spanclass="pre">WhatsTheTimeMr</span></code> zugreifen können.
Die Firewall können Sie mit folgendem Befehl wiederherstellen:</p>
<li><p>Studieren Sie <codeclass="docutils literal notranslate"><spanclass="pre">MrTimeDaemon.c</span></code>, <codeclass="docutils literal notranslate"><spanclass="pre">Daemonizer.c</span></code> und <codeclass="docutils literal notranslate"><spanclass="pre">TimeDaemon.c</span></code> und analysieren Sie, wie die Daemonisierung abläuft. Entfernen Sie die Kommentare im Macro <codeclass="docutils literal notranslate"><spanclass="pre">Out-PutPIDs</span></code> am Anfang des Moduls <codeclass="docutils literal notranslate"><spanclass="pre">Daemonizer.c</span></code>. Übersetzen Sie die Programme mit make und starten Sie <codeclass="docutils literal notranslate"><spanclass="pre">MrTimeDaemon</span></code> erneut. Analysieren Sie die Ausgabe, was fällt Ihnen auf? Notieren Sie alle für die vollständige Daemonisierung notwendigen Schritte.</p></li>
<li><p>Setzen Sie beim Aufruf von <codeclass="docutils literal notranslate"><spanclass="pre">Daemonizer()</span></code> in <codeclass="docutils literal notranslate"><spanclass="pre">MrTimeDaemon.c</span></code> anstelle von <codeclass="docutils literal notranslate"><spanclass="pre">lock-FilePath</span></code> den Null-Zeiger <codeclass="docutils literal notranslate"><spanclass="pre">NULL</span></code> ein. Damit wird keine lock-Datei erzeugt. Übersetzen Sie die Programme und starten Sie erneut <codeclass="docutils literal notranslate"><spanclass="pre">MrTimedaemon</span></code>. Was geschieht bzw. wie können Sie feststellen, was geschehen ist?</p>
<p><strong>Hinweis:</strong> lesen Sie das log-File: <codeclass="docutils literal notranslate"><spanclass="pre">/tmp/timeDaemon.log.</span></code></p>
<p>Wenn Sie noch Zeit und Lust haben: messen Sie die Zeit, zwischen Start der Zeitanfrage und Eintreffen der Antwort. Dazu müssen Sie die Datei <codeclass="docutils literal notranslate"><spanclass="pre">WhatsTheTimeMr.c</span></code> entsprechend anpassen.</p>
</section>
<hrclass="docutils"/>
<sectionid="zusatzinformationen">
<h2>4. Zusatzinformationen<aclass="headerlink"href="#zusatzinformationen"title="Permalink to this headline">¶</a></h2>
<hrclass="docutils"/>
<sectionid="diese-implementation">
<h3>4.1 Diese Implementation<aclass="headerlink"href="#diese-implementation"title="Permalink to this headline">¶</a></h3>
<p>Dieser Daemon besteht aus den 3 Komponenten.</p>
<p>Hier werden die Pfade für die lock-Datei, die log-Datei und der ”Aufenthaltsort” des Daemons gesetzt. Die lock-Datei wird benötigt um sicherzustellen, dass der Daemon nur einmal gestartet werden kann. In die lock-Datei schreibt der Daemon z.B. seine PID und sperrt sie dann für Schreiben. Wird der Daemon ein zweites Mal gestartet und will seine PID in diese Datei schreiben, erhält er eine Fehlermeldung und terminiert (es soll ja nur ein Daemon arbeiten). Terminiert der Daemon, wird die Datei automatisch freigegeben. Weil Daemonen sämtliche Kontakte mit ihrer Umwelt im Normalfall abbrechen und auch kein Kontrollterminal besitzen, ist es sinnvoll, zumindest die Ausgabe des Daemons in eine log-Datei umzuleiten. Dazu stehen einige Systemfunktionen für Logging zur Verfügung. Der Einfachheit halber haben wir hier eine normale Datei im Verzeichnis <codeclass="docutils literal notranslate"><spanclass="pre">/tmp</span></code> gewählt.</p>
<blockquote>
<div><p><strong>Anmerkung:</strong> die Wahl des Verzeichnisses <codeclass="docutils literal notranslate"><spanclass="pre">/tmp</span></code> für die lock- und log-Datei ist für den normalen Betrieb problematisch, weil der Inhalt dieses Verzeichnisses jederzeit gelöscht werden kann, bzw. darf. Wir haben dieses Verzeichnis gewählt, weil wir die beiden Dateien nur für die kurze Zeit des Praktikums benötigen.</p>
</div></blockquote>
<p>Der Daemon erbt sein Arbeitsverzeichnis vom Elternprozesse, er sollte deshalb in ein festes Verzeichnis des Systems wechseln, um zu verhindern, dass er sich in einem montierten (gemounteten) Verzeichnis aufhält, das dann beim Herunterfahren nicht demontiert werden könnte (wir haben hier wiederum <codeclass="docutils literal notranslate"><spanclass="pre">/tmp</span></code> gewählt).</p>
<p><strong>Daemonizer: Daemonizer.c</strong></p>
<p>Der Daemonizer macht aus dem aktuellen Prozess einen Daemon. Z.B. sollte er Signale (eine Art Softwareinterrupts) ignorieren: wenn Sie die CTRL-C Taste während dem Ausführen eines Vordergrundprozess drücken, erhält dieser vom Betriebssystem das Signal SIGINT und bricht seine Ausführung ab. Weiter sollte er die Dateierzeugungsmaske auf 0 setzen (Dateizugriffsrechte), damit kann er beim Öffnen von Dateien beliebige Zugriffsrechte verlangen (die Dateierzeugungsmaske erbt er vom Elternprozess). Am Schluss startet der Daemonizer das eigentliche Daemonprogramm: TimeDaemon.e.</p>
<p>Das Daemonprogramm wartet in einer unendlichen Schleife auf Anfragen zur Zeit und schickt die Antwort an den Absender zurück. Die Datenkommunikation ist, wie schon erwähnt, mit Sockets implementiert, auf die wir aber im Rahmen dieses Praktikums nicht weiter eingehen wollen (wir stellen lediglich Hilfsfunktionen zur Verfügung).</p>
<h3>4.2 Zusatzinformation zu Dämon Prozessen<aclass="headerlink"href="#zusatzinformation-zu-damon-prozessen"title="Permalink to this headline">¶</a></h3>
<p>Dämonen oder englisch Daemons sind eine spezielle Art von Prozessen, die vollständig unabhängig arbeiten, d.h. ohne direkte Interaktion mit dem Anwender. Dämonen sind Hintergrundprozesse und terminieren i.A. nur, wenn das System heruntergefahren wird oder abstürzt. Dämonen erledigen meist Aufgaben, die periodisch ausgeführt werden müssen, z.B. Überwachung von Systemkomponenten, abfragen, ob neue Mails angekommen sind, etc.</p>
<p>Ein typisches Beispiel unter Unix ist der Printer Daemon <codeclass="docutils literal notranslate"><spanclass="pre">lpd</span></code>, der periodisch nachschaut, ob ein Anwender eine Datei zum Ausdrucken hinterlegt hat. Wenn ja, schickt er die Datei auf den Drucker.</p>
<p>Hier wird eine weitere Eigenschaft von Daemons ersichtlich: meist kann nur ein Dämon pro Aufgabe aktiv sein: stellen Sie sich vor, was passiert, wenn zwei Druckerdämonen gleichzeitig arbeiten. Andererseits muss aber auch dafür gesorgt werden, dass ein Dämon wieder gestartet wird, falls er stirbt.</p>
</section>
</section>
<hrclass="docutils"/>
<sectionid="bewertung">
<h2>5. Bewertung<aclass="headerlink"href="#bewertung"title="Permalink to this headline">¶</a></h2>
<p>Die gegebenenfalls gestellten Theorieaufgaben und der funktionierende Programmcode müssen der Praktikumsbetreuung gezeigt werden. Die Lösungen müssen mündlich erklärt werden.</p>