Fragen zur Handhabung von dnsmasq

Ist auch voll logisch. Die pid-Datei wird glaube ich irgendwo bei rc.dnsmasq angelegt und anschließend wieder gelöscht. Man muss es halt ordentlich als dienst starten und stoppen und nicht einfach killen oder zum Absturz bringen. [...]
  1. Das init-Skript legt keine .pid-Datei an.
  2. Das init-Skript selbst killt den Dienst per SIGTERM, was ja auch völlig in Ordnung ist. Siehe Zeile 84.
  3. SIGTERM ist ein ordentlicher Weg, einen Prozess zu beenden.

[...] Ich vermute, AVM checkt irgendwie, wer auf Port 53 lauscht und killt denjenigen dann einfach. Vermutlich macht das sogar multid selbst. Ist zwar hart und unüblich, aber was sollst... [...]
Das ist falsch.

[...] Wie gesagt, wrapper nach silent-tears-Methode platzieren und alles ist in Butter. [...]
Hmm, halte ich auch für unnötig. Es reicht aus, die .pid-Datei beim Beenden des Dienstes zu löschen bzw. noch besser den Check mit "pidof" durchzuführen. Ich ändere mir die Firmware morgen mal entsprechend und berichte dann.

Edit:
Noch etwas zum Thema SIGTERM. Im Code von dnsmasq ist ersichtlich, dass es bei einem SIGTERM ordentlich beendet wird. Siehe dazu "freetz-1.0.2/source/dnsmasq-2.46/src/dnsmasq.c", Zeile 837 und Zeile 788.
 
Zuletzt bearbeitet:
Ein strace sagt mir, dass der Code korrekt ausgeführt wird. Leider ist das PID-File aber root:root und daher darf der dnsmasq (nobody) das nicht löschen.
Code:
unlink("/var/run/dnsmasq.pid")          = -1 EACCES (Permission denied)
MfG Oliver
 
Legt dnsmasq die PID-Datei denn selbt an, solange er noch root ist? Dann wäre es ein Fehler in dnsmasq, oder irgendwelche Rechte sind nicht so, wie es von dnsmasq vorgesehen ist.

Die Modlib Funktionen, die man verwenden könnte, sind modlib_stop, modlib_status und modlib_check_running. Speziell modlib_check_running prüft nicht nur, ob eine PID-Datei existiert, sondern auch, ob dazu ein Prozeß existiert.
 
Code:
      /* write pidfile _after_ forking ! */
      if (daemon->runfile)
        {
          FILE *pidfile;
          /* only complain if started as root */
          if ((pidfile = fopen(daemon->runfile, "w")))
            {
              fprintf(pidfile, "%d\n", (int) getpid());
              fclose(pidfile);
            }
          else if (getuid() == 0)
            {
              send_event(err_pipe[1], EVENT_PIDFILE, errno);
              _exit(0);
            }
        }
      /* open  stdout etc to /dev/null */
      nullfd = open("/dev/null", O_RDWR);
      dup2(nullfd, STDOUT_FILENO);
      dup2(nullfd, STDERR_FILENO);
      dup2(nullfd, STDIN_FILENO);
      close(nullfd);
Sollte der User nach dem Fork nicht nobody sein!?

MfG Oliver
 
Irgendwann wird er den Benutzer wechseln, vor oder nach dem fork. Wer ist denn der Eigentümer der Datei, solange der dnsmasq läuft? Wenn es nobody ist, dann wurde der Benutzer an der Stelle, wo die PID-Datei erstellt wird, bereits gewechselt. In diesem Fall sollten wir die Zugriffsrechte für das Verzeichnis /var/run auf 1777 setzen.

Da aber die Datei erstellt werden kann, wird sie vermutlich als root angelegt. Alternativ könnten wir daher die Rechte auf 777 setzen. Das wäre für ein normales System zwar ungeschickt, aber die Box ist ja kein Mehrbenutzer-System. Eine andere Möglichkeit wäre, aus dem Start-Skript den Eigentümer nachträglich zu ändern. Das ist aber auch nicht sonderlich elegant, und je nach dem, wann die Datei erstellt wird, müßte man möglicherweise darauf warten, daß sie erscheint.
 
