From 2b7af1243f46496c0b5973b3fa2a6396243f7613 Mon Sep 17 00:00:00 2001 From: Cheyenne Wills <cwills@sinenomine.net> Date: Fri, 9 Aug 2019 14:25:03 -0600 Subject: [PATCH] LINUX 5.3.0: Use send_sig instead of force_sig Linux 5.3.0 commit 3cf5d076fb4d48979f382bc9452765bf8b79e740 "signal Remove task parameter from force_sig" (part of siginfo-linus branch) changes the parameters for the Linux kernel function force_sig. See LKML thread starting at https://lkml.org/lkml/2019/5/22/1351 According to the LKML discussion and the above commit message force_sig is only safe to deliver a synchronous signal to the current task. To send a signal to another task, we're supposed to use send_sig instead, which has been available since at least linux 2.6.12-rc12. Currently, rx_knet calls force_sig to kill the rxk_ListenerTask. With the Linux 5.3.0 kernel, this module fails to compile due to the above noted changes. Replace the force_sig call with send_sig. In order to use send_sig, the rxk_listener thread must allow SIGKILL and during shutdown (umount) SIGKILL must be unblocked for the rxk_listener thread. Note that SIGKILL is initially blocked on rxk_listener and is only unblocked when shutting down the thread. Having the signal blocked is sufficient to prevent unwanted signals from reaching the rxk_listener thread during normal operation. Change-Id: I0c31d66f4ecd887ff9253ba506565592010e8bcb Reviewed-on: https://gerrit.openafs.org/13753 Reviewed-by: Benjamin Kaduk <kaduk@mit.edu> Tested-by: BuildBot <buildbot@rampaginggeek.com> --- src/afs/LINUX/osi_misc.c | 11 +++++++++++ src/afs/afs_osi.c | 3 +++ src/afs/afs_prototypes.h | 2 +- src/rx/LINUX/rx_knet.c | 2 +- src/rx/rx_kcommon.c | 1 + 5 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/afs/LINUX/osi_misc.c b/src/afs/LINUX/osi_misc.c index 6550767..0e9336d 100644 --- a/src/afs/LINUX/osi_misc.c +++ b/src/afs/LINUX/osi_misc.c @@ -37,6 +37,17 @@ osi_linux_mask(void) SIG_UNLOCK(current); } +void +osi_linux_unmaskrxk(void) +{ + extern struct task_struct *rxk_ListenerTask; + /* Note this unblocks signals on the rxk_Listener + * thread from a thread that is stopping rxk */ + SIG_LOCK(rxk_ListenerTask); + sigdelset(&rxk_ListenerTask->blocked, SIGKILL); + SIG_UNLOCK(rxk_ListenerTask); +} + /* LOOKUP_POSITIVE is becoming the default */ #ifndef LOOKUP_POSITIVE #define LOOKUP_POSITIVE 0 diff --git a/src/afs/afs_osi.c b/src/afs/afs_osi.c index 2009d19..c970ea3 100644 --- a/src/afs/afs_osi.c +++ b/src/afs/afs_osi.c @@ -138,6 +138,9 @@ afs_osi_MaskSignals(void) void afs_osi_UnmaskRxkSignals(void) { +#ifdef AFS_LINUX22_ENV + osi_linux_unmaskrxk(); +#endif } /* Two hacks to try and fix afsdb */ diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index d5ecb25..ec28e80 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -644,7 +644,7 @@ extern int uiomove(char *dp, int length, uio_flag_t rw, struct uio *uiop); extern void osi_linux_free_inode_pages(void); #endif extern void osi_linux_mask(void); -extern void osi_linux_unmask(void); +extern void osi_linux_unmaskrxk(void); extern int setpag(cred_t ** cr, afs_uint32 pagvalue, afs_uint32 * newpag, int change_parent); #endif diff --git a/src/rx/LINUX/rx_knet.c b/src/rx/LINUX/rx_knet.c index dea64fb..9fbb563 100644 --- a/src/rx/LINUX/rx_knet.c +++ b/src/rx/LINUX/rx_knet.c @@ -272,7 +272,7 @@ osi_StopListener(void) while (rxk_ListenerTask) { if (rxk_ListenerTask) { flush_signals(rxk_ListenerTask); - force_sig(SIGKILL, rxk_ListenerTask); + send_sig(SIGKILL, rxk_ListenerTask, 1); } if (!rxk_ListenerTask) break; diff --git a/src/rx/rx_kcommon.c b/src/rx/rx_kcommon.c index 51dcfa9..c2cc187 100644 --- a/src/rx/rx_kcommon.c +++ b/src/rx/rx_kcommon.c @@ -1197,6 +1197,7 @@ rxk_Listener(void) #ifdef AFS_LINUX20_ENV rxk_ListenerPid = current->pid; rxk_ListenerTask = current; + allow_signal(SIGKILL); /* Allowed, but blocked until shutdown */ #endif #ifdef AFS_SUN5_ENV rxk_ListenerPid = 1; /* No PID, just a flag that we're alive */ -- 1.7.1