On Mon, Jan 12, 2015 at 10:00:08PM +0100, Cedric Ware wrote:
>
> I eventually traced it to the systemd-fsck-root service hanging if
> /etc/e2fsck.conf specifies logging to a yet-unmounted directory. I think
> it is an fd leak similar to bug #682592:
>
> * systemd-fsck forks fsck with argument "-C<n>", with fd <n> being one end
> of a pipe which systemd uses to read progress information.
>
> * systemd-fsck attempts to read from pipe until EOF (systemd source file
> src/fsck/fsck.c, function process_progress).
>
> * fsck forks e2fsck (actually fsck.ext4), which needs fd <n>.
>
> * e2fsck forks/detaches a child to wait until directory mounted/writable,
> without closing fd <n>.
>
> * e2fsck and fsck terminate, e2fsck child waits for boot to complete,
> systemd-fsck waits for pipe to be closed, deadlock.
>
Arguably this is as mucha bug in systemd-fsck since it could have been
waiting for fsck to terminate instead of waiting for an EOF from the
progress_fd pipe, but I agree that it would be better if e2fsck were
to close the progress_fd.
This isn't an RC bug by any means (I don't think it even rates
"important") since very few people are using the e2fsck.conf logging
capabilities --- most debian users pre-systemd have been been using
/var/log/fsck/*, and systemd will do its own journalctl thing.
So I'll fix this, with a patch like this (see attached), but it's not
something that's worth fixing in Jessie.
- Ted
commit a4f95ccad41f5befb6768ff58fe26b179237df6a
Author: Theodore Ts'o <[email protected]>
Date: Mon Jan 12 19:42:29 2015 -0500
e2fsck: close the progress_fd in the logfile child process
If e2fsck.conf's logging feature is enabled, and e2fsck is being run
via systemd-fsck, there will be a deadlock since systemd-fsck is
waiting for progress_fd pipe to be closed, instead of waiting for the
fsck process to exit --- and so the logfile child process won't exit
until it can write out the logfile, and systemd won't continue the
boot process so that the file system can be remounted read-write.
Oops.
Addresses-Debian-Bug: #775234
Signed-off-by: Theodore Ts'o <[email protected]>
diff --git a/e2fsck/logfile.c b/e2fsck/logfile.c
index c48b8eb..e004f31 100644
--- a/e2fsck/logfile.c
+++ b/e2fsck/logfile.c
@@ -20,6 +20,8 @@
#include "e2fsck.h"
#include <pwd.h>
+extern e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
+
struct string {
char *s;
int len;
@@ -233,6 +235,8 @@ static FILE *save_output(const char *s0, const char *s1,
const char *s2)
}
if (pid == 0) {
+ if (e2fsck_global_ctx && e2fsck_global_ctx->progress_fd)
+ close(e2fsck_global_ctx->progress_fd);
if (daemon(0, 0) < 0) {
perror("daemon");
exit(1);
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]