summaryrefslogtreecommitdiffstats
path: root/sys/compat/linprocfs/linprocfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/compat/linprocfs/linprocfs.c')
-rw-r--r--sys/compat/linprocfs/linprocfs.c120
1 files changed, 116 insertions, 4 deletions
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 9142c93..bf0610b 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/ptrace.h>
#include <sys/resourcevar.h>
+#include <sys/resource.h>
#include <sys/sbuf.h>
#include <sys/sem.h>
#include <sys/smp.h>
@@ -858,10 +859,20 @@ linprocfs_doprocstatus(PFS_FILL_ARGS)
static int
linprocfs_doproccwd(PFS_FILL_ARGS)
{
+ struct filedesc *fdp;
+ struct vnode *vp;
char *fullpath = "unknown";
char *freepath = NULL;
- vn_fullpath(td, p->p_fd->fd_cdir, &fullpath, &freepath);
+ fdp = p->p_fd;
+ FILEDESC_SLOCK(fdp);
+ vp = fdp->fd_cdir;
+ if (vp != NULL)
+ VREF(vp);
+ FILEDESC_SUNLOCK(fdp);
+ vn_fullpath(td, vp, &fullpath, &freepath);
+ if (vp != NULL)
+ vrele(vp);
sbuf_printf(sb, "%s", fullpath);
if (freepath)
free(freepath, M_TEMP);
@@ -874,12 +885,20 @@ linprocfs_doproccwd(PFS_FILL_ARGS)
static int
linprocfs_doprocroot(PFS_FILL_ARGS)
{
- struct vnode *rvp;
+ struct filedesc *fdp;
+ struct vnode *vp;
char *fullpath = "unknown";
char *freepath = NULL;
- rvp = jailed(p->p_ucred) ? p->p_fd->fd_jdir : p->p_fd->fd_rdir;
- vn_fullpath(td, rvp, &fullpath, &freepath);
+ fdp = p->p_fd;
+ FILEDESC_SLOCK(fdp);
+ vp = jailed(p->p_ucred) ? fdp->fd_jdir : fdp->fd_rdir;
+ if (vp != NULL)
+ VREF(vp);
+ FILEDESC_SUNLOCK(fdp);
+ vn_fullpath(td, vp, &fullpath, &freepath);
+ if (vp != NULL)
+ vrele(vp);
sbuf_printf(sb, "%s", fullpath);
if (freepath)
free(freepath, M_TEMP);
@@ -1332,6 +1351,97 @@ linprocfs_dofdescfs(PFS_FILL_ARGS)
return (0);
}
+/*
+ * Filler function for proc/pid/limits
+ */
+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 int
+linprocfs_doproclimits(PFS_FILL_ARGS)
+{
+ const struct linux_rlimit_ident *li;
+ struct plimit *limp;
+ struct rlimit rl;
+ ssize_t size;
+ int res, error;
+
+ error = 0;
+
+ PROC_LOCK(p);
+ limp = lim_hold(p->p_limit);
+ PROC_UNLOCK(p);
+ size = sizeof(res);
+ sbuf_printf(sb, "%-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:
+ /* FALLTHROUGH */
+ case LINUX_RLIMIT_RTTIME:
+ rl.rlim_cur = RLIM_INFINITY;
+ break;
+ case LINUX_RLIMIT_SIGPENDING:
+ error = kernel_sysctlbyname(td,
+ "kern.sigqueue.max_pending_per_proc",
+ &res, &size, 0, 0, 0, 0);
+ if (error != 0)
+ goto out;
+ rl.rlim_cur = res;
+ rl.rlim_max = res;
+ break;
+ case LINUX_RLIMIT_MSGQUEUE:
+ error = kernel_sysctlbyname(td,
+ "kern.ipc.msgmnb", &res, &size, 0, 0, 0, 0);
+ if (error != 0)
+ goto out;
+ rl.rlim_cur = res;
+ rl.rlim_max = res;
+ break;
+ case LINUX_RLIMIT_NICE:
+ /* FALLTHROUGH */
+ case LINUX_RLIMIT_RTPRIO:
+ rl.rlim_cur = 0;
+ rl.rlim_max = 0;
+ break;
+ default:
+ rl = limp->pl_rlimit[li->rlim_id];
+ break;
+ }
+ if (rl.rlim_cur == RLIM_INFINITY)
+ sbuf_printf(sb, "%-26s%-21s%-21s%-10s\n",
+ li->desc, "unlimited", "unlimited", li->unit);
+ else
+ sbuf_printf(sb, "%-26s%-21llu%-21llu%-10s\n",
+ li->desc, (unsigned long long)rl.rlim_cur,
+ (unsigned long long)rl.rlim_max, li->unit);
+ }
+out:
+ lim_free(limp);
+ return (error);
+}
/*
* Filler function for proc/sys/kernel/random/uuid
@@ -1470,6 +1580,8 @@ linprocfs_init(PFS_INIT_ARGS)
NULL, NULL, NULL, 0);
pfs_create_file(dir, "auxv", &linprocfs_doauxv,
NULL, &procfs_candebug, NULL, PFS_RD|PFS_RAWRD);
+ pfs_create_file(dir, "limits", &linprocfs_doproclimits,
+ NULL, NULL, NULL, PFS_RD);
/* /proc/scsi/... */
dir = pfs_create_dir(root, "scsi", NULL, NULL, NULL, 0);
OpenPOWER on IntegriCloud