I have a dnsmasq running which looks like that in "pstree": |-+- 56712 nobody /usr/local/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/home/novel/code/libvirt/_build/src/libvirt_leaseshelper | \--- 56713 root /usr/local/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/home/novel/code/libvirt/_build/src/libvirt_leaseshelper Contents of the /var/lib/libvirt/dnsmasq/default.conf file is: strict-order pid-file=/var/run/libvirt/network/default.pid except-interface=lo0 bind-dynamic interface=virbr0 dhcp-range=192.168.122.2,192.168.122.254,255.255.255.0 dhcp-no-override dhcp-authoritative dhcp-lease-max=253 dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts $ sudo cat /var/run/libvirt/network/default.pid 56712 $ PID file is pointing to the parent process. IIUC, having these two processes is also good as it needs root process to run the dhcp script. So far so good. But, when I kill the parent process: $ sudo kill 56712 I expect it to kill both parent (56712) and child (56713). But it does not happen, I have 56713 still running: $ pstree |grep "sbin/dnsm" | | \--- 57159 novel grep sbin/dnsm |--- 56713 root /usr/local/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/home/novel/code/libvirt/_build/src/libvirt_leaseshelper $ At the same time, I've checked a similar setup on a Linux host, and it works as expected: novel@localhost:~$ pstree -u -a -s -p|grep dnsm |-dnsmasq,1250,dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro ... | `-dnsmasq,1251,root --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro ... | |-grep,1426 --color=auto dnsm novel@localhost:~$ sudo kill 1250 novel@localhost:~$ pstree -u -a -s -p|grep dnsm | |-grep,1447 --color=auto dnsm novel@localhost:~$ I think behavior that I see on FreeBSD is a bug, because I'd expect killing a process with pid as specified in the "pid-file" configuration path to clean up that dnsmasq instance, like it happens on Linux. Version information: FreeBSD: $ dnsmasq --version Dnsmasq version 2.91 Copyright (c) 2000-2025 Simon Kelley Compile time options: IPv6 GNU-getopt no-DBus no-UBus i18n IDN2 DHCP DHCPv6 no-Lua TFTP no-conntrack ipset no-nftset auth DNSSEC loop-detect no-inotify dumpfile Linux: novel@localhost:~$ dnsmasq --version Dnsmasq version 2.90 Copyright (c) 2000-2024 Simon Kelley Compile time options: IPv6 GNU-getopt DBus no-UBus i18n IDN2 DHCP DHCPv6 no-Lua TFTP conntrack ipset nftset auth cryptohash DNSSEC loop-detect inotify dumpfile
Hi Roman, thanks for the report. Can you check if the 56713 process is somehow in state "D" because it's stuck waiting for network I/O, and goes away later? Can you also test an up to date dns/dnsmasq-devel (v2.92test12 as of latest commits) and see if that behaves the same?
For me, with a configuation not quite the same but similar to yours, and a stupid dhcp-script that just calls logger and then sleeps 5 s, and without DHCP clients, it seems to run the dhcp-script once on startup, but killing the "nobody" process makes the "root" child process go away quicker than I can check its existence.
(In reply to Matthias Andree from comment #1) ps shows the "I" state: PID TT STAT TIME COMMAND 56713 - I 0:00,00 /usr/local/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/home/novel/code/libvirt/_build/src/libvirt_leaseshelper Same behavior with Dnsmasq version 2.92test11.
Seems there's more to it than just running things. Either network traffic, or different OS, or your libvirt interface (I just used vtnet0 because I test it in my FreeBSD 14.2-RELEASE-p<latest> amd64 qemu-based VM hosted on Fedora 42). I cannot currently help here. It might help, with a lot of patience, to ask on the dnsmasq-discuss@ upstream mailing list.
(In reply to Matthias Andree from comment #4) I think I have a simpler repro: $ pwd /home/novel/dnsmasq_bug $ ls default.addnhosts default.hostsfile dnsmasq_test.pid test.conf $ sudo cat test.conf strict-order pid-file=/home/novel/dnsmasq_bug/dnsmasq_test.pid except-interface=lo0 bind-dynamic interface=bridge0 dhcp-range=192.168.127.2,192.168.127.254,255.255.255.0 dhcp-no-override dhcp-authoritative dhcp-lease-max=253 dhcp-hostsfile=/home/novel/dnsmasq_bug/default.hostsfile addn-hosts=//home/novel/dnsmasq_bug/default.addnhosts $ cat default.addnhosts default.hostsfile $ ps aux|grep dnsma novel 60139 0,0 0,0 14192 2340 24 S+ 19:24 0:00,00 grep dnsma $ sudo dnsmasq --conf-file=./test.conf --leasefile-ro --dhcp-script=/usr/bin/true $ ps aux|grep dnsm nobody 60145 0,0 0,0 16884 5008 - S 19:24 0:00,00 dnsmasq --conf-file=./test.conf --leasefile-ro --dhcp-script=/usr/bin/true root 60146 0,0 0,0 16884 4884 - S 19:24 0:00,00 dnsmasq --conf-file=./test.conf --leasefile-ro --dhcp-script=/usr/bin/true novel 60148 0,0 0,0 14192 2336 24 S+ 19:24 0:00,00 grep dnsm $ sudo kill 60145 $ ps aux|grep dnsm root 60146 0,0 0,0 16884 4884 - S 19:24 0:00,00 dnsmasq --conf-file=./test.conf --leasefile-ro --dhcp-script=/usr/bin/true novel 60153 0,0 0,0 14192 2340 24 S+ 19:24 0:00,00 grep dnsm $ Could you please check if it works the same way on your side?