Compare commits

..

99 Commits

Author SHA1 Message Date
Lennart Poettering 1f4faf21e8
Merge pull request #15197 from ssahani/smtp-dhcp
DHCP4: Add support to emit and receive SMTP servers.
2020-03-30 18:58:26 +02:00
Lennart Poettering 01262d0d9e
Merge pull request #13084 from ddstreet/log_time
log: add support for prefixing console log messages with current timestamp
2020-03-30 17:57:34 +02:00
Lennart Poettering 6305608f1c
Merge pull request #15194 from keur/import_pull_etag
import: Only keep RO copy if ETag header is set
2020-03-30 17:34:06 +02:00
Lennart Poettering 4c287f9a0b
Merge pull request #14853 from floppym/issue9806
safe_fork: unblock most signals before waiting for child
2020-03-30 17:27:55 +02:00
Lennart Poettering fef7397022
Merge pull request #15251 from keszybz/coverity-fixes
A few small fixups for stuff found by coverity
2020-03-30 17:18:35 +02:00
Frantisek Sumsal 15529f5cea
Merge pull request #14338 from keszybz/functional-test-rework
Functional test rework
2020-03-30 16:25:12 +02:00
Evgeny Vereshchagin 6b8d32ea7b ci: turn off FuzzBuzz
I don't think anyone uses it.
2020-03-30 14:57:22 +02:00
Susant Sahani ad1e288013 networkctl: Add support to display DHCP SMTP servers 2020-03-29 22:59:21 +02:00
Susant Sahani c1c6ff10a1 sd-network: Add support to emit and receive SMTP server information 2020-03-29 22:59:18 +02:00
Susant Sahani f6269fe7bb network: DHCP - add support to emit and receive SMTP server information 2020-03-29 22:59:11 +02:00
Zbigniew Jędrzejewski-Szmek 37bc9dcc09 nss-systemd: use _cleanup_ for pthread_mutex_{lock,unlock}
v2: separate the declaration from the assignment to appease clang.
2020-03-28 17:03:21 +01:00
Zbigniew Jędrzejewski-Szmek 29d4392ca0 basic: add _cleanup_ wrappers for pthread_mutex_{lock,unlock}
I put the helper functions in a separate header file, because they don't fit
anywhere else. pthread_mutex_{lock,unlock} is used in two places: nss-systemd
and hashmap. I don't indent to convert hashmap to use the helpers, because
there it'd make the code more complicated. Is it worth to create a new header
file even if the only use is in nss-systemd.c? I think yes, because it feels
clean and also I think it's likely that pthread_mutex_{lock,unlock} will be
used in other places later.
2020-03-28 13:29:39 +01:00
Zbigniew Jędrzejewski-Szmek e7e9a9d0dc nss-systemd: add missing jump to unlock mutex
CID#1412415.
2020-03-28 13:03:06 +01:00
Zbigniew Jędrzejewski-Szmek 42b977810d test-strv: add missing oom check
CID#1420259.
2020-03-28 12:46:52 +01:00
Zbigniew Jędrzejewski-Szmek 8af10ca3fc test: print test of name in output 2020-03-28 12:37:28 +01:00
Zbigniew Jędrzejewski-Szmek e2d612a8e4 meson: use find_program() for add-git-hook.sh
On azure systemd.systemd ci, the build would fail with:
meson.build:53:0: ERROR: Program or command '/home/appuser/fuzzer/tools/add-git-hook.sh' not found or not executable

We use find_program() for all helpers, so let's do it for this one too.
This should solve the issue, whatever it exactly is.
2020-03-28 12:37:28 +01:00
Zbigniew Jędrzejewski-Szmek f4c7bf9e90 test: run unittests with newlines in /proc/cmdline
This should help catch this class of errors.
2020-03-28 11:51:29 +01:00
Zbigniew Jędrzejewski-Szmek 1506edca91 test: stop caching loopdev
It is more trouble than it is worth. The setup is of a loopback device
is very quick, so it's better to always create it when needed and
immediately drop afterwards.
2020-03-28 11:51:29 +01:00
Zbigniew Jędrzejewski-Szmek 693ad298e9 test: perform partial cleanup after each test is run
This causes the unprivileged-nspawn-root directory to be removed
after running one test. The advantage is that we reduce the maximum
disk-space use quite a bit (47*400 MB → about 18GB).
2020-03-28 11:51:29 +01:00
Zbigniew Jędrzejewski-Szmek 108d00a6b2 test: simplify the Makefiles
has-overflow was a temporary hack that was removed in
844da987ef (Oct. 2016). All the makefiles
can be the same, and all the targets can be handled identically.
2020-03-28 11:51:29 +01:00
Zbigniew Jędrzejewski-Szmek ec43f6862e test: run tests directly from the loopback device
Before, we'd copy the test tree into nspawn-root, and run the tests from there.
This is OK, and doesn't actually take much extra time. But it uses quite a lot
of extra disk space. So let's make things a bit more efficient by running
directly from the image file.

We still run the unprivileged nspawn tests from a copy. Once the kernel
implements fs shift, we can do away with that too.
2020-03-28 11:51:29 +01:00
Zbigniew Jędrzejewski-Szmek eb1290ef35 test: wipe journal files after test
Otherwise they accumulate and create noise.
2020-03-28 11:51:29 +01:00
Zbigniew Jędrzejewski-Szmek b74a306197 test: echo a message when the tests fails
Sometimes it is not clear from the preceding output that there was a
failure.
2020-03-28 11:51:29 +01:00
Zbigniew Jędrzejewski-Szmek 9d84eb2053 test/TEST-01: allow running w/o -Dinstall-tests=true
This is useful for sanitizer builds under CI, see
https://github.com/systemd/systemd-centos-ci/pull/202#issuecomment-566476592.
2020-03-28 11:51:29 +01:00
Zbigniew Jędrzejewski-Szmek 8c3534b5db test: rework how images are created
Before, we'd create a separate image for each test, in
/var/tmp/systemd-test.XXXXX/rootdisk.img. Most of the images
where very similar, except that each one had some unit files installed
specifically for the test. The installation of those custom unit files
was removed in previous commits (all the unit files are always installed).

The new approach is to only create as few distinct images as possible.
We have:
default.img: the "normal" image suitable for almost all the tests
basic.img: the same as default image but doesn't mask any services
cryptsetup.img: p2 is used for encrypted /var
badid.img: /etc/machine-id is overwritten with stuff
selinux.img: with selinux added for fun and fun
and a few others:

