mirror of
https://github.com/systemd/systemd
synced 2025-10-05 11:44:45 +02:00
Compare commits
8 Commits
9e6f0d4bbd
...
706e622e88
Author | SHA1 | Date | |
---|---|---|---|
![]() |
706e622e88 | ||
![]() |
bef244392b | ||
![]() |
4fb09adec4 | ||
![]() |
7292d676d0 | ||
![]() |
aca4353ab2 | ||
![]() |
b0123576f4 | ||
![]() |
c136be3f04 | ||
![]() |
9154cc7e80 |
@ -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
371
src/basic/filesystem-sets.py
Executable 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
|
@ -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}
|
@ -5,15 +5,6 @@
|
||||
#include "stat-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) {
|
||||
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;
|
||||
}
|
||||
|
||||
bool fs_in_group(const struct statfs *s, FilesystemGroups fs_group) {
|
||||
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) {
|
||||
const FilesystemSet* filesystem_set_find(const char *name) {
|
||||
if (isempty(name) || name[0] != '@')
|
||||
return NULL;
|
||||
|
||||
|
@ -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
|
@ -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
|
@ -168,41 +168,33 @@ basic_sources += generated_gperf_headers
|
||||
|
||||
############################################################
|
||||
|
||||
r = run_command(
|
||||
[
|
||||
'env', '--chdir', meson.project_build_root(),
|
||||
files('check-filesystems.sh'),
|
||||
cpp,
|
||||
files('filesystems-gperf.gperf'),
|
||||
system_include_args,
|
||||
],
|
||||
check: false,
|
||||
)
|
||||
if r.returncode() != 0
|
||||
warning('Unknown filesystems defined in kernel headers:\n\n' + r.stdout())
|
||||
endif
|
||||
filesystem_sets_py = files('filesystem-sets.py')
|
||||
filesystem_sets_c = custom_target(
|
||||
output : 'filesystem-sets.c',
|
||||
command : [filesystem_sets_py,
|
||||
'fs-type-to-string',
|
||||
'filesystem-sets',
|
||||
'fs-in-group'],
|
||||
capture : true)
|
||||
|
||||
filesystems_gperf_gperf = custom_target(
|
||||
output : 'filesystems-gperf.gperf',
|
||||
command : [filesystem_sets_py,
|
||||
'gperf'],
|
||||
capture : true)
|
||||
|
||||
filesystems_gperf_h = custom_target(
|
||||
input : 'filesystems-gperf.gperf',
|
||||
input : filesystems_gperf_gperf,
|
||||
output : 'filesystems-gperf.h',
|
||||
command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])
|
||||
|
||||
filesystem_list_inc = custom_target(
|
||||
input : 'filesystems-gperf.gperf',
|
||||
output : 'filesystem-list.inc',
|
||||
command : [files('generate-filesystem-list.py'),
|
||||
'@INPUT@'],
|
||||
capture : true)
|
||||
generated_sources += [filesystem_sets_c, filesystems_gperf_gperf, filesystems_gperf_h]
|
||||
basic_sources += [filesystem_sets_c, filesystems_gperf_h]
|
||||
|
||||
filesystem_switch_case_inc = custom_target(
|
||||
input : 'filesystems-gperf.gperf',
|
||||
output : 'filesystem-switch-case.inc',
|
||||
command : [files('generate-filesystem-switch-case.py'),
|
||||
'@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]
|
||||
test('kernel-filesystem-magics',
|
||||
filesystem_sets_py,
|
||||
args : ['check'],
|
||||
env : ['CPP=@0@'.format(cpp)])
|
||||
|
||||
libbasic_static = static_library(
|
||||
'basic',
|
||||
|
@ -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) {
|
||||
struct statvfs st;
|
||||
struct statfs st;
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
if (fstatvfs(fd, &st) < 0)
|
||||
if (fstatfs(fd, &st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (st.f_flag & ST_RDONLY)
|
||||
if (st.f_flags & ST_RDONLY)
|
||||
return true;
|
||||
|
||||
/* 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;
|
||||
if (is_network_fs(&st)) {
|
||||
/* On NFS, fstatfs() 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;
|
||||
}
|
||||
|
@ -48,6 +48,7 @@ static EFI_STATUS load_via_boot_services(
|
||||
EFI_HANDLE parent,
|
||||
EFI_LOADED_IMAGE_PROTOCOL* parent_loaded_image,
|
||||
uint32_t compat_entry_point,
|
||||
const char16_t *cmdline,
|
||||
const struct iovec *kernel,
|
||||
const struct iovec *initrd) {
|
||||
_cleanup_(unload_imagep) EFI_HANDLE kernel_image = NULL;
|
||||
@ -96,6 +97,11 @@ static EFI_STATUS load_via_boot_services(
|
||||
if (err != EFI_SUCCESS)
|
||||
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;
|
||||
err = initrd_register(initrd->iov_base, initrd->iov_len, &initrd_handle);
|
||||
if (err != EFI_SUCCESS)
|
||||
@ -174,6 +180,7 @@ EFI_STATUS linux_exec(
|
||||
parent,
|
||||
parent_loaded_image,
|
||||
compat_entry_point,
|
||||
cmdline,
|
||||
kernel,
|
||||
initrd);
|
||||
|
||||
|
@ -137,6 +137,8 @@ static int add_credential_gettys(void) {
|
||||
};
|
||||
int r;
|
||||
|
||||
log_debug("Checking credentials for configuration...");
|
||||
|
||||
FOREACH_ELEMENT(t, table) {
|
||||
_cleanup_free_ char *b = NULL;
|
||||
size_t sz = 0;
|
||||
@ -247,11 +249,12 @@ static void parse_env(void) {
|
||||
|
||||
r = getenv_for_pid(1, "SYSTEMD_GETTY_AUTO", &value);
|
||||
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) {
|
||||
r = parse_getty_sources(value, &arg_getty_sources);
|
||||
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");
|
||||
else if (r > 0)
|
||||
STRV_FOREACH(i, consoles) {
|
||||
/* We assume that gettys on virtual terminals are started via manual configuration
|
||||
* and do this magic only for non-VC terminals. */
|
||||
/* We assume that gettys on virtual terminals are started via manual
|
||||
* configuration and do this magic only for non-VC terminals. */
|
||||
if (tty_is_vc(*i))
|
||||
continue;
|
||||
|
||||
|
@ -142,8 +142,6 @@ enum nf_tables_msg_types {
|
||||
NFT_MSG_DESTROYOBJ,
|
||||
NFT_MSG_DESTROYFLOWTABLE,
|
||||
NFT_MSG_GETSETELEM_RESET,
|
||||
NFT_MSG_NEWDEV,
|
||||
NFT_MSG_DELDEV,
|
||||
NFT_MSG_MAX,
|
||||
};
|
||||
|
||||
@ -1786,18 +1784,10 @@ enum nft_synproxy_attributes {
|
||||
* enum nft_device_attributes - nf_tables device netlink attributes
|
||||
*
|
||||
* @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 {
|
||||
NFTA_DEVICE_UNSPEC,
|
||||
NFTA_DEVICE_NAME,
|
||||
NFTA_DEVICE_TABLE,
|
||||
NFTA_DEVICE_FLOWTABLE,
|
||||
NFTA_DEVICE_CHAIN,
|
||||
NFTA_DEVICE_SPEC,
|
||||
__NFTA_DEVICE_MAX
|
||||
};
|
||||
#define NFTA_DEVICE_MAX (__NFTA_DEVICE_MAX - 1)
|
||||
|
@ -25,8 +25,6 @@ enum nfnetlink_groups {
|
||||
#define NFNLGRP_ACCT_QUOTA NFNLGRP_ACCT_QUOTA
|
||||
NFNLGRP_NFTRACE,
|
||||
#define NFNLGRP_NFTRACE NFNLGRP_NFTRACE
|
||||
NFNLGRP_NFT_DEV,
|
||||
#define NFNLGRP_NFT_DEV NFNLGRP_NFT_DEV
|
||||
__NFNLGRP_MAX,
|
||||
};
|
||||
#define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
|
||||
|
@ -29,9 +29,5 @@ for i in *.h */*.h; do
|
||||
# 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"
|
||||
;;
|
||||
vm_sockets.h)
|
||||
# the header requires struct sockaddr declared
|
||||
sed -r -i '/#define _VM_SOCKETS_H/a \\n#include <sys/socket.h>' "$i"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
@ -17,7 +17,7 @@
|
||||
#ifndef _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/types.h>
|
||||
|
@ -7,8 +7,9 @@
|
||||
static void test_FORMAT_LIFETIME_one(usec_t lifetime, const char *expected) {
|
||||
const char *t = FORMAT_LIFETIME(lifetime);
|
||||
|
||||
log_debug(USEC_FMT " → \"%s\" (expected \"%s\")", lifetime, t, expected);
|
||||
assert_se(streq(t, expected));
|
||||
log_debug(USEC_FMT " → \"%s\" (expected \"%s\")", lifetime, t, strna(expected));
|
||||
if (expected)
|
||||
ASSERT_STREQ(t, expected);
|
||||
}
|
||||
|
||||
TEST(FORMAT_LIFETIME) {
|
||||
@ -17,9 +18,11 @@ TEST(FORMAT_LIFETIME) {
|
||||
now_usec = now(CLOCK_BOOTTIME);
|
||||
|
||||
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");
|
||||
|
||||
/* 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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user