binfmt: also unregister binfmt entries from unit

We unregister binfmt_misc twice during shutdown with this change:

1. A previous commit added support for doing that in the final shutdown
   phase, i.e. when we do the aggressive umount loop. This is the robust
   thing to do, in case the earlier ("clean") shutdown phase didn't work
   for some reason.

2. This commit adds support for doing that when systemd-binfmt.service
   is stopped. This is a good idea so that people can order mounts
   before the service if they want to register binaries from such
   mounts, as in that case we'll undo the registration on shutdown
   again, before unmounting those mounts.

And all that, just because of that weird "F" flag the kernel introduced
that can pin files...

Fixes: #14981
This commit is contained in:
Lennart Poettering 2020-04-23 16:36:45 +02:00
parent f3670df13e
commit 846acb6798
2 changed files with 15 additions and 2 deletions

View File

@ -10,6 +10,7 @@
#include <sys/types.h>
#include "alloc-util.h"
#include "binfmt-util.h"
#include "conf-files.h"
#include "def.h"
#include "fd-util.h"
@ -24,6 +25,7 @@
static bool arg_cat_config = false;
static PagerFlags arg_pager_flags = 0;
static bool arg_unregister = false;
static int delete_rule(const char *rule) {
_cleanup_free_ char *x = NULL, *fn = NULL;
@ -115,6 +117,7 @@ static int help(void) {
" --version Show package version\n"
" --cat-config Show configuration files\n"
" --no-pager Do not pipe output into a pager\n"
" --unregister Unregister all existing entries\n"
"\nSee the %s for details.\n"
, program_invocation_short_name
, link
@ -128,6 +131,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_VERSION = 0x100,
ARG_CAT_CONFIG,
ARG_NO_PAGER,
ARG_UNREGISTER,
};
static const struct option options[] = {
@ -135,6 +139,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "version", no_argument, NULL, ARG_VERSION },
{ "cat-config", no_argument, NULL, ARG_CAT_CONFIG },
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "unregister", no_argument, NULL, ARG_UNREGISTER },
{}
};
@ -161,6 +166,10 @@ static int parse_argv(int argc, char *argv[]) {
arg_pager_flags |= PAGER_DISABLE;
break;
case ARG_UNREGISTER:
arg_unregister = true;
break;
case '?':
return -EINVAL;
@ -168,9 +177,9 @@ static int parse_argv(int argc, char *argv[]) {
assert_not_reached("Unhandled option");
}
if (arg_cat_config && argc > optind)
if ((arg_unregister || arg_cat_config) && argc > optind)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Positional arguments are not allowed with --cat-config");
"Positional arguments are not allowed with --cat-config or --unregister");
return 1;
}
@ -188,6 +197,9 @@ static int run(int argc, char *argv[]) {
r = 0;
if (arg_unregister)
return disable_binfmt();
if (argc > optind) {
int i;

View File

@ -28,4 +28,5 @@ ConditionDirectoryNotEmpty=|/run/binfmt.d
Type=oneshot
RemainAfterExit=yes
ExecStart=@rootlibexecdir@/systemd-binfmt
ExecStop=@rootlibexecdir@/systemd-binfmt --unregister
TimeoutSec=90s