Module Name:    src
Committed By:   christos
Date:           Sun May 12 17:22:29 UTC 2024

Modified Files:
        src/sys/miscfs/procfs: procfs.h procfs_limit.c procfs_subr.c
            procfs_vfsops.c procfs_vnops.c

Log Message:
PR/58240: Ricardo Branco: Add support for proc/self/limits as used by Linux


To generate a diff of this commit:
cvs rdiff -u -r1.84 -r1.85 src/sys/miscfs/procfs/procfs.h
cvs rdiff -u -r1.4 -r1.5 src/sys/miscfs/procfs/procfs_limit.c
cvs rdiff -u -r1.117 -r1.118 src/sys/miscfs/procfs/procfs_subr.c
cvs rdiff -u -r1.114 -r1.115 src/sys/miscfs/procfs/procfs_vfsops.c
cvs rdiff -u -r1.230 -r1.231 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.84 src/sys/miscfs/procfs/procfs.h:1.85
--- src/sys/miscfs/procfs/procfs.h:1.84	Wed Jan 17 05:20:12 2024
+++ src/sys/miscfs/procfs/procfs.h	Sun May 12 13:22:29 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs.h,v 1.84 2024/01/17 10:20:12 hannken Exp $	*/
+/*	$NetBSD: procfs.h,v 1.85 2024/05/12 17:22:29 christos Exp $	*/
 
 /*
  * Copyright (c) 1993
@@ -97,6 +97,7 @@ typedef enum {
 	PFSfpregs,	/* the process's FP register set */
 	PFSloadavg,	/* load average (if -o linux) */
 	PFSlimit,	/* resource limits */
+	PFSlimits,	/* resource limits, Linux style (if -o linux) */
 	PFSmap,		/* memory map */
 	PFSmaps,	/* memory map, Linux style (if -o linux) */
 	PFSmem,		/* the process's memory image */
@@ -269,6 +270,8 @@ int procfs_doauxv(struct lwp *, struct p
     struct uio *);
 int procfs_dolimit(struct lwp *, struct proc *, struct pfsnode *,
     struct uio *);
