Paul,

I too looked at this over the weekend.  Here's what I
discovered:

 - linux 2.6 and later linux 2.4 kernels provide 32-bit to 64-bit ioctl
   conversions.  Earlier linux 2.4 kernels provide some 32 to 64 bit
   ioctl conversions on a architecture by architecture basis, but the
   supported ioctl list is sparse.

 - the legacy CDROM driver ioctl interface uses 'S' as the magic number
   for its ioctls.  The SCSI driver also uses 'S' as the magic number of
   some of its ioctls.  Some CDROM driver ioctls conflict even with SCSI
   ioctls.

 - register_ioctl32_conversion and unregister_ioctl32_conversion was
   added somewhere between 2.4.18 and 2.4.20.  CDROM ioctls were also
   added somewhere between 2.4.18 and 2.4.20.  All 2.6 kernel have it.
   The functions refuse to register a conversion that has already been
   specified and refuse to unregister a "base" definition (one specified
   for the architecture in the kernel, such as the CDROM conversions).

 - as of 2.6.11, a new file operation (compat_ioctl) was added to
   perform device specific 32 to 64 bit conversions.

Here is a little precedent for the use of 'S':

 - STR is defined as ('S'<<8) in Fourth edition of the i386 ABI.
   ("System V Application Binary Interface -- Intel386(TM) Architecture
   Processor Supplement")

 - STR is defined as ('S'<<8) in the Third edition of the MIPS ABI.
   ("System V Application Binary Interface -- MIPS(R) RISC Processor
   Supplement").

 - The ARM ABI follows i386 in this regard.

 - The X86_64 ABI ("System V Application Binary Interface -- x86_64(TM)
   Architecture Processor Supplement") indicates that the 32-bit CAE
   must conform to the i386 ABI and regarding the stropts.h header, that
   it is unchanged from the i386 ABI.

 - GNU glibc header files <sys/stropts.h> conforms to these ABIs and in
   fact provides ('S'<<8) for all architectures including S390.

 - Original AT&T SVR4 header (of course) use 'S'.
 - OSF/1 Release 1.1 headers use 'S'.
 - OSF/1 Release 1.2 headers use 'S'.
 - Solaris 2.6 headers use 'S'.
 - Solaris 2.7 headers use 'S'.
 - SUSv3/POSIX 2003 does not specify a magic number

 - It is noted in the iBCS (now LinuxABI) package that 'S' is used for
   all architectures, but that SCO 3.2.x (x<4) set the high bit in a
   conflicting ioctl.  (You say that you cannot remember why you chose
   0xdc.  Probably 0xd3 would have been a better choice: it is 'S'
   (0x53) with the high bit set.)

With regard to the current state of S390X ifdefs in 2.18.0 (that your
patch suggests also be applied to x86_64):

 - The list of registered ioctls currently includes I_SETSIG, I_SRDOPT,
   I_PUSH, I_LINK, I_UNLINK, and I_STR.  (head/linux-mdep.c)  All but
   I_STR simply call sys_ioctl (i.e. no conversion).

 - 2.4 kernels without register_ioctl32_conversion will fail to build.
   (But then older 2.4 kernels don't really support 32 over 64 anyway.)

 - The conversion registration will always fail if STR is defined as
   ('S'<<8) because the CDROM/SCSI ioctls using 'S' conflict with almost
   all standard STREAMS ioctls.

 - 2.4 kernels with register_ioctl32_conversion and 2.6 kernels will
   fail [EINVAL] on all ioctls other than the six listed above, because
   the default is to fail.  This means that the following ioctls will
   fail (even with STR defined to 0xdc):

   I_NREAD, I_POP, I_LOOK, I_FLUSH, I_GRDOPT, I_GETSIG, I_FIND,
   I_ISASTREAM, I_RECVFD, I_PEEK, I_FDINSERT, I_SENDFD, I_E_RECVFD,
   I_SWROPT, I_GWROPT, I_LIST, I_PLINK, I_PUNLINK, I_FLUSHBAND,
   I_CKBAND, I_GETBAND, I_ATMARK, I_SETCLTIME, I_GETCLTIME, I_CANPUT,
   I_SERROPT, I_GERROPT, I_ANCHOR, I_ESETSIG, I_EGETSIG, I_S_RECVFD,
   I_STATS, I_BIGPIPE, I_GETTP, I_TILDE, I_GETMSG, I_PUTMSG, I_GETPMSG,
   I_PUTPMSG, I_PIPE, I_FIFO, I_POLL, I_SETDELAY, I_GETDELAY,
   I_RUN_QUEUES, I_AUTOPUSH, I_HEAD_REPORT, I_FATTACH, I_FDETACH,
   I_LIS_PIPE, I_LIS_FATTACH, I_LIS_FDETACH, I_LIS_GETPMSG,
   I_LIS_PUTPMSG, I_LIS_SEMTIME, I_LIS_LOCKS, I_LIS_SDBGMSK2,
   I_LIS_QRUN_STATS, I_LIS_PRNTQUEUES, I_LIS_PRNTSPL,
   I_LIS_GET_MAXMSGMEM, I_LIS_SET_MAXMSGMEM, I_LIS_GET_MAXMEM,
   I_LIS_SET_MAXMEM, I_LIS_GETSTATS, I_LIS_PRNTSTRM, I_LIS_PRNTMEM,
   I_LIS_SDBGMSK.

   Many of these are required for standard operation as well as required
   for proper operation of 32 bit applications programs using the
   STREAMS ioctl(2p) interface.

   Even getmsg/putmsg will break on 2.6.11+ kernels because the ioctl
   interface must be used for getpmsg/putpmsg instead of the read/write
   interface.  isastream() will also report that a Stream is not a
   Stream (because it uses I_CANPUT, which will fail).

Changing STR from ('S'<<8) to 0xdc for x86_64 has the following
consequences:

 - STREAMS will no longer comply with the SVID, i386 or x86_64 ABIs.
   This means that any legacy applications will fail to run.  Also,
   any applications compiled against standard headers <stropts.h> will
   also fail.

 - Any driver that passes STREAMS messages to peripheral hardware (or
   directly to another system) based on a standard STREAMS
   implementation will also fail.
   
   (This was the major reason for changing the message type number
   (M_PROTO, M_DATA, etc.) in 2.18.0 which I notice that your patch
   LiS-2.18.0-A changes back to 2.16 LiS numbering for some reason.  The
   numbering of message types in 2.18.0 was placed as close to other
   STREAMS implementations as possible to permit STREAMS message to be
   passed directly between systems.)

 - For kernels 2.6.11 and greater, there is no need to change STR
   because compat_ioctl file operation can do device specific conversion
   and there will be no conflict with the legacy base CDROM/SCSI ioctls.

There is just too much precedent for 'S'.  Therefore, I propose the
following for the next LiS (LiS-2.18.3) and Linux Fast-STREAMS
(streams-0.7a.5) release:

 - For LiS I will rip the ioctl conversion hash table and the cdrom
   conversion functions from the system map and override the CDROM
   ioctls with a function that checks for character or block device and
   then either calls the CDROM conversion or calls the STREAMS
   conversions.

 - For Linux Fast-STREAMS I will take the same approach before kernel
   2.6.11.  For kernel 2.6.11 and beyond I will define the compat_ioctl
   file operation to perform device specific conversions. (LiS cannot
   handle unlocked ioctls so this approach is pointless for LiS.)

 - Using either approach, I will define conversions for ALL defined
   ioctls, not just the six.

How does that sound?

--brian


On Sun, 12 Feb 2006, Paul Landay wrote:

> I found a RHEL4-x86_64 system to try this one and my
> memory was (mostly) correct.  The change to __SID in
> LiS/include/sys/gnu.stropts.h and LiS/include/sys/stropts.h
> in the patches I sent 03 Feb 2006 08:25:05 does fix
> this issue.  The part I forgot was that you should have
> the stropts.h '#define STR' match that of the __SID values.
> 
> To be specific, these are the changes:
>    "include/sys/stropts.h"
>      #define __SID           (0xdc<<8)       /* for GNU libc
>      #define STR             (0xdc<<8)       /* for UnixWare
>    "include/sys/gnu.stropts.h"
>      #define __SID           (0xdc<< 8)
> 
> I don't recall how we selected the 0xdc base offset value,
> but it has proven to work for rhel3,rhel4,sles8,sles8 on
> i686,s390,s390x,ppc64,x86_64.
> 
> This change means you to have to recompile any of your LiS
> dependent code, but since x86_64 is new for you that should
> not be a big problem.  If you need to maintain binary
> compatibility with old modules on old platforms you can
> #ifdef the '#define _SID' and '#define STR' to use different
> values for different platforms.
> 
> Paul Landay
> 
> _______________________________________________
> Linux-streams mailing list
> [email protected]
> http://gsyc.escet.urjc.es/mailman/listinfo/linux-streams

-- 
Brian F. G. Bidulock    ¦ The reasonable man adapts himself to the ¦
[EMAIL PROTECTED]    ¦ world; the unreasonable one persists in  ¦
http://www.openss7.org/ ¦ trying  to adapt the  world  to himself. ¦
                        ¦ Therefore  all  progress  depends on the ¦
                        ¦ unreasonable man. -- George Bernard Shaw ¦
_______________________________________________
Linux-streams mailing list
[email protected]
http://gsyc.escet.urjc.es/mailman/listinfo/linux-streams

Reply via email to