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>
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
void
afs_osi_UnmaskRxkSignals(void)
{
+#ifdef AFS_LINUX22_ENV
+ osi_linux_unmaskrxk();
+#endif
}
/* Two hacks to try and fix afsdb */
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
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;
#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 */