diff options
author | Menno Lageman <Menno.Lageman@Sun.COM> | 2009-05-15 23:41:08 -0700 |
---|---|---|
committer | Menno Lageman <Menno.Lageman@Sun.COM> | 2009-05-15 23:41:08 -0700 |
commit | 55c01d4fc0ce8d2c59d6ade573e676a70d0a9c8a (patch) | |
tree | d5604d0be552d298a35f61b2c0d92952c943ff72 /usr/src/uts/common/syscall/rctlsys.c | |
parent | 59ebecb81fc63e888d5661392827ec4fa529312d (diff) | |
download | illumos-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.c | 60 |
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); |