Solved Why won't my "new-style" rc script start at boot?

CleanCut

New Member


Messages: 5

On pfSense 2.2.4 (FreeBSD 10.1), my custom init script filebeat_wrapper won't start at boot.

According to rcorder it should start right after boot:

Code:
# rcorder /etc/rc.d/* /usr/local/etc/rc.d/*
(snip)
/etc/rc.d/SERVERS
/etc/rc.d/DAEMON
/etc/rc.d/LOGIN
/usr/local/etc/rc.d/filebeat_wrapper
(snip)
The rc script works fine from the command-line, and service filebeat_wrapper enabled has a return code of 0 (meaning enabled, if I understand correctly, since it's a returncode).

Code:
# service filebeat_wrapper status
filebeat_wrapper is not running
# service filebeat_wrapper start
starting filebeat_wrapper
# service filebeat_wrapper status
filebeat_wrapper is running
# ps auxww | grep \[b\]eat
root    80780 75.9  0.3  13212  5536  -  R    10:09PM 0:17.91 /usr/local/bin/python /usr/local/bin/filebeat_wrapper (python2.7)
root    81127 42.5  0.7 798488 14816  -  S    10:09PM 0:10.12 /usr/local/bin/filebeat-freebsd-386 -c /usr/local/etc/filebeat.yml -e -v
# service filebeat_wrapper stop
stopping filebeat_wrapper
# service filebeat_wrapper status
filebeat_wrapper is not running
# service filebeat_wrapper enabled
# echo $?
0
If I change the filename of the rc script to end in .sh (/usr/local/etc/rc.d/filebeat_wrapper.sh), then the script starts at boot (since it is interpreted as an old-style script), and everything else is happy -- providing that you include the `.sh` in your commands:

Code:
# service filebeat_wrapper.sh status
filebeat_wrapper is running
Why does my script need a .sh extension, when other rc scripts apparently do not?

Here is my file listing:

Code:
# ls -l /usr/local/etc/rc.d/filebeat_wrapper.sh
-rwxr-xr-x  1 root  wheel  876 Jul 13 21:48 /usr/local/etc/rc.d/filebeat_wrapper.sh
Here are the contents of the file (note that the rc script calls a python script of a similar name in /usr/local/bin)

Code:
#!/bin/sh

# PROVIDE: filebeat_wrapper
# REQUIRE: NETWORKING LOGIN
# KEYWORD: nojail shutdown

. /etc/rc.subr

name="filebeat_wrapper"
rcvar="filebeat_wrapper_enabled"
pidfile="/var/run/${name}.pid"
start_cmd="${name}_start"
stop_cmd="${name}_stop"
status_cmd="${name}_status"

load_rc_config $name
: ${filebeat_wrapper_enabled:="YES"}

filebeat_wrapper_flags="-p ${pidfile} -f"
command="/usr/local/bin/filebeat_wrapper"

filebeat_wrapper_start()
{
    echo "starting ${name}"
    /usr/sbin/daemon -f -p ${pidfile} /usr/local/bin/python ${command}
}

filebeat_wrapper_stop()
{
    echo "stopping ${name}"
    kill `cat ${pidfile}`
}

filebeat_wrapper_status()
{
    if [ -e ${pidfile} ] ; then
        if ps `cat ${pidfile}` > /dev/null ; then
            echo "${name} is running"
            return
        fi
    fi
    echo "${name} is not running"
}

run_rc_command "$1"
 
OP
OP
CleanCut

CleanCut

New Member


Messages: 5

Hmm, in retrospect I suppose I should have begun on the pfSense forums asking if they had altered the init system at all.
 
OP
OP
CleanCut

CleanCut

New Member


Messages: 5

Are you saying all FreeBSD Derivatives have modified the init process itself so that it works differently?
 

kpa

Beastie's Twin

Reaction score: 1,811
Messages: 6,318

Are you saying all FreeBSD Derivatives have modified the init process itself so that it works differently?
Definitely not all of them but pfSense has modified it very heavily and none of the usual advice given for vanilla FreeBSD applies there.
 

Murph

Well-Known Member

Reaction score: 181
Messages: 297

Are you saying all FreeBSD Derivatives have modified the init process itself so that it works differently?
It certainly looks like it. /usr/local/etc/rc.d/* behaves quite differently on a real FreeBSD install, and will accept all normal scripts of the style found in /etc/rc.d, and not just *.sh as is being reported here.

They are quite free to do that, although it seems rather bizarre to me that they have done so. Hopefully there is a good reason for it, as it makes no sense to me right now.
 
OP
OP
CleanCut

CleanCut

New Member


Messages: 5

Thanks! That helps set my expectations appropriately. Up until now I was under the assumption that they would not have messed with the init system itself, so I have been reading all FreeBSD official docs. Now, hopefully, I can avoid some future hair-pulling angst.
 

kpa

Beastie's Twin

Reaction score: 1,811
Messages: 6,318

It certainly looks like it. /usr/local/etc/rc.d/* behaves quite differently on a real FreeBSD install, and will accept all normal scripts of the style found in /etc/rc.d, and not just *.sh as is being reported here.

They are quite free to do that, although it seems rather bizarre to me that they have done so. Hopefully there is a good reason for it, as it makes no sense to me right now.
I bet it's the heritage of m0n0wall from which pfSense was derived from.
 

crees@

New Member
Developer

Reaction score: 3
Messages: 10

Necro post alert (should help users landing here)!

Several issues with your script:

Your rcvar should be

Bash:
rcvar=filebeat_wrapper_enable
Note the lack of 'd' at the end.

Also, you should set _enable to NO by default, and add
Bash:
filebeat_wrapper_enable=yes
to rc.conf.

Make sure the script is executable, and also, you shouldn't need to redefine _start etc; just set
Bash:
command=/usr/sbin/daemon
command_args="/usr/local/bin/python /usr/local/bin/filebeat_wrapper"
filebeat_wrapper_flags="-f -p $pidfile"
 

PMc

Aspiring Daemon

Reaction score: 193
Messages: 542

Ah, that works also. Only one has to keep in mind that $filebeat_wrapper_flags is NOT the flags to the filebeat_wrapper program but the flags to the daemon. So I wouldn't use that variable, because it is misleading to the operator.

Another weakness is: you cannot stop that; rc.d cannot not find the running process. (That might work better with a capital -P.)
Or, I'm doing it that way:
Code:
pidfile="/var/run/${name}.pid"
procname="/ext/sbin/${name}"
command="/usr/sbin/daemon"
command_args="-S -p ${pidfile} ${procname} ..."
A more piggish one, bareos-webui as a freestanding appserver on an uwsgi rig:
Code:
name="bareos_ui"
[...]
pidfile="/var/uWSGI/bareosUI/${name}.pid"
command="/usr/bin/umask"
procname="/usr/local/bin/uwsgi-3.6"
command_args="077; /usr/sbin/daemon -t Bareos\ WebUI -S -T uwsgi_bwui -p ${pidfile} ${procname} ${bareos_ui_config}"
(it seems rc.d is lacking an umask option)

BTW: try to avoid putting a symlink into $procname; some programs able to exec() themselves, and then the argv[0] will change to whatever the link points to, with the PID unchanged, and rc.d will not find it anymore.
 
Last edited:

Crotalus

Member

Reaction score: 1
Messages: 97

Thanks! That helps set my expectations appropriately. Up until now I was under the assumption that they would not have messed with the init system itself, so I have been reading all FreeBSD official docs. Now, hopefully, I can avoid some future hair-pulling angst.
Be carefull of PfSense where you put things as they may disappear with a reboot.
 

crees@

New Member
Developer

Reaction score: 3
Messages: 10

Code:
pidfile="/var/uWSGI/bareosUI/${name}.pid"
command="/usr/bin/umask"
procname="/usr/local/bin/uwsgi-3.6"
command_args="077; /usr/sbin/daemon -t Bareos\ WebUI -S -T uwsgi_bwui -p ${pidfile} ${procname} ${bareos_ui_config}"
(it seems rc.d is lacking an umask option)
Code:
start_precmd="/usr/bin/umask 077"
This is the approach here. Yes, you need to set procname with /usr/sbin/daemon too-- nice catch.
 
  • Thanks
Reactions: PMc

PMc

Aspiring Daemon

Reaction score: 193
Messages: 542

Code:
start_precmd="/usr/bin/umask 077"
This is the approach here. Yes, you need to set procname with /usr/sbin/daemon too-- nice catch.
Yes, that would be nice - but it doesnt work that way (because the user is switched). :(

What gets actually executed is this:
limits -C daemon su -m uwsgi -c 'sh -c "/usr/sbin/daemon -t Bareos\ WebUI -S -T uwsgi_bwui -p /var/uWSGI/bareosUI/bareos_ui.pid /usr/local/bin/uwsgi-3.6 /ext/etc/uWSGI/bareos-webUI.ini"'

The problem here is the su -m, which does reset the umask:
Code:
# umask
22
# umask 027
# umask
27
# su -m uwsgi -c /usr/bin/umask
0022
As it seems, su does set the umask to it's default (which makes sense). But in case of -m, it does set it not to the default of the invoked user (which we could change appropriately in login.conf), but to the default of the current user. Which in this case is usually root, so what we finally get is the umask from /usr/src/etc/root/dot.cshrc:
Code:
# A righteous umask
umask 22
(And we do not want to change that.)

So, I fought with that one for a while, and I could not find any other approach than the 'piggish' one.
 

crees@

New Member
Developer

Reaction score: 3
Messages: 10

This would be the point in which you implement ${name}_umask in rc.subr and send a PR ;)
 

PMc

Aspiring Daemon

Reaction score: 193
Messages: 542

This would be the point in which you implement ${name}_umask in rc.subr and send a PR ;)
Yes, that might happen.
And I would do this more likely if I knew a way to have something actually done with such PR.

Whereby, this one is clearly a functional enhancement, and not a bugfix. With these I'm okay when I can handle them by some piggish scripting. With the actual bugs it's a more serious matter.

An example:
/etc/rc.d/kadmind
Code:
command_args="$command_args &"
I for my part think an ampersand is for use in interactive shell, and doesn't belongs into the system rc scripts.

But worse, I need two of these daemons running. (Don't ask me if that's a good idea; I'm just trying to find that out - and to find it out I must do it.) And so I wrote a new rc.d script, in the style of the jail script, to be able to start and stop an arbitrary number of instances individually. And I failed to get that working while using that ampersand scheme (the script would just block on boot).
OTOH, that process needs the ampersand, it cannot run under /usr/sbin/daemon :(

I do not expect anybody else to want to run two kadmind (and I'm quite sure nobody has ever tried).
But I consider it indeed a bug for a system background process to need "&" to start. And the fix, to make it run under daemon, is simply this one:
Code:
--- crypto/heimdal/kadmin/kadm_conn.c   (revision 351611)
+++ crypto/heimdal/kadmin/kadm_conn.c   (working copy)
@@ -189,8 +189,9 @@

     pgrp = getpid();

-    if(setpgid(0, pgrp) < 0)
-       err(1, "setpgid");
+    if(pgrp != getpgrp())
+       if(setpgid(0, pgrp) < 0)
+           err(1, "setpgid");

     signal(SIGTERM, terminate);
     signal(SIGINT, terminate);
I for my part think, the even better approach would be to change this within the setpgid() system call, so that it does not fail in such a case, and thereby have the problem solved once and for all. But that is not allowed by posix, and as soon as I started to talk about posix on the mailing-list, I got utterly beaten upon.

So, my conclusion is, it is quite troublesome and usually fruitless to try to get anything improve, because there seem to be claims, and people, defending their claims, and it is no fun at all to deal with such.
 
Top