1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-28 02:50:16 +03:00

Added option --check-inhibitors for non-tty usage

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.
This commit is contained in:
Felix Stupp 2020-10-29 12:48:48 +01:00 committed by Lennart Poettering
parent 65ab27211c
commit 4327574fc1
6 changed files with 67 additions and 22 deletions

View File

@ -1849,17 +1849,34 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
</varlistentry>
<varlistentry>
<term><option>-i</option></term>
<term><option>--ignore-inhibitors</option></term>
<term><option>--check-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>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>
<listitem>
<para>Shortcut for <option>--check-inhibitors=no</option>.</para>
</listitem>
</varlistentry>

View 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

View 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]' \

View 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;

View 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:

View 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;