Bug 630174 - RFE: systemd-unscrew-my-system
Summary: RFE: systemd-unscrew-my-system
Alias: None
Product: Fedora
Classification: Fedora
Component: systemd
Version: rawhide
Hardware: All
OS: Linux
Target Milestone: ---
Assignee: systemd-maint
QA Contact: Fedora Extras Quality Assurance
Depends On:
Blocks: systemd-RFE
TreeView+ depends on / blocked
Reported: 2010-09-03 22:02 UTC by Bill Nottingham
Modified: 2015-03-13 05:04 UTC (History)
13 users (show)

Fixed In Version: systemd-218-5.fc22
Doc Type: Bug Fix
Doc Text:
Clone Of:
Last Closed: 2015-03-13 05:04:27 UTC
Type: ---

Attachments (Terms of Use)

Description Bill Nottingham 2010-09-03 22:02:16 UTC
Description of problem:

While systemd's symlink-based configuration is very flexible, it's not as easy to back out of as a config file approach, where you can just install the stock config file.

What would be nice is some simple command that resets /etc/systemd/system to a default known state.

Not sure how complex this would be, though.

Version-Release number of selected component (if applicable):


Comment 1 Michal Schmidt 2010-09-07 20:23:35 UTC
In today's IRC conversation with Adam Williams during the systemd Test Day about bug 630952 I got some ideas which are in fact closely related to this bug.
I'll copy my comment from bug 630952 here:

I'm thinking the main error is in systemd design itself.

Deciding to "systemctl enable" a service in various %post scriptlets based on
whether the package is installed or upgraded is fragile. Once a packager
forgets to enable the service in a package, he cannot easily fix it in a later
version. The "if [ $1 -eq 1 ]" test is no good.

We witnessed this already several times during F-14 development. See the
"Heads-up" emails from Lennart on the devel mailing list asking people to fixup
their symlinks by a manual action. A good design would easily allow a new
version of the package to correct the mistakes of the previous version

Also, the default configuration of symlinks is scattered across packages'
scriptlets. There's no way to easily find out, what the default setup is
supposed to look like. See a related bug 630174.

I propose systemctl should get a new subcommand, let's call it "new-services".
Scriptlets would not run "systemctl enable my.service" but "systemctl
new-services". This would scan the /lib/systemd/system directory for newly
installed *.service and process their "[Install]" sections as the "enable"
command would. The difference would be that systemctl would keep a state
directory somewhere to track which services were already enabled by it.
This will allow to distinguish between services that were never enabled and
those that were manually disabled by the user.

Comment 2 Michal Schmidt 2010-09-07 20:23:58 UTC
Some more thoughts about the general issue:

Considering a service which ships a SysV initscript:

The initscript can be in these states:
   - /etc/init.d/$service exists
   - /etc/rc?.d/[SK]* symlinks not present
   - e.g., after "chkconfig --add $service"
   - K* symlinks present
   - if the initscript's chkconfig header asks for it,
     also some S* symlinks are present
   - after the administrator changed some K* symlinks to S* or vice-versa
   - e.g. after "chkconfig $service {on,off}" was used

The service is packaged in a RPM which does:
chkconfig --add $service

It can do that both after installation and upgrade, because the action is idempotent - repeating it does not change the result.
If the service was just INSTALLED, it will be ADDED.
If it was already ADDED, nothing will change.
If it was already MODIFIED, nothing will change.

Now consider the service uses a native systemd unit instead:

A systemd service can be either:
   - /lib/systemd/system/$service.service exists, but is not symlinked
   - after "systemctl enable $service.service"
   - some symlinks point to it

The key problem here is that there is no third state. There is no simple way to detect if the service was enabled/disabled by the administrator. If there were three states, packages could do something like:

systemctl add-unit $service.service

add-unit would notify systemd of a newly installed unit file and optionally enable the service too. The service could request this using a new key in the [Install] section:

add-unit would have to be idempotent. Tracking of the three states could be implemented using state information kept in, say /var/lib/systemd/. It could be a simple flat list of units already added or something more complicated if needed.

(The "new-services" idea from comment #1 was probably complicating it a bit too much.)

Comment 3 Valdis Kletnieks 2010-09-29 12:39:42 UTC
Amen to that - I've gotten bit by this issue already (my gettys managed to evaporate).

Additionally, as this makes its way into RHEL and onto systems that have audit requirements, there *will* be questions from auditors of the form "list all installed but not enabled daemons". It's easy to find them under chkconfig, just look in /etc/init.d and all possible daemons are there, whether or not chkconfig --add has been run. Doing an 'rpm -qa' and wading through the 1,889 rpms on my laptop is a non-starter.

Comment 4 Matthias Clasen 2010-10-08 22:46:26 UTC
Moving systemd bugs to f15, since the systemd feature got delayed.

Comment 5 Lennart Poettering 2010-11-21 21:44:06 UTC
Note that at least the issue with default.target is gone since we nowadays place a fallback default.target symlink in /lib/systemd which is used in case the one in /etc/systemd does not exist.

Comment 6 Fedora Admin XMLRPC Client 2011-10-20 16:25:57 UTC
This package has changed ownership in the Fedora Package Database.  Reassigning to the new owner of this component.

Comment 7 Jóhann B. Guðmundsson 2012-02-27 11:05:19 UTC
Ping what's the current status on this?

Comment 8 Rudd-O DragonFear 2012-07-26 00:48:55 UTC
Presets are poised to fix this problem.  Check F18 features.

Comment 9 Lennart Poettering 2013-01-14 22:18:14 UTC
We could implement this relatively nicely now, using the preset logic. i.e. by doing the equivalent of invoking "systemctl reenable" on all unit files we have. That will sync the system with the preset files, and leave only symlinks to services that are not shipped upstream in /etc, plus any files that might exist there.

Comment 10 Harald Hoyer 2013-04-10 15:10:09 UTC
(In reply to comment #9)
> We could implement this relatively nicely now, using the preset logic. i.e.
> by doing the equivalent of invoking "systemctl reenable" on all unit files
> we have. That will sync the system with the preset files, and leave only
> symlinks to services that are not shipped upstream in /etc, plus any files
> that might exist there.


Comment 11 Bill Nottingham 2013-04-10 15:11:46 UTC
pinging... who? That seems like a reasonable implementation.

Comment 12 Harald Hoyer 2013-04-10 15:14:23 UTC
(In reply to comment #11)
> pinging... who? That seems like a reasonable implementation.

ping for the actual implementation :)

Comment 14 Lennart Poettering 2014-06-17 00:44:25 UTC
#9 is now implemented in git.

Comment 15 Zbigniew Jędrzejewski-Szmek 2015-03-13 05:04:27 UTC
systemctl preset-all should do the trick.

Note You need to log in before you can comment on or make changes to this bug.