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 | |
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')
-rw-r--r-- | usr/src/uts/common/os/rctl.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/sys/rctl.h | 9 | ||||
-rw-r--r-- | usr/src/uts/common/syscall/rctlsys.c | 60 |
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); |