PR/58227: Ricardo Branco: Add support for proc/sysvipc in Linux emulator
This commit is contained in:
parent
25cb9c57ac
commit
87f98fe280
|
@ -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 proc *, struct pfsnode *,
|
|||
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 **);
|
||||
|
|
|
@ -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.c,v 1.87 2020/09/05 16:30:12 riastradh
|
|||
#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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, struct vnode *vp,
|
|||
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);
|
||||
|
|
|
@ -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_root_targets[] = {
|
|||
{ 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);
|
||||
}
|
||||
|
@ -1444,6 +1501,40 @@ procfs_readdir(void *v)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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"
|
||||
|
|
Loading…
Reference in New Issue