
rc.d belongs in libexec, not etc - Khaine
https://jmmv.dev/2020/08/rcd-libexec-etc.html
======
waheoo
> August 24, 2020

Unexpected to say the least.

Good read though, mostly agree.

> My main gripe is that the files under /etc/rc.d/ are immutable scripts.

Are they though? A lot of, well at least old software, lacked configuration
files, their command line flags and unit scripts were for all intensive
purposes, their config files.

Whether this actually makes upgrade harder (the next point made), is kind of
debatable no?

Arch does fine with pacsave and pacnew files.

Making changes or tracking changes to these files is going to be required
regardless from a systems upgrade point of view - because people want control
over their system units.

And for what its worth, I'd rather find out about a breaking update via
pacsave/new than figure it out months later when my copied but now outdated
and untracked unit starts failing.

~~~
krastanov
Just a minor grammar point that does not detract from your argument: It is
"for all intents and purposes", not "intensive purposes"
[https://www.dictionary.com/e/for-all-intents-and-purposes-
vs...](https://www.dictionary.com/e/for-all-intents-and-purposes-vs-for-all-
intensive-purposes/)

~~~
adzm
These kinds of substitutions are called eggcorns (like acorns)
[https://en.wikipedia.org/wiki/Eggcorn](https://en.wikipedia.org/wiki/Eggcorn)

~~~
Zamicol
My household has started calling them "Bone Apple Teas".

[https://old.reddit.com/r/BoneAppleTea/](https://old.reddit.com/r/BoneAppleTea/)

My favorite being a friend called a cul-de-sac a "culture sack". Years later
we still laugh about this one.

~~~
jacobush
It’s also true

------
mst
I'd note that Tru64 unix kept its rc.d in /sbin instead of /etc.

I'd also note that the first time I had to debug a Tru64 networking problem it
took me _quite_ some time to find the bloody things.

I mean, once I did my first thought was "honestly if anything that makes more
sense than /etc would".

But argh.

Then in the end it turned out the network configuration had been fine all
along and one of the developers had stolen the switch port it was using for
something else.

(being a sysadmin at a software house tends to involve the developers getting
to do wtf they want since their work is revenue critical and yours isn't
perceived to be so much, though I still mostly enjoyed the job because my
director was understanding and let me yell at developers for doing stupid shit
so long as he didn't get _too_ many complaints ;)

~~~
segfaultbuserr
I'm never a fan of mixing runscripts that come with the package and runscripts
written by the user. If rc.d is a libexec, it enables the perfect solution -
/usr/local. It even allows one to potentially override a runscript in the most
natural way, too bad it never gained the traction.

~~~
mst
You _can_ actually have a /usr/local/sbin directory too, you know.

------
geofft
I'm a little confused why the author is getting merge conflicts in /etc/rc.d
one paragraph after asserting that these files don't need to be edited by the
local system administrator.

Plenty of files that properly belong in /etc get edited _rarely_ by the local
sysadmin, perhaps more rarely than rc.d. (When was the last time you edited
/etc/pam.d/ or /etc/gai.conf or /etc/protocols?) Yet they _can_ be edited, and
so they properly belong in /etc. If the local sysadmin doesn't actually touch
them, an upgrade procedure should just upgrade them without prompting. (I
assume the BSDs are clever enough for this.)

So, if you're getting prompted, it's not just because there's a change to
review, it's because there's a _merge_ to review, and therefore it's because
there was a local modification, and therefore clearly either you or some other
sysadmin did in fact edit that file. It is of course worth making it no longer
necessary to edit it, such as by moving configuration to /etc/rc.conf for
/etc/default/ or a service-specific /etc/foobard.conf, but that change needs
to actually happen before you can call the rc script immutable, and once you
do make that change, you no longer care if the rc script moves to libexec
because you're no longer getting merge prompts.

~~~
roelschroeven
> So, if you're getting prompted, it's not just because there's a change to
> review, it's because there's a merge to review, and therefore it's because
> there was a local modification, and therefore clearly either you or some
> other sysadmin did in fact edit that file.

That's the way it should be, but while upgrading Debian I have very often seen
prompts for files that were never touched locally.

~~~
geofft
You may have seen them for files that were automatically edited in some
fashion (e.g., by another package's install script). IMO needing to do that is
a low-grade bug.

------
agarzenm
From the article.

>My main gripe is that the files under /etc/rc.d/ are immutable scripts.

If the files/config (I know the author argues they aren't config files) are
truely immutable why would the system upgrade command modify them? and how
would it as if they are immutable in the same way that running chattr +i
somefile on Linux will make a file immutable even to root then I don't
understand how the upgrade command is modifying them.

Systemd-d is growing on me, partly because it is being forced upon us but also
because once you get over the initial carpet pull from beneath you, you don't
need to be exposed to the extra bullshit it brings.

If you want to experience pain with System-d, install a fresh copy of Ubuntu
and try to setup /etc/resolv.conf, for an extra challenge try setup
/etc/resolv.conf using unbound as a stub resolver.

I was amazed at how much effort I had to spend fighting the OS to just say
"Stop managing this file, do not load this file, I am going to manage it"

I spend most of my time with Linux systems so I admire the simplicity of the
System V approach. It is interesting to see other people discuss this from a
BSD perspective as I have very little exposure to BSD like systems.

BSD seems great, I love reading the security.html page of the OpenBSD project,
it has so many great ideas + implementations.

[https://www.openbsd.org/security.html](https://www.openbsd.org/security.html)

~~~
segfaultbuserr
> _If the files /config (I know the author argues they aren't config files)
> are truely immutable why would the system upgrade command modify them?_

You are confusing the two different scenarios that you need to distinguish.

The first scenario is when a config file is simply a part of a package,
managed by the package manager. In any reasonable package manager, if you ever
edited a config file manually under /etc, the package manager will never
attempt to update it automatically. For example, apt-get will ask you whether
you need to preserve the old file, use the new file, or diff-and-edit it
manually. This is the reason why the author suggests to move rc.d from /etc to
/libexec, because every time you upgrade your system, the package manager will
ask you to diff-and-update some random runscripts that you've never written.

The author's point here is that the rc files do not behave like config files,
they are closer to programs or executables, the package manager should be able
to update them when a new version in installed without annoying the user, just
like any other binaries.

\---

The second scenario is when a config file is managed by the init system, a
script, or a daemon in the system. For example, /boot/grub.cfg is managed by
update-grub & os-prober, and ideally one should never edit the file manually.

In this scenario, it's completely off-topic and irrelevant to the original
topic of whether rc.d should be treated as libexec, but here's my opinion
anyway...

> _I was amazed at how much effort I had to spend fighting the OS to just say
> "Stop managing this file, do not load this file, I am going to manage it"_

Never attempt to fight with the system in a brute force manner - edit this
file, later the file is edited back, edit again, edit back, and finally
"chattr +i" the file, I never understand this mentality. Using "chattr +i" is
almost never the correct solution.

All you need to do is politely tell your intention to the daemon in charge,
spending 30 minutes (or each time after a system upgrade) to fight with it,
can easily save your 5 minutes to read the documentation.

> _for an extra challenge try setup /etc/resolv.conf using unbound as a stub
> resolver._

If you read the documentation, you'll sometimes find your needs are already
supported, and managing it manually is not needed in the first place. For
example, NetworkManager already comes with builtin, automatic support of a
stub resolver. Not only that, it supports both dnsmasq and unbound, and even
has extra logic to help you updating the DNS when you're connected to a VPN.
All of these features are here to make one's work easier.

Yet one still chooses to fight with the system in the most brute force way
such as "chattr +i", at the very least you can turn it off smoothly and it'll
never bother you again.

For example,

$ man NetworkManager.conf

> dns

> Set the DNS processing mode.

> default: NetworkManager will update /etc/resolv.conf to reflect the
> nameservers provided by currently active connections.

> dnsmasq: NetworkManager will run dnsmasq as a local caching nameserver,
> using "Conditional Forwarding" if you are connected to a VPN, and then
> update resolv.conf to point to the local nameserver. It is possible to pass
> custom options to the dnsmasq instance by adding them to files in the
> "/etc/NetworkManager/dnsmasq.d/" directory. Note that when multiple upstream
> servers are available, dnsmasq will initially contact them in parallel and
> then use the fastest to respond, probing again other servers after some
> time. This behavior can be modified passing the 'all-servers' or 'strict-
> order' options to dnsmasq (see the manual page for more details).

> systemd-resolved: NetworkManager will push the DNS configuration to systemd-
> resolved

> unbound: NetworkManager will talk to unbound and dnssec-triggerd, using
> "Conditional Forwarding" with DNSSEC support. /etc/resolv.conf will be
> managed by dnssec-trigger daemon.

> none: NetworkManager will not modify resolv.conf. This implies rc-manager
> unmanaged.

$ man systemd-networked

> by one of the .network files will be ignored. It is also possible to

> explicitly tell systemd-networkd to ignore a link by using

> Unmanaged=yes option, see systemd.network(5).

I guess one reason that everyone's fighting with the system is not realizing
the official way of telling one's intention to the system. Perhaps everyone
should learn the way GRUB warns its user.

    
    
        #
        # DO NOT EDIT THIS FILE
        #
        # It is automatically generated by grub2-mkconfig using templates
        # from /etc/grub.d and settings from /etc/default/grub
        #
    

Perhaps someone should contribute a patch to NetworkManager to add a similar
warning.

    
    
        # DO NOT EDIT THIS FILE. This file is currently under the management
        # of NetworkManager. It's automatically generated according to the
        # DNS configuration of the current network connection in NetworkManager.
        # Any change to this file will be overwritten. 
        #
        # If you are trying to change your DNS resolver per connection, use "nmtui", "nmcli", 
        # or alternatively, edit "/etc/NetworkManager/system-connections/".
        #
        # To stop NetworkManager from managing it altogether, edit 
        # /etc/NetworkManager.conf, set the following and
        # restart NetworkManager, before you edit /etc/resolve.conf.
        #
        # [main]
        # dns=none
        #
        # If you are trying to set up a stub DNS resolver, it's recommended to
        # NetworkManager's builtin support. Set "dns=dnsmasq" or "dns=unbound"
        #
        # See "man 5 NetworkManager.conf" for more details.

~~~
yellowapple
> Perhaps someone should contribute a patch to NetworkManager to add a similar
> warning

Worth noting that NetworkManager does indeed add a shorter and milder version
of such a warning (at least on my machine):

    
    
        # Generated by NetworkManager
        search blah.blah.blah
        nameserver x.x.x.x
        nameserver y.y.y.y
        nameserver z.z.z.z

------
xorcist
The answer is maybe to auto merge what has not changed locally? To me, changes
to the boot process is just as interesting as changes to the default shell
settings.

The distinction between configuration and code isn't what's important here.
The purpose of these files are to describe a system wide default state. It is
not to mark them as devoid of programmable logic.

The latter doesn't even make sense if you look at what else is there.
/etc/profile for example is _clearly_ code.

~~~
gbrown_
> The answer is maybe to auto merge what has not changed locally?

Yup sysmerge(8) does this on OpenBSD. Not sure if other BSDs have similar
mechanisms, from the article I would guess not.

------
ggm
/etc is a name. If you start at BSD /etc was baked in from Version 7.

What Bell would have done in /etc is not what BSD did.

~~~
lanstin
IIRC plan9 has some crazy thing like this. I have gotten used to libexec but
part of me groans at the desire to make things ideal. We going to rename creat
next?

~~~
ggm
I heard dennis play the creat(e) joke at a UUG meeting.. It always went down
well

------
yellowapple
The entire premise of this article seems to be that code and configuration are
somehow mutually exclusive, despite decades' worth of examples to the contrary
(including init/RC scripts). Just because this configuration is typically
managed and "owned" by a package manager doesn't mean it's somehow not
configuration (nor is this even universally true; see also: Slackware, which
uses the same sort of setup but _does_ treat the contents of /etc/rc.d/ as
user-editable config files).

------
guerrilla
One of the few things that I actually like about systemd configuration is how
they split it up in a clear way. I can't recally where it was documented but
they make the distinction between site (lib), system (etc), user (home) and
runtime (run). I don't recall them making a distinction between executable or
not, but since it doesn't for the most part use rc scripts, that shouldn't
matter quite as much in the general case. If it we wanted that, it'd be nice
to nest it on top of current tree.

------
enriquto
> because they are code, not configuration.

This distinction is nonsensical. They are files that you can change to suit
your needs. I often comment a few lines on them. Code is a particular case of
data.

~~~
kchoudhu
But the distinction is useful because it paves the way for something everyone
wants, which is seamless upgrades without user intervention. The fewer places
the user touches something, the fewer decision points the upgrade process has
to deal with.

~~~
magicalhippo
Indeed. I was thinking about this just yesterday, when I upgraded my KDE Neon
install. I was asked about keeping or merging a conf file I was unsure what
was for, and that I can't recall having edited.

It's possible I did modify the conf file, in a late-night attempt to fix some
issue long ago, but that was all forgotten by now.

The changes to the conf file were extensive, and I had no idea what were _my_
changes, assuming I had indeed done any changes, vs what was just changes due
to the new version.

Why couldn't my change in etc just be a one-liner? Then the OS could upgrade
the base conf file safely, and simply inform me that I need to review my conf
override in etc to see if it was still valid or needed.

This way the upgrade tool could potentially be even smarter as it can clearly
distinguish what has been changed, so it can warn even more loudly when a
configuration variable has been removed or drastically changed for example.

------
DNied
So then you must keep 'libexec' on the root partition (if your system is
partitioned). Whereas '/etc' is on the root partition for sure.

~~~
jmmv
/libexec is already on the root partition, at least on NetBSD, and that's why
I wrote the paths that way in the article.

And that's why I also mentioned en passing that sourcing local files from a
potential /usr/pkg/libexec/rc.d/ directory would be problematic.

In fact, even today, making rc.d files automatically work from installed
packages is a problem precisely because of this: those files currently end up
in /usr/pkg/etc/rc.d/, and /etc/rc cannot use them by default because
/usr/pkg/ might be in a different partition. There have been endless and
repeated discussions about this issue on the NetBSD mailing lists.

~~~
DNied
Hence my usage of the word "keep". You can't move /libexec elsewhere.

------
zeptonix
Nonsense. /etc is for important system stuff. libexec is BSD specific and btw
not everything is BSD.

~~~
geofft
libexec exists on Red Hat lineage OSes too, and it's standardized in LSB. (I
think I'd basically say that it's Debian lineage that _doesn 't_ have it; the
default of e.g. anything that follows GNU's 'make install' standards is to use
it unless instructed not to.)

LSB is worth reading, because it had a precise definition of /etc that is not
"important system stuff."

~~~
teddyh
Debian also has libexec. I can see 80 packages¹ in Debian which has files in
either /usr/libexec or /usr/$ARCH/libexec. The Debian Policy² does not mention
libexec, but does refer to the FHS, which _does_ allow libexec³.

1\. Here is the list:

    
    
      https://tracker.debian.org/pkg/apper
      https://tracker.debian.org/pkg/arctica-greeter
      https://tracker.debian.org/pkg/arctica-greeter-guest-session
      https://tracker.debian.org/pkg/at-spi2-core
      https://tracker.debian.org/pkg/bacula-common
      https://tracker.debian.org/pkg/dillo
      https://tracker.debian.org/pkg/drkonqi
      https://tracker.debian.org/pkg/eximon4
      https://tracker.debian.org/pkg/fgetty
      https://tracker.debian.org/pkg/flatpak
      https://tracker.debian.org/pkg/flatpak-builder-tests
      https://tracker.debian.org/pkg/flatpak-tests
      https://tracker.debian.org/pkg/flatpak-xdg-utils
      https://tracker.debian.org/pkg/flatpak-xdg-utils-tests
      https://tracker.debian.org/pkg/font-viewer
      https://tracker.debian.org/pkg/frameworkintegration
      https://tracker.debian.org/pkg/gamemode-daemon
      https://tracker.debian.org/pkg/gstreamer-qapt
      https://tracker.debian.org/pkg/gtk-3-examples
      https://tracker.debian.org/pkg/hotspot
      https://tracker.debian.org/pkg/iwd
      https://tracker.debian.org/pkg/kde-cli-tools
      https://tracker.debian.org/pkg/kde-config-gtk-style
      https://tracker.debian.org/pkg/kde-config-gtk-style-preview
      https://tracker.debian.org/pkg/kde-config-systemd
      https://tracker.debian.org/pkg/kdeconnect
      https://tracker.debian.org/pkg/kde-telepathy-auth-handler
      https://tracker.debian.org/pkg/kde-telepathy-call-ui
      https://tracker.debian.org/pkg/kde-telepathy-filetransfer-handler
      https://tracker.debian.org/pkg/kde-telepathy-text-ui
      https://tracker.debian.org/pkg/khelpcenter
      https://tracker.debian.org/pkg/kinit
      https://tracker.debian.org/pkg/kio
      https://tracker.debian.org/pkg/kwin-common
      https://tracker.debian.org/pkg/lambda-align2
      https://tracker.debian.org/pkg/libexecline2.5
      https://tracker.debian.org/pkg/libexecline-dev
      https://tracker.debian.org/pkg/libexecs0
      https://tracker.debian.org/pkg/libexecs-dev
      https://tracker.debian.org/pkg/libexecs-embedded0
      https://tracker.debian.org/pkg/libkf5config-bin
      https://tracker.debian.org/pkg/libkf5kdelibs4support5-bin
      https://tracker.debian.org/pkg/libkf5purpose-bin
      https://tracker.debian.org/pkg/libkf5screen-bin
      https://tracker.debian.org/pkg/libkf5su-bin
      https://tracker.debian.org/pkg/libkf5wayland-dev
      https://tracker.debian.org/pkg/libkf5xmlgui-bin
      https://tracker.debian.org/pkg/libkim-api-dev
      https://tracker.debian.org/pkg/libkscreenlocker5
      https://tracker.debian.org/pkg/libktpotr9
      https://tracker.debian.org/pkg/libmbim-proxy
      https://tracker.debian.org/pkg/libmodsecurity3
      https://tracker.debian.org/pkg/libqmi-proxy
      https://tracker.debian.org/pkg/mlucas
      https://tracker.debian.org/pkg/ntpsec
      https://tracker.debian.org/pkg/openconnect
      https://tracker.debian.org/pkg/opensmtpd
      https://tracker.debian.org/pkg/opensmtpd-extras
      https://tracker.debian.org/pkg/os-autoinst
      https://tracker.debian.org/pkg/ostree-boot
      https://tracker.debian.org/pkg/ostree-tests
      https://tracker.debian.org/pkg/plasma-desktop
      https://tracker.debian.org/pkg/plasma-discover
      https://tracker.debian.org/pkg/plasma-discover-backend-snap
      https://tracker.debian.org/pkg/plasma-workspace
      https://tracker.debian.org/pkg/plasma-workspace-wayland
      https://tracker.debian.org/pkg/polkit-kde-agent-1
      https://tracker.debian.org/pkg/powerdevil
      https://tracker.debian.org/pkg/pulseaudio-module-gsettings
      https://tracker.debian.org/pkg/remote-logon-service
      https://tracker.debian.org/pkg/rkward
      https://tracker.debian.org/pkg/seahorse
      https://tracker.debian.org/pkg/sysprof
      https://tracker.debian.org/pkg/tomcat9
      https://tracker.debian.org/pkg/tomcat9-common
      https://tracker.debian.org/pkg/xdg-dbus-proxy-tests
      https://tracker.debian.org/pkg/xdg-desktop-portal
      https://tracker.debian.org/pkg/xdg-desktop-portal-gtk
      https://tracker.debian.org/pkg/xdg-desktop-portal-kde
      https://tracker.debian.org/pkg/xdg-desktop-portal-tests
    

2\. [https://www.debian.org/doc/debian-
policy/](https://www.debian.org/doc/debian-policy/)

3\.
[https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.html#us...](https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.html#usrlibexec)

~~~
JdeBP
Debian generally favours individual subdirectories of /usr/lib instead.
/usr/lib/policykit-1/polkitd rather than /usr/local/libexec/polkitd (in older
FreeBSD packages), for example.

------
altmind
and /etc/resolv.conf dont belong anywhere as it is runtime settings

~~~
progval
What about /run or /proc?

~~~
nuxi
There is no /run by default on FreeBSD (only /var/run), and /proc (procfs) is
being phased out since 2011.

------
JdeBP
The reality is not quite as the article paints it.

First of all, there was a system before Mewburn rc. FreeBSD had an
/etc/rc.local.d/ mechanism for drop-in scripts in the middle 1990s, added by
Jordan Hubbard and Garrett Wollman.

* [http://jdebp.uk./FGA/rc.local-is-history.html](http://jdebp.uk./FGA/rc.local-is-history.html)

Second, /etc/rc.conf is not the only service configuration file in FreeBSD's
version of Mewburn rc. The primary configuration file is in fact
/etc/defaults/rc.conf , and _that_ file lists, in a variable, the name of
other secondary configuration files, including /etc/rc.conf and
/etc/rc.conf.local . On PC-BSD of old, and then TrueOS, it also named things
like /etc/rc.conf.pcbsd for example.

    
    
        % sysrc -f /etc/defaults/rc.conf rc_conf_files
        rc_conf_files: /etc/rc.conf.pcbsd /etc/rc.conf /etc/rc.conf.local
        %
    

Third, if you go back to Usenet of the 1980s, and indeed contemporary books
about system administration, you'll find that the distinction between /etc/rc
and /etc/rc.local was problematic and not what people tell you it is supposed
to be. People then too thought that /etc/rc was for the operating system
manufacturer, and /etc/rc.local was for the system administrator. But in
practice operating system _resellers_ ended up putting their stuff in
/etc/rc.local making it _also_ something that system administrators touched at
their peril, lest they break operating system upgrades.

Fourth, the article says "You might even want to support a separate location
for user-created services". That already exists. It's /usr/local/etc/rc.d/ .
And to highlight the point about resellers invading "local" stuff, note that
PC-BSD and TrueOS fill it with additional PC-BSD services like pcdm and pc-
samba and the problem of "reseller"-provided add-ons being "local" continues
to this day.

    
    
        % sysrc -f /etc/defaults/rc.conf local_startup
        local_startup: /usr/local/etc/rc.d /usr/pbi/rc.d
        %
    

Fifth, systemd unit files are not scripts. This is one of their defining
features, and one of the things widely touted about them, in fact. As the
systemd developers will themselves tell you, and have, they are configuration
files. Hence the systemd developers thinking that it was a mistake to provide
an EnvironmentFile setting. systemd isn't dividing things up into
"configuration files" and "code", as this article talks about. It has multiple
sets of things _all_ of which are configuration files.

* [https://unix.stackexchange.com/a/419061/5132](https://unix.stackexchange.com/a/419061/5132)

Sixth, the systemd search order for unit files isn't that simple, and has a
history of being improperly documented. It searches 17 directories nowadays,
including subdirectories of /usr/local .

* [http://jdebp.uk./FGA/systemd-documentation-errata.html#Missi...](http://jdebp.uk./FGA/systemd-documentation-errata.html#MissingUsrLocalLibSystemd)

For completeness, note that Debian's 2014 improvements to van Smoorenburg rc
put new things like init-d-script into /lib/init/ .

* [https://manpages.debian.org/sid/sysvinit-utils/init-d-script...](https://manpages.debian.org/sid/sysvinit-utils/init-d-script.5.en.html)

