# rc.d daemon not processing command flags



## justrjlewis (Jan 4, 2016)

I started working with a great web server called caddy and started working on an rc.d script to get it running as a service. I put together a script that mostly worked seen here. The bug in this original script was that the service would start on boot/reboot, but it didn’t play well with the start/stop/restart/etc… commands. I went through more information and came up with the following. It works well for starting, stopping and restarting the server process, BUT the script fails if I add ${caddy_flags} to the start command. Example:


```
caddy_start() {
  ${daemon_cmd} ${daemon_cmd_args} ${command} ${caddy_flags}
}
```

One other thing is that whether the script works or not, nothing prints in the command_msg where I have ${rc_pid}.
I’ve tried it several ways, but there is something that I am missing. Any suggestions would be welcome. Here’s the full script:


```
#!/bin/sh
# PROVIDE: caddy
# REQUIRE: LOGIN
# KEYWORD: shutdown

# Documentation=https://caddyserver.com/docs
# add php-fpm to REQUIRE to run php/fastcgi processes

# Add the following lines to /etc/rc.conf to enable caddy:
#
# OPTION                DEFAULTS
#
# caddy_enabl (bool):   I set to Yes by default (26),
#                       because frankly, it's my script. :smile:
# caddy_user:           caddysrv:caddysrv (user:group): www was unable to start
#                       caddy because it doesn't have a user/home directory.
#                       Assuming that is by design, $caddy_user serves this
#                       function [caddy start/stop/restart].
# caddy_bool (bool):    true
# caddy_email (mailto): No default - set to your contact info
# caddy_config (path):  My default: `/srv/www/Caddyfile`
#                       Set to your webserver PATH
# caddy_flags (str):    -agree=true
#                       -email="you@mailserver.com"
#                       -conf=/your/webroot/path/Caddyfile
#                       -pidfile=/path/to/var/run/caddy.pid

. /etc/rc.subr

name="caddy"
rcvar=caddy_enable

# Set defaults
: ${caddy_enable:="YES"}
: ${caddy_user="caddysrv"}
: ${caddy_terms="true"}
: ${caddy_email="me@gmail.com"}
: ${caddy_config="/srv/www/Caddyfile"}
: ${caddy_flags="-agree=$caddy_terms -email=$caddy_email -conf=$caddy_config"}

pidfile="/srv/var/run/${name}.pid"
command="/usr/local/sbin/${name}"

daemon_cmd="/usr/sbin/daemon"
daemon_cmd_args="-cf -p ${pidfile} -u ${caddy_user}"
command_msg="Starting caddy with ${caddy_email} in directory ${caddy_config}.  The PID is ${rc_pid}."

sig_stop="QUIT"
sig_reload="USR1"

start_cmd="${name}_start"
start_precmd="${name}_prestart"

caddy_prestart() {
  touch ${pidfile}
  chown ${caddy_user} ${pidfile} && chmod 775 ${pidfile}
}
caddy_start() {
  ${daemon_cmd} ${daemon_cmd_args} ${command}
  echo ${command_msg}
}

load_rc_config "$name"
run_rc_command "$1"
```


----------



## junovitch@ (Jan 5, 2016)

Hello. An output of what the failure is would be helpful. When it comes to shell scripting the -x flag (see sh(1)) can be very helpful if not a bit noisy at first look.  So `sh -x /usr/local/etc/rc.d/<yourscript> start` will give some clues at what the issue is.

Also, I notice you are rolling some of your own code for using /usr/sbin/daemon.  Take a look at some ports that do something similar and you should be able to simplify things slightly.  Here's an example: https://svnweb.FreeBSD.org/ports/head/databases/influxdb/files/influxd.in?view=markup


----------



## justrjlewis (Jan 5, 2016)

Ah- thanks!  I made a pastebin since it's pretty long – here: http://pastebin.com/5XfZccPC


----------



## Juha Nurmela (Jan 5, 2016)

Looks like rc_pid does not get set at all in the *start* case, by rc-system design. If there were a caddy already running, rc_pid would be of that *old* process. You ought to see it set properly in the *status* case, I think. 

Another problem is that command_msg is expanded on the spot, when assigned, before rc_pid has had a chance to receive any value. If you wanted to see it's value, you would need to delay the expansion

```
command_msg="....\$rc_pid ..."
...
eval echo $commmand_msg
```

Juha


----------



## justrjlewis (Jan 5, 2016)

