rc.d doesn't see my pidfile

oitdmser

New Member

Reaction score: 3
Messages: 14

FreeBSD noob here, coming from some experience with Linux and systemd.

I'm running ElectrumX which is a python3.6 script and want to have an rc.d script to control it. Electrumx reads it configuration variables from environment variables. In systemd config files I had a line like ENVIRONMENTFILE=/path/to/electrumx.confg for systemd to load all the variables into memory. The config file looks like this:

Code:
COIN=BitcoinSegwit
NET=mainnet
CACHE_MB=384
BANNER_FILE=/var/db/electrumx/banner.txt
Etc.
Etc.

For an rc.d scripted system the author recommends using his shell script run_electrumx that basically just adds an export in front of every variable, then it runs the electrumx_server python script. run_electrumx looks like this:
Code:
#!/usr/local/bin/bash
###############
# run_electrumx
###############


export COIN=BitcoinSegwit
export NET=mainnet
export CACHE_MB=384
export BANNER_FILE=/var/db/electrumx/banner.txt

# connectivity
export HOST=
export RPC_PORT=0
export TCP_PORT=50001
export SSL_PORT=50002
export SSL_CERTFILE=/var/db/electrumx/server.crt
export SSL_KEYFILE=/var/db/electrumx/server.key
export PEER_DISCOVERY=self
export DB_DIRECTORY=/var/db/electrumx/db

/usr/local/bin/electrumx_server 2>> /var/log/electrumx >> /var/log/electrumx &

My problem is that electrumx_server doesn't generate a PID file so rc.subr(8) has no way of knowing if it's running. The problem with this startup script is that it launches electrumx_server then quits so rc.subr(8) can't tell if electrumx is running either and is no more useful than just a boring init script.

I tried creating my own startup script startex.sh that loads the environment variables, sends logging to syslog, and creates a PID file with the pid of electrumx_server:

Code:
#!/usr/local/bin/bash

#sends outputs to syslog
exec 1> >(logger -p daemon.notice -t electrumx) 2>&1

#Tells BASH to export all variables
set -o allexport

#Tells BASH to load the config file into environment variables
source $electrumx_config
set +o allexport

#the & disown run the server script then detach it. Othwerwise terminal just sits there until it terminates.
/usr/local/bin/electrumx_server & disown

#copies the PID to a variable and prints it to the electrumx PID file
PID=$!
echo $PID > $electrumx_pid

and edited my rc.d script to include the pid file:

Code:
#!/bin/sh

# PROVIDE: electrumx
# REQUIRE: bitcoin
# KEYWORD: shutdown

#
# Add the following lines to /etc/rc.conf.local or /etc/rc.conf
# to enable this service:
#
# electrumx_enable (bool):      Set to NO by default.
#                               Set it to YES to enable bitcoin.
# electrumx_config (path):      Set to /var/local/electrumx/electrumx.conf
#                               by default.

. /etc/rc.subr

name=electrumx
rcvar=electrumx_enable

: ${electrumx_enable:=NO}
: ${electrumx_config=/var/local/electrumx/electrumx.conf}
: ${electrumx_user="electrumx"}
: ${electrumx_group="electrumx"}

required_files=${electrumx_config}

pidfile="/var/local/electrumx/electrumx.pid"
start_precmd=electrumx_prestart

command_interpreter="/usr/local/bin/bash"                                           
command="/usr/local/sbin/startex.sh"

electrumx_prestart()
{
        export electrumx_config=$electrumx_config
        export electrumx_pid=$pidfile
}

load_rc_config $name
run_rc_command "$1"

When I run service start electrumx it starts successfully. cat /var/local/electrumx/electrumx.pid returns the correct PID, but service doesn't seems to recognize the PID file:

Code:
% sudo service electrumx status
electrumx is not running.
%

I'm flat out of ideas here. Why doesn't service see the pid file?
 

PMc

Daemon

Reaction score: 685
Messages: 1,381

You might need an option
Code:
procname="/usr/local/bin/electrumx_server"
in addition to the pidfile="..."
 

T-Daemon

Daemon

Reaction score: 929
Messages: 1,816

rc.subr(8)
Code:
run_rc_command uses the following shell variables to    control    its
       behaviour.  Unless otherwise    stated,    these are optional.

...

pidfile   Path    to PID file.  Used to determine    the PID(s) of
               the running command.     If pidfile is set, use:

                 check_pidfile $pidfile    $procname

               to find the PID.  Otherwise,    if command is set,
               use:

                 check_process $procname

               to find the PID.
(Not that I know whats wrong, just pointing out.)
 

PMc

Daemon

Reaction score: 685
Messages: 1,381

Whats -most likely- wrong is that the T.O. starts a daemon with the name "electrumx_server", and I do not see that the rc.d would be told this name.

When the rc.d checks if the process is running, it must check that
  1. the pidfile exists
  2. a process is running with that pid
  3. that process has the correct name
because otherwise the process could be crashed, and some other process could have occupied that pid.
 
OP
O

oitdmser

New Member

Reaction score: 3
Messages: 14

You might need an option
Code:
procname="/usr/local/bin/electrumx_server"
in addition to the pidfile="..."
That fixed it. I didn't realize that rc.d checks the pid AND the proc name match. Wow, thanks!
 
Top