Commit Graph
422 Commits
Author SHA1 Message Date
Daan De Meyer e77e07f601 preset: Add ignore directive
The ignore directive specifies to not do anything with the given
unit and leave existing configuration intact. This allows distributions
to gradually adopt preset files by shipping a ignore * preset file.
2023-04-14 20:27:59 +01:00
Luca Boccassi 4d67245472 Merge pull request #27266 from dtardon/take-struct
Use TAKE_STRUCT() to copy and reset structs
2023-04-14 14:15:35 +01:00
David Tardon f52477d611 install: use FOREACH_ARRAY 2023-04-14 10:24:07 +02:00
David Tardon 05cdf6a701 tree-wide: rename cleanup function
... with accordance to the current coding style.
2023-04-14 10:24:07 +02:00
David Tardon 52c788e6e0 install: fix memory leak if GREEDY_REALLOC() fails 2023-04-14 10:23:15 +02:00
David Tardon 088d71f8ed tree-wide: use TAKE_STRUCT 2023-04-14 10:15:44 +02:00
David Tardon 2768156357 install: rename function 2023-04-12 17:11:52 +02:00
David Tardon 27beea26ef install: drop unused function 2023-04-12 17:09:41 +02:00
David Tardon c92899fdad install: define hash_ops for UnitFileList 2023-03-28 14:16:47 +02:00
Daan De Meyer f461a28da7 chase-symlinks: Rename chase_symlinks() to chase()
Chasing symlinks is a core function that's used in a lot of places
so it deservers a less verbose names so let's rename it to chase()
and chaseat().

We also slightly change the pattern used for the chaseat() helpers
so we get chase_and_openat() and similar.
2023-03-24 13:43:51 +01:00
Lennart Poettering 4870133bfa basic: add RuntimeScope enum
In various tools and services we have a per-system and per-user concept.
So far we sometimes used a boolean indicating whether we are in system
mode, or a reversed boolean indicating whether we are in user mode, or
the LookupScope enum used by the lookup path logic.

Let's address that, in introduce a common enum for this, we can use all
across the board.

This is mostly just search/replace, no actual code changes.
2023-03-10 09:47:39 +01:00
David Tardon f8979e8698 install: fail early if specifier expansion failed
Before:

systemd[1]: Assertion 'path' failed at src/shared/install.c:288, function install_changes_add(). Aborting.
systemd[1]: Caught <ABRT> from our own process.
systemd[1]: Caught <ABRT>, dumped core as pid 2525.
systemd[1]: Freezing execution

After:

Failed to enable unit: Invalid specifier in user-%J.service

Fixes #26467.

