mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-02-04 17:47:03 +03:00
commit
1af1c95e30
@ -163,26 +163,37 @@ int null_or_empty_fd(int fd) {
|
||||
return null_or_empty(&st);
|
||||
}
|
||||
|
||||
int path_is_read_only_fs(const char *path) {
|
||||
static int fd_is_read_only_fs(int fd) {
|
||||
struct statvfs st;
|
||||
|
||||
assert(path);
|
||||
assert(fd >= 0);
|
||||
|
||||
if (statvfs(path, &st) < 0)
|
||||
if (fstatvfs(fd, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (st.f_flag & ST_RDONLY)
|
||||
return true;
|
||||
|
||||
/* On NFS, statvfs() might not reflect whether we can actually
|
||||
* write to the remote share. Let's try again with
|
||||
* access(W_OK) which is more reliable, at least sometimes. */
|
||||
if (access(path, W_OK) < 0 && errno == EROFS)
|
||||
/* On NFS, fstatvfs() might not reflect whether we can actually write to the remote share. Let's try
|
||||
* again with access(W_OK) which is more reliable, at least sometimes. */
|
||||
if (access_fd(fd, W_OK) == -EROFS)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int path_is_read_only_fs(const char *path) {
|
||||
_cleanup_close_ int fd = -EBADFD;
|
||||
|
||||
assert(path);
|
||||
|
||||
fd = open(path, O_CLOEXEC | O_PATH);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
return fd_is_read_only_fs(fd);
|
||||
}
|
||||
|
||||
int files_same(const char *filea, const char *fileb, int flags) {
|
||||
struct stat a, b;
|
||||
|
||||
|
@ -190,6 +190,18 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int binfmt_mounted_warn(void) {
|
||||
int r;
|
||||
|
||||
r = binfmt_mounted();
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to check if /proc/sys/fs/binfmt_misc is mounted: %m");
|
||||
if (r == 0)
|
||||
log_debug("/proc/sys/fs/binfmt_misc is not mounted in read-write mode, skipping.");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
int r, k;
|
||||
|
||||
@ -206,13 +218,17 @@ static int run(int argc, char *argv[]) {
|
||||
if (arg_unregister)
|
||||
return disable_binfmt();
|
||||
|
||||
if (argc > optind)
|
||||
if (argc > optind) {
|
||||
r = binfmt_mounted_warn();
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
for (int i = optind; i < argc; i++) {
|
||||
k = apply_file(argv[i], false);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
_cleanup_strv_free_ char **files = NULL;
|
||||
|
||||
r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) CONF_PATHS_STRV("binfmt.d"));
|
||||
@ -225,6 +241,10 @@ static int run(int argc, char *argv[]) {
|
||||
return cat_files(NULL, files, 0);
|
||||
}
|
||||
|
||||
r = binfmt_mounted_warn();
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
/* Flush out all rules */
|
||||
r = write_string_file("/proc/sys/fs/binfmt_misc/status", "-1", WRITE_STRING_FILE_DISABLE_BUFFER);
|
||||
if (r < 0)
|
||||
|
@ -5,10 +5,30 @@
|
||||
#include <sys/vfs.h>
|
||||
|
||||
#include "binfmt-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "missing_magic.h"
|
||||
#include "stat-util.h"
|
||||
|
||||
int binfmt_mounted(void) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
int r;
|
||||
|
||||
fd = RET_NERRNO(open("/proc/sys/fs/binfmt_misc", O_CLOEXEC | O_DIRECTORY | O_PATH));
|
||||
if (fd == -ENOENT)
|
||||
return false;
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
r = fd_is_fs_type(fd, BINFMTFS_MAGIC);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
return access_fd(fd, W_OK) >= 0;
|
||||
}
|
||||
|
||||
int disable_binfmt(void) {
|
||||
int r;
|
||||
|
||||
@ -18,13 +38,13 @@ int disable_binfmt(void) {
|
||||
* 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;
|
||||
}
|
||||
r = binfmt_mounted();
|
||||
if (r < 0)
|
||||
return log_warning_errno(r, "Failed to determine whether binfmt_misc is mounted: %m");
|
||||
if (r == 0) {
|
||||
log_debug("binfmt_misc is not mounted in read-write mode, not detaching entries.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = write_string_file("/proc/sys/fs/binfmt_misc/status", "-1", WRITE_STRING_FILE_DISABLE_BUFFER);
|
||||
if (r < 0)
|
||||
|
@ -1,4 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
int binfmt_mounted(void);
|
||||
int disable_binfmt(void);
|
||||
|
@ -18,7 +18,7 @@ After=proc-sys-fs-binfmt_misc.automount
|
||||
After=proc-sys-fs-binfmt_misc.mount
|
||||
After=local-fs.target
|
||||
Before=sysinit.target shutdown.target
|
||||
ConditionPathIsReadWrite=/proc/sys/
|
||||
ConditionPathIsMountPoint=/proc/sys/fs/binfmt_misc
|
||||
ConditionDirectoryNotEmpty=|/lib/binfmt.d
|
||||
ConditionDirectoryNotEmpty=|/usr/lib/binfmt.d
|
||||
ConditionDirectoryNotEmpty=|/usr/local/lib/binfmt.d
|
||||
|
Loading…
x
Reference in New Issue
Block a user