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;
}