Subject: kern/30815: ntpd refclockio broken wrt/ SIGIO
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <kardel@acm.org>
List: netbsd-bugs
Date: 07/23/2005 13:30:00
>Number:         30815
>Category:       kern
>Synopsis:       ntpd refclockio broken wrt/ SIGIO
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jul 23 13:30:00 +0000 2005
>Originator:     Frank Kardel
>Release:        NetBSD 3.99.7-20050723
>Organization:
	
>Environment:
System: NetBSD pip.kardel.name 3.99.7 NetBSD 3.99.7 (PIP_ISDN) #1: Sat Jul 23 10:44:34 MEST 2005 kardel@pip.kardel.name:/fs/IC35L180AVV207-1-n/IC35L120AVV207-0-e/src/NetBSD/netbsd/sys/arch/i386/compile/obj.i386/PIP_ISDN i386
Architecture: i386
Machine: i386
>Description:
	The recent relaxation to allow SIGIO on tty descriptors without
	requiring TIOCSCTTY is incomplete. Current version 1.9 of
	usr.sbin/ntp/include/config.h has USE_FSETOWNCTTY commented out.
	So ntpd doesn't aquire a CTTY. Fact is that currently TTY input
	does not cause a SIGIO to be delivered in this setup.
	ntpd pretends to run because of network SIGIOs, but ntpd is
        unable to actually use a tty refclock as input on a TTY as
	input is batched in intervals of network caused SIGIOs.

	So, currently ntpd refclock support is broken.
	
>How-To-Repeat:
	Run the current (20050723) ntpd with a reference clock and see 
	following pattern:

Setup:
  1683 ntpd     CALL  ioctl(0x10,TIOCSETA,0xbfbfdcc0)
  1683 ntpd     GIO   fd 16 wrote 44 bytes
       "\^E\0\0\0\0\0\0\0\0\M-K\0\0\0\0\0\0\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\^A\0\M^?\M^?\0K\0\0\0K\0\0"
  1683 ntpd     RET   ioctl 0
  1683 ntpd     CALL  __sigprocmask14(1,0xbfbfda90,0)
  1683 ntpd     RET   __sigprocmask14 0
  1683 ntpd     CALL  getpid
  1683 ntpd     RET   getpid 1683/0x693, 1
  1683 ntpd     CALL  fcntl(0x10,6,0x693)
  1683 ntpd     RET   fcntl 0
  1683 ntpd     CALL  fcntl(0x10,4,0x44)
  1683 ntpd     RET   fcntl 0
  1683 ntpd     CALL  __sigprocmask14(2,0xbfbfda90,0)
  1683 ntpd     RET   __sigprocmask14 0
  1683 ntpd     CALL  ioctl(0x10,TIOCFLUSH,0xbfbfdab0)