Code:
# ls -al /var/run/dnsmasq.pid
-rw-r--r--    1 root     root            5 Mar  9 00:02 /var/run/dnsmasq.pid

MfG Oliver
 
Wie wäre es mit einem Verzeichnis /var/run/dnsmasq und Eigentümer nobody? Das entspricht dem, was auch einem normalen Linux-System gemacht wird.

Ist es schwierig, dem dnsmasq den anderen Pfadnamen für die PID-Datei beizubringen? Im Zweifelsfall müßte man einen Patch machen, der es im Source ändert.

Ich habe schon mal eine Erweiterung in modlibrc gemacht, die abweichende PID-Files unterstützt.
 
[...] Ist es schwierig, dem dnsmasq den anderen Pfadnamen für die PID-Datei beizubringen? [...]
Sollte recht leicht sein:
Code:
-x, --pid-file=<path>
    Specify an alternate path for dnsmasq to record its process-id in. Normally /var/run/dnsmasq.pid.
Den Parameter könnte man auch in die "/etc/dnsmasq.conf" eintragen.
Aber das löst meines Erachtens das Problem nicht, dass die Datei mit root:root angelegt wird und nachher nicht gelöscht werden kann.

Was spricht dagegen, die .pid-Datei einfach außen vor zu lassen und den Check mit "pidof" zu machen?
 
Es löst das Problem insoweit, als man dem Verzeichnis auch den Eigentümer nobody geben kann, so daß die Datei nachher auch gelöscht werden kann.

Pidof ist eine Möglichkeit, die bei dnsmasq vermutlich funktionieren würde, bei Busybox-basierten Server dagegen je nach Konfiguration unter Umständen nicht. In manchen Fällen könnte es mehrere Prozesse mit gleichem Namen geben, von denen man nur einen stoppen will. Und solange es ohne Probleme möglich ist, wäre es wünschenswert, das einheitlich zu machen.
 
Ich habe die Frage auf der dnsmasq Mailingliste gestellt. Antwort des Autors:
The problem is not the permissions on the PID file, what matters for unlink() is the permission on the _directory_ (ie /var/run).

Clearly the only way to delete a file from /var/run is to be root, and dnsmasq doesn't run as root deliberately, for security reasons. It used to be that dnsmasq didn't even try to delete the PID file. Instead the start/stop script (which is running as root) did the deletion.

It became necessary to have dnsmasq delete the PID-file on Debian and Ubuntu, since the Debian/Ubuntu dnsmasq package now supports "fast shutdown" where the daemon is sent SIGTERM, but no start/stop script runs. To do that the unlink() call was added. To make this work, it's necessary to do the following.

1) Create a directory (say /var/run/dnsmasq)

2) Change ownership of /var/run/dnsmasq to the user dnsmasq will run as, either "nobody" or (much better) a unique system userid. Make it owner-writable.

3) Tell dnsmasq to store the PID file in /var/run/dnsmasq/dnsmasq.pid with a command-line or configuration option. If using a system user-id, tell dnsmasq to use that in the same way.

4) Make sure that the start/stop script is using the same location as the place where it expects to find the pid-file.

Note that the actual PID-file will still be owned by root: that doesn't matter, the important thing is the ownership of the directory /var/run/dnsmasq. Beware that on some systems /var/run gets cleared over a reboot, so the startup script may have to recreate the directory each time dnsmasq is started.


HTH

Simon.
 
Das erklärt alles. Der Workaround mit dem pidof-Check funktioniert bei mir erstmal, aber es wäre schon wünschenswert, wenn diese hier angesprochenen Änderungen in der offiziellen Freetz-Version umgesetzt werden würden.
 
Ich hab jetzt mal das Verzeichnis geändert und im Startskript wird /var/run/dnsmasq erzeugt. Könnt ihr mal bitte schauen, ob das jetzt tut wie es soll?

http://www.freetz.org/changeset/3144

