From d37ed5a03a772cb9c9a1d8a53c3181c1b9b71b14 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Fri, 30 Apr 1999 13:04:21 +0000 Subject: [PATCH] Add a new "file" to procfs: "rlimit" which shows the resource limits for the process. PR: 11342 Submitted by: Adrian Chadd adrian@freebsd.org Reviewed by: phk --- share/man/man5/procfs.5 | 12 +- sys/conf/files | 1 + sys/fs/procfs/procfs.h | 6 +- sys/fs/procfs/procfs_rlimit.c | 175 ++++++++++++++++++++++++++++++ sys/fs/procfs/procfs_subr.c | 7 +- sys/fs/procfs/procfs_vnops.c | 4 +- sys/miscfs/procfs/procfs.h | 6 +- sys/miscfs/procfs/procfs_rlimit.c | 175 ++++++++++++++++++++++++++++++ sys/miscfs/procfs/procfs_subr.c | 7 +- sys/miscfs/procfs/procfs_vnops.c | 4 +- sys/sys/resource.h | 21 +++- 11 files changed, 408 insertions(+), 10 deletions(-) create mode 100644 sys/fs/procfs/procfs_rlimit.c create mode 100644 sys/miscfs/procfs/procfs_rlimit.c diff --git a/share/man/man5/procfs.5 b/share/man/man5/procfs.5 index d7010c700fef..b4ffb1eb6ee6 100644 --- a/share/man/man5/procfs.5 +++ b/share/man/man5/procfs.5 @@ -1,4 +1,4 @@ -.\" $Id: procfs.5,v 1.9 1998/03/12 07:30:48 charnier Exp $ +.\" $Id: procfs.5,v 1.10 1998/06/28 21:33:42 hoek Exp $ .\" Written by Garrett Wollman .\" This file is in the public domain. .\" @@ -109,6 +109,12 @@ defined in .Pa . .Pa regs can only be written when the process is stopped. +.It Pa rlimit +This is a read-only file containing the process current and maximum +limits. Each line is of the format +.Ar rlimit current max +, with -1 +indicating infinity. .It Pa status The process status. This file is read-only and returns a single line containing @@ -192,6 +198,8 @@ directory containing process information for process .Pa pid . .It Pa /proc/curproc directory containing process information for the current process +.It Pa /proc/curproc/cmdline +the process executable name .It Pa /proc/curproc/ctl used to send control messages to the process .It Pa /proc/curproc/etype @@ -210,6 +218,8 @@ used for signaling the process used for signaling the process group .It Pa /proc/curproc/regs the process register set +.It Pa /proc/curproc/rlimit +the process current and maximum rlimit .It Pa /proc/curproc/status the process' current status .El diff --git a/sys/conf/files b/sys/conf/files index e06b7b2c28fd..a40d135af0a7 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -370,6 +370,7 @@ miscfs/procfs/procfs_subr.c optional procfs miscfs/procfs/procfs_type.c optional procfs miscfs/procfs/procfs_vfsops.c optional procfs miscfs/procfs/procfs_vnops.c optional procfs +miscfs/procfs/procfs_rlimit.c optional procfs miscfs/specfs/spec_vnops.c standard miscfs/umapfs/umap_subr.c optional umapfs miscfs/umapfs/umap_vfsops.c optional umapfs diff --git a/sys/fs/procfs/procfs.h b/sys/fs/procfs/procfs.h index d9b333bda765..0c2698a77d48 100644 --- a/sys/fs/procfs/procfs.h +++ b/sys/fs/procfs/procfs.h @@ -37,7 +37,7 @@ * @(#)procfs.h 8.9 (Berkeley) 5/14/95 * * From: - * $Id: procfs.h,v 1.22 1999/04/27 11:16:35 phk Exp $ + * $Id: procfs.h,v 1.23 1999/04/28 11:37:18 phk Exp $ */ /* @@ -57,7 +57,8 @@ typedef enum { Pnotepg, /* process group notifier */ Pmap, /* memory map */ Ptype, /* executable type */ - Pcmdline /* command line */ + Pcmdline, /* command line */ + Prlimit /* resource limits */ } pfstype; /* @@ -156,6 +157,7 @@ int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, str int procfs_domap __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); int procfs_dotype __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); int procfs_docmdline __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_dorlimit __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); /* Return 1 if process has special kernel digging privileges */ int procfs_kmemaccess __P((struct proc *)); diff --git a/sys/fs/procfs/procfs_rlimit.c b/sys/fs/procfs/procfs_rlimit.c new file mode 100644 index 000000000000..b211d0bb7e3c --- /dev/null +++ b/sys/fs/procfs/procfs_rlimit.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 1999 Adrian Chadd + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94 + * + * $Id: procfs_status.c,v 1.12 1999/01/05 03:53:06 peter Exp $ + */ + +/* + * To get resource.h to include our rlimit_ident[] array of rlimit identifiers + */ + +#define _RLIMIT_IDENT + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * This converts a quad_t to a string, stored in fin + * It is here because there doesn't exist a quad_t entry in the kernel + * printf() library. + */ + +static void quadtostring (char *fin, quad_t num) +{ + char str[128]; + char *cp; + int i, n; + + cp = str; + i = 0; + + /* + * Create the number string. + * The string will be in reverse from the original number. + */ + + while (num) { + *(cp++) = (num % 10) + '0'; + num /= 10; + i++; + } + + /* Null terminate */ + *cp = '\0'; + + /* + * Now, swap the order + */ + + for (n = 0; n < i; n++) { + fin[n] = str[(i-1)-n]; + } + + /* Null terminate */ + fin[n] = '\0'; + + return; +} + + + +int +procfs_dorlimit(curp, p, pfs, uio) + struct proc *curp; + struct proc *p; + struct pfsnode *pfs; + struct uio *uio; +{ + char *ps; + int i; + int xlen; + int error; + char psbuf[512]; /* XXX - conservative */ + char qstr[64]; + + if (uio->uio_rw != UIO_READ) + return (EOPNOTSUPP); + + + ps = psbuf; + + for (i = 0; i < RLIM_NLIMITS; i++) { + + /* + * Add the rlimit ident + */ + + ps += sprintf(ps, "%s ", rlimit_ident[i]); + + /* + * Replace RLIM_INFINITY with -1 in the string + */ + + /* + * current limit + */ + + if (p->p_rlimit[i].rlim_cur == RLIM_INFINITY) { + ps += sprintf(ps, "-1 "); + } else { + quadtostring(qstr, p->p_rlimit[i].rlim_cur); + ps += sprintf(ps, "%s ", qstr); + } + + /* + * maximum limit + */ + + if (p->p_rlimit[i].rlim_max == RLIM_INFINITY) { + ps += sprintf(ps, "-1\n"); + } else { + quadtostring(qstr, p->p_rlimit[i].rlim_max); + ps += sprintf(ps, "%s\n", qstr); + } + } + + /* + * This logic is rather tasty - but its from procfs_status.c, so + * I guess I'll use it here. + */ + + xlen = ps - psbuf; + xlen -= uio->uio_offset; + ps = psbuf + uio->uio_offset; + xlen = imin(xlen, uio->uio_resid); + if (xlen <= 0) + error = 0; + else + error = uiomove(ps, xlen, uio); + + return (error); +} + diff --git a/sys/fs/procfs/procfs_subr.c b/sys/fs/procfs/procfs_subr.c index 98e36879a4b6..7b5e18c440d5 100644 --- a/sys/fs/procfs/procfs_subr.c +++ b/sys/fs/procfs/procfs_subr.c @@ -36,7 +36,7 @@ * * @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95 * - * $Id: procfs_subr.c,v 1.22 1999/01/05 03:53:06 peter Exp $ + * $Id: procfs_subr.c,v 1.23 1999/01/27 22:42:07 dillon Exp $ */ #include @@ -182,6 +182,7 @@ procfs_allocvp(mp, vpp, pid, pfs_type) case Pmap: case Pstatus: case Pcmdline: + case Prlimit: pfs->pfs_mode = (VREAD) | (VREAD >> 3) | (VREAD >> 6); @@ -287,6 +288,10 @@ procfs_rw(ap) rtval = procfs_docmdline(curp, p, pfs, uio); break; + case Prlimit: + rtval = procfs_dorlimit(curp, p, pfs, uio); + break; + default: rtval = EOPNOTSUPP; break; diff --git a/sys/fs/procfs/procfs_vnops.c b/sys/fs/procfs/procfs_vnops.c index 4f0b8fefb107..f229a6917692 100644 --- a/sys/fs/procfs/procfs_vnops.c +++ b/sys/fs/procfs/procfs_vnops.c @@ -36,7 +36,7 @@ * * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95 * - * $Id: procfs_vnops.c,v 1.65 1999/04/27 11:16:39 phk Exp $ + * $Id: procfs_vnops.c,v 1.66 1999/04/28 11:37:21 phk Exp $ */ /* @@ -102,6 +102,7 @@ static struct proc_target { { DT_REG, N("map"), Pmap, procfs_validmap }, { DT_REG, N("etype"), Ptype, procfs_validtype }, { DT_REG, N("cmdline"), Pcmdline, NULL }, + { DT_REG, N("rlimit"), Prlimit, NULL }, #undef N }; static const int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]); @@ -577,6 +578,7 @@ procfs_getattr(ap) case Pnote: case Pnotepg: case Pcmdline: + case Prlimit: vap->va_nlink = 1; vap->va_uid = procp->p_ucred->cr_uid; vap->va_gid = procp->p_ucred->cr_gid; diff --git a/sys/miscfs/procfs/procfs.h b/sys/miscfs/procfs/procfs.h index d9b333bda765..0c2698a77d48 100644 --- a/sys/miscfs/procfs/procfs.h +++ b/sys/miscfs/procfs/procfs.h @@ -37,7 +37,7 @@ * @(#)procfs.h 8.9 (Berkeley) 5/14/95 * * From: - * $Id: procfs.h,v 1.22 1999/04/27 11:16:35 phk Exp $ + * $Id: procfs.h,v 1.23 1999/04/28 11:37:18 phk Exp $ */ /* @@ -57,7 +57,8 @@ typedef enum { Pnotepg, /* process group notifier */ Pmap, /* memory map */ Ptype, /* executable type */ - Pcmdline /* command line */ + Pcmdline, /* command line */ + Prlimit /* resource limits */ } pfstype; /* @@ -156,6 +157,7 @@ int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, str int procfs_domap __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); int procfs_dotype __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); int procfs_docmdline __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); +int procfs_dorlimit __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio)); /* Return 1 if process has special kernel digging privileges */ int procfs_kmemaccess __P((struct proc *)); diff --git a/sys/miscfs/procfs/procfs_rlimit.c b/sys/miscfs/procfs/procfs_rlimit.c new file mode 100644 index 000000000000..b211d0bb7e3c --- /dev/null +++ b/sys/miscfs/procfs/procfs_rlimit.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 1999 Adrian Chadd + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94 + * + * $Id: procfs_status.c,v 1.12 1999/01/05 03:53:06 peter Exp $ + */ + +/* + * To get resource.h to include our rlimit_ident[] array of rlimit identifiers + */ + +#define _RLIMIT_IDENT + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * This converts a quad_t to a string, stored in fin + * It is here because there doesn't exist a quad_t entry in the kernel + * printf() library. + */ + +static void quadtostring (char *fin, quad_t num) +{ + char str[128]; + char *cp; + int i, n; + + cp = str; + i = 0; + + /* + * Create the number string. + * The string will be in reverse from the original number. + */ + + while (num) { + *(cp++) = (num % 10) + '0'; + num /= 10; + i++; + } + + /* Null terminate */ + *cp = '\0'; + + /* + * Now, swap the order + */ + + for (n = 0; n < i; n++) { + fin[n] = str[(i-1)-n]; + } + + /* Null terminate */ + fin[n] = '\0'; + + return; +} + + + +int +procfs_dorlimit(curp, p, pfs, uio) + struct proc *curp; + struct proc *p; + struct pfsnode *pfs; + struct uio *uio; +{ + char *ps; + int i; + int xlen; + int error; + char psbuf[512]; /* XXX - conservative */ + char qstr[64]; + + if (uio->uio_rw != UIO_READ) + return (EOPNOTSUPP); + + + ps = psbuf; + + for (i = 0; i < RLIM_NLIMITS; i++) { + + /* + * Add the rlimit ident + */ + + ps += sprintf(ps, "%s ", rlimit_ident[i]); + + /* + * Replace RLIM_INFINITY with -1 in the string + */ + + /* + * current limit + */ + + if (p->p_rlimit[i].rlim_cur == RLIM_INFINITY) { + ps += sprintf(ps, "-1 "); + } else { + quadtostring(qstr, p->p_rlimit[i].rlim_cur); + ps += sprintf(ps, "%s ", qstr); + } + + /* + * maximum limit + */ + + if (p->p_rlimit[i].rlim_max == RLIM_INFINITY) { + ps += sprintf(ps, "-1\n"); + } else { + quadtostring(qstr, p->p_rlimit[i].rlim_max); + ps += sprintf(ps, "%s\n", qstr); + } + } + + /* + * This logic is rather tasty - but its from procfs_status.c, so + * I guess I'll use it here. + */ + + xlen = ps - psbuf; + xlen -= uio->uio_offset; + ps = psbuf + uio->uio_offset; + xlen = imin(xlen, uio->uio_resid); + if (xlen <= 0) + error = 0; + else + error = uiomove(ps, xlen, uio); + + return (error); +} + diff --git a/sys/miscfs/procfs/procfs_subr.c b/sys/miscfs/procfs/procfs_subr.c index 98e36879a4b6..7b5e18c440d5 100644 --- a/sys/miscfs/procfs/procfs_subr.c +++ b/sys/miscfs/procfs/procfs_subr.c @@ -36,7 +36,7 @@ * * @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95 * - * $Id: procfs_subr.c,v 1.22 1999/01/05 03:53:06 peter Exp $ + * $Id: procfs_subr.c,v 1.23 1999/01/27 22:42:07 dillon Exp $ */ #include @@ -182,6 +182,7 @@ procfs_allocvp(mp, vpp, pid, pfs_type) case Pmap: case Pstatus: case Pcmdline: + case Prlimit: pfs->pfs_mode = (VREAD) | (VREAD >> 3) | (VREAD >> 6); @@ -287,6 +288,10 @@ procfs_rw(ap) rtval = procfs_docmdline(curp, p, pfs, uio); break; + case Prlimit: + rtval = procfs_dorlimit(curp, p, pfs, uio); + break; + default: rtval = EOPNOTSUPP; break; diff --git a/sys/miscfs/procfs/procfs_vnops.c b/sys/miscfs/procfs/procfs_vnops.c index 4f0b8fefb107..f229a6917692 100644 --- a/sys/miscfs/procfs/procfs_vnops.c +++ b/sys/miscfs/procfs/procfs_vnops.c @@ -36,7 +36,7 @@ * * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95 * - * $Id: procfs_vnops.c,v 1.65 1999/04/27 11:16:39 phk Exp $ + * $Id: procfs_vnops.c,v 1.66 1999/04/28 11:37:21 phk Exp $ */ /* @@ -102,6 +102,7 @@ static struct proc_target { { DT_REG, N("map"), Pmap, procfs_validmap }, { DT_REG, N("etype"), Ptype, procfs_validtype }, { DT_REG, N("cmdline"), Pcmdline, NULL }, + { DT_REG, N("rlimit"), Prlimit, NULL }, #undef N }; static const int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]); @@ -577,6 +578,7 @@ procfs_getattr(ap) case Pnote: case Pnotepg: case Pcmdline: + case Prlimit: vap->va_nlink = 1; vap->va_uid = procp->p_ucred->cr_uid; vap->va_gid = procp->p_ucred->cr_gid; diff --git a/sys/sys/resource.h b/sys/sys/resource.h index 4e4119383871..7e09e86dadce 100644 --- a/sys/sys/resource.h +++ b/sys/sys/resource.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)resource.h 8.4 (Berkeley) 1/9/95 - * $Id: resource.h,v 1.7 1997/02/22 09:45:46 peter Exp $ + * $Id: resource.h,v 1.8 1997/11/18 08:07:37 bde Exp $ */ #ifndef _SYS_RESOURCE_H_ @@ -92,6 +92,25 @@ struct rusage { #define RLIM_INFINITY ((rlim_t)(((u_quad_t)1 << 63) - 1)) + +/* + * Resource limit string identifiers + */ + +#ifdef _RLIMIT_IDENT +static char *rlimit_ident[] = { + "cpu", + "fsize", + "data", + "stack", + "core", + "rss", + "memlock", + "nproc", + "nofile", +}; +#endif + struct orlimit { int32_t rlim_cur; /* current (soft) limit */ int32_t rlim_max; /* maximum value for rlim_cur */