summaryrefslogtreecommitdiff
path: root/usr/src/uts/common
diff options
context:
space:
mode:
authorMenno Lageman <Menno.Lageman@Sun.COM>2009-05-15 23:41:08 -0700
committerMenno Lageman <Menno.Lageman@Sun.COM>2009-05-15 23:41:08 -0700
commit55c01d4fc0ce8d2c59d6ade573e676a70d0a9c8a (patch)
treed5604d0be552d298a35f61b2c0d92952c943ff72 /usr/src/uts/common
parent59ebecb81fc63e888d5661392827ec4fa529312d (diff)
downloadillumos-joyent-55c01d4fc0ce8d2c59d6ade573e676a70d0a9c8a.tar.gz
6839350 getrctl(2) should do exactly what it says on the tin
Diffstat (limited to 'usr/src/uts/common')
-rw-r--r--usr/src/uts/common/os/rctl.c4
-rw-r--r--usr/src/uts/common/sys/rctl.h9
-rw-r--r--usr/src/uts/common/syscall/rctlsys.c60
3 files changed, 55 insertions, 18 deletions
diff --git a/usr/src/uts/common/os/rctl.c b/usr/src/uts/common/os/rctl.c
index dee5330bca..bd32159049 100644
--- a/usr/src/uts/common/os/rctl.c
+++ b/usr/src/uts/common/os/rctl.c
@@ -510,7 +510,7 @@ rctl_add_legacy_limit(const char *name, const char *mname, const char *lname,
rctl_add_default_limit(name, qty, RCPRIV_PRIVILEGED, RCTL_LOCAL_DENY);
}
-static rctl_set_t *
+rctl_set_t *
rctl_entity_obtain_rset(rctl_dict_entry_t *rcd, struct proc *p)
{
rctl_set_t *rset = NULL;
@@ -1445,7 +1445,7 @@ tearoff_rewalk_list:
mutex_exit(&set->rcs_lock);
}
-static int
+int
rctl_set_find(rctl_set_t *set, rctl_hndl_t hndl, rctl_t **rctl)
{
uint_t index = hndl % rctl_set_size;
diff --git a/usr/src/uts/common/sys/rctl.h b/usr/src/uts/common/sys/rctl.h
index 2061398fba..af81cd387b 100644
--- a/usr/src/uts/common/sys/rctl.h
+++ b/usr/src/uts/common/sys/rctl.h
@@ -19,15 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_RCTL_H
#define _SYS_RCTL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/kmem.h>
#include <sys/resource.h>
#include <sys/types.h>
@@ -208,6 +206,9 @@ int rcop_no_test(struct rctl *, struct proc *, rctl_entity_p_t *,
int rcop_absolute_test(struct rctl *, struct proc *, rctl_entity_p_t *,
struct rctl_val *, rctl_qty_t, uint_t);
+#define RCTLOP_NO_USAGE(r) \
+ (r->rc_dict_entry->rcd_ops->rco_get_usage == rcop_no_usage)
+
extern rctl_ops_t rctl_default_ops;
extern rctl_ops_t rctl_absolute_ops;
@@ -291,6 +292,7 @@ int rctl_val_cmp(rctl_val_t *, rctl_val_t *, int);
int rctl_val_list_insert(rctl_val_t **, rctl_val_t *);
rctl_set_t *rctl_set_create(void);
+rctl_set_t *rctl_entity_obtain_rset(rctl_dict_entry_t *, struct proc *);
rctl_alloc_gp_t *rctl_set_init_prealloc(rctl_entity_t);
rctl_set_t *rctl_set_init(rctl_entity_t, struct proc *, rctl_entity_p_t *,
rctl_set_t *, rctl_alloc_gp_t *);
@@ -300,6 +302,7 @@ rctl_set_t *rctl_set_dup(rctl_set_t *, struct proc *, struct proc *,
rctl_entity_p_t *, rctl_set_t *, rctl_alloc_gp_t *, int);
void rctl_set_reset(rctl_set_t *, struct proc *, rctl_entity_p_t *);
void rctl_set_tearoff(rctl_set_t *, struct proc *);
+int rctl_set_find(rctl_set_t *, rctl_hndl_t, rctl_t **);
void rctl_set_free(rctl_set_t *);
void rctl_prealloc_destroy(rctl_alloc_gp_t *);
diff --git a/usr/src/uts/common/syscall/rctlsys.c b/usr/src/uts/common/syscall/rctlsys.c
index ef987b357a..1e95ec2716 100644
--- a/usr/src/uts/common/syscall/rctlsys.c
+++ b/usr/src/uts/common/syscall/rctlsys.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/cmn_err.h>
@@ -207,13 +205,16 @@ rctl_invalid_value(rctl_dict_entry_t *rde, rctl_val_t *rval)
*
* Overview
* rctlsys_get() is the implementation of the core logic of getrctl(2), the
- * public system call for fetching resource control values. Two mutually
- * exclusive flag values are supported: RCTL_FIRST and RCTL_NEXT. When
- * RCTL_FIRST is presented, the value of old_rblk is ignored, and the first
- * value in the resource control value sequence for the named control is
- * transformed and placed in the user memory location at new_rblk. In the
- * RCTL_NEXT case, the value of old_rblk is examined, and the next value in
- * the sequence is transformed and placed at new_rblk.
+ * public system call for fetching resource control values. Three mutually
+ * exclusive flag values are supported: RCTL_USAGE, RCTL_FIRST and RCTL_NEXT.
+ * When RCTL_USAGE is presented, the current usage for the resource control
+ * is returned in new_blk if the resource control provides an implementation
+ * of the usage operation. When RCTL_FIRST is presented, the value of
+ * old_rblk is ignored, and the first value in the resource control value
+ * sequence for the named control is transformed and placed in the user
+ * memory location at new_rblk. In the RCTL_NEXT case, the value of old_rblk
+ * is examined, and the next value in the sequence is transformed and placed
+ * at new_rblk.
*/
static long
rctlsys_get(char *name, rctl_opaque_t *old_rblk, rctl_opaque_t *new_rblk,
@@ -261,12 +262,45 @@ rctlsys_get(char *name, rctl_opaque_t *old_rblk, rctl_opaque_t *new_rblk,
kmem_free(kname, MAXPATHLEN);
- nval = kmem_cache_alloc(rctl_val_cache, KM_SLEEP);
+ if (action != RCTL_USAGE)
+ nval = kmem_cache_alloc(rctl_val_cache, KM_SLEEP);
if (action == RCTL_USAGE) {
- kmem_cache_free(rctl_val_cache, nval);
+ rctl_set_t *rset;
+ rctl_t *rctl;
+ rctl_qty_t usage;
+
+ mutex_enter(&curproc->p_lock);
+ if ((rset = rctl_entity_obtain_rset(krde, curproc)) == NULL) {
+ mutex_exit(&curproc->p_lock);
+ kmem_free(krde, sizeof (rctl_dict_entry_t));
+ return (set_errno(ESRCH));
+ }
+ mutex_enter(&rset->rcs_lock);
+ if (rctl_set_find(rset, hndl, &rctl) == -1) {
+ mutex_exit(&rset->rcs_lock);
+ mutex_exit(&curproc->p_lock);
+ kmem_free(krde, sizeof (rctl_dict_entry_t));
+ return (set_errno(ESRCH));
+ }
+ if (RCTLOP_NO_USAGE(rctl)) {
+ mutex_exit(&rset->rcs_lock);
+ mutex_exit(&curproc->p_lock);
+ kmem_free(krde, sizeof (rctl_dict_entry_t));
+ return (set_errno(ENOTSUP));
+ }
+ usage = RCTLOP_GET_USAGE(rctl, curproc);
+ mutex_exit(&rset->rcs_lock);
+ mutex_exit(&curproc->p_lock);
+
+ nblk = kmem_alloc(sizeof (rctl_opaque_t), KM_SLEEP);
+ bzero(nblk, sizeof (rctl_opaque_t));
+ nblk->rcq_value = usage;
+
+ ret = copyout(nblk, new_rblk, sizeof (rctl_opaque_t));
+ kmem_free(nblk, sizeof (rctl_opaque_t));
kmem_free(krde, sizeof (rctl_dict_entry_t));
- return (set_errno(ENOTSUP));
+ return (ret == 0 ? 0 : set_errno(EFAULT));
} else if (action == RCTL_FIRST) {
mutex_enter(&curproc->p_lock);