Compare commits

...

8 Commits

Author SHA1 Message Date
Benjamin Berg 31c68e0277 docs: Add some notes about managing graphical user sessions
This is work in progress and not finished yet. However, I hope to have
captured some of the key points that came up in previous discussions
with appropriate notes about things that still need to be defined.

I may revisit it later. Also, feel free to completely rewrite if the
format is not quite right.
2020-03-27 21:57:44 +01:00
Sean-StarLabs b642dfcdc2
hwdb: add Star Lite Mk II and Star LabTop Mk III (#14621) 2020-03-27 20:07:58 +01:00
Tom 90c40df0a6 Add Lenovo IdeaPad Miix 300 ACCEL_MOUNT_MATRIX 2020-03-27 19:32:29 +01:00
Balint Reczey 93c23c9297 user-util: Allow names starting with a digit
In 1a29610f5f the change inadvertedly
disabled names with digit as the first character. This follow-up change
allows a digit as the first character in compat mode.

Fixes: #15141
2020-03-27 19:06:36 +01:00
Wen Yang acd1987a18 core/unit: print info when unit_add_name failed
When there are hundreds of mounts on the server, it will take a long
time to analyze the failure of a certain mount unit. So it is useful
to print the reason why unit_add_name() failed.
2020-03-27 18:46:13 +01:00
Zhu Li 9520a0308d Remove stale doc about PrivateNetwork and type 2020-03-27 18:40:31 +01:00
Franck Bui e730db6c90 systemd-network-generator.service: network-pre.target is a passive target unit 2020-03-27 18:30:57 +01:00
Pieter Lexis 72e1c0b308 Add `shell` to machinectl ZSH completion 2020-03-27 18:15:15 +01:00
9 changed files with 168 additions and 20 deletions

View File

@ -0,0 +1,102 @@
---
title: Desktop Environment Integration
category: Concepts
layout: default
---
# Desktop Environments
NOTE: This document is a work-in-progress.
## Single Graphical Session
systemd only supports running one graphical session per user at a time.
While this might not have always been the case historically, having multiple
sessions for one user running at the same time is problematic.
The DBus session bus is shared between all the logins, and services that are
started must be implicitly assigned to the user's current graphical session.
In principle it is possible to run a single graphical session across multiple
logind seats, and this could be a way to use more than one display per user.
When a user logs in to a second seat, the seat resources could be assigned
to the existing session, allowing the graphical environment to present it
is a single seat.
Currently nothing like this is supported or even planned.
## Pre-defined systemd units
[`systemd.special(7)`](https://www.freedesktop.org/software/systemd/man/systemd.special.html)
defines the `graphical-session.target` and `graphical-session-pre.target` to
allow cross-desktop integration. Furthermore, systemd defines the three base
slices `background`, `apps` and `session`.
All units should be placed into one of these slices depending on their purposes:
* `session.slice`: Contains only processes essential to run the user's graphical session
* `apps.slice`: Contains all normal applications that the user is running
* `background.slice`: Useful for low-priority background tasks
The purpose of this grouping is to assign different priorities to the
applications.
This could e.g. mean reserving memory to session processes,
preferentially killing background tasks in out-of-memory situations
or assinging different memory/CPU/IO priorities to ensure that the session
runs smoothly under load.
TODO: Will there be a default to place units into e.g. `apps.slice` by default
rather than the root slice?
## XDG standardization for applications
To ensure cross-desktop compatibility and encourage sharing of good practices,
desktop environments should adhere to the following conventions:
* Application units should follow the scheme `apps-<launcher>-<ApplicationID>-<RANDOM>.service`,
e.g. `apps-gnome-org.gnome.Evince-12345.service`,
`apps-flatpak-org.telegram.desktop-12345.service` or `apps-KDE-org.kde.okular-12345.service`.
* Using `.service` units instead of `.scope` units, i.e. allowing systemd to
start the process on behalf of the caller,
instead of the caller starting the process and letting systemd know about it,
is encouraged.
* If no application ID is available, the launcher should generate a reasonable
name when possible (e.g. using `basename(argv[0])`). This name must not
contain a `-` character.
This has the following advantages:
* Using the `apps-<launcher>-` prefix means that the unit defaults can be
adjusted using desktop environment specific drop-in files.
* The application ID can be retrieved by stripping the prefix and postfix.
This in turn should map to the corresponding `.desktop` file when available
TODO: Define the name of slices that should be used.
This could be `apps-<launcher>-<ApplicationID>-<RANDOM>.slice`.
TODO: Does it really make sense to insert the `<launcher>`? In GNOME I am
currently using a drop-in to configure `BindTo=graphical-session.target`,
`CollectMode=inactive-or-failed` and `TimeoutSec=5s`. I feel that such a
policy makes sense, but it may make much more sense to just define a
global default for all (graphical) applications.
* Should application lifetime be bound to the session?
* May the user have applications that do not belong to the graphical session (e.g. launched from SSH)?
* Could we maybe add a default `apps-.service.d` drop-in configuration?
## XDG autostart integration
To allow XDG autostart integration, systemd will ship a cross-desktop generator
to create appropriate units for the autostart directory.
Desktop Environments will be able to make use of this simply by starting the
appropriate XDG related targets (representing e.g. content of the
`$XDG_CURRENT_DESKTOP` environment variable to handle `OnlyShowIn/NotShowIn`).
The names and ordering rules for these targets are to be defined.
This generator will likely never support certain desktop specific extensions.
One such example is the GNOME specific feature to bind a service to a settings
variable.
## Startup and shutdown best practices
Question here are:
* Are there strong opinions on how the session-leader process should watch the user's session units?
* Should systemd/logind/… provide an integrated way to define a session in terms of a running *user* unit?
* Is having `gnome-session-shutdown.target` that is run with `replace-irreversibly` considered a good practice?

View File

@ -571,6 +571,24 @@ evdev:name:ETPS/2 Elantech Touchpad:dmi:*svnSAMSUNGELECTRONICSCO.,LTD.:pn870Z5E/
EVDEV_ABS_35=::30 EVDEV_ABS_35=::30
EVDEV_ABS_36=::29 EVDEV_ABS_36=::29
#########################################
# Star Labs
#########################################
# Star LabTop Mk III
evdev:name:ALPS0001:00 0911:5288 Touchpad:dmi:*svnStarLabs:pnLabTop*
EVDEV_ABS_00=0:2627:25
EVDEV_ABS_01=0:1331:20
EVDEV_ABS_35=0:2627:25
EVDEV_ABS_36=0:1331:20
# Star Lite Mk II
evdev:name:ALPS0001:00 0911:5288 Touchpad:dmi:*svnStarLabs:pnLite:*
EVDEV_ABS_00=55:1750:16
EVDEV_ABS_01=51:950:15
EVDEV_ABS_35=55:1750:16
EVDEV_ABS_36=51:950:15
######################################### #########################################
# System76 # System76
######################################### #########################################

View File

@ -407,6 +407,10 @@ sensor:modalias:acpi:SMO8500*:dmi:bvnLENOVO:*:pvrLenovoMIIX3-830:*
sensor:modalias:acpi:BOSC0200*:dmi:*:svnLENOVO:pn81H3:* sensor:modalias:acpi:BOSC0200*:dmi:*:svnLENOVO:pn81H3:*
ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1 ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1
# IdeaPad Miix 300
sensor:modalias:acpi:SMO8500*:dmi:bvnLENOVO:*:pvrMIIX300-*
ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
# IdeaPad Miix 310 note this only is for BIOS version (bvr) 1HCN4?WW and 1HCN2?WW, which has # IdeaPad Miix 310 note this only is for BIOS version (bvr) 1HCN4?WW and 1HCN2?WW, which has
# a portrait LCD panel, versions with bvr 1HCN3?WW have a landscape panel # a portrait LCD panel, versions with bvr 1HCN3?WW have a landscape panel
sensor:modalias:acpi:KIOX000A*:dmi:bvnLENOVO:bvr1HCN4?WW:*:svnLENOVO:pn80SG:* sensor:modalias:acpi:KIOX000A*:dmi:bvnLENOVO:bvr1HCN4?WW:*:svnLENOVO:pn80SG:*

View File

@ -217,8 +217,7 @@
this notification message has been sent. If this option is used, <varname>NotifyAccess=</varname> (see this notification message has been sent. If this option is used, <varname>NotifyAccess=</varname> (see
below) should be set to open access to the notification socket provided by systemd. If below) should be set to open access to the notification socket provided by systemd. If
<varname>NotifyAccess=</varname> is missing or set to <option>none</option>, it will be forcibly set to <varname>NotifyAccess=</varname> is missing or set to <option>none</option>, it will be forcibly set to
<option>main</option>. Note that currently <varname>Type=</varname><option>notify</option> will not work if <option>main</option></para></listitem>.
used in combination with <varname>PrivateNetwork=</varname><option>yes</option>.</para></listitem>
<listitem><para>Behavior of <option>idle</option> is very similar to <option>simple</option>; however, <listitem><para>Behavior of <option>idle</option> is very similar to <option>simple</option>; however,
actual execution of the service program is delayed until all active jobs are dispatched. This may be used actual execution of the service program is delayed until all active jobs are dispatched. This may be used

View File

@ -28,6 +28,7 @@
"start:Start container as a service" "start:Start container as a service"
"stop:Stop container (equal to poweroff)" "stop:Stop container (equal to poweroff)"
"login:Get a login prompt on a VM/container" "login:Get a login prompt on a VM/container"
"shell:Invoke a shell (or other command) in a container"
"enable:Enable automatic container start at boot" "enable:Enable automatic container start at boot"
"disable:Disable automatic container start at boot" "disable:Disable automatic container start at boot"
"poweroff:Power off one or more VMs/containers" "poweroff:Power off one or more VMs/containers"

View File

@ -701,16 +701,18 @@ int take_etc_passwd_lock(const char *root) {
bool valid_user_group_name_full(const char *u, bool strict) { bool valid_user_group_name_full(const char *u, bool strict) {
const char *i; const char *i;
long sz; long sz;
bool warned = false;
/* Checks if the specified name is a valid user/group name. Also see POSIX IEEE Std 1003.1-2008, 2016 Edition, /* Checks if the specified name is a valid user/group name. Also see POSIX IEEE Std 1003.1-2008, 2016 Edition,
* 3.437. We are a bit stricter here however. Specifically we deviate from POSIX rules: * 3.437. We are a bit stricter here however. Specifically we deviate from POSIX rules:
* *
* - We require that names fit into the appropriate utmp field * - We require that names fit into the appropriate utmp field
* - We don't allow empty user names * - We don't allow empty user names
* - No dots or digits in the first character * - No dots in the first character
* *
* If strict==true, additionally: * If strict==true, additionally:
* - We don't allow any dots (this conflicts with chown syntax which permits dots as user/group name separator) * - We don't allow any dots (this conflicts with chown syntax which permits dots as user/group name separator)
* - We don't allow a digit as the first character
* *
* Note that other systems are even more restrictive, and don't permit underscores or uppercase characters. * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters.
*/ */
@ -720,17 +722,26 @@ bool valid_user_group_name_full(const char *u, bool strict) {
if (!(u[0] >= 'a' && u[0] <= 'z') && if (!(u[0] >= 'a' && u[0] <= 'z') &&
!(u[0] >= 'A' && u[0] <= 'Z') && !(u[0] >= 'A' && u[0] <= 'Z') &&
!(u[0] >= '0' && u[0] <= '9' && !strict) &&
u[0] != '_') u[0] != '_')
return false; return false;
bool warned = false; bool only_digits_seen = u[0] >= '0' && u[0] <= '9';
if (only_digits_seen) {
log_warning("User or group name \"%s\" starts with a digit, accepting for compatibility.", u);
warned = true;
}
for (i = u+1; *i; i++) { for (i = u+1; *i; i++) {
if (((*i >= 'a' && *i <= 'z') || if (((*i >= 'a' && *i <= 'z') ||
(*i >= 'A' && *i <= 'Z') || (*i >= 'A' && *i <= 'Z') ||
(*i >= '0' && *i <= '9') || (*i >= '0' && *i <= '9') ||
IN_SET(*i, '_', '-'))) IN_SET(*i, '_', '-'))) {
if (!(*i >= '0' && *i <= '9'))
only_digits_seen = false;
continue; continue;
}
if (*i == '.' && !strict) { if (*i == '.' && !strict) {
if (!warned) { if (!warned) {
@ -744,6 +755,9 @@ bool valid_user_group_name_full(const char *u, bool strict) {
return false; return false;
} }
if (only_digits_seen)
return false;
sz = sysconf(_SC_LOGIN_NAME_MAX); sz = sysconf(_SC_LOGIN_NAME_MAX);
assert_se(sz > 0); assert_se(sz > 0);

View File

@ -210,11 +210,13 @@ int unit_add_name(Unit *u, const char *text) {
if (unit_name_is_valid(text, UNIT_NAME_TEMPLATE)) { if (unit_name_is_valid(text, UNIT_NAME_TEMPLATE)) {
if (!u->instance) if (!u->instance)
return -EINVAL; return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EINVAL),
"instance is not set when adding name '%s': %m", text);
r = unit_name_replace_instance(text, u->instance, &s); r = unit_name_replace_instance(text, u->instance, &s);
if (r < 0) if (r < 0)
return r; return log_unit_debug_errno(u, r,
"failed to build instance name from '%s': %m", text);
} else { } else {
s = strdup(text); s = strdup(text);
if (!s) if (!s)
@ -224,36 +226,43 @@ int unit_add_name(Unit *u, const char *text) {
if (set_contains(u->names, s)) if (set_contains(u->names, s))
return 0; return 0;
if (hashmap_contains(u->manager->units, s)) if (hashmap_contains(u->manager->units, s))
return -EEXIST; return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EEXIST),
"unit already exist when adding name '%s': %m", text);
if (!unit_name_is_valid(s, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) if (!unit_name_is_valid(s, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
return -EINVAL; return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EINVAL),
"name '%s' is invalid: %m", text);
t = unit_name_to_type(s); t = unit_name_to_type(s);
if (t < 0) if (t < 0)
return -EINVAL; return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EINVAL),
"failed to to derive unit type from name '%s': %m", text);
if (u->type != _UNIT_TYPE_INVALID && t != u->type) if (u->type != _UNIT_TYPE_INVALID && t != u->type)
return -EINVAL; return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EINVAL),
"unit type is illegal: u->type(%d) and t(%d) for name '%s': %m",
u->type, t, text);
r = unit_name_to_instance(s, &i); r = unit_name_to_instance(s, &i);
if (r < 0) if (r < 0)
return r; return log_unit_debug_errno(u, r, "failed to extract instance from name '%s': %m", text);
if (i && !unit_type_may_template(t)) if (i && !unit_type_may_template(t))
return -EINVAL; return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EINVAL), "templates are not allowed for name '%s': %m", text);
/* Ensure that this unit is either instanced or not instanced, /* Ensure that this unit is either instanced or not instanced,
* but not both. Note that we do allow names with different * but not both. Note that we do allow names with different
* instance names however! */ * instance names however! */
if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i) if (u->type != _UNIT_TYPE_INVALID && !u->instance != !i)
return -EINVAL; return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EINVAL),
"instance is illegal: u->type(%d), u->instance(%s) and i(%s) for name '%s': %m",
u->type, u->instance, i, text);
if (!unit_type_may_alias(t) && !set_isempty(u->names)) if (!unit_type_may_alias(t) && !set_isempty(u->names))
return -EEXIST; return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EEXIST), "symlinks are not allowed for name '%s': %m", text);
if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES) if (hashmap_size(u->manager->units) >= MANAGER_MAX_NAMES)
return -E2BIG; return log_unit_debug_errno(u, SYNTHETIC_ERRNO(E2BIG), "too many units: %m");
r = set_put(u->names, s); r = set_put(u->names, s);
if (r < 0) if (r < 0)
@ -263,7 +272,7 @@ int unit_add_name(Unit *u, const char *text) {
r = hashmap_put(u->manager->units, s, u); r = hashmap_put(u->manager->units, s, u);
if (r < 0) { if (r < 0) {
(void) set_remove(u->names, s); (void) set_remove(u->names, s);
return r; return log_unit_debug_errno(u, r, "add unit to hashmap failed for name '%s': %m", text);
} }
if (u->type == _UNIT_TYPE_INVALID) { if (u->type == _UNIT_TYPE_INVALID) {

View File

@ -96,7 +96,7 @@ static void test_valid_user_group_name_compat(void) {
assert_se(valid_user_group_name_compat("eff.")); assert_se(valid_user_group_name_compat("eff."));
assert_se(valid_user_group_name_compat("some5")); assert_se(valid_user_group_name_compat("some5"));
assert_se(!valid_user_group_name_compat("5some")); assert_se(valid_user_group_name_compat("5some"));
assert_se(valid_user_group_name_compat("INNER5NUMBER")); assert_se(valid_user_group_name_compat("INNER5NUMBER"));
} }
@ -166,7 +166,7 @@ static void test_valid_user_group_name_or_id_compat(void) {
assert_se(valid_user_group_name_or_id_compat("kk-k")); assert_se(valid_user_group_name_or_id_compat("kk-k"));
assert_se(valid_user_group_name_or_id_compat("some5")); assert_se(valid_user_group_name_or_id_compat("some5"));
assert_se(!valid_user_group_name_or_id_compat("5some")); assert_se(valid_user_group_name_or_id_compat("5some"));
assert_se(valid_user_group_name_or_id_compat("INNER5NUMBER")); assert_se(valid_user_group_name_or_id_compat("INNER5NUMBER"));
} }

View File

@ -12,6 +12,7 @@ Description=Generate network units from Kernel command line
Documentation=man:systemd-network-generator.service(8) Documentation=man:systemd-network-generator.service(8)
DefaultDependencies=no DefaultDependencies=no
Before=network-pre.target Before=network-pre.target
Wants=network-pre.target
[Service] [Service]
Type=oneshot Type=oneshot
@ -19,4 +20,4 @@ RemainAfterExit=yes
ExecStart=@rootlibexecdir@/systemd-network-generator ExecStart=@rootlibexecdir@/systemd-network-generator
[Install] [Install]
WantedBy=network-pre.target WantedBy=sysinit.target