Other Writing daemon on java

abishai

Aspiring Daemon

Reaction score: 197
Messages: 786

Hello,
I'm writing daemon on java, can you share best practices about daemon developing? I use tmux, however want to make it correctly.

1. I don't need root privileges at all. How should I drop privileges? With su command in rc.d script ? Probably, I'd be scared to run anything java under root.
2. Main thread is in endless loop now to keep all threads alive. It's OK to service to be killed in any time. However, should I handle some signals to ensure graceful termination?

If you know some java daemons in port tree, links are welcome.
 

usdmatt

Daemon

Reaction score: 610
Messages: 1,546

A common way to do this is with daemon().
For instance daemon -cf -u user -p /var/run/myapp.pid /full/path/to/java -jar /path/to/myapp.jar will daemonize and run the specified command. You can also add -r to have it automatically restart the command if it exits.

The unifi port is a java daemon i happen to have installed. Their rc.d file looks like the below. On start the rc.d system runs command with command_args as arguments, so they just replace those with the required daemon command line.

Code:
# PROVIDE: unifi
# REQUIRE: LOGIN
# KEYWORD: shutdown

#
# Add the following line to /etc/rc.conf to enable `unifi':
#
# unifi_enable="YES"

. /etc/rc.subr
name=unifi

rcvar=unifi_enable
load_rc_config ${name}

: ${unifi_enable:=NO}
: ${unifi_user:=unifi}
: ${unifi_group:=unifi}
: ${unifi_chdir=/usr/local/share/java/unifi}
: ${unifi_javaflags:="-Djava.awt.headless=true -Xmx1024M"}

pidfile="/var/run/unifi/${name}.pid"
procname=/usr/local/bin/java
command="/usr/sbin/daemon"
command_args="-f -p ${pidfile} /usr/local/bin/java ${unifi_javaflags} -jar lib/ace.jar start"
start_precmd=start_precmd

start_precmd()
{
        if [ ! -e /var/run/unifi ] ; then
                install -d -o unifi -g unifi /var/run/unifi;
        fi
}

run_rc_command "$1"
 
OP
A

abishai

Aspiring Daemon

Reaction score: 197
Messages: 786

I tried it today, however I can't figure out why I can't stop the daemon.

Code:
# PROVIDE: smartping
[CODE]
# REQUIRE: LOGIN
# KEYWORD: shutdown

#
# Add the following line to /etc/rc.conf to enable `smartping':
#
# smartping_enable="YES"

. /etc/rc.subr
name=smartping

rcvar=smartping_enable
load_rc_config ${name}

: ${smartping_enable:=NO}
: ${smartping_user:=smartping}
: ${smartping_group:=smartping}
: ${smartping_chdir=/home/abishai/smartping}
: ${smartping_javaflags:="-Dorg.slf4j.simpleLogger.logFile=/var/log/smartping/smartping.log"}

pidfile="/var/run/smartping/smartping.pid"
java_cmd="/usr/local/bin/java"
procname="${java_cmd}"
command="/usr/sbin/daemon"
command_args="-p ${pidfile} ${java_cmd} ${smartping_javaflags} -cp ${smartping_chdir}/smartping.jar ru.abinet.smartping.SmartPing"
start_precmd=start_precmd

start_precmd()
{
if [ ! -e /var/run/smartping ] ; then
install -d -o smartping -g smartping /var/run/smartping;
fi

if [ ! -e /var/log/smartping ]; then
install -d -o smartping -g smartping /var/log/smartping;
fi
}

run_rc_command "$1"

[/CODE]

Code:
abishai@mts:~ % doas service smartping onestop
smartping not running? (check /var/run/smartping/smartping.pid).

Code:
abishai@mts:~ % ls -la /var/run/smartping/
total 13
drwxr-xr-x  2 smartping  smartping   3 Mar 18 13:41 .
drwxr-xr-x  6 root       wheel      16 Mar 18 04:15 ..
-rw-------  1 smartping  smartping   5 Mar 18 13:41 smartping.pid

Code:
abishai@mts:~ % doas cat /var/run/smartping/smartping.pid
46371

ps shows started daemon and logs confirms it's up
Code:
46370  -  IWsJ 0:00.00 daemon: /usr/local/bin/java[46371] (daemon)
46371  -  IJ   0:02.48 /usr/local/openjdk8/bin/java -Dorg.slf4j.simpleLogger.logFile=/var/log/smartping/smartping.log -cp /home/abishai/smartping/smartping.jar ru.abinet.smartping.SmartPing

What I'm missing?
 

usdmatt

Daemon

Reaction score: 610
Messages: 1,546

I dealt with this exact issue the other day. The rc system is trying to match $procname to the ps line in order to make sure it's finding the right process. Your $procname is set to /usr/local/bin/java but process 46371 doesn't contain that.

In my case I just changed procname to /usr/local/openjdk8/bin/java. Not sure what the real way to deal with this is, as I doubt hardcoding the openjdk8 path into a committed port is a good idea.
 
Top