<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<atom:link href="https://dev1galaxy.org/extern.php?action=feed&amp;tid=4904&amp;type=rss" rel="self" type="application/rss+xml" />
		<title><![CDATA[Dev1 Galaxy Forum / [SOLVED] Runit and background daemons]]></title>
		<link>https://dev1galaxy.org/viewtopic.php?id=4904</link>
		<description><![CDATA[The most recent posts in [SOLVED] Runit and background daemons.]]></description>
		<lastBuildDate>Tue, 22 Feb 2022 16:35:21 +0000</lastBuildDate>
		<generator>FluxBB</generator>
		<item>
			<title><![CDATA[[SOLVED] Runit and background daemons]]></title>
			<link>https://dev1galaxy.org/viewtopic.php?pid=34832#p34832</link>
			<description><![CDATA[<p>Runit is designed to work with daemons that stay in the foreground, so that the daemon may be supervised easily. Many daemons do try and run in the background but there is often an option that can be given to tell it to run in the foreground. Thus <span class="bbc">ntpd</span> can use the <span class="bbc">-n (--nofork)</span> option to run in the foreground.</p><p>Occasionally, there is a daemon which only runs in the background. I have found <span class="bbc">noip2</span> which updates my dynamic IP address. I have not found a way to tell it to run in the foreground. There are one or two things which you can do to handle this.</p><p>Runit comes with a program to change the process status (<span class="bbc">chpst</span>).<br />This has a number of things it can do, such as changing the user or group it runs as.<br />The options which are useful here are -l &amp; -L which can open a lock file for writing and obtain an exclusive lock on it, creating the file if necessary. <span class="bbc">-l</span> will wait for the file to become available, while <span class="bbc">-L</span> will fail immediately if it is not available.</p><p>The file <span class="bbc">/etc/sv/noip2/run</span> looks like this :-</p><div class="quotebox"><blockquote><div><p>#!/bin/sh -eu<br />exec 2&gt;&amp;1</p><p>echo &quot;executing /etc/sv/noip2/run&quot;</p><p>chpst -L supervise/runlock /usr/local/bin/noip2 || exit 1<br />exec chpst -l supervise/runlock true</p></div></blockquote></div><p>The echo message is logged if logging has been set up.</p><p>The daemon <span class="bbc">noip2</span> is run by <span class="bbc">chpst</span> with an exclusive lock on the file <span class="bbc">/etc/sv/noip2/supervise/runlock</span></p><p>The second instance of <span class="bbc">chpst</span> is ready to run the command <span class="bbc">true</span> and waits for the lock file to become available, i.e. when <span class="bbc">noip2</span> stops running. When the lock file becomes available the command <span class="bbc">true</span> will be run, which returns immediately and <span class="bbc">runit</span> becomes aware that <span class="bbc">noip2</span> is no longer running and can take the appropriate actions.</p><p>But what happens if we want to stop the daemon? If</p><div class="codebox"><pre><code>sv down noip2</code></pre></div><p>is run then <span class="bbc">runit</span> will stop the waiting <span class="bbc">chpst</span> process, but not <span class="bbc">noip2</span>.<br />After it has stopped <span class="bbc">chpst</span> it will then look for the file <span class="bbc">finish</span> and run it if it exists.<br />As we know the name of the lock file, we can find the PID of the process which has it open, using <span class="bbc">lsof</span>, which may need installing.</p><div class="codebox"><pre><code>apt install lsof</code></pre></div><p>We can find the processes which have the lock file open :-</p><div class="codebox"><pre><code>lsof /run/runit/supervise/noip2/runlock

COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chpst   2006   root    3w   REG   0,23        0 1738 /run/runit/supervise/noip2/runlock
noip2   2051 nobody    3w   REG   0,23        0 1738 /run/runit/supervise/noip2/runlock</code></pre></div><p>We could find the PID of the daemon by looking through the output for the process run by <span class="bbc">nobody</span><br />and then printing the second field :-</p><div class="codebox"><pre><code>PID=`lsof /run/runit/supervise/noip2/runlock | grep nobody | awk &#039;{ print $2 }&#039; -`</code></pre></div><p>although <span class="bbc">awk</span> can do the search as well :-</p><div class="codebox"><pre><code>PID=`lsof /run/runit/supervise/noip2/runlock | awk &#039;/nobody/ { print $2 }&#039; -`</code></pre></div><p>However, a study of the lsof man page shows that there are lots of options available and the <span class="bbc">-t</span> option just prints out the PIDs</p><div class="codebox"><pre><code>lsof -t /run/runit/supervise/noip2/runlock

2006
2051</code></pre></div><p>Also, there is the <span class="bbc">-c</span> option which can select the process of a particular command or filter out processes of certain commands with the negation <span class="bbc">^</span>. In this case we don&#039;t want the <span class="bbc">chpst</span> process.</p><div class="codebox"><pre><code>lsof -t -c ^chpst /run/runit/supervise/noip2/runlock

2051</code></pre></div><p>which can be incorporated into the file <span class="bbc">/etc/sv/noip2/finish</span> :-</p><div class="quotebox"><blockquote><div><p>#!/bin/sh<br />exec 2&amp;&gt;1</p><p># use lsof to find the process with a lock on our file.</p><p>PID=`lsof -t -c ^chpst /run/runit/supervise/noip2/runlock`</p><p>echo &quot;executing /etc/sv/noip2/finish. PID = $PID&quot;</p><p>[ -z $PID ] &amp;&amp; exit 1</p><p># We could do something like &quot;kill -TERM $PID&quot;, but in this case &quot;noip2 -K $PID&quot; works.</p><p>/usr/local/bin/noip2 -K $PID</p></div></blockquote></div><p>This seems to work nicely. With <span class="bbc">run</span> and <span class="bbc">finish</span> set up the daemon can be started, supervised and stopped.</p>]]></description>
			<author><![CDATA[dummy@example.com (Geoff 42)]]></author>
			<pubDate>Tue, 22 Feb 2022 16:35:21 +0000</pubDate>
			<guid>https://dev1galaxy.org/viewtopic.php?pid=34832#p34832</guid>
		</item>
	</channel>
</rss>
