]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
run: make custom slice imply XDG_SESSION_CLASS=none
authorRonan Pigott <ronan@rjp.ie>
Wed, 17 Jun 2026 19:36:16 +0000 (12:36 -0700)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 28 Jun 2026 04:48:02 +0000 (13:48 +0900)
--slice and --slice-inherit are intended to make the new service unit
part of a specific slice. Logind is incompatible with that goal, as a
session of any kind will prompt logind to immediately yoink the new
command from the service unit into a new session scope, which does not
inherit from run0's own slice. The use can still explicitly request a
session with --setenv=XDG_SESSION_CLASS=<class>.

Also make --slice and --slice-inherit conflict with --lightweight and
--area, which depend on logind to be effective.

man/run0.xml
src/run/run.c

index fee0e08a5e11301e0f05130e433e02969760b38e..c2e891149f0eb7c2777081f40896923f5d1c51a6 100644 (file)
         <term><option>--slice=</option></term>
 
         <listitem><para>Make the new <filename>.service</filename> unit part of the specified slice, instead
-        of <filename>user.slice</filename>.</para>
+        of <filename>user.slice</filename>. This option conflicts with <option>--lightweight=</option> and
+        <option>--area=</option>, and implies <literal>XDG_SESSION_CLASS=none</literal>,
+        to keep the new process within the specified slice instead of a new session scope.</para>
 
         <xi:include href="version-info.xml" xpointer="v256"/>
         </listitem>
         <listitem><para>Make the new <filename>.service</filename> unit part of the slice the
         <command>run0</command> itself has been invoked in. This option may be combined with
         <option>--slice=</option>, in which case the slice specified via <option>--slice=</option> is placed
-        within the slice the <command>run0</command> command is invoked in.</para>
+        within the slice the <command>run0</command> command is invoked in. Also conflicts with
+        <option>--lightweight=</option> and <option>--area=</option> and implies
+        <literal>XDG_SESSION_CLASS=none</literal>, similar to <option>--slice=</option>.</para>
 
         <para>Example: consider <command>run0</command> being invoked in the slice
         <filename>foo.slice</filename>, and the <option>--slice=</option> argument is
index f7dc5b56708a8771989f4e3158b7e5a7596b66f7..2e37a0a2f63f3279c376a6b3af9c9be7c8ab48bc 100644 (file)
@@ -992,6 +992,14 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
 
         _cleanup_strv_free_ char **l = NULL;
         char **args = option_parser_get_args(&opts);
+        bool custom_slice = arg_slice_inherit || arg_slice;
+        if (custom_slice && arg_lightweight >= 0)
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                "--lightweight= may not be combined with a custom slice");
+        if (custom_slice && !isempty(arg_area))
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                "--area= may not be combined with a custom slice");
+
         if (!strv_isempty(args)) {
                 if (arg_validate)
                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
@@ -1108,9 +1116,12 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
         }
 
         if (!strv_env_get(arg_environment, "XDG_SESSION_CLASS")) {
+                const char *class = NULL;
+                if (custom_slice)
+                        class = "none";
 
                 /* If logging into an area, imply lightweight mode */
-                if (arg_lightweight < 0 && !isempty(arg_area))
+                else if (arg_lightweight < 0 && !isempty(arg_area))
                         arg_lightweight = true;
 
                 /* When using run0 to acquire privileges temporarily, let's not pull in session manager by
@@ -1120,14 +1131,14 @@ static int parse_argv_sudo_mode(int argc, char *argv[]) {
                  * this for root or --empower though, under the assumption that if a regular user temporarily
                  * transitions into another regular user it's a better default that the full user environment is
                  * uniformly available. */
-                if (arg_lightweight < 0 && (become_root() || arg_empower))
+                else if (arg_lightweight < 0 && (become_root() || arg_empower))
                         arg_lightweight = true;
 
-                if (arg_lightweight >= 0) {
-                        const char *class =
-                                arg_lightweight ? (arg_stdio == ARG_STDIO_PTY ? (become_root() ? "user-early-light" : "user-light") : "background-light") :
+                if (arg_lightweight >= 0)
+                        class = arg_lightweight ? (arg_stdio == ARG_STDIO_PTY ? (become_root() ? "user-early-light" : "user-light") : "background-light") :
                                                   (arg_stdio == ARG_STDIO_PTY ? (become_root() ? "user-early" : "user") : "background");
 
+                if (class) {
                         log_debug("Setting XDG_SESSION_CLASS to '%s'.", class);
 
                         r = strv_env_assign(&arg_environment, "XDG_SESSION_CLASS", class);