On Fri, Jan 07, 2022 at 03:20:04PM +0100, Manuel Bouyer wrote: > Hello > I'm trying to get a linux binary to run on NetBSD, as stated in this thread > http://mail-index.netbsd.org/current-users/2022/01/06/msg041891.html > > Now I hit an issue where the linux process does a readlink() on a procfs > file and gets EINVAL. > It seems that this is because, on linux all files in /proc/<pid>/fd/ are > symlinks, while on NetBSD they are some kind of hard links. > E.g. on linux: > bip:/dsk/l1/misc/bouyer/HEAD/clean/src>ls -l /proc/$$/fd/ > total 0 > lr-x------ 1 bouyer ita-iatos 64 Jan 7 14:13 0 -> /dev/null > lr-x------ 1 bouyer ita-iatos 64 Jan 7 14:13 1 -> /dev/null > lrwx------ 1 bouyer ita-iatos 64 Jan 7 15:16 15 -> /dev/pts/11 > lrwx------ 1 bouyer ita-iatos 64 Jan 7 14:13 16 -> /dev/pts/11 > lrwx------ 1 bouyer ita-iatos 64 Jan 7 15:16 17 -> /dev/pts/11 > lrwx------ 1 bouyer ita-iatos 64 Jan 7 15:16 18 -> /dev/pts/11 > lrwx------ 1 bouyer ita-iatos 64 Jan 7 15:16 19 -> /dev/pts/11 > lr-x------ 1 bouyer ita-iatos 64 Jan 7 14:13 2 -> /dev/null > > On NetBSD: > armandeche:/local/armandeche1/bouyer>/emul/linux/bin/ls -l /proc/$$/fd/ > total 0 > crw--w---- 1 bouyer tty 3, 13 Jan 7 15:19 15 > crw--w---- 1 bouyer tty 3, 13 Jan 7 15:19 16 > crw--w---- 1 bouyer tty 3, 13 Jan 7 15:19 17 > > Any idea on how to properly fix it ?
The attached diff changes the procfs behavior to match the linux one, for linux processes: comore:/home/bouyer>ls -l /proc/self/fd/ total 1 crw--w---- 1 bouyer tty 5, 0 Jan 11 11:08 0 crw--w---- 1 bouyer tty 5, 0 Jan 11 11:08 1 crw--w---- 1 bouyer tty 5, 0 Jan 11 11:08 2 lr-xr-xr-x 1 bouyer staff 512 Jan 11 11:08 3 -> /home/bouyer ls: /proc/self/fd//4: Invalid argument lr-xr-xr-x 1 bouyer staff 0 Jan 11 11:08 4 comore:/home/bouyer>/emul/linux/bin/ls -l /proc/self/fd/ total 0 lr-xr-xr-x 1 root wheel 0 Jan 11 11:08 0 -> /dev/ttyp0 lr-xr-xr-x 1 root wheel 0 Jan 11 11:08 1 -> /dev/ttyp0 lr-xr-xr-x 1 root wheel 0 Jan 11 11:08 2 -> /dev/ttyp0 lr-xr-xr-x 1 bouyer staff 0 Jan 11 11:08 3 -> / and my linux binaries seems to work properly now would it be OK to commit ? -- Manuel Bouyer <bou...@antioche.eu.org> NetBSD: 26 ans d'experience feront toujours la difference --
Index: sys/miscfs/procfs/procfs.h =================================================================== RCS file: /cvsroot/src/sys/miscfs/procfs/procfs.h,v retrieving revision 1.80 diff -u -p -u -r1.80 procfs.h --- sys/miscfs/procfs/procfs.h 29 Apr 2020 07:18:24 -0000 1.80 +++ sys/miscfs/procfs/procfs.h 11 Jan 2022 10:06:44 -0000 @@ -213,6 +213,14 @@ struct mount; struct proc *procfs_proc_find(struct mount *, pid_t); bool procfs_use_linux_compat(struct mount *); + +static inline bool +procfs_proc_is_linux_compat(void) +{ + const char *emulname = curlwp->l_proc->p_emul->e_name; + return (strncmp(emulname, "linux", 5) == 0); +} + int procfs_proc_lock(struct mount *, int, struct proc **, int); void procfs_proc_unlock(struct proc *); int procfs_allocvp(struct mount *, struct vnode **, pid_t, pfstype, int); Index: sys/miscfs/procfs/procfs_vfsops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/procfs/procfs_vfsops.c,v retrieving revision 1.110 diff -u -p -u -r1.110 procfs_vfsops.c --- sys/miscfs/procfs/procfs_vfsops.c 28 Dec 2020 22:36:16 -0000 1.110 +++ sys/miscfs/procfs/procfs_vfsops.c 11 Jan 2022 10:06:44 -0000 @@ -343,7 +343,8 @@ procfs_loadvnode(struct mount *mp, struc * We make symlinks for directories * to avoid cycles. */ - if (vxp->v_type == VDIR) + if (vxp->v_type == VDIR || + procfs_proc_is_linux_compat()) goto symlink; vp->v_type = vxp->v_type; break; Index: sys/miscfs/procfs/procfs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/miscfs/procfs/procfs_vnops.c,v retrieving revision 1.220 diff -u -p -u -r1.220 procfs_vnops.c --- sys/miscfs/procfs/procfs_vnops.c 8 Dec 2021 20:11:54 -0000 1.220 +++ sys/miscfs/procfs/procfs_vnops.c 11 Jan 2022 10:06:44 -0000 @@ -1142,7 +1142,8 @@ procfs_lookup(void *v) fvp = fp->f_vnode; /* Don't show directories */ - if (fp->f_type == DTYPE_VNODE && fvp->v_type != VDIR) { + if (fp->f_type == DTYPE_VNODE && fvp->v_type != VDIR && + !procfs_proc_is_linux_compat()) { vref(fvp); closef(fp); procfs_proc_unlock(p); @@ -1659,7 +1660,8 @@ procfs_readlink(void *v) switch (fp->f_type) { case DTYPE_VNODE: vxp = fp->f_vnode; - if (vxp->v_type != VDIR) { + if (vxp->v_type != VDIR && + !procfs_proc_is_linux_compat()) { error = EINVAL; break; }