Hi,<br><br>Over the weekend I decided to create an icecast relay for Nicecast. I wanted this to run in a <br>chroot jail on a redhat server. There did not seem to be much on the web about&nbsp; setting this up; <br>I&#39;m including some details here. This is my first encounter with icecast; I&#39;m&nbsp; hoping to <br>
elicit comments and criticism (e.g., if my post is too long).<br><br>First, there did not seem to be a startup script for Red Hat compatible with chkconfig, much less<br>such a script with a reload section; I include mine. This handles reloading the configuration--I&#39;m <br>
wondering if there is a better way to do this. <br><br>Also, I have another problem: I want an off the air loop to play exactly once, after which the<br>user is disconnected. However, the loop plays indefinitely.<br><br>First, here is the startup script (I call this icectl); my configuration chroots icecast to&nbsp; <br>
/usr/local/share/icecast. The relevant case is reload)<br><br>!/bin/sh<br>#<br>#<br># chkconfig: 2345 70 40<br># description: icecast startup script<br>#<br>ICECAST=/usr/local/bin/icecast<br>ICECONFIG=/usr/local/etc/icecast.xml<br>
ICEPIDFILE=/usr/local/share/icecast/icecast.pid<br><br>. /etc/rc.d/init.d/functions<br><br>RETVAL=0<br><br>case &quot;$1&quot; in<br>&nbsp;&nbsp; start)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -n &quot;Starting icecast: &quot;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ -f $ICECAST ] || exit 1<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ -f $ICECONFIG ] || exit 1<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; daemon --pidfile=$ICEPIDFILE $ICECAST -b -c $ICECONFIG &gt; /dev/null<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETVAL=$?<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ $RETVAL -eq 0 ] &amp;&amp; touch /var/lock/subsys/icecast<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br><br>&nbsp; stop)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -n &quot;Shutting down icecast: &quot;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; killproc -p $ICEPIDFILE $ICECAST<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETVAL=$?<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ $RETVAL -eq 0 ] &amp;&amp; rm -f /var/lock/subsys/icecast<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br><br>&nbsp; restart)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0 stop<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $0 start<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETVAL=$?<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br><br>&nbsp; reload)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo -n &quot;Reloading icecast configuration: &quot;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; killproc -p $ICEPIDFILE $ICECAST -HUP<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETVAL=$?<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br><br>&nbsp; status)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status -p $ICEPIDFILE icecast<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RETVAL=$?<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;<br>&nbsp; *)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo &quot;Usage: $0 {start|stop|restart|reload|status}&quot;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exit 1<br>esac<br><br>exit $RETVAL<br><br>The first problem I had with the reload function is that the location of<br>the configuration file, /usr/local/etc/icecast.xml, is inaccessible<br>once the process is chrooted. I resolved this by moving the configuration<br>
file to /usr/local/share/icecast/usr/local/etc/icecast.xml and setting a symbolic<br>link to this in /usr/local/etc/. This enabled the icecast process to read the<br>configuation on startup, and subsequently relative to the jail root of<br>
/usr/local/share/icecast.<br><br>The next problem was that /etc/mime.types was inaccessible after a reload,<br>but this was fixed by copying this file to /usr/local/share/icecast/etc.<br>Before adding the mime.types, the /usr/local/share/icecast/etc directory contained<br>
<br>[root@myhost etc]# ls -latrs<br>total 56<br>8 -rw-r--r-- 1 nobody nogroup&nbsp; 113 Nov&nbsp; 1 21:08 resolv.conf<br>8 -rw-r--r-- 1 nobody nogroup&nbsp;&nbsp; 38 Nov&nbsp; 1 21:28 passwd<br>8 -rw-r--r-- 1 nobody nogroup&nbsp;&nbsp; 17 Nov&nbsp; 1 21:28 group<br>
8 -rw-r--r-- 1 nobody nogroup 1693 Nov&nbsp; 1 21:42 nsswitch.conf<br>8 drwxr-xr-x 9 nobody nogroup 4096 Nov&nbsp; 1 21:50 ..<br>8 -rw-r--r-- 1 nobody nogroup&nbsp; 607 Nov&nbsp; 1 21:58 hosts<br>8 drwxr-xr-x 2 nobody nogroup 4096 Nov&nbsp; 1 21:58 .<br>
<br>Where the files were edited to contain (close to) the minimum necessary.<br>For example, passwd and group were obtained with <br>&nbsp; getent passwd nobody &gt; passwd<br>&nbsp; getent group&nbsp; nogroup &gt; group<br>and nsswitch.conf had all references to ldap removed.<br>
<br>/etc/hosts was copied to /usr/local/share/icecast/etc/hosts, and most<br>entries were removed; however I added an entry for <a href="http://dir.xiph.org">dir.xiph.org</a>. No doubt<br>I did not completely populate my chroot jail with all the needed libraries, since<br>
I seemed to need this hosts file entry for the lookup to succeed.<br><br><br>The lib directory was populated using the ldd command to locate<br>needed libraries; symbolic links were added as needed<br><br>[root@myhost etc]# ldd /usr/local/bin/icecast libcurl.so.2 =&gt; /opt/grid/prima<br>
/lib/libcurl.so.2 (0x00002b3811c8b000)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libssl.so.6 =&gt; /lib64/libssl.so.6 (0x0000003a01200000)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libcrypto.so.6 =&gt; /lib64/libcrypto.so.6 (0x00000039fc400000)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libdl.so.2 =&gt; /lib64/libdl.so.2 (0x00000039f4400000)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libvorbis.so.0 =&gt; /usr/lib64/libvorbis.so.0 (0x00000039f5800000)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libxslt.so.1 =&gt; /usr/lib64/libxslt.so.1 (0x0000003d14400000)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libxml2.so.2 =&gt; /opt/grid/apache/lib/libxml2.so.2 (0x00002b3811ed4000)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libz.so.1 =&gt; /usr/lib64/libz.so.1 (0x00000039f4c00000)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libm.so.6 =&gt; /lib64/libm.so.6 (0x00000039f4000000)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libpthread.so.0 =&gt; /lib64/libpthread.so.0 (0x00000039f4800000)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libc.so.6 =&gt; /lib64/libc.so.6 (0x00000039f3c00000)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libogg.so.0 =&gt; /usr/lib64/libogg.so.0 (0x00002b381227e000)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libgssapi_krb5.so.2 =&gt; /usr/lib64/libgssapi_krb5.so.2 (0x00000039ff6000<br>00)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libkrb5.so.3 =&gt; /usr/lib64/libkrb5.so.3 (0x00000039fc800000)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libcom_err.so.2 =&gt; /lib64/libcom_err.so.2 (0x00000039f9000000)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libk5crypto.so.3 =&gt; /usr/lib64/libk5crypto.so.3 (0x00000039fb000000)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /lib64/ld-linux-x86-64.so.2 (0x00000039f3800000)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libkrb5support.so.0 =&gt; /usr/lib64/libkrb5support.so.0 (0x00000039ffa000<br>
00)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libkeyutils.so.1 =&gt; /lib64/libkeyutils.so.1 (0x00000039fee00000)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libresolv.so.2 =&gt; /lib64/libresolv.so.2 (0x00000039fa000000)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libselinux.so.1 =&gt; /lib64/libselinux.so.1 (0x00000039f5400000)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libsepol.so.1 =&gt; /lib64/libsepol.so.1 (0x00002b3812487000)<br><br>The libraries were copied with<br><br>for file in $(ldd /usr/local/bin/icecast | awk &#39;{print $3}&#39;); do <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cp $file lib; <br>done<br>
<br><br>For name resolution, additional libraries were needed in lib<br><br>&nbsp; cp /lib/<a href="http://libnss_files-2.5.so">libnss_files-2.5.so</a> .<br>&nbsp; ln -s <a href="http://libnss_files-2.5.so">libnss_files-2.5.so</a> libnss_files.so.2<br>
<br>&nbsp; cp /lib/<a href="http://libnss_dns-2.5.so">libnss_dns-2.5.so</a> .<br>&nbsp; ln -s <a href="http://libnss_dns-2.5.so">libnss_dns-2.5.so</a> libnss_dns.so.2<br><br>I may need to include directories for locales since the time logged is in UTC.<br>
<br>This whole procedure follows the typical thing one does for jailing apache or bind.<br><br>-----------------------------------------------------------------------<br><br>Now with the reload function working in the chroot jail, I was able to experiment<br>
with changing the icecast.xml configuration without restarting the server and breaking<br>connections.<br><br>But, the following &lt;mount&gt; sections in my icecast.xml configuration left me with<br>the mount point OffTheAir.mp3 looping indefinitely<br>
<br>&lt;mount&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;mount-name&gt;/listen&lt;/mount-name&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- Not known how to avoid an infinite loop<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; with a short fallback mount. Setting <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; max-listener-duration did not work&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;fallback-mount&gt;OffTheAir.mp3&lt;/fallback-mount&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;fallback-override&gt;1&lt;/fallback-override&gt; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;intro&gt;/intro.mp3&lt;/intro&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/mount&gt;<br>
<br>&nbsp;&nbsp;&nbsp; &lt;mount&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;mount-name&gt;/OffTheAir.mp3&lt;/mount-name&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;max-listener-duration&gt;3&lt;/max-listener-duration&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;hidden&gt;1&lt;/hidden&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/mount&gt;<br>
<br><br>I wanted the fallback mountpoint to play once, and then disconnect the user.<br>However, the&nbsp; &lt;max-listener-duration&gt; parameter seems to work only for <br>connections directly to the OffTheAir.mp3 mountpoint, but not if this is<br>
the fallback mountpoint.<br><br>Thanks for bearing with me.<br><br>FL<br>