From 58b65c6d6d4e0363a43c11415028eefd6c592ea8 Mon Sep 17 00:00:00 2001 From: Lucas Werkmeister Date: Fri, 15 Jan 2021 20:01:44 +0100 Subject: [PATCH 1/3] test: fix exec-standardoutput-truncate test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cmp in ExecStartPost= was actually failing – ExecStartPost= has the same StandardOutput as the rest of the service, so the output file is truncated before cmp can compare it with the expected output – but the test still passed because test_exec_standardoutput_truncate() calls test(), which only checks the main result, rather than test_service(), which checks the result of the whole service. Fix the test by merging the ExecStartPost= into the ExecStart= – the cmp has to be part of the same command line as the cat so that the file is not truncated between the two processes. --- test/test-execute/exec-standardoutput-truncate.service | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/test-execute/exec-standardoutput-truncate.service b/test/test-execute/exec-standardoutput-truncate.service index 7a12a06923..4b4bb87b75 100644 --- a/test/test-execute/exec-standardoutput-truncate.service +++ b/test/test-execute/exec-standardoutput-truncate.service @@ -8,6 +8,5 @@ StandardInput=data StandardInputText=hi StandardOutput=truncate:/tmp/test-exec-standardoutput-output StandardError=null -ExecStart=cat -ExecStartPost=cmp /tmp/test-exec-standardoutput-output /tmp/test-exec-standardoutput-expected +ExecStart=sh -c 'cat && cmp /tmp/test-exec-standardoutput-output /tmp/test-exec-standardoutput-expected' Type=oneshot From d15b1a6c225b40894953cde308b347cf99605f5f Mon Sep 17 00:00:00 2001 From: Lucas Werkmeister Date: Fri, 15 Jan 2021 20:10:51 +0100 Subject: [PATCH 2/3] man: document that truncate:file happens per command line --- man/systemd.exec.xml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 7328f9b965..a3c641e116 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -2425,8 +2425,12 @@ SystemCallErrorNumber=EPERM is similar to - above, but it truncates the file when opening it. - + above, but it truncates the file when opening + it. For units with multiple command lines, e.g. Type=oneshot services with + multiple ExecStart=, or services with ExecCondition=, + ExecStartPre= or ExecStartPost=, the output file is reopened + and therefore re-truncated for each command line. Any ExecReload= will likewise + truncate the file when run. connects standard output to a socket acquired via socket activation. The semantics are similar to the same option of StandardInput=, see above. From e37258406766efe53b161ee1d077872fda82ae1b Mon Sep 17 00:00:00 2001 From: Lucas Werkmeister Date: Mon, 18 Jan 2021 21:58:28 +0100 Subject: [PATCH 3/3] man: document effects of concurrent truncation Co-authored-by: Lennart Poettering --- man/systemd.exec.xml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index a3c641e116..9b0169f0d6 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -2429,8 +2429,15 @@ SystemCallErrorNumber=EPERM it. For units with multiple command lines, e.g. Type=oneshot services with multiple ExecStart=, or services with ExecCondition=, ExecStartPre= or ExecStartPost=, the output file is reopened - and therefore re-truncated for each command line. Any ExecReload= will likewise - truncate the file when run. + and therefore re-truncated for each command line. If the output file is truncated while another + process still has the file open, e.g. by an ExecReload= running concurrently with + an ExecStart=, and the other process continues writing to the file without + adjusting its offset, then the space between the file pointers of the two processes may be filled + with NUL bytes, producing a sparse file. Thus, + is typically only useful for units where + only one process runs at a time, such as services with a single ExecStart= and no + ExecStartPost=, ExecReload=, ExecStop= or + similar. connects standard output to a socket acquired via socket activation. The semantics are similar to the same option of StandardInput=, see above.