Is it possible to wake a user Process from a kernel module - linux-kernel

I have a user level process which is sleeping currently, by using sleep() function. I am trying to write a kernel module which can first extract the task_struct of the user process from its PID, and then can wake the process. Till date I have implemented the code for getting the task_struct from PID. But, I dont know of any function which can wake up that process. I tried wake_up_process(task_struct), though its returning 1, i.e, success in waking up the process, but the the printf() statement just after the sleep() statement of the user process is not getting executed. Will changing the state of the task_struct help? Or there's some another approach for doing the same? Please guide me further.

It is possible, but you might be going about it the wrong way. sleep() waits on a delay, and even though you could signal the process from within the kernel (essentially like kill(2) in user mode, with some non harmful signal, but something that will "kick you out" of the system call, the correct way of doing so is having the sleeping process block on a device which your kernel module exports. This way, the kernel module will have control - the process will be stuck in a read(2) call, and until your read implmentation in the module returns, the process will be stuck.
This is preferable, because the whole idea of sleeping is when you are waiting for something. When you simple sleep(xxxx) indefinitely, you're basically waiting on a time out. What more, using the device approach, you can add the file descriptor to a select(2)/poll(2) loop, as well, which makes for very elegant synchronization with other input/output descriptors.

Related

Unexpected blocking behavior on OSX, Pthreads and calls to system(3)

I am working on a program to start a long running process (afplay, with long sound files) using system() and at a later time possibly decide to terminate this process. It seems that it would be straightforward to invoke a system("prog") call and then later a system("killall prog") call. Using pthreads, I fire up a thread to invoke the initial system("prog") call and then later if application detects that its time to terminate early, the main thread will call system("killall prog"). Through print statements I can see that the main thread properly detects the logic to stop but the subsequent system call blocks until the original system call is finished (the main thread doesn't appear to block until this time, other activity does progress past the thread creation for the initial system call). If I try the killall from a separate shell after my program invokes the prog, killlall works (as you'd expect). I know that macOS has requirements on programs that interact with the ui libraries need to handle such activity from the main thread only. Are there other requirements for programs shelling out to system(3) that I clearly am ignorant of?
On windows, the only difference in the code is the choices for "prog", and the behavior works as I expect.
system() is expected to block until the launched program exits -- if it didn't, there would be no way for system() to return the exit-status of the child process as part of its return value.
If you want your thread to continue executing in parallel with the child process, you will need to use a different API (typically fork() followed by calling exec() from the child-process's branch of the fork) instead.

How can I handle a `system` call which fails?

I have a Perl script which calls an external program. (Right now I'm actually using backticks, but I could just as easily use system or something from cpan.) Sometimes the program fails, causing Windows to create a dialog box "(external program) has stopped working" with the text
Windows is checking for a solution to the problem...
shortly replaced with
A problem caused the program to stop working correctly. windows will close the program and notify you if a solution is available.
Unfortunately, this error message stops the process from dying, causing Perl to not return until the user (me!) clicks "Cancel" or "Close Program". Is there a way to avoid this behavior?
In my use case it is acceptable to have the program fail -- it does useful but strictly not necessary work. But as it needs to run unattended I can't have it block the program's remaining work.
The problem with your current approach is that backticks & system block while the external program is running/hanging. Possible other aproaches might include.
Using threads & various modules from the Win32 family to busy-wait for the process end or click on the dialong box. This is probably overkill.
Use an Alarm Signal or Event to wake up your program when the external program has taken 'too long' to respond.
Use an IPC Module to open the program and monitor it's progress.
If you don't need the child program's return value, STDOUT or STDERR, simbabque's exec option has merit, but if you need to keep a handle on the process, try Win32::Process. I've found this useful on many an occasion. The module's wait method can be an excellent alternative to my Alarm suggestion or simabque's sleep suggestion with the added benefit that your program will not sleep longer than required by the child.
If you do not need to wait for the external program to finish running to continue, you can do exec instead of system and it will never return.
You could always add a sleep $n afterwards to make it wait for the external program to theoretically finish.
exec('maybe_dies.exe');
sleep 1; # make sure it does stuff before it dies, or not, or whatever...

Does Windows 7 recycle process id (PID) numbers?

I have this little test program that tracks PID's as they are created and shut down.
I am investigating a problem that my program has found and would like to ask you about this
in order to have a better idea on what's going on.
When a windows process is started, it gets a PID but when the process is shut down, does the PID
become retired (like a star basketballer's jersey number) or is it possible for a new, entirely
unrelated, process to be created under that released PID?
Thanks
Yes, process IDs may be recycled by the system. They become available for this as soon as the last handle to the process has been closed.
Raymond Chen discussed this matter here: When does a process ID become available for reuse?
The process ID is a value associated with the process object, and as
long as the process object is still around, so too will its process
ID. The process object remains as long as the process is still running
(the process implicitly retains a reference to itself) or as long as
somebody still has a handle to the process object.
If you think about it, this makes sense, because as long as there is
still a handle to the process, somebody can call WaitForSingleObject
to wait for the process to exit, or they can call GetExitCodeProcess
to retrieve the exit code, and that exit code has to be stored
somewhere for later retrieval.
When all handles are closed, then the kernel knows that nobody is
going to ask whether the process is still running or what its exit
code is (because you need a handle to ask those questions). At which
point the process object can be destroyed, which in turn destroys the
process ID.
I ran a test for about an hour and in that time 302 processes exits and 70 of them had PIDs in common (same PID was used for a new process). So that would say they are reused frequently.
Evidently, if the process is terminated, its PID is available for reuse.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683215%28v=vs.85%29.aspx
Remarks
Until a process terminates, its process identifier uniquely identifies it on the system. For more information about access rights, see Process Security and Access Rights.

How to detect that foreground process is waiting for input in UNIX?

I have to create a script (ksh or perl) that starts certain number of parallel jobs (another scripts), each of them runs as a foreground process in a separate session. Plus I start monitoring job that has to determine if any of those scripts is expecting input from operator, and switch to the corresponding session if necessary.
My problem is that I have not found a good way to determine that process is expecting input. For the background process it's pretty easy: process state is "stopped" and this can be easily checked with 'ps' command. In case of foreground process this does not work.
So far I tried to attach to the process with dbx or truss to see if it's hanging on 'read', but this approach seems too heavyweight.
Could you suggest some better solution? Perl, shell, C, Java, etc. … is ok as long as it’s standard and does not require extra 3rd party or OS-specific stuff to install.
Thank you.
What you're asking isn't possible, at least not reliably. The process may be using select or other polling method rather than blocking on a read call. You can't know whether it's waiting for operator input or busy doing other stuff, and in general it could be both (doing stuff in the background while being responsive to operator input).
The normal way for a program to signal that it's waiting for operator input is to print a prompt. Thus you should consider a session to be active if it's displayed a prompt since the last time you fed it input.
If your programs don't behave this way, you'll need to find some other program-specific way to know that these processes are waiting for input.

Get current state of caps/scroll/numlock in windows w/o using Peek/ReadConsoleInput()

I'm programming a Windows console application in plain C and using PeekConsoleInput/ReadConsoleInput to get keystrokes from the user and process them.
I need to get the current state of the Caps Lock, Scroll Lock, and Num Lock keys when the program starts, before the user has entered anything. Meaning there would be no KEY_EVENTs in the message queue to process.
Is this possible to do? If so, how? I've looked at most of the functions in wincon.h and nothing seems appropriate.
You can call GetAsyncKeyState three times, and it will usually work, but there are a few cases where it still won't work for you. The arguments for your three calls would be VK_CAPITAL, VK_SCROLL, and VK_NUMLOCK.

Resources