IO pattern:
  1683 ntpd     PSIG  SIGIO caught handler=0x8090880 mask=())
  1683 ntpd     CALL  clock_gettime(0,0xbfbfe448)
  1683 ntpd     RET   clock_gettime 0
  1683 ntpd     CALL  select(0x12,0xbfbfe420,0,0,0xbfbfdfa8)
  1683 ntpd     RET   select 2
  1683 ntpd     CALL  read(0x10,0x8138c1c,0x444)
  1683 ntpd     GIO   fd 16 read 375 bytes
       "\^B23.07.05; 6; 12:33:32; +00:00;   S    ; 50.0484N   8.7879E  193m\^C\^B23.07.05; 6; 12:33:33; +00:00;   S    ; 50.0484N   8.7879E  193m\^C\^B23.07.05;\
         6; 12:33:34; +00:00;   S    ; 50.0484N   8.7879E  193m\^C\^B23.07.05; 6; 12:33:35; +00:00;   S    ; 50.0484N   8.7879E  193m\^C\^B23.07.05; 6; 12:33:36\
        ; +00:00;   S    ; 50.0484N   8.7879E  193m\^C\^A\^C\^A$\0\M-&\^D\M-R\0b\^V\^A\0005\^E\0\M-p\0\0\0\0\0\0(>\0\0\0\0\0\0\M-`\M-<\0\0\0\0\0\0\M-^\^D\^E\0\r\
        \r"
  1683 ntpd     RET   read 375/0x177
  1683 ntpd     CALL  ioctl(0x10,TIOCDCDTIMESTAMP,0xbfbfd9c0)
  1683 ntpd     GIO   fd 16 read 8 bytes
  1683 ntpd     CALL  ioctl(0x10,TIOCDCDTIMESTAMP,0xbfbfd9c0)
  1683 ntpd     GIO   fd 16 read 8 bytes
       "\^_9\M-bB\M-98\^O\0"
  1683 ntpd     RET   ioctl 0
  1683 ntpd     CALL  gettimeofday(0xbfbfc028,0)
  1683 ntpd     RET   gettimeofday 0
  1683 ntpd     CALL  getpid
  1683 ntpd     RET   getpid 1683/0x693, 1
  1683 ntpd     CALL  sendto(3,0xbfbfc4a0,0xd0,0,0,0)
  1683 ntpd     GIO   fd 3 wrote 208 bytes
       "<30>Jul 23 14:33:36 ntpd[1683]: PARSE receiver #0: STATE CHANGE: UTC DISPLAY; TIME CODE; POSITION; (LEAP INDICATION; POSITION) -> UTC DISPLAY; TIME CODE\
        ; PPS; POSITION; (LEAP INDICATION; PPS SIGNAL; POSITION)"
  1683 ntpd     RET   sendto 208/0xd0
  1683 ntpd     CALL  ioctl(0x10,TIOCDCDTIMESTAMP,0xbfbfd9c0)
  1683 ntpd     GIO   fd 16 read 8 bytes
       "\^_9\M-bB\M-98\^O\0"
  1683 ntpd     RET   ioctl 0
  1683 ntpd     CALL  gettimeofday(0xbfbfc028,0)
  1683 ntpd     RET   gettimeofday 0
  1683 ntpd     CALL  getpid
  1683 ntpd     RET   getpid 1683/0x693, 1
  1683 ntpd     CALL  sendto(3,0xbfbfc4a0,0xd0,0,0,0)
  1683 ntpd     GIO   fd 3 wrote 208 bytes
       "<30>Jul 23 14:33:36 ntpd[1683]: PARSE receiver #0: STATE CHANGE: UTC DISPLAY; TIME CODE; PPS; POSITION; (LEAP INDICATION; PPS SIGNAL; POSITION) -> UTC D\
        ISPLAY; TIME CODE; POSITION; (LEAP INDICATION; POSITION)"
  1683 ntpd     RET   sendto 208/0xd0
  1683 ntpd     CALL  ioctl(0x10,TIOCDCDTIMESTAMP,0xbfbfd9c0)
  1683 ntpd     GIO   fd 16 read 8 bytes
       "\^_9\M-bB\M-98\^O\0"
  1683 ntpd     RET   ioctl 0
  1683 ntpd     CALL  ioctl(0x10,TIOCDCDTIMESTAMP,0xbfbfd9c0)
  1683 ntpd     GIO   fd 16 read 8 bytes
       "\^_9\M-bB\M-98\^O\0"
  1683 ntpd     RET   ioctl 0
  1683 ntpd     CALL  ioctl(0x10,TIOCDCDTIMESTAMP,0xbfbfd9c0)
  1683 ntpd     GIO   fd 16 read 8 bytes
       "\^_9\M-bB\M-98\^O\0"
  1683 ntpd     RET   ioctl 0
  1683 ntpd     CALL  ioctl(0x10,TIOCDCDTIMESTAMP,0xbfbfd9c0)
  1683 ntpd     GIO   fd 16 read 8 bytes
       "\^_9\M-bB\M-98\^O\0"
  1683 ntpd     RET   ioctl 0
  1683 ntpd     CALL  recvfrom(6,0x813917c,0x444,0,0x8139064,0xbfbfdfa4)
  1683 ntpd     GIO   fd 6 read 48 bytes
       "#\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  1683 ntpd     RET   recvfrom 48/0x30
  1683 ntpd     CALL  select(0x12,0xbfbfe420,0,0,0xbfbfdfa8)
  1683 ntpd     RET   select 0
  1683 ntpd     CALL  clock_gettime(0,0xbfbfdf38)
  1683 ntpd     RET   clock_gettime 0
  1683 ntpd     CALL  compat_16___sigreturn14(0xbfbfe49c)
  1683 ntpd     RET   compat_16___sigreturn14 JUSTRETURN
  1683 ntpd     CALL  __sigprocmask14(2,0xbfbfe510,0)
  1683 ntpd     RET   __sigprocmask14 0
  1683 ntpd     CALL  open(0xbfbfc960,0,0)
  1683 ntpd     NAMI  "/usr/share/zoneinfo/GMT"
  1683 ntpd     RET   open 18/0x12
  1683 ntpd     CALL  read(0x12,0xbfbfaa50,0x1f08)
  1683 ntpd     GIO   fd 18 read 56 bytes
       "TZif\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\^A\0\0\0\^A\0\0\0\0\0\0\0\0\0\0\0\^A\0\0\0\^D\0\0\0\0\0\0GMT\0\0\0"
  1683 ntpd     RET   read 56/0x38
 

Notice the big gob of character from the TTY (fd=16). The SIGIO was actually caused by the network interaction on fd 6.

When enabling CTTY for the TTY things look normal again wrt/ SIGIO.

