1
0
mirror of https://github.com/systemd/systemd synced 2025-10-05 11:44:45 +02:00

Compare commits

...

8 Commits

Author SHA1 Message Date
Yu Watanabe
706e622e88 include: update kernel headers from v6.16-rc7
- netfilter changes in v6.16-rc1 were reverted,
- vm_sockets.h now includes sys/socket.h, hence our workaround is not
  necessary anymore.
2025-07-27 23:50:06 +01:00
Luca Boccassi
bef244392b stub: fix passing kernel cmdline when loading via shim
This was mistakenly dropped when the custom PE loader was added.
Add it back, otherwise no smbios/addon cmdline options are passed
through.

Fixes https://github.com/systemd/systemd/issues/38349

Follow-up for 40aabfae72619e313f8bcc038e57e0d3a5433d1a
2025-07-27 22:44:05 +01:00
Yu Watanabe
4fb09adec4
Rework file system group magic lookups (#38340) 2025-07-28 03:39:34 +09:00
Yu Watanabe
7292d676d0 test: skip verification for racy test cases
FORMAT_LIFETIME() internally calls now(), hence we cannot provide any
reliable verifications for finite lifetime.
2025-07-28 03:37:31 +09:00
Zbigniew Jędrzejewski-Szmek
aca4353ab2 Rework file system group lookups
We want to check if the magic we got from statfs() is one of the magics listed
for one of the file systems in the given group. To do this, we'd iteratate over
the file system names, convert each name to an array of magics, and compare
those to the one we got. We were using gperf-generated lookup table for this,
so the string lookups were quick, but still this seems unnecessarily complex.
Let's just generate a simple lookup function, because we can:

$ src/basic/filesystem-sets.py fs-in-group
bool fs_in_group(const struct statfs *st, FilesystemGroups fs_group) {
        switch (fs_group) {
        case FILESYSTEM_SET_BASIC_API:
                return F_TYPE_EQUAL(st->f_type, CGROUP2_SUPER_MAGIC)
                    || F_TYPE_EQUAL(st->f_type, CGROUP_SUPER_MAGIC)
                    || F_TYPE_EQUAL(st->f_type, DEVPTS_SUPER_MAGIC)
                    || F_TYPE_EQUAL(st->f_type, MQUEUE_MAGIC)
                    || F_TYPE_EQUAL(st->f_type, PROC_SUPER_MAGIC)
                    || F_TYPE_EQUAL(st->f_type, SYSFS_MAGIC)
                    || F_TYPE_EQUAL(st->f_type, TMPFS_MAGIC);
        case FILESYSTEM_SET_ANONYMOUS:
                return F_TYPE_EQUAL(st->f_type, ANON_INODE_FS_MAGIC)
                    || F_TYPE_EQUAL(st->f_type, PIPEFS_MAGIC)
                    || F_TYPE_EQUAL(st->f_type, SOCKFS_MAGIC);
...

We flatten the nested lookup of group=>fs=>magic into a single level.
The compiler can work its magic here to make the lookup quick.
2025-07-27 13:14:05 +02:00
Zbigniew Jędrzejewski-Szmek
b0123576f4 meson: rework generation of file system lookup helpers
Previously, the gperf table was the main "source of truth", and additional
information (e.g. which file system names are obsolete) was scattered in
various files. We would then parse the gperf file, using python, awk, grep, and
bash, and use the results in various ways. This is hard to understand and
maintain. Let's replace all of this with a single python script that generates
the requested outputs as appropriate.

$ diff -u <(git show @{u}:src/basic/filesystems-gperf.gperf) \
          <(src/basic/filesystem-sets.py gperf)
shows that the outputs are the same except for comments.

Similarly, 'src/basic/filesystem-sets.py fs-type-to-string' and
'src/basic/filesystem-sets.py filesystem-sets' can be used to view
the generated code.

The check that the kernel doesn't define any new file system magics is
converted into a normal test. It doesn't seem necessary to fail the build
when that happens.
2025-07-27 13:13:54 +02:00
Zbigniew Jędrzejewski-Szmek
c136be3f04 basic/stat-util: avoid access syscall
I was looking at strace for systemd-getty-generator and noticed the call to
faccessat2(3</sys>, "", W_OK, AT_EMPTY_PATH), even though we already did
fstatfs(3</sys>), which should give us all the necessary information. Let's
only do this additional check when it's likely to yield something useful, i.e.
for network fses and otherwise skip the syscall.

The call to statvfs is replaced by statfs because that gives us the .f_type
field and allows is_network_fs() to be called.

I'm a bit worried that the is_network_fs() is somewhat costly. This will be
improved in later commits.
2025-07-27 13:13:43 +02:00
Zbigniew Jędrzejewski-Szmek
9154cc7e80 getty-generator: improve debugging messages
We generally log what happens, but we didn't log anything about checking credentials,
so add that.

The error message when we cannot acces /proc/1/environ was confusing.
2025-07-25 14:04:17 +02:00
15 changed files with 424 additions and 441 deletions

View File

@ -1,31 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -eu
set -o pipefail
cpp="${1:?}"
filesystems_gperf="${2:?}"
shift 2
error=false
# shellcheck disable=SC2086
for fs in $($cpp -dM -include linux/magic.h "$@" - </dev/null | \
grep -E '_MAGIC' | \
grep -vE 'LINUX_MAGIC' | \
awk '/^#define[ \t]+[A-Z0-9_]+MAGIC[ \t]+/ { print $2; }'); do
if ! grep -E "\{.*$fs.*\}" "$filesystems_gperf" >/dev/null; then
# STACK_END_MAGIC doesn't refer to a filesystem
# mtd_inode was removed in 2015
# futexfs was removed in 2018
if [[ "$fs" =~ ^(STACK_END_MAGIC|MTD_INODE_FS_MAGIC|FUTEXFS_SUPER_MAGIC)$ ]]; then
continue
fi
echo "Filesystem found in kernel header but not in $(basename "$filesystems_gperf"): $fs";
error=true
fi
done
if $error; then
exit 1
fi

371
src/basic/filesystem-sets.py Executable file
View File

@ -0,0 +1,371 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: LGPL-2.1-or-later
import os
import subprocess
import sys
NAME_TO_MAGIC = {
'apparmorfs': ['AAFS_MAGIC'],
'adfs': ['ADFS_SUPER_MAGIC'],
'affs': ['AFFS_SUPER_MAGIC'],
'afs': ['AFS_FS_MAGIC',
'AFS_SUPER_MAGIC'],
'anon_inodefs': ['ANON_INODE_FS_MAGIC'],
'autofs': ['AUTOFS_SUPER_MAGIC'],
'balloon-kvm': ['BALLOON_KVM_MAGIC'],
'bcachefs': ['BCACHEFS_SUPER_MAGIC'],
'bdev': ['BDEVFS_MAGIC'],
'binder': ['BINDERFS_SUPER_MAGIC'],
'binfmt_misc': ['BINFMTFS_MAGIC'],
'bpf': ['BPF_FS_MAGIC'],
'btrfs': ['BTRFS_SUPER_MAGIC'],
'btrfs_test_fs': ['BTRFS_TEST_MAGIC'],
# cpuset's magic got reassigned to cgroupfs
'cpuset': ['CGROUP_SUPER_MAGIC'],
'ceph': ['CEPH_SUPER_MAGIC'],
'cgroup2': ['CGROUP2_SUPER_MAGIC'],
# note that the cgroupfs magic got reassigned from cpuset
'cgroup': ['CGROUP_SUPER_MAGIC'],
'cifs': ['CIFS_SUPER_MAGIC',
'SMB2_SUPER_MAGIC'],
'coda': ['CODA_SUPER_MAGIC'],
'configfs': ['CONFIGFS_MAGIC'],
'cramfs': ['CRAMFS_MAGIC'],
'dax': ['DAXFS_MAGIC'],
'debugfs': ['DEBUGFS_MAGIC'],
'devmem': ['DEVMEM_MAGIC'],
'devpts': ['DEVPTS_SUPER_MAGIC'],
# devtmpfs is just a special instance of tmpfs, hence it reports its magic
'devtmpfs': ['TMPFS_MAGIC'],
'dmabuf': ['DMA_BUF_MAGIC'],
'ecryptfs': ['ECRYPTFS_SUPER_MAGIC'],
'efivarfs': ['EFIVARFS_MAGIC'],
'efs': ['EFS_SUPER_MAGIC'],
'erofs': ['EROFS_SUPER_MAGIC_V1'],
# ext2 + ext3 + ext4 use the same magic
'ext2': ['EXT2_SUPER_MAGIC'],
'ext3': ['EXT3_SUPER_MAGIC'],
'ext4': ['EXT4_SUPER_MAGIC'],
'exfat': ['EXFAT_SUPER_MAGIC'],
'f2fs': ['F2FS_SUPER_MAGIC'],
# fuseblk is so closely related to fuse that it shares the same magic
'fuseblk': ['FUSE_SUPER_MAGIC'],
'fuse': ['FUSE_SUPER_MAGIC'],
'fusectl': ['FUSE_CTL_SUPER_MAGIC'],
# gfs is an old version of gfs2 and reuses the magic
'gfs': ['GFS2_MAGIC'],
'gfs2': ['GFS2_MAGIC'],
'hostfs': ['HOSTFS_SUPER_MAGIC'],
'hpfs': ['HPFS_SUPER_MAGIC'],
'hugetlbfs': ['HUGETLBFS_MAGIC'],
'iso9660': ['ISOFS_SUPER_MAGIC'],
'jffs2': ['JFFS2_SUPER_MAGIC'],
'minix': ['MINIX_SUPER_MAGIC',
'MINIX_SUPER_MAGIC2',
'MINIX2_SUPER_MAGIC',
'MINIX2_SUPER_MAGIC2',
'MINIX3_SUPER_MAGIC'],
'mqueue': ['MQUEUE_MAGIC'],
# msdos is an older legacy version of vfat, shares the magic
'msdos': ['MSDOS_SUPER_MAGIC'],
# ncp/ncpfs have been removed from the kernel, but ncpfs was the official name
'ncp': ['NCP_SUPER_MAGIC'],
'ncpfs': ['NCP_SUPER_MAGIC'],
# nfs is the old version of nfs4, and they share the same magic
'nfs': ['NFS_SUPER_MAGIC'],
'nfs4': ['NFS_SUPER_MAGIC'],
'nilfs2': ['NILFS_SUPER_MAGIC'],
'nsfs': ['NSFS_MAGIC'],
'ntfs': ['NTFS_SB_MAGIC'],
'ntfs3': ['NTFS3_SUPER_MAGIC'],
'ocfs2': ['OCFS2_SUPER_MAGIC'],
'openpromfs': ['OPENPROM_SUPER_MAGIC'],
'orangefs': ['ORANGEFS_DEVREQ_MAGIC'],
'overlay': ['OVERLAYFS_SUPER_MAGIC'],
'pidfs': ['PID_FS_MAGIC'],
'pipefs': ['PIPEFS_MAGIC'],
'ppc-cmm': ['PPC_CMM_MAGIC'],
'proc': ['PROC_SUPER_MAGIC'],
'pstore': ['PSTOREFS_MAGIC'],
# pvfs2 is the old version of orangefs
'pvfs2': ['ORANGEFS_DEVREQ_MAGIC'],
'qnx4': ['QNX4_SUPER_MAGIC'],
'qnx6': ['QNX6_SUPER_MAGIC'],
'ramfs': ['RAMFS_MAGIC'],
'resctrl': ['RDTGROUP_SUPER_MAGIC'],
'reiserfs': ['REISERFS_SUPER_MAGIC'],
'rpc_pipefs': ['RPC_PIPEFS_SUPER_MAGIC'],
'secretmem': ['SECRETMEM_MAGIC'],
'securityfs': ['SECURITYFS_MAGIC'],
'selinuxfs': ['SELINUX_MAGIC'],
'shiftfs': ['SHIFTFS_MAGIC'],
'smackfs': ['SMACK_MAGIC'],
# smb3 is an alias for cifs
'smb3': ['CIFS_SUPER_MAGIC'],
# smbfs was removed from the kernel in 2010, the magic remains
'smbfs': ['SMB_SUPER_MAGIC'],
'sockfs': ['SOCKFS_MAGIC'],
'squashfs': ['SQUASHFS_MAGIC'],
'sysfs': ['SYSFS_MAGIC'],
# note that devtmpfs shares the same magic with tmpfs, given it is just a special named instance of it.
'tmpfs': ['TMPFS_MAGIC'],
'tracefs': ['TRACEFS_MAGIC'],
'udf': ['UDF_SUPER_MAGIC'],
'usbdevfs': ['USBDEVICE_SUPER_MAGIC'],
'vboxsf': ['VBOXSF_SUPER_MAGIC'],
# note that msdos shares the same magic (and is the older version)
'vfat': ['MSDOS_SUPER_MAGIC'],
'v9fs': ['V9FS_MAGIC'],
'xenfs': ['XENFS_SUPER_MAGIC'],
'xfs': ['XFS_SUPER_MAGIC'],
'z3fold': ['Z3FOLD_MAGIC'],
'zonefs': ['ZONEFS_MAGIC'],
'zsmalloc': ['ZSMALLOC_MAGIC'],
}
# System magics are sometimes not unique, because file systems got new
# revisions or got renamed. Let's prefer newer over older here, and thus ignore
# the old names.
OBSOLETE_NAMES = {
'cpuset', # magic taken over by cgroupfs
'devtmpfs', # not a file system of its own, but just a "named superblock" of tmpfs
'ext2', # ext4 is the newest revision of ext2 + ext3
'ext3',
'fuseblk', # closely related to fuse; they share a single magic, but the latter is more common
'gfs', # magic taken over by gfs2
'msdos', # vfat is the newest revision of msdos
'ncp', # ncpfs (not ncp) was the last name of the netware 'file_system_type'
# name before it was removed in 2018
'nfs', # nfs4 is the newest revision of nfs
'pvfs2', # orangefs is the new name of pvfs2
'smb3', # smb3 is an alias for cifs
}
FILESYSTEM_SETS = [
(
"@basic-api",
"Basic filesystem API",
"cgroup",
"cgroup2",
"devpts",
"devtmpfs",
"mqueue",
"proc",
"sysfs",
),
(
"@anonymous",
"Anonymous inodes",
"anon_inodefs",
"pipefs",
"sockfs",
),
(
"@application",
"Application virtual filesystems",
"autofs",
"fuse",
"overlay",
),
(
"@auxiliary-api",
"Auxiliary filesystem API",
"binfmt_misc",
"configfs",
"efivarfs",
"fusectl",
"hugetlbfs",
"rpc_pipefs",
"securityfs",
),
(
"@common-block",
"Common block device filesystems",
"btrfs",
"erofs",
"exfat",
"ext4",
"f2fs",
"iso9660",
"ntfs3",
"squashfs",
"udf",
"vfat",
"xfs",
),
(
"@historical-block",
"Historical block device filesystems",
"ext2",
"ext3",
"minix",
),
(
"@network",
"Well-known network filesystems",
"afs",
"ceph",
"cifs",
"gfs",
"gfs2",
"ncp",
"ncpfs",
"nfs",
"nfs4",
"ocfs2",
"orangefs",
"pvfs2",
"smb3",
"smbfs",
),
(
"@privileged-api",
"Privileged filesystem API",
"bpf",
"debugfs",
"pstore",
"tracefs",
),
(
"@security",
"Security/MAC API VFS",
"apparmorfs",
"selinuxfs",
"smackfs",
),
(
"@temporary",
"Temporary filesystems",
"ramfs",
"tmpfs",
),
(
"@known",
"All known filesystems declared in the kernel",
*NAME_TO_MAGIC.keys(),
),
]
def generate_gperf():
print("""\
/* SPDX-License-Identifier: LGPL-2.1-or-later */
%{
#if __GNUC__ >= 15
_Pragma("GCC diagnostic ignored \\"-Wzero-as-null-pointer-constant\\"")
#endif
#include <linux/magic.h>
#include "filesystems.h"
#include "stat-util.h"
struct FilesystemMagic {
const char *name;
statfs_f_type_t magic[FILESYSTEM_MAGIC_MAX];
};
%}
struct FilesystemMagic;
%language=ANSI-C
%define hash-function-name filesystems_gperf_hash
%define lookup-function-name filesystems_gperf_lookup
%define slot-name name
%readonly-tables
%omit-struct-type
%struct-type
%includes
%%""")
for name, magics in NAME_TO_MAGIC.items():
print(f"{name + ',':16} {{{', '.join(magics)}}}")
def generate_fs_type_to_string():
print("""\
#include <linux/magic.h>
#include "filesystems.h"
const char* fs_type_to_string(statfs_f_type_t magic) {
switch (magic) {""")
for name, magics in NAME_TO_MAGIC.items():
if name in OBSOLETE_NAMES:
continue
for magic in magics:
print(f' case (statfs_f_type_t) {magic}:')
print(f' return "{name}";')
print("""\
}
return NULL;
}""")
def generate_fs_in_group():
print('bool fs_in_group(const struct statfs *st, FilesystemGroups fs_group) {')
print(' switch (fs_group) {')
for name, _, *filesystems in FILESYSTEM_SETS:
magics = sorted(set(sum((NAME_TO_MAGIC[fs] for fs in filesystems),
start=[])))
enum = 'FILESYSTEM_SET_' + name[1:].upper().replace('-', '_')
print(f' case {enum}:')
opts = '\n || '.join(f'F_TYPE_EQUAL(st->f_type, {magic})'
for magic in magics)
print(f' return {opts};')
print(' default: assert_not_reached();')
print(' }')
print('}')
def generate_filesystem_sets():
print('const FilesystemSet filesystem_sets[_FILESYSTEM_SET_MAX] = {')
for name, desc, *filesystems in FILESYSTEM_SETS:
enum = 'FILESYSTEM_SET_' + name[1:].upper().replace('-', '_')
print(f' [{enum}] = {{')
print(f' .name = "{name}",')
print(f' .help = "{desc}",')
print(f' .value =')
for filesystem in filesystems:
print(f' "{filesystem}\\0"')
print(' },')
print('};')
def magic_defines():
cpp = os.environ['CPP'].split()
out = subprocess.check_output(
[*cpp, '-dM', '-include', 'linux/magic.h', '-'],
stdin=subprocess.DEVNULL,
text=True)
for line in out.splitlines():
_, name, *rest = line.split()
if ('_MAGIC' in name
and rest and rest[0].startswith('0x')
and name not in {
'STACK_END_MAGIC',
'MTD_INODE_FS_MAGIC',
'FUTEXFS_SUPER_MAGIC',
'CRAMFS_MAGIC_WEND',
}):
yield name
def check():
kernel_magics = set(magic_defines())
our_magics = set(sum(NAME_TO_MAGIC.values(), start=[]))
extra = kernel_magics - our_magics
if extra:
sys.exit(f"kernel knows additional filesystem magics: {', '.join(sorted(extra))}")
if __name__ == '__main__':
for arg in sys.argv[1:]:
if arg == 'gperf':
generate_gperf()
elif arg == 'fs-type-to-string':
generate_fs_type_to_string()
elif arg == 'filesystem-sets':
generate_filesystem_sets()
elif arg == 'fs-in-group':
generate_fs_in_group()
elif arg == 'check':
check()
else:
raise ValueError

View File

@ -1,135 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
%{
#if __GNUC__ >= 15
_Pragma("GCC diagnostic ignored \"-Wzero-as-null-pointer-constant\"")
#endif
#include <linux/magic.h>
#include "filesystems.h"
#include "stat-util.h"
struct FilesystemMagic {
const char *name;
statfs_f_type_t magic[FILESYSTEM_MAGIC_MAX];
};
%}
struct FilesystemMagic;
%language=ANSI-C
%define hash-function-name filesystems_gperf_hash
%define lookup-function-name filesystems_gperf_lookup
%define slot-name name
%readonly-tables
%omit-struct-type
%struct-type
%includes
%%
apparmorfs, {AAFS_MAGIC}
adfs, {ADFS_SUPER_MAGIC}
affs, {AFFS_SUPER_MAGIC}
afs, {AFS_FS_MAGIC, AFS_SUPER_MAGIC}
anon_inodefs, {ANON_INODE_FS_MAGIC}
autofs, {AUTOFS_SUPER_MAGIC}
balloon-kvm, {BALLOON_KVM_MAGIC}
bcachefs, {BCACHEFS_SUPER_MAGIC}
bdev, {BDEVFS_MAGIC}
binder, {BINDERFS_SUPER_MAGIC}
binfmt_misc, {BINFMTFS_MAGIC}
bpf, {BPF_FS_MAGIC}
btrfs, {BTRFS_SUPER_MAGIC}
btrfs_test_fs, {BTRFS_TEST_MAGIC}
# cpuset's magic got reassigned to cgroupfs
cpuset, {CGROUP_SUPER_MAGIC}
ceph, {CEPH_SUPER_MAGIC}
cgroup2, {CGROUP2_SUPER_MAGIC}
# note that the cgroupfs magic got reassigned from cpuset
cgroup, {CGROUP_SUPER_MAGIC}
cifs, {CIFS_SUPER_MAGIC, SMB2_SUPER_MAGIC}
coda, {CODA_SUPER_MAGIC}
configfs, {CONFIGFS_MAGIC}
cramfs, {CRAMFS_MAGIC}
dax, {DAXFS_MAGIC}
debugfs, {DEBUGFS_MAGIC}
devmem, {DEVMEM_MAGIC}
devpts, {DEVPTS_SUPER_MAGIC}
# devtmpfs is just a special instance of tmpfs, hence it reports its magic
devtmpfs, {TMPFS_MAGIC}
dmabuf, {DMA_BUF_MAGIC}
ecryptfs, {ECRYPTFS_SUPER_MAGIC}
efivarfs, {EFIVARFS_MAGIC}
efs, {EFS_SUPER_MAGIC}
erofs, {EROFS_SUPER_MAGIC_V1}
# ext2 + ext3 + ext4 use the same magic
ext2, {EXT2_SUPER_MAGIC}
ext3, {EXT3_SUPER_MAGIC}
ext4, {EXT4_SUPER_MAGIC}
exfat, {EXFAT_SUPER_MAGIC}
f2fs, {F2FS_SUPER_MAGIC}
# fuseblk is so closely related to fuse that it shares the same magic
fuseblk, {FUSE_SUPER_MAGIC}
fuse, {FUSE_SUPER_MAGIC}
fusectl, {FUSE_CTL_SUPER_MAGIC}
# gfs is an old version of gfs2 and reuses the magic
gfs, {GFS2_MAGIC}
gfs2, {GFS2_MAGIC}
hostfs, {HOSTFS_SUPER_MAGIC}
hpfs, {HPFS_SUPER_MAGIC}
hugetlbfs, {HUGETLBFS_MAGIC}
iso9660, {ISOFS_SUPER_MAGIC}
jffs2, {JFFS2_SUPER_MAGIC}
minix, {MINIX_SUPER_MAGIC, MINIX_SUPER_MAGIC2, MINIX2_SUPER_MAGIC, MINIX2_SUPER_MAGIC2, MINIX3_SUPER_MAGIC}
mqueue, {MQUEUE_MAGIC}
# msdos is an older legacy version of vfat, shares the magic
msdos, {MSDOS_SUPER_MAGIC}
# ncp/ncpfs have been removed from the kernel, but ncpfs was the official name
ncp, {NCP_SUPER_MAGIC}
ncpfs, {NCP_SUPER_MAGIC}
# nfs is the old version of nfs4, and they share the same magic
nfs, {NFS_SUPER_MAGIC}
nfs4, {NFS_SUPER_MAGIC}
nilfs2, {NILFS_SUPER_MAGIC}
nsfs, {NSFS_MAGIC}
ntfs, {NTFS_SB_MAGIC}
ntfs3, {NTFS3_SUPER_MAGIC}
ocfs2, {OCFS2_SUPER_MAGIC}
openpromfs, {OPENPROM_SUPER_MAGIC}
orangefs, {ORANGEFS_DEVREQ_MAGIC}
overlay, {OVERLAYFS_SUPER_MAGIC}
pidfs, {PID_FS_MAGIC}
pipefs, {PIPEFS_MAGIC}
ppc-cmm, {PPC_CMM_MAGIC}
proc, {PROC_SUPER_MAGIC}
pstore, {PSTOREFS_MAGIC}
# pvfs2 is the old version of orangefs
pvfs2, {ORANGEFS_DEVREQ_MAGIC}
qnx4, {QNX4_SUPER_MAGIC}
qnx6, {QNX6_SUPER_MAGIC}
ramfs, {RAMFS_MAGIC}
resctrl, {RDTGROUP_SUPER_MAGIC}
reiserfs, {REISERFS_SUPER_MAGIC}
rpc_pipefs, {RPC_PIPEFS_SUPER_MAGIC}
secretmem, {SECRETMEM_MAGIC}
securityfs, {SECURITYFS_MAGIC}
selinuxfs, {SELINUX_MAGIC}
shiftfs, {SHIFTFS_MAGIC}
smackfs, {SMACK_MAGIC}
# smb3 is an alias for cifs
smb3, {CIFS_SUPER_MAGIC}
# smbfs was removed from the kernel in 2010, the magic remains
smbfs, {SMB_SUPER_MAGIC}
sockfs, {SOCKFS_MAGIC}
squashfs, {SQUASHFS_MAGIC}
sysfs, {SYSFS_MAGIC}
# note that devtmpfs shares the same magic with tmpfs, given it is just a special named instance of it.
tmpfs, {TMPFS_MAGIC}
tracefs, {TRACEFS_MAGIC}
udf, {UDF_SUPER_MAGIC}
usbdevfs, {USBDEVICE_SUPER_MAGIC}
vboxsf, {VBOXSF_SUPER_MAGIC}
# note that msdos shares the same magic (and is the older version)
vfat, {MSDOS_SUPER_MAGIC}
v9fs, {V9FS_MAGIC}
xenfs, {XENFS_SUPER_MAGIC}
xfs, {XFS_SUPER_MAGIC}
z3fold, {Z3FOLD_MAGIC}
zonefs, {ZONEFS_MAGIC}
zsmalloc, {ZSMALLOC_MAGIC}

View File

@ -5,15 +5,6 @@
#include "stat-util.h" #include "stat-util.h"
#include "string-util.h" #include "string-util.h"
const char* fs_type_to_string(statfs_f_type_t magic) {
switch (magic) {
#include "filesystem-switch-case.inc"
}
return NULL;
}
int fs_type_from_string(const char *name, const statfs_f_type_t **ret) { int fs_type_from_string(const char *name, const statfs_f_type_t **ret) {
const struct FilesystemMagic *fs_magic; const struct FilesystemMagic *fs_magic;
@ -28,143 +19,7 @@ int fs_type_from_string(const char *name, const statfs_f_type_t **ret) {
return 0; return 0;
} }
bool fs_in_group(const struct statfs *s, FilesystemGroups fs_group) { const FilesystemSet* filesystem_set_find(const char *name) {
int r;
NULSTR_FOREACH(fs, filesystem_sets[fs_group].value) {
const statfs_f_type_t *magic;
r = fs_type_from_string(fs, &magic);
if (r >= 0)
for (size_t i = 0; i < FILESYSTEM_MAGIC_MAX; i++) {
if (magic[i] == 0)
break;
if (is_fs_type(s, magic[i]))
return true;
}
}
return false;
}
const FilesystemSet filesystem_sets[_FILESYSTEM_SET_MAX] = {
[FILESYSTEM_SET_BASIC_API] = {
.name = "@basic-api",
.help = "Basic filesystem API",
.value =
"cgroup\0"
"cgroup2\0"
"devpts\0"
"devtmpfs\0"
"mqueue\0"
"proc\0"
"sysfs\0"
},
[FILESYSTEM_SET_ANONYMOUS] = {
.name = "@anonymous",
.help = "Anonymous inodes",
.value =
"anon_inodefs\0"
"pipefs\0"
"sockfs\0"
},
[FILESYSTEM_SET_APPLICATION] = {
.name = "@application",
.help = "Application virtual filesystems",
.value =
"autofs\0"
"fuse\0"
"overlay\0"
},
[FILESYSTEM_SET_AUXILIARY_API] = {
.name = "@auxiliary-api",
.help = "Auxiliary filesystem API",
.value =
"binfmt_misc\0"
"configfs\0"
"efivarfs\0"
"fusectl\0"
"hugetlbfs\0"
"rpc_pipefs\0"
"securityfs\0"
},
[FILESYSTEM_SET_COMMON_BLOCK] = {
.name = "@common-block",
.help = "Common block device filesystems",
.value =
"btrfs\0"
"erofs\0"
"exfat\0"
"ext4\0"
"f2fs\0"
"iso9660\0"
"ntfs3\0"
"squashfs\0"
"udf\0"
"vfat\0"
"xfs\0"
},
[FILESYSTEM_SET_HISTORICAL_BLOCK] = {
.name = "@historical-block",
.help = "Historical block device filesystems",
.value =
"ext2\0"
"ext3\0"
"minix\0"
},
[FILESYSTEM_SET_NETWORK] = {
.name = "@network",
.help = "Well-known network filesystems",
.value =
"afs\0"
"ceph\0"
"cifs\0"
"gfs\0"
"gfs2\0"
"ncp\0"
"ncpfs\0"
"nfs\0"
"nfs4\0"
"ocfs2\0"
"orangefs\0"
"pvfs2\0"
"smb3\0"
"smbfs\0"
},
[FILESYSTEM_SET_PRIVILEGED_API] = {
.name = "@privileged-api",
.help = "Privileged filesystem API",
.value =
"bpf\0"
"debugfs\0"
"pstore\0"
"tracefs\0"
},
[FILESYSTEM_SET_SECURITY] = {
.name = "@security",
.help = "Security/MAC API VFS",
.value =
"apparmorfs\0"
"selinuxfs\0"
"smackfs\0"
},
[FILESYSTEM_SET_TEMPORARY] = {
.name = "@temporary",
.help = "Temporary filesystems",
.value =
"ramfs\0"
"tmpfs\0"
},
[FILESYSTEM_SET_KNOWN] = {
.name = "@known",
.help = "All known filesystems declared in the kernel",
.value =
#include "filesystem-list.inc"
},
};
const FilesystemSet *filesystem_set_find(const char *name) {
if (isempty(name) || name[0] != '@') if (isempty(name) || name[0] != '@')
return NULL; return NULL;

View File

@ -1,15 +0,0 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: LGPL-2.1-or-later
import sys
keywords_section = False
for line in open(sys.argv[1]):
if line[0] == '#':
continue
if keywords_section:
print('"{}\\0"'.format(line.split(',')[0].strip()))
elif line.startswith('%%'):
keywords_section = True

View File

@ -1,53 +0,0 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: LGPL-2.1-or-later
import sys
def filter_fsname(name):
# File system magics are sometimes not unique, because file systems got new
# revisions or got renamed. Let's prefer newer over older here, and thus
# ignore the old names.
return name in {
"cpuset", # magic taken over by cgroupfs
"devtmpfs", # not a file system of its own, but just a "named superblock" of tmpfs
"ext2", # ext4 is the newest revision of ext2 + ext3
"ext3",
"fuseblk", # closely related to fuse; they share a single magic, but the latter is more common
"gfs", # magic taken over by gfs2
"msdos", # vfat is the newest revision of msdos
"ncp", # ncpfs (not ncp) was the last name of the netware `file_system_type`
# name before it was removed in 2018
"nfs", # nfs4 is the newest revision of nfs
"pvfs2", # orangefs is the new name of pvfs2
"smb3", # smb3 is an alias for cifs
}
gperf_file = sys.argv[1]
keywords_section = False
for line in open(gperf_file):
if line[0] == "#":
continue
if keywords_section:
name, ids = line.split(",", 1)
name = name.strip()
if filter_fsname(name):
continue
ids = ids.strip()
assert ids[0] == "{"
assert ids[-1] == "}"
ids = ids[1:-1]
for id in ids.split(","):
print(f"case (statfs_f_type_t) {id.strip()}:")
print(f' return "{name}";')
if line.startswith("%%"):
keywords_section = True

View File

@ -168,41 +168,33 @@ basic_sources += generated_gperf_headers
############################################################ ############################################################
r = run_command( filesystem_sets_py = files('filesystem-sets.py')
[ filesystem_sets_c = custom_target(
'env', '--chdir', meson.project_build_root(), output : 'filesystem-sets.c',
files('check-filesystems.sh'), command : [filesystem_sets_py,
cpp, 'fs-type-to-string',
files('filesystems-gperf.gperf'), 'filesystem-sets',
system_include_args, 'fs-in-group'],
], capture : true)
check: false,
) filesystems_gperf_gperf = custom_target(
if r.returncode() != 0 output : 'filesystems-gperf.gperf',
warning('Unknown filesystems defined in kernel headers:\n\n' + r.stdout()) command : [filesystem_sets_py,
endif 'gperf'],
capture : true)
filesystems_gperf_h = custom_target( filesystems_gperf_h = custom_target(
input : 'filesystems-gperf.gperf', input : filesystems_gperf_gperf,
output : 'filesystems-gperf.h', output : 'filesystems-gperf.h',
command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@']) command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
filesystem_list_inc = custom_target( generated_sources += [filesystem_sets_c, filesystems_gperf_gperf, filesystems_gperf_h]
input : 'filesystems-gperf.gperf', basic_sources += [filesystem_sets_c, filesystems_gperf_h]
output : 'filesystem-list.inc',
command : [files('generate-filesystem-list.py'),
'@INPUT@'],
capture : true)
filesystem_switch_case_inc = custom_target( test('kernel-filesystem-magics',
input : 'filesystems-gperf.gperf', filesystem_sets_py,
output : 'filesystem-switch-case.inc', args : ['check'],
command : [files('generate-filesystem-switch-case.py'), env : ['CPP=@0@'.format(cpp)])
'@INPUT@'],
capture : true)
generated_sources += [filesystem_list_inc, filesystem_switch_case_inc, filesystems_gperf_h]
basic_sources += [filesystem_list_inc, filesystem_switch_case_inc, filesystems_gperf_h]
libbasic_static = static_library( libbasic_static = static_library(
'basic', 'basic',

View File

@ -220,20 +220,22 @@ int null_or_empty_path_with_root(const char *fn, const char *root) {
} }
int fd_is_read_only_fs(int fd) { int fd_is_read_only_fs(int fd) {
struct statvfs st; struct statfs st;
assert(fd >= 0); assert(fd >= 0);
if (fstatvfs(fd, &st) < 0) if (fstatfs(fd, &st) < 0)
return -errno; return -errno;
if (st.f_flag & ST_RDONLY) if (st.f_flags & ST_RDONLY)
return true; return true;
/* On NFS, fstatvfs() might not reflect whether we can actually write to the remote share. Let's try if (is_network_fs(&st)) {
* again with access(W_OK) which is more reliable, at least sometimes. */ /* On NFS, fstatfs() might not reflect whether we can actually write to the remote share.
if (access_fd(fd, W_OK) == -EROFS) * Let's try again with access(W_OK) which is more reliable, at least sometimes. */
return true; if (access_fd(fd, W_OK) == -EROFS)
return true;
}
return false; return false;
} }

View File

@ -48,6 +48,7 @@ static EFI_STATUS load_via_boot_services(
EFI_HANDLE parent, EFI_HANDLE parent,
EFI_LOADED_IMAGE_PROTOCOL* parent_loaded_image, EFI_LOADED_IMAGE_PROTOCOL* parent_loaded_image,
uint32_t compat_entry_point, uint32_t compat_entry_point,
const char16_t *cmdline,
const struct iovec *kernel, const struct iovec *kernel,
const struct iovec *initrd) { const struct iovec *initrd) {
_cleanup_(unload_imagep) EFI_HANDLE kernel_image = NULL; _cleanup_(unload_imagep) EFI_HANDLE kernel_image = NULL;
@ -96,6 +97,11 @@ static EFI_STATUS load_via_boot_services(
if (err != EFI_SUCCESS) if (err != EFI_SUCCESS)
return log_error_status(EFI_LOAD_ERROR, "Error getting kernel image from protocol from shim: %m"); return log_error_status(EFI_LOAD_ERROR, "Error getting kernel image from protocol from shim: %m");
if (cmdline) {
loaded_image->LoadOptions = (void *) cmdline;
loaded_image->LoadOptionsSize = strsize16(loaded_image->LoadOptions);
}
_cleanup_(cleanup_initrd) EFI_HANDLE initrd_handle = NULL; _cleanup_(cleanup_initrd) EFI_HANDLE initrd_handle = NULL;
err = initrd_register(initrd->iov_base, initrd->iov_len, &initrd_handle); err = initrd_register(initrd->iov_base, initrd->iov_len, &initrd_handle);
if (err != EFI_SUCCESS) if (err != EFI_SUCCESS)
@ -174,6 +180,7 @@ EFI_STATUS linux_exec(
parent, parent,
parent_loaded_image, parent_loaded_image,
compat_entry_point, compat_entry_point,
cmdline,
kernel, kernel,
initrd); initrd);

View File

@ -137,6 +137,8 @@ static int add_credential_gettys(void) {
}; };
int r; int r;
log_debug("Checking credentials for configuration...");
FOREACH_ELEMENT(t, table) { FOREACH_ELEMENT(t, table) {
_cleanup_free_ char *b = NULL; _cleanup_free_ char *b = NULL;
size_t sz = 0; size_t sz = 0;
@ -247,11 +249,12 @@ static void parse_env(void) {
r = getenv_for_pid(1, "SYSTEMD_GETTY_AUTO", &value); r = getenv_for_pid(1, "SYSTEMD_GETTY_AUTO", &value);
if (r < 0) if (r < 0)
log_warning_errno(r, "Failed to parse $SYSTEMD_GETTY_AUTO environment variable, ignoring: %m"); log_warning_errno(r, "Failed to read $SYSTEMD_GETTY_AUTO in PID 1's environment, ignoring: %m");
else if (r > 0) { else if (r > 0) {
r = parse_getty_sources(value, &arg_getty_sources); r = parse_getty_sources(value, &arg_getty_sources);
if (r < 0) if (r < 0)
log_warning_errno(r, "Failed to parse $SYSTEMD_GETTY_AUTO environment variable, ignoring: %s", value); log_warning_errno(r, "Failed to parse $SYSTEMD_GETTY_AUTO from PID 1's environment, ignoring: %s",
value);
} }
} }
@ -314,8 +317,8 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
log_warning_errno(r, "Failed to get active kernel consoles, ignoring: %m"); log_warning_errno(r, "Failed to get active kernel consoles, ignoring: %m");
else if (r > 0) else if (r > 0)
STRV_FOREACH(i, consoles) { STRV_FOREACH(i, consoles) {
/* We assume that gettys on virtual terminals are started via manual configuration /* We assume that gettys on virtual terminals are started via manual
* and do this magic only for non-VC terminals. */ * configuration and do this magic only for non-VC terminals. */
if (tty_is_vc(*i)) if (tty_is_vc(*i))
continue; continue;

View File

@ -142,8 +142,6 @@ enum nf_tables_msg_types {
NFT_MSG_DESTROYOBJ, NFT_MSG_DESTROYOBJ,
NFT_MSG_DESTROYFLOWTABLE, NFT_MSG_DESTROYFLOWTABLE,
NFT_MSG_GETSETELEM_RESET, NFT_MSG_GETSETELEM_RESET,
NFT_MSG_NEWDEV,
NFT_MSG_DELDEV,
NFT_MSG_MAX, NFT_MSG_MAX,
}; };
@ -1786,18 +1784,10 @@ enum nft_synproxy_attributes {
* enum nft_device_attributes - nf_tables device netlink attributes * enum nft_device_attributes - nf_tables device netlink attributes
* *
* @NFTA_DEVICE_NAME: name of this device (NLA_STRING) * @NFTA_DEVICE_NAME: name of this device (NLA_STRING)
* @NFTA_DEVICE_TABLE: table containing the flowtable or chain hooking into the device (NLA_STRING)
* @NFTA_DEVICE_FLOWTABLE: flowtable hooking into the device (NLA_STRING)
* @NFTA_DEVICE_CHAIN: chain hooking into the device (NLA_STRING)
* @NFTA_DEVICE_SPEC: hook spec matching the device (NLA_STRING)
*/ */
enum nft_devices_attributes { enum nft_devices_attributes {
NFTA_DEVICE_UNSPEC, NFTA_DEVICE_UNSPEC,
NFTA_DEVICE_NAME, NFTA_DEVICE_NAME,
NFTA_DEVICE_TABLE,
NFTA_DEVICE_FLOWTABLE,
NFTA_DEVICE_CHAIN,
NFTA_DEVICE_SPEC,
__NFTA_DEVICE_MAX __NFTA_DEVICE_MAX
}; };
#define NFTA_DEVICE_MAX (__NFTA_DEVICE_MAX - 1) #define NFTA_DEVICE_MAX (__NFTA_DEVICE_MAX - 1)

View File

@ -25,8 +25,6 @@ enum nfnetlink_groups {
#define NFNLGRP_ACCT_QUOTA NFNLGRP_ACCT_QUOTA #define NFNLGRP_ACCT_QUOTA NFNLGRP_ACCT_QUOTA
NFNLGRP_NFTRACE, NFNLGRP_NFTRACE,
#define NFNLGRP_NFTRACE NFNLGRP_NFTRACE #define NFNLGRP_NFTRACE NFNLGRP_NFTRACE
NFNLGRP_NFT_DEV,
#define NFNLGRP_NFT_DEV NFNLGRP_NFT_DEV
__NFNLGRP_MAX, __NFNLGRP_MAX,
}; };
#define NFNLGRP_MAX (__NFNLGRP_MAX - 1) #define NFNLGRP_MAX (__NFNLGRP_MAX - 1)

View File

@ -29,9 +29,5 @@ for i in *.h */*.h; do
# add casts in ethtool_cmd_speed() # add casts in ethtool_cmd_speed()
sed -r -i '/return (ep->speed_hi << 16) | ep->speed;/ s/return .*;/return ((__u32) ep->speed_hi << 16) | (__u32) ep->speed;/' "$i" sed -r -i '/return (ep->speed_hi << 16) | ep->speed;/ s/return .*;/return ((__u32) ep->speed_hi << 16) | (__u32) ep->speed;/' "$i"
;; ;;
vm_sockets.h)
# the header requires struct sockaddr declared
sed -r -i '/#define _VM_SOCKETS_H/a \\n#include <sys/socket.h>' "$i"
;;
esac esac
done done

View File

@ -17,7 +17,7 @@
#ifndef _VM_SOCKETS_H #ifndef _VM_SOCKETS_H
#define _VM_SOCKETS_H #define _VM_SOCKETS_H
#include <sys/socket.h> #include <sys/socket.h> /* for struct sockaddr and sa_family_t */
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/types.h> #include <linux/types.h>

View File

@ -7,8 +7,9 @@
static void test_FORMAT_LIFETIME_one(usec_t lifetime, const char *expected) { static void test_FORMAT_LIFETIME_one(usec_t lifetime, const char *expected) {
const char *t = FORMAT_LIFETIME(lifetime); const char *t = FORMAT_LIFETIME(lifetime);
log_debug(USEC_FMT "\"%s\" (expected \"%s\")", lifetime, t, expected); log_debug(USEC_FMT "\"%s\" (expected \"%s\")", lifetime, t, strna(expected));
assert_se(streq(t, expected)); if (expected)
ASSERT_STREQ(t, expected);
} }
TEST(FORMAT_LIFETIME) { TEST(FORMAT_LIFETIME) {
@ -17,9 +18,11 @@ TEST(FORMAT_LIFETIME) {
now_usec = now(CLOCK_BOOTTIME); now_usec = now(CLOCK_BOOTTIME);
test_FORMAT_LIFETIME_one(now_usec, "for 0"); test_FORMAT_LIFETIME_one(now_usec, "for 0");
test_FORMAT_LIFETIME_one(usec_add(now_usec, 2 * USEC_PER_SEC - 1), "for 1s");
test_FORMAT_LIFETIME_one(usec_add(now_usec, 3 * USEC_PER_WEEK + USEC_PER_SEC - 1), "for 3w");
test_FORMAT_LIFETIME_one(USEC_INFINITY, "forever"); test_FORMAT_LIFETIME_one(USEC_INFINITY, "forever");
/* These two are necessarily racy, especially for slow test environment. */
test_FORMAT_LIFETIME_one(usec_add(now_usec, 2 * USEC_PER_SEC - 1), NULL);
test_FORMAT_LIFETIME_one(usec_add(now_usec, 3 * USEC_PER_WEEK + USEC_PER_SEC - 1), NULL);
} }
DEFINE_TEST_MAIN(LOG_DEBUG); DEFINE_TEST_MAIN(LOG_DEBUG);