summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/common/inc/c_synonyms.h3
-rw-r--r--usr/src/lib/libc/inc/synonyms.h3
-rw-r--r--usr/src/lib/libc/port/llib-lc3
-rw-r--r--usr/src/lib/libc/port/mapfile-vers2
-rw-r--r--usr/src/lib/libc/port/sys/rctlsys.c15
-rw-r--r--usr/src/lib/libproc/common/libproc.h4
-rw-r--r--usr/src/lib/libproc/common/llib-lproc9
-rw-r--r--usr/src/lib/libproc/common/mapfile-vers3
-rw-r--r--usr/src/lib/libproc/common/pr_getrctl.c85
-rw-r--r--usr/src/lib/libproject/common/setproject.c169
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) {
/*