Discussion:
rcorder question
(too old to reply)
Milan Obuch
2024-02-13 11:19:37 UTC
Permalink
Hi,

I am trying to solve an issue how to start local scripts in proper
order (for my application). Basically, I use net/socat port to create
virtual serial port used to read data from some device (just simple
character stream, with CR LF terminating the record with fixed position
items).

I configured socat instance in /etc/rc.conf:

socat_enable="YES"

and /usr/local/etc/socat-instances.conf:

[moxa]
daemonuser=root
flags="PTY,link=/dev/cuaV0,rawer,wait-slave TCP4:192.168.x.y:5000"

It works - on boot, designated device is contacted and virtual serial
port is created.

For starting program consuming data, I put following in /etc/rc.local:

/usr/local/xxx/yyy/zzz /dev/cuaV0 &

If started manually after boot up, it works as intended, but here is
the problem, it is started before socat, because

# rcorder /etc/rc.d/* /usr/local/etc/rc.d/* | grep local
/etc/rc.d/mountcritlocal
/usr/local/etc/rc.d/dbus
/etc/rc.d/local
/usr/local/etc/rc.d/socat

(some more entries edited out, not relevant to the issue).

So the question is how could I alter boot order to start /etc/rc.local
*after* socat instance. I tried, altering /etc/rc.d/local line (naively)

# REQUIRE: DAEMON

to

# REQUIRE: DAEMON socat

but this does not work, because then rcorder reports

rcorder: Circular dependency on file `/usr/local/etc/rc.d/socat'.
rcorder: Circular dependency on provision `LOGIN': /etc/rc.d/LOGIN -> /etc/rc.d/local -> /usr/local/etc/rc.d/socat -> /etc/rc.d/LOGIN.
rcorder: `/usr/local/etc/rc.d/socat' was seen in circular dependencies for 1 times.
rcorder: `/etc/rc.d/local' was seen in circular dependencies for 1 times.
rcorder: `/etc/rc.d/LOGIN' was seen in circular dependencies for 1 times.
rcorder: `/usr/local/etc/rc.d/socat' was seen in circular dependencies for 1 times.

I did some more, but no success yet... Anybody to offer some hint I can
try?

Regards,
Milan


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
David Chisnall
2024-02-13 11:27:44 UTC
Permalink
A quick look at teh socat RC script suggests that it contains this line:

# PROVIDE: socat

You should be able to simply add:

# REQUIRE: socat

And your service will start after socat. But to do that you need to not use `rc.local` and instead provide a separate RC script. There are some examples in the man page and the web site:

https://man.freebsd.org/cgi/man.cgi?query=rc

https://docs.freebsd.org/en/articles/rc-scripting/

In general, I wouldn’t use rc.local for anything that has dependencies outside of rc.local (or, in fact, for anything). If you have a service that needs to be started after something else, then put it in etc/rc.d and enable it via rc.conf (or, ideally, something in rc.conf.d). If you want to move it to a different machine, you now just need to copy the files across rather than extract bits of config files (this also makes it easier to create packages for it, if you wish to automate installation).

David
Post by Milan Obuch
Hi,
I am trying to solve an issue how to start local scripts in proper
order (for my application). Basically, I use net/socat port to create
virtual serial port used to read data from some device (just simple
character stream, with CR LF terminating the record with fixed position
items).
socat_enable="YES"
[moxa]
daemonuser=root
flags="PTY,link=/dev/cuaV0,rawer,wait-slave TCP4:192.168.x.y:5000"
It works - on boot, designated device is contacted and virtual serial
port is created.
/usr/local/xxx/yyy/zzz /dev/cuaV0 &
If started manually after boot up, it works as intended, but here is
the problem, it is started before socat, because
# rcorder /etc/rc.d/* /usr/local/etc/rc.d/* | grep local
/etc/rc.d/mountcritlocal
/usr/local/etc/rc.d/dbus
/etc/rc.d/local
/usr/local/etc/rc.d/socat
(some more entries edited out, not relevant to the issue).
So the question is how could I alter boot order to start /etc/rc.local
*after* socat instance. I tried, altering /etc/rc.d/local line (naively)
# REQUIRE: DAEMON
to
# REQUIRE: DAEMON socat
but this does not work, because then rcorder reports
rcorder: Circular dependency on file `/usr/local/etc/rc.d/socat'.
rcorder: Circular dependency on provision `LOGIN': /etc/rc.d/LOGIN -> /etc/rc.d/local -> /usr/local/etc/rc.d/socat -> /etc/rc.d/LOGIN.
rcorder: `/usr/local/etc/rc.d/socat' was seen in circular dependencies for 1 times.
rcorder: `/etc/rc.d/local' was seen in circular dependencies for 1 times.
rcorder: `/etc/rc.d/LOGIN' was seen in circular dependencies for 1 times.
rcorder: `/usr/local/etc/rc.d/socat' was seen in circular dependencies for 1 times.
I did some more, but no success yet... Anybody to offer some hint I can
try?
Regards,
Milan
Milan Obuch
2024-02-14 21:54:33 UTC
Permalink
On Tue, 13 Feb 2024 11:27:44 +0000
Post by David Chisnall
# PROVIDE: socat
# REQUIRE: socat
And your service will start after socat. But to do that you need to
not use `rc.local` and instead provide a separate RC script. There
https://man.freebsd.org/cgi/man.cgi?query=rc
https://docs.freebsd.org/en/articles/rc-scripting/
In general, I wouldn’t use rc.local for anything that has
dependencies outside of rc.local (or, in fact, for anything). If you
have a service that needs to be started after something else, then
put it in etc/rc.d and enable it via rc.conf (or, ideally, something
in rc.conf.d). If you want to move it to a different machine, you
now just need to copy the files across rather than extract bits of
config files (this also makes it easier to create packages for it, if
you wish to automate installation).
David
Thanks for pointer, I created simple script and it looks like it works
as expected:

--- 8< ---------------------------------

#!/bin/sh

# PROVIDE: scex
# REQUIRE: socat

/etc/rc.subr

name=scex
rcvar=scex_enable

start_cmd="${name}_start"
stop_cmd=":"

load_rc_config $name
: ${scex_enable:=no}

scex_start()
{
/usr/local/bin/init_program
/usr/local/bin/main_program /dev/cuaV0 &
}

run_rc_command "$1"

--- 8< ---------------------------------

For it to run, I added to /etc/rc.conf:

scex_enable="YES"

There is no stop instruction, but it is just enough for my purpose at
the moment. Is there anything which would be recommended to change?

Regards,
Milan


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Juraj Lutter
2024-02-14 22:03:19 UTC
Permalink
Hi,
Post by Milan Obuch
scex_start()
{
/usr/local/bin/init_program
/usr/local/bin/main_program /dev/cuaV0 &
I would consider wrapping by /usr/sbin/daemon instead of putting it into background this way.

otis



Juraj Lutter
***@FreeBSD.org



--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
David Chisnall
2024-02-15 07:45:03 UTC
Permalink
Post by Juraj Lutter
I would consider wrapping by /usr/sbin/daemon instead of putting it into background this way.
In particular, that makes it trivial to write the stop command. This may be overkill, but I find it’s actually *more* useful when debugging my own things than for production services.

David



--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Loading...