]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Added option --check-inhibitors for non-tty usage
authorFelix Stupp <felix.stupp@outlook.com>
Thu, 29 Oct 2020 11:48:48 +0000 (12:48 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 13 Jan 2021 15:07:36 +0000 (16:07 +0100)
As described in #2680, systemctl did ignore inhibitors if it is not
attached to a tty to allow scripts to ignore inhibitors automatically.
This pull request preserves this behavior but allows scripts to
explicit check inhibitors if required.

The new parameter '--check-inhibitors=yes' enables this feature.
The old parameter '-i'/'--ignore-inhibitors' was deprecated in favor
of '--check-inhibitors=no', the default behaviour can be specified
with '--check-inhibitors=auto'.
The new parameter is also described in the documentations and shell
completions found here.

man/systemctl.xml
shell-completion/bash/systemctl.in
shell-completion/zsh/_systemctl.in
src/systemctl/systemctl-logind.c
src/systemctl/systemctl.c
src/systemctl/systemctl.h

index 27207fcf49f1802db3d01bba716caff3bc82cb47..b512f4a8b8516a58f67204f214405fba1dd39ec9 100644 (file)
@@ -1848,18 +1848,35 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--check-inhibitors=</option></term>
+
+        <listitem>
+          <para>When system shutdown or sleep state is request, this option controls how to deal with
+          inhibitor locks. It takes one of <literal>auto</literal>, <literal>yes</literal> or
+          <literal>no</literal>. Defaults to <literal>auto</literal>, which will behave like
+          <literal>yes</literal> for interactive invocations (i.e. from a TTY) and <literal>no</literal>
+          for non-interactive invocations.
+          <literal>yes</literal> will let the request respect inhibitor locks.
+          <literal>no</literal> will let the request ignore inhibitor locks.
+          </para>
+          <para>Applications can establish inhibitor locks to avoid that certain important operations
+          (such as CD burning or suchlike) are interrupted by system shutdown or a sleep state. Any user may
+          take these locks and privileged users may override these locks.
+          If any locks are taken, shutdown and sleep state requests will normally fail (unless privileged)
+          and a list of active locks is printed.
+          However, if <literal>no</literal> is specified or <literal>auto</literal> is specified on a
+          non-interactive requests, the established locks are ignored and not shown, and the operation
+          attempted anyway, possibly requiring additional privileges.
+          May be overriden by <option>--force</option>.</para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>-i</option></term>
-        <term><option>--ignore-inhibitors</option></term>
 
         <listitem>
-          <para>When system shutdown or a sleep state is requested, ignore inhibitor locks. Applications can establish
-          inhibitor locks to avoid that certain important operations (such as CD burning or suchlike) are interrupted
-          by system shutdown or a sleep state. Any user may take these locks and privileged users may override these
-          locks. If any locks are taken, shutdown and sleep state requests will normally fail (unless privileged) and a
-          list of active locks is printed. However, if <option>--ignore-inhibitors</option> is specified, the
-          established locks are ignored and not shown, and the operation attempted anyway, possibly requiring
-          additional privileges.</para>
+          <para>Shortcut for <option>--check-inhibitors=no</option>.</para>
         </listitem>
       </varlistentry>
 
index b26381a324b5b541ce0ef4708a1d7124562f21a1..4bd80948d6449734a1cfc2ed8a7df5fd304392b5 100644 (file)
@@ -125,9 +125,9 @@ _systemctl () {
         [STANDALONE]='--all -a --reverse --after --before --defaults --force -f --full -l --global
                              --help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall --now
                              --quiet -q --system --user --version --runtime --recursive -r --firmware-setup
-                             --show-types -i --ignore-inhibitors --plain --failed --value --fail --dry-run --wait'
+                             --show-types --plain --failed --value --fail --dry-run --wait'
         [ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --job-mode --root
-                             --preset-mode -n --lines -o --output -M --machine --message --timestamp'
+                             --preset-mode -n --lines -o --output -M --machine --message --timestamp --check-inhibitors'
     )
 
     if __contains_word "--user" ${COMP_WORDS[*]}; then
@@ -179,6 +179,9 @@ _systemctl () {
             --timestamp)
                 comps='pretty us µs utc us+utc µs+utc'
                 ;;
+            --check-inhibitors)
+                comps='auto yes no'
+                ;;
         esac
         COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
         return 0
index 22c40898e34dfd0f47ff9873ba13c0b82636dba0..10af6d5121e91e4d725406ce574f0304f676f2c0 100644 (file)
@@ -443,6 +443,13 @@ done
         _values -s , "${_styles[@]}"
     }
 
+(( $+functions[_systemctl_check_inhibitors] )) ||
+    _systemctl_check_inhibitors() {
+        local -a _modes
+        _modes=(auto yes no)
+        _values -s , "${_modes[@]}"
+    }
+
 # Build arguments for "systemctl" to be used in completion.
 local -a _modes; _modes=("--user" "--system")
 # Use the last mode (they are exclusive and the last one is used).