Follow-up for: f5a0162
2023-02-21 18:39:07 +00:00
Dmitry V. Levin 30fd9a2dab treewide: fix a few typos in NEWS, docs and comments 2023-02-15 10:41:03 +00:00
Robin Humble 19cfda9fc3 pid1: fix segv triggered by status query (#26279)
If any query makes it to the end of install_info_follow() then I think symlink_target is set to NULL.
If that is followed by -EXDEV from unit_file_load_or_readlink(), then that causes basename(NULL)
which segfaults pid 1.

This is triggered by eg. "systemctl status crond" in RHEL9 if

/etc/systemd/system/crond.service
  -> /ram/etc/systemd/system/crond.service
  -> /usr/lib/systemd/system/.crond.service.blah.blah
  -> /usr/lib/systemd/system/crond.service
2023-02-01 21:36:48 +09:00
Zbigniew Jędrzejewski-Szmek 8f5d716a71 shared/install: rework an assert to appease gcc-13
With the previous form, gcc is confused and thinks that .type might be unset.

Fixes #26118.
2023-01-22 18:25:56 +01:00
Zbigniew Jędrzejewski-Szmek 4a4af850b3 shared/install: rework InstallChange to always have .path set
We would set .path in all cases except INSTALL_CHANGE_AUXILIARY_FAILED, where
we would just just .source. This special case is just not worth it, because
we can't easily assert that .path is set. Let's remove this special case to
help the compiler know that .path is actually set.

Avoids a warning with gcc-13.0.1-0.1.fc38.x86_64.
2023-01-22 18:25:56 +01:00
Mike Yuan c067e61b85 systemctl: enable: overwrite broken alias symlinks
When switching to an alternative alias provider,
the previous one might have been uninstalled or so.
It should be fine for us to overwrite them directly.

Closes #23694
2023-01-05 02:10:42 +01:00
Zbigniew Jędrzejewski-Szmek 254d1313ae tree-wide: use -EBADF for fd initialization
-1 was used everywhere, but -EBADF or -EBADFD started being used in various
places. Let's make things consistent in the new style.

Note that there are two candidates:
EBADF 9 Bad file descriptor
EBADFD 77 File descriptor in bad state

Since we're initializating the fd, we're just assigning a value that means
"no fd yet", so it's just a bad file descriptor, and the first errno fits
better. If instead we had a valid file descriptor that became invalid because
of some operation or state change, the other errno would fit better.

In some places, initialization is dropped if unnecessary.
2022-12-19 15:00:57 +01:00
Mike Yuan bf1bea43f1 systemctl: warn if trying to disable a unit with no install info
Trying to disable a unit with no install info is mostly useless, so
adding a warning like we do for enable (with the new dbus method
'DisableUnitFilesWithFlagsAndInstallInfo()'). Note that it would
still find and remove symlinks to the unit in /etc, regardless of
whether it has install info or not, just like before. And if there are
actually files to remove, we suppress the warning.

Fixes #17689
2022-12-03 20:26:14 +08:00
Zbigniew Jędrzejewski-Szmek 28db6fbff1 Rename def.h to constants.h
The name "def.h" originates from before the rule of "no needless abbreviations"
was established. Let's rename the file to clarify that it contains a collection
of various semi-related constants.
2022-11-08 18:21:10 +01:00
Yu Watanabe f5a0162d20 install: process all Wants= symlinks even if some of them fail
Follow-up for 94e7298d30.

Fixes CID#1499992.
2022-10-28 14:36:53 +02:00
Zbigniew Jędrzejewski-Szmek a6f318a554 systemctl,manager: refuse linking unit files underneath the search paths
We treat symlinks to unit files outside of the search path differently from
symlinks to unit files *in* the search path. The former are "linked" unit
files, while the latter are enablement symlinks and such and will be removed
when disabling the unit.

The history of the check for in_search_path() is interesting: this condition
was added already in the first version of the code in
830964834f. Since the beginning, matching
arguments would simply be ignored. I think this is dubious. The man page says:

> Link a unit file that is *not* in the unit file search paths
> into the unit file search path

But for backwards-compat, let's continue to silently do nothing for files
*in* the search path.

The case of symlinks to unit files underneath the search path, but in some
subdirectory, is less clear. We didn't check for this case, so it was
implicitly allowed. But that's just an oversight, we don't want to allow people
to create additional subhierarchies under our hierarchy. Let's check for this
case and refuse.

Closes #24605.
2022-10-24 12:51:41 +02:00
Zbigniew Jędrzejewski-Szmek f31f10a620 shared/install: check that install_changes_add() didn't fail on success
This adds a check for an allocation error for the calls to install_changes_add()
where we're plannig to return success from the call. In cases where we're
returning failure, it doesn't matter as much: the operation will fail anyway,
and if the allocation fails, we'll just get a less descriptive error message.
2022-10-24 12:38:28 +02:00
Zbigniew Jędrzejewski-Szmek 81de696273 shared/install: add forgotten calls to install_changes_add()
The machinery to report a good error message only works if the
error was registered with install_changes_add() and a file name. Otherwise
we only get a generic "Op failed: %m" message.

In some places -EINVAL is replaced by -EUCLEAN, so that we get the proper
error message.
2022-10-24 12:38:28 +02:00
Zbigniew Jędrzejewski-Szmek 94e7298d30 shared/install: make install_changes_add propagate passed-in errno value
The function was written to only return an error from internal allocation
failures, because when using it to create a bus message, we want to distinguish
a failed operation from an allocation error when sending the reply. But it
turns out that the only caller that makes this distinction checks that the
passed-in errno value ('type') is not negative beforehand. So we can make the
function pass 'type' value through, which makes most of the callers nicer.

No functional change.
2022-10-24 12:37:19 +02:00
Zbigniew Jędrzejewski-Szmek 5ad58fea73 Make comment about coordinating offline and online installation symmetric
https://github.com/systemd/systemd/pull/24728#issuecomment-1260966910
2022-10-20 12:28:00 +02:00
Lennart Poettering b364c4de62 install: include full type name in special UnitFilePresetMode values
Typically the _MAX and _INVALID special enum values use the full type as
prefix, even if the actual values of the enum might not. Let's follow
this rule here too.
2022-10-14 11:41:32 +02:00
Lennart Poettering f8662fee2f install: make InstallChange enum type a proper type
We can just make this an enum, as long as we ensure it has enough range,
which we can do by adding -ERRNO_MAX as one possible value (at least on
GNU C). We already do that at multiple other places, so let's do this
here too.
2022-10-14 11:40:40 +02:00
Zbigniew Jędrzejewski-Szmek bf3b0d5f29 shared/install: print warning when unmasking unit with cmdline mask
'systemctl unmask foo' will try to remove the symlink to /dev/null under /etc/.
But the unit may also be masked by a symlink under /run/generator, in particular
the one created by systemd-debug-generator based on systemd.mask=foo on the
kernel commandline. The unmask call cannot anything about this: even if it removed
the symlink from /run/generator, it'll be recreated on the next daemon-reload.
Thus, we can only warn about it.

Initially, I wanted to check if 'systemctl.mask' is defined on the kernel
command-line, but that's not effective, because such mask symlinks can be
created by other generators based on other conditions. Checking for runtime
mask is "dumber", but is more robust because it doesn't assume who created the
mask and why.

The handling of InstallInfo is the copied from install_info_symlink_wants().
It's pretty ugly, this whole code should be rewritten from scratch.

The message is printed, but the whole operation is still "successful". This
keep backwards compatibility: people might call unmask to remove filesystem
masks even if there's still a cmdline param in place. We allow 'systemctl
mask' to create such a mask, so 'unmask' should be able to remove it.

Fixes #22689.
2022-10-13 19:44:47 +02:00
Zbigniew Jędrzejewski-Szmek acb5b83438 shared/install: use cleanup func for InstallInfo*
In the next commit cleanup will be used in one more place. This change
avoids proliferation of the open-coded cleanup calls.
2022-10-13 19:44:47 +02:00
Zbigniew Jędrzejewski-Szmek 0047d54d42 shared/install: rename 'UnitFileInstallInfo' to 'InstallInfo'
- shorter is better
- name now matches the defining-file name

I was also considering UnitInstallInfo. Can change if people prefer that.
2022-10-13 19:44:47 +02:00
Zbigniew Jędrzejewski-Szmek 1308f72e83 shared/install: rename 'unit_file_change_type' to 'install_change' + followups
We had an anonymous enum with values called UNIT_FILE_…, which could easily be
confused with UNIT_FILE_… from UnitFileFlags enum. This commit renames the enum
values and also the variables which refer to them.
2022-10-13 19:44:47 +02:00
Zbigniew Jędrzejewski-Szmek 91810c8ffc shared/install: rename UnitFileInstallInfo.type to .install_mode 2022-10-13 19:44:47 +02:00
Zbigniew Jędrzejewski-Szmek 318031fdb2 shared/install: rename 'unit file type' to 'install mode'
git grep -l -nwi 'UnitFileType|UNIT_FILE_TYPE' | \
xargs sed -r -i 's/UnitFileType/InstallMode/g; s/UNIT_FILE_TYPE/INSTALL_MODE/g; s/unit_file_type/install_mode/g'
2022-10-13 19:44:47 +02:00
Zbigniew Jędrzejewski-Szmek cd44ec5a92 shared/install: rename UnitFileChange to InstallChange
It's shorter and more generic. The struct can contain info about changes to
unit files, but also symlinks and errors.
2022-10-13 19:44:47 +02:00
Zbigniew Jędrzejewski-Szmek 0f87041f94 shared/install: rename 'files' param to 'names'
… or 'name_or_path' or 'names_or_paths' as appropriate. Those functions are
generally called with unit names as arguments.
2022-10-13 19:44:47 +02:00
Lennart Poettering 45519d13a4 tree-wide: port things dirname_malloc() → path_extract_directory() 2022-08-23 15:10:15 +02:00
David Tardon e2341b6bc3 tree-wide: allow ASCII fallback for → in logs 2022-06-28 12:50:43 +02:00
Zbigniew Jędrzejewski-Szmek 9aa3d6b41e Revert "shared/install: create relative symlinks for enablement and aliasing"
This reverts commit d6c9411072.

I still think this is something that needs to be done, but we're hitting some
unexplained failures, e.g. https://github.com/systemd/systemd/issues/22920.
So let's revert this for now, so -rc2 can be released, with a plan to return
to this after a release.

Closes #22920.
2022-05-05 19:02:26 +02:00
Yu Watanabe 0b6bf4b674 shared/install: use correct cleanup function
Fixes #23250.
2022-05-02 22:17:56 +01:00
Zbigniew Jędrzejewski-Szmek 6e961aeb26 shared/install: fix crash when reenable is called without --root 2022-04-15 18:26:07 +02:00
Yu Watanabe 798931160e tree-wide: add a space after if, switch, for, and while 2022-04-01 22:48:42 +09:00
Yu Watanabe 8b7378e145 fix typo 2022-03-30 21:10:06 +09:00
Zbigniew Jędrzejewski-Szmek b380b64383 Rename UnitFileScope to LookupScope
As suggested in
https://github.com/systemd/systemd/pull/22649/commits/8b3ad3983f5440eef812b34e5ed862ca59fdf7f7#r837345892

The define is generalized and moved to path-lookup.h, where it seems to fit
better. This allows a recursive include to be removed and in general makes
things simpler.
2022-03-29 16:17:57 +02:00
Zbigniew Jędrzejewski-Szmek 3fc53351dc shared/install: when creating symlinks, accept different but equivalent symlinks
We would only accept "identical" links, but having e.g. a symlink
/usr/lib/systemd/system/foo-alias.service → /usr/lib/systemd/system/foo.service
when we're trying to create /usr/lib/systemd/system/foo-alias.service →
./foo.service is OK. This fixes an issue found in ubuntuautopkg package
installation, where we'd fail when enabling systemd-resolved.service, because
the existing alias was absolute, and (with the recent patches) we were trying
to create a relative one.

A test is added.
(For .wants/.requires symlinks we were already doing OK. A test is also
added, to verify.)
2022-03-29 16:17:57 +02:00
Zbigniew Jędrzejewski-Szmek 48eadb9d9b shared/install: fix handling of a linked unit file
When we have a symlink that goes outside of our search path, we should just
ignore the target file name. But we were verifying it, and rejecting in
the case where a symlink was created manually.
2022-03-29 16:17:57 +02:00
Zbigniew Jędrzejewski-Szmek 48ed75adab shared/install: split UNIT_FILE_SYMLINK into two states
The two states are distinguished, but are treated everywhere identically,
so there is no difference in behaviour except for slighlty different log
output.
2022-03-29 16:17:57 +02:00
Zbigniew Jędrzejewski-Szmek 38e8a6c7fd shared/install: stop passing duplicate root argument to install_name_printf()
All callers were just passing info + info->root, we can simplify this.
2022-03-29 16:17:56 +02:00
Zbigniew Jędrzejewski-Szmek 466f6979c9 shared/install: when looking for symlinks in .wants/.requires, ignore symlink target
We'd say that file is enabled indirectly if we had a symlink like:
  foo@.service ← bar.target.wants/foo@one.service
but not when we had
  foo@one.service ← bar.target.wants/foo@one.service

The effect of both link types is the same. In fact we don't care
about the symlink target. (We'll warn if it is mismatched, but we honour
it anyway.)

So let's use the original match logic only for aliases.
For .wants/.requires we instead look for a matching source name,
or a source name that matches after stripping of instance.
2022-03-29 16:17:56 +02:00
Zbigniew Jędrzejewski-Szmek d6c9411072 shared/install: create relative symlinks for enablement and aliasing
This is a fairly noticable change, but I think it needs to be done.
So far we'd create an absolute symlink to the target unit file:
  .wants/foo.service → /usr/lib/systemd/system/foo.service
or
  alias.service → /etc/systemd/system/aliased.service.

This works reasonably well, except in one case: where the unit file
is linked. When we look at a file link, the name of the physical file
isn't used, and we only take the account the symlink source name.
(In fact, the destination filename may not even be a well-formed unit name,
so we couldn't use it, even if we wanted to.) But this means that if
a file is linked, and specifies aliases, we'd create absolute links for
those aliases, and systemd would consider each "alias" to be a separate
unit. This isn't checked by the tests here, because we don't have a running
systemd instance, but it is easy enough to check manually.

The most reasonable way to fix this is to create relative links to the
unit file:
  .wants/foo.service → ../foo.service
  alias.service → aliased.service.

I opted to use no prefix for aliases, both normal and 'default.target',
and to add "../" for .wants/ and .requires/. Note that the link that is
created doesn't necessarily point to the file. E.g. if we're enabling
a file under /usr/lib/systemd/system, and create a symlink in /etc/systemd/system,
it'll still be "../foo.service", not "../../usr/lib/systemd/system/foo.service".
For our unit loading logic this doesn't matter, and figuring out a path
that actually leads somewhere would be more work. Since the user is allowed
to move the unit file, or add a new unit file in a different location, and
we don't actually follow the symlink, I think it's OK to create a dangling
symlink. The prefix of "../" is useful to give a hint that the link points
to files that are conceptually "one level up" in the directory hierarchy.

With the relative symlinks, systemd knows that those are aliases.

The tests are adjusted to use the new forms. There were a few tests that
weren't really testing something useful: 'test -e x' fails if 'x' is a
a dangling symlink. Absolute links in the chroot would be dangling, even
though the target existed in the expected path, but become non-dangling
when made relative and the test fails.

This should be described in NEWS, but I'm not adding that here, because
it'd likely result in conflicts.
2022-03-29 16:17:56 +02:00