Re: Should all services in rc.d support a status argument?

From: Dan Mahoney (Ports) <freebsd_at_gushi.org>
Date: Thu, 20 Feb 2025 02:11:52 UTC

> On Feb 19, 2025, at 17:53, Paul Procacci <pprocacci@gmail.com> wrote:
> 
> On Wed, Feb 19, 2025 at 6:00 PM Dan Mahoney (Ports) <freebsd@gushi.org> wrote:
>> 
>> Hey there all,
>> 
>> I’m in the process of implementing a nagios check at the dayjob that basically ensures that all “enabled” services are running.  (Arguably, the answer to a service that fell over is *not* always to just quietly restart it).
>> 
>> However, not all services support the “status” command.
>> 
>> For example, /usr/local/etc/rc.d/dma_flushq is just a hook to flush the queue on boot — it doesn’t start a process with a long-running pidfile, and since there is no pidfile listes, there’s no useful output to the “status” command, and in fact, this yields an error:
>> 
>> # service dma_flushq status
>> /usr/local/etc/rc.d/dma_flushq: unknown directive 'status'.
>> Usage: /usr/local/etc/rc.d/dma_flushq [fast|force|one|quiet](start|stop|restart|rcvar|enable|disable|delete|enabled|describe|extracommands)
>> # echo $?
>> 1
>> 
>> But if we take something like sshguard, then rc.subr is smart enough to look at the pidfile and figure out what I want, even though no special status command has been defined in /usr/local/etc/rc.d/sshguard:
>> 
>> # service sshguard status
>> sshguard is running as pid 814.
>> 
>> Now, I could go through each and every service in /usr/local/etc/rc.d, and parse the auto-generated “Usage:" to see what commands they offer…
>> 
>> # /usr/local/etc/rc.d/dma_flushq
>> Usage: /usr/local/etc/rc.d/dma_flushq [fast|force|one|quiet](start|stop|restart|rcvar|enable|disable|delete|enabled|describe|extracommands)
>> 
>> And use that to build a list of exceptions, but that’s annoying.
>> 
>> So here’s my fun question:  For scripts that don’t *have* a status defined, should rc.subr simply return 0 with a nicer message, because it’s not a statusable service?
>> 
>> The “practical rc.d scripting in FreeBSD” document mentions that “status” is a standard command, but is silent on this use-case.
>> 
>> -Dan
>> 
>> (Describe is also a valid command, but none of this stuff sets a description, even in the base OS.  I recall I took an action to make more of this stuff pass rclint).
> 
> dma_flushq isn't an actual service.  It certainly can be in
> /usr/local/etc/rc.d/ to be run upon boot, but a service it is not.

It's started by rc, and controlled with the "service" command.  We may be getting into semantics, but I think that makes it a service, just...not a daemon.

> As for “practical rc.d scripting in FreeBSD” document, any piece you
> think is missing can always be found in the man pages:
> 
> "
> If pidfile or procname is set, also support:
> 
>                 poll    Wait for the command to exit.
>                 status  Show the status of the process.
> "

Which manpage is that from?  It's not listed that way in man rc, nor in man service?

> 
> You clearly don't have a pidfile/long standing process/etc.  It's not a service.
> An exit of 1 is the appropriate exit value here.  `status` isn't valid
> in these instances.
> I'm not sure what you're trying to accomplish but targeted checks for
> each process you know to be services should be the answer to your
> problem.

Literally the first sentence in my email:

>> I’m in the process of implementing a nagios check at the dayjob that basically ensures that all “enabled” services are running. 

This includes services that don't have daemons that listen on a TCP port or domain socket, but that *do* write PID files, for which the desired check is an individual service nnn status (which can be run as non-root users).

I would enumerate those with "service -e", which shows all enabled services, including (as one example) dma_flushq.

The "service" command makes no distinction between which services are things that run once at boot, and which things start long-running daemons, and that's what I'm looking for.  I suppose another command that would be useful is something like "service foo haspid".

Short of grepping everything in /usr/local/etc/rc.d for "pidfile" there's no good way to get that list.

-Dan