1
0
mirror of https://github.com/systemd/systemd synced 2026-04-06 23:24:52 +02:00

Compare commits

...

47 Commits

Author SHA1 Message Date
Lennart Poettering
2ec0c4f94d sysext: fix tmpfs mount source
It's "sysext", not "sysexit".

The string passed here is pure decoration, and noone will see it, since
it's only in our private mount namespace. But still, it's a typo, let's
fix it
2021-11-16 17:02:18 +01:00
Franck Bui
0c98f381e7 TEST-08: don't force ext4 for /
Forcing a specific fs for the image is usually a bad idea because the initrd
(borrowed from the host) is likely to include only support for the filesystem
used by the host's rootfs.

Since the point of this test is to check aliases on mount units, there's no
specific need for ext4, hence drop any parts that request or rely on ext4.
2021-11-16 16:58:49 +01:00
Daan De Meyer
054ed43075 meson: Downgrade unused function from error to warning in local builds
When working on systemd, it's often useful to be able to comment out
a function to see how a build behaves without it. Currently, when doing
this with a static function that's only used once, the build fails because
the function then becomes unused. As such, Let's downgrade the unused
function error to a warning in local builds.
2021-11-16 16:57:36 +01:00
Zbigniew Jędrzejewski-Szmek
b15f6eae42 tmpfiles: split out config for systemd-resolve
This mirrors what was done in 564761fcaeda8c013210f7c6934847a6d0228ec9
for sysusers.d. If we allow separating resolved sysusers config
in a subpackage, we should do the same for the symlink that is
only useful when resolved is installed.

Related to #21317.
2021-11-16 16:56:08 +01:00
Lennart Poettering
67d0c6744f
Merge pull request #21275 from keszybz/makefs-quiet
Makefs quiet output
2021-11-16 16:55:47 +01:00
Lennart Poettering
032e11a234
Merge pull request #21386 from keszybz/binfmt-later
Order binfmt.service after local-fs.target
2021-11-16 16:54:47 +01:00
Takashi Sakamoto
289c2459b7 hwdb: ieee1394-unit-function: add entry for MOTU Track 16
In Linux kernel 5.16 prepatch, MOTU Track 16 is newly supported by ALSA
firewire-motu driver.

This commit adds hwdb entry for the device.

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=411ac2982cb6
2021-11-16 16:54:33 +01:00
Yu Watanabe
39b91d1ae4 network: tuntap: drop unnecessary minus 2021-11-16 16:53:43 +01:00
Lennart Poettering
91822de4f6
Merge pull request #21383 from yuwata/network-address-scope
network: use route_scope_from_string() at one more place
2021-11-16 16:53:26 +01:00
Lennart Poettering
31f5c84dfc
Merge pull request #21380 from poettering/homed-test-qemu
homed: make sure homed tests actually run in qemu, too
2021-11-16 16:52:57 +01:00
Lennart Poettering
d6c3a32056 umount: fix log message
The sentence wasn't correct English language, let's fix that. More
importantly: if the mount options are empty we'd display "(null)" here.
Fix that. (And they can be empty IRL, see CI results)
2021-11-16 15:08:29 +01:00
Zbigniew Jędrzejewski-Szmek
1c271d3871 man: document fs types known to makefs 2021-11-16 13:55:50 +01:00
Zbigniew Jędrzejewski-Szmek
2d96440fd5 makefs: add "support" for f2fs
The man page doesn't quite match what --help says, and I needed to use "-f" to
write a wiped partition. This all feels a bit experimental, but the fs has some
adherents, and we should make it easy to use.

(Also, an empty 256MB device formatted and mounted shows up as
  Filesystem      Size  Used Avail Use% Mounted on
  /dev/loop0      254M   85M  170M  34% /var/tmp/mount
which also seems a bit over the top…)

Requested in https://github.com/systemd/systemd/pull/21275#issuecomment-967928690.
2021-11-16 13:55:49 +01:00
Zbigniew Jędrzejewski-Szmek
8d433a99a4 makefs: fix too-long swap labels
Apparently mkswap has it's own limit, and it seems to be one lower than the one
for ext2/3/4.

$ for i in ext2 ext3 ext4 btrfs xfs vfat swap minix; do
  echo $i && wipefs -q -a '/var/tmp/głąbźśńćąśððð.img'
  build/systemd-makefs $i '/var/tmp/głąbźśńćąśððð.img'
done

ext2
/var/tmp/głąbźśńćąśððð.img successfully formatted as ext2 (label "głąbźśńćą", uuid 7626bc5c-8ac4-43cf-87b7-1b2761272dd3)
ext3
/var/tmp/głąbźśńćąśððð.img successfully formatted as ext3 (label "głąbźśńćą", uuid 0da22cad-0dbf-4a7a-962d-12cd39d006b5)
ext4
/var/tmp/głąbźśńćąśððð.img successfully formatted as ext4 (label "głąbźśńćą", uuid dded267b-8955-4d19-82a5-1f231d446059)
btrfs
/var/tmp/głąbźśńćąśððð.img successfully formatted as btrfs (label "głąbźśńćąśððð.img", uuid 9e2e89f1-010d-4ab6-80f3-f9e215dbc225)
xfs
/var/tmp/głąbźśńćąśððð.img successfully formatted as xfs (label "głąbźśń", uuid 2cc937af-4c41-465c-8f52-aab2304bd860)
vfat
mkfs.fat 4.2 (2021-01-31)
/var/tmp/głąbźśńćąśððð.img successfully formatted as vfat (label "G__B_______", uuid a3a9e028)

swap
...
LABEL=głąbźśńć, UUID=0ab787aa-37a6-4b32-978b-d71efc6e6098
/var/tmp/głąbźśńćąśððð.img successfully formatted as swap (label "głąbźśńć", uuid 0ab787aa-37a6-4b32-978b-d71efc6e6098)

minix
...
/var/tmp/głąbźśńćąśððð.img successfully formatted as minix (no label or uuid specified)
2021-11-16 13:55:48 +01:00
Zbigniew Jędrzejewski-Szmek
7ffe593b79 makefs: fix too-long ext2/3/4 labels 2021-11-16 13:55:46 +01:00
Zbigniew Jędrzejewski-Szmek
dc91c971bf makefs: fix label for vfat filesystems
I was testing with a "test1.img" and mkfs.vfat rejects "TEST1.IMG" with the
error "Labels with characters *?.,;:/\|+=<>[]" are not allowed". So let's
replace those characters with "_".
2021-11-16 13:55:33 +01:00
Zbigniew Jędrzejewski-Szmek
9b49a3b49e basic/utf8: add function to convert to ASCII
The conversion must be lossy because ASCII doesn't have enough chars.
2021-11-16 13:54:38 +01:00
Lennart Poettering
3054863345 test: make homed test run in qemu 2021-11-16 12:33:44 +01:00
Lennart Poettering
491347bdf6 homed: wait for luks devices to go away
Let's make sure LUKS volumes are really definitely gone before we retun
in the deactivation logic.
2021-11-16 10:27:24 +01:00
Zbigniew Jędrzejewski-Szmek
7ee587afe3
Merge pull request #21373 from poettering/filesystems-more-groups
some file system tables/magic love
2021-11-16 10:27:21 +01:00
Zbigniew Jędrzejewski-Szmek
0491ab5fcd units: delay binfmt processing until after local-fs.target
Users may use rules that refer to binaries e.g. in /opt or /usr/local,
and those directories may be separate mount points. We don't need the
binfmt rules in early boot, so let's delay the service so that we can
rely on the full local filesystem being visible.

