Subject: process hangs in short wait
To: None <port-i386@NetBSD.ORG>
From: Andreas Wrede <andreas@planix.com>
List: port-i386
Date: 02/05/1998 17:13:19
I have an number of Xenix (IBCS2) programs that I am trying to run on NetBSD 
1.3 in ibcs2 emulation. I had to add code for xenix_locking and ustat(2) to 
the kernel, the diffs are attached below.  The programs run fine, but 
eventually the process will freeze and ps shows it to be in short term, 
uninterruptible  wait (state 'D+') at wchan 'temp'. Once one process is in 
this state, other processes, like 'ls -l /proc' or 'strip netbsd' can freeze 
as well, same state and same wchan.   A ktrace of a frozen process shows 
that it is trying to read() 16 bytes from a freshly opened file.

$ kdump -m 20
   370 ktrace   RET   ktrace 0
   370 ktrace   CALL  execve(0xefbfdbbf,0xefbfdb5c,0xefbfdb64)
   370 ktrace   NAMI  "./brw1"
   370 brw1     EMUL  "ibcs2"
   370 brw1     RET   execve JUSTRETURN
   370 brw1     CALL  time(0xefbfdb64)
   370 brw1     RET   time 886699932/0x34d9f79c
   370 brw1     CALL  ftime(0x18e1660)
   370 brw1     RET   ftime 0
   370 brw1     CALL  open(0xefbfd80c,0,0xefbfdb64)
   370 brw1     NAMI  "/emul/ibcs2/usr/lib/terminfo/p/pc3"
   370 brw1     NAMI  "/usr/lib/terminfo/p/pc3"
   370 brw1     RET   open 5
   370 brw1     CALL  read(0x5,0xefbfc7ec,0x1000)
   370 brw1     GIO   fd 5 read 919 bytes
       "\^Z\^A\^[\0\^U\0\^O\0000\^A\M-]\0pc3|IBM "
   370 brw1     RET   read 919/0x397
   370 brw1     CALL  close(0x5)
   370 brw1     RET   close 0
   370 brw1     CALL  ioctl(0x1,_IO('T',0x1,0),0xefbfc7b0)
   370 brw1     RET   ioctl 0
   370 brw1     CALL  ioctl(0x1,_IO('T',0x1,0),0x197505a)
   370 brw1     RET   ioctl 0
   370 brw1     CALL  ioctl(0x1,_IO('T',0x3,0),0x197506c)
   370 brw1     RET   ioctl 0
   370 brw1     CALL  obreak(0x2000800)
   370 brw1     RET   obreak 0
   370 brw1     CALL  ioctl(0,_IO('T',0x1,0),0xefbfd990)
   370 brw1     RET   ioctl 0
   370 brw1     CALL  fstat(0,0xefbfd9b8)
   370 brw1     RET   fstat 0
   370 brw1     CALL  open(0x1881bf8,0,0xffffffff)
   370 brw1     NAMI  "/emul/ibcs2/dev/"
   370 brw1     NAMI  "/dev/"
   370 brw1     RET   open 5
   370 brw1     CALL  read(0x5,0xefbfda00,0x10)


I am not a kernel hacker, so I hope that my mods to the kernel are not the 
source of the problem:

*** ibcs2_misc.c.orig	Sat Oct 11 09:18:09 1997
--- ibcs2_misc.c	Thu Feb  5 16:33:27 1998
***************
*** 1410,1415 ****
--- 1410,1454 ----
  	IBCS2_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  	return sys_readlink(p, uap, retval);
  }
+ #define X_CMN_UNLCK 0
+ #define X_CMN_WRLCK 1
+ #define X_CMN_RDLCK 2
+ 
+ #define X_LK_UNLCK  X_CMN_UNLCK
+ #define X_LK_LOCK   X_CMN_WRLCK
+ #define X_LK_NBLCK 20 
+ #define X_LK_RLCK   X_CNM_RDLCK
+ #define X_LK_NBRLCK 4
+ #define X_LK_GETLK  5
+ #define X_LK_SETLK  6
+ #define X_LK_SETLKW 7
+ #define X_LK_TESTLK 8
+ 
+ int
+ xenix_xlocking(p, v, retval)
+ 	struct proc *p;
+ 	void *v;
+ 	register_t *retval;
+ {
+ 	struct xenix_xlocking_args /* {
+ 		syscallarg(int) fd;
+ 		syscallarg(int) blk;
+ 		syscallarg(int) sz;
+ 	} */ *uap = v;
+ 	struct sys_flock_args fl;
+ 
+ 	SCARG(&fl, fd) = SCARG(uap, fd);
+ 	switch SCARG(uap, blk) {
+ 	case X_LK_UNLCK: SCARG(&fl, how)=LOCK_UN; break;
+ 	case X_LK_NBLCK: SCARG(&fl, how)=LOCK_NB|LOCK_EX; break;
+ 	case X_LK_NBRLCK: SCARG(&fl, how)=LOCK_NB|LOCK_SH; break;
+ 	case X_LK_LOCK: SCARG(&fl, how)=LOCK_EX; break;
+ 	case X_LK_SETLKW: SCARG(&fl, how)=LOCK_EX; break;
+ 	default: return EINVAL;
+ 	}
+ 
+ 	return sys_flock(p, &fl, retval);
+ }
  
  int
  ibcs2_sys_sysi86(p, v, retval)
*** ibcs2_stat.c.orig	Tue Oct 21 04:17:51 1997
--- ibcs2_stat.c	Thu Feb  5 16:52:11 1998
***************
*** 268,277 ****
  		return copyout((caddr_t)&sut, (caddr_t)SCARG(uap, a1),
  			       ibcs2_utsname_len);
  	}
- 
  	case 2:			/* ustat(2) */
  	{
! 		return ENOSYS;	/* XXX - TODO */
  	}
  
  	default:
--- 268,283 ----
  		return copyout((caddr_t)&sut, (caddr_t)SCARG(uap, a1),
  			       ibcs2_utsname_len);
  	}
  	case 2:			/* ustat(2) */
  	{
! 	/* XXX temporary return values */
! 		struct ibcs2_ustat xu;
! 		xu.f_tfree=60000;
! 		xu.f_tinode=32000;
! 		xu.f_fname[0]=0;
! 		xu.f_fpack[0]=0;
! 		return copyout((caddr_t)&xu, (caddr_t)SCARG(uap,a1),
! 				ibcs2_ustat_len);
  	}
  
  	default:

-- 
Andreas Wrede              Planix, Inc.
andreas@planix.com         Networking, System Administration, Consulting
http://www.planix.com      Toronto, Ontario, Canada