ls -l build/test/*img
lrwxrwxrwx 1 root root 38 Mar 21 21:23 build/test/badid.img -> /var/tmp/systemd-test.PJFFeo/badid.img
lrwxrwxrwx 1 root root 38 Mar 21 21:17 build/test/basic.img -> /var/tmp/systemd-test.na0xOI/basic.img
lrwxrwxrwx 1 root root 43 Mar 21 21:18 build/test/cryptsetup.img -> /var/tmp/systemd-test.Tzjv06/cryptsetup.img
lrwxrwxrwx 1 root root 40 Mar 21 21:19 build/test/default.img -> /var/tmp/systemd-test.EscAsS/default.img
lrwxrwxrwx 1 root root 39 Mar 21 21:22 build/test/nspawn.img -> /var/tmp/systemd-test.HSebKo/nspawn.img
lrwxrwxrwx 1 root root 40 Mar 21 21:20 build/test/selinux.img -> /var/tmp/systemd-test.daBjbx/selinux.img
lrwxrwxrwx 1 root root 39 Mar 21 21:21 build/test/test08.img -> /var/tmp/systemd-test.OgnN8Z/test08.img

I considered trying to use the same image everywhere. It would probably be
possible, but it would be very brittle. By using separate images where it is
necessary we keep various orthogonal modifications independent.

The way that images are cached is complicated by the fact that we still
want to keep them in /var/tmp. Thus, an image is created on first use and
linked to from build/test/ so it can be found by other tests.

Tests cannot be run in parallel. I think that is an acceptable limitation.
Creation of the images was probably taking more resources then the actual
tests, so we should be better off anyway.
2020-03-28 11:51:29 +01:00
Zbigniew Jędrzejewski-Szmek 388b68a74f semaphoreci: trivial cleanup 2020-03-28 11:51:29 +01:00
Zbigniew Jędrzejewski-Szmek de0162a95a test/TEST-28: avoid race in handling of /testok 2020-03-28 11:51:29 +01:00
Zbigniew Jędrzejewski-Szmek 4962ed9f33 test: make sure to reset state before starting integration tests 2020-03-28 11:51:27 +01:00
Zbigniew Jędrzejewski-Szmek 8a59e79c09 test: mount root rw and drop /etc/fstab
We had an fstab for the sole purpose of remounting "/" rw. Mounting root ro
is a pointless excercise in obsolete approaches. More importantly, the nspawn
image is now the same as the qemu one.
2020-03-28 11:51:13 +01:00
Zbigniew Jędrzejewski-Szmek 50b836518c test: drop cargo-cult line
p2 is only used in the cryptsetup test...
2020-03-28 11:51:13 +01:00
Zbigniew Jędrzejewski-Szmek 80c53fe7d5 test: improve reporting a bit 2020-03-28 11:51:13 +01:00
Zbigniew Jędrzejewski-Szmek 70ce817ccb test: de-duplicate test_setup() functions
Now we will run setup_nspawn_root() in some case where do don't need to.
2020-03-28 11:51:11 +01:00
Zbigniew Jędrzejewski-Szmek bdfa9657d0 test: move TEST-47-* to static files 2020-03-28 11:50:53 +01:00
Zbigniew Jędrzejewski-Szmek 2c75449a38 test: move TEST-46-HOMED to static files 2020-03-28 11:50:53 +01:00
Zbigniew Jędrzejewski-Szmek e29e4d5742 test: convert TEST-45 to a normal meson test
On my laptop, it now takes 0.23 s. We don't need the overhead of creating
an image and spawning a machine to mangle a file in /tmp.
2020-03-28 11:50:38 +01:00
Zbigniew Jędrzejewski-Szmek 07d16f438a test: move TEST-44-* to static files 2020-03-28 11:46:48 +01:00
Zbigniew Jędrzejewski-Szmek d0ac89a1e8 test: move TEST-43-* setup to static files
Setup of lingering is dropped. I don't think it's necessary for anything,
because the unit is still pulled in from the testsuite service.
2020-03-28 11:46:48 +01:00
Zbigniew Jędrzejewski-Szmek bdfd515ad1 test: move TEST-42-EXECSTOPPOST setup to static files 2020-03-28 11:46:48 +01:00
Zbigniew Jędrzejewski-Szmek 0ac5dbf3ae test/TEST-41: use a file in /tmp and reset the contents
If the test was run a second time from the same root, it would fail.
2020-03-28 11:46:48 +01:00
Zbigniew Jędrzejewski-Szmek 2b2eefee06 test: move TEST-41-ONESHOT-RESTART setup to static files 2020-03-28 11:46:48 +01:00
Zbigniew Jędrzejewski-Szmek d48b27bffd test: move TEST-40-EXEC-COMMAND-EX setup to static files 2020-03-28 11:46:48 +01:00
Zbigniew Jędrzejewski-Szmek 7124ae207a test: move TEST-39-EXECRELOAD setup to static files 2020-03-28 11:46:48 +01:00
Zbigniew Jędrzejewski-Szmek 4db7d044b8 test: move TEST-37-RUNTIMEDIRECTORYPRESERVE setup to static files 2020-03-28 11:46:48 +01:00
Zbigniew Jędrzejewski-Szmek 534a42705b test/TEST-36: move the config files to /run
This way we always start with a clean slate when running the test
repeatedly.
2020-03-28 11:46:48 +01:00
Zbigniew Jędrzejewski-Szmek 097d8c6eb7 test: move TEST-36-NUMAPOLICY setup to static files
No need to call setup_nspawn_root() if we plan to only run under qemu.
2020-03-28 11:46:48 +01:00
Zbigniew Jędrzejewski-Szmek fbaa11372b test: convert TEST-35-NETWORK-GENERATOR into a unit test 2020-03-28 11:46:48 +01:00
Zbigniew Jędrzejewski-Szmek 01efa07960 test: move TEST-34-DYNAMICUSERMIGRATE setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek ff978cd24a test: move TEST-33-CLEAN-UNIT setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek c8937bed08 test: move TEST-32-OOMPOLICY setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 048d52d51e test: move TEST-31-DEVICE-ENUMERATION setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 7eeeab205d test: move TEST-30-ONCLOCKCHANGE setup to static files
The two timezone files are now installed in the global setup. I am not too
happy about this, but it still seems better than to create a completely
separate image just for this.
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek e578ea4df4 test: move TEST-29-UDEV-ID_RENAMING setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 94370e627f test: move TEST-28-PERCENTJ-WANTEDBY setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 468874997a test: move TEST-27-STDOUTFILE setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek dfa633ca6a test: move TEST-26-SETENV setup to static files
Also run mask_supporting_services() here.
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 68e2dc0f91 test/TEST-25: remove all images at the end of the test
scratch5 would be left behind, and trying to run the test again on the same
image would fail.
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 6e796683df test: move TEST-25-IMPORT setup to static files
Also run mask_supporting_services() here.
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek f4c40fd754 test: move TEST-24-UNIT-TESTS setup to static files
I picked the list of zone files to install by grepping through the code. This
is is a bit brittle, but installing all of them takes a while, and more
importantly, writes a lot of lines to the log.
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 30b84c78ea test-fileio: fix bogus error when /proc/cmdline contains newlines
The kernel does not sanitize /proc/cmdline. E.g. when running under qemu, it is
easy to pass a string with newline by mistake. We use read_one_line_file(), so
we would read only the first list of the file, and
write_string_file(WRITE_STRING_FILE_VERIFY_ON_FAILURE) would fail because the
target file is obviously different. Change to a kernel-generated file to avoid
the issue.

v2:
- use /proc/version instead of /proc/uptime for attempted writes, so the test
  test passes even if test_write_string_file_verify() takes more than 10 ms ;]
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek b49325d028 test: move TEST-23-TYPE-EXEC setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek c0b97b0fc8 test: move TEST-22-TMPFILES setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek c1d6c135bc test: move TEST-20-MAINPIDGAMES setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek e67a2644a8 test: move TEST-19-DELEGATE setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek dce2b8ce48 test: move TEST-18-FAILUREACTION setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 9911131a60 test: move TEST-17-WANTS setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek e5b0aaaf56 test/TEST-16: simplify how variables are set
The amount of lines doesn't change much, but I think it's much more
straightforward this way.
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 2b5981b40a test: move TEST-16-EXTEND-TIMEOUT setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 1aa0f38491 test/TEST-15: call daemon-reload in two more places
Sometimes the test would fail there, nondeterministically. I'm not sure why,
but relying on PID1 not caching the file is clearly very brittle. Let's instead
call daemon-reload.
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 4e2ac45a83 test/TEST-15: remove all created unit files
We would miss anything created under a template instance.
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 2c7519c036 test: move TEST-15-DROPIN setup to static files
Unfortunately the services needed to be renamed because of conflicts with other
services that exist in the shared dir.
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek afd9c55dcc test: move most of TEST-14-MACHINE-ID setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek e5badaf335 test: move most of TEST-13-NSPAWN-SMOKE setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek d10029bba4 test: move TEST-12-ISSUE-3171 setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 3ac189d8aa test: move TEST-11-ISSUE-3166 setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 8c6d58f65d test: move TEST-10-ISSUE-2467 setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 4110a6deb9 test: use shell arrays and remove duplicates
The tool lists are obviously not empty, so let's remove the test if they are.
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek e88302002f test: move TEST-09-ISSUE-2691 setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek c84752398b test: move TEST-08-ISSUE-2730 setup to static files and meson scripts
Unfortunately meson does not install symlinks, but copies the symlink
destination instead. So symlinks need to be created by a script.
This commit adds both symlinks in test/testsuite-08.units/ and meson
scriptlet calls. Strictly speaking, the first is not necessary, since nothing
reads stuff directly from the source tree.
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 58a1bdb467 test: move TEST-07-ISSUE-1981 setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 4caa1ac794 test/TEST-06: make autorelabel.service a static file too 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 1c76b5b5bb test/TEST-06: skip test if no selinux
I put SELINUX=disabled on my laptop, and the test fails with ENOENT when trying
to write to /sys/fs/selinux/enforce. It's a bit of a special case, but let's
avoid the failure.
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 1ed5556e56 test: move most of TEST-06-* setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek ed024e1d98 test: move TEST-05-RLIMITS setup to static files
The test currently fails in the check for LimitNOFILESoft/LimitNOFILE. I see
default values there. This doesn't seem to be related to the changes in the
test suite, but rather to the recent changes to pid1.
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 9901a6ad2e test: convert TEST-04-JOURNAL to generic image 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 41b1b2a563 test: move TEST-03-JOBS setup to static files 2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek 5964e39a69 test: move part of TEST-02-CRYPTSETUP setup to static files
Since we create an encrypted partition for this test, let's create a separate image here.
2020-03-28 11:46:47 +01:00
Zbigniew Jędrzejewski-Szmek fe85f2bb9c test: move TEST-01-BASIC setup to static files
After this commit, only tests that were converted will work, because the
interface to test_run() changed.
2020-03-28 11:46:47 +01:00
Susant Sahani 2c649ca1c9 sd-dhcp: Add support to emit and retrieve SMTP server 2020-03-28 11:21:17 +01:00
Kevin Kuehler 50dfca2eaf import: Only keep RO copy if ETag header is set
We fix the case when the webserver servers container images without
setting the ETag header in the response.  When an image is downloaded to
image root, a read only copy is stored alongside it.  The filename has
the following form:
    .raw-<encoded-url-of-image>.\x22<ETAG-header>\22.raw.
This is so, if the same resource is fetched multiple times, importd can
avoid extra downloads by creating the new image using the local read-only copy.

The current code assumes the ETag header is set because, if the server
does not set the ETag header, the file is stored without the ETag value
in the filename. When importd fetches a duplicate image, it will run
rename_noreplace and fail:

  Failed to rename raw file to /var/lib/machines/.raw-http:\x2f\x2flocalhost:8000\x2fwalkthroughd.raw: File exists

This patch makes importd only store a read-only image if the webserver
has set the ETag header.
2020-03-23 21:39:59 -07:00
Zbigniew Jędrzejewski-Szmek 5f28f3ddaf test: allow overriding EFI_MOUNT like other variables 2020-03-22 10:22:42 +01:00
Zbigniew Jędrzejewski-Szmek b6261be84d meson: report -Dinstall-tests in summary 2020-03-22 10:22:42 +01:00
Zbigniew Jędrzejewski-Szmek 80769cb66c meson: use install_subdir() to install files
This gives us slightly less control, but we don't need to update the
file list...
2020-03-22 10:22:42 +01:00
Zbigniew Jędrzejewski-Szmek f55198f034 test: replace symlinks with actual unit files
During installation, meson complains:
> Installing /home/zbyszek/src/systemd-work/test/units/sysinit.target to /var/tmp/systemd-test.Q1FSuj/root/usr/lib/systemd/tests/testdata/units
> Warning: trying to copy a symlink that points to a file. This will copy the file,
> but this will be changed in a future version of Meson to copy the symlink as is. Please update your
> build definitions so that it will not break when the change happens.

It *is* convenient to have those files as symlinks, but it is also confusing,
because symlinks create aliases, and it seems that in those cases we actually
don't want aliases (at least in the case of loopy*.service that'd make the test
pointless).
2020-03-22 10:22:42 +01:00
Zbigniew Jędrzejewski-Szmek 7b43295346 tests: move unit files to units/ subdirectory
We have a bazillion of those unit files, and keeping them all directly in tests/
has become rather unwieldy.
2020-03-19 16:23:27 +01:00
Mike Gilbert 4b3abcd019 safe_fork: use a cleanup function to restore signal mask in parent 2020-03-09 17:01:30 -04:00
Mike Gilbert d7e38115cb safe_fork: unblock most signals before waiting for child
This ensures we will recieve SIGTSTP if the user presses Ctrl-Z.

We continue blocking SIGCHLD to ensure the child is processed by
wait_for_terminate_and_check.

Fixes: https://github.com/systemd/systemd/issues/9806
2020-03-09 16:58:43 -04:00
Dan Streetman c5673ed0de log: add support for prefixing console log messages with current timestamp 2020-02-10 07:01:30 -05:00
Dan Streetman 2526af6ddd man: remove the '=' from --log-color and --log-location as they are optional arg
These params are optional arg, so remove the '=' from their doc.

Also include systemd.log_location in the statement explaining they are
set to true if no argument is provided to the parameter.
2020-02-10 07:01:30 -05:00
Dan Streetman 3d5f01383d man: sort log parameters in alphabetical order
This only sorts the --log-* params in order in the man page docs;
no text is added or removed or modified.
2020-02-10 07:01:30 -05:00
314 changed files with 2339 additions and 2701 deletions

View File

@ -1,33 +0,0 @@
base: ubuntu:16.04
language: c
setup:
- sudo bash -c "echo 'deb-src http://archive.ubuntu.com/ubuntu/ xenial main restricted universe multiverse' >>/etc/apt/sources.list"
- sudo apt-get update -y
- sudo apt-get build-dep -y systemd
- sudo apt-get install -y python3-pip
- sudo apt-get install -y libfdisk-dev libp11-kit-dev libssl-dev libpwquality-dev
- pip3 install meson ninja
- export PATH="$HOME/.local/bin/:$PATH"
- CC=$FUZZ_CC CXX=$FUZZ_CXX meson -Dfuzzbuzz=true -Dfuzzbuzz-engine-dir=$(dirname "$FUZZ_ENGINE") -Dfuzzbuzz-engine=$(cut -d. -f1 <(basename "$FUZZ_ENGINE")) -Db_lundef=false ./build
- ninja -v -C ./build fuzzers
environment:
targets:
- name: fuzz-compress
harness:
binary: ./build/fuzz-compress
- name: fuzz-unit-file
harness:
binary: ./build/fuzz-unit-file
corpus: ./test/fuzz/fuzz-unit-file
- name: fuzz-journald-syslog
harness:
binary: ./build/fuzz-journald-syslog
corpus: ./test/fuzz/fuzz-journald-syslog
- name: fuzz-netdev-parser
harness:
binary: ./build/fuzz-netdev-parser
corpus: ./test/fuzz/fuzz-netdev-parser
- name: fuzz-network-parser
harness:
binary: ./build/fuzz-network-parser
corpus: ./test/fuzz/fuzz-network-parser

View File

@ -141,6 +141,7 @@
<varlistentry> <varlistentry>
<term><varname>$SYSTEMD_LOG_TARGET</varname></term> <term><varname>$SYSTEMD_LOG_TARGET</varname></term>
<term><varname>$SYSTEMD_LOG_LEVEL</varname></term> <term><varname>$SYSTEMD_LOG_LEVEL</varname></term>
<term><varname>$SYSTEMD_LOG_TIME</varname></term>
<term><varname>$SYSTEMD_LOG_COLOR</varname></term> <term><varname>$SYSTEMD_LOG_COLOR</varname></term>
<term><varname>$SYSTEMD_LOG_LOCATION</varname></term> <term><varname>$SYSTEMD_LOG_LOCATION</varname></term>

View File

@ -63,10 +63,11 @@
<variablelist class='config-directives'> <variablelist class='config-directives'>
<varlistentry> <varlistentry>
<term><varname>LogLevel=</varname></term>
<term><varname>LogTarget=</varname></term>
<term><varname>LogColor=</varname></term> <term><varname>LogColor=</varname></term>
<term><varname>LogLevel=</varname></term>
<term><varname>LogLocation=</varname></term> <term><varname>LogLocation=</varname></term>
<term><varname>LogTarget=</varname></term>
<term><varname>LogTime=</varname></term>
<term><varname>DumpCore=yes</varname></term> <term><varname>DumpCore=yes</varname></term>
<term><varname>CrashChangeVT=no</varname></term> <term><varname>CrashChangeVT=no</varname></term>
<term><varname>CrashShell=no</varname></term> <term><varname>CrashShell=no</varname></term>

View File

@ -1910,6 +1910,16 @@
<listitem><para>Similar to the <varname>DNS=</varname> settings described above, these <listitem><para>Similar to the <varname>DNS=</varname> settings described above, these
settings configure whether and what POP3 server information shall be emitted as part of settings configure whether and what POP3 server information shall be emitted as part of
the DHCP lease. The same syntax, propagation semantics and defaults apply as for the DHCP lease. The same syntax, propagation semantics and defaults apply as for
<term><varname>SMTPServers=</varname></term>
<varname>DNS=</varname>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>SMTPServers=</varname></term>
<listitem><para>Similar to the <varname>DNS=</varname> setting described above, this
setting configures whether and what SMTP server information shall be emitted as part of
the DHCP lease. The same syntax, propagation semantics and defaults apply as for
<varname>DNS=</varname>.</para></listitem> <varname>DNS=</varname>.</para></listitem>
</varlistentry> </varlistentry>

View File

@ -606,6 +606,13 @@
<title>Environment</title> <title>Environment</title>
<variablelist class='environment-variables'> <variablelist class='environment-variables'>
<varlistentry>
<term><varname>$SYSTEMD_LOG_COLOR</varname></term>
<listitem><para>Controls whether systemd highlights important
log messages. This can be overridden with
<option>--log-color</option>.</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>$SYSTEMD_LOG_LEVEL</varname></term> <term><varname>$SYSTEMD_LOG_LEVEL</varname></term>
<listitem><para>systemd reads the log level from this <listitem><para>systemd reads the log level from this
@ -613,6 +620,13 @@
<option>--log-level=</option>.</para></listitem> <option>--log-level=</option>.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>$SYSTEMD_LOG_LOCATION</varname></term>
<listitem><para>Controls whether systemd prints the code
location along with log messages. This can be overridden with
<option>--log-location</option>.</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>$SYSTEMD_LOG_TARGET</varname></term> <term><varname>$SYSTEMD_LOG_TARGET</varname></term>
<listitem><para>systemd reads the log target from this <listitem><para>systemd reads the log target from this
@ -621,17 +635,10 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>$SYSTEMD_LOG_COLOR</varname></term> <term><varname>$SYSTEMD_LOG_TIME</varname></term>
<listitem><para>Controls whether systemd highlights important <listitem><para>Controls whether systemd prefixes log
log messages. This can be overridden with messages with the current time. This can be overridden with
<option>--log-color=</option>.</para></listitem> <option>--log-time=</option>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>$SYSTEMD_LOG_LOCATION</varname></term>
<listitem><para>Controls whether systemd prints the code
location along with log messages. This can be overridden with
<option>--log-location=</option>.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -829,18 +836,21 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>systemd.log_target=</varname></term>
<term><varname>systemd.log_level=</varname></term>
<term><varname>systemd.log_location=</varname></term>
<term><varname>systemd.log_color</varname></term> <term><varname>systemd.log_color</varname></term>
<term><varname>systemd.log_level=</varname></term>
<term><varname>systemd.log_location</varname></term>
<term><varname>systemd.log_target=</varname></term>
<term><varname>systemd.log_time</varname></term>
<listitem><para>Controls log output, with the same effect as the <listitem><para>Controls log output, with the same effect as the
<varname>$SYSTEMD_LOG_TARGET</varname>, <varname>$SYSTEMD_LOG_COLOR</varname>,
<varname>$SYSTEMD_LOG_LEVEL</varname>, <varname>$SYSTEMD_LOG_LEVEL</varname>,
<varname>$SYSTEMD_LOG_LOCATION</varname>, <varname>$SYSTEMD_LOG_LOCATION</varname>,
<varname>$SYSTEMD_LOG_COLOR</varname> environment variables described above. <varname>$SYSTEMD_LOG_TARGET</varname>,
<varname>systemd.log_color</varname> can be specified without an argument, <varname>$SYSTEMD_LOG_TIME</varname>, environment variables described above.
with the same effect as a positive boolean.</para></listitem> <varname>systemd.log_color</varname>, <varname>systemd.log_location</varname>, and
<varname>systemd.log_time</varname> can be specified without an argument, with the
same effect as a positive boolean.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -1135,9 +1145,10 @@
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>--log-target=</option></term> <term><option>--log-color</option></term>
<listitem><para>Set log target. See <varname>systemd.log_target</varname> above.</para></listitem> <listitem><para>Highlight important log messages. See <varname>systemd.log_color</varname> above.
</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -1146,13 +1157,6 @@
<listitem><para>Set log level. See <varname>systemd.log_level</varname> above.</para></listitem> <listitem><para>Set log level. See <varname>systemd.log_level</varname> above.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--log-color</option></term>
<listitem><para>Highlight important log messages. See <varname>systemd.log_color</varname> above.
</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--log-location</option></term> <term><option>--log-location</option></term>
@ -1160,6 +1164,19 @@
above.</para></listitem> above.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--log-target=</option></term>
<listitem><para>Set log target. See <varname>systemd.log_target</varname> above.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--log-time=</option></term>
<listitem><para>Prefix messages with timestamp. See <varname>systemd.log_time</varname> above.
</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--machine-id=</option></term> <term><option>--machine-id=</option></term>

View File

@ -39,20 +39,22 @@ conf.set_quoted('RELATIVE_SOURCE_PATH', relative_source_path)
want_ossfuzz = get_option('oss-fuzz') want_ossfuzz = get_option('oss-fuzz')
want_libfuzzer = get_option('llvm-fuzz') want_libfuzzer = get_option('llvm-fuzz')
want_fuzzbuzz = get_option('fuzzbuzz') if want_ossfuzz + want_libfuzzer > 1
if want_ossfuzz + want_libfuzzer + want_fuzzbuzz > 1 error('only one of oss-fuzz or llvm-fuzz can be specified')
error('only one of oss-fuzz, llvm-fuzz or fuzzbuzz can be specified')
endif endif
skip_deps = want_ossfuzz or want_libfuzzer skip_deps = want_ossfuzz or want_libfuzzer
fuzzer_build = want_ossfuzz or want_libfuzzer or want_fuzzbuzz fuzzer_build = want_ossfuzz or want_libfuzzer
##################################################################### #####################################################################
# Try to install the git pre-commit hook # Try to install the git pre-commit hook
git_hook = run_command(join_paths(project_source_root, 'tools/add-git-hook.sh')) add_git_hook_sh = find_program('tools/add-git-hook.sh', required : false)
if git_hook.returncode() == 0 if add_git_hook_sh.found()
git_hook = run_command(add_git_hook_sh)
if git_hook.returncode() == 0
message(git_hook.stdout().strip()) message(git_hook.stdout().strip())
endif
endif endif
##################################################################### #####################################################################
@ -322,8 +324,6 @@ if want_libfuzzer
endif endif
elif want_ossfuzz elif want_ossfuzz
fuzzing_engine = meson.get_compiler('cpp').find_library('FuzzingEngine') fuzzing_engine = meson.get_compiler('cpp').find_library('FuzzingEngine')
elif want_fuzzbuzz
fuzzing_engine = meson.get_compiler('cpp').find_library(get_option('fuzzbuzz-engine'), dirs: get_option('fuzzbuzz-engine-dir'))
endif endif
# Those generate many false positives, and we do not want to change the code to # Those generate many false positives, and we do not want to change the code to
@ -2506,7 +2506,7 @@ if conf.get('ENABLE_BINFMT') == 1
endif endif
if conf.get('ENABLE_REPART') == 1 if conf.get('ENABLE_REPART') == 1
executable('systemd-repart', exe = executable('systemd-repart',
systemd_repart_sources, systemd_repart_sources,
include_directories : includes, include_directories : includes,
link_with : [libshared], link_with : [libshared],
@ -2518,6 +2518,12 @@ if conf.get('ENABLE_REPART') == 1
install_rpath : rootlibexecdir, install_rpath : rootlibexecdir,
install : true, install : true,
install_dir : rootbindir) install_dir : rootbindir)
if want_tests != 'false'
test('test-repart',
test_repart_sh,
args : exe.full_path())
endif
endif endif
if conf.get('ENABLE_VCONSOLE') == 1 if conf.get('ENABLE_VCONSOLE') == 1
@ -2962,13 +2968,20 @@ if conf.get('ENABLE_NETWORKD') == 1
install_dir : rootbindir) install_dir : rootbindir)
public_programs += exe public_programs += exe
executable('systemd-network-generator', exe = executable('systemd-network-generator',
network_generator_sources, network_generator_sources,
include_directories : includes, include_directories : includes,
link_with : [networkd_link_with], link_with : [networkd_link_with],
install_rpath : rootlibexecdir, install_rpath : rootlibexecdir,
install : true, install : true,
install_dir : rootlibexecdir) install_dir : rootlibexecdir)
if want_tests != 'false'
test('test-network-generator-conversion',
test_network_generator_conversion_sh,
# https://github.com/mesonbuild/meson/issues/2681
args : exe.full_path())
endif
endif endif
executable('systemd-sulogin-shell', executable('systemd-sulogin-shell',
@ -3099,7 +3112,7 @@ foreach tuple : fuzzers
incs = tuple.length() >= 5 ? tuple[4] : includes incs = tuple.length() >= 5 ? tuple[4] : includes
link_args = [] link_args = []
if want_ossfuzz or want_fuzzbuzz if want_ossfuzz
dependencies += fuzzing_engine dependencies += fuzzing_engine
elif want_libfuzzer elif want_libfuzzer
if fuzzing_engine.found() if fuzzing_engine.found()
@ -3111,10 +3124,6 @@ foreach tuple : fuzzers
sources += 'src/fuzz/fuzz-main.c' sources += 'src/fuzz/fuzz-main.c'
endif endif
if want_fuzzbuzz
sources += 'src/fuzz/fuzzer-entry-point.c'
endif
name = sources[0].split('/')[-1].split('.')[0] name = sources[0].split('/')[-1].split('.')[0]
fuzzer_exes += executable( fuzzer_exes += executable(
@ -3474,6 +3483,7 @@ foreach tuple : [
['debug siphash'], ['debug siphash'],
['valgrind', conf.get('VALGRIND') == 1], ['valgrind', conf.get('VALGRIND') == 1],
['trace logging', conf.get('LOG_TRACE') == 1], ['trace logging', conf.get('LOG_TRACE') == 1],
['install tests', install_tests],
['link-udev-shared', get_option('link-udev-shared')], ['link-udev-shared', get_option('link-udev-shared')],
['link-systemctl-shared', get_option('link-systemctl-shared')], ['link-systemctl-shared', get_option('link-systemctl-shared')],
['link-networkd-shared', get_option('link-networkd-shared')], ['link-networkd-shared', get_option('link-networkd-shared')],

View File

@ -354,9 +354,3 @@ option('oss-fuzz', type : 'boolean', value : 'false',
description : 'build against oss-fuzz') description : 'build against oss-fuzz')
option('llvm-fuzz', type : 'boolean', value : 'false', option('llvm-fuzz', type : 'boolean', value : 'false',
description : 'build against LLVM libFuzzer') description : 'build against LLVM libFuzzer')
option('fuzzbuzz', type : 'boolean', value : 'false',
description : 'build against FuzzBuzz')
option('fuzzbuzz-engine', type : 'string',
description : 'the name of the FuzzBuzz fuzzing engine')
option('fuzzbuzz-engine-dir', type : 'string',
description : 'the directory where the FuzzBuzz fuzzing engine is')

View File

View File

@ -17,7 +17,7 @@ PHASES=(${@:-SETUP RUN})
create_container() { create_container() {
# create autopkgtest LXC image; this sometimes fails with "Unable to fetch # create autopkgtest LXC image; this sometimes fails with "Unable to fetch
# GPG key from keyserver", so retry a few times # GPG key from keyserver", so retry a few times
for retry in $(seq 5); do for retry in {1..5}; do
sudo lxc-create -n $CONTAINER -t download -- -d $DISTRO -r $RELEASE -a $ARCH --keyserver hkp://keyserver.ubuntu.com:80 && break sudo lxc-create -n $CONTAINER -t download -- -d $DISTRO -r $RELEASE -a $ARCH --keyserver hkp://keyserver.ubuntu.com:80 && break
sleep $((retry*retry)) sleep $((retry*retry))
done done

View File

@ -51,6 +51,7 @@ static bool syslog_is_stream = false;
static bool show_color = false; static bool show_color = false;
static bool show_location = false; static bool show_location = false;
static bool show_time = false;
static bool upgrade_syslog_to_journal = false; static bool upgrade_syslog_to_journal = false;
static bool always_reopen_console = false; static bool always_reopen_console = false;
@ -332,8 +333,10 @@ static int write_to_console(
const char *func, const char *func,
const char *buffer) { const char *buffer) {
char location[256], prefix[1 + DECIMAL_STR_MAX(int) + 2]; char location[256],
struct iovec iovec[6] = {}; header_time[FORMAT_TIMESTAMP_MAX],
prefix[1 + DECIMAL_STR_MAX(int) + 2];
struct iovec iovec[8] = {};
const char *on = NULL, *off = NULL; const char *on = NULL, *off = NULL;
size_t n = 0; size_t n = 0;
@ -345,6 +348,13 @@ static int write_to_console(
iovec[n++] = IOVEC_MAKE_STRING(prefix); iovec[n++] = IOVEC_MAKE_STRING(prefix);
} }
if (show_time) {
if (format_timestamp(header_time, sizeof(header_time), now(CLOCK_REALTIME))) {
iovec[n++] = IOVEC_MAKE_STRING(header_time);
iovec[n++] = IOVEC_MAKE_STRING(" ");
}
}
if (show_color) if (show_color)
get_log_colors(LOG_PRI(level), &on, &off, NULL); get_log_colors(LOG_PRI(level), &on, &off, NULL);
@ -1099,6 +1109,12 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
if (log_show_location_from_string(value ?: "1") < 0) if (log_show_location_from_string(value ?: "1") < 0)
log_warning("Failed to parse log location setting '%s'. Ignoring.", value); log_warning("Failed to parse log location setting '%s'. Ignoring.", value);
} else if (proc_cmdline_key_streq(key, "systemd.log_time")) {
if (log_show_time_from_string(value ?: "1") < 0)
log_warning("Failed to parse log time setting '%s'. Ignoring.", value);
} }
return 0; return 0;
@ -1130,6 +1146,10 @@ void log_parse_environment_realm(LogRealm realm) {
e = getenv("SYSTEMD_LOG_LOCATION"); e = getenv("SYSTEMD_LOG_LOCATION");
if (e && log_show_location_from_string(e) < 0) if (e && log_show_location_from_string(e) < 0)
log_warning("Failed to parse log location '%s'. Ignoring.", e); log_warning("Failed to parse log location '%s'. Ignoring.", e);
e = getenv("SYSTEMD_LOG_TIME");
if (e && log_show_time_from_string(e) < 0)
log_warning("Failed to parse log time '%s'. Ignoring.", e);
} }
LogTarget log_get_target(void) { LogTarget log_get_target(void) {
@ -1156,6 +1176,14 @@ bool log_get_show_location(void) {
return show_location; return show_location;
} }
void log_show_time(bool b) {
show_time = b;
}
bool log_get_show_time(void) {
return show_time;
}
int log_show_color_from_string(const char *e) { int log_show_color_from_string(const char *e) {
int t; int t;
@ -1178,6 +1206,17 @@ int log_show_location_from_string(const char *e) {
return 0; return 0;
} }
int log_show_time_from_string(const char *e) {
int t;
t = parse_boolean(e);
if (t < 0)
return t;
log_show_time(t);
return 0;
}
bool log_on_console(void) { bool log_on_console(void) {
if (IN_SET(log_target, LOG_TARGET_CONSOLE, if (IN_SET(log_target, LOG_TARGET_CONSOLE,
LOG_TARGET_CONSOLE_PREFIXED)) LOG_TARGET_CONSOLE_PREFIXED))

View File

@ -59,9 +59,12 @@ void log_show_color(bool b);
bool log_get_show_color(void) _pure_; bool log_get_show_color(void) _pure_;
void log_show_location(bool b); void log_show_location(bool b);
bool log_get_show_location(void) _pure_; bool log_get_show_location(void) _pure_;
void log_show_time(bool b);
bool log_get_show_time(void) _pure_;
int log_show_color_from_string(const char *e); int log_show_color_from_string(const char *e);
int log_show_location_from_string(const char *e); int log_show_location_from_string(const char *e);
int log_show_time_from_string(const char *e);
LogTarget log_get_target(void) _pure_; LogTarget log_get_target(void) _pure_;
int log_get_max_level_realm(LogRealm realm) _pure_; int log_get_max_level_realm(LogRealm realm) _pure_;

View File

@ -171,6 +171,7 @@ basic_sources = files('''
process-util.h process-util.h
procfs-util.c procfs-util.c
procfs-util.h procfs-util.h
pthread-util.h
quota-util.c quota-util.c
quota-util.h quota-util.h
random-util.c random-util.c

View File

@ -1178,6 +1178,11 @@ int must_be_root(void) {
return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be root."); return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be root.");
} }
static void restore_sigsetp(sigset_t **ssp) {
if (*ssp)
(void) sigprocmask(SIG_SETMASK, *ssp, NULL);
}
int safe_fork_full( int safe_fork_full(
const char *name, const char *name,
const int except_fds[], const int except_fds[],
@ -1187,7 +1192,8 @@ int safe_fork_full(
pid_t original_pid, pid; pid_t original_pid, pid;
sigset_t saved_ss, ss; sigset_t saved_ss, ss;
bool block_signals = false; _cleanup_(restore_sigsetp) sigset_t *saved_ssp = NULL;
bool block_signals = false, block_all = false;
int prio, r; int prio, r;
/* A wrapper around fork(), that does a couple of important initializations in addition to mere forking. Always /* A wrapper around fork(), that does a couple of important initializations in addition to mere forking. Always
@ -1202,7 +1208,7 @@ int safe_fork_full(
* be sure that SIGTERMs are not lost we might send to the child. */ * be sure that SIGTERMs are not lost we might send to the child. */
assert_se(sigfillset(&ss) >= 0); assert_se(sigfillset(&ss) >= 0);
block_signals = true; block_signals = block_all = true;
} else if (flags & FORK_WAIT) { } else if (flags & FORK_WAIT) {
/* Let's block SIGCHLD at least, so that we can safely watch for the child process */ /* Let's block SIGCHLD at least, so that we can safely watch for the child process */
@ -1212,28 +1218,31 @@ int safe_fork_full(
block_signals = true; block_signals = true;
} }
if (block_signals) if (block_signals) {
if (sigprocmask(SIG_SETMASK, &ss, &saved_ss) < 0) if (sigprocmask(SIG_SETMASK, &ss, &saved_ss) < 0)
return log_full_errno(prio, errno, "Failed to set signal mask: %m"); return log_full_errno(prio, errno, "Failed to set signal mask: %m");
saved_ssp = &saved_ss;
}
if (flags & FORK_NEW_MOUNTNS) if (flags & FORK_NEW_MOUNTNS)
pid = raw_clone(SIGCHLD|CLONE_NEWNS); pid = raw_clone(SIGCHLD|CLONE_NEWNS);
else else
pid = fork(); pid = fork();
if (pid < 0) { if (pid < 0)
r = -errno; return log_full_errno(prio, errno, "Failed to fork: %m");
if (block_signals) /* undo what we did above */
(void) sigprocmask(SIG_SETMASK, &saved_ss, NULL);
return log_full_errno(prio, r, "Failed to fork: %m");
}
if (pid > 0) { if (pid > 0) {
/* We are in the parent process */ /* We are in the parent process */
log_debug("Successfully forked off '%s' as PID " PID_FMT ".", strna(name), pid); log_debug("Successfully forked off '%s' as PID " PID_FMT ".", strna(name), pid);
if (flags & FORK_WAIT) { if (flags & FORK_WAIT) {
if (block_all) {
/* undo everything except SIGCHLD */
ss = saved_ss;
assert_se(sigaddset(&ss, SIGCHLD) >= 0);
(void) sigprocmask(SIG_SETMASK, &ss, NULL);
}
r = wait_for_terminate_and_check(name, pid, (flags & FORK_LOG ? WAIT_LOG : 0)); r = wait_for_terminate_and_check(name, pid, (flags & FORK_LOG ? WAIT_LOG : 0));
if (r < 0) if (r < 0)
return r; return r;
@ -1241,9 +1250,6 @@ int safe_fork_full(
return -EPROTO; return -EPROTO;
} }
if (block_signals) /* undo what we did above */
(void) sigprocmask(SIG_SETMASK, &saved_ss, NULL);
if (ret_pid) if (ret_pid)
*ret_pid = pid; *ret_pid = pid;
@ -1252,6 +1258,9 @@ int safe_fork_full(
/* We are in the child process */ /* We are in the child process */
/* Restore signal mask manually */
saved_ssp = NULL;
if (flags & FORK_REOPEN_LOG) { if (flags & FORK_REOPEN_LOG) {
/* Close the logs if requested, before we log anything. And make sure we reopen it if needed. */ /* Close the logs if requested, before we log anything. And make sure we reopen it if needed. */
log_close(); log_close();

16
src/basic/pthread-util.h Normal file
View File

@ -0,0 +1,16 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include <pthread.h>
#include "macro.h"
static inline pthread_mutex_t* pthread_mutex_lock_assert(pthread_mutex_t *mutex) {
assert_se(pthread_mutex_lock(mutex) == 0);
return mutex;
}
static inline void pthread_mutex_unlock_assertp(pthread_mutex_t **mutexp) {
if (*mutexp)
assert_se(pthread_mutex_unlock(*mutexp) == 0);
}

View File

@ -542,8 +542,9 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
DEFINE_SETTER(config_parse_level2, log_set_max_level_from_string, "log level"); DEFINE_SETTER(config_parse_level2, log_set_max_level_from_string, "log level");
DEFINE_SETTER(config_parse_target, log_set_target_from_string, "target"); DEFINE_SETTER(config_parse_target, log_set_target_from_string, "target");
DEFINE_SETTER(config_parse_color, log_show_color_from_string, "color" ); DEFINE_SETTER(config_parse_color, log_show_color_from_string, "color");
DEFINE_SETTER(config_parse_location, log_show_location_from_string, "location"); DEFINE_SETTER(config_parse_location, log_show_location_from_string, "location");
DEFINE_SETTER(config_parse_time, log_show_time_from_string, "time");
static int config_parse_default_timeout_abort( static int config_parse_default_timeout_abort(
const char *unit, const char *unit,
@ -571,6 +572,7 @@ static int parse_config_file(void) {
{ "Manager", "LogTarget", config_parse_target, 0, NULL }, { "Manager", "LogTarget", config_parse_target, 0, NULL },
{ "Manager", "LogColor", config_parse_color, 0, NULL }, { "Manager", "LogColor", config_parse_color, 0, NULL },
{ "Manager", "LogLocation", config_parse_location, 0, NULL }, { "Manager", "LogLocation", config_parse_location, 0, NULL },
{ "Manager", "LogTime", config_parse_time, 0, NULL },
{ "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core }, { "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core },
{ "Manager", "CrashChVT", /* legacy */ config_parse_crash_chvt, 0, &arg_crash_chvt }, { "Manager", "CrashChVT", /* legacy */ config_parse_crash_chvt, 0, &arg_crash_chvt },
{ "Manager", "CrashChangeVT", config_parse_crash_chvt, 0, &arg_crash_chvt }, { "Manager", "CrashChangeVT", config_parse_crash_chvt, 0, &arg_crash_chvt },
@ -718,6 +720,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_LOG_TARGET, ARG_LOG_TARGET,
ARG_LOG_COLOR, ARG_LOG_COLOR,
ARG_LOG_LOCATION, ARG_LOG_LOCATION,
ARG_LOG_TIME,
ARG_UNIT, ARG_UNIT,
ARG_SYSTEM, ARG_SYSTEM,
ARG_USER, ARG_USER,
@ -745,6 +748,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "log-target", required_argument, NULL, ARG_LOG_TARGET }, { "log-target", required_argument, NULL, ARG_LOG_TARGET },
{ "log-color", optional_argument, NULL, ARG_LOG_COLOR }, { "log-color", optional_argument, NULL, ARG_LOG_COLOR },
{ "log-location", optional_argument, NULL, ARG_LOG_LOCATION }, { "log-location", optional_argument, NULL, ARG_LOG_LOCATION },
{ "log-time", optional_argument, NULL, ARG_LOG_TIME },
{ "unit", required_argument, NULL, ARG_UNIT }, { "unit", required_argument, NULL, ARG_UNIT },
{ "system", no_argument, NULL, ARG_SYSTEM }, { "system", no_argument, NULL, ARG_SYSTEM },
{ "user", no_argument, NULL, ARG_USER }, { "user", no_argument, NULL, ARG_USER },
@ -818,6 +822,18 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_LOG_TIME:
if (optarg) {
r = log_show_time_from_string(optarg);
if (r < 0)
return log_error_errno(r, "Failed to parse log time setting \"%s\": %m",
optarg);
} else
log_show_time(true);
break;
case ARG_DEFAULT_STD_OUTPUT: case ARG_DEFAULT_STD_OUTPUT:
r = exec_output_from_string(optarg); r = exec_output_from_string(optarg);
if (r < 0) if (r < 0)
@ -1037,6 +1053,7 @@ static int help(void) {
" --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n" " --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
" --log-color[=BOOL] Highlight important log messages\n" " --log-color[=BOOL] Highlight important log messages\n"
" --log-location[=BOOL] Include code location in log messages\n" " --log-location[=BOOL] Include code location in log messages\n"
" --log-time[=BOOL] Prefix log messages with current time\n"
" --default-standard-output= Set default standard output for services\n" " --default-standard-output= Set default standard output for services\n"
" --default-standard-error= Set default standard error output for services\n" " --default-standard-error= Set default standard error output for services\n"
"\nSee the %s for details.\n" "\nSee the %s for details.\n"
@ -1419,6 +1436,9 @@ static int become_shutdown(
if (log_get_show_location()) if (log_get_show_location())
command_line[pos++] = "--log-location"; command_line[pos++] = "--log-location";
if (log_get_show_time())
command_line[pos++] = "--log-time";
if (streq(shutdown_verb, "exit")) { if (streq(shutdown_verb, "exit")) {
command_line[pos++] = "--exit-code"; command_line[pos++] = "--exit-code";
command_line[pos++] = exit_code; command_line[pos++] = exit_code;

View File

@ -16,6 +16,7 @@
#LogTarget=journal-or-kmsg #LogTarget=journal-or-kmsg
#LogColor=yes #LogColor=yes
#LogLocation=no #LogLocation=no
#LogTime=no
#DumpCore=yes #DumpCore=yes
#ShowStatus=yes #ShowStatus=yes
#CrashChangeVT=no #CrashChangeVT=no

View File

@ -15,6 +15,7 @@
#LogTarget=console #LogTarget=console
#LogColor=yes #LogColor=yes
#LogLocation=no #LogLocation=no
#LogTime=no
#SystemCallArchitectures= #SystemCallArchitectures=
#TimerSlackNSec= #TimerSlackNSec=
#StatusUnitFormat=@STATUS_UNIT_FORMAT_DEFAULT@ #StatusUnitFormat=@STATUS_UNIT_FORMAT_DEFAULT@

View File

@ -6,6 +6,3 @@
/* The entry point into the fuzzer */ /* The entry point into the fuzzer */
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
/* https://docs.fuzzbuzz.io/developer-documentation/porting-targets-to-fuzzbuzz/libfuzzer-targets */
int FuzzerEntrypoint(const uint8_t *data, size_t size);

View File

@ -1,5 +0,0 @@
#include "fuzz.h"
int FuzzerEntrypoint(const uint8_t *data, size_t size) {
return LLVMFuzzerTestOneInput(data, size);
}

View File

@ -509,6 +509,8 @@ static void raw_pull_job_on_finished(PullJob *j) {
raw_pull_report_progress(i, RAW_FINALIZING); raw_pull_report_progress(i, RAW_FINALIZING);
if (i->raw_job->etag) {
/* Only make a read-only copy if ETag header is set. */
r = import_make_read_only_fd(i->raw_job->disk_fd); r = import_make_read_only_fd(i->raw_job->disk_fd);
if (r < 0) if (r < 0)
goto finish; goto finish;
@ -518,6 +520,7 @@ static void raw_pull_job_on_finished(PullJob *j) {
log_error_errno(r, "Failed to rename raw file to %s: %m", i->final_path); log_error_errno(r, "Failed to rename raw file to %s: %m", i->final_path);
goto finish; goto finish;
} }
}
i->temp_path = mfree(i->temp_path); i->temp_path = mfree(i->temp_path);

View File

@ -64,6 +64,9 @@ struct sd_dhcp_lease {
struct in_addr *pop3_server; struct in_addr *pop3_server;
size_t pop3_server_size; size_t pop3_server_size;
struct in_addr *smtp_server;
size_t smtp_server_size;
struct sd_dhcp_route *static_route; struct sd_dhcp_route *static_route;
size_t static_route_size, static_route_allocated; size_t static_route_size, static_route_allocated;

View File

@ -55,8 +55,8 @@ struct sd_dhcp_server {
char *timezone; char *timezone;
struct in_addr *ntp, *dns, *sip, *pop3_server; struct in_addr *ntp, *dns, *sip, *pop3_server, *smtp_server;
unsigned n_ntp, n_dns, n_sip, n_pop3_server; unsigned n_ntp, n_dns, n_sip, n_pop3_server, n_smtp_server;
OrderedHashmap *extra_options; OrderedHashmap *extra_options;
OrderedHashmap *vendor_options; OrderedHashmap *vendor_options;

View File

@ -140,6 +140,17 @@ int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **a
return (int) lease->pop3_server_size; return (int) lease->pop3_server_size;
} }
int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr) {
assert_return(lease, -EINVAL);
assert_return(addr, -EINVAL);
if (lease->smtp_server_size <= 0)
return -ENODATA;
*addr = lease->smtp_server;
return (int) lease->smtp_server_size;
}
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) { int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
assert_return(lease, -EINVAL); assert_return(lease, -EINVAL);
assert_return(domainname, -EINVAL); assert_return(domainname, -EINVAL);
@ -291,6 +302,7 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
free(lease->ntp); free(lease->ntp);
free(lease->sip); free(lease->sip);
free(lease->pop3_server); free(lease->pop3_server);
free(lease->smtp_server);
free(lease->static_route); free(lease->static_route);
free(lease->client_id); free(lease->client_id);
free(lease->vendor_specific); free(lease->vendor_specific);
@ -619,6 +631,12 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
log_debug_errno(r, "Failed to parse POP3 server, ignoring: %m"); log_debug_errno(r, "Failed to parse POP3 server, ignoring: %m");
break; break;
case SD_DHCP_OPTION_SMTP_SERVER:
r = lease_parse_in_addrs(option, len, &lease->smtp_server, &lease->smtp_server_size);
if (r < 0)
log_debug_errno(r, "Failed to parse SMTP server, ignoring: %m");
break;
case SD_DHCP_OPTION_STATIC_ROUTE: case SD_DHCP_OPTION_STATIC_ROUTE:
r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated); r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated);
if (r < 0) if (r < 0)
@ -1056,6 +1074,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
*ntp = NULL, *ntp = NULL,
*sip = NULL, *sip = NULL,
*pop3_server = NULL, *pop3_server = NULL,
*smtp_server = NULL,
*mtu = NULL, *mtu = NULL,
*routes = NULL, *routes = NULL,
*domains = NULL, *domains = NULL,
@ -1086,6 +1105,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
"NTP", &ntp, "NTP", &ntp,
"SIP", &sip, "SIP", &sip,
"POP3_SERVERS", &pop3_server, "POP3_SERVERS", &pop3_server,
"SMTP_SERVERS", &smtp_server,
"MTU", &mtu, "MTU", &mtu,
"DOMAINNAME", &lease->domainname, "DOMAINNAME", &lease->domainname,
"HOSTNAME", &lease->hostname, "HOSTNAME", &lease->hostname,
@ -1206,6 +1226,14 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
lease->pop3_server_size = r; lease->pop3_server_size = r;
} }
if (smtp_server) {
r = deserialize_in_addrs(&lease->smtp_server, smtp_server);
if (r < 0)
log_debug_errno(r, "Failed to deserialize SMTP server %s, ignoring: %m", smtp_server);
else
lease->smtp_server_size = r;
}
if (mtu) { if (mtu) {
r = safe_atou16(mtu, &lease->mtu); r = safe_atou16(mtu, &lease->mtu);
if (r < 0) if (r < 0)

View File

@ -141,6 +141,7 @@ static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) {
free(server->ntp); free(server->ntp);
free(server->sip); free(server->sip);
free(server->pop3_server); free(server->pop3_server);
free(server->smtp_server);
hashmap_free(server->leases_by_client_id); hashmap_free(server->leases_by_client_id);
@ -523,6 +524,15 @@ static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
return r; return r;
} }
if (server->n_smtp_server > 0) {
r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_SMTP_SERVER,
sizeof(struct in_addr) * server->n_smtp_server, server->smtp_server);
if (r < 0)
return r;
}
if (server->timezone) { if (server->timezone) {
r = dhcp_option_append( r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0, &packet->dhcp, req->max_optlen, &offset, 0,
@ -1216,6 +1226,31 @@ int sd_dhcp_server_set_pop3_server(sd_dhcp_server *server, const struct in_addr
return 1; return 1;
} }
int sd_dhcp_server_set_smtp_server(sd_dhcp_server *server, const struct in_addr smtp_server[], unsigned n) {
assert_return(server, -EINVAL);
assert_return(smtp_server || n <= 0, -EINVAL);
if (server->n_smtp_server == n &&
memcmp(server->smtp_server, smtp_server, sizeof(struct in_addr) * n) == 0)
return 0;
if (n <= 0) {
server->smtp_server = mfree(server->smtp_server);
server->n_smtp_server = 0;
} else {
struct in_addr *c;
c = newdup(struct in_addr, smtp_server, n);
if (!c)
return -ENOMEM;
free_and_replace(server->smtp_server, c);
server->n_smtp_server = n;
}
return 1;
}
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) { int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) {
assert_return(server, -EINVAL); assert_return(server, -EINVAL);

View File

@ -260,6 +260,10 @@ _public_ int sd_network_link_get_pop3_servers(int ifindex, char ***pop3) {
return network_link_get_strv(ifindex, "POP3_SERVERS", pop3); return network_link_get_strv(ifindex, "POP3_SERVERS", pop3);
} }
_public_ int sd_network_link_get_smtp_servers(int ifindex, char ***ret) {
return network_link_get_strv(ifindex, "SMTP_SERVERS", ret);
}
_public_ int sd_network_link_get_dns_default_route(int ifindex) { _public_ int sd_network_link_get_dns_default_route(int ifindex) {
char path[STRLEN("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1]; char path[STRLEN("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
_cleanup_free_ char *s = NULL; _cleanup_free_ char *s = NULL;

View File

@ -1241,7 +1241,7 @@ static int link_status_one(
const LinkInfo *info) { const LinkInfo *info) {
_cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **sip = NULL, **search_domains = NULL, **route_domains = NULL, _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **sip = NULL, **search_domains = NULL, **route_domains = NULL,
**pop3_server = NULL; **pop3_server = NULL, **smtp_server = NULL;
_cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *tz = NULL; _cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *tz = NULL;
_cleanup_free_ char *t = NULL, *network = NULL; _cleanup_free_ char *t = NULL, *network = NULL;
const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL; const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL;
@ -1269,6 +1269,7 @@ static int link_status_one(
(void) sd_network_link_get_ntp(info->ifindex, &ntp); (void) sd_network_link_get_ntp(info->ifindex, &ntp);
(void) sd_network_link_get_sip(info->ifindex, &sip); (void) sd_network_link_get_sip(info->ifindex, &sip);
(void) sd_network_link_get_pop3_servers(info->ifindex, &pop3_server); (void) sd_network_link_get_pop3_servers(info->ifindex, &pop3_server);
(void) sd_network_link_get_smtp_servers(info->ifindex, &smtp_server);
if (info->sd_device) { if (info->sd_device) {
(void) sd_device_get_property_value(info->sd_device, "ID_NET_LINK_FILE", &link); (void) sd_device_get_property_value(info->sd_device, "ID_NET_LINK_FILE", &link);
@ -1832,6 +1833,9 @@ static int link_status_one(
if (r < 0) if (r < 0)
return r; return r;
r = dump_list(table, "POP3 servers:", pop3_server); r = dump_list(table, "POP3 servers:", pop3_server);
if (r < 0)
return r;
r = dump_list(table, "SMTP servers:", smtp_server);
if (r < 0) if (r < 0)
return r; return r;
r = dump_ifindexes(table, "Carrier Bound To:", carrier_bound_to); r = dump_ifindexes(table, "Carrier Bound To:", carrier_bound_to);

View File

@ -189,6 +189,55 @@ static int link_push_uplink_pop3_to_dhcp_server(Link *link, sd_dhcp_server *s) {
return sd_dhcp_server_set_pop3_server(s, addresses, n_addresses); return sd_dhcp_server_set_pop3_server(s, addresses, n_addresses);
} }
static int link_push_uplink_smtp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
_cleanup_free_ struct in_addr *addresses = NULL;
size_t n_addresses = 0, n_allocated = 0;
char **a;
if (!link->network)
return 0;
log_link_debug(link, "Copying SMTP server information from link");
STRV_FOREACH(a, link->network->smtp) {
union in_addr_union ia;
/* Only look for IPv4 addresses */
if (in_addr_from_string(AF_INET, *a, &ia) <= 0)
continue;
/* Never propagate obviously borked data */
if (in4_addr_is_null(&ia.in) || in4_addr_is_localhost(&ia.in))
continue;
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
return log_oom();
addresses[n_addresses++] = ia.in;
}
if (link->dhcp_lease) {
const struct in_addr *da = NULL;
int j, n;
n = sd_dhcp_lease_get_smtp_server(link->dhcp_lease, &da);
if (n > 0) {
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + n))
return log_oom();
for (j = 0; j < n; j++)
if (in4_addr_is_non_local(&da[j]))
addresses[n_addresses++] = da[j];
}
}
if (n_addresses <= 0)
return 0;
return sd_dhcp_server_set_smtp_server(s, addresses, n_addresses);
}
static int link_push_uplink_sip_to_dhcp_server(Link *link, sd_dhcp_server *s) { static int link_push_uplink_sip_to_dhcp_server(Link *link, sd_dhcp_server *s) {
_cleanup_free_ struct in_addr *addresses = NULL; _cleanup_free_ struct in_addr *addresses = NULL;
size_t n_addresses = 0, n_allocated = 0; size_t n_addresses = 0, n_allocated = 0;
@ -341,11 +390,26 @@ int dhcp4_server_configure(Link *link) {
r = 0; r = 0;
} else } else
r = link_push_uplink_pop3_to_dhcp_server(uplink, link->dhcp_server); r = link_push_uplink_pop3_to_dhcp_server(uplink, link->dhcp_server);
} }
if (r < 0) if (r < 0)
log_link_warning_errno(link, r, "Failed to set POP3 server for DHCP server, ignoring: %m"); log_link_warning_errno(link, r, "Failed to set POP3 server for DHCP server, ignoring: %m");
if (link->network->n_dhcp_server_smtp > 0)
r = sd_dhcp_server_set_smtp_server(link->dhcp_server, link->network->dhcp_server_smtp, link->network->n_dhcp_server_smtp);
else {
if (!acquired_uplink)
uplink = manager_find_uplink(link->manager, link);
if (!uplink) {
log_link_debug(link, "Not emitting SMTP server information on link, couldn't find suitable uplink.");
r = 0;
} else
r = link_push_uplink_smtp_to_dhcp_server(uplink, link->dhcp_server);
}
if (r < 0)
log_link_warning_errno(link, r, "Failed to SMTP server for DHCP server, ignoring: %m");
r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router); r = sd_dhcp_server_set_emit_router(link->dhcp_server, link->network->dhcp_server_emit_router);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Failed to set router emission for DHCP server: %m"); return log_link_error_errno(link, r, "Failed to set router emission for DHCP server: %m");
@ -550,6 +614,8 @@ int config_parse_dhcp_server_sip(
m[n->n_dhcp_server_sip++] = a.in; m[n->n_dhcp_server_sip++] = a.in;
n->dhcp_server_sip = m; n->dhcp_server_sip = m;
} }
return 0;
} }
int config_parse_dhcp_server_pop3_servers( int config_parse_dhcp_server_pop3_servers(
@ -602,4 +668,60 @@ int config_parse_dhcp_server_pop3_servers(
m[n->n_dhcp_server_pop3++] = a.in; m[n->n_dhcp_server_pop3++] = a.in;
n->dhcp_server_pop3 = m; n->dhcp_server_pop3 = m;
} }
return 0;
}
int config_parse_dhcp_server_smtp_servers(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Network *n = data;
const char *p = rvalue;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
for (;;) {
_cleanup_free_ char *w = NULL;
union in_addr_union a;
struct in_addr *m;
r = extract_first_word(&p, &w, NULL, 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to extract word, ignoring: %s", rvalue);
return 0;
}
if (r == 0)
return 0;
r = in_addr_from_string(AF_INET, w, &a);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse SMTP server address '%s', ignoring: %m", w);
continue;
}
m = reallocarray(n->dhcp_server_smtp, n->n_dhcp_server_smtp + 1, sizeof(struct in_addr));
if (!m)
return log_oom();
m[n->n_dhcp_server_smtp++] = a.in;
n->dhcp_server_smtp = m;
}
return 0;
} }

View File

@ -13,3 +13,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_dns);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_sip); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_sip);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_pop3_servers); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_pop3_servers);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_smtp_servers);