@Ralf
Wie muss man jetzt den Statuscheck ändern?

MfG Oliver
 
Wie kommst du da drauf, dass die pid-file Option in die conf muss?

MfG Oliver
 
Ich hatte den config.h-Patch übersehen.

Meines Erachtens ist es besser den Namen in der Konfigurationsdatei zu ändern, anstatt die Programmdatei zu patchen. Allein schon wegen der Übersichtlichkeit des Ganzen. Auf der einen Seite besteht ihr darauf eine klare Linie zu fahren, aber auf der anderen Seite setzt ihr ein paar Optionen in der .conf und andere patcht ihr direkt in den Code. Das erschwert die Fehlersuche.
 
Der Ort des pid file ist für mich keine Option die man in der Config setzen muss, da man das normalerweise nicht ändert.

MfG Olver
 
Ich meine auch nicht, daß man in der Oberfläche einen anderen Pfad eingeben können soll, sondern daß man es aus dem rc-Skript fest übergibt. Man ist dadurch nicht auf den Patch des Programms angewiesen und die Information über die PID-Datei ist damit zentral an einer Stelle, nämlich nur im rc-Skript. Ansonsten besteht die Gefahr, daß man irgendwann etwas ändert und nicht mehr daran denkt, daß Skript und Patch aufeinander abgestimmt sein müssen.

Ich habe bisher folgenden Patch, aber noch nicht getestet. Damit kann man bei Bedarf den Pfad der PID-Datei an einer einzigen Stelle ändern.
Code:
--- make/dnsmasq/files/root/etc/init.d/rc.dnsmasq       (Revision 3115)
+++ make/dnsmasq/files/root/etc/init.d/rc.dnsmasq       (Arbeitskopie)
@@ -4,6 +4,10 @@
 export LD_LIBRARY_PATH=/mod/lib

 DAEMON=dnsmasq
+DAEMON_LONG_NAME=dnsmasq
+DAEMON_USER=nobody
+DAEMON_GROUP=nobody
+PID_FILE=/var/run/$DAEMON/$DAEMON.pid

 . /etc/init.d/modlibrc

@@ -19,8 +23,10 @@
 start() {
        local lease

-       modlib_addgroup nobody
-       modlib_adduser nobody -s /bin/false -D -S -H -G nobody -g 'nobody'
+       modlib_addgroup $DAEMON_GROUP
+       modlib_adduser $DAEMON_USER -s /bin/false -D -S -H -G $DAEMON_GROUP -g $DAEMON_GROUP
+       mkdir -p ${PID_FILE%/*}
+       chown $DAEMON_USER:$DAEMON_GROUP ${PID_FILE%/*}

        (
                if [ -x "/tmp/flash/${DAEMON}_conf" ]; then
@@ -38,7 +44,7 @@
        if [ "$1" != "nomultid" ]; then
                multid -s > /dev/null 2>&1
        fi
-       OPTIONS="$DNSMASQ_OPTIONS"
+       OPTIONS="--pid-file=$PID_FILE $DNSMASQ_OPTIONS"
        if [ "$DNSMASQ_DNS_PORT" ]; then
                OPTIONS="$OPTIONS -p \"$DNSMASQ_DNS_PORT\""
        fi
@@ -116,7 +122,7 @@
                        exit 1;
                fi

-               if [ -e "/var/run/dnsmasq.pid" ]; then
+               if modlib_check_running; then
                        echo "$DAEMON already started."
                else
                        if [ -z "$(pidof multid)" ]; then
@@ -144,11 +150,7 @@
                multid $MULTIDPARAM > /dev/null 2>&1
                ;;
        status)
-               if [ -z "$(pidof "$DAEMON")" ]; then
-                       echo 'stopped'
-               else
-                       echo 'running'
-               fi
+               modlib_status
                ;;
        *)
                echo "Usage: $0 [load|unload|start|stop|restart|status]" 1>&2
 
Ah, und die modlib Funktionen nutzten jetzt die Variable PID_FILE?

MfG Oliver
 
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.