Contained WithinFind More DocumentationFeatured Support Resources | Download this book in PDF (875 KB)
Chapter 5 Resource ControlsThis chapter describes resource controls and their properties. Overview of Resource ControlsUse the extended accounting facility to determine the resource consumption of workloads on your system. After the resource consumption has been determined, use the resource control facility to place bounds on resource usage. Bounds that are placed on resources prevent workloads from over-consuming resources. For an overview of resource controls and example commands for administering resource controls, see Chapter 6, Resource Controls (Overview), in System Administration Guide: Solaris Containers-Resource Management and Solaris Zones and Chapter 7, Administering Resource Controls (Tasks), in System Administration Guide: Solaris Containers-Resource Management and Solaris Zones. The resource control facility adds the following benefits.
Resource Controls Flags and ActionsThis section describes flags, actions, and signals associated with resource controls. rlimit, Resource Limitrlimit is process-based. rlimit establishes a restricting boundary on the consumption of a variety of system resources by a process. Each process that the process creates inherits from the original process. A resource limit is defined by a pair of values. The values specify the current (soft) limit and the maximum (hard) limit. A process might irreversibly lower its hard limit to any value that is greater than or equal to the soft limit. Only a process with superuser ID can raise the hard limit. See setrlimit() and getrlimit(). The rlimit structure contains two members that define the soft limit and hard limit. rlim_t rlim_cur; /* current (soft) limit */ rlim_t rlim_max /* hard limit */ rctl, Resource Controlrctl extends the process-based limits of rlimit by controlling resource consumption by processes, tasks, and projects defined in the project database. Note – The rctl mechanism is preferred to the use of rlimit to set resource limits. The only reason to use the rlimit facility is when portability is required across UNIX platforms. Applications fall into the following broad categories depending on how an application deals with resource controls. Based on the action that is taken, resource controls can be further classified. Most report an error and terminate operation. Other resource controls allow applications to resume operation and adapt to the reduced resource usage. A progressive chain of actions at increasing values can be specified for each resource control. The list of attributes for a resource control consists of a privilege level, a threshold value, and an action that is taken when the threshold is exceeded. Resource Control Values and Privilege LevelsEach threshold value on a resource control must be associated with one of the following privilege levels:
Figure 5–2 shows the timeline for setting privilege levels for signals that are defined by the /etc/project file process.max-cpu-time resource control. Local Actions and Local FlagsThe local action and local flags are applied to the current resource control value represented by this resource control block. Local actions and local flags are value-specific. For each threshold value that is placed on a resource control, the following local actions and local flags are available:
Global Actions and Global FlagsGlobal flags apply to all current resource control values represented by this resource control block. Global actions and global flags are set by rctladm(1M). Global actions and global flags cannot be set with setrctl(). Global flags apply to all resource controls. For each threshold value that is placed on a resource control, the following global actions and global flags are available:
Resource Control Sets Associated With a Project, Processes, and TasksThe following figure shows the resource control sets associated with tasks, processes and a project. Figure 5–1 Resource Control Sets for Task, Project, and Process
More than one resource control can exist on a resource, each resource control at a containment level in the process model. Resource controls can be active on the same resource for both a process and collective task or collective project. In this case, the action for the process takes precedence. For example, action is taken on process.max-cpu-time before task.max-cpu-time if both controls are encountered simultaneously. Resource Controls Associated With a ProjectResource controls associated with a project include the following:
Resource Controls Associated With TasksResource controls associated with tasks include the following:
Resource Controls Associated With ProcessesResource controls associated with processes include the following:
Zone-Wide Resource ControlsZone-wide resource controls are available on a system with zones installed. Zone-wide resource controls limit the total resource usage of all process entities within a zone.
For information on configuring zone-wide resource controls, see Chapter 17, Non-Global Zone Configuration (Overview), in System Administration Guide: Solaris Containers-Resource Management and Solaris Zones and Chapter 18, Planning and Configuring Non-Global Zones (Tasks), in System Administration Guide: Solaris Containers-Resource Management and Solaris Zones. Note that it is possible to use the zonecfg command to apply a zone-wide resource control to the global zone on a system with non-global zones installed. Signals Used With Resource ControlsFor each threshold value that is placed on a resource control, the following restricted set of signals is available:
Other signals might be permitted due to global properties of a specific control. Note – Calls to setrctl() with illegal signals fail. Figure 5–2 Setting Privilege Levels for Signals
Resource Controls API FunctionsThe resource controls API contains functions that: Operate on Action-Value Pairs of a Resource ControlThe following list contains the functions that set or get the resource control block.
Operate on Local Modifiable ValuesThe following list contains the functions associated with the local, modifiable resource control block.
Retrieve Local Read-Only ValuesThe following list contains the functions associated with the local, read-only resource control block.
Retrieve Global Read-Only ActionsThe following list contains the functions associated with the global, read-only resource control block.
Resource Control Code ExamplesMaster Observing Process for Resource ControlsThe following example is the master observer process. Figure 5–3 shows the resource controls for the master observing process. Note – The line break is not valid in an /etc/project file. The line break is shown here only to allow the example to display on a printed or displayed page. Each entry in the /etc/project file must be on a separate line. Figure 5–3 Master Observing Process
The key points for the example include the following:
rctlblk_t *mlwprcb;
sigset_t smask;
/* Omit return value checking/error processing to keep code sample short */
/* First, install a RCPRIV_BASIC, v=1000, signal=SIGXRES rctl */
mlwprcb = calloc(1, rctlblk_size()); /* rctl blocks are opaque: */
rctlblk_set_value(mlwprcb, 1000);
rctlblk_set_privilege(mlwprcb, RCPRIV_BASIC);
rctlblk_set_local_action(mlwprcb, RCTL_LOCAL_SIGNAL, SIGXRES);
if (setrctl("task.max-lwps", NULL, mlwprcb, RCTL_INSERT) == -1) {
perror("setrctl");
exit (1);
}
/* Now, create the thread which waits for the signal */
sigemptyset(&smask);
sigaddset(&smask, SIGXRES);
thr_sigsetmask(SIG_BLOCK, &smask, NULL);
thr_create(NULL, 0, sigthread, (void *)SIGXRES, THR_DETACHED, NULL));
/* Omit return value checking/error processing to keep code sample short */
void *sigthread(void *a)
{
int sig = (int)a;
int rsig;
sigset_t sset;
sigemptyset(&sset);
sigaddset(&sset, sig);
while (1) {
rsig = sigwait(&sset);
if (rsig == SIGXRES) {
notify_all_children();
/* e.g. sigsend(P_PID, child_pid, SIGXRES); */
}
}
}
List all the Value-Action Pairs for a Specific Resource ControlThe following example lists all the value-action pairs for a specific resource control, task.max-lwps. The key point for the example is that getrctl(2) takes two resource control blocks, and returns the resource control block for the RCTL_NEXT flag. To iterate through all resource control blocks, repeatedly swap the resource control block values, as shown here using the rcb_tmp rctl block. rctlblk_t *rcb1, *rcb2, *rcb_tmp;
...
/* Omit return value checking/error processing to keep code sample short */
rcb1 = calloc(1, rctlblk_size()); /* rctl blocks are opaque: */
/* "rctlblk_t rcb" does not work */
rcb2 = calloc(1, rctlblk_size());
getrctl("task.max-lwps", NULL, rcb1, RCTL_FIRST);
while (1) {
print_rctl(rcb1);
rcb_tmp = rcb2;
rcb2 = rcb1;
rcb1 = rcb_tmp; /* swap rcb1 with rcb2 */
if (getrctl("task.max-lwps", rcb2, rcb1, RCTL_NEXT) == -1) {
if (errno == ENOENT) {
break;
} else {
perror("getrctl");
exit (1);
}
}
}
Set project.cpu-shares and Add a New ValueThe key points of the example include the following:
The example gets the project's CPU share allocation, project.cpu-shares, and changes its value to nshares. /* Omit return value checking/error processing to keep code sample short */
blk1 = malloc(rctlblk_size());
getrctl("project.cpu-shares", NULL, blk1, RCTL_FIRST);
my_shares = rctlblk_get_value(blk1);
printout_my_shares(my_shares);
/* if privileged, do the following to */
/* change project.cpu-shares to "nshares" */
blk1 = malloc(rctlblk_size());
blk2 = malloc(rctlblk_size());
if (getrctl("project.cpu-shares", NULL, blk1, RCTL_FIRST) != 0) {
perror("getrctl failed");
exit(1);
}
bcopy(blk1, blk2, rctlblk_size());
rctlblk_set_value(blk1, nshares);
if (setrctl("project.cpu-shares", blk2, blk1, RCTL_REPLACE) != 0) {
perror("setrctl failed");
exit(1);
}
Set LWP Limit Using Resource Control BlocksIn the following example, an application has set a privileged limit of 3000 LWPs that may not be exceeded. In addition, the application has set a basic limit of 2000 LWPs. When this limit is exceeded, a SIGXRES is sent to the application. Upon receiving a SIGXRES, the application might send notification to its child processes that might in turn reduce the number of LWPs the processes use or need. /* Omit return value and error checking */
#include <rctl.h>
rctlblk_t *rcb1, *rcb2;
/*
* Resource control blocks are opaque
* and must be explicitly allocated.
*/
rcb1 = calloc(rctlblk_size());
rcb2 = calloc(rctlblk_size());
/* Install an RCPRIV_PRIVILEGED, v=3000: do not allow more than 3000 LWPs */
rctlblk_set_value(rcb1, 3000);
rctlblk_set_privilege(rcb1, RCPRIV_PRIVILEGED);
rctlblk_set_local_action(rcb1, RCTL_LOCAL_DENY);
setrctl("task.max-lwps", NULL, rcb1, RCTL_INSERT);
/* Install an RCPRIV_BASIC, v=2000 to send SIGXRES when LWPs exceeds 2000 */
rctlblk_set_value(rcb2, 2000);
rctlblk_set_privilege(rcb2, RCPRIV_BASIC);
rctlblk_set_local_action(rcb2, RCTL_LOCAL_SIGNAL, SIGXRES);
setrctl("task.max-lwps", NULL, rcb2, RCTL_INSERT);
Programming Issues Associated With Resource ControlsConsider the following issues when writing your application:
|
|||||||||||||||