Setup:
  2221 ntpd     CALL  ioctl(0x10,TIOCSETA,0xbfbfdcc0)
  2221 ntpd     GIO   fd 16 wrote 44 bytes
       "\^E\0\0\0\0\0\0\0\0\M-K\0\0\0\0\0\0\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\M^?\^A\0\M^?\M^?\0K\0\0\0K\0\0"
  2221 ntpd     RET   ioctl 0
  2221 ntpd     CALL  __sigprocmask14(1,0xbfbfda90,0)
  2221 ntpd     RET   __sigprocmask14 0
  2221 ntpd     CALL  ioctl(0x10,TIOCSCTTY,0)
  2221 ntpd     RET   ioctl 0
  2221 ntpd     CALL  getpid
  2221 ntpd     RET   getpid 2221/0x8ad, 1
  2221 ntpd     CALL  fcntl(0x10,6,0x8ad)
  2221 ntpd     RET   fcntl 0
  2221 ntpd     CALL  fcntl(0x10,4,0x44)
  2221 ntpd     RET   fcntl 0
  2221 ntpd     CALL  __sigprocmask14(2,0xbfbfda90,0)
  2221 ntpd     RET   __sigprocmask14 0
  2221 ntpd     CALL  ioctl(0x10,TIOCFLUSH,0xbfbfdab0)

IO pattern:
  2221 ntpd     RET   select 1
  2221 ntpd     CALL  read(0x10,0x813f1a4,0x444)
  2221 ntpd     GIO   fd 16 read 8 bytes
       "\^B23.07.0"
  2221 ntpd     RET   read 8
  2221 ntpd     CALL  select(0x12,0xbfbfe3d0,0,0,0xbfbfdf58)
  2221 ntpd     RET   select 0
  2221 ntpd     CALL  clock_gettime(0,0xbfbfded8)
  2221 ntpd     RET   clock_gettime 0
  2221 ntpd     CALL  compat_16___sigreturn14(0xbfbfe49c)
  2221 ntpd     RET   compat_16___sigreturn14 JUSTRETURN
  2221 ntpd     CALL  __sigprocmask14(2,0xbfbfe510,0)
  2221 ntpd     RET   __sigprocmask14 0
  2221 ntpd     CALL  __sigprocmask14(1,0xbfbfe510,0)
  2221 ntpd     RET   __sigprocmask14 0
  2221 ntpd     CALL  __sigprocmask14(2,0,0xbfbfe510)
  2221 ntpd     RET   __sigprocmask14 0
  2221 ntpd     CALL  __sigsuspend14(0xbfbfe510)
  2221 ntpd     RET   __sigsuspend14 -1 errno 4 Interrupted system call
  2221 ntpd     PSIG  SIGIO caught handler=0x808f694 mask=())
  2221 ntpd     CALL  clock_gettime(0,0xbfbfe448)
  2221 ntpd     RET   clock_gettime 0
  2221 ntpd     CALL  select(0x12,0xbfbfe3d0,0,0,0xbfbfdf58)
  2221 ntpd     RET   select 1
  2221 ntpd     CALL  read(0x10,0x813f1a4,0x444)
  2221 ntpd     GIO   fd 16 read 8 bytes
       "5; 6; 12"
  2221 ntpd     RET   read 8
  2221 ntpd     CALL  select(0x12,0xbfbfe3d0,0,0,0xbfbfdf58)
  2221 ntpd     RET   select 0
  2221 ntpd     CALL  clock_gettime(0,0xbfbfded8)
  2221 ntpd     RET   clock_gettime 0
  2221 ntpd     CALL  compat_16___sigreturn14(0xbfbfe49c)
  2221 ntpd     RET   compat_16___sigreturn14 JUSTRETURN
  2221 ntpd     CALL  __sigprocmask14(2,0xbfbfe510,0)
  2221 ntpd     RET   __sigprocmask14 0
  2221 ntpd     CALL  __sigprocmask14(1,0xbfbfe510,0)
  2221 ntpd     RET   __sigprocmask14 0
  2221 ntpd     CALL  __sigprocmask14(2,0,0xbfbfe510)
  2221 ntpd     RET   __sigprocmask14 0
  2221 ntpd     CALL  __sigsuspend14(0xbfbfe510)
  2221 ntpd     RET   __sigsuspend14 -1 errno 4 Interrupted system call
  2221 ntpd     PSIG  SIGIO caught handler=0x808f694 mask=())
  2221 ntpd     CALL  clock_gettime(0,0xbfbfe448)
  2221 ntpd     RET   clock_gettime 0
  2221 ntpd     CALL  select(0x12,0xbfbfe3d0,0,0,0xbfbfdf58)
  2221 ntpd     RET   select 1
  2221 ntpd     CALL  read(0x10,0x813f1a4,0x444)
  2221 ntpd     GIO   fd 16 read 8 bytes
       ":18:47; "
  2221 ntpd     RET   read 8
  2221 ntpd     CALL  select(0x12,0xbfbfe3d0,0,0,0xbfbfdf58)
  2221 ntpd     RET   select 0
  2221 ntpd     CALL  clock_gettime(0,0xbfbfded8)
  2221 ntpd     RET   clock_gettime 0

Here a SIGIO is handled every 8 characters. This SIGIO is caused by TTY input. The ntpd reference clock code works.

>Fix:
	Correct TTY code to post SIGIO (and only SIGIO) on input even when the TTY is not a CTTY.