2.4.9-ac3 kpnpbios gets zombie
Subsystems (3)
IIRC Andrew Morton had fixed that with
a proper daemonize.
Am I wrong or did this bug crept in again?
USER PID STAT START TIME COMMAND root 1 S 13:23 0:04 init [ root 2 Z 13:23 0:01 [kpnpbios <defunct>
Quoted 3 lines
IIRC Andrew Morton had fixed that with
a proper daemonize.
Am I wrong or did this bug crept in again?
Nobody has ever finished it or merged it
Quoted 6 lines · Alan Cox
Quoted 4 lines
IIRC Andrew Morton had fixed that with
a proper daemonize.
Am I wrong or did this bug crept in again?Nobody has ever finished it or merged it
I was uncomfortable with the idea of changing the behaviour of daemonize(), so this patch gives us a new API function, called reparent_to_init(). It is designed to detach the calling process from its current parent and it reparents itself to child_reaper.
reparent_to_init() also initialises various members of *current to sane defaults, to avoid possible problems where kernel threads which are parented by userspace processes could have inappropriate state. The selection of *which* fields to initialise was fairly ad-hoc - I basically scanned task_struct and tossed in any fields which looked like they shouldn't be randomised. Comments on omissions or unnecessary entries would be welcome.
Also note that reparent_to_init() has only been called from two places - rtl8139_thread and the pnpbios code. There are probably other kernel threads which need to make a call to this function - basically anything which is started up by a userspace task and which can exit. nfs daemons, raid daemons, loopback, journalling fs daemons, etc.
We normally don't observe problems with this stuff because the userspace process which starts the kernel thread does an exit(), and hides the problem. Think of mount(8), ifconfig(8), raidstart(8), etc.
The main problems which we're fixing here are:
- kernel threads which do not set their exit signal to SIGCHLD are not reapable by init's waitpid(-1, ...). So we set the exit signal to SIGCHLD.
- kernel threads which *do* set SIGCHLD will send a signal to their parent on exit. The parent could be a userspace process, such as (in the case of 8139too.c) ifconfig or dhcpcd. The kernel should not be sending signals out to userspace tasks just because they opened a netdevice recently...
The 8139too.c problem is the biggest one - DHCP clients like to open and close the interface regularly and we end up with a huge number of defunct kernel threads. Presumably these all go away when the dhcp client is killed off.
Anyway, the code works OK - there may be other ways of solving these problems... Patch is against 2.4.9-ac4
include/linux/sched.h +1 -0
@@ -755,6 +755,7 @@ extern void exit_mm(struct task_struct *extern void exit_files (struct task_struct *);extern void exit_sighand (struct task_struct *); +extern void reparent_to_init (void );extern void daemonize (void );extern int do_execve (char *,char **,char **,struct pt_regs *);
kernel/sched.c +54 -0
66 lines not on this page · raw message
kernel/ksyms.c +1 -0
@@ -475,6 +475,7 @@ EXPORT_SYMBOL(secure_tcp_sequence_numberEXPORT_SYMBOL (get_random_bytes);EXPORT_SYMBOL (securebits);EXPORT_SYMBOL (cap_bset); +EXPORT_SYMBOL (reparent_to_init);EXPORT_SYMBOL (daemonize);EXPORT_SYMBOL (csum_partial);/* for networking and md */
drivers/pnp/pnp_bios.c +1 -0
@@ -506,6 +506,7 @@ static int pnp_dock_thread(void * unusedstatic struct pnp_docking_station_info now;int docked =-1 , d;daemonize (); +reparent_to_init ();strcpy (current->comm,"kpnpbios" );while (!unloading && !signal_pending (current)) {
drivers/net/8139too.c +1 -0
@@ -1610,6 +1610,7 @@ static int rtl8139_thread (void *data)unsigned long timeout;daemonize (); +reparent_to_init ();spin_lock_irq (¤t->sigmask_lock);sigemptyset (¤t->blocked);recalc_sigpending (current);