Subject: Re: patch to make compat_sunos use /emul/sunos.
To: matthew green <mrg@mame.mu.Oz.Au>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: port-sparc
Date: 06/08/1995 14:20:15
On Wed, 07 Jun 1995 22:33:58 +1000 
 matthew green <mrg@mame.mu.OZ.AU> wrote:

Matt, you're too cool for words.  :-)

I just plopped this into the kernel on my SS1, and had to make one teeny 
little addition for sunos_util.c to build -- need to include 
<sys/exec.h>.  No biggie.

However, when running Netscape 1.1N, I was having problems finding the 
XKeysymDB file...ktrace revealed that compat_43_* stuff was being used, 
and it doesn't have any of the namei hacks.  Here's the interesting bits 
from the ktrace:

   255 netscape_dns CALL  compat_43_stat(0x46f8,0xf7ffeef0)
   255 netscape_dns NAMI  "/usr/lib/X11/XKeysymDB"
   255 netscape_dns RET   compat_43_stat -1 errno 2 No such file or directory
   255 netscape_dns CALL  compat_43_stat(0x4710,0xf7ffeef0)
   255 netscape_dns NAMI  "/usr/openwin/lib/XKeysymDB"
   255 netscape_dns RET   compat_43_stat -1 errno 2 No such file or directory
   255 netscape_dns CALL  compat_43_stat(0x4730,0xf7ffeef0)
   255 netscape_dns NAMI  "/usr/openwin/lib/X11/XKeysymDB"
   255 netscape_dns RET   compat_43_stat -1 errno 2 No such file or directory

