Module Name: src Committed By: bouyer Date: Mon Jan 17 11:20:00 UTC 2022
Modified Files: src/sys/miscfs/procfs: procfs.h procfs_vfsops.c procfs_vnops.c Log Message: If the calling process is running under linux emulation, make /proc/xxx/fd/ return only symlinks pointing to the original file in the filesystem, instead of a hard link. This matches the linux behavior, and some linux programs relies on it (they unconditionally call readlink() on /proc/xxx/fd/yy and don't deal with it returning EINVAL). Proposed on tech-kern@ in http://mail-index.netbsd.org/tech-kern/2022/01/11/msg027877.html To generate a diff of this commit: cvs rdiff -u -r1.80 -r1.81 src/sys/miscfs/procfs/procfs.h cvs rdiff -u -r1.110 -r1.111 src/sys/miscfs/procfs/procfs_vfsops.c cvs rdiff -u -r1.226 -r1.227 src/sys/miscfs/procfs/procfs_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/miscfs/procfs/procfs.h diff -u src/sys/miscfs/procfs/procfs.h:1.80 src/sys/miscfs/procfs/procfs.h:1.81 --- src/sys/miscfs/procfs/procfs.h:1.80 Wed Apr 29 07:18:24 2020 +++ src/sys/miscfs/procfs/procfs.h Mon Jan 17 11:20:00 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: procfs.h,v 1.80 2020/04/29 07:18:24 riastradh Exp $ */ +/* $NetBSD: procfs.h,v 1.81 2022/01/17 11:20:00 bouyer Exp $ */ /* * Copyright (c) 1993 @@ -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: src/sys/miscfs/procfs/procfs_vfsops.c diff -u src/sys/miscfs/procfs/procfs_vfsops.c:1.110 src/sys/miscfs/procfs/procfs_vfsops.c:1.111 --- src/sys/miscfs/procfs/procfs_vfsops.c:1.110 Mon Dec 28 22:36:16 2020 +++ src/sys/miscfs/procfs/procfs_vfsops.c Mon Jan 17 11:20:00 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: procfs_vfsops.c,v 1.110 2020/12/28 22:36:16 riastradh Exp $ */ +/* $NetBSD: procfs_vfsops.c,v 1.111 2022/01/17 11:20:00 bouyer Exp $ */ /* * Copyright (c) 1993 @@ -76,7 +76,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.110 2020/12/28 22:36:16 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.111 2022/01/17 11:20:00 bouyer Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -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: src/sys/miscfs/procfs/procfs_vnops.c diff -u src/sys/miscfs/procfs/procfs_vnops.c:1.226 src/sys/miscfs/procfs/procfs_vnops.c:1.227 --- src/sys/miscfs/procfs/procfs_vnops.c:1.226 Fri Jan 14 23:46:56 2022 +++ src/sys/miscfs/procfs/procfs_vnops.c Mon Jan 17 11:20:00 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: procfs_vnops.c,v 1.226 2022/01/14 23:46:56 christos Exp $ */ +/* $NetBSD: procfs_vnops.c,v 1.227 2022/01/17 11:20:00 bouyer Exp $ */ /*- * Copyright (c) 2006, 2007, 2008, 2020 The NetBSD Foundation, Inc. @@ -105,7 +105,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.226 2022/01/14 23:46:56 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.227 2022/01/17 11:20:00 bouyer Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -1143,7 +1143,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); @@ -1651,7 +1652,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; }