Alan Stern wrote:
> 
> On Thu, 19 Aug 2004, Alexander N. Kozhushkin wrote:
> 
> >     My experience of using Linux  kernels 2.6 shows that there is some
> > problem  with hotplug  devices.  Namely,  it seems  that, there  is no
> > uniform approach of how an  application performing I/O operations on a
> > device must be handled, when that device is disconnected.
> >
> >     The  following  consideration explains  the  problem.  Consider  a
> > process, which is  performing a system call with  a file descriptor as
> > an  argument.  The  file descriptor  corresponds to  a  device special
> > file,  and  the  device  was  disconnected after  the  descriptor  was
> > created.
> > There are three reasonable ways by which the process can be handled:
> > 1. If the  call involves an I/O  operation on the  device, the process
> >    hangs indefinitely until a signal  has terminated  the call  or the
> >    process.
> > 2. If the call  involves an I/O operation on  the disconnected device,
> >    the  process  waits  for the  device.  As  soon  as the  device  is
> >    connected again,  an initialization  procedure will put  the device
> >    into  an  appropriate  state  and  will make  the  stopped  process
> >    continue.   If the  call does  not  involve I/O  operations on  the
> >    device,  it is  performed  without  waiting, as  if  the device  is
> >    presented.  In  any case the process  is able to  complete the call
> >    successfully.
> > 3. The  call  completes without  waiting  for  the  device.  The  file
> >    descriptor has been unusable for I/O operations on the device since
> >    the disconnection, therefore the result of the call is not affected
> >    if the  device has  been connected again.   The result of  the call
> >    depends on  the kind of  the called function and  other conditions.
> >    However, the 'close' function closes the file, and there are system
> >    calls which produce a specific error code in such situations.
> >
> > In addition  to the  above, in many  cases it  is useful to  deliver a
> > signal to  a selected  process at the  moment when the  device becomes
> > disconnected.
> >
> >     The choice of the standard affects not only the kernel itself, but
> > also applications.  The third  approach looks like the most reasonable
> > one, it is proposed in the 'drivers/usb/usb-skeleton.c' file, however,
> > all of  the approaches above  are in use  now.
> >
> > Which approach is the standard one or is supposed to be the standard?
> >
> > What is  the standard behavior of the  'read()', 'write()', 'ioctl()',
> > 'select()',  'fcntl()',   'close()',  ...  system  calls   in  such  a
> > situation?
> 
> As I understand it, the kernel should always use your option 3.  I'm not
> aware that any of the other options are in use anywhere; can you provide a
> list?
> 
> Alan Stern

> Certainly USB should do it that way in 2.6, although the device
> drivers can try to implement other behavior.  I think that's made
> a big improvement in robustness.
>
> David Brownell

Hi,

    Unfortunately, now I cannot present  a full list of device drivers
which   use   the   first   and  second   approaches.   However,   the
"drivers/input/mousedev.c"  file by  Vojtech Pavlik  is an  example of
such a device driver. It  offers the first approach for the mouse-like
devices with  the minor numbers from 0  to 30, and the  second one for
the so-called "MOUSEDEV_MIX" device with minor number 31.

    Here is a  patch for kernel 2.6.7 which makes  that driver use the
third approach for the devices  with minor numbers 0--30. Most likely,
the patch  can be used  for kernels 2.6.8  and 2.6.9 too.  The archive
"tests.tgz" contains some  very simple programs to test  the patch and
the  original mouse  driver. The  description  of the  changes to  the
"mousedev.c" file can be found in the "patch.txt" file.

    The  'gpm' program, properly  rewritten by  me to  support hotplug
mice,  and the  above  tests work  reliably  on my  computer with  the
modified mouse driver. The X-server  works reliably too if it uses the
data supplied  by the  modified version of  the 'gmp', instead  of the
real mouse data.

Sincerely yours,
                Alexander.


-- 
*********************************************************
                Alexander N. Kozhushkin.
            ADDR: [EMAIL PROTECTED]
*********************************************************

Attachment: patch.gz
Description: GNU Zip compressed data

I have made the following changes to the "drivers/input/mousedev.c" file: 

1. 'mousedev_write()', 'mousedev_read()':
   The changes protect an application using the 'read()' function from
   waiting indefinitely  for a disconnected mouse.  If the application
   performs a read or write  operation on the disconnected device, the
   call  fails with  the 'ENODEV'  error  code. This  behavior of  the
   'read()'   and    'write()'   functions   is    proposed   in   the
   "drivers/usb/usb-skeleton.c" file.

2. 'mousedev_poll()':
   The changes  protect an  application using the  'select()' function
   from waiting  indefinitely for a  disconnected mouse. If  the mouse
   was  disconnected, each  file descriptor  of the  respective device
   file  is  assumed  to  be  always ready  for  reading.  The  device
   disconnection is assumed to be a permanent exceptional condition on
   the  file  descriptor. The  'select()'  function  treats that  file
   descriptor as a  valid and ready one. So if  the file descriptor is
   contained in a  descriptor set supplied to a  'select()' call as an
   argument, then the 'select()' function adds that file descriptor to
   the respective  output descriptor  set, i.e., sets  the appropriate
   bit of  the respective 'fd_set'  input variable.  In this  case the
   function  returns successfully.   The mouse  disconnection  and the
   unusable  file descriptor can  be easily  detected by  checking the
   results of  the successive  'read()' calls, which  make use  of the
   results of the 'select()' call, for the 'ENODEV' error.

3. 'mousedev_disconnect()':
   a) Sending a 'SIGIO' signal.
      This   'SIGIO'  signal   protects  an   application   using  the
      'sigsuspend()' function from  waiting indefinitely for a 'SIGIO'
      signal.  If a file  descriptor corresponds  to a  device special
      file representing a mouse, and  the 'O_ASYNC' status flag is set
      on that file descriptor, a  'SIGIO' signal is generated when the
      mouse becomes disconnected.
   b) The  pointers  in  the  'mousedev_table' are  used  only by  the
      'mousedev_open()'  and  'mousedev_connect()'  functions, so  the
      'mousedev_disconnect()' function  can safely remove  the pointer
      corresponding    to   the    disconnected    mouse   from    the
      'mousedev_table'.

4. 'mousedev_free()':
   The  line "mousedev_table[mousedev->minor] =  NULL;" is  moved into
   the 'mousedev_disconnect()' function.

Attachment: tests.tgz
Description: Binary data

Reply via email to