From 139e6e8ef6ee9a56fc1737240ecd8402fbcadd82 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 10 Nov 2023 12:03:43 +0100 Subject: um: Reap winch thread if it fails When the winch thread runs into an error condition, it would exit(1) and never be reaped until shutdown time. Change this to write a command byte which causes the driver to kill it, therefore reaping the child. Signed-off-by: Benjamin Berg Signed-off-by: Richard Weinberger --- arch/um/drivers/chan_user.c | 16 +++++++++++----- arch/um/drivers/line.c | 13 ++++++++----- 2 files changed, 19 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index c2b83cb99aae..ed7cc830b3e7 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -141,7 +141,7 @@ struct winch_data { int pipe_fd; }; -static int winch_thread(void *arg) +static __noreturn int winch_thread(void *arg) { struct winch_data *data = arg; sigset_t sigs; @@ -168,7 +168,7 @@ static int winch_thread(void *arg) if (sigprocmask(SIG_SETMASK, &sigs, NULL) < 0) { os_info("winch_thread : sigprocmask failed, errno = %d\n", errno); - exit(1); + goto wait_kill; } /* In sigsuspend(), block anything else than SIGWINCH. */ sigdelset(&sigs, SIGWINCH); @@ -176,19 +176,19 @@ static int winch_thread(void *arg) if (setsid() < 0) { os_info("winch_thread : setsid failed, errno = %d\n", errno); - exit(1); + goto wait_kill; } if (ioctl(pty_fd, TIOCSCTTY, 0) < 0) { os_info("winch_thread : TIOCSCTTY failed on " "fd %d err = %d\n", pty_fd, errno); - exit(1); + goto wait_kill; } if (tcsetpgrp(pty_fd, os_getpid()) < 0) { os_info("winch_thread : tcsetpgrp failed on fd %d err = %d\n", pty_fd, errno); - exit(1); + goto wait_kill; } /* @@ -214,6 +214,12 @@ static int winch_thread(void *arg) os_info("winch_thread : write failed, err = %d\n", errno); } + +wait_kill: + c = 2; + count = write(pipe_fd, &c, sizeof(c)); + while (1) + pause(); } static int winch_tramp(int fd, struct tty_port *port, int *fd_out, diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index b98545f3edb5..449d320c3f55 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -629,15 +629,18 @@ static irqreturn_t winch_interrupt(int irq, void *data) if (fd != -1) { err = generic_read(fd, &c, NULL); - if (err < 0) { + /* A read of 2 means the winch thread failed and has warned */ + if (err < 0 || (err == 1 && c == 2)) { if (err != -EAGAIN) { winch->fd = -1; list_del(&winch->list); os_close_file(fd); - printk(KERN_ERR "winch_interrupt : " - "read failed, errno = %d\n", -err); - printk(KERN_ERR "fd %d is losing SIGWINCH " - "support\n", winch->tty_fd); + if (err < 0) { + printk(KERN_ERR "winch_interrupt : read failed, errno = %d\n", + -err); + printk(KERN_ERR "fd %d is losing SIGWINCH support\n", + winch->tty_fd); + } INIT_WORK(&winch->work, __free_winch); schedule_work(&winch->work); return IRQ_HANDLED; -- cgit v1.2.3