@@ -460,7 +467,7 @@ _arguments -s \
     '--before[Show units ordered before]' \
     {-l,--full}"[Don't ellipsize unit names on output]" \
     '--show-types[When showing sockets, show socket type]' \
-    {-i,--ignore-inhibitors}'[When executing a job, ignore jobs dependencies]' \
+    '--check-inhibitors[Specify if inhibitors should be checked]:mode:_systemctl_check_inhibitors' \
     {-q,--quiet}'[Suppress output]' \
     '--no-block[Do not wait until operation finished]' \
     '--no-legend[Do not print a legend, i.e. the column headers and the footer with hints]' \
index 405f12a33d930a3653a689ddce2cc6823ecabb13..4070c6425770229ad663b0b11d8974ac8346bed8 100644 (file)
@@ -96,17 +96,19 @@ int logind_check_inhibitors(enum action a) {
         char **s;
         int r;
 
-        if (arg_ignore_inhibitors || arg_force > 0)
+        if (arg_check_inhibitors == 0 || arg_force > 0)
                 return 0;
 
         if (arg_when > 0)
                 return 0;
 
-        if (geteuid() == 0)
-                return 0;
+        if (arg_check_inhibitors < 0) {
+                if (geteuid() == 0)
+                        return 0;
 
-        if (!on_tty())
-                return 0;
+                if (!on_tty())
+                        return 0;
+        }
 
         if (arg_transport != BUS_TRANSPORT_LOCAL)
                 return 0;
index 7fe1e4e65b478048861bb57257b151e80aa6f869..7471fadd91308f190ced597d7c4fa786cabd7e18 100644 (file)
@@ -74,7 +74,7 @@ bool arg_no_wall = false;
 bool arg_no_reload = false;
 bool arg_value = false;
 bool arg_show_types = false;
-bool arg_ignore_inhibitors = false;
+int arg_check_inhibitors = -1;
 bool arg_dry_run = false;
 bool arg_quiet = false;
 bool arg_full = false;
@@ -241,7 +241,10 @@ static int systemctl_help(void) {
                "  -T --show-transaction  When enqueuing a unit job, show full transaction\n"
                "     --show-types        When showing sockets, explicitly show their type\n"
                "     --value             When showing properties, only print the value\n"
-               "  -i --ignore-inhibitors When shutting down or sleeping, ignore inhibitors\n"
+               "     --check-inhibitors=MODE\n"
+               "                         Specify if checking inhibitors before shutting down,\n"
+               "                         sleeping or hibernating\n"
+               "  -i                     Shortcut for --check-inhibitors=no\n"
                "     --kill-who=WHO      Whom to send signal to\n"
                "  -s --signal=SIGNAL     Which signal to send\n"
                "     --what=RESOURCES    Which types of resources to remove\n"
@@ -364,6 +367,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 ARG_REVERSE,
                 ARG_AFTER,
                 ARG_BEFORE,
+                ARG_CHECK_INHIBITORS,
                 ARG_DRY_RUN,
                 ARG_SHOW_TYPES,
                 ARG_IRREVERSIBLE,
@@ -415,7 +419,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 { "fail",                no_argument,       NULL, ARG_FAIL                }, /* compatibility only */
                 { "irreversible",        no_argument,       NULL, ARG_IRREVERSIBLE        }, /* compatibility only */
                 { "ignore-dependencies", no_argument,       NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
-                { "ignore-inhibitors",   no_argument,       NULL, 'i'                     },
+                { "ignore-inhibitors",   no_argument,       NULL, 'i'                     }, /* compatibility only */
+                { "check-inhibitors",    required_argument, NULL, ARG_CHECK_INHIBITORS    },
                 { "value",               no_argument,       NULL, ARG_VALUE               },
                 { "user",                no_argument,       NULL, ARG_USER                },
                 { "system",              no_argument,       NULL, ARG_SYSTEM              },
@@ -716,7 +721,18 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'i':
-                        arg_ignore_inhibitors = true;
+                        arg_check_inhibitors = 0;
+                        break;
+
+                case ARG_CHECK_INHIBITORS:
+                        if (streq(optarg, "auto"))
+                                arg_check_inhibitors = -1;
+                        else {
+                                r = parse_boolean(optarg);
+                                if (r < 0)
+                                        return log_error_errno(r, "Failed to parse --check-inhibitors= argument: %s", optarg);
+                                arg_check_inhibitors = r;
+                        }
                         break;
 
                 case ARG_PLAIN:
index f8cefc9b0128a5104f92cf1cdab02c4a4e2b7292..cdf56c72208197c180d239121d2fea433792fd71 100644 (file)
@@ -59,7 +59,7 @@ extern bool arg_no_wall;
 extern bool arg_no_reload;
 extern bool arg_value;
 extern bool arg_show_types;
-extern bool arg_ignore_inhibitors;
+extern int arg_check_inhibitors;
 extern bool arg_dry_run;
 extern bool arg_quiet;
 extern bool arg_full;