From nobody@FreeBSD.ORG Thu Mar 18 10:21:27 1999
Return-Path: <nobody@FreeBSD.ORG>
Received: by hub.freebsd.org (Postfix, from userid 32767)
	id 7085D1550A; Thu, 18 Mar 1999 10:21:27 -0800 (PST)
Message-Id: <19990318182127.7085D1550A@hub.freebsd.org>
Date: Thu, 18 Mar 1999 10:21:27 -0800 (PST)
From: M.Indlekofer@fz-juelich.de
Sender: nobody@FreeBSD.ORG
To: freebsd-gnats-submit@freebsd.org
Subject: cdevsw_module_handler MOD_UNLOAD problem
X-Send-Pr-Version: www-1.0

>Number:         10653
>Category:       kern
>Synopsis:       cdevsw_module_handler MOD_UNLOAD problem
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Mar 18 10:30:00 PST 1999
>Closed-Date:    Tue Mar 23 13:40:40 PST 1999
>Last-Modified:  Tue Mar 23 13:41:12 PST 1999
>Originator:     Michael Indlekofer
>Release:        3.1-RELEASE
>Organization:
Forschungs Zentrum Juelich GmbH
>Environment:
FreeBSD control10... 3.1-RELEASE FreeBSD 3.1-RELEASE #0: Tue Mar 16
13:31:56 GMT 1999 root@control10.../usr/src/sys/compile/MYKERNEL.3 i386
>Description:
A char device driver which uses 
CDEV_MODULE(xxx_mod,MYMAJOR,xxx_devsw,xxx_handler,0)
and wants to prevent an unloading of the module
(because some devices he offers are still in use e.g.) has a problem:
kldunload -> /sys/kern/kern_conf.c:cdevsw_module_handler
which calls for MOD_UNLOAD the function cdevsw_add(...,NULL,NULL)
which unregisters our xxx_devsw! AFTERWARDS xxx_handler is asked
if he wants to unload,...but it's too late...the xxx_devsw is gone,
even for the case we don't want to unload!

In my case: A program used a device and kldunload was called.
xxx_handler returned EBUSY and kldunload said: can't unload, device busy.
The next time the program issued a ioctl for the still open device
the system crashed in spec_ioctl (gdb -k ...) with an invalid
entry in the cdevsw for MYMAJOR: Fatal trap 12: page fault in kernel mode.
>How-To-Repeat:
see example above
>Fix:
/sys/kern/kern_conf.c:???devsw_module_handler should consult the
module handler (data->chainevh) FIRST in the case of MOD_UNLOAD
whether the module want's to unload before it "kills" the devsw!

>Release-Note:
>Audit-Trail:

From: Doug Rabson <dfr@nlsystems.com>
To: M.Indlekofer@fz-juelich.de
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: kern/10653: cdevsw_module_handler MOD_UNLOAD problem
Date: Fri, 19 Mar 1999 10:58:05 +0000 (GMT)

 On Thu, 18 Mar 1999 M.Indlekofer@fz-juelich.de wrote:
 
 > In my case: A program used a device and kldunload was called.
 > xxx_handler returned EBUSY and kldunload said: can't unload, device busy.
 > The next time the program issued a ioctl for the still open device
 > the system crashed in spec_ioctl (gdb -k ...) with an invalid
 > entry in the cdevsw for MYMAJOR: Fatal trap 12: page fault in kernel mode.
 > >How-To-Repeat:
 > see example above
 > >Fix:
 > /sys/kern/kern_conf.c:???devsw_module_handler should consult the
 > module handler (data->chainevh) FIRST in the case of MOD_UNLOAD
 > whether the module want's to unload before it "kills" the devsw!
 
 Could you test this patch:
 
 Index: kern_conf.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/kern/kern_conf.c,v
 retrieving revision 1.30
 diff -u -r1.30 kern_conf.c
 --- kern_conf.c	1999/01/27 21:49:55	1.30
 +++ kern_conf.c	1999/03/19 10:22:40
 @@ -173,14 +173,18 @@
  
  	switch (what) {
  	case MOD_LOAD:
 -		if ((error = cdevsw_add(&data->dev, data->cdevsw, NULL)) != 0)
 -			return error;
 -		break;
 +		error = cdevsw_add(&data->dev, data->cdevsw, NULL);
 +		if (!error && data->chainevh)
 +			error = data->chainevh(mod, what, data->chainarg);
 +		return error;
  
  	case MOD_UNLOAD:
 -		if ((error = cdevsw_add(&data->dev, NULL, NULL)) != 0)
 -			return error;
 -		break;
 +		if (data->chainevh) {
 +			error = data->chainevh(mod, what, data->chainarg);
 +			if (error)
 +				return error;
 +		}
 +		return cdevsw_add(&data->dev, NULL, NULL);
  	}
  
  	if (data->chainevh)
 @@ -197,20 +201,23 @@
  
  	switch (what) {
  	case MOD_LOAD:
 -		if ((error = cdevsw_add(&data->cdev, data->cdevsw, NULL)) != 0)
 -			return error;
 -		if ((error = bdevsw_add(&data->bdev, data->cdevsw, NULL)) != 0) {
 -			cdevsw_add(&data->bdev, NULL, NULL);
 -			return error;
 -		}
 -		break;
 +		error = cdevsw_add(&data->cdev, data->cdevsw, NULL);
 +		if (!error)
 +			error = bdevsw_add(&data->bdev, data->cdevsw, NULL);
 +		if (!error && data->chainevh)
 +			error = data->chainevh(mod, what, data->chainarg);
 +		return error;
  
  	case MOD_UNLOAD:
 -		if ((error = bdevsw_add(&data->bdev, NULL, NULL)) != 0)
 -			return error;
 -		if ((error = cdevsw_add(&data->cdev, NULL, NULL)) != 0)
 -			return error;
 -		break;
 +		if (data->chainevh) {
 +			error = data->chainevh(mod, what, data->chainarg);
 +			if (error)
 +				return error;
 +		}
 +		error = bdevsw_add(&data->bdev, NULL, NULL);
 +		if (!error)
 +			error = cdevsw_add(&data->cdev, NULL, NULL);
 +		return error;
  	}
  
  	if (data->chainevh)
 
 --
 Doug Rabson				Mail:  dfr@nlsystems.com
 Nonlinear Systems Ltd.			Phone: +44 181 442 9037
 
 
 
 

From: "M.Indlekofer" <micki@mips.isi.kfa-juelich.de>
To: Doug Rabson <dfr@nlsystems.com>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: kern/10653: cdevsw_module_handler MOD_UNLOAD problem
Date: Mon, 22 Mar 1999 15:44:50 +0100 (MET)

 I applied the patch for kern/kern_conf.c and the problem is fixed.
 Thanks.
 
 
 ---------------------------------------------
 Michael Indlekofer
 Institut fuer Schicht- und Ionentechnik (ISI)
 Forschungszentrum Juelich GmbH
 D-52425 Juelich
 
 Telephone : ++49 2461 61 2345
 Fax       : ++49 2461 61 2940
 ---------------------------------------------
 
 
State-Changed-From-To: open->closed 
State-Changed-By: dfr 
State-Changed-When: Tue Mar 23 13:40:40 PST 1999 
State-Changed-Why:  
Fixed in version 1.31 and 1.29.2.1 of kern_conf.c 
>Unformatted:
