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