Fixes #21178.
2021-11-16 09:21:22 +01:00
Zbigniew Jędrzejewski-Szmek
fe8538e499 man: add markup 2021-11-16 09:21:22 +01:00
Zbigniew Jędrzejewski-Szmek
1990bc64cd basic/errno-util: adjust indentation
It was bothering me that this backslash wasn't aligned with the
ones below.
2021-11-16 09:21:22 +01:00
Yu Watanabe
faa201dc6b network: address: explicitly mention that the address is localhost 2021-11-16 16:01:18 +09:00
Yu Watanabe
d8c472f297 network: address: use route_scope_from_string() 2021-11-16 16:01:18 +09:00
Lennart Poettering
ad004abe9d filesystems: apparently f2fs is als reasonably common
As suggested:

https://github.com/systemd/systemd/pull/21373#discussion_r749523677
2021-11-15 22:54:15 +01:00
Lennart Poettering
05715f12a8 filesystems: add ntfs/ntfs3 magic and add it current version to group
As suggested:

https://github.com/systemd/systemd/pull/21373#discussion_r749523677
2021-11-15 22:53:25 +01:00
Lennart Poettering
ad4e99fe9a filesystems: add comments to gperf file anomalies
Some file systems have non-unique names or non-unique magics. Let's add
some comments explaining that.
2021-11-15 22:43:03 +01:00
Lennart Poettering
0ed6103c19 filesystems: fix magic of "smb3" fs
smb3 is an alias for modern CIFS, not the old SMB fs (see kmod alias list, i.e. modinfo fs-smb3).

(the old smbfs has long been removed from the kernel actually, it's dead
and obsolete)
2021-11-15 22:43:03 +01:00
Lennart Poettering
d7c2f8817a filesystems: list rpc_pipefs as auxiliary kernel API VFS 2021-11-15 22:43:03 +01:00
Lennart Poettering
7e8fd61089 filesystems: list orangefs as network fs
it's the new name or pvfs2, hence we might as well list it, given we
list that already.
2021-11-15 22:43:03 +01:00
Lennart Poettering
2b69f6e591 devtmpfs is a primary API fs 2021-11-15 22:43:03 +01:00
Lennart Poettering
e0f89b0656 analyze: don't list filesystems among ungrouped that are aliases
There are a bunch of filesystems that actually are just aliases for
other filesystems. So far we listed them as "ungrouped", suggesting they
should be added to some file system group. But that's not really
something needed, since they are after all not file systems in their own
right, but aliases only (and usually legacy at that).

hence, let's hide them from display (but debug log about them)
2021-11-15 22:43:03 +01:00
Lennart Poettering
7c604e89aa homed: replace home-grown fs magic translation with fs_type_to_string() 2021-11-15 22:43:03 +01:00
Lennart Poettering
66d39325d7 filesystems: add three more file system types
devtmpfs and cpuset are not actual filesystems of their own. cpuset used
to be but is now an alias for cgroupsfs. devtmpfs is the same as tmpfs
as its just a "named superblock", i.e. a specific instance of tmpfs, but
not a file system of its own.
2021-11-15 22:43:03 +01:00
Lennart Poettering
5538ecbac8 analyze: show fs magic info in 'systemd-analyze filesystem'
Let's show this information, since its quite useful. Moreover it allows
us to highlight file system aliases.
2021-11-15 22:43:03 +01:00
Lennart Poettering
6d439321e8 filesystems: add internal APIs to convert fs magic to name
We previously had tooling for the opposite direction, let's complete the
work.
2021-11-15 22:43:03 +01:00
Lennart Poettering
3818d6a3a5 mountpoint-util: sort list of read-only fs again 2021-11-15 22:43:03 +01:00
Lennart Poettering
5feeb2584f filesystems: add group for "application" file system
This group shall cover file systems whose job is to make stuff that
isn't actually storing anything in itself, and isn't just an API file
system, but allows exposing stuff with special semantics in the VFS.
2021-11-15 22:43:03 +01:00
Lennart Poettering
9c8214d559 filesystems: add binfmt_misc to auxiliary API VFS group 2021-11-15 22:43:03 +01:00
Lennart Poettering
333a2ad649 filesystems: add ceph to network file systems group 2021-11-15 22:43:03 +01:00
Lennart Poettering
2867cb392a filesystems: slightly update common block device groups 2021-11-15 22:43:03 +01:00
Lennart Poettering
73e7576e3b filesystems: add two new filesystem groups
1. @anonymous → for file systems that aren't real file systems but
   simply the backing for sockets, pipes and other "anonymous" fds.

2. @security → for the various MAC security file systems.
2021-11-15 22:43:03 +01:00
Zbigniew Jędrzejewski-Szmek
a456086b37 basic/utf8: inline some iterator variables 2021-11-12 15:51:26 +01:00
Zbigniew Jędrzejewski-Szmek
4f05a11c55 makefs: supress mkfs output, but print one line on success
$ for i in ext2 ext3 ext4 btrfs xfs vfat swap minix; do
  echo $i && wipefs -q -a /var/tmp/test2_img && build/systemd-makefs $i /var/tmp/test2_img
done

ext2
/var/tmp/test2_img successfully formatted as ext2 (label "test2_img", uuid ad584a5b-037b-497a-825d-eaf2ba90da2d)
ext3
/var/tmp/test2_img successfully formatted as ext3 (label "test2_img", uuid 95239fff-55f4-44d5-bae0-11ef75d13166)
ext4
/var/tmp/test2_img successfully formatted as ext4 (label "test2_img", uuid 8c7ea699-05ab-4ce6-8df6-bc20d53dfd29)
btrfs
/var/tmp/test2_img successfully formatted as btrfs (label "test2_img", uuid 860bb061-4d92-4607-8821-a9d00216490e)
xfs
/var/tmp/test2_img successfully formatted as xfs (label "test2_img", uuid f32499ea-7311-47bb-be57-da62e51d33ae)
vfat
mkfs.fat 4.2 (2021-01-31)
/var/tmp/test2_img successfully formatted as vfat (label "TEST2_IMG", uuid d1e4ae63)
swap
mkswap: /var/tmp/test2_img: insecure permissions 0644, fix with: chmod 0600 /var/tmp/test2_img

