1
0
mirror of https://github.com/systemd/systemd synced 2026-03-13 00:24:48 +01:00

Compare commits

...

23 Commits

Author SHA1 Message Date
Frantisek Sumsal
3f161ba9bc test: make the test entrypoint scripts shellcheck-compliant 2021-04-20 10:26:43 +02:00
Lennart Poettering
4d686e6b0b mount-util: make umount_and_rmdir_and_freep() cleanup handler deal with NULL 2021-04-20 10:23:30 +02:00
Lennart Poettering
fd2f6f7248
Merge pull request #19096 from poettering/repart-features
repart: four new features: CopyBlocks=auto + --image= + ReadOnly=/Flags= + MakeDirectories=
2021-04-20 10:20:22 +02:00
Peter Hutterer
7a4afd3a15 shell-completion: use base.lst, not xorg.lst
Since 2005 xorg.lst has been the legacy symlink to the real file base.lst.
2021-04-20 10:19:41 +02:00
Lennart Poettering
7cc3966693 update TODO 2021-04-19 23:19:52 +02:00
Lennart Poettering
5a3b86404a test: add test for new repart features 2021-04-19 23:19:52 +02:00
Lennart Poettering
b620bf332f dissect: ext4 and loopback files are unimpressed by read-only access
Even if we set up a loopback device read-only and mount it read-only
this means nothing, ext4 will still write through to the backing storage
file.

Yes, I lost 6h debugging time on this.

Apparently, we have to specify "norecovery" when mounting such file
systems, to force them into truly read-only mode. Let's do so.
2021-04-19 23:16:02 +02:00
Lennart Poettering
e73309c532 repart: add new ReadOnly= and Flags= settings for repart dropins
Let's make the GPT partition flags configurable when creating new
partitions. This is primarily useful for the read-only flag (which we
want to set for verity enabled partitions).

This adds two settings for this: Flags= and ReadOnly=, which strictly
speaking are redundant. The main reason to have both is that usually the
ReadOnly= setting is the one wants to control, and it' more generic.
Moreover we might later on introduce inherting of flags from CopyBlocks=
partitions, where one might want to control most flags as is except for
the RO flag and similar, hence let's keep them separate.
2021-04-19 23:16:02 +02:00
Lennart Poettering
5c08da586f repart: add CopyBlocks=auto support
When using systemd-repart as an installer that replicates the install
medium on another medium it is useful to reference the root
partition/usr partition or verity data that is currently booted, in
particular in A/B scenarios where we have two copies and want to
reference the one we currently use. Let's add a CopyBlocks=auto for this
case: for a partition that uses that we'll copy a suitable partition
from the host.

CopyBlocks=auto finds the partition to copy like this: based on the
configured partition type uuid we determine the usual mount point (i.e.
for the /usr partition type we determine /usr/, and so on). We then
figure out the block device behind that path, through dm-verity and
dm-crypt if necessary. Finally, we compare the partition type uuid of
the partition found that way with the one we are supposed to fill and
only use it if it matches (the latter is primarily important on
dm-verity setups where a volume is likely backed by two partitions and
we need to find the right one).

This is particularly fun to use in conjunction with --image= (where
we'll restrict the device search onto the specify device, for security
reasons), as this allows "duplicating" an image like this:

    # systemd-repart --image=source.raw --empty=create --size=auto target.raw

