Module Name: src
Committed By: christos
Date: Sun May 12 17:26:51 UTC 2024
Modified Files:
src/sys/miscfs/procfs: procfs.h procfs_linux.c procfs_subr.c
procfs_vfsops.c procfs_vnops.c
Log Message:
PR/58227: Ricardo Branco: Add support for proc/sysvipc in Linux emulator
To generate a diff of this commit:
cvs rdiff -u -r1.85 -r1.86 src/sys/miscfs/procfs/procfs.h
cvs rdiff -u -r1.87 -r1.88 src/sys/miscfs/procfs/procfs_linux.c
cvs rdiff -u -r1.118 -r1.119 src/sys/miscfs/procfs/procfs_subr.c
cvs rdiff -u -r1.115 -r1.116 src/sys/miscfs/procfs/procfs_vfsops.c
cvs rdiff -u -r1.231 -r1.232 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.85 src/sys/miscfs/procfs/procfs.h:1.86
--- src/sys/miscfs/procfs/procfs.h:1.85 Sun May 12 13:22:29 2024
+++ src/sys/miscfs/procfs/procfs.h Sun May 12 13:26:50 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: procfs.h,v 1.85 2024/05/12 17:22:29 christos Exp $ */
+/* $NetBSD: procfs.h,v 1.86 2024/05/12 17:26:50 christos Exp $ */
/*
* Copyright (c) 1993
@@ -112,7 +112,11 @@ typedef enum {
PFSstat, /* process status (if -o linux) */
PFSstatm, /* process memory info (if -o linux) */
PFSstatus, /* process status */
- PFStask, /* task subdirector (if -o linux) */
+ PFSsysvipc, /* sysvipc subdirectory (if -o linux) */
+ PFSsysvipc_msg, /* sysvipc msg info (if -o linux) */
+ PFSsysvipc_sem, /* sysvipc sem info (if -o linux) */
+ PFSsysvipc_shm, /* sysvipc shm info (if -o linux) */
+ PFStask, /* task subdirectory (if -o linux) */
PFSuptime, /* elapsed time since (if -o linux) */
PFSversion, /* kernel version (if -o linux) */
#ifdef __HAVE_PROCFS_MACHDEP
@@ -272,6 +276,12 @@ int procfs_dolimit(struct lwp *, struct
struct uio *);
int procfs_dolimits(struct lwp *, struct proc *, struct pfsnode *,
struct uio *);
+int procfs_dosysvipc_msg(struct lwp *, struct proc *, struct pfsnode *,
+ struct uio *);
+int procfs_dosysvipc_sem(struct lwp *, struct proc *, struct pfsnode *,
+ struct uio *);
+int procfs_dosysvipc_shm(struct lwp *, struct proc *, struct pfsnode *,
+ struct uio *);
void procfs_hashrem(struct pfsnode *);
int procfs_getfp(struct pfsnode *, struct proc *, struct file **);
Index: src/sys/miscfs/procfs/procfs_linux.c
diff -u src/sys/miscfs/procfs/procfs_linux.c:1.87 src/sys/miscfs/procfs/procfs_linux.c:1.88
--- src/sys/miscfs/procfs/procfs_linux.c:1.87 Sat Sep 5 12:30:12 2020
+++ src/sys/miscfs/procfs/procfs_linux.c Sun May 12 13:26:50 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: procfs_linux.c,v 1.87 2020/09/05 16:30:12 riastradh Exp $ */
+/* $NetBSD: procfs_linux.c,v 1.88 2024/05/12 17:26:50 christos Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@@ -36,7 +36,11 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_linux.c,v 1.87 2020/09/05 16:30:12 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_linux.c,v 1.88 2024/05/12 17:26:50 christos Exp $");
+
+#if defined(_KERNEL_OPT)
+#include "opt_sysv.h"
+#endif
#include <sys/param.h>
#include <sys/systm.h>
@@ -58,6 +62,15 @@ __KERNEL_RCSID(0, "$NetBSD: procfs_linux
#include <sys/sysctl.h>
#include <sys/kauth.h>
#include <sys/filedesc.h>
+#ifdef SYSVMSG
+#include <sys/msg.h>
+#endif
+#ifdef SYSVSEM
+#include <sys/sem.h>
+#endif
+#ifdef SYSVSHM
+#include <sys/shm.h>
+#endif
#include <miscfs/procfs/procfs.h>
@@ -746,3 +759,141 @@ out:
sysctl_unlock();
return error;
}
+
+int
+procfs_dosysvipc_msg(struct lwp *curl, struct proc *p,
+ struct pfsnode *pfs, struct uio *uio)
+{
+ char *bf;
+ int offset = 0;
+ int error = EFBIG;
+
+ bf = malloc(LBFSZ, M_TEMP, M_WAITOK);
+
+ offset += snprintf(bf, LBFSZ,
+ "%10s %10s %4s %10s %10s %5s %5s %5s %5s %5s %5s %10s %10s %10s\n",
+ "key", "msqid", "perms", "cbytes", "qnum", "lspid", "lrpid",
+ "uid", "gid", "cuid", "cgid", "stime", "rtime", "ctime");
+ if (offset >= LBFSZ)
+ goto out;
+
+#ifdef SYSVMSG
+ for (int id = 0; id < msginfo.msgmni; id++)
+ if (msqs[id].msq_u.msg_qbytes > 0) {
+ offset += snprintf(&bf[offset], LBFSZ - offset,
+ "%10d %10d %4o %10zu %10lu %5u %5u %5u %5u %5u %5u %10lld %10lld %10lld\n",
+ (int) msqs[id].msq_u.msg_perm._key,
+ IXSEQ_TO_IPCID(id, msqs[id].msq_u.msg_perm),
+ msqs[id].msq_u.msg_perm.mode,
+ msqs[id].msq_u._msg_cbytes,
+ msqs[id].msq_u.msg_qnum,
+ msqs[id].msq_u.msg_lspid,
+ msqs[id].msq_u.msg_lrpid,
+ msqs[id].msq_u.msg_perm.uid,
+ msqs[id].msq_u.msg_perm.gid,
+ msqs[id].msq_u.msg_perm.cuid,
+ msqs[id].msq_u.msg_perm.cgid,
+ (long long)msqs[id].msq_u.msg_stime,
+ (long long)msqs[id].msq_u.msg_rtime,
+ (long long)msqs[id].msq_u.msg_ctime);
+ if (offset >= LBFSZ)
+ goto out;
+ }
+#endif
+
+ error = uiomove_frombuf(bf, offset, uio);
+out:
+ free(bf, M_TEMP);
+ return error;
+}
+
+int
+procfs_dosysvipc_sem(struct lwp *curl, struct proc *p,
+ struct pfsnode *pfs, struct uio *uio)
+{
+ char *bf;
+ int offset = 0;
+ int error = EFBIG;
+
+ bf = malloc(LBFSZ, M_TEMP, M_WAITOK);
+
+ offset += snprintf(bf, LBFSZ,
+ "%10s %10s %4s %10s %5s %5s %5s %5s %10s %10s\n",
+ "key", "semid", "perms", "nsems", "uid", "gid", "cuid", "cgid",
+ "otime", "ctime");
+ if (offset >= LBFSZ)
+ goto out;
+
+#ifdef SYSVSEM
+ for (int id = 0; id < seminfo.semmni; id++)
+ if ((sema[id].sem_perm.mode & SEM_ALLOC) != 0) {
+ offset += snprintf(&bf[offset], LBFSZ - offset,
+ "%10d %10d %4o %10u %5u %5u %5u %5u %10lld %10lld\n",
+ (int) sema[id].sem_perm._key,
+ IXSEQ_TO_IPCID(id, sema[id].sem_perm),
+ sema[id].sem_perm.mode,
+ sema[id].sem_nsems,
+ sema[id].sem_perm.uid,
+ sema[id].sem_perm.gid,
+ sema[id].sem_perm.cuid,
+ sema[id].sem_perm.cgid,
+ (long long)sema[id].sem_otime,
+ (long long)sema[id].sem_ctime);
+ if (offset >= LBFSZ)
+ goto out;
+ }
+#endif
+
+ error = uiomove_frombuf(bf, offset, uio);
+out:
+ free(bf, M_TEMP);
+ return error;
+}
+
+int
+procfs_dosysvipc_shm(struct lwp *curl, struct proc *p,
+ struct pfsnode *pfs, struct uio *uio)
+{
+ char *bf;
+ int offset = 0;
+ int error = EFBIG;
+
+ bf = malloc(LBFSZ, M_TEMP, M_WAITOK);
+
+ offset += snprintf(bf, LBFSZ,
+ "%10s %10s %s %21s %5s %5s %5s %5s %5s %5s %5s %10s %10s %10s %21s %21s\n",
+ "key", "shmid", "perms", "size", "cpid", "lpid", "nattch", "uid",
+ "gid", "cuid", "cgid", "atime", "dtime", "ctime", "rss", "swap");
+ if (offset >= LBFSZ)
+ goto out;
+
+#ifdef SYSVSHM
+ for (unsigned int id = 0; id < shminfo.shmmni; id++)
+ if ((shmsegs[id].shm_perm.mode & SHMSEG_ALLOCATED) != 0) {
+ offset += snprintf(&bf[offset], LBFSZ - offset,
+ "%10d %10d %4o %21zu %5u %5u %5u %5u %5u %5u %5u %10lld %10lld %10lld %21d %21d\n",
+ (int) shmsegs[id].shm_perm._key,
+ IXSEQ_TO_IPCID(id, shmsegs[id].shm_perm),
+ shmsegs[id].shm_perm.mode,
+ shmsegs[id].shm_segsz,
+ shmsegs[id].shm_cpid,
+ shmsegs[id].shm_lpid,
+ shmsegs[id].shm_nattch,
+ shmsegs[id].shm_perm.uid,
+ shmsegs[id].shm_perm.gid,
+ shmsegs[id].shm_perm.cuid,
+ shmsegs[id].shm_perm.cgid,
+ (long long)shmsegs[id].shm_atime,
+ (long long)shmsegs[id].shm_dtime,
+ (long long)shmsegs[id].shm_ctime,
+ 0, 0); /* XXX rss & swp are not supported */
+ if (offset >= LBFSZ)
+ goto out;
+ }
+#endif
+
+ error = uiomove_frombuf(bf, offset, uio);
+out:
+ free(bf, M_TEMP);
+ return error;
+}
Index: src/sys/miscfs/procfs/procfs_subr.c
diff -u src/sys/miscfs/procfs/procfs_subr.c:1.118 src/sys/miscfs/procfs/procfs_subr.c:1.119
--- src/sys/miscfs/procfs/procfs_subr.c:1.118 Sun May 12 13:22:29 2024
+++ src/sys/miscfs/procfs/procfs_subr.c Sun May 12 13:26:50 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: procfs_subr.c,v 1.118 2024/05/12 17:22:29 christos Exp $ */
+/* $NetBSD: procfs_subr.c,v 1.119 2024/05/12 17:26:50 christos Exp $ */
/*-
* Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -102,7 +102,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.118 2024/05/12 17:22:29 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.119 2024/05/12 17:26:50 christos Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -287,6 +287,18 @@ procfs_rw(void *v)
error = procfs_doauxv(curl, p, pfs, uio);
break;
+ case PFSsysvipc_msg:
+ error = procfs_dosysvipc_msg(curl, p, pfs, uio);
+ break;
+
+ case PFSsysvipc_sem:
+ error = procfs_dosysvipc_sem(curl, p, pfs, uio);
+ break;
+
+ case PFSsysvipc_shm:
+ error = procfs_dosysvipc_shm(curl, p, pfs, uio);
+ break;
+
#ifdef __HAVE_PROCFS_MACHDEP
PROCFS_MACHDEP_NODETYPE_CASES
error = procfs_machdep_rw(curl, l, pfs, uio);
Index: src/sys/miscfs/procfs/procfs_vfsops.c
diff -u src/sys/miscfs/procfs/procfs_vfsops.c:1.115 src/sys/miscfs/procfs/procfs_vfsops.c:1.116
--- src/sys/miscfs/procfs/procfs_vfsops.c:1.115 Sun May 12 13:22:29 2024
+++ src/sys/miscfs/procfs/procfs_vfsops.c Sun May 12 13:26:50 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: procfs_vfsops.c,v 1.115 2024/05/12 17:22:29 christos Exp $ */
+/* $NetBSD: procfs_vfsops.c,v 1.116 2024/05/12 17:26:50 christos Exp $ */
/*
* Copyright (c) 1993
@@ -76,7 +76,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.115 2024/05/12 17:22:29 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.116 2024/05/12 17:26:50 christos Exp $");
#if defined(_KERNEL_OPT)
#include "opt_compat_netbsd.h"
@@ -437,6 +437,21 @@ procfs_loadvnode(struct mount *mp, struc
vp->v_type = VREG;
break;
+ case PFSsysvipc:/* /proc/sysvipc = dr-xr-xr-x */
+ if (pfs->pfs_fd == -1) {
+ pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|
+ S_IROTH|S_IXOTH;
+ vp->v_type = VDIR;
+ break;
+ }
+ /*FALLTHROUGH*/
+ case PFSsysvipc_msg: /* /proc/sysvipc/msg = -r--r--r-- */
+ case PFSsysvipc_sem: /* /proc/sysvipc/sem = -r--r--r-- */
+ case PFSsysvipc_shm: /* /proc/sysvipc/shm = -r--r--r-- */
+ pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH;
+ vp->v_type = VREG;
+ break;
+
#ifdef __HAVE_PROCFS_MACHDEP
PROCFS_MACHDEP_NODETYPE_CASES
procfs_machdep_allocvp(vp);
Index: src/sys/miscfs/procfs/procfs_vnops.c
diff -u src/sys/miscfs/procfs/procfs_vnops.c:1.231 src/sys/miscfs/procfs/procfs_vnops.c:1.232
--- src/sys/miscfs/procfs/procfs_vnops.c:1.231 Sun May 12 13:22:29 2024
+++ src/sys/miscfs/procfs/procfs_vnops.c Sun May 12 13:26:51 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: procfs_vnops.c,v 1.231 2024/05/12 17:22:29 christos Exp $ */
+/* $NetBSD: procfs_vnops.c,v 1.232 2024/05/12 17:26:51 christos 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.231 2024/05/12 17:22:29 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.232 2024/05/12 17:26:51 christos Exp $");
#include <sys/param.h>
#include <sys/atomic.h>
@@ -203,11 +203,28 @@ static const struct proc_target proc_roo
{ DT_REG, N("stat"), PFScpustat, procfs_validfile_linux },
{ DT_REG, N("loadavg"), PFSloadavg, procfs_validfile_linux },
{ DT_REG, N("version"), PFSversion, procfs_validfile_linux },
+ { DT_DIR, N("sysvipc"), PFSsysvipc, procfs_validfile_linux },
#undef N
};
static const int nproc_root_targets =
sizeof(proc_root_targets) / sizeof(proc_root_targets[0]);
+/*
+ * List of files in the sysvipc directory
+ */
+static const struct proc_target proc_sysvipc_targets[] = {
+#define N(s) sizeof(s)-1, s
+ /* name type validp */
+ { DT_DIR, N("."), PFSsysvipc, NULL },
+ { DT_DIR, N(".."), PFSroot, NULL },
+ { DT_REG, N("msg"), PFSsysvipc_msg, procfs_validfile_linux },
+ { DT_REG, N("sem"), PFSsysvipc_sem, procfs_validfile_linux },
+ { DT_REG, N("shm"), PFSsysvipc_shm, procfs_validfile_linux },
+#undef N
+};
+static const int nproc_sysvipc_targets =
+ sizeof(proc_sysvipc_targets) / sizeof(proc_sysvipc_targets[0]);
+
int procfs_lookup(void *);
int procfs_open(void *);
int procfs_close(void *);
@@ -725,10 +742,18 @@ procfs_getattr(void *v)
case PFSself:
case PFScurproc:
case PFSroot:
+ case PFSsysvipc_msg:
+ case PFSsysvipc_sem:
+ case PFSsysvipc_shm:
vap->va_nlink = 1;
vap->va_uid = vap->va_gid = 0;
break;
+ case PFSsysvipc:
+ vap->va_nlink = 5;
+ vap->va_uid = vap->va_gid = 0;
+ break;
+
case PFSproc:
case PFStask:
case PFSfile:
@@ -843,6 +868,10 @@ procfs_getattr(void *v)
case PFSloadavg:
case PFSstatm:
case PFSversion:
+ case PFSsysvipc:
+ case PFSsysvipc_msg:
+ case PFSsysvipc_sem:
+ case PFSsysvipc_shm:
vap->va_bytes = vap->va_size = 0;
break;
case PFSlimit:
@@ -1159,6 +1188,34 @@ procfs_lookup(void *v)
procfs_proc_unlock(p);
return error;
}
+ case PFSsysvipc:
+ if (cnp->cn_flags & ISDOTDOT) {
+ error = procfs_allocvp(dvp->v_mount, vpp, 0, PFSroot,
+ -1);
+ return (error);
+ }
+
+ for (i = 0; i < nproc_sysvipc_targets; i++) {
+ pt = &proc_sysvipc_targets[i];
+ /*
+ * check for node match. proc is always NULL here,
+ * so call pt_valid with constant NULL lwp.
+ */
+ if (cnp->cn_namelen == pt->pt_namlen &&
+ memcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 &&
+ (pt->pt_valid == NULL ||
+ (*pt->pt_valid)(NULL, dvp->v_mount)))
+ break;
+ }
+
+ if (i != nproc_sysvipc_targets) {
+ error = procfs_allocvp(dvp->v_mount, vpp, 0,
+ pt->pt_pfstype, -1);
+ return (error);
+ }
+
+ return (ENOENT);
+
default:
return (ENOTDIR);
}
@@ -1445,6 +1502,40 @@ procfs_readdir(void *v)
}
/*
+ * sysvipc subdirectory
+ */
+ case PFSsysvipc: {
+ if ((error = procfs_proc_lock(vp->v_mount, pfs->pfs_pid, &p,
+ ESRCH)) != 0)
+ return error;
+ if (ap->a_ncookies) {
+ ncookies = uimin(ncookies, (nproc_sysvipc_targets - i));
+ cookies = malloc(ncookies * sizeof (off_t),
+ M_TEMP, M_WAITOK);
+ *ap->a_cookies = cookies;
+ }
+
+ for (pt = &proc_sysvipc_targets[i];
+ uio->uio_resid >= UIO_MX && i < nproc_sysvipc_targets; pt++, i++) {
+ if (pt->pt_valid &&
+ (*pt->pt_valid)(NULL, vp->v_mount) == 0)
+ continue;
+ d.d_fileno = PROCFS_FILENO(pfs->pfs_pid,
+ pt->pt_pfstype, -1);
+ d.d_namlen = pt->pt_namlen;
+ memcpy(d.d_name, pt->pt_name, pt->pt_namlen + 1);
+ d.d_type = pt->pt_type;
+
+ if ((error = uiomove(&d, UIO_MX, uio)) != 0)
+ break;
+ if (cookies)
+ *cookies++ = i + 1;
+ }
+
+ goto out;
+ }
+
+ /*
* this is for the root of the procfs filesystem
* what is needed are special entries for "curproc"
* and "self" followed by an entry for each process