View File

@ -4106,6 +4106,12 @@ int link_save(Link *link) {
space = false; space = false;
fputstrv(f, link->network->pop3, NULL, &space); fputstrv(f, link->network->pop3, NULL, &space);
fputc('\n', f);
fputs("SMTP_SERVERS=", f);
space = false;
fputstrv(f, link->network->smtp, NULL, &space);
if (link->dhcp_lease) { if (link->dhcp_lease) {
const struct in_addr *addresses; const struct in_addr *addresses;
@ -4115,6 +4121,15 @@ int link_save(Link *link) {
space = true; space = true;
} }
if (link->dhcp_lease) {
const struct in_addr *addresses;
r = sd_dhcp_lease_get_smtp_server(link->dhcp_lease, &addresses);
if (r > 0)
if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0)
space = true;
}
if (link->network->dhcp6_use_ntp && dhcp6_lease) { if (link->network->dhcp6_use_ntp && dhcp6_lease) {
struct in6_addr *in6_addrs; struct in6_addr *in6_addrs;
char **hosts; char **hosts;

View File

@ -1490,7 +1490,7 @@ static int ordered_set_put_in4_addrv(OrderedSet *s,
static int manager_save(Manager *m) { static int manager_save(Manager *m) {
_cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *pop3 = NULL, _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *pop3 = NULL,
*search_domains = NULL, *route_domains = NULL; *smtp = NULL, *search_domains = NULL, *route_domains = NULL;
const char *operstate_str, *carrier_state_str, *address_state_str; const char *operstate_str, *carrier_state_str, *address_state_str;
LinkOperationalState operstate = LINK_OPERSTATE_OFF; LinkOperationalState operstate = LINK_OPERSTATE_OFF;
LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF; LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF;
@ -1523,6 +1523,10 @@ static int manager_save(Manager *m) {
if (!pop3) if (!pop3)
return -ENOMEM; return -ENOMEM;
smtp = ordered_set_new(&string_hash_ops);
if (!smtp)
return -ENOMEM;
search_domains = ordered_set_new(&dns_name_hash_ops); search_domains = ordered_set_new(&dns_name_hash_ops);
if (!search_domains) if (!search_domains)
return -ENOMEM; return -ENOMEM;
@ -1598,7 +1602,6 @@ static int manager_save(Manager *m) {
return r; return r;
} }
r = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &addresses); r = sd_dhcp_lease_get_pop3_server(link->dhcp_lease, &addresses);
if (r > 0) { if (r > 0) {
r = ordered_set_put_in4_addrv(pop3, addresses, r, in4_addr_is_non_local); r = ordered_set_put_in4_addrv(pop3, addresses, r, in4_addr_is_non_local);
@ -1607,6 +1610,14 @@ static int manager_save(Manager *m) {
} else if (r < 0 && r != -ENODATA) } else if (r < 0 && r != -ENODATA)
return r; return r;
r = sd_dhcp_lease_get_smtp_server(link->dhcp_lease, &addresses);
if (r > 0) {
r = ordered_set_put_in4_addrv(smtp, addresses, r, in4_addr_is_non_local);
if (r < 0)
return r;
} else if (r < 0 && r != -ENODATA)
return r;
if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) { if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
const char *domainname; const char *domainname;
char **domains = NULL; char **domains = NULL;
@ -1659,6 +1670,7 @@ static int manager_save(Manager *m) {
ordered_set_print(f, "NTP=", ntp); ordered_set_print(f, "NTP=", ntp);
ordered_set_print(f, "SIP=", sip); ordered_set_print(f, "SIP=", sip);
ordered_set_print(f, "POP3_SERVERS=", pop3); ordered_set_print(f, "POP3_SERVERS=", pop3);
ordered_set_print(f, "SMTP_SERVERS=", smtp);
ordered_set_print(f, "DOMAINS=", search_domains); ordered_set_print(f, "DOMAINS=", search_domains);
ordered_set_print(f, "ROUTE_DOMAINS=", route_domains); ordered_set_print(f, "ROUTE_DOMAINS=", route_domains);

View File

@ -208,6 +208,7 @@ DHCPServer.NTP, config_parse_dhcp_server_ntp,
DHCPServer.EmitSIP, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_sip) DHCPServer.EmitSIP, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_sip)
DHCPServer.SIP, config_parse_dhcp_server_sip, 0, 0 DHCPServer.SIP, config_parse_dhcp_server_sip, 0, 0
DHCPServer.POP3Servers, config_parse_dhcp_server_pop3_servers, 0, 0 DHCPServer.POP3Servers, config_parse_dhcp_server_pop3_servers, 0, 0
DHCPServer.SMTPServers, config_parse_dhcp_server_smtp_servers, 0, 0
DHCPServer.EmitRouter, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_router) DHCPServer.EmitRouter, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_router)
DHCPServer.EmitTimezone, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_timezone) DHCPServer.EmitTimezone, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_timezone)
DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone) DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone)