If the right repart data is embedded into "source.raw" this will be able
to create and initialize a partition table on target.raw that carrries
all needed partitions, and will stream the source's file systems onto it
as configured.
2021-04-19 23:16:02 +02:00
Lennart Poettering
e81acfd251 gpt: add some simple helpers for categorizing GPT partition types 2021-04-19 23:16:02 +02:00
Lennart Poettering
f3859d5f55 loop-util: store device major/minor in LoopDevice object
Let's store this away. It's useful when matching up mounts (i.e.  struct
stat's .st_dev field) with loopback devices.
2021-04-19 23:16:02 +02:00
Lennart Poettering
d83d804863 repart: add high-level setting for creating dirs in formatted file systems
So far we already had the CopyFiles= option in systemd-repart drop-in
files, as a mechanism for populating freshly formatted file systems with
files and directories. This adds MakeDirectories= in similar style, and
creates simple directories as listed. The option is of course entirely
redundant, since the same can be done with CopyFiles= simply by copying
in a directory. It's kinda nice to encode the dirs to create directly in
the drop-in files however, instead of providing a directory subtree to
copy in somehere, to make the files more self-contained — since often
just creating dirs is entirely sufficient.

The main usecase for this are GPT OS images that carry only a /usr/
tree, and for which a root file system is only formatted on first boot
via repart.  Without any additional CopyFiles=/MakeDirectories=
configuration these root file systems are entirely empty of course
initially. To mount in the /usr/ tree, a directory inode for /usr/ to
mount over needs to be created.  systemd-nspawn will do so automatically
when booting up the image, as will the initrd during boot. However, this
requires the image to be writable – which is OK for npawn and
initrd-based boots, but there are plenty tools where read-only operation
is desirable after repart ran, before the image was booted for the first
time. Specifically, "systemd-dissect" opens the image in read-only to
inspect its contents, and this will only work of /usr/ can be properly
mounted. Moreover systemd-dissect --mount --read-only won't succeed
either if the fs is read-only.

Via MakeDirectories= we now provide a way that ensures that the image
can be mounted/inspected in a fully read-only way immediately after
systemd-repart completed. Specifically, let's consider a GPT disk image
shipping with a file usr/lib/repart.d/50-root.conf:

       [Partition]
       Type=root
       Format=btrfs
       MakeDirectories=/usr
       MakeDirectories=/efi

With this in place systemd-repart will create a root partition when run,
and add /usr and /efi into it as directory inods. This ensures that the
whole image can then be mounted truly read-only anf /usr and /efi can be
overmounted by the /usr partition and the ESP.
2021-04-19 23:16:02 +02:00
Lennart Poettering
78eee6ce4d repart: use free_and_strdup_warn() where appropriate 2021-04-19 23:16:02 +02:00
Lennart Poettering
be9ce0188e repart: deal with empty partition label sensibly
libfdisk appears to return NULL when encountering an empty partition
label, let's handle this sanely, and treat NULL and "" for the current
label as the same, but for the new label as distinct: there NULL means
nothing is set, and "" means an actual empty label.
2021-04-19 23:16:02 +02:00
Lennart Poettering
22163eb51b repart: handle DISCARD failing with EBUSY gracefully 2021-04-19 23:16:02 +02:00
Lennart Poettering
55d380144a repart: add one more overflow check 2021-04-19 23:16:02 +02:00
Lennart Poettering
d17db7b2bf repart: when we can't fit in all partitions explain how large the image would have to be 2021-04-19 23:16:02 +02:00
Lennart Poettering
252d626711 repart: add --image= switch
This is similar to the --image= switch in the other tools, like
systemd-sysusers or systemd-tmpfiles, i.e. it apply the configuration
from the image to the image.

This is particularly useful for downloading minimized GPT image, and
then extending it to the desired size via:

   # systemd-repart --image=foo.image --size=5G
2021-04-19 23:16:02 +02:00
Lennart Poettering
8e5f3cecdf repart: slightly improve error message if partition is not on dm-crypt/dm-verity 2021-04-19 23:16:02 +02:00
Lennart Poettering
0efb3f83da repart: move NOP destructors into shared code 2021-04-19 23:16:02 +02:00
Lennart Poettering
ef9c184d3d dissect: split read-only flag into two
Let's have one flag to request that when dissecting an image the
loopback device is made read-only, and another one to request that when
it is mounted to make it read-only. Previously both concepts were always
done read-only together.

(Of course, making the loopback device read-only but mounting it
read-write doesn't make too much sense, but the kernel should catch that
for us, no need to make restrictions from our side there)

Use-case for this: in systemd-repart we'd like to operate on images for
adding partitions. Thus we'd like to have the loopback device writable,
but if we read repart.d/ snippets from it, we want to do that read-only.
2021-04-19 23:16:02 +02:00
Lennart Poettering
0ade2213e6 repart: port more code to generic path_simplify_and_warn()
We have this nice helper, hence use it when parsing paths and logging
about it.
2021-04-19 23:16:02 +02:00
Lennart Poettering
a0ff997180 repart: fix incorrect error code propagation 2021-04-19 23:16:02 +02:00
72 changed files with 1380 additions and 310 deletions

2
TODO
View File

@ -400,8 +400,6 @@ Features:
* systemd-repart: allow sizing partitions as factor of available RAM, so that * systemd-repart: allow sizing partitions as factor of available RAM, so that
we can reasonably size swap partitions for hibernation. we can reasonably size swap partitions for hibernation.
* systemd-repart: allow managing the gpt read-only partition flag + auto-mount flag
* systemd-repart: allow boolean option that ensures that if existing partition * systemd-repart: allow boolean option that ensures that if existing partition
doesn't exist within the configured size bounds the whole command fails. This doesn't exist within the configured size bounds the whole command fails. This
is useful to implement ESP vs. XBOOTLDR schemes in installers: have one set is useful to implement ESP vs. XBOOTLDR schemes in installers: have one set

View File

@ -422,12 +422,25 @@
<varlistentry> <varlistentry>
<term><varname>CopyBlocks=</varname></term> <term><varname>CopyBlocks=</varname></term>
<listitem><para>Takes a path to a regular file, block device node or directory. If specified and the <listitem><para>Takes a path to a regular file, block device node or directory, or the special value
partition is newly created the data from the specified path is written to the newly created <literal>auto</literal>. If specified and the partition is newly created, the data from the specified
partition, on the block level. If a directory is specified the backing block device of the file path is written to the newly created partition, on the block level. If a directory is specified, the
system the directory is on is determined and the data read directly from that. This option is useful backing block device of the file system the directory is on is determined, and the data read directly
to efficiently replicate existing file systems on the block level on a new partition, for example to from that. This option is useful to efficiently replicate existing file systems onto new partitions
build a simple OS installer or OS image builder.</para> on the block level — for example to build a simple OS installer or an OS image builder.</para>
<para>If the special value <literal>auto</literal> is specified, the source to copy from is
automatically picked up from the running system (or the image specified with
<option>--image=</option> — if used). A partition that matches both the configured partition type (as
declared with <varname>Type=</varname> above), and the currently mounted directory appropriate for
that partition type is determined. For example, if the partition type is set to
<literal>root</literal> the partition backing the root directory (<filename>/</filename>) is used as
source to copy from — if its partition type is set to <literal>root</literal> as well. If the
declared type is <literal>usr</literal> the partition backing <filename>/usr/</filename> is used as
source to copy blocks from — if its partition type is set to <literal>usr</literal> too. The logic is
capable of automatically tracking down the the backing partitions for encrypted and Verity-enabled
volumes. <literal>CopyBlocks=auto</literal> is useful for implementing "self-replicating" systems,
i.e. systems that are their own installer.</para>
<para>The file specified here must have a size that is a multiple of the basic block size 512 and not <para>The file specified here must have a size that is a multiple of the basic block size 512 and not
be empty. If this option is used, the size allocation algorithm is slightly altered: the partition is be empty. If this option is used, the size allocation algorithm is slightly altered: the partition is
@ -486,7 +499,38 @@
<para>The copy operation is executed before the file system is registered in the partition table, <para>The copy operation is executed before the file system is registered in the partition table,
thus ensuring that a file system populated this way only ever exists fully initialized.</para> thus ensuring that a file system populated this way only ever exists fully initialized.</para>
<para>This option cannot be combined with <varname>CopyBlocks=</varname>.</para></listitem> <para>This option cannot be combined with <varname>CopyBlocks=</varname>.</para>
<para>When <command>systemd-repart</command> is invoked with the <option>--image=</option> or
<option>--root=</option> command line switches the source paths specified are taken relative to the
specified root directory or disk image root.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>MakeDirectories=</varname></term>
<listitem><para>akes one or more absolute paths, separated by whitespace, each declaring a directory
to create within the new file system. Behaviour is similar to <varname>CopyFiles=</varname>, but
instead of copying in a set of files this just creates the specified directories with the default
mode of 0755 owned by the root user and group, plus all their parent directories (with the same
ownership and access mode). To configure directories with different ownership or access mode, use
<varname>CopyFiles=</varname> and specify a source tree to copy containing appropriately
owned/configured directories. This option may be used more than once to create multiple
directories. When <varname>CopyFiles=</varname> and <varname>MakeDirectories=</varname> are used
together the former is applied first. If a directory listed already exists no operation is executed
(in particular, the ownership/access mode of the directories is left as is).</para>
<para>The primary usecase for this option is to create a minimal set of directories that may be
mounted over by other partitions contained in the same disk image. For example, a disk image where
the root file system is formatted at first boot might want to automatically pre-create
<filename>/usr/</filename> in it this way, so that the <literal>usr</literal> partition may
over-mount it.</para>
<para>Consider using
<citerefentry><refentrytitle>systemd-tmpfiles</refentrytitle><manvolnum>8</manvolnum></citerefentry>
with its <option>--image=</option> option to pre-create other, more complex directory hierarchies (as
well as other inodes) with fine-grained control of ownership, access modes and other file
attributes.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -521,6 +565,29 @@
factory reset operation. This functionality is useful to implement schemes where images can be reset factory reset operation. This functionality is useful to implement schemes where images can be reset
into their original state by removing partitions and creating them anew. Defaults to off.</para></listitem> into their original state by removing partitions and creating them anew. Defaults to off.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>Flags=</varname></term>
<listitem><para>Configures the 64bit GPT partition flags to set for the partition when creating
it. This option has no effect if the partition already exists. If not specified the flags values is
set to all zeroes, except if the partition type (as configured with <varname>Type=</varname> above)
refers to a Verity partition, in wich case bit 60 is set (i.e. the read-only bit). This bit may also
be configured separately via <varname>ReadOnly=</varname>, see below. Specify the flags value in
hexadecimal (by prefixing it with <literal>0x</literal>), binary (prefix <literal>0b</literal>) or
decimal (no prefix).</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>ReadOnly=</varname></term>
<listitem><para>Configures the Read-Only partition flags (bit 60) of the partition table entry. This
option is a friendly way to set bit 60 of the partition flags value without setting any of the other
bits, and may be set via <varname>Flags=</varname> too, see above.</para>
<para>If both <varname>Flags=</varname> and <varname>ReadOnly=</varname> are set the latter controls
the value of the flag.</para></listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>

View File

@ -40,16 +40,17 @@
<citerefentry><refentrytitle>repart.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>. <citerefentry><refentrytitle>repart.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para> </para>
<para>If invoked with no arguments, it operates on the block device backing the root file system partition <para>If invoked with no arguments, it operates on the block device backing the root file system
of the OS, thus growing and adding partitions of the booted OS image itself. When called in the initial partition of the running OS, thus growing and adding partitions of the booted OS image itself. If
RAM disk it operates on the block device backing <filename>/sysroot/</filename> instead, i.e. on the <varname>--image=</varname> is used it will operate on the specified image file. When called in the
block device the system will soon transition into. The <filename>systemd-repart.service</filename> <literal>initrd</literal> it operates on the block device backing <filename>/sysroot/</filename> instead,
service is generally run at boot in the initial RAM disk, in order to augment the partition table of the i.e. on the block device the system will soon transition into. The
OS before its partitions are mounted. <command>systemd-repart</command> (mostly) operates in a purely <filename>systemd-repart.service</filename> service is generally run at boot in the initial RAM disk, in
incremental mode: it only grows existing and adds new partitions; it does not shrink, delete or move order to augment the partition table of the OS before its partitions are
existing partitions. The service is intended to be run on every boot, but when it detects that the mounted. <command>systemd-repart</command> (mostly) operates in a purely incremental mode: it only grows
partition table already matches the installed <filename>repart.d/*.conf</filename> configuration existing and adds new partitions; it does not shrink, delete or move existing partitions. The service is
files, it executes no operation.</para> intended to be run on every boot, but when it detects that the partition table already matches the
installed <filename>repart.d/*.conf</filename> configuration files, it executes no operation.</para>
<para><command>systemd-repart</command> is intended to be used when deploying OS images, to automatically <para><command>systemd-repart</command> is intended to be used when deploying OS images, to automatically
adjust them to the system they are running on, during first boot. This way the deployed image can be adjust them to the system they are running on, during first boot. This way the deployed image can be
@ -251,13 +252,21 @@
<term><option>--root=</option></term> <term><option>--root=</option></term>
<listitem><para>Takes a path to a directory to use as root file system when searching for <listitem><para>Takes a path to a directory to use as root file system when searching for
<filename>repart.d/*.conf</filename> files and for the machine ID file to use as seed. By default <filename>repart.d/*.conf</filename> files, for the machine ID file to use as seed and for the
when invoked on the regular system this defaults to the host's root file system <varname>CopyFiles=</varname> and <varname>CopyBlocks=</varname> source files and directories. By
default when invoked on the regular system this defaults to the host's root file system
<filename>/</filename>. If invoked from the initial RAM disk this defaults to <filename>/</filename>. If invoked from the initial RAM disk this defaults to
<filename>/sysroot/</filename>, so that the tool operates on the configuration and machine ID stored <filename>/sysroot/</filename>, so that the tool operates on the configuration and machine ID stored
in the root file system later transitioned into itself.</para></listitem> in the root file system later transitioned into itself.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--image=</option></term>
<listitem><para>Takes a path to a disk image file or device to mount and use in a similar fashion to
<option>--root=</option>, see above.</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--seed=</option></term> <term><option>--seed=</option></term>

View File

@ -39,7 +39,7 @@ _localectl_set-x11-keymap() {
local -a _file _layout _model _variant _options local -a _file _layout _model _variant _options
local _xorg_lst local _xorg_lst
_xorg_lst=${"$($commands[pkg-config] xkeyboard-config --variable=xkb_base)"} _xorg_lst=${"$($commands[pkg-config] xkeyboard-config --variable=xkb_base)"}
_file=( ${(ps:\n\!:)"$(<$_xorg_lst/rules/xorg.lst)"} ) _file=( ${(ps:\n\!:)"$(<$_xorg_lst/rules/base.lst)"} )
_layout=( ${${${(M)${(f)_file[2]}:# *}# }%% *} ) _layout=( ${${${(M)${(f)_file[2]}:# *}# }%% *} )
_model=( ${${${(M)${(f)_file[1]}:# *}# }%% *} ) _model=( ${${${(M)${(f)_file[1]}:# *}# }%% *} )
_variant=( ${${${(M)${(f)_file[3]}:# *}# }%% *} ) _variant=( ${${${(M)${(f)_file[3]}:# *}# }%% *} )

View File

@ -1853,7 +1853,7 @@ int setup_namespace(
r = loop_device_make_by_path( r = loop_device_make_by_path(
root_image, root_image,
FLAGS_SET(dissect_image_flags, DISSECT_IMAGE_READ_ONLY) ? O_RDONLY : -1 /* < 0 means writable if possible, read-only as fallback */, FLAGS_SET(dissect_image_flags, DISSECT_IMAGE_DEVICE_READ_ONLY) ? O_RDONLY : -1 /* < 0 means writable if possible, read-only as fallback */,
FLAGS_SET(dissect_image_flags, DISSECT_IMAGE_NO_PARTITION_TABLE) ? 0 : LO_FLAGS_PARTSCAN, FLAGS_SET(dissect_image_flags, DISSECT_IMAGE_NO_PARTITION_TABLE) ? 0 : LO_FLAGS_PARTSCAN,
&loop_device); &loop_device);
if (r < 0) if (r < 0)

