diff options
Diffstat (limited to 'usr/src/lib')
| -rw-r--r-- | usr/src/lib/common/inc/c_synonyms.h | 3 | ||||
| -rw-r--r-- | usr/src/lib/libc/inc/synonyms.h | 3 | ||||
| -rw-r--r-- | usr/src/lib/libc/port/llib-lc | 3 | ||||
| -rw-r--r-- | usr/src/lib/libc/port/mapfile-vers | 2 | ||||
| -rw-r--r-- | usr/src/lib/libc/port/sys/rctlsys.c | 15 | ||||
| -rw-r--r-- | usr/src/lib/libproc/common/libproc.h | 4 | ||||
| -rw-r--r-- | usr/src/lib/libproc/common/llib-lproc | 9 | ||||
| -rw-r--r-- | usr/src/lib/libproc/common/mapfile-vers | 3 | ||||
| -rw-r--r-- | usr/src/lib/libproc/common/pr_getrctl.c | 85 | ||||
| -rw-r--r-- | usr/src/lib/libproject/common/setproject.c | 169 |
10 files changed, 227 insertions, 69 deletions
diff --git a/usr/src/lib/common/inc/c_synonyms.h b/usr/src/lib/common/inc/c_synonyms.h index 581f55150f..d652cc06c2 100644 --- a/usr/src/lib/common/inc/c_synonyms.h +++ b/usr/src/lib/common/inc/c_synonyms.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -800,6 +800,7 @@ extern "C" { #define setppriv _setppriv #define setpwent _setpwent #define setrctl _setrctl +#define setprojrctl _setprojrctl #define setregid _setregid #define setreuid _setreuid #define setrlimit _setrlimit diff --git a/usr/src/lib/libc/inc/synonyms.h b/usr/src/lib/libc/inc/synonyms.h index faa9d33034..209d7f6063 100644 --- a/usr/src/lib/libc/inc/synonyms.h +++ b/usr/src/lib/libc/inc/synonyms.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -917,6 +917,7 @@ extern "C" { #define setpgid _setpgid #define setpgrp _setpgrp #define setppriv _setppriv +#define setprojrctl _setprojrctl #define setpwent _setpwent #define setrctl _setrctl #define setregid _setregid diff --git a/usr/src/lib/libc/port/llib-lc b/usr/src/lib/libc/port/llib-lc index 169b444f6a..cff6f24c5d 100644 --- a/usr/src/lib/libc/port/llib-lc +++ b/usr/src/lib/libc/port/llib-lc @@ -20,7 +20,7 @@ */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1348,6 +1348,7 @@ int getrctl(const char *name, rctlblk_t *old_rblk, rctlblk_t *new_rblk, int setrctl(const char *name, rctlblk_t *old_rblk, rctlblk_t *new_rblk, int flags); /* (private functions) */ +int setprojrctl(const char *name, rctlblk_t *new_rblk, size_t size, int flags); int rctlctl(const char *, rctlblk_t *, int); size_t rctllist(char *, size_t); diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index 560ac9d878..1f3fdc9d6a 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -1989,6 +1989,8 @@ SUNWprivate_1.1 { _setgrent; _setlogmask; _setpwent; + setprojrctl; + _setprojrctl; _setregid; _setreuid; setsigacthandler; diff --git a/usr/src/lib/libc/port/sys/rctlsys.c b/usr/src/lib/libc/port/sys/rctlsys.c index e47511ac2a..9e395d3048 100644 --- a/usr/src/lib/libc/port/sys/rctlsys.c +++ b/usr/src/lib/libc/port/sys/rctlsys.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,6 +29,7 @@ #pragma weak getrctl = _getrctl #pragma weak rctllist = _rctllist #pragma weak rctlctl = _rctlctl +#pragma weak setprojrctl = _setprojrctl #include "synonyms.h" #include <sys/types.h> @@ -71,3 +71,10 @@ rctlctl(const char *name, rctlblk_t *rblk, int flags) { return (syscall(SYS_rctlsys, 3, name, rblk, NULL, 0, flags)); } + +int +setprojrctl(const char *name, rctlblk_t *new_rblk, size_t size, int flags) +{ + return (syscall(SYS_rctlsys, + 4, name, NULL, new_rblk, size, flags)); +} diff --git a/usr/src/lib/libproc/common/libproc.h b/usr/src/lib/libproc/common/libproc.h index 07e58fa05c..d12fda05e3 100644 --- a/usr/src/lib/libproc/common/libproc.h +++ b/usr/src/lib/libproc/common/libproc.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -325,6 +325,8 @@ extern int pr_getrlimit(struct ps_prochandle *, int, struct rlimit *); extern int pr_setrlimit(struct ps_prochandle *, int, const struct rlimit *); +extern int pr_setprojrctl(struct ps_prochandle *, const char *, + rctlblk_t *, size_t, int); #if defined(_LARGEFILE64_SOURCE) extern int pr_getrlimit64(struct ps_prochandle *, int, struct rlimit64 *); diff --git a/usr/src/lib/libproc/common/llib-lproc b/usr/src/lib/libproc/common/llib-lproc index 015de9ca0e..b9eff09617 100644 --- a/usr/src/lib/libproc/common/llib-lproc +++ b/usr/src/lib/libproc/common/llib-lproc @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -23,7 +22,7 @@ /* PROTOLIB1 */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -248,6 +247,8 @@ int pr_getrctl(struct ps_prochandle *Pr, const char *rname, rctlblk_t *old_blk, rctlblk_t *new_blk, int rflag); int pr_setrctl(struct ps_prochandle *Pr, const char *rname, rctlblk_t *old_blk, rctlblk_t *new_blk, int rflag); +int pr_setprojrctl(struct ps_prochandle *Pr, const char *rname, + rctlblk_t *new_blk, size_t size, int rflag); /* pr_getrlimit.c */ int pr_getrlimit(struct ps_prochandle *Pr, diff --git a/usr/src/lib/libproc/common/mapfile-vers b/usr/src/lib/libproc/common/mapfile-vers index ef256570ce..758f43d99f 100644 --- a/usr/src/lib/libproc/common/mapfile-vers +++ b/usr/src/lib/libproc/common/mapfile-vers @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -208,6 +208,7 @@ SUNWprivate_1.1 { pr_pset_bind; pr_rename; pr_setitimer; + pr_setprojrctl; pr_setrctl; pr_setrlimit; pr_setrlimit64; diff --git a/usr/src/lib/libproc/common/pr_getrctl.c b/usr/src/lib/libproc/common/pr_getrctl.c index d54fc228a6..9cbf7dfa0c 100644 --- a/usr/src/lib/libproc/common/pr_getrctl.c +++ b/usr/src/lib/libproc/common/pr_getrctl.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -33,6 +32,7 @@ #include <errno.h> #include <strings.h> #include "libproc.h" +#include <sys/rctl_impl.h> /* * getrctl() system call -- executed by subject process @@ -197,3 +197,78 @@ pr_setrctl(struct ps_prochandle *Pr, const char *rname, } return (rval.sys_rval1); } + +/* + * setprojrctl() system call -- executed by subject process + */ +int +pr_setprojrctl(struct ps_prochandle *Pr, const char *rname, + rctlblk_t *new_blk, size_t size, int rflag) +{ + sysret_t rval; + argdes_t argd[6]; + argdes_t *adp; + int error; + + if (Pr == NULL) /* no subject process */ + return (setprojrctl(rname, new_blk, size, rflag)); + + adp = &argd[0]; + adp->arg_value = 4; /* switch for setprojrctls in rctlsys */ + adp->arg_object = NULL; + adp->arg_type = AT_BYVAL; + adp->arg_inout = AI_INPUT; + adp->arg_size = 0; + + adp++; + adp->arg_value = 0; + adp->arg_object = (void *)rname; + adp->arg_type = AT_BYREF; + adp->arg_inout = AI_INPUT; + adp->arg_size = strlen(rname) + 1; + + adp++; + adp->arg_value = 0; /* old_blk is not used by setprojrctls() */ + adp->arg_object = NULL; + adp->arg_type = AT_BYVAL; + adp->arg_inout = AI_INPUT; + adp->arg_size = 0; + + + adp++; + if (new_blk == NULL) { + adp->arg_value = 0; + adp->arg_object = NULL; + adp->arg_type = AT_BYVAL; + adp->arg_inout = AI_INPUT; + adp->arg_size = 0; + } else { + adp->arg_value = 0; + adp->arg_object = new_blk; + adp->arg_type = AT_BYREF; + adp->arg_inout = AI_INPUT; + adp->arg_size = rctlblk_size() * size; + } + + adp++; + adp->arg_value = size; /* obufsz is used by setrctls() */ + adp->arg_object = NULL; + adp->arg_type = AT_BYVAL; + adp->arg_inout = AI_INPUT; + adp->arg_size = 0; + + adp++; + adp->arg_value = rflag; + adp->arg_object = NULL; + adp->arg_type = AT_BYVAL; + adp->arg_inout = AI_INPUT; + adp->arg_size = 0; + + error = Psyscall(Pr, &rval, SYS_rctlsys, 6, &argd[0]); + + if (error) { + errno = (error > 0) ? error : ENOSYS; + return (-1); + } + return (rval.sys_rval1); +} diff --git a/usr/src/lib/libproject/common/setproject.c b/usr/src/lib/libproject/common/setproject.c index d22878a36f..e15c719c5c 100644 --- a/usr/src/lib/libproject/common/setproject.c +++ b/usr/src/lib/libproject/common/setproject.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -36,6 +36,7 @@ #include <signal.h> #include <stdlib.h> #include <string.h> +#include <strings.h> #include <nss_dbdefs.h> #include <pwd.h> #include <pool.h> @@ -45,6 +46,7 @@ #include <zone.h> #include <sys/pool.h> #include <sys/pool_impl.h> +#include <sys/rctl_impl.h> static void xstrtolower(char *s) @@ -177,7 +179,7 @@ build_rctlblk(rctlblk_t *blk, int comp_num, char *component) #define BADSPEC 5 static int -rctl_set(char *ctl_name, char *val, struct ps_prochandle *Pr) +rctl_set(char *ctl_name, char *val, struct ps_prochandle *Pr, int flags) { int error = 0; uint_t component = 0; @@ -185,18 +187,68 @@ rctl_set(char *ctl_name, char *val, struct ps_prochandle *Pr) uint_t state = 0; char *component_head; rctlblk_t *blk; - - remove_spaces(val); - if ((blk = malloc(rctlblk_size())) == NULL) { + rctlblk_t *ablk; + int project_entity = 0; + int count = 0; + char *tmp; + int local_action; + + /* We cannot modify a zone resource control */ + if (strncmp(ctl_name, "zone.", strlen("zone.")) == 0) { return (SETFAILED); } + remove_spaces(val); + /* - * Tear down everything with this ctl name. + * As we are operating in a new task, both process and task + * rctls are referenced by this process alone. Tear down + * matching process and task rctls only. + * + * blk will be the RCPRIV_SYSTEM for this resource control, + * populated by the last pr_setrctl(). */ - while (pr_getrctl(Pr, ctl_name, NULL, blk, RCTL_FIRST) != -1 && - rctlblk_get_privilege(blk) != RCPRIV_SYSTEM) { - (void) pr_setrctl(Pr, ctl_name, NULL, blk, RCTL_DELETE); + if ((strncmp(ctl_name, "process.", strlen("process.")) == 0) || + (strncmp(ctl_name, "task.", strlen("task.")) == 0)) { + + if ((blk = (rctlblk_t *)malloc(rctlblk_size())) == NULL) { + return (SETFAILED); + } + + + while (pr_getrctl(Pr, ctl_name, NULL, blk, RCTL_FIRST) != -1 && + rctlblk_get_privilege(blk) != RCPRIV_SYSTEM) { + (void) pr_setrctl(Pr, ctl_name, NULL, blk, RCTL_DELETE); + } + + } else if (strncmp(ctl_name, "project.", strlen("project.")) == 0) { + project_entity = 1; + + /* Determine how many attributes we'll be setting */ + for (tmp = val; *tmp != '\0'; tmp++) { + if (*tmp == '(') + count++; + } + + /* Allocate sufficient memory for rctl blocks */ + if ((count == 0) || ((ablk = + (rctlblk_t *)malloc(rctlblk_size() * count)) == NULL)) { + return (SETFAILED); + } + blk = ablk; + + /* + * In order to set the new rctl's local_action, we'll need the + * current value of global_flags. We obtain global_flags by + * performing a pr_getrctl(). + * + * The ctl_name has been verified as valid, so we have no reason + * to suspect that pr_getrctl() will return an error. + */ + (void) pr_getrctl(Pr, ctl_name, NULL, blk, RCTL_FIRST); + + } else { + return (SETFAILED); } /* @@ -205,11 +257,13 @@ rctl_set(char *ctl_name, char *val, struct ps_prochandle *Pr) rctlblk_set_privilege(blk, RCPRIV_PRIVILEGED); rctlblk_set_value(blk, 0); rctlblk_set_local_flags(blk, 0); + if (rctlblk_get_global_flags(blk) & RCTL_GLOBAL_DENY_ALWAYS) - rctlblk_set_local_action(blk, RCTL_LOCAL_DENY, 0); + local_action = RCTL_LOCAL_DENY; else - rctlblk_set_local_action(blk, RCTL_LOCAL_NOACTION, 0); + local_action = RCTL_LOCAL_NOACTION; + rctlblk_set_local_action(blk, local_action, 0); for (; ; val++) { switch (*val) { @@ -238,22 +292,35 @@ rctl_set(char *ctl_name, char *val, struct ps_prochandle *Pr) state &= ~INPAREN; component = 0; valuecount++; - if (pr_setrctl(Pr, ctl_name, NULL, blk, - RCTL_INSERT) == -1) + + if (project_entity && + (rctlblk_get_privilege(blk) == + RCPRIV_BASIC)) { error = SETFAILED; + } else if (project_entity) { + if (valuecount > count) + return (SETFAILED); + + if (valuecount != count) + blk = RCTLBLK_INC(ablk, + valuecount); + } else { + if (pr_setrctl(Pr, ctl_name, + NULL, blk, RCTL_INSERT) == + -1) + error = SETFAILED; + } /* re-initialize block */ - rctlblk_set_privilege(blk, - RCPRIV_PRIVILEGED); - rctlblk_set_value(blk, 0); - rctlblk_set_local_flags(blk, 0); - if (rctlblk_get_global_flags(blk) & - RCTL_GLOBAL_DENY_ALWAYS) - rctlblk_set_local_action(blk, - RCTL_LOCAL_DENY, 0); - else + if (!project_entity || + (valuecount != count)) { + rctlblk_set_privilege(blk, + RCPRIV_PRIVILEGED); + rctlblk_set_value(blk, 0); + rctlblk_set_local_flags(blk, 0); rctlblk_set_local_action(blk, - RCTL_LOCAL_NOACTION, 0); + local_action, 0); + } } else { error = CLOSEBEFOREOPEN; } @@ -288,6 +355,12 @@ rctl_set(char *ctl_name, char *val, struct ps_prochandle *Pr) break; } + if (project_entity) { + blk = ablk; + if (pr_setprojrctl(Pr, ctl_name, blk, count, flags) == -1) + error = SETFAILED; + } + free(blk); if (valuecount == 0) @@ -465,6 +538,7 @@ setproject_proc(const char *project_name, const char *user_name, int flags, int ret = 0; kva_t *kv_array; struct project local_proj; /* space to store proj if not provided */ + const char *pool_name = NULL; if (project_name != NULL) { /* @@ -508,45 +582,37 @@ setproject_proc(const char *project_name, const char *user_name, int flags, projid = getprojid(); } + + if ((kv_array = _str2kva(proj->pj_attr, KV_ASSIGN, + KV_DELIMITER)) != NULL) { + for (i = 0; i < kv_array->length; i++) { + if (strcmp(kv_array->data[i].key, + "project.pool") == 0) { + pool_name = kv_array->data[i].value; + } + if (strcmp(kv_array->data[i].key, "task.final") == 0) { + flags |= TASK_FINAL; + } + } + } + /* - * Only bind to a pool if pools are configured. + * Bind process to a pool only if pools are configured */ if (pools_enabled() == 1) { - const char *pool_name = NULL; char *old_pool_name; - int taskflags = flags; /* * Attempt to bind to pool before calling * settaskid(). */ - if ((kv_array = _str2kva(proj->pj_attr, KV_ASSIGN, - KV_DELIMITER)) != NULL) { - for (i = 0; i < kv_array->length; i++) { - if (strcmp(kv_array->data[i].key, - "project.pool") == 0) { - pool_name = kv_array->data[i].value; - break; - } - if (strcmp(kv_array->data[i].key, - "task.final") == 0) { - taskflags |= TASK_FINAL; - } - } - } - old_pool_name = pool_get_binding(pid); - - /* - * If parent is not bound to the default pool, then we want - * to preserve same binding as parent. - */ - if (pool_name != NULL && bind_to_pool(pool_name, pid, 0) != 0) { + if (bind_to_pool(pool_name, pid, 0) != 0) { if (old_pool_name) free(old_pool_name); _kva_free(kv_array); return (SETPROJ_ERR_POOL); } - if (pr_settaskid(Pr, projid, taskflags) == -1) { + if (pr_settaskid(Pr, projid, flags & TASK_MASK) == -1) { int saved_errno = errno; /* @@ -568,9 +634,10 @@ setproject_proc(const char *project_name, const char *user_name, int flags, /* * Pools are not configured, so simply create new task. */ - if (pr_settaskid(Pr, projid, flags) == -1) + if (pr_settaskid(Pr, projid, flags & TASK_MASK) == -1) { + _kva_free(kv_array); return (SETPROJ_ERR_TASK); - kv_array = _str2kva(proj->pj_attr, KV_ASSIGN, KV_DELIMITER); + } } if (project_name == NULL) { @@ -612,7 +679,7 @@ setproject_proc(const char *project_name, const char *user_name, int flags, } ret = rctl_set(kv_array->data[i].key, - kv_array->data[i].value, Pr); + kv_array->data[i].value, Pr, flags & TASK_PROJ_MASK); if (ret && unknown == 0) { /* |