View File

@ -652,6 +652,7 @@ static Network *network_free(Network *network) {
strv_free(network->ntp); strv_free(network->ntp);
free(network->dns); free(network->dns);
strv_free(network->sip); strv_free(network->sip);
strv_free(network->smtp);
ordered_set_free_free(network->search_domains); ordered_set_free_free(network->search_domains);
ordered_set_free_free(network->route_domains); ordered_set_free_free(network->route_domains);
strv_free(network->bind_carrier); strv_free(network->bind_carrier);

View File

@ -150,6 +150,9 @@ struct Network {
struct in_addr *dhcp_server_pop3; struct in_addr *dhcp_server_pop3;
unsigned n_dhcp_server_pop3; unsigned n_dhcp_server_pop3;
struct in_addr *dhcp_server_smtp;
unsigned n_dhcp_server_smtp;
bool dhcp_server_emit_router; bool dhcp_server_emit_router;
bool dhcp_server_emit_timezone; bool dhcp_server_emit_timezone;
char *dhcp_server_timezone; char *dhcp_server_timezone;
@ -300,6 +303,7 @@ struct Network {
char **ntp; char **ntp;
char **sip; char **sip;
char **pop3; char **pop3;
char **smtp;
char **bind_carrier; char **bind_carrier;
}; };

View File

@ -9,6 +9,7 @@
#include "group-record-nss.h" #include "group-record-nss.h"
#include "macro.h" #include "macro.h"
#include "nss-util.h" #include "nss-util.h"
#include "pthread-util.h"
#include "signal-util.h" #include "signal-util.h"
#include "strv.h" #include "strv.h"
#include "user-util.h" #include "user-util.h"
@ -277,10 +278,11 @@ static enum nss_status nss_systemd_endent(GetentData *p) {
assert(p); assert(p);
assert_se(pthread_mutex_lock(&p->mutex) == 0); _cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = NULL;
_l = pthread_mutex_lock_assert(&p->mutex);
p->iterator = userdb_iterator_free(p->iterator); p->iterator = userdb_iterator_free(p->iterator);
p->by_membership = false; p->by_membership = false;
assert_se(pthread_mutex_unlock(&p->mutex) == 0);
return NSS_STATUS_SUCCESS; return NSS_STATUS_SUCCESS;
} }
@ -294,45 +296,41 @@ enum nss_status _nss_systemd_endgrent(void) {
} }
enum nss_status _nss_systemd_setpwent(int stayopen) { enum nss_status _nss_systemd_setpwent(int stayopen) {
enum nss_status ret;
PROTECT_ERRNO; PROTECT_ERRNO;
BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
if (userdb_nss_compat_is_enabled() <= 0) if (userdb_nss_compat_is_enabled() <= 0)
return NSS_STATUS_NOTFOUND; return NSS_STATUS_NOTFOUND;
assert_se(pthread_mutex_lock(&getpwent_data.mutex) == 0); _cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = NULL;
int r;
_l = pthread_mutex_lock_assert(&getpwent_data.mutex);
getpwent_data.iterator = userdb_iterator_free(getpwent_data.iterator); getpwent_data.iterator = userdb_iterator_free(getpwent_data.iterator);
getpwent_data.by_membership = false; getpwent_data.by_membership = false;
ret = userdb_all(nss_glue_userdb_flags(), &getpwent_data.iterator) < 0 ? r = userdb_all(nss_glue_userdb_flags(), &getpwent_data.iterator);
NSS_STATUS_UNAVAIL : NSS_STATUS_SUCCESS; return r < 0 ? NSS_STATUS_UNAVAIL : NSS_STATUS_SUCCESS;
assert_se(pthread_mutex_unlock(&getpwent_data.mutex) == 0);
return ret;
} }
enum nss_status _nss_systemd_setgrent(int stayopen) { enum nss_status _nss_systemd_setgrent(int stayopen) {
enum nss_status ret;
PROTECT_ERRNO; PROTECT_ERRNO;
BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
if (userdb_nss_compat_is_enabled() <= 0) if (userdb_nss_compat_is_enabled() <= 0)
return NSS_STATUS_NOTFOUND; return NSS_STATUS_NOTFOUND;
assert_se(pthread_mutex_lock(&getgrent_data.mutex) == 0); _cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = NULL;
int r;
_l = pthread_mutex_lock_assert(&getgrent_data.mutex);
getgrent_data.iterator = userdb_iterator_free(getgrent_data.iterator); getgrent_data.iterator = userdb_iterator_free(getgrent_data.iterator);
getpwent_data.by_membership = false; getpwent_data.by_membership = false;
ret = groupdb_all(nss_glue_userdb_flags(), &getgrent_data.iterator) < 0 ? r = groupdb_all(nss_glue_userdb_flags(), &getgrent_data.iterator);
NSS_STATUS_UNAVAIL : NSS_STATUS_SUCCESS; return r < 0 ? NSS_STATUS_UNAVAIL : NSS_STATUS_SUCCESS;
assert_se(pthread_mutex_unlock(&getgrent_data.mutex) == 0);
return ret;
} }
enum nss_status _nss_systemd_getpwent_r( enum nss_status _nss_systemd_getpwent_r(
@ -341,7 +339,6 @@ enum nss_status _nss_systemd_getpwent_r(
int *errnop) { int *errnop) {
_cleanup_(user_record_unrefp) UserRecord *ur = NULL; _cleanup_(user_record_unrefp) UserRecord *ur = NULL;
enum nss_status ret;
int r; int r;
PROTECT_ERRNO; PROTECT_ERRNO;
@ -359,40 +356,33 @@ enum nss_status _nss_systemd_getpwent_r(
if (!r) if (!r)
return NSS_STATUS_NOTFOUND; return NSS_STATUS_NOTFOUND;
assert_se(pthread_mutex_lock(&getpwent_data.mutex) == 0); _cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = NULL;
_l = pthread_mutex_lock_assert(&getpwent_data.mutex);
if (!getpwent_data.iterator) { if (!getpwent_data.iterator) {
UNPROTECT_ERRNO; UNPROTECT_ERRNO;
*errnop = EHOSTDOWN; *errnop = EHOSTDOWN;
ret = NSS_STATUS_UNAVAIL; return NSS_STATUS_UNAVAIL;
goto finish;
} }
r = userdb_iterator_get(getpwent_data.iterator, &ur); r = userdb_iterator_get(getpwent_data.iterator, &ur);
if (r == -ESRCH) { if (r == -ESRCH)
ret = NSS_STATUS_NOTFOUND; return NSS_STATUS_NOTFOUND;
goto finish;
}
if (r < 0) { if (r < 0) {
UNPROTECT_ERRNO; UNPROTECT_ERRNO;
*errnop = -r; *errnop = -r;
ret = NSS_STATUS_UNAVAIL; return NSS_STATUS_UNAVAIL;
goto finish;
} }
r = nss_pack_user_record(ur, result, buffer, buflen); r = nss_pack_user_record(ur, result, buffer, buflen);
if (r < 0) { if (r < 0) {
UNPROTECT_ERRNO; UNPROTECT_ERRNO;
*errnop = -r; *errnop = -r;
ret = NSS_STATUS_TRYAGAIN; return NSS_STATUS_TRYAGAIN;
goto finish;
} }
ret = NSS_STATUS_SUCCESS; return NSS_STATUS_SUCCESS;
finish:
assert_se(pthread_mutex_unlock(&getpwent_data.mutex) == 0);
return ret;
} }
enum nss_status _nss_systemd_getgrent_r( enum nss_status _nss_systemd_getgrent_r(
@ -402,7 +392,6 @@ enum nss_status _nss_systemd_getgrent_r(
_cleanup_(group_record_unrefp) GroupRecord *gr = NULL; _cleanup_(group_record_unrefp) GroupRecord *gr = NULL;
_cleanup_free_ char **members = NULL; _cleanup_free_ char **members = NULL;
enum nss_status ret;
int r; int r;
PROTECT_ERRNO; PROTECT_ERRNO;
@ -420,19 +409,20 @@ enum nss_status _nss_systemd_getgrent_r(
if (!r) if (!r)
return NSS_STATUS_UNAVAIL; return NSS_STATUS_UNAVAIL;
assert_se(pthread_mutex_lock(&getgrent_data.mutex) == 0); _cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = NULL;
_l = pthread_mutex_lock_assert(&getgrent_data.mutex);
if (!getgrent_data.iterator) { if (!getgrent_data.iterator) {
UNPROTECT_ERRNO; UNPROTECT_ERRNO;
*errnop = EHOSTDOWN; *errnop = EHOSTDOWN;
ret = NSS_STATUS_UNAVAIL; return NSS_STATUS_UNAVAIL;
goto finish;
} }
if (!getgrent_data.by_membership) { if (!getgrent_data.by_membership) {
r = groupdb_iterator_get(getgrent_data.iterator, &gr); r = groupdb_iterator_get(getgrent_data.iterator, &gr);
if (r == -ESRCH) { if (r == -ESRCH) {
/* So we finished iterating native groups now. let's now continue with iterating /* So we finished iterating native groups now. Let's now continue with iterating
* native memberships, and generate additional group entries for any groups * native memberships, and generate additional group entries for any groups
* referenced there that are defined in NSS only. This means for those groups there * referenced there that are defined in NSS only. This means for those groups there
* will be two or more entries generated during iteration, but this is apparently how * will be two or more entries generated during iteration, but this is apparently how
@ -444,23 +434,20 @@ enum nss_status _nss_systemd_getgrent_r(
if (r < 0) { if (r < 0) {
UNPROTECT_ERRNO; UNPROTECT_ERRNO;
*errnop = -r; *errnop = -r;
ret = NSS_STATUS_UNAVAIL; return NSS_STATUS_UNAVAIL;
goto finish;
} }
getgrent_data.by_membership = true; getgrent_data.by_membership = true;
} else if (r < 0) { } else if (r < 0) {
UNPROTECT_ERRNO; UNPROTECT_ERRNO;
*errnop = -r; *errnop = -r;
ret = NSS_STATUS_UNAVAIL; return NSS_STATUS_UNAVAIL;
goto finish;
} else if (!STR_IN_SET(gr->group_name, root_group.gr_name, nobody_group.gr_name)) { } else if (!STR_IN_SET(gr->group_name, root_group.gr_name, nobody_group.gr_name)) {
r = membershipdb_by_group_strv(gr->group_name, nss_glue_userdb_flags(), &members); r = membershipdb_by_group_strv(gr->group_name, nss_glue_userdb_flags(), &members);
if (r < 0) { if (r < 0) {
UNPROTECT_ERRNO; UNPROTECT_ERRNO;
*errnop = -r; *errnop = -r;
ret = NSS_STATUS_UNAVAIL; return NSS_STATUS_UNAVAIL;
goto finish;
} }
} }
} }
@ -472,15 +459,12 @@ enum nss_status _nss_systemd_getgrent_r(
_cleanup_free_ char *user_name = NULL, *group_name = NULL; _cleanup_free_ char *user_name = NULL, *group_name = NULL;
r = membershipdb_iterator_get(getgrent_data.iterator, &user_name, &group_name); r = membershipdb_iterator_get(getgrent_data.iterator, &user_name, &group_name);
if (r == -ESRCH) { if (r == -ESRCH)
ret = NSS_STATUS_NOTFOUND; return NSS_STATUS_NOTFOUND;
goto finish;
}
if (r < 0) { if (r < 0) {
UNPROTECT_ERRNO; UNPROTECT_ERRNO;
*errnop = -r; *errnop = -r;
ret = NSS_STATUS_UNAVAIL; return NSS_STATUS_UNAVAIL;
goto finish;
} }
if (STR_IN_SET(user_name, root_passwd.pw_name, nobody_passwd.pw_name)) if (STR_IN_SET(user_name, root_passwd.pw_name, nobody_passwd.pw_name))
@ -494,8 +478,7 @@ enum nss_status _nss_systemd_getgrent_r(
if (lock_fd < 0 && lock_fd != -EBUSY) { if (lock_fd < 0 && lock_fd != -EBUSY) {
UNPROTECT_ERRNO; UNPROTECT_ERRNO;
*errnop = -lock_fd; *errnop = -lock_fd;
ret = NSS_STATUS_UNAVAIL; return NSS_STATUS_UNAVAIL;
goto finish;
} }
} }
@ -525,15 +508,10 @@ enum nss_status _nss_systemd_getgrent_r(
if (r < 0) { if (r < 0) {
UNPROTECT_ERRNO; UNPROTECT_ERRNO;
*errnop = -r; *errnop = -r;
ret = NSS_STATUS_TRYAGAIN; return NSS_STATUS_TRYAGAIN;
goto finish;
} }
ret = NSS_STATUS_SUCCESS; return NSS_STATUS_SUCCESS;
finish:
assert_se(pthread_mutex_unlock(&getgrent_data.mutex) == 0);
return ret;
} }
enum nss_status _nss_systemd_initgroups_dyn( enum nss_status _nss_systemd_initgroups_dyn(

View File

@ -3,3 +3,5 @@
systemd_repart_sources = files(''' systemd_repart_sources = files('''
repart.c repart.c
'''.split()) '''.split())
test_repart_sh = find_program('test-repart.sh')

111
src/partition/test-repart.sh Executable file
View File

@ -0,0 +1,111 @@
#!/usr/bin/env bash
set -ex
repart=$1
test -x $repart
D=$(mktemp --directory)
trap "rm -rf '$D'" EXIT INT QUIT PIPE
mkdir -p $D/definitions
truncate -s 1G $D/zzz
SEED=e2a40bf9-73f1-4278-9160-49c031e7aef8
$repart $D/zzz --empty=force --dry-run=no --seed=$SEED
sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' > $D/empty
cmp $D/empty - <<EOF
label: gpt
label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
device: $D/zzz
unit: sectors
first-lba: 2048
last-lba: 2097118
EOF
cat >$D/definitions/root.conf <<EOF
[Partition]
Type=root
EOF
ln -s root.conf $D/definitions/root2.conf
cat >$D/definitions/home.conf <<EOF
[Partition]
Type=home
EOF
cat > $D/definitions/swap.conf <<EOF
[Partition]
Type=swap
SizeMaxBytes=64M
PaddingMinBytes=92M
EOF
$repart $D/zzz --dry-run=no --seed=$SEED --definitions=$D/definitions
sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' >$D/populated
cmp $D/populated - <<EOF
label: gpt
label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
device: $D/zzz
unit: sectors
first-lba: 2048
last-lba: 2097118
$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home"
$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64"
$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2"
$D/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap"
EOF
cat >$D/definitions/swap.conf <<EOF
[Partition]
Type=swap
SizeMaxBytes=64M
EOF
cat >$D/definitions/extra.conf <<EOF
[Partition]
Type=linux-generic
EOF
$repart $D/zzz --dry-run=no --seed=$SEED --definitions=$D/definitions
sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' >$D/populated2
cmp $D/populated2 - <<EOF
label: gpt
label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
device: $D/zzz
unit: sectors
first-lba: 2048
last-lba: 2097118
$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home"
$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64"
$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2"
$D/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap"
$D/zzz5 : start= 1908696, size= 188416, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=03477476-06AD-44E8-9EF4-BC2BD7771289, name="linux-generic"
EOF
truncate -s 2G $D/zzz
$repart $D/zzz --dry-run=no --seed=$SEED --definitions=$D/definitions
sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' >$D/populated3
cmp $D/populated3 - <<EOF
label: gpt
label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
device: $D/zzz
unit: sectors
first-lba: 2048
last-lba: 4194270
$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home"
$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64"
$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2"
$D/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap"
$D/zzz5 : start= 1908696, size= 2285568, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=03477476-06AD-44E8-9EF4-BC2BD7771289, name="linux-generic"
EOF

View File

@ -92,7 +92,6 @@ static void test_packet_from_file(const char* filename, bool canonical) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
int i, N; int i, N;
_cleanup_free_ char *pkts_glob = NULL;
_cleanup_globfree_ glob_t g = {}; _cleanup_globfree_ glob_t g = {};
char **fnames; char **fnames;
@ -102,7 +101,8 @@ int main(int argc, char **argv) {
N = argc - 1; N = argc - 1;
fnames = argv + 1; fnames = argv + 1;
} else { } else {
pkts_glob = path_join(get_testdata_dir(), "test-resolve/*.pkts"); _cleanup_free_ char *pkts_glob = NULL;
assert_se(get_testdata_dir("test-resolve/*.pkts", &pkts_glob) >= 0);
assert_se(glob(pkts_glob, GLOB_NOSORT, NULL, &g) == 0); assert_se(glob(pkts_glob, GLOB_NOSORT, NULL, &g) == 0);
N = g.gl_pathc; N = g.gl_pathc;
fnames = g.gl_pathv; fnames = g.gl_pathv;

View File

@ -58,21 +58,25 @@ static void load_testdata_env(void) {
setenv(*k, *v, 0); setenv(*k, *v, 0);
} }
const char* get_testdata_dir(void) { int get_testdata_dir(const char *suffix, char **ret) {
const char *env; const char *dir;
char *p;
load_testdata_env(); load_testdata_env();
/* if the env var is set, use that */ /* if the env var is set, use that */
env = getenv("SYSTEMD_TEST_DATA"); dir = getenv("SYSTEMD_TEST_DATA");
if (!env) if (!dir)
env = SYSTEMD_TEST_DATA; dir = SYSTEMD_TEST_DATA;
if (access(env, F_OK) < 0) { if (access(dir, F_OK) < 0)
fprintf(stderr, "ERROR: $SYSTEMD_TEST_DATA directory [%s] does not exist\n", env); return log_error_errno(errno, "ERROR: $SYSTEMD_TEST_DATA directory [%s] not accesible: %m", dir);
exit(EXIT_FAILURE);
}
return env; p = path_join(dir, suffix);
if (!p)
return log_oom();
*ret = p;
return 0;
} }
const char* get_catalog_dir(void) { const char* get_catalog_dir(void) {

View File

@ -20,7 +20,7 @@ static inline bool manager_errno_skip_test(int r) {
char* setup_fake_runtime_dir(void); char* setup_fake_runtime_dir(void);
int enter_cgroup_subroot(char **ret_cgroup); int enter_cgroup_subroot(char **ret_cgroup);
const char* get_testdata_dir(void); int get_testdata_dir(const char *suffix, char **ret);
const char* get_catalog_dir(void); const char* get_catalog_dir(void);
bool slow_tests_enabled(void); bool slow_tests_enabled(void);
void test_setup_logging(int level); void test_setup_logging(int level);

View File

@ -51,6 +51,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_LOG_TARGET, ARG_LOG_TARGET,
ARG_LOG_COLOR, ARG_LOG_COLOR,
ARG_LOG_LOCATION, ARG_LOG_LOCATION,
ARG_LOG_TIME,
ARG_EXIT_CODE, ARG_EXIT_CODE,
ARG_TIMEOUT, ARG_TIMEOUT,
}; };
@ -60,6 +61,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "log-target", required_argument, NULL, ARG_LOG_TARGET }, { "log-target", required_argument, NULL, ARG_LOG_TARGET },
{ "log-color", optional_argument, NULL, ARG_LOG_COLOR }, { "log-color", optional_argument, NULL, ARG_LOG_COLOR },
{ "log-location", optional_argument, NULL, ARG_LOG_LOCATION }, { "log-location", optional_argument, NULL, ARG_LOG_LOCATION },
{ "log-time", optional_argument, NULL, ARG_LOG_TIME },
{ "exit-code", required_argument, NULL, ARG_EXIT_CODE }, { "exit-code", required_argument, NULL, ARG_EXIT_CODE },
{ "timeout", required_argument, NULL, ARG_TIMEOUT }, { "timeout", required_argument, NULL, ARG_TIMEOUT },
{} {}
@ -110,6 +112,17 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_LOG_TIME:
if (optarg) {
r = log_show_time_from_string(optarg);
if (r < 0)
log_error_errno(r, "Failed to parse log time setting %s, ignoring: %m", optarg);
} else
log_show_time(true);
break;
case ARG_EXIT_CODE: case ARG_EXIT_CODE:
r = safe_atou8(optarg, &arg_exit_code); r = safe_atou8(optarg, &arg_exit_code);
if (r < 0) if (r < 0)

View File

@ -83,6 +83,7 @@ enum {
SD_DHCP_OPTION_REBINDING_T2_TIME = 59, SD_DHCP_OPTION_REBINDING_T2_TIME = 59,
SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60, SD_DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60,
SD_DHCP_OPTION_CLIENT_IDENTIFIER = 61, SD_DHCP_OPTION_CLIENT_IDENTIFIER = 61,
SD_DHCP_OPTION_SMTP_SERVER = 69,
SD_DHCP_OPTION_POP3_SERVER = 70, SD_DHCP_OPTION_POP3_SERVER = 70,
SD_DHCP_OPTION_USER_CLASS = 77, SD_DHCP_OPTION_USER_CLASS = 77,
SD_DHCP_OPTION_FQDN = 81, SD_DHCP_OPTION_FQDN = 81,

View File

@ -46,6 +46,7 @@ int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr); int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu); int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname); int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains); int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);

View File

@ -51,6 +51,7 @@ int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], u
int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n); int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n);
int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n); int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n);
int sd_dhcp_server_set_pop3_server(sd_dhcp_server *server, const struct in_addr pop3_server[], unsigned n); int sd_dhcp_server_set_pop3_server(sd_dhcp_server *server, const struct in_addr pop3_server[], unsigned n);
int sd_dhcp_server_set_smtp_server(sd_dhcp_server *server, const struct in_addr smtp_server[], unsigned n);
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled); int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled);
int sd_dhcp_server_add_option(sd_dhcp_server *server, sd_dhcp_option *v); int sd_dhcp_server_add_option(sd_dhcp_server *server, sd_dhcp_option *v);

