I'm wondering if there is a hook that could be used in a Linux Kernel Module that is fired when a user space application/process is killed ?
You could first register for a notifier chain within your kernel module.
Inside get_signal_to_deliver(kernel/signal.c), any process which has just (this being a relative term IMHO) been killed has its PF_SIGNALED flag being set. Here you could check for the name of the current process using its tcomm field like so:
char tcomm[sizeof(current->comm)];
get_task_comm(tcomm, current);
If it is indeed the process under question, you could just fire the notification chain which will awaken your module which has been waiting on that chain.
Related
I am writing a new syscall where I want to send a kill(pid, SIGSTOP) signal to a process that I just created in order to move it from the runqueue to the waitqueue. Then, I can wake it up again using kill(pid, SIGCONT).
The problem is that the kill is only used from the userspace, how can I send a signal from inside the kernel itself? is there an equivalent function to use that can do so?
I found kill_pid, but I don't know how its headers should be included.
It seems like you found the correct method of sending a signal to a process from kernel space - kill_pid which is also exported, which means it is available to kernel modules.
Using elixir - lets look at some usage examples - this shows you in which header file the symbol is defined - so you should start by including sched/signal.h and do the process for any other dependencies you may have
I am working on a kernel module where I need to be "aware" that a given process has crashed.
Right now my approach is to set up a periodic timer interrupt in the kernel module; on every timer interrupt, I check the task_struct.state and task_struct.exitstate values for that process.
I am wondering if there's a way to set up an interrupt in the kernel module that would go off when the process terminates, or, when the process receives a given signal (e.g., SIGINT or SIGHUP).
Thanks!
EDIT: A catch here is that I can't modify the user application. Or at least, it would be a much tougher sell to the customer if I place additional requirements/constraints on s/w from another vendor...
You could have your module create a character device node and then open that node from your userspace process. It's only about a dozen lines of boilerplate to register a simple cdev in your module. Your cdev's open method will get called when the process opens the device node and the release method will be called when the device node is closed. If a process exits, either intentionally or because of a signal, all open file descriptors are closed by the kernel. So you can be certain that release will be called. This avoids any need to poll the process status and you can avoid modifying any kernel code outside of your module.
You could also setup a watchdog style system, where your process must write one byte to the device every so often. Have the write method of the cdev reset a timer. If too much time passes without a write and the timer expires, it is assumed the process has somehow failed, even if it hasn't crashed and terminated. For instance a programming bug that allowed for a mutex deadlock or placed the process into an infinite loop.
There is a point in the kernel code where signals are delivered to user processes. You could patch that, check the process name, and signal a condition variable if it matches. This would just catch signals, not intentional process exits. IMHO, this is much uglier and you'll need to deal with maintaining a kernel patch. But it's not that hard, there's a single point, I don't recall what function, sorry, where one can insert the necessary code and it will catch all signals.
I'm trying to make sure that a unique user process executes as soon as possible after a particular hardware interrupt occurs.
One mechanism I'm aware of for doing this is to write a small kernel module that exports a device while sleeping inside the read handler. The module also registers an irq handler, which does nothing but wake the process. Then from the user's perspective, reads to that device block until the relevant interrupt occurs.
(1) On a modern CPU with a mainline kernel, can you reliably expect sub millisecond latency between the kernel seeing the interrupt and the user process regaining control with this?
(2) Are there any lower latency mechanisms on a mainline kernel?
Apply the PREEMPT_RT patch to the kernel and compile it configuring full preemptability through make menuconfig.
This will allow you to have threaded interrupts (i.e., interrupt handlers executed as kernel threads). Then, you can assign maximum priority (i.e., RT prio > 50) to your specific interrupt handler (check its PID using ps aux) and to your specific process, and a lower priority to anything else.
Out of these three steps, is this the right order, or do I need to switch any?
1) Save current state data
2) Turn on kernel mode
3) Determine cause of interrupt
So, let me try to help you figuring out the correct order.
Only the kernel can switch a context as only the kernel has access to the necessary data and can for example change the page tables for the other process' address space.
To determine whether to do a context switch or not, the kernel needs to analyse some "inputs". A context switch might be done for example because the timer interrupt fired and the time slice of a process is over or because the process started doing some IO.
Only the kernel can save the state of a user process because a user process would change its state when it would try storing it. The kernel however knows that if its running, the user process is currently interrupted (eg because of an interrupt or because the user space process voluntarily entered the kernel eg for a system call)
The current context of a process is first saved partly by the hardware(processor) and rest by the software(kernel).
Then the control is transferred from the user process to the kernel by loading the new eip, esp and other saved context of kernel is loaded by hardware from Task State Segment(TSS).
Then based on the interrupt or trap no. the request is dispatched to the appropriate handler.
I'm working in kernel space and I want to find out when an application has stopped or crashed.
When I receive an ioctl call, I can get the struct task_struct where I have a lot of information regarding the process of the application.
My problem is that I want to periodically check if the process is still alive or better yet, to have some asynchronous call when the process is killed.
My test environment was on QEMU and after a while in the application I've run a system("kill -9 pid"). Meanwhile in the kernel I've had a periodical check on task_struct with:
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
static inline int pid_alive(struct task_struct *p)
The problem is that my task_struct pointer seems to be unmodified. Normally I would say that each process has a task_struct and of course it is corespondent with the process state. Otherwise I don't see the point of "volatile long state"
What am I missing? Is it that I'm testing on QEMU, it is that I've tested checking the task_struct in a while(1) with an msleep of 100? Any help would be appreciated.
I would be partially happy if I could receive the pid of the application when the app is closing the file descriptor of the module ("/dev/driver").
Thanks!
You cannot hive off the task_struct pointer and refer to it later. If the process has been killed, the pointer is no longer valid - that task_struct is gone. You also should not be using PID values within the kernel to refer to processes. PID values are re-used, so you might not even be talking about the same process.
Your driver can supply a .release callback, which will be called when your driver file is closed, including if the process is terminated or killed. You can access current from this callback. Note that if a process opens your file and then forks, the process calling .release could well be different from the process that called .open. Your driver must be able to handle this.
It has been a long time since I mucked around inside the kernel. It seems to me if your process actually dies, then your best bet would be to put hooks into the code that tears down processes. If it doesn't die but gets caught in a non-responsive loop, you'd probably be better off causing an application level core dump.
A solution that worked beautifully in my operating systems homework is to use a kprobe to detect when do_exit is called. What's beautiful is that do_exit will always be called, no matter how the process is closed. I think even in the case of a kernel oops this one will still be called.
You should also hook into _do_fork, just in case.
Oh, and look at the .release callback mentioned in the other answer (do note that dup2 and fork will cause unexpected behavior -- you will only be notified when the last of the copies created by these two is closed).