mkswap: /var/tmp/test2_img contains holes or other unsupported extents.
        This swap file can be rejected by kernel on swap activation!
        Use --verbose for more details.

Setting up swapspace version 1, size = 256 MiB (268431360 bytes)
LABEL=test2_img, UUID=16bc3d8c-98d4-462b-8ff8-338467cde871
/var/tmp/test2_img successfully formatted as swap (no label or uuid specified)
minix
21856 inodes
65535 blocks
Firstdatazone=696 (696)
Zonesize=1024
Maxsize=268966912

/var/tmp/test2_img successfully formatted as minix (no label or uuid specified)
2021-11-12 15:51:24 +01:00
Zbigniew Jędrzejewski-Szmek
8e93a614e7 makefs: also set uuid/label for ext2/ext3
We were only "supporting" ext4. Let's add "support", i.e. pass our optimization
options and uuid/label for the other two fses in the same family.

Nowadays there is separate code in the kernel, all three fs types are handled
by ext4 code. ext2 in particular is useful for in-memory devices: the journal
is just a waste of space there. ext3 is added for completeness mostly, since
ext4 should probably be used instead. But people might use it for testing or
for compatibility with older systems and I don't see much reason to not add
"support" here.
2021-11-09 09:12:01 +01:00
Zbigniew Jędrzejewski-Szmek
44cdeb6e33 makefs: reindent mkfs calls to follow the same style
I think this also makes it much easier to see what args are passed.
2021-11-09 09:12:01 +01:00
36 changed files with 634 additions and 110 deletions

View File

@ -1089,6 +1089,13 @@ ieee1394:ven000001F2mo*sp000001F2ver00000035
IEEE1394_UNIT_FUNCTION_MIDI=1
IEEE1394_UNIT_FUNCTION_AUDIO=1
ieee1394:node:ven0x0001f2units0x0001f2:0x000039
ieee1394:ven000001F2mo*sp000001F2ver00000039
ID_VENDOR_FROM_DATABASE=MOTU
ID_MODEL_FROM_DATABASE=Track 16
IEEE1394_UNIT_FUNCTION_MIDI=1
IEEE1394_UNIT_FUNCTION_AUDIO=1
ieee1394:node:ven0x0001f2units0x0001f2:0x000045
ieee1394:ven000001F2mo*sp000001F2ver00000045
ID_VENDOR_FROM_DATABASE=MOTU

View File

@ -44,9 +44,8 @@
url="https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html">binfmt-misc.rst</ulink> documentation
file for more information on registration of additional binary formats and how to write rules.</para>
<para>Empty lines and lines beginning with ; and # are ignored.
Note that this means you may not use ; and # as delimiter in
binary format rules.</para>
<para>Empty lines and lines beginning with <literal>;</literal> and <literal>#</literal> are ignored.
Note that this means you may not use those symbols as the delimiter in binary format rules.</para>
</refsect1>
<xi:include href="standard-conf.xml" xpointer="confd" />

View File

@ -52,7 +52,12 @@
systems and swap devices, and after checking that the block device does not already
contain a file system or other content, it will execute binaries specific to
each filesystem type (<filename>/sbin/mkfs.<replaceable>type</replaceable></filename>
or <filename>/sbin/mkswap</filename>).</para>
or <filename>/sbin/mkswap</filename>). For certain file system types (currently
ext2/ext3/<citerefentry project='man-pages'><refentrytitle>ext4</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry project='url'><refentrytitle url='https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs(5)'>btrfs</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>xfs</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
f2fs, vfat) and for swap devices, it will configure reasonable defaults and set
the file system label and UUID based on the device name.</para>
<para><filename>systemd-growfs</filename> knows very little about specific file
systems and swap devices, and will instruct the kernel to grow the mounted

View File

@ -348,7 +348,6 @@ possible_common_cc_flags = [
'-Werror=shift-count-overflow',
'-Werror=shift-overflow=2',
'-Werror=undef',
'-Werror=unused-function',
'-Wfloat-equal',
'-Wimplicit-fallthrough=5',
'-Winit-self',
@ -363,6 +362,7 @@ possible_common_cc_flags = [
'-Wstrict-aliasing=2',
'-Wstrict-prototypes',
'-Wsuggest-attribute=noreturn',
'-Wunused-function',
'-Wwrite-strings',
# negative arguments are correctly detected starting with meson 0.46.

View File

@ -1850,8 +1850,9 @@ static void filesystem_set_remove(Set *s, const FilesystemSet *set) {
}
}
static void dump_filesystem(const FilesystemSet *set) {
static void dump_filesystem_set(const FilesystemSet *set) {
const char *filesystem;
int r;
if (!set)
return;
@ -1863,8 +1864,38 @@ static void dump_filesystem(const FilesystemSet *set) {
ansi_normal(),
set->help);
NULSTR_FOREACH(filesystem, set->value)
printf(" %s%s%s\n", filesystem[0] == '@' ? ansi_underline() : "", filesystem, ansi_normal());
NULSTR_FOREACH(filesystem, set->value) {
const statfs_f_type_t *magic;
if (filesystem[0] == '@') {
printf(" %s%s%s\n", ansi_underline(), filesystem, ansi_normal());
continue;
}
r = fs_type_from_string(filesystem, &magic);
assert_se(r >= 0);
printf(" %s", filesystem);
for (size_t i = 0; magic[i] != 0; i++) {
const char *primary;
if (i == 0)
printf(" %s(magic: ", ansi_grey());
else
printf(", ");
printf("0x%llx", (unsigned long long) magic[i]);
primary = fs_type_to_string(magic[i]);
if (primary && !streq(primary, filesystem))
printf("[%s]", primary);
if (magic[i+1] == 0)
printf(")%s", ansi_normal());
}
printf("\n");
}
}
static int dump_filesystems(int argc, char *argv[], void *userdata) {
@ -1892,7 +1923,7 @@ static int dump_filesystems(int argc, char *argv[], void *userdata) {
if (!first)
puts("");
dump_filesystem(set);
dump_filesystem_set(set);
filesystem_set_remove(kernel, set);
if (i != FILESYSTEM_SET_KNOWN)
filesystem_set_remove(known, set);
@ -1913,8 +1944,29 @@ static int dump_filesystems(int argc, char *argv[], void *userdata) {
strv_sort(l);
STRV_FOREACH(filesystem, l)
STRV_FOREACH(filesystem, l) {
const statfs_f_type_t *magic;
bool is_primary = false;
assert(fs_type_from_string(*filesystem, &magic) >= 0);
for (size_t i = 0; magic[i] != 0; i++) {
const char *primary;
primary = fs_type_to_string(magic[i]);
assert(primary);
if (streq(primary, *filesystem))
is_primary = true;
}
if (!is_primary) {
log_debug("Skipping ungrouped file system '%s', because it's an alias for another one.", *filesystem);
continue;
}
printf("# %s\n", *filesystem);
}
}
if (k < 0) {
@ -1956,7 +2008,7 @@ static int dump_filesystems(int argc, char *argv[], void *userdata) {
"Filesystem set \"%s\" not found.", *name);
}
dump_filesystem(set);
dump_filesystem_set(set);
first = false;
}
}

View File

@ -13,7 +13,7 @@ static inline void _reset_errno_(int *saved_errno) {
errno = *saved_errno;
}
#define PROTECT_ERRNO \
#define PROTECT_ERRNO \
_cleanup_(_reset_errno_) _unused_ int _saved_errno_ = errno
#define UNPROTECT_ERRNO \

View File

@ -34,8 +34,11 @@ 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_MAGIC_NUMBER}
coda, {CODA_SUPER_MAGIC}
@ -45,19 +48,24 @@ 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}
@ -67,13 +75,18 @@ 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 offical 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}
@ -82,27 +95,33 @@ 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, {SMB_SUPER_MAGIC}
# smb3 is an alias for cifs
smb3, {CIFS_MAGIC_NUMBER}
# 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}

