summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
authorIago López Galeiras <iagol@microsoft.com>2021-02-08 19:54:24 +0100
committerIago Lopez Galeiras <iagol@microsoft.com>2021-10-06 10:52:10 +0200
commit1315ce3120c2e6850e9386b64fbc4e5c7f34048c (patch)
treeacbcc0cf48a8fc0c9b62c22b0742228a7eb0e76e /src/basic
parent3ef4e91abe19f5aa89e1c022bb5438716c07144f (diff)
downloadsystemd-1315ce3120c2e6850e9386b64fbc4e5c7f34048c.tar.gz
basic: add filesystem database
Stores filesystem_name -> magic_number(s).
Diffstat (limited to 'src/basic')
-rwxr-xr-xsrc/basic/check-filesystems.sh36
-rw-r--r--src/basic/filesystems-gperf.gperf112
-rw-r--r--src/basic/filesystems.c131
-rw-r--r--src/basic/filesystems.h38
-rwxr-xr-xsrc/basic/generate-filesystem-list.py12
-rw-r--r--src/basic/meson.build2
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