View previous topic :: View next topic |
Author |
Message |
ChadJoan n00b
Joined: 17 Oct 2010 Posts: 38
|
Posted: Thu Mar 07, 2024 9:35 pm Post subject: Start/stop OpenRC services based on Internet availability? |
|
|
On a system using OpenRC (not systemd) and NetworkManager (not dhcpcd, dhclient, netifrc, or others), how do I get services (e.g. /etc/init.d) to start and stop whenever networking+DNS+internet is available on any networking interface?
I ran into this problem because my /etc/init.d/ntp-client service is trying to start too early at boot and creating the following error in /var/log/rc.log:
Code: |
* Setting clock via the NTP client 'ntpdate' ...
Exiting, name server cannot be used: Temporary failure in name resolution (-3) * Failed to set clock
[ !! ]
* ERROR: ntp-client failed to start
|
Following that, I experience various kinds of mischief whenever the system ends up with the wrong time set on its clock (ex: browser can't visit websites because SSL/TLS won't work without correctly synchronized clock). As a workaround, I run /etc/init.d/ntp-client start by hand everytime I boot the system. But oof, there must be a better way!
I already tried the net-misc/chrony package mentioned in this thread.
It did not work. (And I'm not sure why it would? It didn't have any logic, that I could see, for delaying ntp-client until network+DNS is available.)
My /etc/conf.d/ntp-client file has rc_use="dns" set in it. But this does not help.
Now I want to point out that this is not just an ntp-client problem.
I have experienced a generalization of this problem when trying to make my system automatically make an SSH connection to another machine. That was intended to open a reverse-tunnel that I can use to access my laptop-or-whatever from any network that doesn't block outbound SSH connections. (I used custom /etc/init.d script to do this, but it never worked right, because...)
That endeavor met the Same Problem: I had no way to start the service once networking became available (DNS or not), or stop it gracefully when network access disappears.
And beyond NTP and SSH tunnels, I can imagine how this might cause problems for other services I might want to run. I start to wonder how many things on my system only work because they just "happened to" come up late enough, or maybe aren't working at all because they failed the same way but were silent about their failure (and thus lead to diffuse, hard-to-troubleshoot, problems/symptoms in other programs/apps/etc).
I tried looking for ways to introduce networking as a dependency in initscripts.
This Flameeyes' blog post from 2012 suggested that this was still an Open Problem at that time.
rc_hotplug in /etc/rc.conf looks promising, but nothing I've read explains what it really does: Will services dependent on the named service be started/restarted, or just the service itself? How does it know when some hardware has been plugged/unplugged? Is it just looking at the existence of device nodes? If so, how do I specify which ones? And even if so, maybe this still isn't the right way to do this thing, because it doesn't work with any software that checks for internet connectivity based on successful pings/requests/etc? Or does it actually do deep connectivity checks for network connections, and if so, how does it distinguish that case from other, non-networking, hardware-availability issues? (If rc_hotplug isn't the answer, then I don't really expect all those questions answered. These are all rhetorical: I just can't find such information anywhere. And it doesn't seem worth it to run experiments, because I doubt it's actually checking for internet connectivity.)
I noticed the /etc/init.d/net-online service. That looks potentially helpful. But I'm not sure how to make other services depend on it (edit "rc_" values in rc.conf? edit depend() in /etc/init.d/<scriptname>?), or ensure that it starts+stops services outside of runlevel execution (or maybe I misunderstand how initscripts are processed, and it's more dynamic than I expect). I still don't understand what rc_need, rc_use, rc_after, rc_before, rc_depend_strict, or any others do, or why I'd want to use one over the other. (And does the existence of rc_depend_strict imply the existence of rc_depend?) I can find documents that mention these things (example), but I can't find a list of definitions for them.
So now I really want to know: what is the proper mechanism is for solving the start-and-stop-services-based-on-internet-availability problem?
My internet searches are coming up empty-handed. |
|
Back to top |
|
|
alamahant Advocate
Joined: 23 Mar 2019 Posts: 3916
|
Posted: Fri Mar 08, 2024 11:10 am Post subject: |
|
|
Quote: |
I ran into this problem because my /etc/init.d/ntp-client service is trying to start too early at boot and creating the following error in /var/log/rc.log:
|
Plz enable it @default NOT @boot runlevel.
You may add rc hooks like
Code: |
# You can also enable the above commands here for each service. Below is an
# example for service foo.
#rc_foo_config="/etc/foo"
#rc_foo_need="openvpn"
#rc_foo_after="clock"
|
in /etc/rc.conf
or in
/etc/conf.d/<service> _________________
|
|
Back to top |
|
|
ChadJoan n00b
Joined: 17 Oct 2010 Posts: 38
|
Posted: Fri Mar 08, 2024 4:39 pm Post subject: |
|
|
Quote: | Plz enable it @default NOT @boot runlevel. |
I'm afraid it won't be that easy. It's already in @default:
Code: |
cdj-desktop /etc # rc-status
Runlevel: default
syslog-ng [ started ]
iwd [ started ]
NetworkManager [ started ]
ntp-client ................. [ started ] <----
cronie [ started ]
sshd [ started ]
netmount [ started ]
cupsd [ started ]
firewalld [ started ]
sensord [ started ]
local [ started ]
Dynamic Runlevel: hotplugged
Dynamic Runlevel: needed/wanted
display-manager-setup [ started ]
dbus [ started ]
avahi-daemon [ started ]
display-manager [ started ]
Dynamic Runlevel: manual
cdj-desktop /etc # rc-update show
NetworkManager | default
binfmt | boot
bootmisc | boot
cgroups | sysinit
cronie | default
cupsd | default
devfs | sysinit
dmesg | sysinit
elogind | boot
firewalld | default
fsck | boot
hostname | boot
hwclock | boot
iwd | default
keymaps | boot
killprocs | shutdown
kmod-static-nodes | sysinit
local | default nonetwork
localmount | boot
loopback | boot
modules | boot
mount-ro | shutdown
mtab | boot
netmount | default
ntp-client | default <---------------
procfs | boot
root | boot
save-keymaps | boot
save-termencoding | boot
savecache | shutdown
seedrng | boot
sensord | default
sshd | default
swap | boot
sysctl | boot
sysfs | sysinit
syslog-ng | default
systemd-tmpfiles-setup | boot
systemd-tmpfiles-setup-dev | sysinit
termencoding | boot
udev | sysinit
udev-trigger | sysinit
cdj-desktop /etc #
|
No runlevel is good enough (including @default) because none of them guarantee internet availability, or even correlate with network status (e.g. the default runlevel doesn't stop() when network interfaces become unavailable, nevermind internet connectivity; and it shouldn't ).
Quote: | You may add rc hooks like ... |
That does look promising, but I'm still stuck because I can't find the right documentation for it:
What are all of the possible options, exhaustively? What do they do? Why would I use one over the other?
Then once I've figured out rc hooks, what service do I use as a dependency? net-online would be my first guess, but I'd like to know what the best option is, if anyone knows.
Then it's back to rc hook syntax: How do I name the service in the rc_something="<service>" line? Is it the name of the file in /etc/init.d? Or is it the string that shows up in the provide <name> line in the depend() block of the service's init.d file? Or something else?
Then the biggie: how do I know which services to add rc_hooks for? I just got blindsided and I'd like to root-cause this thing.
Thank you for the help! |
|
Back to top |
|
|
flexibeast Guru
Joined: 04 Apr 2022 Posts: 449 Location: Naarm/Melbourne, Australia
|
Posted: Fri Mar 15, 2024 3:10 am Post subject: |
|
|
Does the openrc-run(8) man page, and in particular the DEPENDENCIES section, go some way to providing the sort of information you're after? |
|
Back to top |
|
|
ChadJoan n00b
Joined: 17 Oct 2010 Posts: 38
|
Posted: Sat Mar 16, 2024 7:14 pm Post subject: |
|
|
Quote: |
Does the openrc-run(8 ) man page, and in particular the DEPENDENCIES section, go some way to providing the sort of information you're after?
|
So far, that is quite helpful! I have made progress.
Thank you, flexibeast.
Unfortunately, after some experimentation, I get the feeling that there are still things about it that I do not understand
Right now, I have worked around the problem by adding this line to /etc/rc.conf:
Code: |
# We need DNS+Internet for talking to the NTP server.
rc_ntp_client_need="NetworkManager"
|
That gets ntp-client to come up at the correct time.
I also added this (also in /etc/rc.conf) in an attempt to make ntp-client stop when the network goes down (or NetworkManager is stopped with rc-service NetworkManager stop), and have it start again (rc-service NetworkManager start) whenever the network comes back up:
Code: |
rc_ntp_client_after="NetworkManager"
|
This approach also has the promise of delegating the "internet availability detection" responsibility to the NetworkManager service. NetworkManager seems to have reliable logic for this (notable reading), and its rc service will have an "inactive" status when there is no connectivity. By causality that still isn't clear to me, this also seems to include DNS functionality. Fun fact: /etc/NetworkManager/dispatcher.d/10-openrc-status has some special logic in it that helps the NetworkManager service reflect network availability.
However, it doesn't work.
Right now, stopping NetworkManager will also stop the ntp-client service, but starting NetworkManager will not bring ntp-client back up. ntp-client's behavior is mirrored by the netmount service.
I am also very confused by the dns service. Numerous services seem to depend on it, but none seem to provide it:
Code: |
cdj-desktop /etc # grep -RPin "\bdns\b" /etc/init.d
/etc/init.d/wg-quick:10: use dns
/etc/init.d/bacula-fd:12: use dns
/etc/init.d/openvpn:16: use dns
/etc/init.d/openvpn:78: # which configures our DNS if any and marks us as up.
/etc/init.d/openvpn:96: # Warn about the inability to change ip/route/dns information when
/etc/init.d/openvpn:101: ewarn "or DNS configuration."
/etc/init.d/mdadm:6: use logger dns net
/etc/init.d/apache2:36: use dns entropy logger mysql netmount postgresql
/etc/init.d/bacula-dir:15: use dns bacula-fd bacula-sd
/etc/init.d/sshd:27: use logger dns entropy
/etc/init.d/ntpd:13: use net dns logger
/etc/init.d/netmount:27: use dns
/etc/init.d/apcupsd:19: use dns
/etc/init.d/rdate:8: use dns
/etc/init.d/nfs:28: use ypbind net dns rpc.rquotad rpc.idmapd rpc.svcgssd
/etc/init.d/nfsclient:18: use ypbind dns
/etc/init.d/sntp:10: use dns logger
/etc/init.d/iwd:12: before dns dhcpcd net
/etc/init.d/ntp-client:8: use dns logger
/etc/init.d/dhcpd:14: use logger dns
/etc/init.d/ddclient:15: use dns logger
/etc/init.d/glusterfsd:25: use dns
/etc/init.d/bacula-sd:12: use dns
|
At an earlier point in my investigation, my workaround involved creating the dns service in a file /etc/init.d/dns with these contents:
Code: |
name="dns"
description="Stub for dependency management of DNS on NetworkManager system."
depend() {
need NetworkManager
after NetworkManager
}
start() {
return 0
}
stop() {
return 0
}
|
... and then having ntp-client "need" the dns service via rc_ntp_client_need in /etc/rc.conf. (Oddly enough, the "use dns ..." in /etc/init.d/ntp-client is not sufficient, even with the above dns added to the default runlevel, and adding "after dns" isn't sufficient either, so it has to be "needed" specifically!) But I don't necessarily recommend doing this, because I have no idea how the dns is actually supposed to be defined (maybe I am missing a package, or misconfigured something else, or I-don't-know-what).
My understanding of how openrc manages dependencies is definitely incomplete!
So I feel like we're getting closer (I have a workaround that accomplishes SOME of the desired outcome), but not quite to SOLVED yet, because I can't make things come up/down in sync with the network. |
|
Back to top |
|
|
grknight Retired Dev
Joined: 20 Feb 2015 Posts: 1918
|
Posted: Sat Mar 16, 2024 8:45 pm Post subject: |
|
|
ChadJoan wrote: | I am also very confused by the dns service. Numerous services seem to depend on it, but none seem to provide it:
Code: |
cdj-desktop /etc # grep -RPin "\bdns\b" /etc/init.d
/etc/init.d/wg-quick:10: use dns
/etc/init.d/bacula-fd:12: use dns
/etc/init.d/openvpn:16: use dns
/etc/init.d/openvpn:78: # which configures our DNS if any and marks us as up.
/etc/init.d/openvpn:96: # Warn about the inability to change ip/route/dns information when
/etc/init.d/openvpn:101: ewarn "or DNS configuration."
/etc/init.d/mdadm:6: use logger dns net
/etc/init.d/apache2:36: use dns entropy logger mysql netmount postgresql
/etc/init.d/bacula-dir:15: use dns bacula-fd bacula-sd
/etc/init.d/sshd:27: use logger dns entropy
/etc/init.d/ntpd:13: use net dns logger
/etc/init.d/netmount:27: use dns
/etc/init.d/apcupsd:19: use dns
/etc/init.d/rdate:8: use dns
/etc/init.d/nfs:28: use ypbind net dns rpc.rquotad rpc.idmapd rpc.svcgssd
/etc/init.d/nfsclient:18: use ypbind dns
/etc/init.d/sntp:10: use dns logger
/etc/init.d/iwd:12: before dns dhcpcd net
/etc/init.d/ntp-client:8: use dns logger
/etc/init.d/dhcpd:14: use logger dns
/etc/init.d/ddclient:15: use dns logger
/etc/init.d/glusterfsd:25: use dns
/etc/init.d/bacula-sd:12: use dns
|
|
"use dns" means "If there is a service added in a runlevel that is either named dns or 'provide dns', start that first. If it doesn't exist or not added, don't consider it" Scripts like dnsmasq, named or unbound "provide dns" |
|
Back to top |
|
|
ChadJoan n00b
Joined: 17 Oct 2010 Posts: 38
|
Posted: Mon Mar 18, 2024 5:55 am Post subject: |
|
|
Quote: |
"use dns" means "If there is a service added in a runlevel that is either named dns or 'provide dns', start that first. If it doesn't exist or not added, don't consider it"
|
Great! This is what I expected, and I'm glad you clarified how the names work. Thanks!
Quote: |
Scripts like dnsmasq, named or unbound "provide dns"
|
Cool; thanks for the examples!
...
I think the thing boggling me about it is that I'm on a system with perfectly working DNS, and no service that "provide(s) dns" or any named that (until I added a stub by hand).
Is there some way I'm supposed to get the NetworkManager package to provide the dns RC initscript? (And without installing+integrating dnsmasq, because I don't need it: my DNS already works fine.)
Though now I'm noticing that dnsmasq, named, and unbound are all DNS servers. So now I am wondering about this: could the dns service be intended to correlate with a DNS server instead of a DNS client? If it's for a server, then I am possibly worrying about nothing, as I don't need a server. I just want to make sure other services know that DNS lookup functionality is available.
Strongly related question: is the net service supposed to include DNS functionality? (I could see this easily being the case if the dns service is about DNS servers, rather than clients. Or it could be redundant.)
I had expected that the net service just guarantees that there is a network interface UP, but not that there is any DNS availability or actual connectivity (ex: eth0 might be UP, but it's plugged into a connectionless router). That would be in line with my earlier-in-life experiences with Netifrc, where I would ln -s /etc/init.d/net.lo /etc/init.d/net.<interface_name> (as described in the wiki). But now I am questioning that assumption/expectation, and maybe I don't really understand just what the net service is supposed to be (or do). |
|
Back to top |
|
|
grknight Retired Dev
Joined: 20 Feb 2015 Posts: 1918
|
Posted: Mon Mar 18, 2024 12:34 pm Post subject: |
|
|
Yes, "use dns" is to ensure any DNS server, often used for local caching, starts before other services that may utilize it.
If you want to guarantee network availability before a service starts, then look into the net-online service (after configuring it in conf.d) and have services depend on that (using "need" or "want" statements, see man openrc-run for the difference) in either rc.conf or their respective conf.d files.
Note that OpenRC is not continuously aware of network status on its own. Only when invoked can it check state of any service, otherwise it is stateless. |
|
Back to top |
|
|
pa4wdh l33t
Joined: 16 Dec 2005 Posts: 882
|
Posted: Mon Mar 18, 2024 6:34 pm Post subject: |
|
|
ChadJoan wrote: |
So now I really want to know: what is the proper mechanism is for solving the start-and-stop-services-based-on-internet-availability problem?
|
I don't think there is a ready made solution.
One thing that comes to mind is this:
Use the default runlevel to only start items that don't need network/internet connectivity. Create a new runlevel (named "online" for example) and place all services that require internet connectivity there.
Now, create a script that checks network/internet connectivity that simply changes runlevel based on the result of this check. This also allows you to define what "internet available" means to you. Is it good enough to be able to ping something? Do you want to check if DNS resolution works? Anything else?
An other option:
I know you mentioned you use network manager and not one of the dhcp daemons. Be aware that at least dhcpcd can run hooks(scripts) on different events dhcp related events which might help with your use case. _________________ The gentoo way of bringing peace to the world:
USE="-war" emerge --newuse @world
My shared code repository: https://code.pa4wdh.nl.eu.org
Music, Free as in Freedom: https://www.jamendo.com |
|
Back to top |
|
|
szatox Advocate
Joined: 27 Aug 2013 Posts: 3430
|
Posted: Mon Mar 18, 2024 7:36 pm Post subject: |
|
|
Quote: | [..]I noticed the /etc/init.d/net-online service. That looks potentially helpful. But I'm not sure how to make other services depend on it (edit "rc_" values in rc.conf? edit depend() in /etc/init.d/<scriptname>?), or ensure that it starts+stops services outside of runlevel execution (or maybe I misunderstand how initscripts are processed, and it's more dynamic than I expect). I still don't understand what rc_need, rc_use, rc_after, rc_before, rc_depend_strict[...] |
If you put this in /etc/conf.d/<service> Code: |
depend () {
need net-online
# or maybe should it be called for a specific interface instead:
need net-online.eth0
}
|
it should result in your service waiting for net-online to come up, and also your service should be stopped when you take net down.
"use net-online" should result in your service waiting for net-online but not stopping when net goes down.
Now, i haven't checked what exactly does net-online do, but it belongs to openrc and _not_ netifrc, so there is a chance it will work with other tools too.
Finally, one last tip from me, if you run any network servers on your machine, it's a good idea to create a virtual interface with an IP address instead of assigning that IP to a physical interface. I've been using a bridge I'd enslave NIC with, but it could also be a dummy - possibly behind DNAT.
The point is to disconnect service's IP address from the physical link, which allows you to reconfigure network without restarting your servers. This enables your server to start as soon as that virtual interface is up and has an IP address assigned, even before the whole machine comes online. Of course the service still won't be not be accessible until network gets ready, but at least it won't corrupt server's state (like sockets not binding on startup). _________________ Make Computing Fun Again |
|
Back to top |
|
|
grknight Retired Dev
Joined: 20 Feb 2015 Posts: 1918
|
Posted: Mon Mar 18, 2024 7:39 pm Post subject: |
|
|
szatox wrote: | If you put this in /etc/conf.d/<service> Code: |
depend () {
need net-online
# or maybe should it be called for a specific interface instead:
need net-online.eth0
}
|
| This is better expressed as rc_need="net-online" (or similar) in a conf.d file. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|