View File

@ -1,6 +1,17 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "filesystems-gperf.h"
#include "stat-util.h"
const char *fs_type_to_string(statfs_f_type_t magic) {
switch (magic) {
#include "filesystem-switch-case.h"
}
return NULL;
}
int fs_type_from_string(const char *name, const statfs_f_type_t **ret) {
const struct FilesystemMagic *fs_magic;
@ -13,7 +24,6 @@ int fs_type_from_string(const char *name, const statfs_f_type_t **ret) {
return -EINVAL;
*ret = fs_magic->magic;
return 0;
}
@ -47,18 +57,37 @@ const FilesystemSet filesystem_sets[_FILESYSTEM_SET_MAX] = {
"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] = {
@ -66,7 +95,14 @@ const FilesystemSet filesystem_sets[_FILESYSTEM_SET_MAX] = {
.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"
},
@ -83,14 +119,16 @@ const FilesystemSet filesystem_sets[_FILESYSTEM_SET_MAX] = {
.help = "Well-known network filesystems",
.value =
"afs\0"
"ceph\0"
"cifs\0"
"gfs\0"
"gfs2\0"
"ncpfs\0"
"ncp\0"
"ncpfs\0"
"nfs\0"
"nfs4\0"
"ocfs2\0"
"orangefs\0"
"pvfs2\0"
"smb3\0"
"smbfs\0"
@ -104,6 +142,14 @@ const FilesystemSet filesystem_sets[_FILESYSTEM_SET_MAX] = {
"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",

View File

@ -10,11 +10,14 @@
typedef enum FilesystemGroups {
/* Please leave BASIC_API first and KNOWN last, but sort the rest alphabetically */
FILESYSTEM_SET_BASIC_API,
FILESYSTEM_SET_ANONYMOUS,
FILESYSTEM_SET_APPLICATION,
FILESYSTEM_SET_AUXILIARY_API,
FILESYSTEM_SET_COMMON_BLOCK,
FILESYSTEM_SET_HISTORICAL_BLOCK,
FILESYSTEM_SET_NETWORK,
FILESYSTEM_SET_PRIVILEGED_API,
FILESYSTEM_SET_SECURITY,
FILESYSTEM_SET_TEMPORARY,
FILESYSTEM_SET_KNOWN,
_FILESYSTEM_SET_MAX,
@ -31,6 +34,7 @@ extern const FilesystemSet filesystem_sets[];
const FilesystemSet *filesystem_set_find(const char *name);
const char *fs_type_to_string(statfs_f_type_t magic);
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);

View File

@ -6,6 +6,9 @@ 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('%%'):

View File

@ -0,0 +1,63 @@
#!/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. Specifically:
#
# → cgroupfs took over the magic of cpuset
# → devtmpfs is not a file system of its own, but just a "named superblock" of tmpfs
# → ext4 is the newest revision of ext2 + ext3
# → fuseblk is closely related to fuse, so close that they share a single magic, but the latter is more common
# → gfs2 is the newest revision of gfs
# → vfat is the newest revision of msdos
# → ncpfs (not ncp) was the last name of the netware `file_system_type` name before it was removed in 2018
# → nfs4 is the newest revision of nfs
# → orangefs is the new name of pvfs2
# → smb3 is an alias for cifs
return name in (
"cpuset",
"devtmpfs",
"ext2",
"ext3",
"fuseblk",
"gfs",
"msdos",
"ncp",
"nfs",
"pvfs2",
"smb3",
)
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

@ -383,8 +383,8 @@ filesystem_includes = ['linux/magic.h',
check_filesystems = find_program('check-filesystems.sh')
r = run_command([check_filesystems, cpp, 'filesystems-gperf.gperf'] + filesystem_includes)
if r.returncode() != 0
error('found unknown filesystem(s) defined in kernel headers:\n\n' + r.stdout())
r.stdout()
error('found unknown filesystem(s) defined in kernel headers:\n\n' + r.stdout())
r.stdout()
endif
filesystems_gperf_h = custom_target(
@ -403,7 +403,17 @@ filesystem_list_h = custom_target(
'@INPUT@'],
capture : true)
basic_sources += [filesystem_list_h, filesystems_gperf_h]
generate_filesystem_switch_case_h = find_program('generate-filesystem-switch-case.py')
fname = 'filesystem-switch-case.h'
filesystem_switch_case_h = custom_target(
fname,
input : 'filesystems-gperf.gperf',
output : 'filesystem-switch-case.h',
command : [generate_filesystem_switch_case_h,
'@INPUT@'],
capture : true)
basic_sources += [filesystem_list_h, filesystem_switch_case_h, filesystems_gperf_h]
libbasic = static_library(
'basic',

View File

@ -172,3 +172,18 @@
#ifndef EXFAT_SUPER_MAGIC
#define EXFAT_SUPER_MAGIC 0x2011BAB0UL
#endif
/* Not exposed yet, internally actually called RPCAUTH_GSSMAGIC. Defined in net/sunrpc/rpc_pipe.c */
#ifndef RPC_PIPEFS_SUPER_MAGIC
#define RPC_PIPEFS_SUPER_MAGIC 0x67596969
#endif
/* Not exposed yet, defined at fs/ntfs/ntfs.h */
#ifndef NTFS_SB_MAGIC
#define NTFS_SB_MAGIC 0x5346544e
#endif
/* Not exposed yet, encoded literally in fs/ntfs3/super.c. */
#ifndef NTFS3_SUPER_MAGIC
#define NTFS3_SUPER_MAGIC 0x7366746e
#endif

View File

@ -373,7 +373,6 @@ bool fstype_is_network(const char *fstype) {
/* Filesystems not present in the internal database */
return STR_IN_SET(fstype,
"ceph",
"davfs",
"glusterfs",
"lustre",
@ -412,8 +411,8 @@ bool fstype_is_ro(const char *fstype) {
/* All Linux file systems that are necessarily read-only */
return STR_IN_SET(fstype,
"DM_verity_hash",
"iso9660",
"erofs",
"iso9660",
"squashfs");
}

View File

@ -124,11 +124,9 @@ int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar) {
}
bool utf8_is_printable_newline(const char* str, size_t length, bool allow_newline) {
const char *p;
assert(str);
for (p = str; length > 0;) {
for (const char *p = str; length > 0;) {
int encoded_len, r;
char32_t val;
@ -289,14 +287,12 @@ char *utf8_escape_non_printable_full(const char *str, size_t console_width, bool
}
char *ascii_is_valid(const char *str) {
const char *p;
/* Check whether the string consists of valid ASCII bytes,
* i.e values between 0 and 127, inclusive. */
assert(str);
for (p = str; *p; p++)
for (const char *p = str; *p; p++)
if ((unsigned char) *p >= 128)
return NULL;
@ -316,6 +312,37 @@ char *ascii_is_valid_n(const char *str, size_t len) {
return (char*) str;
}
int utf8_to_ascii(const char *str, char replacement_char, char **ret) {
/* Convert to a string that has only ASCII chars, replacing anything that is not ASCII
* by replacement_char. */
_cleanup_free_ char *ans = new(char, strlen(str) + 1);
if (!ans)
return -ENOMEM;
char *q = ans;
for (const char *p = str; *p; q++) {
int l;
l = utf8_encoded_valid_unichar(p, SIZE_MAX);
if (l < 0) /* Non-UTF-8, let's not even try to propagate the garbage */
return l;
if (l == 1)
*q = *p;
else
/* non-ASCII, we need to replace it */
*q = replacement_char;
p += l;
}
*q = '\0';
*ret = TAKE_PTR(ans);
return 0;
}
/**
* utf8_encode_unichar() - Encode single UCS-4 character as UTF-8
* @out_utf8: output buffer of at least 4 bytes or NULL

View File

@ -21,6 +21,8 @@ static inline char *utf8_is_valid(const char *s) {
char *ascii_is_valid(const char *s) _pure_;
char *ascii_is_valid_n(const char *str, size_t len);
int utf8_to_ascii(const char *str, char replacement_char, char **ret);
bool utf8_is_printable_newline(const char* str, size_t length, bool allow_newline) _pure_;
#define utf8_is_printable(str, length) utf8_is_printable_newline(str, length, true)

View File

@ -17,6 +17,7 @@
#include "errno-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "filesystems.h"
#include "fs-util.h"
#include "home-util.h"
#include "homed-home-bus.h"
@ -2466,19 +2467,6 @@ int home_get_disk_status(
ret_access_mode);
}
static const char *fstype_magic_to_name(statfs_f_type_t magic) {
/* For now, let's only translate the magic values of the file systems we actually are able to manage */
if (F_TYPE_EQUAL(magic, EXT4_SUPER_MAGIC))
return "ext4";
if (F_TYPE_EQUAL(magic, XFS_SUPER_MAGIC))
return "xfs";
if (F_TYPE_EQUAL(magic, BTRFS_SUPER_MAGIC))
return "btrfs";
return NULL;
}
int home_augment_status(
Home *h,
UserRecordLoadFlags flags,
@ -2518,7 +2506,7 @@ int home_augment_status(
if (r < 0)
return r;
fstype = fstype_magic_to_name(magic);
fstype = fs_type_to_string(magic);
if (disk_floor == UINT64_MAX || (disk_usage != UINT64_MAX && disk_floor < disk_usage))
disk_floor = disk_usage;

View File

@ -13,6 +13,8 @@
#endif
#include "sd-daemon.h"
#include "sd-device.h"
#include "sd-event.h"
#include "blkid-util.h"
#include "blockdev-util.h"
@ -45,6 +47,7 @@
#include "strv.h"
#include "sync-util.h"
#include "tmpfile-util.h"
#include "udev-util.h"
#include "user-util.h"
/* Round down to the nearest 4K size. Given that newer hardware generally prefers 4K sectors, let's align our
@ -1506,6 +1509,7 @@ int home_deactivate_luks(UserRecord *h, HomeSetup *setup) {
}
}
(void) wait_for_block_device_gone(setup, USEC_PER_SEC * 30);
setup->undo_dm = false;
if (user_record_luks_offline_discard(h))
@ -3196,3 +3200,127 @@ int home_unlock_luks(UserRecord *h, HomeSetup *setup, const PasswordCache *cache
log_info("LUKS device resumed.");
return 0;
}
static int device_is_gone(HomeSetup *setup) {
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
struct stat st;
int r;
assert(setup);
if (!setup->dm_node)
return true;
if (stat(setup->dm_node, &st) < 0) {
if (errno != ENOENT)
return log_error_errno(errno, "Failed to stat block device node %s: %m", setup->dm_node);
return true;
}
r = sd_device_new_from_stat_rdev(&d, &st);
if (r < 0) {
if (r != -ENODEV)
return log_error_errno(errno, "Failed to allocate device object from block device node %s: %m", setup->dm_node);
return true;
}
return false;
}
static int device_monitor_handler(sd_device_monitor *monitor, sd_device *device, void *userdata) {
HomeSetup *setup = userdata;
int r;
assert(setup);
if (!device_for_action(device, SD_DEVICE_REMOVE))
return 0;
/* We don't really care for the device object passed to us, we just check if the device node still
* exists */
r = device_is_gone(setup);
if (r < 0)
return r;
if (r > 0) /* Yay! we are done! */
(void) sd_event_exit(sd_device_monitor_get_event(monitor), 0);
return 0;
}
int wait_for_block_device_gone(HomeSetup *setup, usec_t timeout_usec) {
_cleanup_(sd_device_monitor_unrefp) sd_device_monitor *m = NULL;
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
int r;
assert(setup);
/* So here's the thing: we enable "deferred deactivation" on our dm-crypt volumes. This means they
* are automatically torn down once not used anymore (i.e. once unmounted). Which is great. It also
* means that when we deactivate a home directory and try to tear down the volume that backs it, it
* possibly is aleady torn down or in the process of being torn down, since we race against the
* automatic tearing down. Which is fine, we handle errors from that. However, we lose the ability to
* naturally wait for the tear down operation to complete: if we are not the ones who tear down the
* device we are also not the ones who naturally block on that operation. Hence let's add some code
* to actively wait for the device to go away, via sd-device. We'll call this whenever tearing down a
* LUKS device, to ensure the device is really really gone before we proceed. Net effect: "homectl
* deactivate foo && homectl activate foo" will work reliably, i.e. deactivation immediately followed
* by activation will work. Also, by the time deactivation completes we can guarantee that all data
* is sync'ed down to the lowest block layer as all higher levels are fully and entirely
* destructed. */
if (!setup->dm_name)
return 0;
assert(setup->dm_node);
log_debug("Waiting until %s disappears.", setup->dm_node);
r = sd_event_new(&event);
if (r < 0)
return log_error_errno(r, "Failed to allocate event loop: %m");
r = sd_device_monitor_new(&m);
if (r < 0)
return log_error_errno(r, "Failed to allocate device monitor: %m");
r = sd_device_monitor_filter_add_match_subsystem_devtype(m, "block", "disk");
if (r < 0)
return log_error_errno(r, "Failed to configure device monitor match: %m");
r = sd_device_monitor_attach_event(m, event);
if (r < 0)
return log_error_errno(r, "Failed to attach device monitor to event loop: %m");
r = sd_device_monitor_start(m, device_monitor_handler, setup);
if (r < 0)
return log_error_errno(r, "Failed to start device monitor: %m");
r = device_is_gone(setup);
if (r < 0)
return r;
if (r > 0) {
log_debug("%s has already disappeared before entering wait loop.", setup->dm_node);
return 0; /* gone already */
}
if (timeout_usec != USEC_INFINITY) {
r = sd_event_add_time_relative(event, NULL, CLOCK_MONOTONIC, timeout_usec, 0, NULL, NULL);
if (r < 0)
return log_error_errno(r, "Failed to add timer event: %m");
}
r = sd_event_loop(event);
if (r < 0)
return log_error_errno(r, "Failed to run event loop: %m");
r = device_is_gone(setup);
if (r < 0)
return r;
if (r == 0)
return log_error_errno(r, "Device %s still around.", setup->dm_node);
log_debug("Successfully waited until device %s disappeared.", setup->dm_node);
return 0;
}

View File

@ -43,3 +43,5 @@ int run_fallocate(int backing_fd, const struct stat *st);
int run_fallocate_by_path(const char *backing_path);
int run_mark_dirty(int fd, bool b);
int run_mark_dirty_by_path(const char *path, bool b);
int wait_for_block_device_gone(HomeSetup *setup, usec_t timeout_usec);

View File

@ -8,6 +8,7 @@
#include "copy.h"
#include "fd-util.h"
#include "fileio.h"
#include "filesystems.h"
#include "fs-util.h"
#include "home-util.h"
#include "homework-cifs.h"
@ -325,6 +326,10 @@ int home_setup_undo_dm(HomeSetup *setup, int level) {
if (r < 0)
return log_full_errno(level, r, "Failed to deactivate LUKS device: %m");
/* In case the device was already remove asynchronously by an early unmount via the deferred
* remove logic, let's wait for it */
(void) wait_for_block_device_gone(setup, USEC_PER_SEC * 30);
setup->undo_dm = false;
ret = 1;
} else
@ -704,14 +709,7 @@ static const char *file_system_type_fd(int fd) {
return NULL;
}
if (is_fs_type(&sfs, XFS_SB_MAGIC))
return "xfs";
if (is_fs_type(&sfs, EXT4_SUPER_MAGIC))
return "ext4";
if (is_fs_type(&sfs, BTRFS_SUPER_MAGIC))
return "btrfs";
return NULL;
return fs_type_to_string(sfs.f_type);
}
int home_extend_embedded_identity(UserRecord *h, UserRecord *used, HomeSetup *setup) {

View File

@ -12,8 +12,8 @@
#include "user-record-util.h"
typedef struct HomeSetup {
char *dm_name;
char *dm_node;
char *dm_name; /* "home-<username>" */
char *dm_node; /* "/dev/mapper/home-<username>" */
LoopDevice *loop;
struct crypt_device *crypt_device;

View File

@ -59,10 +59,10 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
fd = open(TUN_DEV, O_RDWR|O_CLOEXEC);
if (fd < 0)
return log_netdev_error_errno(netdev, -errno, "Failed to open tun dev: %m");
return log_netdev_error_errno(netdev, errno, "Failed to open tun dev: %m");
if (ioctl(fd, TUNSETIFF, ifr) < 0)
return log_netdev_error_errno(netdev, -errno, "TUNSETIFF failed on tun dev: %m");
return log_netdev_error_errno(netdev, errno, "TUNSETIFF failed on tun dev: %m");
if (netdev->kind == NETDEV_KIND_TAP)
t = TAP(netdev);
@ -79,7 +79,7 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
return log_netdev_error_errno(netdev, r, "Cannot resolve user name %s: %m", t->user_name);
if (ioctl(fd, TUNSETOWNER, uid) < 0)
return log_netdev_error_errno(netdev, -errno, "TUNSETOWNER failed on tun dev: %m");
return log_netdev_error_errno(netdev, errno, "TUNSETOWNER failed on tun dev: %m");
}
if (t->group_name) {
@ -90,12 +90,12 @@ static int netdev_tuntap_add(NetDev *netdev, struct ifreq *ifr) {
return log_netdev_error_errno(netdev, r, "Cannot resolve group name %s: %m", t->group_name);
if (ioctl(fd, TUNSETGROUP, gid) < 0)
return log_netdev_error_errno(netdev, -errno, "TUNSETGROUP failed on tun dev: %m");
return log_netdev_error_errno(netdev, errno, "TUNSETGROUP failed on tun dev: %m");
}
if (ioctl(fd, TUNSETPERSIST, 1) < 0)
return log_netdev_error_errno(netdev, -errno, "TUNSETPERSIST failed on tun dev: %m");
return log_netdev_error_errno(netdev, errno, "TUNSETPERSIST failed on tun dev: %m");
return 0;
}

View File

@ -14,6 +14,7 @@
#include "networkd-manager.h"
#include "networkd-network.h"
#include "networkd-queue.h"
#include "networkd-route-util.h"
#include "networkd-route.h"
#include "parse-util.h"
#include "string-util.h"
@ -1770,21 +1771,14 @@ int config_parse_address_scope(
return 0;
}
if (streq(rvalue, "host"))
n->scope = RT_SCOPE_HOST;
else if (streq(rvalue, "link"))
n->scope = RT_SCOPE_LINK;
else if (streq(rvalue, "global"))
n->scope = RT_SCOPE_UNIVERSE;
else {
r = safe_atou8(rvalue , &n->scope);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Could not parse address scope \"%s\", ignoring assignment: %m", rvalue);
return 0;
}
r = route_scope_from_string(rvalue);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Could not parse address scope \"%s\", ignoring assignment: %m", rvalue);
return 0;
}
n->scope = r;
n->scope_set = true;
TAKE_PTR(n);
return 0;
@ -1924,8 +1918,8 @@ static int address_section_verify(Address *address) {
if (address->scope_set && address->scope != RT_SCOPE_HOST)
log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: non-host scope is set in the [Address] section from line %u. "
"Ignoring Scope= setting.",
"%s: non-host scope is set for localhost address. "
"Ignoring Scope= setting in the [Address] section from line %u. ",
address->section->filename, address->section->line);
address->scope = RT_SCOPE_HOST;

View File

@ -49,7 +49,7 @@ static int run(int argc, char *argv[]) {
if (lock_fd < 0)
return log_error_errno(lock_fd, "Failed to lock whole block device of \"%s\": %m", device);
} else
log_info("%s is not a block device.", device);
log_debug("%s is not a block device, no need to lock.", device);
r = probe_filesystem(device, &detected);
if (r == -EUCLEAN)

View File

@ -8,6 +8,7 @@
#include "process-util.h"
#include "stdio-util.h"
#include "string-util.h"
#include "utf8.h"
int mkfs_exists(const char *fstype) {
const char *mkfs;
@ -31,6 +32,60 @@ int mkfs_exists(const char *fstype) {
return true;
}
static int mangle_linux_fs_label(const char *s, size_t max_len, char **ret) {
/* Not more than max_len bytes (12 or 16) */
assert(s);
assert(max_len > 0);
assert(ret);
const char *q;
char *ans;
for (q = s; *q;) {
int l;
l = utf8_encoded_valid_unichar(q, SIZE_MAX);
if (l < 0)
return l;
if ((size_t) (q - s + l) > max_len)
break;
q += l;
}
ans = memdup_suffix0(s, q - s);
if (!ans)
return -ENOMEM;
*ret = ans;
return 0;
}
static int mangle_fat_label(const char *s, char **ret) {
assert(s);
_cleanup_free_ char *q = NULL;
int r;
r = utf8_to_ascii(s, '_', &q);
if (r < 0)
return r;
/* Classic FAT only allows 11 character uppercase labels */
strshorten(q, 11);
ascii_strupper(q);
/* mkfs.vfat: Labels with characters *?.,;:/\|+=<>[]" are not allowed.
* Let's also replace any control chars. */
for (char *p = q; *p; p++)
if (strchr("*?.,;:/\\|+=<>[]\"", *p) || char_is_cc(*p))
*p = '_';
*ret = TAKE_PTR(q);
return 0;
}
int make_filesystem(
const char *node,
const char *fstype,
@ -38,7 +93,8 @@ int make_filesystem(
sd_id128_t uuid,
bool discard) {
_cleanup_free_ char *mkfs = NULL;
_cleanup_free_ char *mkfs = NULL, *mangled_label = NULL;
char vol_id[CONST_MAX(ID128_UUID_STRING_MAX, 8 + 1)] = {};
int r;
assert(node);
@ -63,64 +119,113 @@ int make_filesystem(
return log_oom();
}
if (STR_IN_SET(fstype, "ext2", "ext3", "ext4", "xfs", "swap")) {
size_t max_len =
streq(fstype, "xfs") ? 12 :
streq(fstype, "swap") ? 15 :
16;
r = mangle_linux_fs_label(label, max_len, &mangled_label);
if (r < 0)
return log_error_errno(r, "Failed to determine volume label from string \"%s\": %m", label);
label = mangled_label;
} else if (streq(fstype, "vfat")) {
r = mangle_fat_label(label, &mangled_label);
if (r < 0)
return log_error_errno(r, "Failed to determine FAT label from string \"%s\": %m", label);
label = mangled_label;
xsprintf(vol_id, "%08" PRIx32,
((uint32_t) uuid.bytes[0] << 24) |
((uint32_t) uuid.bytes[1] << 16) |
((uint32_t) uuid.bytes[2] << 8) |
((uint32_t) uuid.bytes[3])); /* Take first 32 bytes of UUID */
}
if (isempty(vol_id))
id128_to_uuid_string(uuid, vol_id);
r = safe_fork("(mkfs)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR, NULL);
if (r < 0)
return r;
if (r == 0) {
/* Child */
if (streq(fstype, "ext4"))
/* When changing this conditional, also adjust the log statement below. */
if (streq(fstype, "ext2"))
(void) execlp(mkfs, mkfs,
"-q",
"-L", label,
"-U", ID128_TO_UUID_STRING(uuid),
"-U", vol_id,
"-I", "256",
"-m", "0",
"-E", discard ? "discard,lazy_itable_init=1" : "nodiscard,lazy_itable_init=1",
node, NULL);
else if (STR_IN_SET(fstype, "ext3", "ext4"))
(void) execlp(mkfs, mkfs,
"-q",
"-L", label,
"-U", vol_id,
"-I", "256",
"-O", "has_journal",
"-m", "0",
"-E", discard ? "lazy_itable_init=1,discard" : "lazy_itable_init=1,nodiscard",
"-E", discard ? "discard,lazy_itable_init=1" : "nodiscard,lazy_itable_init=1",
node, NULL);
else if (streq(fstype, "btrfs")) {
if (discard)
(void) execlp(mkfs, mkfs, "-L", label, "-U", ID128_TO_UUID_STRING(uuid), node, NULL);
else
(void) execlp(mkfs, mkfs, "-L", label, "-U", ID128_TO_UUID_STRING(uuid), "--nodiscard", node, NULL);
(void) execlp(mkfs, mkfs,
"-q",
"-L", label,
"-U", vol_id,
node,
discard ? NULL : "--nodiscard",
NULL);
} else if (streq(fstype, "f2fs")) {
(void) execlp(mkfs, mkfs,
"-q",
"-g", /* "default options" */
"-f", /* force override, without this it doesn't seem to want to write to an empty partition */
"-l", label,
"-U", vol_id,
"-t", one_zero(discard),
node,
NULL);
} else if (streq(fstype, "xfs")) {
const char *j;
j = strjoina("uuid=", ID128_TO_UUID_STRING(uuid));
if (discard)
(void) execlp(mkfs, mkfs, "-L", label, "-m", j, "-m", "reflink=1", node, NULL);
else
(void) execlp(mkfs, mkfs, "-L", label, "-m", j, "-m", "reflink=1", "-K", node, NULL);
j = strjoina("uuid=", vol_id);
} else if (streq(fstype, "vfat")) {
char mangled_label[8 + 3 + 1], vol_id[8 + 1];
(void) execlp(mkfs, mkfs,
"-q",
"-L", label,
"-m", j,
"-m", "reflink=1",
node,
discard ? NULL : "-K",
NULL);
/* Classic FAT only allows 11 character uppercase labels */
strncpy(mangled_label, label, sizeof(mangled_label)-1);
mangled_label[sizeof(mangled_label)-1] = 0;
ascii_strupper(mangled_label);
xsprintf(vol_id, "%08" PRIx32,
((uint32_t) uuid.bytes[0] << 24) |
((uint32_t) uuid.bytes[1] << 16) |
((uint32_t) uuid.bytes[2] << 8) |
((uint32_t) uuid.bytes[3])); /* Take first 32 byte of UUID */
} else if (streq(fstype, "vfat"))
(void) execlp(mkfs, mkfs,
"-i", vol_id,
"-n", mangled_label,
"-n", label,
"-F", "32", /* yes, we force FAT32 here */
node, NULL);
} else if (streq(fstype, "swap")) {
else if (streq(fstype, "swap"))
/* TODO: add --quiet here if
* https://github.com/util-linux/util-linux/issues/1499 resolved. */
(void) execlp(mkfs, mkfs,
"-L", label,
"-U", ID128_TO_UUID_STRING(uuid),
"-U", vol_id,
node, NULL);
} else
else
/* Generic fallback for all other file systems */
(void) execlp(mkfs, mkfs, node, NULL);
@ -129,5 +234,12 @@ int make_filesystem(
_exit(EXIT_FAILURE);
}
if (STR_IN_SET(fstype, "ext2", "ext3", "ext4", "btrfs", "f2fs", "xfs", "vfat", "swap"))
log_info("%s successfully formatted as %s (label \"%s\", uuid %s)",
node, fstype, label, vol_id);
else
log_info("%s successfully formatted as %s (no label or uuid specified)",
node, fstype);
return 0;
}

View File

@ -522,7 +522,7 @@ static int remount_with_timeout(MountPoint *m, int umount_log_level) {
if (r < 0)
return r;
if (r == 0) {
log_info("Remounting '%s' read-only in with options '%s'.", m->path, m->remount_options);
log_info("Remounting '%s' read-only with options '%s'.", m->path, strna(m->remount_options));
/* Start the mount operation here in the child */
r = mount(NULL, m->path, NULL, m->remount_flags, m->remount_options);

View File

@ -465,7 +465,7 @@ static int merge_subprocess(Hashmap *images, const char *workspace) {
* but let the kernel do that entirely automatically, once our namespace dies. Note that this file
* system won't be visible to anyone but us, since we opened our own namespace and then made the
* /run/ hierarchy (which our workspace is contained in) MS_SLAVE, see above. */
r = mount_nofollow_verbose(LOG_ERR, "sysexit", workspace, "tmpfs", 0, "mode=0700");
r = mount_nofollow_verbose(LOG_ERR, "sysext", workspace, "tmpfs", 0, "mode=0700");
if (r < 0)
return r;

View File

@ -66,6 +66,33 @@ static void test_ascii_is_valid_n(void) {
assert_se( ascii_is_valid_n("\342\204\242", 0));
}
static void test_utf8_to_ascii_one(const char *s, int r_expected, const char *expected) {
_cleanup_free_ char *ans = NULL;
int r;
r = utf8_to_ascii(s, '*', &ans);
log_debug("\"%s\" → %d/\"%s\" (expected %d/\"%s\")", s, r, strnull(ans), r_expected, strnull(expected));
assert_se(r == r_expected);
assert_se(streq_ptr(ans, expected));
}
static void test_utf8_to_ascii(void) {
log_info("/* %s */", __func__);
test_utf8_to_ascii_one("asdf", 0, "asdf");
test_utf8_to_ascii_one("dąb", 0, "d*b");
test_utf8_to_ascii_one("żęśłą óźń", 0, "***** ***");
test_utf8_to_ascii_one("\342\204\242", 0, "*");
test_utf8_to_ascii_one("\342\204", -EINVAL, NULL); /* truncated */
test_utf8_to_ascii_one("\342", -EINVAL, NULL); /* truncated */
test_utf8_to_ascii_one("\302\256", 0, "*");
test_utf8_to_ascii_one("", 0, "");
test_utf8_to_ascii_one(" ", 0, " ");
test_utf8_to_ascii_one("\t", 0, "\t");
test_utf8_to_ascii_one("", 0, "*");
test_utf8_to_ascii_one("…👊🔪💐…", 0, "*****");
}
static void test_utf8_encoded_valid_unichar(void) {
log_info("/* %s */", __func__);
@ -241,6 +268,7 @@ int main(int argc, char *argv[]) {
test_utf8_is_printable();
test_ascii_is_valid();
test_ascii_is_valid_n();
test_utf8_to_ascii();
test_utf8_encoded_valid_unichar();
test_utf8_escape_invalid();
test_utf8_escape_non_printable();

View File

@ -10,7 +10,6 @@ TEST_NO_NSPAWN=1
. "${TEST_BASE_DIR:?}/test-functions"
QEMU_TIMEOUT=300
FSTYPE=ext4
TEST_FORCE_NEWIMAGE=1
do_test "$@"

View File

@ -3,9 +3,23 @@
set -e
TEST_DESCRIPTION="testing homed"
TEST_NO_QEMU=1
# Skip the qemu version of the test, unless we have btrfs
(modprobe -nv btrfs && command -v mkfs.btrfs) || TEST_NO_QEMU=1
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
# Need loop devices for mounting images
test_append_files() {
(
if [ "$TEST_NO_QEMU" != "1" ] ; then
instmods loop =block
install_dmevent
install_btrfs
generate_module_dependencies
fi
)
}
do_test "$@"

View File

@ -5,8 +5,7 @@ Before=local-fs.target
[Mount]
What=/dev/sda1
Where=/
Type=ext4
Options=errors=remount-ro,noatime
Options=noatime
[Install]
WantedBy=local-fs.target

View File

@ -26,7 +26,9 @@ inspect() {
systemd-analyze log-level debug
systemd-analyze log-target console
NEWPASSWORD=xEhErW0ndafV4s homectl create test-user --disk-size=20M
# we enable --luks-discard= since we run our tests in a tight VM, hence don't
# needlessly pressure for storage
NEWPASSWORD=xEhErW0ndafV4s homectl create test-user --disk-size=256M --luks-discard=yes
inspect test-user
PASSWORD=xEhErW0ndafV4s homectl authenticate test-user

View File

@ -12,9 +12,6 @@ L+ /etc/mtab - - - - ../proc/self/mounts
{% if HAVE_SMACK_RUN_LABEL %}
t /etc/mtab - - - - security.SMACK64=_
{% endif %}
{% if ENABLE_RESOLVE %}
L! /etc/resolv.conf - - - - ../run/systemd/resolve/stub-resolv.conf
{% endif %}
C! /etc/nsswitch.conf - - - -
{% if HAVE_PAM %}
C! /etc/pam.d - - - -

View File

@ -7,6 +7,7 @@ files = [['README', ''],
['journal-nocow.conf', ''],
['systemd-nologin.conf', 'HAVE_PAM'],
['systemd-nspawn.conf', 'ENABLE_MACHINED'],
['systemd-resolve.conf', 'ENABLE_RESOLVE'],
['systemd-tmp.conf', ''],
['portables.conf', 'ENABLE_PORTABLED'],
['systemd-pstore.conf', 'ENABLE_PSTORE'],

View File

@ -0,0 +1,10 @@
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# See tmpfiles.d(5) for details
L! /etc/resolv.conf - - - - ../run/systemd/resolve/stub-resolv.conf

View File

@ -16,6 +16,7 @@ DefaultDependencies=no
Conflicts=shutdown.target
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/
ConditionDirectoryNotEmpty=|/lib/binfmt.d