mirror of
https://github.com/systemd/systemd.git
synced 2024-12-25 01:34:28 +03:00
Merge pull request #15566 from poettering/destroy-binfmt
unregister binary formats during shutdown
This commit is contained in:
commit
bf39cb7b92
@ -41,6 +41,14 @@
|
||||
|
||||
<refsect1><title>Options</title>
|
||||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--unregister</option></term>
|
||||
<listitem><para>If passed, instead of registering configured binary formats in the kernel, the
|
||||
reverse operation is executed: all currently registered binary formats are unregistered from the
|
||||
kernel.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="cat-config" />
|
||||
<xi:include href="standard-options.xml" xpointer="no-pager" />
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
|
@ -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;
|
||||
@ -32,18 +34,17 @@ static int delete_rule(const char *rule) {
|
||||
assert(rule);
|
||||
assert(rule[0]);
|
||||
|
||||
x = strdup(rule);
|
||||
e = strchrnul(rule + 1, rule[0]);
|
||||
x = strndup(rule + 1, e - rule - 1);
|
||||
if (!x)
|
||||
return log_oom();
|
||||
|
||||
e = strchrnul(x+1, x[0]);
|
||||
*e = 0;
|
||||
|
||||
if (!filename_is_valid(x + 1))
|
||||
if (!filename_is_valid(x) ||
|
||||
STR_IN_SET(x, "register", "status"))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Rule file name '%s' is not valid, refusing.", x + 1);
|
||||
"Rule file name '%s' is not valid, refusing.", x);
|
||||
|
||||
fn = path_join("/proc/sys/fs/binfmt_misc", x+1);
|
||||
fn = path_join("/proc/sys/fs/binfmt_misc", x);
|
||||
if (!fn)
|
||||
return log_oom();
|
||||
|
||||
@ -116,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
|
||||
@ -129,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[] = {
|
||||
@ -136,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 },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -162,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;
|
||||
|
||||
@ -169,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;
|
||||
}
|
||||
@ -189,6 +197,9 @@ static int run(int argc, char *argv[]) {
|
||||
|
||||
r = 0;
|
||||
|
||||
if (arg_unregister)
|
||||
return disable_binfmt();
|
||||
|
||||
if (argc > optind) {
|
||||
int i;
|
||||
|
||||
|
33
src/shared/binfmt-util.c
Normal file
33
src/shared/binfmt-util.c
Normal file
@ -0,0 +1,33 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/vfs.h>
|
||||
|
||||
#include "binfmt-util.h"
|
||||
#include "fileio.h"
|
||||
#include "missing_magic.h"
|
||||
#include "stat-util.h"
|
||||
|
||||
int disable_binfmt(void) {
|
||||
int r;
|
||||
|
||||
/* Flush out all rules. This is important during shutdown to cover for rules using "F", since those
|
||||
* might pin a file and thus block us from unmounting stuff cleanly.
|
||||
*
|
||||
* We are a bit careful here, since binfmt_misc might still be an autofs which we don't want to
|
||||
* trigger. */
|
||||
|
||||
r = path_is_fs_type("/proc/sys/fs/binfmt_misc", BINFMTFS_MAGIC);
|
||||
if (r == 0 || r == -ENOENT) {
|
||||
log_debug("binfmt_misc is not mounted, not detaching entries.");
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to determine whether binfmt_misc is mounted: %m");
|
||||
|
||||
r = write_string_file("/proc/sys/fs/binfmt_misc/status", "-1", WRITE_STRING_FILE_DISABLE_BUFFER);
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to unregister binfmt_misc entries: %m");
|
||||
|
||||
log_debug("Unregistered all remaining binfmt_misc entries.");
|
||||
return 0;
|
||||
}
|
4
src/shared/binfmt-util.h
Normal file
4
src/shared/binfmt-util.h
Normal file
@ -0,0 +1,4 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
int disable_binfmt(void);
|
@ -12,6 +12,8 @@ shared_sources = files('''
|
||||
barrier.h
|
||||
base-filesystem.c
|
||||
base-filesystem.h
|
||||
binfmt-util.c
|
||||
binfmt-util.h
|
||||
bitmap.c
|
||||
bitmap.h
|
||||
blkid-util.h
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "async.h"
|
||||
#include "binfmt-util.h"
|
||||
#include "cgroup-setup.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "def.h"
|
||||
@ -386,6 +387,7 @@ int main(int argc, char *argv[]) {
|
||||
sync_with_progress();
|
||||
|
||||
disable_coredumps();
|
||||
disable_binfmt();
|
||||
|
||||
log_info("Sending SIGTERM to remaining processes...");
|
||||
broadcast_signal(SIGTERM, true, true, arg_timeout);
|
||||
|
@ -28,4 +28,5 @@ ConditionDirectoryNotEmpty=|/run/binfmt.d
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=@rootlibexecdir@/systemd-binfmt
|
||||
ExecStop=@rootlibexecdir@/systemd-binfmt --unregister
|
||||
TimeoutSec=90s
|
||||
|
Loading…
Reference in New Issue
Block a user