svcadm(8)을 검색하려면 섹션에서 8 을 선택하고, 맨 페이지 이름에 svcadm을 입력하고 검색을 누른다.
setrctl(2)
setrctl(2) System Calls setrctl(2)
NAME
setrctl, setrctlx, getrctl, getrctlx - set or get resource control val‐
ues
SYNOPSIS
#include <rctl.h>
int setrctl(const char *controlname, rctlblk_t *old_blk,
rctlblk_t *new_blk, uint_t flags);
int setrctlx(const char *controlname, rctlblk_t *old_blk,
rctlblk_t *new_blk, idtype_t idtype, id_t id, uint_t flags);
int getrctl(const char *controlname, rctlblk_t *old_blk,
rctlblk_t *new_blk, uint_t flags);
int getrctlx(const char *controlname, rctlblk_t *old_blk,
rctlblk_t *new_blk, idtype_t idtype, id_t id, uint_t flags);
DESCRIPTION
The setrctl(), setrctlx(), getrctl(), and getrctlx() functions provide
interfaces for the modification and retrieval of resource control
(rctl) values on active entities on the system, such as processes,
tasks, projects or zones. All rctl values are unsigned 64-bit integers;
a collection of flags are defined that modify which rctl value is to be
set or retrieved.
For setrctlx() and getrctlx() functions, the entity is determined by
arguments idtype and id. Valid values of idtype are P_PID, P_TASKID,
P_PROJID and P_ZONEID. If id is P_MYID, then the caller's entity is
selected. If the caller is inside a non-global zone, any entity outside
of the caller's zone is not visible. A caller in the global zone can
see all processes, tasks, and zones on the system, but only projects in
the global zone, as project ids are unique only to a single zone.
When the controlname refers to a resource control associated to a wider
scope of entity than the entity given by idtype, these functions will
act on the wider entity, which the entity given by (idtype, id) pair
belongs to. For example, if idtype is P_TASKID, id is 100, and control‐
name is "project.max-lwps", then these functions will act on the rctl
"project.max-lwps" of the project and task with id 100 belongs to. Note
that each project has its own "project.max-lwps" rctl. An rctl is
determined by a pair of rctl name and the entity. Conversely, if the
resource control specified by controlname is associated to a narrower
range of entity than the entity given by idtype, these functions fail.
For setrctl() and getrctl(), the resource control of the caller's
entity is used. That is, setrctl() and getrctl() are effectively same
as setrctlx() and getrctlx() with arguments idtype equals to P_PID and
id equals to P_MYID.
getrctl() and getrctlx() functions read rctl-related data. Their behav‐
ior depends on the value of flags. Valid values of flags are
RCTL_FIRST, RCTL_SYSTEM, RCTL_SRCH, RCTL_NEXT and RCTL_USAGE. In any
case, new_blk must point to a valid rctlblk_t object.
When flags is RCTL_FIRST, the data of the first rctl value is copied to
the rctlblk_t object pointed by new_blk.
When flags is RCTL_SYSTEM, the data of the system default rctl value is
copied to the rctlblk_t object pointed by new_blk.
When flags is RCTL_SRCH, old_blk must point to an existing rctl value.
Information of the matching rctl value is copied to new_blk. Note that,
content of old_blk and new_blk may differ because of the matching rule.
For example, signal is ignored for matching, but new_blk contains the
signal information of the matching rctl. Otherwise, these functions
fail.
When flags is RCTL_NEXT, old_blk must point to an existing rctl value.
If that rctl value has a next rctl value, then this next rctl value is
copied to new_blk. Otherwise, these functions fail.
When flags is RCTL_USAGE, the current value of the resource usage, if
it exists, is placed in the value field of the resource control block
specified by new_blk. This value can be obtained with rctl‐
blk_get_value(3C). All other members of the returned block are unde‐
fined and might be invalid.
setrctl() and setrctlx() functions modify rctl values. Their behavior
depends on the value of flags. Valid values of flags includes
RCTL_INSERT, RCTL_DELETE, RCTL_REPLACE and RCTL_OVERWRITE. In some
cases, these flags can be ORed with RCTL_USE_RECIPIENT_PID. All other
values of flags are invalid. In any case, new_blk must point to a valid
rctlblk_t object.
Since setrctl() and setrctlx() modify rctl values, the caller must meet
certain access criteria in order to modify rctl values. The requirement
to access an entity to modify rctl is as follows:
o If the entity is a process, the caller must own the process.
If the rctl value being modified is privileged, the
PRIV_SYS_RESOURCE privilege is also required. There is one
exception to this rule when replacing rctl values. It will
be described in the corresponding section.
o If the entity is a task, the caller must own at least one
process of the task. If the rctl value being modified is
privileged, the PRIV_SYS_RESOURCE privilege is also
required.
o If the entity is a project, the caller must have
PRIV_SYS_RESOURCE privilege.
o If the entity is a zone, the caller must have
PRIV_SYS_RESOURCE privilege and the caller must be in the
global zone.
In addition, if the privilege is RCPRIV_SYSTEM, the modification of
this rctl value is not allowed at all. This rctl value is fixed for the
duration of the operating system instance.
When flags is RCTL_INSERT, new_blk must point to a non-existing rctl
value and that rctl value will be inserted. However, the function may
fail if there are too many rctl values. The maximum number of rctl val‐
ues per rctl is fixed for the duration of the operating system instance
and can be retrieved by sysconf(3C) with argument _SC_RCTL_VAL_MAX_NUM.
When flags is RCTL_DELETE, new_blk must point to an existing rctl
value, and that rctl value will be deleted.
When flags is RCTL_REPLACE, old_blk must point to an existing rctl
value, and new_blk must point to a non-existing rctl values except
old_blk and new_blk is considered equal. The rctl value pointed by
old_blk will be replaced by the rctl value pointed by new_blk. The
access requirement for replacing rctl values is same as that required
to perform same operation by combination of deletion and insertion,
except the following case:
o The global flag of the rctl, which can be retrieved by the
rctlblk_get_global_flags() function, has RCTL_GLOBAL_LOWER‐
ABLE bit set, and new_blk is equal to old_blk except new_blk
is lowering the enforced value set and read by rctl‐
blk_set_value() and rctlblk_get_value(). In this case, priv‐
ilege check against PRIS_SYS_RESOURCE() is skipped.
When flags is RCTL_OVERWRITE, new_blk must point to a valid rctl value.
All rctl values which have same privilege as that of new_blk in the
same rctl are deleted and new_blk is inserted. The access requirement
for overwriting rctl values is same as that required to perform same
operation by combination of deletion and insertion. This operation can
fail when there are too many rctl values already in the rctl to insert
a new one.
When setrctl() or setrctlx() is called with flags RCTL_INSERT,
RCTL_REPLACE or RCTL_OVERWRITE, if newly inserted rctl value has privi‐
lege RCPRIV_BASIC and a signal is specified by RCTL_LOCAL_SIGNAL bit in
its flag, then the caller can set RCTL_USE_RECIPIENT_PID bit to flags
to let setrctl() or setrctlx() functions use recipient pid set by rctl‐
blk_set_recipient_pid() function. In this case, the caller must own the
recipient process and the recipient process must be a member of the
target entity. Using RCTL_USE_RECIPIENT_PID in all other cases are
invalid.
In the same situation when we create a new basic rctl value with a sig‐
nal, and if RCTL_USE_RECIPIENT_PID is not given, the system tries to
deduce the default recipient process for the signal. If the target
entity is a process, the same process is used as recipient process. If
the target entity is a task and the calling process is in the target
task, then the calling process is used as the recipient pid. Otherwise,
the system cannot infer the recipient process and these functions fail.
Some rctls do not allow any RCPRIV_BASIC value at all. This can be
checked by comparing the global flag of the rctl with RCTL_GLOBAL_NOBA‐
SIC bit. Even when RCPRIV_BASIC value is allowed, at most one
RCPRIV_BASIC resource control value is permitted per rctl. Any kind of
successful insertion of an RCPRIV_BASIC value will cause any existing
RCPRIV_BASIC value owned by that rctl to be deleted. Because of this
behavior, when calling the setrctl() and setrctlx() functions, the
flags RCTL_INSERT and RCTL_OVERWRITE are effectively same when the
inserted rctl value has the privilege RCPRIV_BASIC and is not an exist‐
ing rctl value in the rctl.
The kernel maintains a history of which resource control values have
triggered for a particular entity, retrievable from a resource control
block with the rctlblk_set_value(3C) function. The insertion or dele‐
tion of a resource control value at or below the currently enforced
value might cause the currently enforced value to be reset. In the case
of insertion, the newly inserted value becomes the actively enforced
value. In the case of deletion of the currently enforced value, the
next higher value becomes the actively enforced value.
The various resource control block properties are described on the
rctlblk_set_value(3C) manual page.
Process and task scope resource controls are inherited from the prede‐
cessor process or task.
One of the exec(2) functions can modify the resource controls of a
process by resetting their histories, as noted above for insertion or
deletion operations.
RETURN VALUES
Upon successful completion, the setrctl(), setrctlx(), getrctl() and
getrctlx() functions return 0. Otherwise they return -1 and set errno
to indicate the error.
ERRORS
The setrctl(), setrctlx(), getrctl() and getrctlx() functions will fail
if:
EFAULT The controlname, old_blk, or new_blk argument points to an
illegal address when they are needed.
EINVAL Wrong input values. They can be invalid controlname, flags,
or rctl values pointed by old_blk or new_blk when they are
needed.
The setrctlx() and getrctlx() functions will fail if:
EINVAL idtype is invalid or not consistent with controlname.
ESRCH There is no entity matched by id or visible to the zone of
the caller.
The setrctl() and setrctlx() functions will fail if:
EINVAL new_blk refers to an existing rctl values when inserting or
replacing an rctl value.
RCTL_USE_RECIPIENT_PID is used with process rctl, and the
recipient pid is different from the pid of the target
process.
ESRCH No matching rctl value found when deleting or replacing rctl
values.
RCTL_USE_RECIPIENT_PID is used with non-process rctl, and the
recipient pid does not exist in the target entity.
ENOSPC There are too many rctl values on the rctl, so new rctl value
cannot be inserted.
EACCES The caller does not have sufficient privilege to control the
target entity.
RCTL_USE_RECIPIENT_PID is used with process rctl, and the
caller does not own the process pointed by recipient pid.
EPERM The caller tried to modify system rctl values.
The setrctlx() function will fail if:
EINVAL Inserting new basic rctl values with signal action by
RCTL_INSERT, RCTL_REPLACE, or RCTL_OVERWRITE, but
RCTL_USE_RECIPIENT_PID is not given, and the system cannot
deduce recipient pid.
The getrctl() and getrctlx() functions will fail if:
ESRCH The rctl value pointed by old_blk can not be found when
looking for the next value.
ENOENT No value beyond the given rctl value exists when looking for
the next value by RCTL_NEXT.
No value matching the given rctl value exists when searching
for the rctl value by RCTL_SRCH.
ENOTSUP The rctl requested by RCTL_USAGE does not support the usage
operation.
EXAMPLES
Example 1 Retrieve a rctl value.
Obtain the lowest enforced rctl value on the rctl limiting the number
of LWPs in a task.
#include <rctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
...
rctlblk_t *rblk;
if ((rblk = (rctlblk_t *)malloc(rctlblk_size())) == NULL) {
(void) fprintf(stderr, "malloc failed: %s\n",
strerror(errno));
exit(1);
}
if (getrctl("task.max-lwps", NULL, rblk, RCTL_FIRST) == -1)
(void) fprintf(stderr, "failed to get rctl: %s\n",
strerror(errno));
else
(void) printf("task.max-lwps = %llu\n",
rctlblk_get_value(rblk));
Example 2 Overwrite rctl Values
Purge and set a new privileged rctl value of max-lwps of a given task.
#include <errno.h>
#include <rctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* Return 1 on success, 0 and set errno on failure.
*/
int
overwrite_task_max_lwp(taskid_t task_id, rctl_qty_t qty)
{
int ret;
rctlblk_t *rblk;
if ((rblk = malloc(rctlblk_size())) == NULL) {
(void) fprintf(stderr, "malloc failed: %s\n",
strerror(errno));
return (0);
}
rctlblk_set_privilege(rblk, RCPRIV_PRIVILEGED);
rctlblk_set_value(rblk, qty);
rctlblk_set_local_flags(rblk, 0);
rctlblk_set_local_action(rblk, 0, 0);
if (setrctlx("task.max-lwps", NULL, rblk, P_TASKID, task_id,
RCTL_OVERWRITE) == 0) {
ret = 1;
} else {
(void) fprintf(stderr, "failed to set rctl: %s\n",
strerror(errno));
ret = 0;
}
free(rblk);
return (ret);
}
USAGE
In an rctl, rctl values are ordered by the following criteria:
1. Their values (including RCTL_LOCAL_MAXIMAL bit of their
flag) are compared first.
2. If their values match, then an rctl value has
RCTL_LOCAL_DENY bit on its action is considered larger than
one without RCTL_LOCAL_DENY bit.
3. After that, privileges are compared. RCPRIV_BASIC is consid‐
ered the lowest and RCPRIV_SYSTEM is considered the largest.
If rctl values are not distinguishable in all above criteria, they are
considered equal and there can be no duplicate rctl values in an rctl
by criteria. This rule of determining the equality of rctl values is
applied whenever searching or matching rctl values.
The resource control facility provides the backend implementation for
both setrctl()/getrctl() and setrlimit()/getrlimit(). The facility
behaves consistently when either of these interfaces is used exclu‐
sively; when using both interfaces, the caller must be aware of the
ordering issues above, as well as the limit equivalencies described in
the following paragraph.
The hard and soft process limits made available with setrlimit() and
getrlimit() are mapped to the resource controls implementation. (New
process resource controls will not be made available with the rlimit
interface.) Because of the RCTL_INSERT and RCTL_DELETE operations, it
is possible that the set of values defined on a resource control has
more or fewer than the two values defined for an rlimit. In this case,
the soft and hard limit are computed as follows:
o If RCTL_LOCAL_DENY is allowed, that is, the rctl does not
have RCTL_GLOBAL_DENY_NEVER set, then the soft limit is the
lowest priority rctl value with the RCTL_LOCAL_DENY flag
set, and the hard limit is the rctl value with the lowest
priority equal to or exceeding RCPRIV_PRIVILEGED with the
RCTL_LOCAL_DENY flag set.
o If RCTL_LOCAL_DENY is not allowed, that is, the rctl has
RCTL_GLOBAL_DENY_NEVER set, then the soft limit is the low‐
est priority rctl value, and the hard limit is the rctl
value with the lowest priority equal to or exceeding
RCPRIV_PRIVILEGED.
If no identifiable soft limit exists on the resource control and setr‐
limit() is called, a new resource control value is created. If a
resource control does not have the global RCTL_GLOBAL_LOWERABLE prop‐
erty set, its hard limit will not allow lowering by unprivileged call‐
ers.
ATTRIBUTES
See attributes(7) for descriptions of the following attributes:
tab() box; cw(2.75i) |cw(2.75i) lw(2.75i) |lw(2.75i) ATTRIBUTE TYPEAT‐
TRIBUTE VALUE _ MT-LevelAsync-Signal-Safe
SEE ALSO
rctladm(8), getrlimit(2), errno(3C), rctlblk_set_value(3C),
sysconf(3C), attributes(7), resource-controls(7)
Oracle Solaris 11.4 17 August 2018 setrctl(2)