+int procfs_dolimits(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_limit.c
diff -u src/sys/miscfs/procfs/procfs_limit.c:1.4 src/sys/miscfs/procfs/procfs_limit.c:1.5
--- src/sys/miscfs/procfs/procfs_limit.c:1.4	Sat May 23 19:42:43 2020
+++ src/sys/miscfs/procfs/procfs_limit.c	Sun May 12 13:22:29 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs_limit.c,v 1.4 2020/05/23 23:42:43 ad Exp $	*/
+/*	$NetBSD: procfs_limit.c,v 1.5 2024/05/12 17:22:29 christos Exp $	*/
 
 /*-
  * Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,11 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_limit.c,v 1.4 2020/05/23 23:42:43 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_limit.c,v 1.5 2024/05/12 17:22:29 christos Exp $");
+
+#if defined(_KERNEL_OPT)
+#include "opt_sysv.h"
+#endif
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -38,8 +42,35 @@ __KERNEL_RCSID(0, "$NetBSD: procfs_limit
 #include <sys/malloc.h>
 #include <sys/resource.h>
 #include <miscfs/procfs/procfs.h>
-
-#define MAXBUFFERSIZE (256 * 1024)
+#include <compat/linux/common/linux_misc.h>
+#ifdef SYSVMSG
+#include <sys/msg.h>
+#endif
+
+/* Taken from FreeBSD sys/compat/linprocfs/linprocfs.c */
+static const struct linux_rlimit_ident {
+	const char      *desc;
+	const char      *unit;
+	unsigned int    rlim_id;
+} linux_rlimits_ident[] = {
+	{ "Max cpu time",	"seconds",	RLIMIT_CPU },
+	{ "Max file size",	"bytes",	RLIMIT_FSIZE },
+	{ "Max data size",	"bytes",	RLIMIT_DATA },
+	{ "Max stack size",	"bytes",	RLIMIT_STACK },
+	{ "Max core file size",	"bytes",	RLIMIT_CORE },
+	{ "Max resident set",	"bytes",	RLIMIT_RSS },
+	{ "Max processes",	"processes",	RLIMIT_NPROC },
+	{ "Max open files",	"files",	RLIMIT_NOFILE },
+	{ "Max locked memory",	"bytes",	RLIMIT_MEMLOCK },
+	{ "Max address space",	"bytes",	RLIMIT_AS },
+	{ "Max file locks",	"locks",	LINUX_RLIMIT_LOCKS },
+	{ "Max pending signals", "signals",	LINUX_RLIMIT_SIGPENDING },
+	{ "Max msgqueue size",	"bytes",	LINUX_RLIMIT_MSGQUEUE },
+	{ "Max nice priority",	"",		LINUX_RLIMIT_NICE },
+	{ "Max realtime priority", "",		LINUX_RLIMIT_RTPRIO },
+	{ "Max realtime timeout", "us",		LINUX_RLIMIT_RTTIME },
+	{ 0, 0, 0 }
+};
 
 static size_t
 prl(char *buf, size_t len, intmax_t lim, char sep)
@@ -92,3 +123,72 @@ procfs_dolimit(struct lwp *curl, struct 
 
 	return error;
 }
+
+int
+procfs_dolimits(struct lwp *curl, struct proc *p, struct pfsnode *pfs,
+     struct uio *uio)
+{
+	const struct linux_rlimit_ident *li;
+	int error;
+	char *buffer;
+	size_t bufsize, pos;
+	struct rlimit rl, rlimits[RLIM_NLIMITS];
+
+	if (uio->uio_rw != UIO_READ)
+		return EOPNOTSUPP;
+
+	mutex_enter(&proc_lock);
+	mutex_enter(p->p_lock);
+	memcpy(rlimits, p->p_rlimit, sizeof(rlimits));
+	mutex_exit(p->p_lock);
+	mutex_exit(&proc_lock);
+
+	error = 0;
+
+	bufsize = (64 * 3) * __arraycount(linux_rlimits_ident);
+	buffer = malloc(bufsize, M_TEMP, M_WAITOK);
+	pos = snprintf(buffer, bufsize, "%-26s%-21s%-21s%-21s\n",
+	    "Limit", "Soft Limit", "Hard Limit", "Units");
+	for (li = linux_rlimits_ident; li->desc != NULL; ++li) {
+		switch (li->rlim_id)
+		{
+		case LINUX_RLIMIT_LOCKS:
+		case LINUX_RLIMIT_RTTIME:
+		case LINUX_RLIMIT_SIGPENDING:
+			rl.rlim_cur = RLIM_INFINITY;
+			break;
+		case LINUX_RLIMIT_MSGQUEUE:
+#ifdef SYSVMSG
+			rl.rlim_cur = rl.rlim_max = msginfo.msgmnb;
+			break;
+#endif
+		case LINUX_RLIMIT_NICE:
+		case LINUX_RLIMIT_RTPRIO:
+			rl.rlim_cur = rl.rlim_max = 0;
+			break;
+		default:
+			rl = rlimits[li->rlim_id];
+			break;
+		}
+		if (rl.rlim_cur == RLIM_INFINITY)
+			pos += snprintf(buffer + pos, bufsize - pos,
+			    "%-26s%-21s%-21s%-10s\n",
+			    li->desc, "unlimited", "unlimited", li->unit);
+		else
+			pos += snprintf(buffer + pos, bufsize - pos,
+			    "%-26s%-21llu%-21llu%-10s\n",
+			    li->desc, (unsigned long long)rl.rlim_cur,
+			    (unsigned long long)rl.rlim_max, li->unit);
+	}
+
+	if ((uintmax_t)uio->uio_offset < pos)
+		error = uiomove(buffer + uio->uio_offset,
+		    pos - uio->uio_offset, uio);
+	else
+		error = 0;
+
+	if (buffer != NULL)
+		free(buffer, M_TEMP);
+
+	return error;
+}

Index: src/sys/miscfs/procfs/procfs_subr.c
diff -u src/sys/miscfs/procfs/procfs_subr.c:1.117 src/sys/miscfs/procfs/procfs_subr.c:1.118
--- src/sys/miscfs/procfs/procfs_subr.c:1.117	Wed Jan 17 05:20:12 2024
+++ src/sys/miscfs/procfs/procfs_subr.c	Sun May 12 13:22:29 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs_subr.c,v 1.117 2024/01/17 10:20:12 hannken Exp $	*/
+/*	$NetBSD: procfs_subr.c,v 1.118 2024/05/12 17:22:29 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.117 2024/01/17 10:20:12 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.118 2024/05/12 17:22:29 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -215,6 +215,10 @@ procfs_rw(void *v)
 		error = procfs_dolimit(curl, p, pfs, uio);
 		break;
 
+	case PFSlimits:
+		error = procfs_dolimits(curl, p, pfs, uio);
+		break;
+
 	case PFSmap:
 		error = procfs_domap(curl, p, pfs, uio, 0);
 		break;

Index: src/sys/miscfs/procfs/procfs_vfsops.c
diff -u src/sys/miscfs/procfs/procfs_vfsops.c:1.114 src/sys/miscfs/procfs/procfs_vfsops.c:1.115
--- src/sys/miscfs/procfs/procfs_vfsops.c:1.114	Wed Jan 17 05:21:01 2024
+++ src/sys/miscfs/procfs/procfs_vfsops.c	Sun May 12 13:22:29 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs_vfsops.c,v 1.114 2024/01/17 10:21:01 hannken Exp $	*/
+/*	$NetBSD: procfs_vfsops.c,v 1.115 2024/05/12 17:22:29 christos Exp $	*/
 
 /*
  * Copyright (c) 1993
@@ -76,7 +76,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.114 2024/01/17 10:21:01 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.115 2024/05/12 17:22:29 christos Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -431,7 +431,8 @@ procfs_loadvnode(struct mount *mp, struc
 	case PFSloadavg:	/* /proc/loadavg = -r--r--r-- */
 	case PFSstatm:		/* /proc/N/statm = -r--r--r-- */
 	case PFSversion:	/* /proc/version = -r--r--r-- */
-	case PFSlimit:		/* /proc/limit = -r--r--r-- */
+	case PFSlimit:		/* /proc/N/limit = -r--r--r-- */
+	case PFSlimits:		/* /proc/N/limits = -r--r--r-- */
 		pfs->pfs_mode = S_IRUSR|S_IRGRP|S_IROTH;
 		vp->v_type = VREG;
 		break;

Index: src/sys/miscfs/procfs/procfs_vnops.c
diff -u src/sys/miscfs/procfs/procfs_vnops.c:1.230 src/sys/miscfs/procfs/procfs_vnops.c:1.231
--- src/sys/miscfs/procfs/procfs_vnops.c:1.230	Wed Jan 17 05:19:21 2024
+++ src/sys/miscfs/procfs/procfs_vnops.c	Sun May 12 13:22:29 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: procfs_vnops.c,v 1.230 2024/01/17 10:19:21 hannken Exp $	*/
+/*	$NetBSD: procfs_vnops.c,v 1.231 2024/05/12 17:22:29 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.230 2024/01/17 10:19:21 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.231 2024/05/12 17:22:29 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -171,6 +171,7 @@ static const struct proc_target {
 	{ DT_REG, N("file"),	PFSfile,	procfs_validfile },
 	{ DT_REG, N("fpregs"),	PFSfpregs,	procfs_validfpregs },
 	{ DT_REG, N("limit"),	PFSlimit,	NULL },
+	{ DT_REG, N("limits"),	PFSlimits,	procfs_validfile_linux },
 	{ DT_REG, N("map"),	PFSmap,		procfs_validmap },
 	{ DT_REG, N("maps"),	PFSmaps,	procfs_validmap },
 	{ DT_REG, N("mem"),	PFSmem,		NULL },
@@ -704,6 +705,7 @@ procfs_getattr(void *v)
 	case PFSmap:
 	case PFSmaps:
 	case PFSlimit:
+	case PFSlimits:
 	case PFSauxv:
 		vap->va_nlink = 1;
 		vap->va_uid = kauth_cred_geteuid(procp->p_cred);
@@ -844,6 +846,7 @@ procfs_getattr(void *v)
 		vap->va_bytes = vap->va_size = 0;
 		break;
 	case PFSlimit:
+	case PFSlimits:
 	case PFSmap:
 	case PFSmaps:
 		/*

Reply via email to