Specifically, what barfed was compat_43_stat().  I did a
`setenv XKEYSYMDB /emul/sunos/usr/lib/X11/XKeysymDB' and it worked fine.

I guess one could put a wrapper around compat_43_* stuff that uses a 
path, like stat and lstat, and have a sunos_stat and a sunos_lstat (there 
are probably more...Is everyhing that uses a pathname supposed to behave 
this way?  I'm thinking specifically of symlink and execve...) that do 
the path frobbing...

 > the svr4 and linux ports both use /emul/<compat> as an alternative
 > root.  i've just made the sunos compat do the same.  this basically
 > means you can copy /usr/{5,}lib to /emul/sunos/usr/{5,}lib on the
 > netbsd box and have compat_sunos work;  not having to hack ld.so to
 > look in /sun/lib, etc.
 > 
 > i've only got 1 sunos binary that i used to test (screenblank) and
 > this seemed ok, but i'm not entirely sure that everything else will
 > be ok.  please try this and let me know of any problems.
 > 
 > thanks.
 > 
 > .mrg.
 > 
 > Index: src/sys/compat/sunos/files.sunos
 > ===================================================================
 > RCS file: /local/cvs/src/sys/compat/sunos/files.sunos,v
 > retrieving revision 1.1.1.1
 > diff -c -r1.1.1.1 files.sunos
 > *** files.sunos	1995/05/07 16:13:56	1.1.1.1
 > --- files.sunos	1995/06/07 07:39:17
 > ***************
 > *** 10,13 ****
 > --- 10,14 ----
 >   file	compat/sunos/sunos_sysent.c	compat_sunos
 >   file	compat/sunos/sunos_ioctl.c	compat_sunos
 >   file	compat/sunos/sunos_misc.c	compat_sunos
 > + file	compat/sunos/sunos_util.c	compat_sunos
 >   #file	compat/sunos/sunos_syscalls.c	compat_sunos
 > Index: src/sys/compat/sunos/sunos_misc.c
 > ===================================================================
 > RCS file: /local/cvs/src/sys/compat/sunos/sunos_misc.c,v
 > retrieving revision 1.1.1.5
 > diff -c -r1.1.1.5 sunos_misc.c
 > *** sunos_misc.c	1995/05/07 16:13:59	1.1.1.5
 > --- sunos_misc.c	1995/06/07 08:46:35
 > ***************
 > *** 83,88 ****
 > --- 83,89 ----
 >   #include <sys/syscallargs.h>
 >   #include <compat/sunos/sunos.h>
 >   #include <compat/sunos/sunos_syscallargs.h>
 > + #include <compat/sunos/sunos_util.h>
 >   
 >   #include <netinet/in.h>
 >   
 > ***************
 > *** 113,118 ****
 > --- 114,122 ----
 >   {
 >   	struct sunos_open_args ouap;
 >   
 > + 	caddr_t sg = stackgap_init();
 > + 	CHECKALT(p, &sg, SCARG(uap, path));
 > + 
 >   	SCARG(&ouap, path) = SCARG(uap, path);
 >   	SCARG(&ouap, flags) = O_WRONLY | O_CREAT | O_TRUNC;
 >   	SCARG(&ouap, mode) = SCARG(uap, mode);
 > ***************
 > *** 120,125 ****
 > --- 124,141 ----
 >   }
 >   
 >   int
 > + sunos_access(p, uap, retval)
 > + 	struct proc *p;
 > + 	struct sunos_access_args *uap;
 > + 	register_t *retval;
 > + {
 > + 	caddr_t sg = stackgap_init();
 > + 	CHECKALT(p, &sg, SCARG(uap, path));
 > + 
 > + 	return (access(p, uap, retval));
 > + }
 > + 
 > + int
 >   sunos_execv(p, uap, retval)
 >   	struct proc *p;
 >   	struct sunos_execv_args *uap;
 > ***************
 > *** 127,132 ****
 > --- 143,151 ----
 >   {
 >   	struct execve_args ouap;
 >   
 > + 	caddr_t sg = stackgap_init();
 > + 	CHECKALT(p, &sg, SCARG(uap, path));
 > + 
 >   	SCARG(&ouap, path) = SCARG(uap, path);
 >   	SCARG(&ouap, argp) = SCARG(uap, argp);
 >   	SCARG(&ouap, envp) = NULL;
 > ***************
 > *** 165,175 ****
 >   	register_t *retval;
 >   {
 >   	int oflags = SCARG(uap, flags), nflags, error;
 > - 	extern char sigcode[], esigcode[];
 >   	char fsname[MFSNAMELEN];
 >   
 > - #define	szsigcode	(esigcode - sigcode)
 > - 
 >   	if (oflags & (SUNM_NOSUB | SUNM_SYS5))
 >   		return (EINVAL);
 >   	if ((oflags & SUNM_NEWTYPE) == 0)
 > --- 184,191 ----
 > ***************
 > *** 581,586 ****
 > --- 597,605 ----
 >   	int noctty;
 >   	int ret;
 >   	
 > + 	caddr_t sg = stackgap_init();
 > + 	CHECKALT(p, &sg, SCARG(uap, path));
 > + 
 >   	/* convert mode into NetBSD mode */
 >   	l = SCARG(uap, flags);
 >   	noctty = l & 0x8000;
 > ***************
 > *** 707,712 ****
 > --- 726,734 ----
 >   	int error;
 >   	struct nameidata nd;
 >   
 > + 	caddr_t sg = stackgap_init();
 > + 	CHECKALT(p, &sg, SCARG(uap, path));
 > + 
 >   	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
 >   	if (error = namei(&nd))
 >   		return (error);
 > ***************
 > *** 759,764 ****
 > --- 781,789 ----
 >   	struct sunos_mknod_args *uap;
 >   	register_t *retval;
 >   {
 > + 	caddr_t sg = stackgap_init();
 > + 	CHECKALT(p, &sg, SCARG(uap, path));
 > + 
 >   	if (S_ISFIFO(SCARG(uap, mode)))
 >   		return mkfifo(p, uap, retval);
 >   
 > Index: src/sys/compat/sunos/sunos_util.c
 > ===================================================================
 > RCS file: sunos_util.c
 > diff -N sunos_util.c
 > *** /dev/null	Wed Jun  7 21:57:02 1995
 > --- sunos_util.c	Wed Jun  7 22:11:38 1995
 > ***************
 > *** 0 ****
 > --- 1,151 ----
 > + /*	$NetBSD$	*/
 > + 
 > + /*
 > +  * Copyright (c) 1994 Christos Zoulas
 > +  * All rights reserved.
 > +  *
 > +  * Redistribution and use in source and binary forms, with or without
 > +  * modification, are permitted provided that the following conditions
 > +  * are met:
 > +  * 1. Redistributions of source code must retain the above copyright
 > +  *    notice, this list of conditions and the following disclaimer.
 > +  * 2. Redistributions in binary form must reproduce the above copyright
 > +  *    notice, this list of conditions and the following disclaimer in the
 > +  *    documentation and/or other materials provided with the distribution.
 > +  * 3. The name of the author may not be used to endorse or promote products
 > +  *    derived from this software without specific prior written permission
 > +  *
 > +  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 > +  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 > +  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 > +  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 > +  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 > +  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 > +  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 > +  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 > +  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 > +  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 > +  */
 > + 
 > + #include <sys/param.h>
 > + #include <sys/systm.h>
 > + #include <sys/namei.h>
 > + #include <sys/proc.h>
 > + #include <sys/file.h>
 > + #include <sys/stat.h>
 > + #include <sys/filedesc.h>
 > + #include <sys/ioctl.h>
 > + #include <sys/kernel.h>
 > + #include <sys/malloc.h>
 > + #include <sys/vnode.h>
 > + 
 > + #include <compat/sunos/sunos_util.h>
 > + 
 > + const char	sunos_emul_path[] = "/emul/sunos";
 > + 
 > + int
 > + sunos_emul_find(p, sgp, prefix, path, pbuf)
 > + 	struct proc *	p;
 > + 	caddr_t *	sgp;          /* Pointer to stackgap memory */
 > + 	const char *	prefix;
 > + 	char *		path;
 > + 	char ** 	pbuf;
 > + {
 > + 	struct nameidata	 nd;
 > + 	struct nameidata	 ndroot;
 > + 	struct vattr		 vat;
 > + 	struct vattr		 vatroot;
 > + 	int			 error;
 > + 	char			*ptr, *buf;
 > + 	size_t			 sz, len;
 > + 
 > + 	buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
 > + 	*pbuf = path;
 > + 
 > + 	for (ptr = buf; (*ptr = *prefix) != '\0'; ptr++, prefix++)
 > + 		continue;
 > + 
 > + 	sz = MAXPATHLEN - (ptr - buf);
 > + 
 > + 	/* 
 > + 	 * If sgp is not given then the path is already in kernel space
 > + 	 */
 > + 	if (sgp == NULL)
 > + 		error = copystr(path, ptr, sz, &len);
 > + 	else
 > + 		error = copyinstr(path, ptr, sz, &len);
 > + 
 > + 	if (error) {
 > + 		DPRINTF(("copy failed %d\n", error));
 > + 		free(buf, M_TEMP);
 > + 		return error;
 > + 	}
 > + 	DPRINTF(("looking for %s [%d, %d]: ", buf, sz, len));
 > + 
 > + 	if (*ptr != '/') {
 > + 		DPRINTF(("no slash\n"));
 > + 		free(buf, M_TEMP);
 > + 		return EINVAL;
 > + 	}
 > + 
 > + 	NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, p);
 > + 
 > + 	if ((error = namei(&nd)) != 0) {
 > + 		DPRINTF(("not found\n"));
 > + 		free(buf, M_TEMP);
 > + 		return error;
 > + 	}
 > + 
 > + 	/*
 > + 	 * We now compare the vnode of the sunos_root to the one
 > + 	 * vnode asked. If they resolve to be the same, then we
 > + 	 * ignore the match so that the real root gets used.
 > + 	 * This avoids the problem of traversing "../.." to find the
 > + 	 * root directory and never finding it, because "/" resolves
 > + 	 * to the emulation root directory. This is expensive :-(
 > + 	 */
 > + 	/* XXX: prototype should have const here for NDINIT */
 > + 	NDINIT(&ndroot, LOOKUP, FOLLOW, UIO_SYSSPACE, 
 > + 	       (char *) sunos_emul_path, p);
 > + 
 > + 	if ((error = namei(&ndroot)) != 0) {
 > + 		/* Cannot happen! */
 > + 		DPRINTF(("no %s!\n", sunos_emul_path));
 > + 		free(buf, M_TEMP);
 > + 		vrele(nd.ni_vp);
 > + 		return error;
 > + 	}
 > + 
 > + 	if ((error = VOP_GETATTR(nd.ni_vp, &vat, p->p_ucred, p)) != 0) {
 > + 		DPRINTF(("no attr for directory\n"));
 > + 		goto done;
 > + 	}
 > + 
 > + 	if ((error = VOP_GETATTR(ndroot.ni_vp, &vatroot, p->p_ucred, p)) != 0) {
 > + 		DPRINTF(("no attr for root\n"));
 > + 		goto done;
 > + 	}
 > + 
 > + 	if (vat.va_fsid == vatroot.va_fsid &&
 > + 	    vat.va_fileid == vatroot.va_fileid) {
 > + 		DPRINTF(("return the real root\n"));
 > + 		error = ENOENT;
 > + 		goto done;
 > + 	}
 > + 
 > + 	if (sgp == NULL)
 > + 		*pbuf = buf;
 > + 	else {
 > + 		sz = &ptr[len] - buf;
 > + 		*pbuf = stackgap_alloc(sgp, sz + 1);
 > + 		error = copyout(buf, *pbuf, sz);
 > + 		free(buf, M_TEMP);
 > + 	}
 > + 
 > + 	DPRINTF(("ok\n"));
 > + 
 > + done:
 > + 	vrele(nd.ni_vp);
 > + 	vrele(ndroot.ni_vp);
 > + 	return error;
 > + }
 > Index: src/sys/compat/sunos/sunos_util.h
 > ===================================================================
 > RCS file: sunos_util.h
 > diff -N sunos_util.h
 > *** /dev/null	Wed Jun  7 21:57:02 1995
 > --- sunos_util.h	Wed Jun  7 18:13:10 1995
 > ***************
 > *** 0 ****
 > --- 1,71 ----
 > + /*	$NetBSD$	*/
 > + 
 > + /*
 > +  * Copyright (c) 1994 Christos Zoulas
 > +  * Copyright (c) 1995 Matthew Green
 > +  * All rights reserved.
 > +  *
 > +  * Redistribution and use in source and binary forms, with or without
 > +  * modification, are permitted provided that the following conditions
 > +  * are met:
 > +  * 1. Redistributions of source code must retain the above copyright
 > +  *    notice, this list of conditions and the following disclaimer.
 > +  * 2. Redistributions in binary form must reproduce the above copyright
 > +  *    notice, this list of conditions and the following disclaimer in the
 > +  *    documentation and/or other materials provided with the distribution.
 > +  * 3. The name of the author may not be used to endorse or promote products
 > +  *    derived from this software without specific prior written permission
 > +  *
 > +  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 > +  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 > +  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 > +  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 > +  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 > +  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 > +  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 > +  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 > +  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 > +  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 > +  */
 > + 
 > + #ifndef	_SUNOS_UTIL_H_
 > + #define	_SUNOS_UTIL_H_
 > + 
 > + #include <machine/vmparam.h>
 > + 
 > + extern	char	sigcode[], esigcode[];
 > + #define szsigcode (esigcode - sigcode)
 > + 
 > + static __inline caddr_t
 > + stackgap_init()
 > + {
 > + 	return STACKGAPBASE;
 > + }
 > + 
 > + 
 > + static __inline void *
 > + stackgap_alloc(sgp, sz)
 > + 	caddr_t *sgp;
 > + 	size_t   sz;
 > + {
 > + 	void    *p = (void *) *sgp;
 > + 	*sgp += ALIGN(sz);
 > + 	return p;
 > + }
 > + 
 > + #ifdef DEBUG_SUNOS
 > + #define DPRINTF(a)	printf a;
 > + #else
 > + #define DPRINTF(a)
 > + #endif
 > + 
 > + extern const char sunos_emul_path[];
 > + extern int sunos_error[];
 > + 
 > + int sunos_emul_find __P((struct proc *, caddr_t *, 
 > + 			const char *, char *, char **));
 > + 
 > + #define CHECKALT(p, sgp, path) \
 > +     sunos_emul_find(p, sgp, sunos_emul_path, path, &(path))
 > + 
 > + #endif /* !_SUNOS_UTIL_H_ */
 > Index: src/sys/compat/sunos/syscalls.master
 > ===================================================================
 > RCS file: /local/cvs/src/sys/compat/sunos/syscalls.master,v
 > retrieving revision 1.1.1.2
 > diff -c -r1.1.1.2 syscalls.master
 > *** syscalls.master	1995/05/07 16:13:52	1.1.1.2
 > --- syscalls.master	1995/06/07 08:42:17
 > ***************
 > *** 74,80 ****
 >   30	UNIMPL		sunos_utime
 >   31	UNIMPL		sunos_stty
 >   32	UNIMPL		sunos_gtty
 > ! 33	NOARGS		{ int access(char *path, int flags); }
 >   34	UNIMPL		sunos_nice
 >   35	UNIMPL		sunos_ftime
 >   36	NOARGS		{ int sync(void); }
 > --- 74,80 ----
 >   30	UNIMPL		sunos_utime
 >   31	UNIMPL		sunos_stty
 >   32	UNIMPL		sunos_gtty
 > ! 33	STD		{ int sunos_access(char *path, int flags); }
 >   34	UNIMPL		sunos_nice
 >   35	UNIMPL		sunos_ftime
 >   36	NOARGS		{ int sync(void); }
 > Index: src/share/man/man8/compat_sunos.8
 > *** compat_sunos.8	Wed Jun  7 22:15:52 1995
 > --- compat_sunos.8	Wed Jun  7 22:27:20 1995
 > ***************
 > *** 38,44 ****
 >   .Nd setup procedure for m68k and sparc architectures
 >   .Sh DESCRIPTION
 >   NetBSD/sparc and some of the NetBSD/m68k architectures can run
 > ! SunOS executables. Most executables will work.
 >   .Pp
 >   The exceptions include programs that use the SunOS kvm library,
 >   and various system calls, ioctl()'s, or kernel semantics
 > --- 38,44 ----
 >   .Nd setup procedure for m68k and sparc architectures
 >   .Sh DESCRIPTION
 >   NetBSD/sparc and some of the NetBSD/m68k architectures can run
 > ! SunOS executables.  Most executables will work.
 >   .Pp
 >   The exceptions include programs that use the SunOS kvm library,
 >   and various system calls, ioctl()'s, or kernel semantics
 > ***************
 > *** 58,93 ****
 >   .It 1.
 >   On your NetBSD machine, do the following:
 >   .nf
 > ! mkdir /sun
 > ! mkdir /sun/lib
 > ! mkdir /sun/5lib
 > ! ln -s /sun/5lib /usr/5lib
 >   .fi
 >   .Pp
 >   .It 2.
 > ! cp
 > ! .Pa SunOS:/usr/lib/lib*.so.*.*
 > ! .Pa NetBSD:/sun/lib
 >   .Pp
 >   .It 3.
 > ! cp
 > ! .Pa SunOS:/usr/5lib/lib*.so.*.*
 > ! .Pa NetBSD:/sun/5lib
 >   .Pp
 >   .It 4.
 > ! cp 
 > ! .Pa SunOS:/usr/lib/ld.so
 > ! .Pa NetBSD:/usr/lib/ld.so
 > ! .Pp
 > ! .It 5.
 > ! On your NetBSD machine, edit the
 > ! .Pa ld.so
 > ! binary using a binary editor.
 > ! In the binary, change every occurance of a path that starts with
 > ! .Pa /usr
 > ! so that it starts with
 > ! .Pa /sun .
 > ! Note that the strings "/usr" and "/sun" are the same length.
 >   .Pp
 >   .It 6.
 >   If you ever expect to use YP, you will want to create a link:
 > --- 58,74 ----
 >   .It 1.
 >   On your NetBSD machine, do the following:
 >   .nf
 > ! mkdir -p /emul/sunos/usr/lib /emul/sunos/usr/5lib
 >   .fi
 >   .Pp
 >   .It 2.
 > ! cp SunOS:/usr/lib/lib*.so.*.* NetBSD:/emul/sunos/usr/lib
 >   .Pp
 >   .It 3.
 > ! cp SunOS:/usr/5lib/lib*.so.*.* NetBSD:/emul/sunos/usr/5lib
 >   .Pp
 >   .It 4.
 > ! cp SunOS:/usr/lib/ld.so NetBSD:/emul/sunos/usr/lib/ld.so
 >   .Pp
 >   .It 6.
 >   If you ever expect to use YP, you will want to create a link:
 > ***************
 > *** 96,105 ****
 >   .fi
 >   .El
 >   .Pp
 >   This will place the SunOS libraries on your NetBSD machine
 > ! in a location where they do not conflict with the standard libraries,
 > ! and also teach the SunOS dynamic linker to search for the SunOS
 > ! dynamic libraries in that place.
 >   .Pp
 >   .Sh BUGS
 >   A list of things which fail to work in compatibility mode should
 > --- 77,97 ----
 >   .fi
 >   .El
 >   .Pp
 > + Alternatively, you can use an NFS mount to accomplish the same
 > + effect.
 > + .Pp
 > + .Bl -tag -width 123 -compact
 > + .It 1.
 > + On your NetBSD machine, do the following:
 > + .nf
 > + mkdir -p /emul/sunos/usr
 > + mount SunOS:/usr /emul/sunos/usr
 > + .fi
 > + .El
 > + .Pp
 >   This will place the SunOS libraries on your NetBSD machine
 > ! in a location where the SunOS compatibility code will look for
 > ! first, where they do not conflict with the standard libraries.
   .Pp
 >   .Sh BUGS
 >   A list of things which fail to work in compatibility mode should

--------------------------------------------------------------------------
Jason R. Thorpe                                       thorpej@nas.nasa.gov
NASA Ames Research Center                               Home: 408.866.1912
NAS: M/S 258-6                                          Work: 415.604.0935
Moffet Field, CA 94035                                 Pager: 415.428.6939