View File

@ -170,6 +170,9 @@ int sd_network_link_get_sip_servers(int ifindex, char ***sip);
/* Get the pop3 servers for a given link. */ /* Get the pop3 servers for a given link. */
int sd_network_link_get_pop3_servers(int ifindex, char ***pop3); int sd_network_link_get_pop3_servers(int ifindex, char ***pop3);
/* Get the SMTP servers for a given link. */
int sd_network_link_get_smtp_servers(int ifindex, char ***smtp);
/* Get whether this link shall be used as 'default route' for DNS queries */ /* Get whether this link shall be used as 'default route' for DNS queries */
int sd_network_link_get_dns_default_route(int ifindex); int sd_network_link_get_dns_default_route(int ifindex);

View File

@ -1026,10 +1026,7 @@ tests += [
] ]
# test-bus-vtable-cc.cc is a symlink and symlinks get lost in containers on FuzzBuzz. if cxx_cmd != ''
# The issue has been reported to the developers of FuzzBuzz and hopefully will be fixed soon.
# In the meantime, let's just skip the symlink there.
if cxx_cmd != '' and not want_fuzzbuzz
tests += [ tests += [
[['src/libsystemd/sd-bus/test-bus-vtable-cc.cc'], [['src/libsystemd/sd-bus/test-bus-vtable-cc.cc'],
[], [],

View File

@ -48,7 +48,9 @@ int main(int argc, char *argv[]) {
if (r == -ENOMEDIUM) if (r == -ENOMEDIUM)
return log_tests_skipped("cgroupfs not available"); return log_tests_skipped("cgroupfs not available");
assert_se(set_unit_path(get_testdata_dir()) >= 0); _cleanup_free_ char *unit_dir = NULL;
assert_se(get_testdata_dir("units", &unit_dir) >= 0);
assert_se(set_unit_path(unit_dir) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir()); assert_se(runtime_dir = setup_fake_runtime_dir());
r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &p); r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &p);

View File

@ -38,7 +38,9 @@ static int test_cgroup_mask(void) {
return log_tests_skipped("cgroupfs not available"); return log_tests_skipped("cgroupfs not available");
/* Prepare the manager. */ /* Prepare the manager. */
assert_se(set_unit_path(get_testdata_dir()) >= 0); _cleanup_free_ char *unit_dir = NULL;
assert_se(get_testdata_dir("units", &unit_dir) >= 0);
assert_se(set_unit_path(unit_dir) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir()); assert_se(runtime_dir = setup_fake_runtime_dir());
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m);
if (IN_SET(r, -EPERM, -EACCES)) { if (IN_SET(r, -EPERM, -EACCES)) {

View File

@ -22,7 +22,9 @@ static int test_default_memory_low(void) {
if (r == -ENOMEDIUM) if (r == -ENOMEDIUM)
return log_tests_skipped("cgroupfs not available"); return log_tests_skipped("cgroupfs not available");
assert_se(set_unit_path(get_testdata_dir()) >= 0); _cleanup_free_ char *unit_dir = NULL;
assert_se(get_testdata_dir("units", &unit_dir) >= 0);
assert_se(set_unit_path(unit_dir) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir()); assert_se(runtime_dir = setup_fake_runtime_dir());
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m);
if (IN_SET(r, -EPERM, -EACCES)) { if (IN_SET(r, -EPERM, -EACCES)) {

View File

@ -26,8 +26,11 @@ int main(int argc, char *argv[]) {
return log_tests_skipped("cgroupfs not available"); return log_tests_skipped("cgroupfs not available");
/* prepare the test */ /* prepare the test */
assert_se(set_unit_path(get_testdata_dir()) >= 0); _cleanup_free_ char *unit_dir = NULL;
assert_se(get_testdata_dir("units", &unit_dir) >= 0);
assert_se(set_unit_path(unit_dir) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir()); assert_se(runtime_dir = setup_fake_runtime_dir());
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m);
if (manager_errno_skip_test(r)) if (manager_errno_skip_test(r))
return log_tests_skipped_errno(r, "manager_new"); return log_tests_skipped_errno(r, "manager_new");

View File

@ -806,7 +806,6 @@ static int run_tests(UnitFileScope scope, const test_entry tests[], char **patte
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
_cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL; _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
_cleanup_free_ char *test_execute_path = NULL;
static const test_entry user_tests[] = { static const test_entry user_tests[] = {
entry(test_exec_basic), entry(test_exec_basic),
@ -878,9 +877,10 @@ int main(int argc, char *argv[]) {
if (r == -ENOMEDIUM) if (r == -ENOMEDIUM)
return log_tests_skipped("cgroupfs not available"); return log_tests_skipped("cgroupfs not available");
_cleanup_free_ char *unit_dir = NULL;
assert_se(get_testdata_dir("test-execute/", &unit_dir) >= 0);
assert_se(set_unit_path(unit_dir) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir()); assert_se(runtime_dir = setup_fake_runtime_dir());
test_execute_path = path_join(get_testdata_dir(), "test-execute");
assert_se(set_unit_path(test_execute_path) >= 0);
/* Unset VAR1, VAR2 and VAR3 which are used in the PassEnvironment test /* Unset VAR1, VAR2 and VAR3 which are used in the PassEnvironment test
* cases, otherwise (and if they are present in the environment), * cases, otherwise (and if they are present in the environment),

View File

@ -444,20 +444,20 @@ static void test_write_string_file_verify(void) {
_cleanup_free_ char *buf = NULL, *buf2 = NULL; _cleanup_free_ char *buf = NULL, *buf2 = NULL;
int r; int r;
assert_se(read_one_line_file("/proc/cmdline", &buf) >= 0); assert_se(read_one_line_file("/proc/version", &buf) >= 0);
assert_se(buf2 = strjoin(buf, "\n")); assert_se(buf2 = strjoin(buf, "\n"));
r = write_string_file("/proc/cmdline", buf, 0); r = write_string_file("/proc/version", buf, 0);
assert_se(IN_SET(r, -EACCES, -EIO)); assert_se(IN_SET(r, -EACCES, -EIO));
r = write_string_file("/proc/cmdline", buf2, 0); r = write_string_file("/proc/version", buf2, 0);
assert_se(IN_SET(r, -EACCES, -EIO)); assert_se(IN_SET(r, -EACCES, -EIO));
assert_se(write_string_file("/proc/cmdline", buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE) == 0); assert_se(write_string_file("/proc/version", buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE) == 0);
assert_se(write_string_file("/proc/cmdline", buf2, WRITE_STRING_FILE_VERIFY_ON_FAILURE) == 0); assert_se(write_string_file("/proc/version", buf2, WRITE_STRING_FILE_VERIFY_ON_FAILURE) == 0);
r = write_string_file("/proc/cmdline", buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_AVOID_NEWLINE); r = write_string_file("/proc/version", buf, WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_AVOID_NEWLINE);
assert_se(IN_SET(r, -EACCES, -EIO)); assert_se(IN_SET(r, -EACCES, -EIO));
assert_se(write_string_file("/proc/cmdline", buf2, WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_AVOID_NEWLINE) == 0); assert_se(write_string_file("/proc/version", buf2, WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_AVOID_NEWLINE) == 0);
} }
static void test_load_env_file_pairs(void) { static void test_load_env_file_pairs(void) {
@ -757,7 +757,7 @@ static void test_read_line3(void) {
_cleanup_free_ char *line = NULL; _cleanup_free_ char *line = NULL;
int r; int r;
f = fopen("/proc/cmdline", "re"); f = fopen("/proc/uptime", "re");
if (!f && IN_SET(errno, ENOENT, EPERM)) if (!f && IN_SET(errno, ENOENT, EPERM))
return; return;
assert_se(f); assert_se(f);

View File

@ -25,7 +25,7 @@ static void test_basic_parsing(void) {
_cleanup_free_ char *journal_data_path = NULL; _cleanup_free_ char *journal_data_path = NULL;
int r; int r;
journal_data_path = path_join(get_testdata_dir(), "journal-data/journal-1.txt"); assert_se(get_testdata_dir("journal-data/journal-1.txt", &journal_data_path) >= 0);
imp.fd = open(journal_data_path, O_RDONLY|O_CLOEXEC); imp.fd = open(journal_data_path, O_RDONLY|O_CLOEXEC);
assert_se(imp.fd >= 0); assert_se(imp.fd >= 0);
@ -56,7 +56,7 @@ static void test_bad_input(void) {
_cleanup_free_ char *journal_data_path = NULL; _cleanup_free_ char *journal_data_path = NULL;
int r; int r;
journal_data_path = path_join(get_testdata_dir(), "journal-data/journal-2.txt"); assert_se(get_testdata_dir("journal-data/journal-1.txt", &journal_data_path) >= 0);
imp.fd = open(journal_data_path, O_RDONLY|O_CLOEXEC); imp.fd = open(journal_data_path, O_RDONLY|O_CLOEXEC);
assert_se(imp.fd >= 0); assert_se(imp.fd >= 0);

View File

@ -251,7 +251,7 @@ int main(int argc, char *argv[]) {
test_setup_logging(LOG_INFO); test_setup_logging(LOG_INFO);
test_path = path_join(get_testdata_dir(), "test-path"); assert_se(get_testdata_dir("test-path", &test_path) >= 0);
assert_se(set_unit_path(test_path) >= 0); assert_se(set_unit_path(test_path) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir()); assert_se(runtime_dir = setup_fake_runtime_dir());

View File

@ -25,8 +25,11 @@ int main(int argc, char *argv[]) {
return log_tests_skipped("cgroupfs not available"); return log_tests_skipped("cgroupfs not available");
/* prepare the test */ /* prepare the test */
assert_se(set_unit_path(get_testdata_dir()) >= 0); _cleanup_free_ char *unit_dir = NULL;
assert_se(get_testdata_dir("units", &unit_dir) >= 0);
assert_se(set_unit_path(unit_dir) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir()); assert_se(runtime_dir = setup_fake_runtime_dir());
r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m);
if (manager_errno_skip_test(r)) if (manager_errno_skip_test(r))
return log_tests_skipped_errno(r, "manager_new"); return log_tests_skipped_errno(r, "manager_new");

View File

@ -674,7 +674,7 @@ static void test_strv_push_prepend(void) {
log_info("/* %s */", __func__); log_info("/* %s */", __func__);
a = strv_new("foo", "bar", "three"); assert_se(a = strv_new("foo", "bar", "three"));
assert_se(strv_push_prepend(&a, strdup("first")) >= 0); assert_se(strv_push_prepend(&a, strdup("first")) >= 0);
assert_se(streq(a[0], "first")); assert_se(streq(a[0], "first"));

View File

@ -15,8 +15,10 @@ static void test_mount_points_list(const char *fname) {
log_info("/* %s(\"%s\") */", __func__, fname ?: "/proc/self/mountinfo"); log_info("/* %s(\"%s\") */", __func__, fname ?: "/proc/self/mountinfo");
if (fname) if (fname) {
fname = testdata_fname = path_join(get_testdata_dir(), fname); assert_se(get_testdata_dir(fname, &testdata_fname) >= 0);
fname = testdata_fname;
}
LIST_HEAD_INIT(mp_list_head); LIST_HEAD_INIT(mp_list_head);
assert_se(mount_points_list_get(fname, &mp_list_head) >= 0); assert_se(mount_points_list_get(fname, &mp_list_head) >= 0);
@ -37,8 +39,10 @@ static void test_swap_list(const char *fname) {
log_info("/* %s(\"%s\") */", __func__, fname ?: "/proc/swaps"); log_info("/* %s(\"%s\") */", __func__, fname ?: "/proc/swaps");
if (fname) if (fname) {
fname = testdata_fname = path_join(get_testdata_dir(), fname); assert_se(get_testdata_dir(fname, &testdata_fname) >= 0);
fname = testdata_fname;
}
LIST_HEAD_INIT(mp_list_head); LIST_HEAD_INIT(mp_list_head);
assert_se(swap_list_get(fname, &mp_list_head) >= 0); assert_se(swap_list_get(fname, &mp_list_head) >= 0);

View File

@ -20,7 +20,10 @@ int main(int argc, char *argv[]) {
if (r == -ENOMEDIUM) if (r == -ENOMEDIUM)
return log_tests_skipped("cgroupfs not available"); return log_tests_skipped("cgroupfs not available");
assert_se(set_unit_path(get_testdata_dir()) >= 0); _cleanup_free_ char *unit_dir = NULL;
assert_se(get_testdata_dir("units/", &unit_dir) >= 0);
assert_se(set_unit_path(unit_dir) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir()); assert_se(runtime_dir = setup_fake_runtime_dir());
assert_se(manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0); assert_se(manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m) >= 0);

View File

@ -10,10 +10,10 @@ ninja: no work to do.
--x-- Running TEST-01-BASIC --x-- --x-- Running TEST-01-BASIC --x--
+ make -C TEST-01-BASIC BUILD_DIR=/home/zbyszek/src/systemd/build clean setup run + make -C TEST-01-BASIC BUILD_DIR=/home/zbyszek/src/systemd/build clean setup run
make: Entering directory '/home/zbyszek/src/systemd/test/TEST-01-BASIC' make: Entering directory '/home/zbyszek/src/systemd/test/TEST-01-BASIC'
TEST CLEANUP: Basic systemd setup TEST-01-BASIC CLEANUP: Basic systemd setup
TEST SETUP: Basic systemd setup TEST-01-BASIC SETUP: Basic systemd setup
... ...
TEST RUN: Basic systemd setup [OK] TEST-01-BASIC RUN: Basic systemd setup [OK]
make: Leaving directory '/home/zbyszek/src/systemd/test/TEST-01-BASIC' make: Leaving directory '/home/zbyszek/src/systemd/test/TEST-01-BASIC'
--x-- Result of TEST-01-BASIC: 0 --x-- --x-- Result of TEST-01-BASIC: 0 --x--
--x-- Running TEST-02-CRYPTSETUP --x-- --x-- Running TEST-02-CRYPTSETUP --x--

View File

@ -1,9 +1,6 @@
BUILD_DIR=$(shell ../../tools/find-build-dir.sh) BUILD_DIR=$(shell ../../tools/find-build-dir.sh)
all setup run: all setup run clean clean-again:
@basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@
clean clean-again:
@basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --clean
.PHONY: all setup run clean clean-again .PHONY: all setup run clean clean-again

View File

@ -1,34 +1,25 @@
#!/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"
RUN_IN_UNPRIVILEGED_CONTAINER=${RUN_IN_UNPRIVILEGED_CONTAINER:-yes} RUN_IN_UNPRIVILEGED_CONTAINER=${RUN_IN_UNPRIVILEGED_CONTAINER:-yes}
TEST_REQUIRE_INSTALL_TESTS=0
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { test_create_image() {
create_empty_image_rootdir create_empty_image_rootdir
# 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=${LOOPDEV}p2)
setup_basic_environment setup_basic_environment
# setup the testsuite service # install tests manually so the test is functional even when -Dinstall-tests=false
cat >$initdir/etc/systemd/system/testsuite.service <<EOF mkdir -p $initdir/usr/lib/systemd/tests/testdata/units/
[Unit] cp -v $(dirname $0)/../units/{testsuite-01,end}.service $initdir/usr/lib/systemd/tests/testdata/units/
Description=Testsuite service
After=multi-user.target
[Service]
ExecStart=/bin/sh -e -x -c 'systemctl --state=failed --no-legend --no-pager > /failed ; systemctl daemon-reload ; echo OK > /testok'
Type=oneshot
EOF
setup_testsuite
) )
setup_nspawn_root setup_nspawn_root
} }
do_test "$@" do_test "$@" 01

View File

@ -1,21 +1,22 @@
#!/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"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
check_result_qemu() { check_result_qemu() {
ret=1 ret=1
mkdir -p $initdir mount_initdir
mount ${LOOPDEV}p1 $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 cryptsetup luksOpen ${LOOPDEV}p2 varcrypt <$TESTDIR/keyfile
mount /dev/mapper/varcrypt $initdir/var mount /dev/mapper/varcrypt $initdir/var
cp -a $initdir/var/log/journal $TESTDIR cp -a $initdir/var/log/journal $TESTDIR
umount $initdir/var rm -r $initdir/var/log/journal/*
umount $initdir _umount_dir $initdir/var
_umount_dir $initdir
cryptsetup luksClose /dev/mapper/varcrypt cryptsetup luksClose /dev/mapper/varcrypt
[[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed
ls -l $TESTDIR/journal/*/*.journal ls -l $TESTDIR/journal/*/*.journal
@ -23,8 +24,7 @@ check_result_qemu() {
return $ret return $ret
} }
test_create_image() {
test_setup() {
create_empty_image_rootdir create_empty_image_rootdir
echo -n test >$TESTDIR/keyfile echo -n test >$TESTDIR/keyfile
cryptsetup -q luksFormat --pbkdf pbkdf2 --pbkdf-force-iterations 1000 ${LOOPDEV}p2 $TESTDIR/keyfile cryptsetup -q luksFormat --pbkdf pbkdf2 --pbkdf-force-iterations 1000 ${LOOPDEV}p2 $TESTDIR/keyfile
@ -42,25 +42,12 @@ test_setup() {
setup_basic_environment setup_basic_environment
mask_supporting_services mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
After=multi-user.target
[Service]
ExecStart=/bin/sh -x -c 'systemctl --state=failed --no-legend --no-pager > /failed ; echo OK > /testok'
Type=oneshot
EOF
setup_testsuite
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 cat $initdir/etc/crypttab | ddebug
cat >>$initdir/etc/fstab <<EOF cat >>$initdir/etc/fstab <<EOF
@ -82,8 +69,8 @@ test_cleanup() {
} }
test_setup_cleanup() { test_setup_cleanup() {
cleanup_root_var cleanup_root_var || :
_test_setup_cleanup cleanup_initdir
} }
do_test "$@" do_test "$@" 02

View File

@ -5,36 +5,4 @@ TEST_NO_QEMU=1
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 03
create_empty_image_rootdir
# Create what will eventually be our root filesystem onto an overlay
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
After=multi-user.target
[Service]
ExecStart=/test-jobs.sh
Type=oneshot
EOF
# copy the units used by this test
cp $TEST_BASE_DIR/{hello.service,sleep.service,hello-after-sleep.target,unstoppable.service} \
$initdir/etc/systemd/system
cp test-jobs.sh $initdir/
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

@ -4,41 +4,4 @@ TEST_DESCRIPTION="Journal-related tests"
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 04
create_empty_image_rootdir
# Create what will eventually be our root filesystem onto an overlay
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/test-journal.sh
Type=oneshot
EOF
cat >$initdir/etc/systemd/system/forever-print-hola.service <<EOF
[Unit]
Description=ForeverPrintHola service
[Service]
Type=simple
ExecStart=/bin/sh -x -c 'while :; do printf "Hola\n" || touch /i-lose-my-logs; sleep 1; done'
EOF
cp test-journal.sh $initdir/
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

@ -1,15 +0,0 @@
#!/usr/bin/env bash
set -x
set -e
set -o pipefail
[[ "$(systemctl show -p DefaultLimitNOFILESoft)" = "DefaultLimitNOFILESoft=10000" ]]
[[ "$(systemctl show -p DefaultLimitNOFILE)" = "DefaultLimitNOFILE=16384" ]]
[[ "$(systemctl show -p LimitNOFILESoft testsuite.service)" = "LimitNOFILESoft=10000" ]]
[[ "$(systemctl show -p LimitNOFILE testsuite.service)" = "LimitNOFILE=16384" ]]
[[ "$(ulimit -n -S)" = "10000" ]]
[[ "$(ulimit -n -H)" = "16384" ]]
touch /testok

View File

@ -4,37 +4,4 @@ TEST_DESCRIPTION="Resource limits-related tests"
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 05
create_empty_image_rootdir
# Create what will eventually be our root filesystem onto an overlay
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
cat >$initdir/etc/systemd/system.conf <<EOF
[Manager]
DefaultLimitNOFILE=10000:16384
EOF
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/test-rlimits.sh
Type=oneshot
EOF
cp test-rlimits.sh $initdir/
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

@ -1,6 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="SELinux tests" TEST_DESCRIPTION="SELinux tests"
IMAGE_NAME="selinux"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
# Requirements: # Requirements:
@ -15,60 +16,16 @@ test -f /usr/share/selinux/devel/include/system/systemd.if || exit 0
SETUP_SELINUX=yes SETUP_SELINUX=yes
KERNEL_APPEND="$KERNEL_APPEND selinux=1 security=selinux" KERNEL_APPEND="$KERNEL_APPEND selinux=1 security=selinux"
test_setup() { test_create_image() {
create_empty_image_rootdir create_empty_image_rootdir
# 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=${LOOPDEV}p2)
setup_basic_environment setup_basic_environment
mask_supporting_services mask_supporting_services
# setup the testsuite service
cat <<EOF >$initdir/etc/systemd/system/testsuite.service
[Unit]
Description=Testsuite service
[Service]
ExecStart=/test-selinux-checks.sh
Type=oneshot
EOF
cat <<EOF >$initdir/etc/systemd/system/hola.service
[Service]
Type=oneshot
ExecStart=/bin/echo Start Hola
ExecReload=/bin/echo Reload Hola
ExecStop=/bin/echo Stop Hola
RemainAfterExit=yes
EOF
setup_testsuite
cat <<EOF >$initdir/etc/systemd/system/load-systemd-test-module.service
[Unit]
Description=Load systemd-test module
DefaultDependencies=no
Requires=local-fs.target
Conflicts=shutdown.target
After=local-fs.target
Before=sysinit.target shutdown.target autorelabel.service
ConditionSecurity=selinux
ConditionPathExists=|/.load-systemd-test-module
[Service]
ExecStart=/bin/sh -x -c 'echo 0 >/sys/fs/selinux/enforce && cd /systemd-test-module && make -f /usr/share/selinux/devel/Makefile load && rm /.load-systemd-test-module'
Type=oneshot
TimeoutSec=0
RemainAfterExit=yes
EOF
touch $initdir/.load-systemd-test-module
mkdir -p $initdir/etc/systemd/system/basic.target.wants
ln -fs load-systemd-test-module.service $initdir/etc/systemd/system/basic.target.wants/load-systemd-test-module.service
local _modules_dir=/var/lib/selinux local _modules_dir=/var/lib/selinux
rm -rf $initdir/$_modules_dir rm -rf $initdir/$_modules_dir
if ! cp -ar $_modules_dir $initdir/$_modules_dir; then if ! cp -ar $_modules_dir $initdir/$_modules_dir; then
@ -87,11 +44,10 @@ EOF
mkdir $initdir/systemd-test-module mkdir $initdir/systemd-test-module
cp systemd_test.te $initdir/systemd-test-module cp systemd_test.te $initdir/systemd-test-module
cp systemd_test.if $initdir/systemd-test-module cp systemd_test.if $initdir/systemd-test-module
cp test-selinux-checks.sh $initdir
dracut_install -o sesearch dracut_install -o sesearch
dracut_install runcon dracut_install runcon
dracut_install checkmodule semodule semodule_package m4 make /usr/libexec/selinux/hll/pp load_policy sefcontext_compile dracut_install checkmodule semodule semodule_package m4 make /usr/libexec/selinux/hll/pp load_policy sefcontext_compile
) )
} }
do_test "$@" do_test "$@" 06

View File

@ -7,32 +7,4 @@ TEST_NO_QEMU=1
NSPAWN_TIMEOUT=30 NSPAWN_TIMEOUT=30
test_setup() { do_test "$@" 07
create_empty_image_rootdir
# Create what will eventually be our root filesystem onto an overlay
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/test-segfault.sh
Type=oneshot
EOF
cp test-segfault.sh $initdir/
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

@ -1,70 +1,22 @@
#!/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"
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
QEMU_TIMEOUT=300 QEMU_TIMEOUT=300
FSTYPE=ext4 FSTYPE=ext4
test_setup() { test_create_image() {
create_empty_image_rootdir create_empty_image_rootdir
# 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=${LOOPDEV}p2)
setup_basic_environment setup_basic_environment
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/bin/sh -x -c 'mount -o remount,rw /dev/sda1 && echo OK > /testok; systemctl poweroff'
Type=oneshot
EOF
rm $initdir/etc/fstab
cat >$initdir/etc/systemd/system/-.mount <<EOF
[Unit]
Before=local-fs.target
[Mount]
What=/dev/sda1
Where=/
Type=ext4
Options=errors=remount-ro,noatime
[Install]
WantedBy=local-fs.target
Alias=root.mount
EOF
cat >$initdir/etc/systemd/system/systemd-remount-fs.service <<EOF
[Unit]
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-fsck-root.service
Before=local-fs-pre.target local-fs.target shutdown.target
Wants=local-fs-pre.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/systemctl reload /
EOF
setup_testsuite
) )
ln -s /etc/systemd/system/-.mount $initdir/etc/systemd/system/root.mount
mkdir -p $initdir/etc/systemd/system/local-fs.target.wants
ln -s /etc/systemd/system/-.mount $initdir/etc/systemd/system/local-fs.target.wants/-.mount
mask_supporting_services mask_supporting_services
} }
do_test "$@" do_test "$@" 08

View File

@ -6,32 +6,4 @@ TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
QEMU_TIMEOUT=300 QEMU_TIMEOUT=300
test_setup() { do_test "$@" 09
create_empty_image_rootdir
# Create what will eventually be our root filesystem onto an overlay
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<'EOF'
[Unit]
Description=Testsuite service
[Service]
Type=oneshot
ExecStart=/bin/sh -c '>/testok'
RemainAfterExit=yes
ExecStop=/bin/sh -c 'kill -SEGV $$$$'
TimeoutStopSec=270s
EOF
setup_testsuite
)
}
do_test "$@"

View File

@ -4,45 +4,4 @@ TEST_DESCRIPTION="https://github.com/systemd/systemd/issues/2467"
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 10
create_empty_image_rootdir
# Create what will eventually be our root filesystem onto an overlay
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
dracut_install true rm socat
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<'EOF'
[Unit]
Description=Testsuite service
[Service]
Type=oneshot
ExecStart=/bin/sh -e -x -c 'rm -f /tmp/nonexistent; systemctl start test.socket; printf x > test.file; socat -t20 OPEN:test.file UNIX-CONNECT:/run/test.ctl; >/testok'
EOF
cat >$initdir/etc/systemd/system/test.socket <<'EOF'
[Socket]
ListenStream=/run/test.ctl
EOF
cat > $initdir/etc/systemd/system/test.service <<'EOF'
[Unit]
Requires=test.socket
ConditionPathExistsGlob=/tmp/nonexistent
[Service]
ExecStart=/bin/true
EOF
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

@ -5,58 +5,4 @@ TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 11
create_empty_image_rootdir
# Create what will eventually be our root filesystem onto an overlay
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
dracut_install false touch
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/test-fail-on-restart.sh
Type=oneshot
EOF
cat >$initdir/etc/systemd/system/fail-on-restart.service <<EOF
[Unit]
Description=Fail on restart
StartLimitIntervalSec=1m
StartLimitBurst=3
[Service]
Type=simple
ExecStart=/bin/false
Restart=always
EOF
cat >$initdir/test-fail-on-restart.sh <<'EOF'
#!/usr/bin/env bash
set -x
systemctl start fail-on-restart.service
active_state=$(systemctl show --property ActiveState fail-on-restart.service)
while [[ "$active_state" == "ActiveState=activating" || "$active_state" == "ActiveState=active" ]]; do
sleep 1
active_state=$(systemctl show --property ActiveState fail-on-restart.service)
done
systemctl is-failed fail-on-restart.service || exit 1
touch /testok
EOF
chmod 0755 $initdir/test-fail-on-restart.sh
setup_testsuite
)
}
do_test "$@"

View File

@ -5,85 +5,4 @@ TEST_NO_QEMU=1
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 12
create_empty_image_rootdir
# Create what will eventually be our root filesystem onto an overlay
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
dracut_install cat mv stat nc
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
After=multi-user.target
[Service]
ExecStart=/test-socket-group.sh
Type=oneshot
EOF
cat >$initdir/test-socket-group.sh <<'EOF'
#!/usr/bin/env bash
set -x
set -e
set -o pipefail
U=/run/systemd/system/test.socket
cat <<'EOL' >$U
[Unit]
Description=Test socket
[Socket]
Accept=yes
ListenStream=/run/test.socket
SocketGroup=adm
SocketMode=0660
EOL
cat <<'EOL' > /run/systemd/system/test@.service
[Unit]
Description=Test service
[Service]
StandardInput=socket
ExecStart=/bin/sh -x -c cat
EOL
systemctl start test.socket
systemctl is-active test.socket
[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
echo A | nc -w1 -U /run/test.socket
mv $U ${U}.disabled
systemctl daemon-reload
systemctl is-active test.socket
[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
echo B | nc -w1 -U /run/test.socket && exit 1
mv ${U}.disabled $U
systemctl daemon-reload
systemctl is-active test.socket
echo C | nc -w1 -U /run/test.socket && exit 1
[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
systemctl restart test.socket
systemctl is-active test.socket
echo D | nc -w1 -U /run/test.socket
[[ "$(stat --format='%G' /run/test.socket)" == adm ]]
touch /testok
EOF
chmod 0755 $initdir/test-socket-group.sh
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

@ -1,10 +0,0 @@
BUILD_DIR=$(shell ../../tools/find-build-dir.sh)
all setup run:
@basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@
clean clean-again:
@basedir=../.. TEST_BASE_DIR=../ ./test.sh --clean
@rm -f has-overflow
.PHONY: all setup run clean clean-again

View File

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

View File

@ -1,193 +1,23 @@
#!/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
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { test_create_image() {
create_empty_image_rootdir create_empty_image_rootdir
# 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=${LOOPDEV}p2)
setup_basic_environment setup_basic_environment
mask_supporting_services mask_supporting_services
dracut_install busybox chmod rmdir unshare ip sysctl
cp create-busybox-container $initdir/ ../create-busybox-container $initdir/nc-container
./create-busybox-container $initdir/nc-container
initdir="$initdir/nc-container" dracut_install nc ip initdir="$initdir/nc-container" dracut_install nc ip
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/test-nspawn.sh
Type=oneshot
EOF
cat >$initdir/test-nspawn.sh <<'EOF'
#!/usr/bin/env bash
set -x
set -e
set -u
set -o pipefail
export SYSTEMD_LOG_LEVEL=debug
# check cgroup-v2
is_v2_supported=no
mkdir -p /tmp/cgroup2
if mount -t cgroup2 cgroup2 /tmp/cgroup2; then
is_v2_supported=yes
umount /tmp/cgroup2
fi
rmdir /tmp/cgroup2
# check cgroup namespaces
is_cgns_supported=no
if [[ -f /proc/1/ns/cgroup ]]; then
is_cgns_supported=yes
fi
is_user_ns_supported=no
# On some systems (e.g. CentOS 7) the default limit for user namespaces
# is set to 0, which causes the following unshare syscall to fail, even
# with enabled user namespaces support. By setting this value explicitly
# we can ensure the user namespaces support to be detected correctly.
sysctl -w user.max_user_namespaces=10000
if unshare -U sh -c :; then
is_user_ns_supported=yes
fi
function check_bind_tmp_path {
# https://github.com/systemd/systemd/issues/4789
local _root="/var/lib/machines/bind-tmp-path"
/create-busybox-container "$_root"
>/tmp/bind
systemd-nspawn --register=no -D "$_root" --bind=/tmp/bind /bin/sh -c 'test -e /tmp/bind'
}
function check_norbind {
# https://github.com/systemd/systemd/issues/13170
local _root="/var/lib/machines/norbind-path"
mkdir -p /tmp/binddir/subdir
echo -n "outer" > /tmp/binddir/subdir/file
mount -t tmpfs tmpfs /tmp/binddir/subdir
echo -n "inner" > /tmp/binddir/subdir/file
/create-busybox-container "$_root"
systemd-nspawn --register=no -D "$_root" --bind=/tmp/binddir:/mnt:norbind /bin/sh -c 'CONTENT=$(cat /mnt/subdir/file); if [[ $CONTENT != "outer" ]]; then echo "*** unexpected content: $CONTENT"; return 1; fi'
}
function check_notification_socket {
# https://github.com/systemd/systemd/issues/4944
local _cmd='echo a | $(busybox which nc) -U -u -w 1 /run/systemd/nspawn/notify'
systemd-nspawn --register=no -D /nc-container /bin/sh -x -c "$_cmd"
systemd-nspawn --register=no -D /nc-container -U /bin/sh -x -c "$_cmd"
}
function run {
if [[ "$1" = "yes" && "$is_v2_supported" = "no" ]]; then
printf "Unified cgroup hierarchy is not supported. Skipping.\n" >&2
return 0
fi
if [[ "$2" = "yes" && "$is_cgns_supported" = "no" ]]; then
printf "CGroup namespaces are not supported. Skipping.\n" >&2
return 0
fi
local _root="/var/lib/machines/unified-$1-cgns-$2-api-vfs-writable-$3"
/create-busybox-container "$_root"
SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" -b
SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" --private-network -b
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" -U -b; then
[[ "$is_user_ns_supported" = "yes" && "$3" = "network" ]] && return 1
else
[[ "$is_user_ns_supported" = "no" && "$3" = "network" ]] && return 1
fi
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" --private-network -U -b; then
[[ "$is_user_ns_supported" = "yes" && "$3" = "yes" ]] && return 1
else
[[ "$is_user_ns_supported" = "no" && "$3" = "yes" ]] && return 1
fi
local _netns_opt="--network-namespace-path=/proc/self/ns/net"
# --network-namespace-path and network-related options cannot be used together
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-interface=lo -b; then
return 1
fi
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-macvlan=lo -b; then
return 1
fi
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-ipvlan=lo -b; then
return 1
fi
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-veth -b; then
return 1
fi
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-veth-extra=lo -b; then
return 1
fi
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-bridge=lo -b; then
return 1
fi
if SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --network-zone=zone -b; then
return 1
fi
# allow combination of --network-namespace-path and --private-network
if ! SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" --private-network -b; then
return 1
fi
# test --network-namespace-path works with a network namespace created by "ip netns"
ip netns add nspawn_test
_netns_opt="--network-namespace-path=/run/netns/nspawn_test"
SYSTEMD_NSPAWN_UNIFIED_HIERARCHY="$1" SYSTEMD_NSPAWN_USE_CGNS="$2" SYSTEMD_NSPAWN_API_VFS_WRITABLE="$3" systemd-nspawn --register=no -D "$_root" "$_netns_opt" /bin/ip a | grep -v -E '^1: lo.*UP'
local r=$?
ip netns del nspawn_test
if [ $r -ne 0 ]; then
return 1
fi
return 0
}
check_bind_tmp_path
check_norbind
check_notification_socket
for api_vfs_writable in yes no network; do
run no no $api_vfs_writable
run yes no $api_vfs_writable
run no yes $api_vfs_writable
run yes yes $api_vfs_writable
done
touch /testok
EOF
chmod 0755 $initdir/test-nspawn.sh
setup_testsuite
) )
} }
do_test "$@" do_test "$@" 13

View File

@ -1,78 +1,21 @@
#!/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
TEST_NO_NSPAWN=1 TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { test_create_image() {
create_empty_image_rootdir create_empty_image_rootdir
# 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=${LOOPDEV}p2)
setup_basic_environment setup_basic_environment
mask_supporting_services mask_supporting_services
printf "556f48e837bc4424a710fa2e2c9d3e3c\ne3d\n" >$initdir/etc/machine-id printf "556f48e837bc4424a710fa2e2c9d3e3c\ne3d\n" >$initdir/etc/machine-id
dracut_install mount cmp
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/bin/sh -e -x -c '/test-machine-id-setup.sh; systemctl --state=failed --no-legend --no-pager > /failed ; echo OK > /testok'
Type=oneshot
EOF
cat >$initdir/test-machine-id-setup.sh <<'EOF'
#!/usr/bin/env bash
set -e
set -x
function setup_root {
local _root="$1"
mkdir -p "$_root"
mount -t tmpfs tmpfs "$_root"
mkdir -p "$_root/etc" "$_root/run"
}
function check {
printf "Expected\n"
cat "$1"
printf "\nGot\n"
cat "$2"
cmp "$1" "$2"
}
r="$(pwd)/overwrite-broken-machine-id"
setup_root "$r"
systemd-machine-id-setup --print --root "$r"
echo abc >>"$r/etc/machine-id"
id=$(systemd-machine-id-setup --print --root "$r")
echo $id >expected
check expected "$r/etc/machine-id"
r="$(pwd)/transient-machine-id"
setup_root "$r"
systemd-machine-id-setup --print --root "$r"
echo abc >>"$r/etc/machine-id"
mount -o remount,ro "$r"
mount -t tmpfs tmpfs "$r/run"
transient_id=$(systemd-machine-id-setup --print --root "$r")
mount -o remount,rw "$r"
commited_id=$(systemd-machine-id-setup --print --commit --root "$r")
[[ "$transient_id" = "$commited_id" ]]
check "$r/etc/machine-id" "$r/run/machine-id"
EOF
chmod +x $initdir/test-machine-id-setup.sh
setup_testsuite
) )
} }
do_test "$@" do_test "$@" 14

View File

@ -5,18 +5,4 @@ TEST_NO_QEMU=1
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 15
# create the basic filesystem layout
setup_basic_environment
mask_supporting_services
# import the test scripts in the rootfs and plug them in systemd
cp testsuite.service $initdir/etc/systemd/system/
cp test-dropin.sh $initdir/
setup_testsuite
# create dedicated rootfs for nspawn (located in $TESTDIR/nspawn-root)
setup_nspawn_root
}
do_test "$@"

View File

@ -1,6 +0,0 @@
[Unit]
Description=Testsuite service
[Service]
ExecStart=/test-dropin.sh
Type=oneshot

View File

@ -6,30 +6,4 @@ TEST_NO_QEMU=1
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 16
create_empty_image
# Create what will eventually be our root filesystem onto an overlay
(
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
for s in success-all success-start success-stop success-runtime \
fail-start fail-stop fail-runtime
do
cp testsuite-${s}.service ${initdir}/etc/systemd/system
done
cp testsuite.service ${initdir}/etc/systemd/system
cp extend_timeout_test_service.sh ${initdir}/
cp assess.sh ${initdir}/
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

@ -1,18 +0,0 @@
[Unit]
Description=Testsuite: Assess all other testsuite-*.services worked as expected
Wants=testsuite-success-all.service
Wants=testsuite-success-start.service
Wants=testsuite-success-runtime.service
Wants=testsuite-success-stop.service
Wants=testsuite-fail-start.service
Wants=testsuite-fail-stop.service
Wants=testsuite-fail-runtime.service
StopWhenUnneeded=yes
[Service]
Type=simple
TimeoutStartSec=infinity
ExecStartPre=/assess.sh
ExecStart=/bin/true

View File

@ -6,29 +6,4 @@ TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
QEMU_TIMEOUT=300 QEMU_TIMEOUT=300
test_setup() { do_test "$@" 17
create_empty_image_rootdir
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/bin/bash -x /testsuite.sh
Type=oneshot
EOF
cp testsuite.sh $initdir/
setup_testsuite
)
}
do_test "$@"

View File

@ -5,31 +5,4 @@ TEST_DESCRIPTION="FailureAction= operation"
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
QEMU_TIMEOUT=600 QEMU_TIMEOUT=600
test_setup() { do_test "$@" 18
create_empty_image_rootdir
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/bin/bash -x /testsuite.sh
Type=oneshot
EOF
cp testsuite.sh $initdir/
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

@ -7,29 +7,4 @@ TEST_NO_NSPAWN=1
QEMU_TIMEOUT=600 QEMU_TIMEOUT=600
UNIFIED_CGROUP_HIERARCHY=yes UNIFIED_CGROUP_HIERARCHY=yes
test_setup() { do_test "$@" 19
create_empty_image_rootdir
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/bin/bash -x /testsuite.sh
Type=oneshot
EOF
cp testsuite.sh $initdir/
setup_testsuite
)
}
do_test "$@"

View File

@ -4,34 +4,4 @@ TEST_DESCRIPTION="test changing main PID"
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 20
create_empty_image_rootdir
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
Before=getty-pre.target
Wants=getty-pre.target
[Service]
ExecStart=/bin/bash -x /testsuite.sh
Type=oneshot
NotifyAccess=all
EOF
cp testsuite.sh $initdir/
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -e set -e
TEST_DESCRIPTION="Sysuser-related tests" TEST_DESCRIPTION="Sysuser-related tests"
IMAGE_NAME=sysusers
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { test_setup() {

View File

@ -2,30 +2,6 @@
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 . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 22
# create the basic filesystem layout
setup_basic_environment
mask_supporting_services
inst_binary mv
inst_binary stat
inst_binary seq
inst_binary xargs
inst_binary mkfifo
inst_binary readlink
# setup the testsuite service
cp testsuite.service $initdir/etc/systemd/system/
setup_testsuite
mkdir -p $initdir/testsuite
cp run-tmpfiles-tests.sh $initdir/testsuite/
cp test-*.sh $initdir/testsuite/
# create dedicated rootfs for nspawn (located in $TESTDIR/nspawn-root)
setup_nspawn_root
}
do_test "$@"

View File

@ -1,33 +1,6 @@
#!/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 . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 23
create_empty_image_rootdir
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/testsuite.sh
Type=oneshot
EOF
cp testsuite.sh $initdir/
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

@ -3,34 +3,43 @@ 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
# embed some newlines in the kernel command line to stress our test suite
KERNEL_APPEND="
frobnicate!
$KERNEL_APPEND
"
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
check_result_nspawn() { check_result_nspawn() {
local _ret=1 local _ret=1
[[ -e $TESTDIR/$1/testok ]] && _ret=0 [[ -e $1/testok ]] && _ret=0
if [[ -s $TESTDIR/$1/failed ]]; then if [[ -s $1/failed ]]; then
_ret=$(($_ret+1)) _ret=$(($_ret+1))
echo "=== Failed test log ===" echo "=== Failed test log ==="
cat $TESTDIR/$1/failed cat $1/failed
else else
if [[ -s $TESTDIR/$1/skipped ]]; then if [[ -s $1/skipped ]]; then
echo "=== Skipped test log ==" echo "=== Skipped test log =="
cat $TESTDIR/$1/skipped cat $1/skipped
fi fi
if [[ -s $TESTDIR/$1/testok ]]; then if [[ -s $1/testok ]]; then
echo "=== Passed tests ===" echo "=== Passed tests ==="
cat $TESTDIR/$1/testok cat $1/testok
fi fi
fi fi
cp -a $TESTDIR/$1/var/log/journal $TESTDIR cp -a $1/var/log/journal $TESTDIR
rm -r $1/var/log/journal/*
_umount_dir $initdir
[[ -n "$TIMED_OUT" ]] && _ret=$(($_ret+1)) [[ -n "$TIMED_OUT" ]] && _ret=$(($_ret+1))
return $_ret return $_ret
} }
check_result_qemu() { check_result_qemu() {
local _ret=1 local _ret=1
mkdir -p $initdir mount_initdir
mount ${LOOPDEV}p1 $initdir
[[ -e $initdir/testok ]] && _ret=0 [[ -e $initdir/testok ]] && _ret=0
if [[ -s $initdir/failed ]]; then if [[ -s $initdir/failed ]]; then
_ret=$(($_ret+1)) _ret=$(($_ret+1))
@ -47,55 +56,10 @@ check_result_qemu() {
fi fi
fi fi
cp -a $initdir/var/log/journal $TESTDIR cp -a $initdir/var/log/journal $TESTDIR
umount $initdir rm -r $initdir/var/log/journal/*
_umount_dir $initdir
[[ -n "$TIMED_OUT" ]] && _ret=$(($_ret+1)) [[ -n "$TIMED_OUT" ]] && _ret=$(($_ret+1))
return $_ret return $_ret
} }
test_setup() { do_test "$@" 24
if type -P meson && [[ "$(meson configure $BUILD_DIR | grep install-tests | awk '{ print $2 }')" != "true" ]]; then
dfatal "Needs to be built with -Dinstall-tests=true"
exit 1
fi
create_empty_image_rootdir
# Create what will eventually be our root filesystem onto an overlay
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
for i in getfacl dirname basename capsh cut rev stat mktemp rmdir ionice unshare uname tr awk getent diff xzcat lz4cat; do
inst_binary $i
done
inst /etc/hosts
setup_basic_environment
install_keymaps yes
install_zoneinfo
# Install nproc to determine # of CPUs for correct parallelization
inst_binary nproc
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/testsuite.sh
Type=oneshot
EOF
cp testsuite.sh $initdir/
setup_testsuite
)
setup_nspawn_root
# mask some services that we do not want to run in these tests
ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
}
do_test "$@"

View File

@ -4,30 +4,4 @@ TEST_DESCRIPTION="test importd"
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 25
create_empty_image_rootdir
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
dracut_install dd gunzip mv tar diff
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/testsuite.sh
Type=oneshot
EOF
cp testsuite.sh $initdir/
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

@ -4,29 +4,4 @@ TEST_DESCRIPTION="test setenv"
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 26
create_empty_image_rootdir
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/bin/bash -x /testsuite.sh
Type=oneshot
EOF
cp testsuite.sh $initdir/
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

@ -4,31 +4,4 @@ TEST_DESCRIPTION="test StandardOutput=file:"
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 27
create_empty_image_rootdir
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
inst_binary cmp
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/testsuite.sh
Type=oneshot
EOF
cp testsuite.sh $initdir/
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

@ -5,52 +5,4 @@ RUN_IN_UNPRIVILEGED_CONTAINER=yes
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 28
create_empty_image_rootdir
# Create what will eventually be our root filesystem onto an overlay
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# Set up the services.
cat >$initdir/etc/systemd/system/specifier-j-wants.service << EOF
[Unit]
Description=Wants with percent-j specifier
Wants=specifier-j-depends-%j.service
After=specifier-j-depends-%j.service
[Service]
Type=oneshot
ExecStart=test -f /tmp/test-specifier-j-%j
ExecStart=/bin/sh -c 'echo OK > /testok'
EOF
cat >$initdir/etc/systemd/system/specifier-j-depends-wants.service << EOF
[Unit]
Description=Dependent service for percent-j specifier
[Service]
Type=oneshot
ExecStart=touch /tmp/test-specifier-j-wants
EOF
cat >$initdir/etc/systemd/system/testsuite.service << EOF
[Unit]
Description=Testsuite: Ensure %j Wants directives work
Wants=specifier-j-wants.service
After=specifier-j-wants.service
[Service]
Type=oneshot
ExecStart=/bin/true
EOF
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

@ -6,29 +6,4 @@ TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
QEMU_TIMEOUT=300 QEMU_TIMEOUT=300
test_setup() { do_test "$@" 29
create_empty_image_rootdir
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/bin/bash -x /testsuite.sh
Type=oneshot
EOF
cp testsuite.sh $initdir/
setup_testsuite
)
}
do_test "$@"

View File

@ -2,42 +2,6 @@
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 . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 30
create_empty_image_rootdir
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
inst_any /usr/share/zoneinfo/Europe/Kiev
inst_any /usr/share/zoneinfo/Europe/Berlin
setup_basic_environment
mask_supporting_services
# extend the watchdog
mkdir -p $initdir/etc/systemd/system/systemd-timedated.service.d
cat >$initdir/etc/systemd/system/systemd-timedated.service.d/watchdog.conf <<EOF
[Service]
WatchdogSec=10min
EOF
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/testsuite.sh
Type=oneshot
EOF
cp testsuite.sh $initdir/
setup_testsuite
)
}
do_test "$@"

View File

@ -6,29 +6,4 @@ TEST_NO_NSPAWN=1
. $TEST_BASE_DIR/test-functions . $TEST_BASE_DIR/test-functions
QEMU_TIMEOUT=300 QEMU_TIMEOUT=300
test_setup() { do_test "$@" 31
create_empty_image_rootdir
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/bin/bash -x /testsuite.sh
Type=oneshot
EOF
cp testsuite.sh $initdir/
setup_testsuite
)
}
do_test "$@"

View File

@ -2,35 +2,8 @@
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 . $TEST_BASE_DIR/test-functions
UNIFIED_CGROUP_HIERARCHY=yes UNIFIED_CGROUP_HIERARCHY=yes
test_setup() { do_test "$@" 32
create_empty_image_rootdir
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/testsuite.sh
Type=oneshot
MemoryAccounting=yes
EOF
cp testsuite.sh $initdir/
setup_testsuite
)
}
do_test "$@"

View File

@ -3,33 +3,6 @@
# 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 . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 33
create_empty_image_rootdir
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/bin/bash -x /testsuite.sh
Type=oneshot
EOF
cp testsuite.sh $initdir/
setup_testsuite
) || return 1
setup_nspawn_root
}
do_test "$@"

View File

@ -1,33 +1,6 @@
#!/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 . $TEST_BASE_DIR/test-functions
test_setup() { do_test "$@" 34
create_empty_image_rootdir
(
LOG_LEVEL=5
eval $(udevadm info --export --query=env --name=${LOOPDEV}p2)
setup_basic_environment
mask_supporting_services
# setup the testsuite service
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
[Unit]
Description=Testsuite service
[Service]
ExecStart=/bin/bash -x /testsuite.sh
Type=oneshot
EOF
cp testsuite.sh $initdir/
setup_testsuite
)
setup_nspawn_root
}
do_test "$@"

View File

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

View File

@ -1,36 +0,0 @@
#!/usr/bin/env bash
set -e
TEST_DESCRIPTION="network-generator tests"
. $TEST_BASE_DIR/test-functions
test_setup() {
mkdir -p $TESTDIR/run/systemd/network
}
test_run() {
local generator
if [[ -x $BUILD_DIR/systemd-network-generator ]]; then
generator=$BUILD_DIR/systemd-network-generator
elif [[ -x /usr/lib/systemd/systemd-network-generator ]]; then
generator=/usr/lib/systemd/systemd-network-generator
elif [[ -x /lib/systemd/systemd-network-generator ]]; then
generator=/lib/systemd/systemd-network-generator
else
exit 1
fi
for f in test-*.input; do
echo "*** Running $f"
rm -f $TESTDIR/run/systemd/network/*
$generator --root $TESTDIR -- $(cat $f)
if ! diff -u $TESTDIR/run/systemd/network ${f%.input}.expected; then
echo "**** Unexpected output for $f"
exit 1
fi
done
}
do_test "$@"

Some files were not shown because too many files have changed in this diff Show More