Solved Writing an rc.d script for a service wrapping multiple processes

I am trying to implement an rc.d(8) service script that starts multiple processes. The exact number of processes is determined dynamically from an rc.conf(5) variable like so:
dummy_process_count=5

I read the tutorial Practical rc.d scripting in BSD, but there is no example with multiple processes.

What would be a practical and simple approach?
I am thinking about doing a loop and then defining "name", "command", "pidfile", etc. multiple times to generate multiple services within a single script:
Bash:
#!/bin/sh

. /etc/rc.subr

: ${dummy_process_count:=0}

for k in seq $dummy_process_count; do
  name="dummy${k}"
  eval ": \${${name}_enable:=no}"
  pidfile="/var/run/${name}.pid"
  start_cmd="/path/to/executable/dummy instance=${k}"
  stop_cmd=":"

  load_rc_config $name
  run_rc_command "$@"
done

Is this approach OK or are there any pitfalls? Is it a bad idea to generate multiple services from a single script?
 
Do you mean instances or profiles? Of course, they are not the same but they share the same approach: use a single rc script to manage multiple processes or, in a general term, multiple things. I think the best way to learn the rc framework is to read the man pages, that article and real rc scripts used in some ports. Here some examples:

 
Do you mean instances or profiles? Of course, they are not the same but they share the same approach: use a single rc script to manage multiple processes or, in a general term, multiple things. I think the best way to learn the rc framework is to read the man pages, that article and real rc scripts used in some ports. Here some examples:

Thanks for the info. My intention is to start a number of SSH processes, each of them with one or more tunnels, according to a predefined configuration.
I did not know about profiles you mentioned. I need to study those examples.
At first glance the sopel example looks very similar to what I am trying to do, I think this should help me find a solution.
 
As a final solution, I used sopel.in as an example.
Here is what I came up with:
Bash:
#!/bin/sh

# PROVIDE: ssh_tunnel
# REQUIRE: LOGIN FILESYSTEMS
# KEYWORD: shutdown

. /etc/rc.subr

name=ssh_tunnel
rcvar=${name}_enable
desc="SSH tunnels started automatically"
start_cmd=ssh_tunnel_start
# ...

load_rc_config "$name"

# set defaults
: ${ssh_tunnel_enable:=NO}
: ${ssh_tunnel_connections:=0}
: ${ssh_tunnel_piddir:=/var/run/${name}}
: ${ssh_tunnel_logdir:=/var/log/${name}}
: ${ssh_tunnel_flags=-N}
: ${ssh_tunnel_user="nobody"}
: ${ssh_tunnel_group="nobody"}

ssh_tunnel_ssh="/usr/bin/ssh"
ssh_tunnel_daemon="/usr/sbin/daemon"

ssh_tunnel_start()
{
    local profile pidfile logfile vn ssh_args
  
    profile="$1"; shift
  
    # ...
  
    pidfile="${ssh_tunnel_piddir}/${name}${profile}.pid"
    logfile="${ssh_tunnel_logdir}/${name}${profile}.log"
    vn="ssh_tunnel_connection_${profile}"
    eval ssh_args=\$${vn}
  
    # ...
  
    echo "Starting ${name}, connection ${profile} of ${ssh_tunnel_connections}, arguments: ${ssh_args}"
  
    ${ssh_tunnel_daemon} -p "${pidfile}" -t "${name}${profile}" -u "${ssh_tunnel_user}" \
        ${ssh_tunnel_ssh} ${ssh_tunnel_flags} -E ${logfile} ${ssh_args} $@
}


# ...

cmd="$1"; shift
for i in $(seq ${ssh_tunnel_connections}); do
    run_rc_command "${cmd}" "${i}" $@
done

Variables set:
Bash:
# sysrc -a | grep ssh
ssh_tunnel_enable: YES
ssh_tunnel_connections: 1
ssh_tunnel_connection_1: -i /usr/local/etc/ssh/mykey  -L localhost:1194:localhost:1194 -p 22 tunnel@myserver.com

I am very pleased with the outcome.
 
Back
Top