summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/syscall/rctlsys.c
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/syscall/rctlsys.c
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/syscall/rctlsys.c')
-rw-r--r--usr/src/uts/common/syscall/rctlsys.c60
1 files changed, 47 insertions, 13 deletions
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);