home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / unix / sysv386 / 12315 < prev    next >
Encoding:
Internet Message Format  |  1992-07-23  |  8.2 KB

  1. Xref: sparky comp.unix.sysv386:12315 comp.unix.xenix:19 alt.sources:1746
  2. Newsgroups: comp.unix.sysv386,comp.unix.xenix,alt.sources
  3. Path: sparky!uunet!caen!batcomputer!banana.ithaca.ny.us!jhood
  4. From: jhood@banana.ithaca.ny.us (John Hood)
  5. Subject: FAS 2.09.1 bugs found and fixed
  6. Organization: Pick a banana, any banana
  7. Date: Thu, 23 Jul 1992 02:54:00 GMT
  8. Message-ID: <1992Jul23.025400.7765@banana.ithaca.ny.us>
  9. Lines: 254
  10.  
  11.  
  12. Several months ago, I started having problems with FAS 2.09.1 on my
  13. busy modem lines.  After a generous amount of headscratching, far
  14. too much study of the source code, and much time wasted waiting for
  15. the modem lines to hang, I finally found the bugs.  I fixed them, and
  16. reported them to Uwe, who will incorporate them into the next
  17. version of FAS.  Meanwhile, I'm releasing a minimal patch for the
  18. other suffering users of FAS.
  19.  
  20. I've had this patch installed on my system for nearly two months now,
  21. and I have not had the modem lines hang since.  (I have had a *modem*
  22. hang, though.  Telebit, fix your code :)
  23.  
  24. Sorry for not getting this out sooner.  Think of it this way-- it's
  25. well tested.
  26.  
  27. This is a minimal set of patches that fixes the bugs and does nothing
  28. else.  Apply to a standard fas 2.09.1 distribution.
  29.  
  30. --jh
  31.  
  32. John Hood, CU student, CU employee, and sometime BananaOp
  33. jhood@albert.mannlib.cornell.edu,jhood@banana.ithaca.ny.us,jeh@crnlvax5.bitnet
  34. By any reasonable computer's standard, I'm a virus.  So are you.
  35.  
  36.  
  37. --buglist--*--buglist--*--buglist--*--buglist--*--buglist--*--buglist--
  38.  
  39. bug 1:
  40.  
  41. ports occasionally get stuck with a getty sleeping on them forever.
  42. Usually, echo is on and the ports are running in cooked mode.  This
  43. can be cured by killing the getty.
  44.  
  45. repeat-by:
  46.  
  47.   from a FAS tty, type:
  48.  
  49. $ exec cat /etc/passwd
  50.  
  51.   <interrupt cat near the end of the file, while FAS is draining its
  52.   internal buffer; note absences of modem hangup and login: prompt>
  53.  
  54. In the real world, this is probably caused by line noise (frequently
  55. including '^?') from a non-error-correcting modem when it is hung up
  56. on. 
  57.  
  58. problem:
  59.  
  60. The kernel calls fasclose() upon closing the last open of a FAS
  61. device.  fasclose() can be interrupted.  This leaves the kernel
  62. thinking the device has been closed, and fas thinking the device is
  63. still open (DF_DEVICE_OPEN).  When the next fasopen() occurs, the
  64. driver hangs on a sleep.  Either it sleeps on ttyp->t_canq or it
  65. becomes a special case of bug #2.  (I don't remember now exactly where
  66. it got stuck; I just remember the central problem, and the fix)
  67.  
  68. fix:
  69.  
  70. change sleeps at low priority in fasclose() to a higher priority, so
  71. they are uninterruptable.  My AIX 2 documentation (this is the best
  72. driver documentation I have) says that an xx_close() routine should
  73. never return an error; I conservatively interpret that to mean that it
  74. should also always return, instead of allowing itself to be exited via
  75. a signal.  Certainly, even if a fasclose exits by some route other
  76. than returning, it should make sure it does something resembling the
  77. normal close cleanup.
  78.  
  79. bug 2:
  80.  
  81. ports occasionally get stuck with a getty sleeping on them forever.
  82. Usually, they are in a no-echo mode.  This can be cured by killing the
  83. getty.
  84.  
  85. repeat-by:
  86.  
  87.   On a FAS tty set up to pay attention to DTR, do the following:
  88.  
  89. $ (trap "" 1; sleep 30) &
  90.   <drop dtr for a short time, but long enough for a new getty to start>
  91.   <raise dtr; note absence of login: prompt>
  92.  
  93. In the real world, this is probably caused by a sleeping inews in the
  94. background keeping the port open (this is one unfortunate feature of
  95. Cnews-- it'll sit there in the background if there's no disk space,
  96. and it's SIGHUP-proofed), or with Waffle, Waffle not waiting for its
  97. children when it gets SIGHUP and allowing another getty to start
  98. before all its children die.  (Waffle is usually run as a shell.)
  99.  
  100. problem:
  101.  
  102. fasopen() will sleep if it is doing a getty open, there is a
  103. preexisting getty open, and there is no carrier.  The only thing that
  104. will wake this sleep is a fasclose().  But since the kernel will
  105. consider the driver open because of the second fasopen(), it will
  106. not call fasclose when the preexisting getty open is closed (actually,
  107. it will never call fasclose).
  108.  
  109. fix:
  110.  
  111. replace if conditional for the first sleep in fasopen() with the code
  112. used in fas 2.09.0.
  113.  
  114.  
  115. --patches--*--patches--*--patches--*--patches--*--patches--*--patches--*
  116.  
  117. *** ../fas-dist/fas.c    Wed Jul 22 22:28:36 1992
  118. --- fas.c    Sun May 24 20:08:05 1992
  119. ***************
  120. *** 629,635
  121.       for (unit = 0; unit < fas_physical_units; unit++)
  122.           (void) printcfg ("fas", (uint) ((ushort) (fas_port [unit])), 7,
  123.                       fas_vec [unit], -1,
  124. !                     "unit=%d type=%c release=2.09.1",
  125.                       unit, port_stat [unit]);
  126.   #else
  127.       port_stat [unit] = '\0';
  128.  
  129. --- 629,635 -----
  130.       for (unit = 0; unit < fas_physical_units; unit++)
  131.           (void) printcfg ("fas", (uint) ((ushort) (fas_port [unit])), 7,
  132.                       fas_vec [unit], -1,
  133. !                     "unit=%d type=%c release=2.09.1.jh.1",
  134.                       unit, port_stat [unit]);
  135.   #else
  136.       port_stat [unit] = '\0';
  137. ***************
  138. *** 633,639
  139.                       unit, port_stat [unit]);
  140.   #else
  141.       port_stat [unit] = '\0';
  142. !     (void) printf ("\nFAS 2.09.1 async driver: Unit 0-%d init state is [%s]\n\n",
  143.               unit - 1,
  144.               port_stat);
  145.   #endif
  146.  
  147. --- 633,639 -----
  148.                       unit, port_stat [unit]);
  149.   #else
  150.       port_stat [unit] = '\0';
  151. !     (void) printf ("\nFAS 2.09.1.jh.1 async driver: Unit 0-%d init state is [%s]\n\n",
  152.               unit - 1,
  153.               port_stat);
  154.   #endif
  155. ***************
  156. *** 683,691
  157.       */
  158.       for (;;)
  159.       {
  160. !         /* If this is a getty open, the FNDELAY flag is not set,
  161. !            and the device is already open for dialout or it is
  162. !            open and there is no carrier, wait until device
  163.              is closed.
  164.           */
  165.           while ((open_mode & OS_OPEN_FOR_GETTY) && !(flag & FNDELAY)
  166.  
  167. --- 683,690 -----
  168.       */
  169.       for (;;)
  170.       {
  171. !         /* If this is a getty open, the device is already open for
  172. !            dialout and the FNDELAY flag is not set, wait until device
  173.              is closed.
  174.           */
  175.           while ((open_mode & OS_OPEN_FOR_GETTY)
  176. ***************
  177. *** 688,698
  178.              open and there is no carrier, wait until device
  179.              is closed.
  180.           */
  181. !         while ((open_mode & OS_OPEN_FOR_GETTY) && !(flag & FNDELAY)
  182. !                 && ((fip->o_state & OS_OPEN_FOR_DIALOUT)
  183. !                     || ((fip->o_state & OS_OPEN_FOR_GETTY)
  184. !                         && !(fip->tty->t_state
  185. !                                 & CARR_ON))))
  186.           {
  187.               if (have_lock)
  188.               {
  189.  
  190. --- 687,695 -----
  191.              dialout and the FNDELAY flag is not set, wait until device
  192.              is closed.
  193.           */
  194. !         while ((open_mode & OS_OPEN_FOR_GETTY)
  195. !                     && (fip->o_state & OS_OPEN_FOR_DIALOUT)
  196. !                     && !(flag & FNDELAY))
  197.           {
  198.               if (have_lock)
  199.               {
  200. ***************
  201. *** 850,856
  202.           : fas_tty_ptr [physical_unit];
  203.       
  204.       old_level = SPLINT ();
  205. !     get_device_lock (fip, TTIPRI);
  206.   
  207.       /* wait for output buffer drain only if device was open */
  208.       if (ttyp->t_state & ISOPEN)
  209.  
  210. --- 847,853 -----
  211.           : fas_tty_ptr [physical_unit];
  212.       
  213.       old_level = SPLINT ();
  214. !     get_device_lock (fip, PZERO - 1);
  215.   
  216.       /* wait for output buffer drain only if device was open */
  217.       if (ttyp->t_state & ISOPEN)
  218. ***************
  219. *** 855,861
  220.       /* wait for output buffer drain only if device was open */
  221.       if (ttyp->t_state & ISOPEN)
  222.       {
  223. !         /* wait for buffer drain and catch interrupts */
  224.           while (ttyp->t_outq.c_cc || (ttyp->t_state & (BUSY | TIMEOUT)))
  225.           {
  226.               ttyp->t_state |= TTIOW;
  227.  
  228. --- 852,858 -----
  229.       /* wait for output buffer drain only if device was open */
  230.       if (ttyp->t_state & ISOPEN)
  231.       {
  232. !         /* wait for buffer drain */
  233.           while (ttyp->t_outq.c_cc || (ttyp->t_state & (BUSY | TIMEOUT)))
  234.           {
  235.               ttyp->t_state |= TTIOW;
  236. ***************
  237. *** 859,872
  238.           while (ttyp->t_outq.c_cc || (ttyp->t_state & (BUSY | TIMEOUT)))
  239.           {
  240.               ttyp->t_state |= TTIOW;
  241. !             if (sleep ((caddr_t) &ttyp->t_oflag, TTOPRI | PCATCH))
  242. !             {
  243. !                 /* caught signal */
  244. !                 ttyp->t_state &= ~TTIOW;
  245. !                 release_device_lock (fip);
  246. !                 (void) splx (old_level);
  247. !                 longjmp (u.u_qsav);
  248. !             }
  249.           }
  250.           /* block transmitter and wait until it is
  251.              empty
  252.  
  253. --- 856,862 -----
  254.           while (ttyp->t_outq.c_cc || (ttyp->t_state & (BUSY | TIMEOUT)))
  255.           {
  256.               ttyp->t_state |= TTIOW;
  257. !             sleep ((caddr_t) &ttyp->t_oflag, PZERO - 1);
  258.           }
  259.           /* block transmitter and wait until it is
  260.              empty
  261. -- 
  262. John Hood, CU student, CU employee, and sometime BananaOp
  263. jhood@albert.mannlib.cornell.edu,jhood@banana.ithaca.ny.us,jeh@crnlvax5.bitnet
  264. By any reasonable computer's standard, I'm a virus.  So are you.
  265.