This reverts commit edda44605f.
The kernel explicitly supports resuming with a different kernel than the one
used before hibernation. If this is something that shouldn't be supported, the
place to change this is in the kernel. We shouldn't censor something that this
exclusively in the kernel's domain.
People might be using this to switch kernels without restaring programs, and
we'd break this functionality for them.
Also, even if resuming with a different kernel was a bad idea, we don't really
prevent that with this check, since most users have more than one kernel and
can freely pick a different one from the menu. So this only affected the corner
case where the kernel has been removed, but there is no reason to single it
out.
This splits out a bunch of functions from fileio.c that have to do with
temporary files. Simply to make the header files a bit shorter, and to
group things more nicely.
No code changes, just some rearranging of source files.
Ideally, coccinelle would strip unnecessary braces too. But I do not see any
option in coccinelle for this, so instead, I edited the patch text using
search&replace to remove the braces. Unfortunately this is not fully automatic,
in particular it didn't deal well with if-else-if-else blocks and ifdefs, so
there is an increased likelikehood be some bugs in such spots.
I also removed part of the patch that coccinelle generated for udev, where we
returns -1 for failure. This should be fixed independently.
This reverts 5fdf2d51c2, except for one improved
log message.
Fixes#10613.
Checking if resume= is configured is a good idea, but it turns out we cannot do
it reliably:
- the code only supported boot options with sd-boot, and it's not very widely
used. This means that for most systemd we could only check the current
commandline, not the next one.
- Various systems resume without, e.g. Debian has
/etc/initramfs-tools/conf.d/resume in the initramfs.
Making those checks better would be possible with enough effort, but there'll
be always new systems that boot in a slightly different way and we would need
to keep adding new cases. Longer term, we want to rely on autodetecting the
resume partition, and then checks like this will not be necessary at all. It is
quite clear from the number of bug reports that the number of poeple impacted
by this is quite high now, so let's just drop this.
The three core variables that affect idleness handling are whether we
are docked, whether we are on AC power and whether the lid is closed,
hence let's also expose the third variable on the bus, to make things
nicely debuggable.
It's not, after all, that's what SetRebootToFirmware() is about.
(I was wondering for a moment whether to make this EMITS_CHANGES, but
decided against it, given that the flag actually can be changed
externally to logind too, and we couldn't send out notifications for
that.)
This is useful so that during shutdown scope units are always terminated
before the mounts necessary for the home directory.
(Ideally we'd also add a similar dependency from the user@.service
instance to the home directory, but this isn't as easy as that service
is defined statically and not dynamically, and hence not easy to modify
dynamically, in particular when it comes to deps)
Instead of managing it explicitly, let's simplify things and rely on
regular Wants=/Requires= dependencies to pull in these units from
user@.service and the session scope, and StopWhenUneeded= to stop these
auxiliary units again. This way, they can be pulled in easily by
unrelated units too.
This simplifies things quite a bit: for each session we now only need to
manage the session scope, and for each user the user@.service, the other
units are not something we need to manage anymore.
This patch also makes sure that if user@.service of a user is masked we
will continue to work, and user-runtime-dir@.service will still be
correctly pulled in, as it is now a dependency of the scope unit.
Fixes: #9461
Replaces: #5546
This makes hibernation unavailable if the kernel image we are currently
running was removed. This is supposed to be superficial protection
against hibernating a system we can never return from because the kernel
has been updated and the kernel we currently run is not available
anymore.
We look at a couple of places for the kernel, which should cover all
distributions I know off. Should I have missed a path I am sure people
will quickly notice and we can add more places to check. (or maybe
convince those distros to stick their kernels at a standard place)
These lines are generally out-of-date, incomplete and unnecessary. With
SPDX and git repository much more accurate and fine grained information
about licensing and authorship is available, hence let's drop the
per-file copyright notice. Of course, removing copyright lines of others
is problematic, hence this commit only removes my own lines and leaves
all others untouched. It might be nicer if sooner or later those could
go away too, making git the only and accurate source of authorship
information.
This part of the copyright blurb stems from the GPL use recommendations:
https://www.gnu.org/licenses/gpl-howto.en.html
The concept appears to originate in times where version control was per
file, instead of per tree, and was a way to glue the files together.
Ultimately, we nowadays don't live in that world anymore, and this
information is entirely useless anyway, as people are very welcome to
copy these files into any projects they like, and they shouldn't have to
change bits that are part of our copyright header for that.
hence, let's just get rid of this old cruft, and shorten our codebase a
bit.
They are not needed, because anything that is non-zero is converted
to true.
C11:
> 6.3.1.2: When any scalar value is converted to _Bool, the result is 0 if the
> value compares equal to 0; otherwise, the result is 1.
https://stackoverflow.com/questions/31551888/casting-int-to-bool-in-c-c
Externally it's an uint64_t anyway, and internally we most just
initialize it to physical_memory() which returns uint64_t, hence there's
exactly zero value in using it as size_t internally. Hence, let's fix
that, and use uint64_t everywhere.
This removes the UserTasksMax= setting in logind.conf. Instead, the generic
TasksMax= setting on the slice should be used. Instead of a transient unit we
use a drop-in to tweak the default definition of a .slice. It's better to use
the normal unit mechanisms instead of creating units on the fly. This will also
make it easier to start user@.service independently of logind, or set
additional settings like MemoryMax= for user slices.
The setting in logind is removed, because otherwise we would have two sources
of "truth": the slice on disk and the logind config. Instead of trying to
coordinate those two sources of configuration (and maintainer overrides to
both), let's just convert to the new one fully.
Right now now automatic transition mechanism is provided. logind will emit a
hint when it encounters the setting, but otherwise it will be ignored.
Fixes#2556.
This drops a good number of type-specific _cleanup_ macros, and patches
all users to just use the generic ones.
In most recent code we abstained from defining type-specific macros, and
this basically removes all those added already, with the exception of
the really low-level ones.
Having explicit macros for this is not too useful, as the expression
without the extra macro is generally just 2ch wider. We should generally
emphesize generic code, unless there are really good reasons for
specific code, hence let's follow this in this case too.
Note that _cleanup_free_ and similar really low-level, libc'ish, Linux
API'ish macros continue to be defined, only the really high-level OO
ones are dropped. From now on this should really be the rule: for really
low-level stuff, such as memory allocation, fd handling and so one, go
ahead and define explicit per-type macros, but for high-level, specific
program code, just use the generic _cleanup_() macro directly, in order
to keep things simple and as readable as possible for the uninitiated.
Note that before this patch some of the APIs (notable libudev ones) were
already used with the high-level macros at some places and with the
generic _cleanup_ macro at others. With this patch we hence unify on the
latter.
$ sudo swapoff -av
swapoff /dev/vda4
$ sudo systemctl hibernate
Failed to hibernate system via logind: Not enough swap space for hibernation
Fixes#6729.
If hibernate.target is masked, and systemctl hibernate is invoked, havoc ensues.
logind starts the hibernation operation, but then doesn't go through with it;
gnome-shell segfaults. Let's be nice to the user and refuse doing anything in
that case.
$ sudo systemctl mask hibernate.target
$ busctl call org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager CanHibernate
s "no"
$ sudo systemctl hibernate
Failed to hibernate system via logind: Access denied
Failed to start hibernate.target: Unit hibernate.target is masked.
https://bugzilla.redhat.com/show_bug.cgi?id=1468003#c4
Files which are installed as-is (any .service and other unit files, .conf
files, .policy files, etc), are left as is. My assumption is that SPDX
identifiers are not yet that well known, so it's better to retain the
extended header to avoid any doubt.
I also kept any copyright lines. We can probably remove them, but it'd nice to
obtain explicit acks from all involved authors before doing that.
When we are attempting to create directory somewhere in the bowels of /var/lib
and get an error that it already exists, it can be quite hard to diagnose what
is wrong (especially for a user who is not aware that the directory must have
the specified owner, and permissions not looser than what was requested). Let's
print a warning in most cases. A warning is appropriate, because such state is
usually a sign of borked installation and needs to be resolved by the adminstrator.
$ build/test-fs-util
Path "/tmp/test-readlink_and_make_absolute" already exists and is not a directory, refusing.
(or)
Directory "/tmp/test-readlink_and_make_absolute" already exists, but has mode 0775 that is too permissive (0755 was requested), refusing.
(or)
Directory "/tmp/test-readlink_and_make_absolute" already exists, but is owned by 1001:1000 (1000:1000 was requested), refusing.
Assertion 'mkdir_safe(tempdir, 0755, getuid(), getgid(), MKDIR_WARN_MODE) >= 0' failed at ../src/test/test-fs-util.c:320, function test_readlink_and_make_absolute(). Aborting.
No functional change except for the new log lines.
Suspend to Hibernate is a new sleep method that invokes suspend
for a predefined period of time before automatically waking up
and hibernating the system.
It's similar to HybridSleep however there isn't a performance
impact on every suspend cycle.
It's intended to use with systems that may have a higher power
drain in their supported suspend states to prevent battery and
data loss over an extended suspend cycle.
Signed-off-by: Mario Limonciello <mario.limonciello@dell.com>
> logind sessions are mostly bound to the audit session concept, and audit
> sessions remain unaffected by "su", in fact they are defined to be
> "sealed off", i.e. in a way that if a process entered a session once, it
> will always stay with it, and so will its children, i.e. the only way to
> get a new session is by forking off something off PID 1 (or something
> similar) that never has been part of a session.
The code had a gap. user@.service is a special case PAM session which does
not create a logind session. Let's remember to check for it.
Fixes#8021
This is an attempt to improve #8228 a bit, by extending the /run/nologin
a bit, but still keeping it somewhat brief.
On purpose I used the vague wording "unprivileged user" rather than
"non-root user" so that pam_nologin can be updated to disable its
behaviour for members of the "wheel" group one day, and our messages
would still make sense.
See #8228.
This usually is very annoying to users who then cannot log in, so
make sure we always warn if that happens (selinux, or whatever other reason).
This reverts a790812cb3.
This change adds support for controlling the suspend-on-lid-close
behaviour based on the power status as well as whether the machine is
docked or has an external monitor. For backwards compatibility the new
configuration file variable is ignored completely by default, and must
be set explicitly before being considered in any decisions.
If for some reason we can't query the firmware state, don't propagate
that to clients, but instead log about it, and claim that
reboot-to-firmware is not available (which is the right answer, since it
is not working).
Let's log about this though, as this is certainly relevant to know, even
though not for the client.
SetLinger is authorized by the PolicyKit action "set-self-linger", if it is
not passed an explicit UID.
According to comments we were determining the default UID from the client's
session. However, user processes e.g. which are run from a terminal
emulator do not necessarily belong to a session scope unit. They may
equally be started from the systemd user manager [1][2]. Actually the
comment was wrong, and it would also have worked for processes
started from the systemd user manager.
Nevertheless it seems to involve fetching "augmented credentials" i.e.
it's using a racy method, so we shouldn't have been authenticating based
on it.
We could change the default UID, but that raises issues especially for
consistency between the methods. Instead we can just use the clients
effective UID for authorization.
This commit also fixes `loginctl enable-linger $USER` to match the docs
that say it was equivalent to `loginctl enable-linger` (given that $USER
matches the callers user and owner_uid). Previously, the former would not
have suceeded for unpriviliged users in the default configuration.
[1] It seems the main meaning of per-session scopes is tracking the PAM
login process. Killing that provokes logind to revoke device access. Less
circularly, killing it provokes getty to hangup the TTY.
[2] User units may be started with an environment which includes
XDG_SESSION_ID (presuambly GNOME does this?). Or not.
The manpages tell that such calls have quite limited meaning. logind has
a few in the implementation of what remains of the session concept.
At the same time, logind basically exposes sd_pid_get_session() as public
API. This is absolutely required, to retain compatability e.g. with Xorg.
But client code will work in more situations if it avoids assuming that it
runs in a session itself.
Its use inside the login session could be replaced with $XDG_SESSION_ID
(which pam_systemd sets). I don't know whether it would be useful to
change Xorg at this point or not. But if you were building something new,
you would think about whether you want to support running it in a systemd
service.
Comment these logind API features, acknowledging the reason they exist is
based in history. I.e. help readers avoid drawing implications from their
existence which apply to history, but not the current general case.
Finally, searching these revealed a call to sd_pid_get_session() in
implementing some types of logind inhibitors. So these inhibitors don't
work as intended when taken from inside a systemd user service :(. Comment
this as well, deferring it as ticket #6852.
If you try to run `loginctl user-status` on a non-logged in user to see
whether "Linger" is enabled, it doesn't work.
If you're already an expert in logind, the fact that the user is considered
unknown actually tells you the user is not lingering. So, probably they
they do not have lingering enabled. I think we can point towards this
without being misleading.
I also reword it because I thought it was slightly confusing to run
`loginctl user-status root` and get an error back about "User 0". Try to
be more specific, that it is "User ID 0".
GetSessionByPID(0) can fail with NO_SESSION_FOR_PID. More obscurely, if
the session is abandoned, it can return NO_SUCH_SESSION. It is not clear
that the latter was intended. The message associated with the former,
hints that this was overlooked.
We don't have a document enumerating the errors. Any specific
error-handling in client code, e.g. translated messages, would also be
liable to overlook the more obscure error code.
I can't see any equivalent condition for GetUserByPID(0). On the other
hand, the code did not return NO_USER_FOR_PID where it probably should.
The relevant code is right next to that for GetSessionByPID(0), so it will
be simpler to understand if both follow the same pattern.
This adds new method calls Halt() and CanHalt() to the logind bus APIs.
They aren't overly useful (as the whole concept of halting isn't really
too useful), however they clean up one major asymmetry: currently, using
the "shutdown" legacy commands it is possibly to enqueue a "halt"
operation through logind, while logind officially doesn't actually
support this. Moreover, the path through "shutdown" currently ultimately
fails, since the referenced "halt" action isn't actually defined in
PolicyKit.
Finally, the current logic results in an unexpected asymmetry in
systemctl: "systemctl poweroff", "systemctl reboot" are currently
asynchronous (due to the logind involvement) while "systemctl halt"
isnt. Let's clean this up, and make all three APIs implemented by
logind natively, and all three hence asynchronous in "systemctl".
Moreover, let's add the missing PK action.
Fixes: #6957
This reverts commit ee043777be.
It broke almost everywhere it touched. The places that
handn't been converted, were mostly followed by special
handling for the invalid PID `0`. That explains why they
tested for `pid < 0` instead of `pid <= 0`.
I think that one was the first commit I reviewed, heh.
Following commit b498d6ea, I belated realized we should tighten the
assertions as well, to make sure that we're setting `m->action_what` to
represent an action in progress. (The check for an action in progress is
to compare `m->action_what` to zero)
This fixed https://bugzilla.redhat.com/show_bug.cgi?id=1476313
as much as I was able to reproduce it in a VM, at least.
E.g. this signal might wake the screen back up, providing a more visible
indicator of suspend failure. In my VM testing, it was also required in
order to unblock keyboard input in gnome-shell after the failed suspend.
At the same time, fix the error handling for scheduled shutdowns. This now
mirrors the behaviour of when you use `shutdown -k` - it sends all the
scary messages about shutting down, "but you'll have to do it [shut down
the system] yourself". It also avoids the risk of locking out the admin
(nologin file), in case they logged out for some reason (and they use
`sudo` instead of root).
Not that I have any idea why you'd want to use `shutdown -k`, but the code
is easier to analyze if it rolls back on error (in the absence of any code
comment as to why that's not wanted).
There is no justification not to wait an extra (default) 5 seconds, for
a more graceful shutdown of user programs. Again, you don't get to ignore
delay inhibitors for unscheduled shutdowns, short of
`systemctl poweroff -f`.
It is simplest if we move the test for `m->shutdown_dry_run` into
manager_scheduled_shutdown_handler().
However we need to not add such delays during a "dry run". Otherwise, we
would still have to be considered "in progress" for some seconds after our
admin has seen the final wall message. If they go to `poweroff`, we would
have blocked them with a misleading error message. Note this `poweroff`
will still process delay inhibitors as needed. If the admin planned to
use a more forceful method... eh. It's their responsibility to assess
whether that's safe.
There is an argument that the alternative behaviour could be used (racily!)
to kludge around them not being able to shutdown to "single user mode". If
we cared about that case, we would have easily preserved non-racy support
for it in `shutdown`.
Additionally, though I think this code does read more easily by reducing
inconsistencies, we didn't come up with any use case for delay inhibitors
v.s. shutdown.[1] The SIGTERM v.s. SIGKILL delay is more general, and we
allow a whole 90 seconds for it, not just 5. So I don't think keeping this
approach bears a risk of significant damage.
[1] https://www.freedesktop.org/wiki/Software/systemd/inhibit/
> We don't want to shutdown while a suspend is running, and vice versa.
> This would be confusing and could lead to data loss in the worst case.
https://bugs.launchpad.net/ubuntu/+source/systemd/+bug/1441253/comments/4
According to the above comment, if the conflicting operation is hung,
we don't want to force things when the admin has not passed a force option.
Similarly if you're not an admin, you probably shouldn't get to sneak
around this check by using a scheduled shutdown instead of an unscheduled
one. (And no-one so far thought it necessary to add such a permission in
PolKit).
Note that if the conflicting operation was _not_ hung, and we lost the
race with suspend, the system might not have shut down at the scheduled
time anyway. Which is no good if you were scheduling a power outage.
And scheduling a shutdown for an arbitrary time when the system is resumed,
does not seem a very useful semantic. More likely, scheduled shutdowns are
useful on systems which do not use suspend, such as multi-user servers.
(In which case even PolKit defaults likely don't let the users trigger
suspend).
Let's add a proper validation function, since validation isn't entirely
trivial. Make use of it where applicable. Also make use of
AUDIT_SESSION_INVALID where we need a marker for an invalid audit
session.
Embedding sd_id128_t's in constant strings was rather cumbersome. We had
SD_ID128_CONST_STR which returned a const char[], but it had two problems:
- it wasn't possible to statically concatanate this array with a normal string
- gcc wasn't really able to optimize this, and generated code to perform the
"conversion" at runtime.
Because of this, even our own code in coredumpctl wasn't using
SD_ID128_CONST_STR.
Add a new macro to generate a constant string: SD_ID128_MAKE_STR.
It is not as elegant as SD_ID128_CONST_STR, because it requires a repetition
of the numbers, but in practice it is more convenient to use, and allows gcc
to generate smarter code:
$ size .libs/systemd{,-logind,-journald}{.old,}
text data bss dec hex filename
1265204 149564 4808 1419576 15a938 .libs/systemd.old
1260268 149564 4808 1414640 1595f0 .libs/systemd
246805 13852 209 260866 3fb02 .libs/systemd-logind.old
240973 13852 209 255034 3e43a .libs/systemd-logind
146839 4984 34 151857 25131 .libs/systemd-journald.old
146391 4984 34 151409 24f71 .libs/systemd-journald
It is also much easier to check if a certain binary uses a certain MESSAGE_ID:
$ strings .libs/systemd.old|grep MESSAGE_ID
MESSAGE_ID=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
MESSAGE_ID=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
MESSAGE_ID=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
MESSAGE_ID=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x
$ strings .libs/systemd|grep MESSAGE_ID
MESSAGE_ID=c7a787079b354eaaa9e77b371893cd27
MESSAGE_ID=b07a249cd024414a82dd00cd181378ff
MESSAGE_ID=641257651c1b4ec9a8624d7a40a9e1e7
MESSAGE_ID=de5b426a63be47a7b6ac3eaac82e2f6f
MESSAGE_ID=d34d037fff1847e6ae669a370e694725
MESSAGE_ID=7d4958e842da4a758f6c1cdc7b36dcc5
MESSAGE_ID=1dee0369c7fc4736b7099b38ecb46ee7
MESSAGE_ID=39f53479d3a045ac8e11786248231fbf
MESSAGE_ID=be02cf6855d2428ba40df7e9d022f03d
MESSAGE_ID=7b05ebc668384222baa8881179cfda54
MESSAGE_ID=9d1aaa27d60140bd96365438aad20286
We don't have plural in the name of any other -util files and this
inconsistency trips me up every time I try to type this file name
from memory. "formats-util" is even hard to pronounce.
For similar reasons as the recent addition of a limit on sessions.
Note that we don't enforce a limit on inhibitors per-user currently, but
there's an implicit one, since each inhibitor takes up one fd, and fds are
limited via RLIMIT_NOFILE, and the limit on the number of processes per user.
We really should put limits on all resources we manage, hence add one to the
number of concurrent sessions, too. This was previously unbounded, hence set a
relatively high limit of 8K by default.
Note that most PAM setups will actually invoke pam_systemd prefixed with "-",
so that the return code of pam_systemd is ignored, and the login attempt
succeeds anyway. On systems like this the session will be created but is not
tracked by systemd.
We enable lingering for anyone who wants this. It is still disabled by
default to avoid keeping long-running processes accidentally.
Admins might want to customize this policy on multi-user sites.
systemd-logind uses mkdir_label and label_fix functions without calling
first mac_selinux_init. This makes /run/user/$UID/ directories not
labelled correctly on an Arch Linux system using SELinux.
Fix this by calling mac_selinux_init("/run") early in systemd-logind.
This makes files created in /etc/udev/rules.d and /var/lib/systemd to be
labelled through transitions in the SELinux policy instead of using
setfscreatecon (with mac_selinux_create_file_prepare).
manager_{start,stop}_{slice,scope,unit} functions had an optional job
output parameter. But all callers specified job, so make the parameter
mandatory, add asserts. Also extract common job variable handling to
a helper function to avoid duplication.
Avoids gcc warning about job being unitialized.
gcc is confused by the common idiom of
return errno ? -errno : -ESOMETHING
and thinks a positive value may be returned. Replace this condition
with errno > 0 to help gcc and avoid many spurious warnings. I filed
a gcc rfe a long time ago, but it hard to say if it will ever be
implemented [1].
Both conventions were used in the codebase, this change makes things
more consistent. This is a follow up to bcb161b023.
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61846
method_schedule_shutdown referenced org.freedesktop.login1.poweroff*
which is never registered in polkit.
Now refers to org.freedesktop.login1.power-off*
Signed-off-by: Joost Bremmer <toost.b@gmail.com>
GLIB has recently started to officially support the gcc cleanup
attribute in its public API, hence let's do the same for our APIs.
With this patch we'll define an xyz_unrefp() call for each public
xyz_unref() call, to make it easy to use inside a
__attribute__((cleanup())) expression. Then, all code is ported over to
make use of this.
The new calls are also documented in the man pages, with examples how to
use them (well, I only added docs where the _unref() call itself already
had docs, and the examples, only cover sd_bus_unrefp() and
sd_event_unrefp()).
This also renames sd_lldp_free() to sd_lldp_unref(), since that's how we
tend to call our destructors these days.
Note that this defines no public macro that wraps gcc's attribute and
makes it easier to use. While I think it's our duty in the library to
make our stuff easy to use, I figure it's not our duty to make gcc's own
features easy to use on its own. Most likely, client code which wants to
make use of this should define its own:
#define _cleanup_(function) __attribute__((cleanup(function)))
Or similar, to make the gcc feature easier to use.
Making this logic public has the benefit that we can remove three header
files whose only purpose was to define these functions internally.
See #2008.
If we requeue jobs, we are no longer interested in old jobs. Hence, we
better ignore any JobRemoved signals for old jobs and concentrate on our
replacements.
When queuing unit jobs, we should rather replace existing units than
fail. This is especially important when we queued a user-shutdown and a
new login is encountered. In this case, we better raplce the shutdown
jobs. systemd takes care of everything else.