junovitch@ said:


> Also, I notice you are rolling some of your own code for using /usr/sbin/daemon.  Take a look at some ports that do something similar and you should be able to simplify things slightly.  Here's an example: https://svnweb.FreeBSD.org/ports/head/databases/influxdb/files/influxd.in?view=markup



Question about the example file.  I notice the precmd starts with the command `install -o $user`...any idea what that means? ...I mean I KNOW what install means, rather I've never seen that particular usage.


----------



## justrjlewis (Jan 5, 2016)

Thanks Juha - you're right.  When the service does start, running status will show the $rc_pid.  I don't really need it in the message. I just wondered why it wasn't printing. 

Thanks again!


----------



## leebrown66 (Jan 5, 2016)

justrjlewis said:


> Question about the example file.  I notice the precmd starts with the command `install -o $user`...any idea what the means? ...I mean I KNOW what install means, rather I've never seen that particular usage.


In that particular case, it's used to create an empty file (overwriting whatever may already exist) with the specified user as owner and execute permissions.  It's analagous to: 
	
	



```
su - guest -c "cp /dev/null /tmp/somefile;chmod +x /tmp/somefile"
```


----------



## SirDice (Jan 5, 2016)

justrjlewis said:


> ```
> # Set defaults
> : ${caddy_enable:="YES"}
> ```


Not part of the issue but services are expected to be off by default.


----------



## justrjlewis (Jan 6, 2016)

okay, I've narrowed something down.  

I altered the rc.d file as suggested and now have the following and it works, BUT if I add the `-conf=/srv/www/Caddyfile`, the script fails. It does not fail if I simply invoke the start command without running it as a service.  It also does not fail if I leave it was originally when I couldn't restart the service... weird.

Here's the new pastebin and the updated code: http://pastebin.com/ea47u5bt


```
#!/bin/sh

# PROVIDE: caddy
# REQUIRE: LOGIN
# KEYWORD: shutdown

# Documentation=https://caddyserver.com/docs
# add php-fpm to REQUIRE to run php/fastcgi processes

# Add the following lines to /etc/rc.conf to enable caddy:
#
# OPTION                DEFAULTS
#
# caddy_enabl (bool):   I set to Yes by default (26),
#                       because frankly, it's my script. :smile:
# caddy_user:           caddysrv:caddysrv (user:group): www was unable to start
#                       caddy because it doesn't have a user/home directory.
#                       Assuming that is by design, $caddy_user serves this
#                       function [caddy start/stop/restart].
# caddy_bool (bool):    true
# caddy_email (str):     No default - set to your contact info
# caddy_config (path):  My default: `/srv/www/Caddyfile`
#                       Set to your webserver PATH

# Opts set in THIS file - can be set in /etc/rc.conf as well (not recommended):
# caddy_flags (str):    -agree=true
#                       -email="you@mailserver.com"
#                       -conf=/your/webroot/path/Caddyfile
#                       -pidfile=/path/to/var/run/caddy.pid

. /etc/rc.subr

name="caddy"
rcvar=caddy_enable

# Set defaults
: ${caddy_enable:="NO"}
: ${caddy_user="caddysrv"}
: ${caddy_config="/srv/www/Caddyfile"}
: ${caddy_email="rj@justrjlewis.com"}
: ${process_flags="-agree=true -email=rj@justrjlewis.com"}

pidfile="/srv/var/run/${name}.pid"
procname="/usr/local/sbin/${name}"

command="/usr/sbin/daemon"
command_args="-cf -p ${pidfile} -u ${caddy_user} ${procname} ${process_flags}"
command_msg="Starting caddy..."

sig_stop="QUIT"
sig_reload="USR1"

start_cmd="${name}_start"
start_precmd="${name}_prestart"
start_postcmd="${name}_poststart"

caddy_prestart() {
  install -o ${caddy_user} /dev/null ${pidfile}
}
caddy_start() {
  ${command} ${command_args}
}
caddy_poststart() {
  echo ${command_msg}
}

load_rc_config "$name"
run_rc_command "$1"
```


----------



## Juha Nurmela (Jan 6, 2016)

Prepending 
	
	



```
ktrace -i -f /tmp/foo ${command} ${command_args}
```
you can later watch what happened inside that process tree, with `kdump -f /tmp/foo`.
*Lots* of stuff to wade thru, but if nothing else helps...

Juha


----------

