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