Subject: Re: kern/21503: empty SCSI tape drives cannot be queried or configured
To: Manuel Bouyer <bouyer@antioche.lip6.fr>
From: Greg A. Woods <woods@weird.com>
List: netbsd-bugs
Date: 06/17/2003 12:50:11
[ On Tuesday, June 17, 2003 at 13:44:15 (+0200), Manuel Bouyer wrote: ]
> Subject: Re: kern/21503: empty SCSI tape drives cannot be queried or configured
>
> Solaris and Linux define it that way, so maybe we should change it.

Well, yes.  :-)

> But then it's redundant with ENXIO

Not to the POSIX definition of ENXIO, which is subtly different.

Traditionally ENODEV suggests you've got a /dev/foo but no driver
installed in the device switch tables for that major number.  The full
POSIX "generic" definition (in the "Error Number" section, as opposed to
the English message given in "errno.h") is:

   [ENODEV]
           No such device.  An attempt was made to apply an
           inappropriate function to a device; for example, trying to
           read a write-only device such as a printer.

In POSIX ENXIO on open() means you've got the driver, but no hardware.
That's also the way *BSD generally (though perhaps not 100%
consistently) uses ENXIO as well, at least for open(2).  For reference
again the full POSIX definition of ENXIO is:

   [ENXIO]
           No such device or address.  Input or output on a special file
           refers to a device that does not exist, or makes a request
           beyond the capabilities of the device.  It may also occur
           when, for example, a tape drive is not on-line.

I.e. for open(2) ENODEV means "no device driver", and for other system
calls it means "no device driver function in the device switch table".

(note also that opening a removable-media device with no media is not
really beyond the capabilities of the device -- only reading from it or
writing to it would be, i.e. the open() should succeed but read() or
write() should return ENXIO)

I remember being confounded over the wording of ENODEV's error message
back in V7 and after learning the true meaning I wished then that the
word "driver" had been appended.  However over the years since I've
simply come to translated it automatically as I read it.


> and we need something else for
> "Operation not supported by device" (maybe use EOPNOTSUPP ?)

That's already there and it's called "ENOTTY" (at least for ioctl() --
it makes no sense for open() anyway).  The POSIX-defined string is:

     [ENOTTY]
             Inappropriate I/O control operation.

EOPNOTSUPP has been socket-only for quite a while, and POSIX also strongly
suggests it's only for sockets too:

   [EOPNOTSUPP]
           Operation not supported on socket.  The type of socket
           (address family or protocol) does not support the requested
           operation.

EOPNOTSUPP might be OK for an ioctl() requesting a rewind operation on a
specific type of device that can't rewind but via a driver that also
does support rewindable devices (e.g. an old 8-track audio loop tape :-),
but I can't conceive of any valid use for EOPNOTSUPP from open(2).


> This require a large audit, because ENODEV is used in many parts of the system

195 occurences in -current's kernel source (not counting compat/*).  :-)

(22 of those are in arch/*/stand code and may even be POSIX-compatible uses)

Most should probably be converted directly to ENXIO, and certainly all
that are in the path of any open(2), but some others may need further
thought.

> > You also have to consider the specific definition of the error code
> > w.r.t. to the system call in question.
> > 
> > ENODEV is not mentioned explicitly as a valid error code for open(2),
> 
> But it's not forbidden either

I should hope not.  :-)

But POSIX does have a quite different suggested meaning for open(),
i.e. it should not indicate anything to do with the state of the
underlying hardware.

> In case of ioctl. We're talking about others system calls here (open,
> in this case)

Well yes -- unless you buy into my bigger suggestion that open() should
succeed even when there's no tape (e.g. as it does for floppies).

> Maybe EOPNOTSUPP is better. ENOSPC doens't look right, in the sense that
> it's confusing:
> mt offline
> mt: /dev/nrst0: No space left on device
> 
> What does the space left on the device has to do with ejecting it ?

You need to have a slightly more relaxed view of what "no space" means!  :-)

Note that we're talking about open() here, not write().  :-)

ENOSPC would definitely be wrong for read() or write() with no media,
but ENXIO would be OK.

> No, I meant removable. hot-plug devices are not limited to devices that
> hold data.

Ah!  OK, yes, hot-pluggable devices!  (which can also be removable media
devices too!  :-)

> We could have some non-data device where only part of it is
> removable, in such a way that the device always probe but isn't always
> fully functionnal.

In the case of a hot-pluggable storage device then the correct error to
return from open(2) when it's suddenly not there any more is ENXIO.

> there's no tape at all, and I think it should be a different error

Strictly I think there should be no error when opening a removable media
device when there's no media in the device -- the open() and any
status-reporting ioctl() should all work, with or without media.

-- 
								Greg A. Woods

+1 416 218-0098;            <g.a.woods@ieee.org>;           <woods@robohack.ca>
Planix, Inc. <woods@planix.com>; VE3TCP; Secrets of the Weird <woods@weird.com>