2004-10-25 11:40:56

by Arne Henrichsen

[permalink] [raw]
Subject: Problems with close() system call

Hi,

I have a question regarding the close() system call. I have written my
own character driver for a serial type card with 8 ports. Each port is
seen as a device by Linux. Everything works great, I can open, close,
write, read etc from/to the individual devices. But I also see some
strange things. When I for instance in my user application open and
configure each device (via ioctl) in a loop, somehow a close system
call has been initiated (not called by my user app). I can see this as
my drivers flush function get called. Who or why is this function
called without my user app even calling close()? Is it related to the
module count of each device? I print out the counter
(filp->f_count.counter), and I do not know how it gets
incremented/decremented. The release call is also supposed to get
called after the user is finished, but is never called which I guess
has something to do with the user count not being zero.

I will see in my driver:

open dev 0
ioctl dev 0
open dev 1
flush dev 0
ioctl dev 1
open dev 2
flush dev 1
etc

Could anybody shed some light on this issue please?

Thanks
Arne


2004-10-26 11:30:43

by Jan Engelhardt

[permalink] [raw]
Subject: Re: Problems with close() system call

>Hi,
>
>I have a question regarding the close() system call. I have written my
>own character driver for a serial type card with 8 ports. [...]
>somehow a close system
>call has been initiated (not called by my user app).

Best is to put a printk("i'm in ioctl()") in the ioctl() function and a
printk("i'm in close()") in the close() one, to be really sure whether the
close() function of your module is called.

>

Jan Engelhardt
--
Gesellschaft f?r Wissenschaftliche Datenverarbeitung
Am Fassberg, 37077 G?ttingen, http://www.gwdg.de

2004-10-26 12:43:58

by Arne Henrichsen

[permalink] [raw]
Subject: Re: Problems with close() system call

On Tue, 26 Oct 2004 13:30:35 +0200 (MEST), Jan Engelhardt
<[email protected]> wrote:
>
> Best is to put a printk("i'm in ioctl()") in the ioctl() function and a
> printk("i'm in close()") in the close() one, to be really sure whether the
> close() function of your module is called.
>

Yes, that is exactly what I am doing. I basically implement the
flush() call (for close) as the release() call was never called on
close. So my release call does nothing. What I see is that the flush
function gets called, even though I have never called the close()
system call from my user app.

I also print out the module counter, and it doesn't make sense who
increments it:

open(0): f_count = 1
ioctl(0): f_count = 2
ioctl(0): f_count = 5
open(1)): f_count = 1
ioctl(1): f_count = 2
flush(0): f_count = 7
ioctl(1): f_count = 5
open(2): f_count = 1
ioctl(2): f_count = 2
flush(1): f_count = 7

My user app looks something like this:
int fd[8];

for(i = 0; i < nr_dev; i)
{
sprintf(dev, "/dev/mydev_%c", '0' + i);
fd[i] = open(dev, O_RDWR | O_SYNC);
if(fd[i] < 0)
{
printf("Error opening device: %s - %s\n", dev, strerror(errno));
goto test_error;
}

status = ioctl(fd[i], CMD1);
if(status != 0)
{
printf("%s - %s\n", dev, strerror(errno));
}

status = ioctl(fd[i], CMD2);
if(status != 0)
{
printf("%s - %s\n", dev, strerror(errno));
}
} /* for(port_id = 0; port_id < nr_ports; port_id++) */

Arne

2004-10-26 15:43:44

by Jan Engelhardt

[permalink] [raw]
Subject: Re: Problems with close() system call

>> Best is to put a printk("i'm in ioctl()") in the ioctl() function and a
>> printk("i'm in close()") in the close() one, to be really sure whether the
>> close() function of your module is called.
>
>Yes, that is exactly what I am doing. I basically implement the
>flush() call (for close) as the release() call was never called on
>close. So my release call does nothing. What I see is that the flush

Uh, then something's wrong. Your device fops should look like this:
{
.release = my_close, // which is called upon close(2)
}

Anything else is of course, never working.

>function gets called, even though I have never called the close()
>system call from my user app.
>
>I also print out the module counter, and it doesn't make sense who
>increments it:

>From that output, I would not either get any idea.
Try opening only one device at a time.
Then, put a dump_stack() where you see fit.

>My user app looks something like this:

> fd[i] = open(dev, O_RDWR | O_SYNC);

I don't think O_SYNC has any effect on unregular files.

> if(status != 0)
> {
> printf("%s - %s\n", dev, strerror(errno));
> }
> } /* for(port_id = 0; port_id < nr_ports; port_id++) */

Well, WHERE do you close() the fd?


Jan Engelhardt
--
Gesellschaft f?r Wissenschaftliche Datenverarbeitung
Am Fassberg, 37077 G?ttingen, http://www.gwdg.de

2004-10-27 04:48:18

by Raj

[permalink] [raw]
Subject: Re: Problems with close() system call

On Tue, 26 Oct 2004 17:43:36 +0200 (MEST), Jan Engelhardt
<[email protected]> wrote:
> >> Best is to put a printk("i'm in ioctl()") in the ioctl() function and a
> >> printk("i'm in close()") in the close() one, to be really sure whether the
> >> close() function of your module is called.
> >
> >Yes, that is exactly what I am doing. I basically implement the
> >flush() call (for close) as the release() call was never called on
> >close. So my release call does nothing. What I see is that the flush
>
> Uh, then something's wrong. Your device fops should look like this:
> {
> .release = my_close, // which is called upon close(2)
> }
>
> Anything else is of course, never working.

iirc, once i faced this problem. I compiled a sample device driver
against kernel version
'X'. and tried to insmod the binary into kernel version 'Y' which had
it's fop's struct
modified. The structure offsets took a beating and all hell broke
loose. Calling open()
called something else etc.... Ever since, i started using the above notation to
initialize struct members. Hard learned lesson ;-)

--
######
raj
######