Linux botnets and Solutions
1. cause:
In a UNIX system, a process stops, but its parent process does not wait (wait/waitpid is called), so it will become a zombie process. Run the ps command to view its defunct flag. A zombie process is a dead process, but it still occupies a slot in the processs table ).
However, if the parent process of the process has ended, the process will not become a zombie process. Because at the end of each process, the system will scan all processes running in the current system to see if any process is a child process of the process that has just ended. If yes, the Init process takes over the process and becomes its parent process to ensure that each process has a parent process. The Init process automatically wait its sub-processes, so all processes taken over by Init will not become zombie processes.
2. Principle Analysis:
Each Unix process has an entry in the process table. All the information used by the core process to execute the process is stored at the entry point. When you use the ps command to view the process information in the system, you will see the relevant data in the Process Table. After a new process is created using a fork () system call, the core process allocates an entry point to the new process in the process table, then, store the information in the table corresponding to the entry point. One of these information is the identifier of the parent process.
The end of the Child process and the running of the parent process are asynchronous processes, that is, the parent process can never predict when the child process ends. Is it because the parent process is too busy to wait for the wait sub-process, or does not know when the sub-process will end and the status information of the sub-process will be lost? No. UNIX provides a mechanism to ensure that the parent process can obtain the state information when the child process ends. This mechanism is: after the sub-process completes its own lifecycle, it will execute the exit () system call, and the kernel will release all the resources of the process, including open files, memory used. However, some information (including the process ID, exit code, exit status the terminationstatus of the process, run time the amountof CPU time taken by the process, etc.), the data will be retained until the system passes it to its parent process, it is released only when the parent process is obtained through wait/waitpid.
3. solution:
(1) The parent process waits for the child process to end through functions such as wait and waitpid, which causes the parent process to stop.
If you execute a wait () or waitpid () system call, the child process immediately returns the data in the table to the parent process after it is terminated. At this time, the system immediately deletes the entry point. In this case, the defunct process is not generated.
(2) If the parent process is busy, you can use the signal function to install handler for SIGCHLD. After the child process ends, the parent process receives this signal. You can call wait in handler to recycle the child process.
(3) If the parent process does not care about when the child process ends, you can use signal (SIGCLD, SIG_IGN) or signal (SIGCHLD, SIG_IGN) to notify the kernel, if you are not interested in the end of the Child process, the kernel recycles the child process and does not send signals to the parent process.
(4) fork two times, the parent process fork a sub-process, and then continue to work, the sub-process fork a sun process and exit, then the sun process is taken over by init, after the sun process ends, init will be recycled. However, the sub-process must be recycled by itself.
Recently, several servers were found to have zombie processes ().
Run the following command to find the zombie process:
Ps-A-o stat, ppid, pid, cmd | grep-e '^ [Zz]'
Command annotation:
-Parameter A lists all processes.
-O custom output field we set the display field to stat (Status), ppid (process parent id), pid (process id), cmd (command) these four parameters
-C is used to specify the name of the command to be executed. Here you let ps only display the process information generated by the php Command.
Ps-C java-o lstart, pid, cmd [but it seems that the print is incomplete ~]
Ps-A-o lstart, pid, args | grep java [This can ~]
Because the process in the z or Z status is a zombie process, we use grep to capture the stat status as zZ process.
Running result:
There are a total of nine zombie processes, and they need to be killed. Execute the command:
Kill-9 8310
Then execute the search for dead processes and find that all dead processes are gone.
Supplement:
Recently I encountered another problem. A server generates 100 dead processes, and the parent processes of each dead process are different, that's not exhausting me.
You should think of a simple command to directly search for dead processes and then kill the parent process ~
Copy codeSample Code: ps-A-o stat, ppid, pid, cmd | grep-e '^ [Zz]' | awk '{print $2}' | xargs kill-9