View File

@ -770,7 +770,7 @@ static int run(int argc, char *argv[]) {
r = loop_device_make_by_path( r = loop_device_make_by_path(
arg_image, arg_image,
FLAGS_SET(arg_flags, DISSECT_IMAGE_READ_ONLY) ? O_RDONLY : O_RDWR, FLAGS_SET(arg_flags, DISSECT_IMAGE_DEVICE_READ_ONLY) ? O_RDONLY : O_RDWR,
FLAGS_SET(arg_flags, DISSECT_IMAGE_NO_PARTITION_TABLE) ? 0 : LO_FLAGS_PARTSCAN, FLAGS_SET(arg_flags, DISSECT_IMAGE_NO_PARTITION_TABLE) ? 0 : LO_FLAGS_PARTSCAN,
&d); &d);
if (r < 0) if (r < 0)

File diff suppressed because it is too large Load Diff

View File

@ -61,4 +61,12 @@ int cryptsetup_get_token_as_json(struct crypt_device *cd, int idx, const char *v
int cryptsetup_get_keyslot_from_token(JsonVariant *v); int cryptsetup_get_keyslot_from_token(JsonVariant *v);
int cryptsetup_add_token_json(struct crypt_device *cd, JsonVariant *v); int cryptsetup_add_token_json(struct crypt_device *cd, JsonVariant *v);
#else
/* If libcryptsetup is not available, let's at least define the basic type and NOP destructors for it, to
* make a little bit less #ifdeferry necessary in main programs. */
struct crypt_device;
static inline void sym_crypt_free(struct crypt_device* cd) {}
static inline void sym_crypt_freep(struct crypt_device** cd) {}
#endif #endif

View File

@ -1408,7 +1408,7 @@ static int mount_partition(
if (streq(fstype, "crypto_LUKS")) if (streq(fstype, "crypto_LUKS"))
return -EUNATCH; return -EUNATCH;
rw = m->rw && !(flags & DISSECT_IMAGE_READ_ONLY); rw = m->rw && !(flags & DISSECT_IMAGE_MOUNT_READ_ONLY);
if (FLAGS_SET(flags, DISSECT_IMAGE_FSCK) && rw) { if (FLAGS_SET(flags, DISSECT_IMAGE_FSCK) && rw) {
r = run_fsck(node, fstype); r = run_fsck(node, fstype);
@ -1463,6 +1463,27 @@ static int mount_partition(
if (!strextend_with_separator(&options, ",", m->mount_options)) if (!strextend_with_separator(&options, ",", m->mount_options))
return -ENOMEM; return -ENOMEM;
/* So, when you request MS_RDONLY from ext4, then this means nothing. It happily still writes to the
* backing storage. What's worse, the BLKRO[GS]ET flag and (in case of loopback devices)
* LO_FLAGS_READ_ONLY don't mean anything, they affect userspace accesses only, and write accesses
* from the upper file system still get propagated through to the underlying file system,
* unrestricted. To actually get ext4/xfs/btrfs to stop writing to the device we need to specify
* "norecovery" as mount option, in addition to MS_RDONLY. Yes, this sucks, since it means we need to
* carry a per file system table here.
*
* Note that this means that we might not be able to mount corrupted file systems as read-only
* anymore (since in some cases the kernel implementations will refuse mounting when corrupted,
* read-only and "norecovery" is specified). But I think for the case of automatically determined
* mount options for loopback devices this is the right choice, since otherwise using the same
* loopback file twice even in read-only mode, is going to fail badly sooner or later. The usecase of
* making reuse of the immutable images "just work" is more relevant to us than having read-only
* access that actually modifies stuff work on such image files. Or to say this differently: if
* people want their file systems to be fixed up they should just open them in writable mode, where
* all these problems don't exist. */
if (!rw && STRPTR_IN_SET(fstype, "ext3", "ext4", "xfs", "btrfs"))
if (!strextend_with_separator(&options, ",", "norecovery"))
return -ENOMEM;
r = mount_nofollow_verbose(LOG_DEBUG, node, p, fstype, MS_NODEV|(rw ? 0 : MS_RDONLY), options); r = mount_nofollow_verbose(LOG_DEBUG, node, p, fstype, MS_NODEV|(rw ? 0 : MS_RDONLY), options);
if (r < 0) if (r < 0)
return r; return r;
@ -1756,7 +1777,7 @@ static int decrypt_partition(
return log_debug_errno(r, "Failed to load LUKS metadata: %m"); return log_debug_errno(r, "Failed to load LUKS metadata: %m");
r = sym_crypt_activate_by_passphrase(cd, name, CRYPT_ANY_SLOT, passphrase, strlen(passphrase), r = sym_crypt_activate_by_passphrase(cd, name, CRYPT_ANY_SLOT, passphrase, strlen(passphrase),
((flags & DISSECT_IMAGE_READ_ONLY) ? CRYPT_ACTIVATE_READONLY : 0) | ((flags & DISSECT_IMAGE_DEVICE_READ_ONLY) ? CRYPT_ACTIVATE_READONLY : 0) |
((flags & DISSECT_IMAGE_DISCARD_ON_CRYPTO) ? CRYPT_ACTIVATE_ALLOW_DISCARDS : 0)); ((flags & DISSECT_IMAGE_DISCARD_ON_CRYPTO) ? CRYPT_ACTIVATE_ALLOW_DISCARDS : 0));
if (r < 0) { if (r < 0) {
log_debug_errno(r, "Failed to activate LUKS device: %m"); log_debug_errno(r, "Failed to activate LUKS device: %m");
@ -2674,7 +2695,7 @@ int mount_image_privately_interactively(
r = loop_device_make_by_path( r = loop_device_make_by_path(
image, image,
FLAGS_SET(flags, DISSECT_IMAGE_READ_ONLY) ? O_RDONLY : O_RDWR, FLAGS_SET(flags, DISSECT_IMAGE_DEVICE_READ_ONLY) ? O_RDONLY : O_RDWR,
FLAGS_SET(flags, DISSECT_IMAGE_NO_PARTITION_TABLE) ? 0 : LO_FLAGS_PARTSCAN, FLAGS_SET(flags, DISSECT_IMAGE_NO_PARTITION_TABLE) ? 0 : LO_FLAGS_PARTSCAN,
&d); &d);
if (r < 0) if (r < 0)

View File

@ -87,13 +87,13 @@ static inline PartitionDesignator PARTITION_VERITY_OF(PartitionDesignator p) {
} }
typedef enum DissectImageFlags { typedef enum DissectImageFlags {
DISSECT_IMAGE_READ_ONLY = 1 << 0, DISSECT_IMAGE_DEVICE_READ_ONLY = 1 << 0, /* Make device read-only */
DISSECT_IMAGE_DISCARD_ON_LOOP = 1 << 1, /* Turn on "discard" if on a loop device and file system supports it */ DISSECT_IMAGE_DISCARD_ON_LOOP = 1 << 1, /* Turn on "discard" if on a loop device and file system supports it */
DISSECT_IMAGE_DISCARD = 1 << 2, /* Turn on "discard" if file system supports it, on all block devices */ DISSECT_IMAGE_DISCARD = 1 << 2, /* Turn on "discard" if file system supports it, on all block devices */
DISSECT_IMAGE_DISCARD_ON_CRYPTO = 1 << 3, /* Turn on "discard" also on crypto devices */ DISSECT_IMAGE_DISCARD_ON_CRYPTO = 1 << 3, /* Turn on "discard" also on crypto devices */
DISSECT_IMAGE_DISCARD_ANY = DISSECT_IMAGE_DISCARD_ON_LOOP | DISSECT_IMAGE_DISCARD_ANY = DISSECT_IMAGE_DISCARD_ON_LOOP |
DISSECT_IMAGE_DISCARD | DISSECT_IMAGE_DISCARD |
DISSECT_IMAGE_DISCARD_ON_CRYPTO, DISSECT_IMAGE_DISCARD_ON_CRYPTO,
DISSECT_IMAGE_GPT_ONLY = 1 << 4, /* Only recognize images with GPT partition tables */ DISSECT_IMAGE_GPT_ONLY = 1 << 4, /* Only recognize images with GPT partition tables */
DISSECT_IMAGE_GENERIC_ROOT = 1 << 5, /* If no partition table or only single generic partition, assume it's the root fs */ DISSECT_IMAGE_GENERIC_ROOT = 1 << 5, /* If no partition table or only single generic partition, assume it's the root fs */
DISSECT_IMAGE_MOUNT_ROOT_ONLY = 1 << 6, /* Mount only the root and /usr partitions */ DISSECT_IMAGE_MOUNT_ROOT_ONLY = 1 << 6, /* Mount only the root and /usr partitions */
@ -107,6 +107,9 @@ typedef enum DissectImageFlags {
DISSECT_IMAGE_MKDIR = 1 << 14, /* Make top-level directory to mount right before mounting, if missing */ DISSECT_IMAGE_MKDIR = 1 << 14, /* Make top-level directory to mount right before mounting, if missing */
DISSECT_IMAGE_USR_NO_ROOT = 1 << 15, /* If no root fs is in the image, but /usr is, then allow this (so that we can mount the rootfs as tmpfs or so */ DISSECT_IMAGE_USR_NO_ROOT = 1 << 15, /* If no root fs is in the image, but /usr is, then allow this (so that we can mount the rootfs as tmpfs or so */
DISSECT_IMAGE_REQUIRE_ROOT = 1 << 16, /* Don't accept disks without root partition (or at least /usr partition if DISSECT_IMAGE_USR_NO_ROOT is set) */ DISSECT_IMAGE_REQUIRE_ROOT = 1 << 16, /* Don't accept disks without root partition (or at least /usr partition if DISSECT_IMAGE_USR_NO_ROOT is set) */
DISSECT_IMAGE_MOUNT_READ_ONLY = 1 << 17, /* Make mounts read-only */
DISSECT_IMAGE_READ_ONLY = DISSECT_IMAGE_DEVICE_READ_ONLY |
DISSECT_IMAGE_MOUNT_READ_ONLY,
} DissectImageFlags; } DissectImageFlags;
struct DissectedImage { struct DissectedImage {

View File

@ -106,3 +106,54 @@ int gpt_partition_label_valid(const char *s) {
return char16_strlen(recoded) <= 36; return char16_strlen(recoded) <= 36;
} }
bool gpt_partition_type_is_root(sd_id128_t id) {
return sd_id128_equal(id, GPT_ROOT_X86) ||
sd_id128_equal(id, GPT_ROOT_X86_64) ||
sd_id128_equal(id, GPT_ROOT_ARM) ||
sd_id128_equal(id, GPT_ROOT_ARM_64) ||
sd_id128_equal(id, GPT_ROOT_IA64) ||
sd_id128_equal(id, GPT_ROOT_RISCV32) ||
sd_id128_equal(id, GPT_ROOT_RISCV64);
}
bool gpt_partition_type_is_root_verity(sd_id128_t id) {
return sd_id128_equal(id, GPT_ROOT_X86_VERITY) ||
sd_id128_equal(id, GPT_ROOT_X86_64_VERITY) ||
sd_id128_equal(id, GPT_ROOT_ARM_VERITY) ||
sd_id128_equal(id, GPT_ROOT_ARM_64_VERITY) ||
sd_id128_equal(id, GPT_ROOT_IA64_VERITY) ||
sd_id128_equal(id, GPT_ROOT_RISCV32_VERITY) ||
sd_id128_equal(id, GPT_ROOT_RISCV64_VERITY);
}
bool gpt_partition_type_is_usr(sd_id128_t id) {
return sd_id128_equal(id, GPT_USR_X86) ||
sd_id128_equal(id, GPT_USR_X86_64) ||
sd_id128_equal(id, GPT_USR_ARM) ||
sd_id128_equal(id, GPT_USR_ARM_64) ||
sd_id128_equal(id, GPT_USR_IA64) ||
sd_id128_equal(id, GPT_USR_RISCV32) ||
sd_id128_equal(id, GPT_USR_RISCV64);
}
bool gpt_partition_type_is_usr_verity(sd_id128_t id) {
return sd_id128_equal(id, GPT_USR_X86_VERITY) ||
sd_id128_equal(id, GPT_USR_X86_64_VERITY) ||
sd_id128_equal(id, GPT_USR_ARM_VERITY) ||
sd_id128_equal(id, GPT_USR_ARM_64_VERITY) ||
sd_id128_equal(id, GPT_USR_IA64_VERITY) ||
sd_id128_equal(id, GPT_USR_RISCV32_VERITY) ||
sd_id128_equal(id, GPT_USR_RISCV64_VERITY);
}
bool gpt_partition_type_knows_read_only(sd_id128_t id) {
return gpt_partition_type_is_root(id) ||
gpt_partition_type_is_usr(id) ||
sd_id128_equal(id, GPT_HOME) ||
sd_id128_equal(id, GPT_SRV) ||
sd_id128_equal(id, GPT_VAR) ||
sd_id128_equal(id, GPT_TMP) ||
gpt_partition_type_is_root_verity(id) || /* pretty much implied, but let's set the bit to make things really clear */
gpt_partition_type_is_usr_verity(id); /* ditto */
}

View File

@ -128,3 +128,10 @@ typedef struct GptPartitionType {
extern const GptPartitionType gpt_partition_type_table[]; extern const GptPartitionType gpt_partition_type_table[];
int gpt_partition_label_valid(const char *s); int gpt_partition_label_valid(const char *s);
bool gpt_partition_type_is_root(sd_id128_t id);
bool gpt_partition_type_is_root_verity(sd_id128_t id);
bool gpt_partition_type_is_usr(sd_id128_t id);
bool gpt_partition_type_is_usr_verity(sd_id128_t id);
bool gpt_partition_type_knows_read_only(sd_id128_t id);

View File

@ -353,6 +353,7 @@ int loop_device_make(
.nr = nr, .nr = nr,
.node = TAKE_PTR(loopdev), .node = TAKE_PTR(loopdev),
.relinquished = true, /* It's not allocated by us, don't destroy it when this object is freed */ .relinquished = true, /* It's not allocated by us, don't destroy it when this object is freed */
.devno = st.st_rdev,
}; };
*ret = d; *ret = d;
@ -425,6 +426,10 @@ int loop_device_make(
UINT64_C(240) * USEC_PER_MSEC * n_attempts/64)); UINT64_C(240) * USEC_PER_MSEC * n_attempts/64));
} }
if (fstat(loop_with_fd, &st) < 0)
return -errno;
assert(S_ISBLK(st.st_mode));
d = new(LoopDevice, 1); d = new(LoopDevice, 1);
if (!d) if (!d)
return -ENOMEM; return -ENOMEM;
@ -432,6 +437,7 @@ int loop_device_make(
.fd = TAKE_FD(loop_with_fd), .fd = TAKE_FD(loop_with_fd),
.node = TAKE_PTR(loopdev), .node = TAKE_PTR(loopdev),
.nr = nr, .nr = nr,
.devno = st.st_rdev,
}; };
*ret = d; *ret = d;

View File

@ -10,6 +10,7 @@ typedef struct LoopDevice LoopDevice;
struct LoopDevice { struct LoopDevice {
int fd; int fd;
int nr; int nr;
dev_t devno;
char *node; char *node;
bool relinquished; bool relinquished;
}; };

View File

@ -93,8 +93,10 @@ int mode_to_inaccessible_node(const char *runtime_dir, mode_t mode, char **dest)
/* Useful for usage with _cleanup_(), unmounts, removes a directory and frees the pointer */ /* Useful for usage with _cleanup_(), unmounts, removes a directory and frees the pointer */
static inline char* umount_and_rmdir_and_free(char *p) { static inline char* umount_and_rmdir_and_free(char *p) {
PROTECT_ERRNO; PROTECT_ERRNO;
(void) umount_recursive(p, 0); if (p) {
(void) rmdir(p); (void) umount_recursive(p, 0);
(void) rmdir(p);
}
return mfree(p); return mfree(p);
} }
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, umount_and_rmdir_and_free); DEFINE_TRIVIAL_CLEANUP_FUNC(char*, umount_and_rmdir_and_free);

View File

@ -1,17 +1,19 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="Basic systemd setup" TEST_DESCRIPTION="Basic systemd setup"
IMAGE_NAME="basic" IMAGE_NAME="basic"
RUN_IN_UNPRIVILEGED_CONTAINER=${RUN_IN_UNPRIVILEGED_CONTAINER:-yes} RUN_IN_UNPRIVILEGED_CONTAINER=${RUN_IN_UNPRIVILEGED_CONTAINER:-yes}
TEST_REQUIRE_INSTALL_TESTS=0 TEST_REQUIRE_INSTALL_TESTS=0
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
test_append_files() { test_append_files() {
# install tests manually so the test is functional even when -Dinstall-tests=false # install tests manually so the test is functional even when -Dinstall-tests=false
local dst="$1/usr/lib/systemd/tests/testdata/units/" local dst="${1:?}/usr/lib/systemd/tests/testdata/units/"
mkdir -p "$dst" mkdir -p "$dst"
cp -v $TEST_UNITS_DIR/{testsuite-01,end}.service $TEST_UNITS_DIR/testsuite.target "$dst" cp -v "$TEST_UNITS_DIR"/{testsuite-01,end}.service "$TEST_UNITS_DIR/testsuite.target" "$dst"
} }
do_test "$@" 01 do_test "$@" 01

View File

@ -1,5 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="Run unit tests under containers" TEST_DESCRIPTION="Run unit tests under containers"
RUN_IN_UNPRIVILEGED_CONTAINER=yes RUN_IN_UNPRIVILEGED_CONTAINER=yes
@ -11,53 +12,63 @@ frobnicate!
$KERNEL_APPEND $KERNEL_APPEND
" "
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
check_result_nspawn() { check_result_nspawn() {
local _ret=1 local workspace="${1:?}"
[[ -e $1/testok ]] && _ret=0 local ret=1
if [[ -s $1/failed ]]; then
_ret=$(($_ret+1)) [[ -e "$workspace/testok" ]] && ret=0
if [[ -s "$workspace/failed" ]]; then
ret=$((ret + 1))
echo "=== Failed test log ===" echo "=== Failed test log ==="
cat $1/failed cat "$workspace/failed"
else else
if [[ -s $1/skipped ]]; then if [[ -s "$workspace/skipped" ]]; then
echo "=== Skipped test log ==" echo "=== Skipped test log =="
cat $1/skipped cat "$workspace/skipped"
fi fi
if [[ -s $1/testok ]]; then if [[ -s "$workspace/testok" ]]; then
echo "=== Passed tests ===" echo "=== Passed tests ==="
cat $1/testok cat "$workspace/testok"
fi fi
fi fi
save_journal $1/var/log/journal
_umount_dir $initdir save_journal "$workspace/var/log/journal"
[[ -n "$TIMED_OUT" ]] && _ret=$(($_ret+1)) _umount_dir "${initdir:?}"
return $_ret
[[ -n "${TIMED_OUT:=}" ]] && ret=$((ret + 1))
return $ret
} }
check_result_qemu() { check_result_qemu() {
local _ret=1 local ret=1
mount_initdir mount_initdir
[[ -e $initdir/testok ]] && _ret=0 [[ -e "${initdir:?}/testok" ]] && ret=0
if [[ -s $initdir/failed ]]; then
_ret=$(($_ret+1)) if [[ -s "$initdir/failed" ]]; then
ret=$((ret + 1))
echo "=== Failed test log ===" echo "=== Failed test log ==="
cat $initdir/failed cat "$initdir/failed"
else else
if [[ -s $initdir/skipped ]]; then if [[ -s "$initdir/skipped" ]]; then
echo "=== Skipped test log ==" echo "=== Skipped test log =="
cat $initdir/skipped cat "$initdir/skipped"
fi fi
if [[ -s $initdir/testok ]]; then if [[ -s "$initdir/testok" ]]; then
echo "=== Passed tests ===" echo "=== Passed tests ==="
cat $initdir/testok cat "$initdir/testok"
fi fi
fi fi
save_journal $initdir/var/log/journal
_umount_dir $initdir save_journal "$initdir/var/log/journal"
[[ -n "$TIMED_OUT" ]] && _ret=$(($_ret+1)) _umount_dir "$initdir"
return $_ret
[[ -n "${TIMED_OUT:=}" ]] && ret=$((ret + 1))
return $ret
} }
do_test "$@" 02 do_test "$@" 02

View File

@ -1,9 +1,11 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="Job-related tests" TEST_DESCRIPTION="Job-related tests"
TEST_NO_QEMU=1 TEST_NO_QEMU=1
IMAGE_NAME="default" IMAGE_NAME="default"
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 03 do_test "$@" 03

View File

@ -1,7 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="Journal-related tests" TEST_DESCRIPTION="Journal-related tests"
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 04 do_test "$@" 04

View File

@ -1,7 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="Resource limits-related tests" TEST_DESCRIPTION="Resource limits-related tests"
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 05 do_test "$@" 05

View File

@ -1,5 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="SELinux tests" TEST_DESCRIPTION="SELinux tests"
IMAGE_NAME="selinux" IMAGE_NAME="selinux"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
@ -12,32 +13,39 @@ TEST_NO_NSPAWN=1
# Check if selinux-policy-devel is installed, and if it isn't bail out early instead of failing # Check if selinux-policy-devel is installed, and if it isn't bail out early instead of failing
test -f /usr/share/selinux/devel/include/system/systemd.if || exit 0 test -f /usr/share/selinux/devel/include/system/systemd.if || exit 0
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
SETUP_SELINUX=yes SETUP_SELINUX=yes
KERNEL_APPEND="$KERNEL_APPEND selinux=1 security=selinux" KERNEL_APPEND="${KERNEL_APPEND:=} selinux=1 security=selinux"
test_append_files() { test_append_files() {
( (
local workspace="${1:?}"
local policy_headers_dir=/usr/share/selinux/devel
local modules_dir=/var/lib/selinux
setup_selinux setup_selinux
local _modules_dir=/var/lib/selinux # Make sure we never expand this to "/..."
rm -rf $1/$_modules_dir rm -rf "${workspace:?}/$modules_dir"
if ! cp -ar $_modules_dir $1/$_modules_dir; then
dfatal "Failed to copy $_modules_dir" if ! cp -ar "$modules_dir" "$workspace/$modules_dir"; then
dfatal "Failed to copy $modules_dir"
exit 1 exit 1
fi fi
local _policy_headers_dir=/usr/share/selinux/devel rm -rf "${workspace:?}/$policy_headers_dir"
rm -rf $1/$_policy_headers_dir
inst_dir /usr/share/selinux inst_dir /usr/share/selinux
if ! cp -ar $_policy_headers_dir $1/$_policy_headers_dir; then
dfatal "Failed to copy $_policy_headers_dir" if ! cp -ar "$policy_headers_dir" "$workspace/$policy_headers_dir"; then
dfatal "Failed to copy $policy_headers_dir"
exit 1 exit 1
fi fi
mkdir $1/systemd-test-module mkdir "$workspace/systemd-test-module"
cp systemd_test.te $1/systemd-test-module cp systemd_test.te "$workspace/systemd-test-module"
cp systemd_test.if $1/systemd-test-module cp systemd_test.if "$workspace/systemd-test-module"
cp systemd_test.fc $1/systemd-test-module cp systemd_test.fc "$workspace/systemd-test-module"
dracut_install -o sesearch dracut_install -o sesearch
dracut_install runcon dracut_install runcon
dracut_install checkmodule semodule semodule_package m4 make load_policy sefcontext_compile dracut_install checkmodule semodule semodule_package m4 make load_policy sefcontext_compile

View File

@ -1,9 +1,11 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/1981" TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/1981"
TEST_NO_QEMU=1 TEST_NO_QEMU=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
NSPAWN_TIMEOUT=30 NSPAWN_TIMEOUT=30

View File

@ -1,10 +1,13 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2730" TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2730"
IMAGE_NAME="test08" IMAGE_NAME="test08"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
QEMU_TIMEOUT=300 QEMU_TIMEOUT=300
FSTYPE=ext4 FSTYPE=ext4
TEST_FORCE_NEWIMAGE=1 TEST_FORCE_NEWIMAGE=1

View File

@ -1,9 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2691" TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2691"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
QEMU_TIMEOUT=300 QEMU_TIMEOUT=300
do_test "$@" 09 do_test "$@" 09

View File

@ -1,7 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2467" TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2467"
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 10 do_test "$@" 10

View File

@ -1,8 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/3166" TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/3166"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 11 do_test "$@" 11

View File

@ -1,8 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/3171" TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/3171"
TEST_NO_QEMU=1 TEST_NO_QEMU=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 12 do_test "$@" 12

View File

@ -1,15 +1,19 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="systemd-nspawn smoke test" TEST_DESCRIPTION="systemd-nspawn smoke test"
IMAGE_NAME="nspawn" IMAGE_NAME="nspawn"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
test_append_files() { test_append_files() {
( (
../create-busybox-container $1/testsuite-13.nc-container local workspace="${1:?}"
initdir="$1/testsuite-13.nc-container" dracut_install nc ip md5sum
"$TEST_BASE_DIR/create-busybox-container" "$workspace/testsuite-13.nc-container"
initdir="$workspace/testsuite-13.nc-container" dracut_install nc ip md5sum
) )
} }

View File

@ -1,13 +1,15 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="/etc/machine-id testing" TEST_DESCRIPTION="/etc/machine-id testing"
IMAGE_NAME="badid" IMAGE_NAME="badid"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
test_append_files() { test_append_files() {
printf "556f48e837bc4424a710fa2e2c9d3e3c\ne3d\n" >$1/etc/machine-id printf "556f48e837bc4424a710fa2e2c9d3e3c\ne3d\n" >"${1:?}/etc/machine-id"
} }
do_test "$@" 14 do_test "$@" 14

View File

@ -1,8 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="Dropin tests" TEST_DESCRIPTION="Dropin tests"
TEST_NO_QEMU=1 TEST_NO_QEMU=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 15 do_test "$@" 15

View File

@ -1,9 +1,11 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="EXTEND_TIMEOUT_USEC=usec start/runtime/stop tests" TEST_DESCRIPTION="EXTEND_TIMEOUT_USEC=usec start/runtime/stop tests"
SKIP_INITRD=yes SKIP_INITRD=yes
TEST_NO_QEMU=1 TEST_NO_QEMU=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 16 do_test "$@" 16

View File

@ -1,10 +1,13 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="UDEV" TEST_DESCRIPTION="UDEV"
IMAGE_NAME="udev" IMAGE_NAME="udev"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
QEMU_TIMEOUT=500 QEMU_TIMEOUT=500
test_append_files() { test_append_files() {

View File

@ -1,8 +1,11 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="FailureAction= operation" TEST_DESCRIPTION="FailureAction= operation"
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
QEMU_TIMEOUT=600 QEMU_TIMEOUT=600
do_test "$@" 18 do_test "$@" 18

View File

@ -1,9 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="test cgroup delegation in the unified hierarchy" TEST_DESCRIPTION="test cgroup delegation in the unified hierarchy"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
QEMU_TIMEOUT=600 QEMU_TIMEOUT=600
UNIFIED_CGROUP_HIERARCHY=yes UNIFIED_CGROUP_HIERARCHY=yes

View File

@ -1,7 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="test changing main PID" TEST_DESCRIPTION="test changing main PID"
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 20 do_test "$@" 20

View File

@ -1,12 +1,15 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="Tmpfiles related tests" TEST_DESCRIPTION="Tmpfiles related tests"
TEST_NO_QEMU=1 TEST_NO_QEMU=1
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
test_append_files() { test_append_files() {
if [[ "$IS_BUILT_WITH_ASAN" == "yes" ]]; then if [[ "${IS_BUILT_WITH_ASAN:=}" == "yes" ]]; then
if [[ -z "$initdir" ]]; then if [[ -z "${initdir:=}" ]]; then
echo >&2 "\$initdir is not defined, can't continue" echo >&2 "\$initdir is not defined, can't continue"
exit 1 exit 1
fi fi

View File

@ -1,6 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="test Type=exec" TEST_DESCRIPTION="test Type=exec"
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 23 do_test "$@" 23

View File

@ -1,68 +1,77 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="cryptsetup systemd setup" TEST_DESCRIPTION="cryptsetup systemd setup"
IMAGE_NAME="cryptsetup" IMAGE_NAME="cryptsetup"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
TEST_FORCE_NEWIMAGE=1 TEST_FORCE_NEWIMAGE=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
check_result_qemu() { check_result_qemu() {
ret=1 local ret=1
mount_initdir mount_initdir
[[ -e $initdir/testok ]] && ret=0 [[ -e "${initdir:?}/testok" ]] && ret=0
[[ -f $initdir/failed ]] && cp -a $initdir/failed $TESTDIR [[ -f "$initdir/failed" ]] && cp -a "$initdir/failed" "${TESTDIR:?}"
cryptsetup luksOpen ${LOOPDEV}p2 varcrypt <$TESTDIR/keyfile
mount /dev/mapper/varcrypt $initdir/var cryptsetup luksOpen "${LOOPDEV:?}p2" varcrypt <"$TESTDIR/keyfile"
save_journal $initdir/var/log/journal mount /dev/mapper/varcrypt "$initdir/var"
_umount_dir $initdir/var save_journal "$initdir/var/log/journal"
_umount_dir $initdir _umount_dir "$initdir/var"
_umount_dir "$initdir"
cryptsetup luksClose /dev/mapper/varcrypt cryptsetup luksClose /dev/mapper/varcrypt
[[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed
echo $JOURNAL_LIST [[ -f "$TESTDIR/failed" ]] && cat "$TESTDIR/failed"
test -s $TESTDIR/failed && ret=$(($ret+1)) echo "${JOURNAL_LIST:-No journals were saved}"
test -s "$TESTDIR/failed" && ret=$((ret + 1))
return $ret return $ret
} }
test_create_image() { test_create_image() {
create_empty_image_rootdir create_empty_image_rootdir
echo -n test >$TESTDIR/keyfile
cryptsetup -q luksFormat --pbkdf pbkdf2 --pbkdf-force-iterations 1000 ${LOOPDEV}p2 $TESTDIR/keyfile echo -n test >"${TESTDIR:?}/keyfile"
cryptsetup luksOpen ${LOOPDEV}p2 varcrypt <$TESTDIR/keyfile cryptsetup -q luksFormat --pbkdf pbkdf2 --pbkdf-force-iterations 1000 "${LOOPDEV:?}p2" "$TESTDIR/keyfile"
cryptsetup luksOpen "${LOOPDEV}p2" varcrypt <"$TESTDIR/keyfile"
mkfs.ext4 -L var /dev/mapper/varcrypt mkfs.ext4 -L var /dev/mapper/varcrypt
mkdir -p $initdir/var mkdir -p "${initdir:?}/var"
mount /dev/mapper/varcrypt $initdir/var mount /dev/mapper/varcrypt "$initdir/var"
# Create what will eventually be our root filesystem onto an overlay # Create what will eventually be our root filesystem onto an overlay
( (
LOG_LEVEL=5 LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=/dev/mapper/varcrypt) # shellcheck source=/dev/null
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) source <(udevadm info --export --query=env --name=/dev/mapper/varcrypt)
# shellcheck source=/dev/null
source <(udevadm info --export --query=env --name="${LOOPDEV}p2")
setup_basic_environment setup_basic_environment
mask_supporting_services mask_supporting_services
install_dmevent install_dmevent
generate_module_dependencies generate_module_dependencies
cat >$initdir/etc/crypttab <<EOF cat >"$initdir/etc/crypttab" <<EOF
$DM_NAME UUID=$ID_FS_UUID /etc/varkey $DM_NAME UUID=$ID_FS_UUID /etc/varkey
EOF EOF
echo -n test >$initdir/etc/varkey echo -n test >"$initdir/etc/varkey"
cat $initdir/etc/crypttab | ddebug ddebug <"$initdir/etc/crypttab"
cat >>$initdir/etc/fstab <<EOF cat >>"$initdir/etc/fstab" <<EOF
/dev/mapper/varcrypt /var ext4 defaults 0 1 /dev/mapper/varcrypt /var ext4 defaults 0 1
EOF EOF
# Forward journal messages to the console, so we have something # Forward journal messages to the console, so we have something
# to investigate even if we fail to mount the encrypted /var # to investigate even if we fail to mount the encrypted /var
echo ForwardToConsole=yes >> $initdir/etc/systemd/journald.conf echo ForwardToConsole=yes >> "$initdir/etc/systemd/journald.conf"
) )
} }
cleanup_root_var() { cleanup_root_var() {
ddebug "umount $initdir/var" ddebug "umount ${initdir:?}/var"
mountpoint $initdir/var && umount $initdir/var mountpoint "$initdir/var" && umount "$initdir/var"
[[ -b /dev/mapper/varcrypt ]] && cryptsetup luksClose /dev/mapper/varcrypt [[ -b /dev/mapper/varcrypt ]] && cryptsetup luksClose /dev/mapper/varcrypt
} }

View File

@ -1,7 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="test importd" TEST_DESCRIPTION="test importd"
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 25 do_test "$@" 25

View File

@ -1,7 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="test setenv" TEST_DESCRIPTION="test setenv"
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 26 do_test "$@" 26

View File

@ -1,7 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="test StandardOutput=file:" TEST_DESCRIPTION="test StandardOutput=file:"
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 27 do_test "$@" 27

View File

@ -1,8 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="Ensure %j Wants directives work" TEST_DESCRIPTION="Ensure %j Wants directives work"
RUN_IN_UNPRIVILEGED_CONTAINER=yes RUN_IN_UNPRIVILEGED_CONTAINER=yes
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 28 do_test "$@" 28

View File

@ -2,12 +2,14 @@
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh # ex: ts=8 sw=4 sts=4 et filetype=sh
set -e set -e
TEST_DESCRIPTION="test systemd-portabled" TEST_DESCRIPTION="test systemd-portabled"
IMAGE_NAME="portabled" IMAGE_NAME="portabled"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
TEST_INSTALL_VERITY_MINIMAL=1 TEST_INSTALL_VERITY_MINIMAL=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
# Need loop devices for mounting images # Need loop devices for mounting images
test_append_files() { test_append_files() {

View File

@ -1,7 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="test OnClockChange= + OnTimezoneChange=" TEST_DESCRIPTION="test OnClockChange= + OnTimezoneChange="
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 30 do_test "$@" 30

View File

@ -1,9 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="plugged -> dead -> plugged issue #11997" TEST_DESCRIPTION="plugged -> dead -> plugged issue #11997"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
QEMU_TIMEOUT=300 QEMU_TIMEOUT=300
do_test "$@" 31 do_test "$@" 31

View File

@ -1,8 +1,11 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="test OOM killer logic" TEST_DESCRIPTION="test OOM killer logic"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
UNIFIED_CGROUP_HIERARCHY=yes UNIFIED_CGROUP_HIERARCHY=yes

View File

@ -2,7 +2,10 @@
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh # ex: ts=8 sw=4 sts=4 et filetype=sh
set -e set -e
TEST_DESCRIPTION="test CleanUnit" TEST_DESCRIPTION="test CleanUnit"
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 33 do_test "$@" 33

View File

@ -1,6 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="test migrating state directory from DynamicUser=1 to DynamicUser=0 and back" TEST_DESCRIPTION="test migrating state directory from DynamicUser=1 to DynamicUser=0 and back"
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 34 do_test "$@" 34

View File

@ -3,7 +3,10 @@ set -e
TEST_DESCRIPTION="test NUMAPolicy= and NUMAMask= options" TEST_DESCRIPTION="test NUMAPolicy= and NUMAMask= options"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
if qemu_min_version "5.2.0"; then if qemu_min_version "5.2.0"; then
QEMU_OPTIONS="-object memory-backend-ram,id=mem0,size=512M -numa node,memdev=mem0,nodeid=0" QEMU_OPTIONS="-object memory-backend-ram,id=mem0,size=512M -numa node,memdev=mem0,nodeid=0"
else else

View File

@ -2,7 +2,10 @@
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh # ex: ts=8 sw=4 sts=4 et filetype=sh
set -e set -e
TEST_DESCRIPTION="test RuntimeDirectoryPreserve=yes" TEST_DESCRIPTION="test RuntimeDirectoryPreserve=yes"
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 37 do_test "$@" 37

View File

@ -1,7 +1,10 @@
#!/bin/bash #!/bin/bash
set -e set -e
TEST_DESCRIPTION="test unit freezing and thawing via DBus and systemctl" TEST_DESCRIPTION="test unit freezing and thawing via DBus and systemctl"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 38 do_test "$@" 38

View File

@ -1,6 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="Test ExecReload= (PR #13098)" TEST_DESCRIPTION="Test ExecReload= (PR #13098)"
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 39 do_test "$@" 39

View File

@ -1,6 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="test ExecXYZEx= service unit dbus hookups" TEST_DESCRIPTION="test ExecXYZEx= service unit dbus hookups"
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 40 do_test "$@" 40

View File

@ -1,6 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="Test oneshot unit restart on failure" TEST_DESCRIPTION="Test oneshot unit restart on failure"
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 41 do_test "$@" 41

View File

@ -1,7 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="test that ExecStopPost= is always run" TEST_DESCRIPTION="test that ExecStopPost= is always run"
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 42 do_test "$@" 42

View File

@ -1,7 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="Test PrivateUsers=yes on user manager" TEST_DESCRIPTION="Test PrivateUsers=yes on user manager"
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
has_user_dbus_socket || exit 0 has_user_dbus_socket || exit 0

View File

@ -1,7 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="test log namespaces" TEST_DESCRIPTION="test log namespaces"
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 44 do_test "$@" 44

View File

@ -1,8 +1,10 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="testing homed" TEST_DESCRIPTION="testing homed"
TEST_NO_QEMU=1 TEST_NO_QEMU=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 46 do_test "$@" 46

View File

@ -1,6 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="Test that KillMode=mixed does not leave left over processes with ExecStopPost=" TEST_DESCRIPTION="Test that KillMode=mixed does not leave left over processes with ExecStopPost="
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 47 do_test "$@" 47

View File

@ -2,7 +2,10 @@
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh # ex: ts=8 sw=4 sts=4 et filetype=sh
set -e set -e
TEST_DESCRIPTION="test StartStopNoReload" TEST_DESCRIPTION="test StartStopNoReload"
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 48 do_test "$@" 48

View File

@ -2,6 +2,8 @@
set -e set -e
TEST_DESCRIPTION="test adding new BindPaths while unit is already running" TEST_DESCRIPTION="test adding new BindPaths while unit is already running"
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 49 do_test "$@" 49

View File

@ -2,12 +2,14 @@
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- # -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh # ex: ts=8 sw=4 sts=4 et filetype=sh
set -e set -e
TEST_DESCRIPTION="test systemd-dissect" TEST_DESCRIPTION="test systemd-dissect"
IMAGE_NAME="dissect" IMAGE_NAME="dissect"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
TEST_INSTALL_VERITY_MINIMAL=1 TEST_INSTALL_VERITY_MINIMAL=1
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
command -v mksquashfs >/dev/null 2>&1 || exit 0 command -v mksquashfs >/dev/null 2>&1 || exit 0
command -v veritysetup >/dev/null 2>&1 || exit 0 command -v veritysetup >/dev/null 2>&1 || exit 0

View File

@ -1,6 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="Test ExecCondition= does not restart on abnormal or failure" TEST_DESCRIPTION="Test ExecCondition= does not restart on abnormal or failure"
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 51 do_test "$@" 51

View File

@ -1,18 +1,20 @@
#!/bin/bash #!/bin/bash
set -e set -e
. $TEST_BASE_DIR/test-functions
TEST_REQUIRE_INSTALL_TESTS=0 TEST_REQUIRE_INSTALL_TESTS=0
TEST_DESCRIPTION="testing honor first shutdown" TEST_DESCRIPTION="testing honor first shutdown"
#INTERACTIVE_DEBUG=1
TEST_NO_QEMU=1 TEST_NO_QEMU=1
#Using timeout because if the test fails it can loop. # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
# Using timeout because if the test fails it can loop.
# The reason is because the poweroff executed by end.service # The reason is because the poweroff executed by end.service
# could turn into a reboot if the test fails. # could turn into a reboot if the test fails.
NSPAWN_TIMEOUT=20 NSPAWN_TIMEOUT=20
#Remove this file if it exists. this is used along with # Remove this file if it exists. This is used along with
# the make target "finish". Since concrete confirmaion is # the make target "finish". Since concrete confirmation is
# only found from the console during the poweroff. # only found from the console during the poweroff.
rm -f /tmp/honorfirstshutdown.log >/dev/null rm -f /tmp/honorfirstshutdown.log >/dev/null

View File

@ -4,8 +4,9 @@ set -e
TEST_DESCRIPTION="test timer units when initial clock is ahead" TEST_DESCRIPTION="test timer units when initial clock is ahead"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
future_date=$(date -u +%Y-%m-%dT%H:%M:%S -d '+3 days') QEMU_OPTIONS="-rtc base=$(date -u +%Y-%m-%dT%H:%M:%S -d '+3 days')"
QEMU_OPTIONS="-rtc base=${future_date}"
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 53 do_test "$@" 53

View File

@ -1,7 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="test credentials" TEST_DESCRIPTION="test credentials"
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 54 do_test "$@" 54

View File

@ -1,47 +1,56 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="systemd-oomd Memory Pressure Test" TEST_DESCRIPTION="systemd-oomd Memory Pressure Test"
. $TEST_BASE_DIR/test-functions # shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
check_result_nspawn() { check_result_nspawn() {
local workspace="${1:?}"
local ret=1 local ret=1
local journald_report="" local journald_report=""
local pids="" local pids=""
[[ -e $1/testok ]] && ret=0
if [[ -e $1/skipped ]]; then [[ -e "$workspace/testok" ]] && ret=0
if [[ -e "$workspace/skipped" ]]; then
echo "TEST-56-OOMD was skipped:" echo "TEST-56-OOMD was skipped:"
cat $1/skipped cat "$workspace/skipped"
ret=0 ret=0
fi fi
[[ -f $1/failed ]] && cp -a $1/failed $TESTDIR
save_journal $1/var/log/journal [[ -f "$workspace/failed" ]] && cp -a "$workspace/failed" "${TESTDIR:?}"
[[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed save_journal "$workspace/var/log/journal"
echo $JOURNAL_LIST [[ -f "$TESTDIR/failed" ]] && cat "$TESTDIR/failed"
test -s $TESTDIR/failed && ret=$(($ret+1)) echo "${JOURNAL_LIST:-No journals were saved}"
[ -n "$TIMED_OUT" ] && ret=$(($ret+1))
check_asan_reports "$1" || ret=$(($ret+1)) test -s "$TESTDIR/failed" && ret=$((ret + 1))
_umount_dir $initdir [ -n "${TIMED_OUT:=}" ] && ret=$((ret + 1))
check_asan_reports "$workspace" || ret=$((ret + 1))
_umount_dir "${initdir:?}"
return $ret return $ret
} }
check_result_qemu() { check_result_qemu() {
local ret=1 local ret=1
mount_initdir mount_initdir
[[ -e $initdir/testok ]] && ret=0 [[ -e "${initdir:?}/testok" ]] && ret=0
if [[ -e $initdir/skipped ]]; then if [[ -e "$initdir/skipped" ]]; then
echo "TEST-56-OOMD was skipped:" echo "TEST-56-OOMD was skipped:"
cat $initdir/skipped cat "$initdir/skipped"
ret=0 ret=0
fi fi
[[ -f $initdir/failed ]] && cp -a $initdir/failed $TESTDIR
save_journal $initdir/var/log/journal [[ -f "$initdir/failed" ]] && cp -a "$initdir/failed" "${TESTDIR:?}"
check_asan_reports "$initdir" || ret=$(($ret+1)) save_journal "$initdir/var/log/journal"
_umount_dir $initdir check_asan_reports "$initdir" || ret=$((ret + 1))
[[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed _umount_dir "$initdir"
echo $JOURNAL_LIST [[ -f "$TESTDIR/failed" ]] && cat "$TESTDIR/failed"
test -s $TESTDIR/failed && ret=$(($ret+1)) echo "${JOURNAL_LIST:-No journals were saved}"
[ -n "$TIMED_OUT" ] && ret=$(($ret+1))
test -s "$TESTDIR/failed" && ret=$((ret + 1))
[ -n "${TIMED_OUT:=}" ] && ret=$((ret + 1))
return $ret return $ret
} }

View File

@ -1,6 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="test ExitType=cgroup" TEST_DESCRIPTION="test ExitType=cgroup"
. $TEST_BASE_DIR/test-functions
# shellcheck source=test/test-functions
. "${TEST_BASE_DIR:?}/test-functions"
do_test "$@" 56 do_test "$@" 56

View File

@ -0,0 +1 @@
../TEST-01-BASIC/Makefile

6
test/TEST-58-REPART/test.sh Executable file
View File

@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -e
TEST_DESCRIPTION="test systemd-repart"
. $TEST_BASE_DIR/test-functions
do_test "$@" 56

View File

@ -0,0 +1,6 @@
[Unit]
Description=TEST-56-EXIT-TYPE
[Service]
ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
Type=oneshot

72
test/units/testsuite-58.sh Executable file
View File

@ -0,0 +1,72 @@
#!/usr/bin/env bash
set -eux
export SYSTEMD_LOG_LEVEL=debug
export PAGER=cat
mkdir -p /tmp/testsuite-58-defs/
# First part: create a disk image and verify its in order
cat > /tmp/testsuite-58-defs/esp.conf <<EOF
[Partition]
Type=esp
SizeMinBytes=10M
Format=vfat
EOF
cat > /tmp/testsuite-58-defs/usr.conf <<EOF
[Partition]
Type=usr
SizeMinBytes=10M
Format=ext4
ReadOnly=yes
EOF
cat > /tmp/testsuite-58-defs/root.conf <<EOF
[Partition]
Type=root
SizeMinBytes=10M
Format=ext4
MakeDirectories=/usr /efi
EOF
systemd-repart --definitions=/tmp/testsuite-58-defs/ --empty=create --size=auto --seed=750b6cd5c4ae4012a15e7be3c29e6a47 /var/tmp/testsuite-58.img
sfdisk --dump /var/tmp/testsuite-58.img > /tmp/testsuite-58.dump
grep -qxF '/var/tmp/testsuite-58.img1 : start= 2048, size= 20480, type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, uuid=39107B09-615D-48FB-BA37-C663885FCE67, name="esp"' /tmp/testsuite-58.dump
grep -qxF '/var/tmp/testsuite-58.img2 : start= 22528, size= 20480, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=60F33797-1D71-4DCB-AA6F-20564F036CD0, name="root-x86-64"' /tmp/testsuite-58.dump
grep -qxF '/var/tmp/testsuite-58.img3 : start= 43008, size= 20480, type=8484680C-9521-48C6-9C11-B0720656F69E, uuid=7E3369DD-D653-4513-ADF5-B993A9F20C16, name="usr-x86-64", attrs="GUID:60"' /tmp/testsuite-58.dump
# Second part, duplicate it with CopyBlocks=auto
cat > /tmp/testsuite-58-defs/esp.conf <<EOF
[Partition]
Type=esp
CopyBlocks=auto
EOF
cat > /tmp/testsuite-58-defs/usr.conf <<EOF
[Partition]
Type=usr
ReadOnly=yes
CopyBlocks=auto
EOF
cat > /tmp/testsuite-58-defs/root.conf <<EOF
[Partition]
Type=root
CopyBlocks=auto
EOF
systemd-repart --definitions=/tmp/testsuite-58-defs/ --empty=create --size=auto --seed=750b6cd5c4ae4012a15e7be3c29e6a47 --image=/var/tmp/testsuite-58.img /var/tmp/testsuite-58.2.img
cmp /var/tmp/testsuite-58.img /var/tmp/testsuite-58.2.img
rm -f /var/tmp/testsuite-58.img /var/tmp/testsuite-58.2.img /tmp/testsuite-58.dump
rm -rf /tmp/testsuite-58-defs/
echo OK >/testok
exit 0