]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemctl: warn if units disabled in user scope are still enabled globally
authorMike Yuan <me@yhndnzj.com>
Sun, 12 Feb 2023 13:08:28 +0000 (21:08 +0800)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 22 Feb 2023 14:05:41 +0000 (23:05 +0900)
Fixes #18271

man/systemctl.xml
src/systemctl/systemctl-enable.c

index f32d2f23cf9c08c9c44f9e5f2d57c2b6959dd4ac..e0f499c41ea2a4cec99c331ad0d7b604fe6f9e99 100644 (file)
@@ -842,6 +842,11 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
             executed. This output may be suppressed by passing <option>--quiet</option>.
             </para>
 
+            <para>When this command is used with <option>--user</option>, the units being operated on might
+            still be enabled in global scope, and thus get started automatically even after a successful
+            disablement in user scope. In this case, a warning about it is shown, which can be suppressed
+            using <option>--no-warn</option>.</para>
+
             <para>This command honors <option>--system</option>, <option>--user</option>, <option>--runtime</option>,
             <option>--global</option> and <option>--no-warn</option> in a similar way as <command>enable</command>.</para>
           </listitem>
@@ -2045,7 +2050,11 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
             </listitem>
             <listitem>
               <para>when using <command>enable</command> or <command>disable</command> on units without
-              install information (i.e. don't have or have an empty [Install] section).</para>
+              install information (i.e. don't have or have an empty [Install] section),</para>
+            </listitem>
+            <listitem>
+              <para>when using <command>disable</command> combined with <option>--user</option> on units
+              that are enabled in global scope.</para>
             </listitem>
           </itemizedlist>
           </para>
index 86d9f602fa0c5493d9f9a3c402fec727020dff94..4ebe5888ac699ba9a6c51f6b30e246078e73b3a0 100644 (file)
@@ -263,6 +263,43 @@ int verb_enable(int argc, char *argv[], void *userdata) {
                            "  instance name specified.",
                            special_glyph(SPECIAL_GLYPH_BULLET));
 
+        if (streq(verb, "disable") && arg_scope == LOOKUP_SCOPE_USER && !arg_quiet && !arg_no_warn) {
+                /* If some of the units are disabled in user scope but still enabled in global scope,
+                 * we emit a warning for that. */
+
+                _cleanup_strv_free_ char **enabled_in_global_scope = NULL;
+
+                STRV_FOREACH(name, names) {
+                        UnitFileState state;
+
+                        r = unit_file_get_state(LOOKUP_SCOPE_GLOBAL, arg_root, *name, &state);
+                        if (r == -ENOENT)
+                                continue;
+                        if (r < 0)
+                                return log_error_errno(r, "Failed to get unit file state for %s: %m", *name);
+
+                        if (IN_SET(state, UNIT_FILE_ENABLED, UNIT_FILE_ENABLED_RUNTIME)) {
+                                r = strv_extend(&enabled_in_global_scope, *name);
+                                if (r < 0)
+                                        return log_oom();
+                        }
+                }
+
+                if (!strv_isempty(enabled_in_global_scope)) {
+                        _cleanup_free_ char *units = NULL;
+
+                        units = strv_join(enabled_in_global_scope, ", ");
+                        if (!units)
+                                return log_oom();
+
+                        log_notice("The following unit files have been enabled in global scope. This means\n"
+                                   "they will still be started automatically after a successful disablement\n"
+                                   "in user scope:\n"
+                                   "%s",
+                                   units);
+                }
+        }
+
         if (arg_now && STR_IN_SET(argv[0], "enable", "disable", "mask")) {
                 sd_bus *bus;
                 size_t len, i;