diff options
author | Iago López Galeiras <iagol@microsoft.com> | 2021-02-08 19:54:24 +0100 |
---|---|---|
committer | Iago Lopez Galeiras <iagol@microsoft.com> | 2021-10-06 10:52:10 +0200 |
commit | 1315ce3120c2e6850e9386b64fbc4e5c7f34048c (patch) | |
tree | acbcc0cf48a8fc0c9b62c22b0742228a7eb0e76e /src/basic | |
parent | 3ef4e91abe19f5aa89e1c022bb5438716c07144f (diff) | |
download | systemd-1315ce3120c2e6850e9386b64fbc4e5c7f34048c.tar.gz |
basic: add filesystem database
Stores filesystem_name -> magic_number(s).
Diffstat (limited to 'src/basic')
-rwxr-xr-x | src/basic/check-filesystems.sh | 36 | ||||
-rw-r--r-- | src/basic/filesystems-gperf.gperf | 112 | ||||
-rw-r--r-- | src/basic/filesystems.c | 131 | ||||
-rw-r--r-- | src/basic/filesystems.h | 38 | ||||
-rwxr-xr-x | src/basic/generate-filesystem-list.py | 12 | ||||
-rw-r--r-- | src/basic/meson.build | 2 |
6 files changed, 331 insertions, 0 deletions
diff --git a/src/basic/check-filesystems.sh b/src/basic/check-filesystems.sh new file mode 100755 index 0000000000..026574652e --- /dev/null +++ b/src/basic/check-filesystems.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eu +set -o pipefail + +cpp="$1" +filesystems_gperf="$2" +shift 2 + +includes="" +for i in "$@"; do + includes="$includes -include $i" +done + +error=false + +# shellcheck disable=SC2086 +for fs in $($cpp -dM $includes - </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 diff --git a/src/basic/filesystems-gperf.gperf b/src/basic/filesystems-gperf.gperf new file mode 100644 index 0000000000..f31c9de192 --- /dev/null +++ b/src/basic/filesystems-gperf.gperf @@ -0,0 +1,112 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +%{ +#include <linux/magic.h> + +#include "filesystems.h" +#include "missing_magic.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} +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} +ceph, {CEPH_SUPER_MAGIC} +cgroup2, {CGROUP2_SUPER_MAGIC} +cgroup, {CGROUP_SUPER_MAGIC} +cifs, {CIFS_MAGIC_NUMBER} +coda, {CODA_SUPER_MAGIC} +configfs, {CONFIGFS_MAGIC} +cramfs, {CRAMFS_MAGIC} +dax, {DAXFS_MAGIC} +debugfs, {DEBUGFS_MAGIC} +devmem, {DEVMEM_MAGIC} +devpts, {DEVPTS_SUPER_MAGIC} +dmabuf, {DMA_BUF_MAGIC} +ecryptfs, {ECRYPTFS_SUPER_MAGIC} +efivarfs, {EFIVARFS_MAGIC} +efs, {EFS_SUPER_MAGIC} +erofs, {EROFS_SUPER_MAGIC_V1} +ext2, {EXT2_SUPER_MAGIC} +ext3, {EXT3_SUPER_MAGIC} +ext4, {EXT4_SUPER_MAGIC} +exfat, {EXFAT_SUPER_MAGIC} +f2fs, {F2FS_SUPER_MAGIC} +fuseblk, {FUSE_SUPER_MAGIC} +fuse, {FUSE_SUPER_MAGIC} +fusectl, {FUSE_CTL_SUPER_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, {MSDOS_SUPER_MAGIC} +ncp, {NCP_SUPER_MAGIC} +ncpfs, {NCP_SUPER_MAGIC} +nfs, {NFS_SUPER_MAGIC} +nfs4, {NFS_SUPER_MAGIC} +nilfs2, {NILFS_SUPER_MAGIC} +nsfs, {NSFS_MAGIC} +ocfs2, {OCFS2_SUPER_MAGIC} +openpromfs, {OPENPROM_SUPER_MAGIC} +orangefs, {ORANGEFS_DEVREQ_MAGIC} +overlay, {OVERLAYFS_SUPER_MAGIC} +pipefs, {PIPEFS_MAGIC} +ppc-cmm, {PPC_CMM_MAGIC} +proc, {PROC_SUPER_MAGIC} +pstore, {PSTOREFS_MAGIC} +pvfs2, {ORANGEFS_DEVREQ_MAGIC} +qnx4, {QNX4_SUPER_MAGIC} +qnx6, {QNX6_SUPER_MAGIC} +ramfs, {RAMFS_MAGIC} +resctrl, {RDTGROUP_SUPER_MAGIC} +reiserfs, {REISERFS_SUPER_MAGIC} +secretmem, {SECRETMEM_MAGIC} +securityfs, {SECURITYFS_MAGIC} +selinuxfs, {SELINUX_MAGIC} +shiftfs, {SHIFTFS_MAGIC} +smackfs, {SMACK_MAGIC} +smb3, {SMB_SUPER_MAGIC} +smbfs, {SMB_SUPER_MAGIC} +sockfs, {SOCKFS_MAGIC} +squashfs, {SQUASHFS_MAGIC} +sysfs, {SYSFS_MAGIC} +tmpfs, {TMPFS_MAGIC} +tracefs, {TRACEFS_MAGIC} +udf, {UDF_SUPER_MAGIC} +usbdevfs, {USBDEVICE_SUPER_MAGIC} +vboxsf, {VBOXSF_SUPER_MAGIC} +vfat, {MSDOS_SUPER_MAGIC} +v9fs, {V9FS_MAGIC} +xenfs, {XENFS_SUPER_MAGIC} +xfs, {XFS_SUPER_MAGIC} +z3fold, {Z3FOLD_MAGIC} +zonefs, {ZONEFS_MAGIC} +zsmalloc, {ZSMALLOC_MAGIC} diff --git a/src/basic/filesystems.c b/src/basic/filesystems.c new file mode 100644 index 0000000000..9fccea2018 --- /dev/null +++ b/src/basic/filesystems.c @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "filesystems-gperf.h" + +int fs_type_from_string(const char *name, const statfs_f_type_t **ret) { + const struct FilesystemMagic *fs_magic; + + assert(name); + assert(ret); + + fs_magic = filesystems_gperf_lookup(name, strlen(name)); + if (!fs_magic) + return -EINVAL; + + *ret = fs_magic->magic; + + return 0; +} + +int fs_in_group(const struct statfs *s, FilesystemGroups fs_group) { + const char *fs; + 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" + "mqueue\0" + "proc\0" + "sysfs\0" + }, + [FILESYSTEM_SET_AUXILIARY_API] = { + .name = "@auxiliary-api", + .help = "Auxiliary filesystem API", + .value = + "configfs\0" + "efivarfs\0" + "fusectl\0" + "hugetlbfs\0" + "securityfs\0" + }, + [FILESYSTEM_SET_COMMON_BLOCK] = { + .name = "@common-block", + .help = "Common block device filesystems", + .value = + "btrfs\0" + "ext4\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" + "cifs\0" + "gfs\0" + "gfs2\0" + "ncpfs\0" + "ncp\0" + "nfs\0" + "nfs4\0" + "ocfs2\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_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.h" + }, +}; + +const FilesystemSet *filesystem_set_find(const char *name) { + if (isempty(name) || name[0] != '@') + return NULL; + + for (FilesystemGroups i = 0; i < _FILESYSTEM_SET_MAX; i++) + if (streq(filesystem_sets[i].name, name)) + return filesystem_sets + i; + + return NULL; +} diff --git a/src/basic/filesystems.h b/src/basic/filesystems.h new file mode 100644 index 0000000000..a0964476af --- /dev/null +++ b/src/basic/filesystems.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "nulstr-util.h" +#include "stat-util.h" +#include "string-util.h" + +#define FILESYSTEM_MAGIC_MAX 10 + +typedef enum FilesystemGroups { + /* Please leave BASIC_API first and KNOWN last, but sort the rest alphabetically */ + FILESYSTEM_SET_BASIC_API, + FILESYSTEM_SET_AUXILIARY_API, + FILESYSTEM_SET_COMMON_BLOCK, + FILESYSTEM_SET_HISTORICAL_BLOCK, + FILESYSTEM_SET_NETWORK, + FILESYSTEM_SET_PRIVILEGED_API, + FILESYSTEM_SET_TEMPORARY, + FILESYSTEM_SET_KNOWN, + _FILESYSTEM_SET_MAX, + _FILESYSTEM_SET_INVALID = -EINVAL, +} FilesystemGroups; + +typedef struct FilesystemSet { + const char *name; + const char *help; + const char *value; +} FilesystemSet; + +extern const FilesystemSet filesystem_sets[]; + +const FilesystemSet *filesystem_set_find(const char *name); + +int fs_type_from_string(const char *name, const statfs_f_type_t **ret); +int fs_in_group(const struct statfs *s, enum FilesystemGroups fs_group); + +/* gperf prototypes */ +const struct FilesystemMagic* filesystems_gperf_lookup(const char *key, GPERF_LEN_TYPE length); diff --git a/src/basic/generate-filesystem-list.py b/src/basic/generate-filesystem-list.py new file mode 100755 index 0000000000..8271b3fbeb --- /dev/null +++ b/src/basic/generate-filesystem-list.py @@ -0,0 +1,12 @@ +#!/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 keywords_section: + print('"{}\\0"'.format(line.split(',')[0].strip())) + elif line.startswith('%%'): + keywords_section = True diff --git a/src/basic/meson.build b/src/basic/meson.build index ade45bdfc2..4f172b48e9 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -54,6 +54,8 @@ basic_sources = files(''' fd-util.h fileio.c fileio.h + filesystems.c + filesystems.h format-util.c format-util.h fs-util.c |