1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include "lint.h"
30 #include <sys/rctl_impl.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <rctl.h>
34
35 /*
36 * Resource control routines
37 *
38 * rctl_walk(3C)
39 *
40 * Resource control block manipulation routines
41 * The setrctl(2) and getrctl(2) interfaces are accessed via opaque resource
42 * control blocks, the characteristics of which are in turn set and fetched
43 * using the following functions. Applications using the following interfaces
44 * will be binary compatible across enhancements to the resource control
45 * subsystem that involve modification of the control block.
46 */
47 int
rctl_walk(int (* callback)(const char * rctlname,void * walk_data),void * init_data)48 rctl_walk(int (*callback)(const char *rctlname, void *walk_data),
49 void *init_data)
50 {
51 int ret = 0;
52 char *ctl_names, *curr_name;
53 size_t sz = rctllist(NULL, 0);
54
55 if ((ctl_names = malloc(sz)) == NULL)
56 return (-1);
57
58 (void) rctllist(ctl_names, sz);
59
60 for (curr_name = ctl_names;
61 curr_name < ctl_names + sz;
62 curr_name += strlen(curr_name) + 1) {
63 if (ret = callback(curr_name, init_data)) {
64 free(ctl_names);
65 return (ret);
66 }
67 }
68
69 free(ctl_names);
70 return (ret);
71 }
72
73 uint_t
rctlblk_get_global_action(rctlblk_t * rblk)74 rctlblk_get_global_action(rctlblk_t *rblk)
75 {
76 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
77
78 return (ropaque->rcq_global_flagaction & (~RCTL_GLOBAL_ACTION_MASK));
79 }
80
81 uint_t
rctlblk_get_local_action(rctlblk_t * rblk,int * signal)82 rctlblk_get_local_action(rctlblk_t *rblk, int *signal)
83 {
84 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
85
86 if (signal != NULL)
87 *signal = ropaque->rcq_local_signal;
88 return (ropaque->rcq_local_flagaction & (~RCTL_LOCAL_ACTION_MASK));
89 }
90
91 uint_t
rctlblk_get_global_flags(rctlblk_t * rblk)92 rctlblk_get_global_flags(rctlblk_t *rblk)
93 {
94 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
95
96 return (ropaque->rcq_global_flagaction & RCTL_GLOBAL_ACTION_MASK);
97 }
98
99 uint_t
rctlblk_get_local_flags(rctlblk_t * rblk)100 rctlblk_get_local_flags(rctlblk_t *rblk)
101 {
102 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
103
104 return (ropaque->rcq_local_flagaction & RCTL_LOCAL_ACTION_MASK);
105 }
106
107 hrtime_t
rctlblk_get_firing_time(rctlblk_t * rblk)108 rctlblk_get_firing_time(rctlblk_t *rblk)
109 {
110 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
111
112 return (ropaque->rcq_firing_time);
113 }
114
115 id_t
rctlblk_get_recipient_pid(rctlblk_t * rblk)116 rctlblk_get_recipient_pid(rctlblk_t *rblk)
117 {
118 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
119
120 return (ropaque->rcq_local_recipient_pid);
121 }
122
123 rctl_priv_t
rctlblk_get_privilege(rctlblk_t * rblk)124 rctlblk_get_privilege(rctlblk_t *rblk)
125 {
126 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
127 return (ropaque->rcq_privilege);
128 }
129
130 rctl_qty_t
rctlblk_get_value(rctlblk_t * rblk)131 rctlblk_get_value(rctlblk_t *rblk)
132 {
133 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
134 return (ropaque->rcq_value);
135 }
136
137 rctl_qty_t
rctlblk_get_enforced_value(rctlblk_t * rblk)138 rctlblk_get_enforced_value(rctlblk_t *rblk)
139 {
140 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
141 return (ropaque->rcq_enforced_value);
142 }
143
144 void
rctlblk_set_local_action(rctlblk_t * rblk,uint_t action,int signal)145 rctlblk_set_local_action(rctlblk_t *rblk, uint_t action, int signal)
146 {
147 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
148 ropaque->rcq_local_signal = signal;
149 ropaque->rcq_local_flagaction = (ropaque->rcq_local_flagaction &
150 RCTL_LOCAL_ACTION_MASK) | (action & ~RCTL_LOCAL_ACTION_MASK);
151 }
152
153 void
rctlblk_set_local_flags(rctlblk_t * rblk,uint_t flags)154 rctlblk_set_local_flags(rctlblk_t *rblk, uint_t flags)
155 {
156 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
157 ropaque->rcq_local_flagaction = (ropaque->rcq_local_flagaction &
158 ~RCTL_LOCAL_ACTION_MASK) | (flags & RCTL_LOCAL_ACTION_MASK);
159 }
160
161 void
rctlblk_set_recipient_pid(rctlblk_t * rblk,id_t pid)162 rctlblk_set_recipient_pid(rctlblk_t *rblk, id_t pid)
163 {
164 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
165 ropaque->rcq_local_recipient_pid = pid;
166 }
167
168 void
rctlblk_set_privilege(rctlblk_t * rblk,rctl_priv_t privilege)169 rctlblk_set_privilege(rctlblk_t *rblk, rctl_priv_t privilege)
170 {
171 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
172 ropaque->rcq_privilege = privilege;
173 }
174
175 void
rctlblk_set_value(rctlblk_t * rblk,rctl_qty_t value)176 rctlblk_set_value(rctlblk_t *rblk, rctl_qty_t value)
177 {
178 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
179 ropaque->rcq_value = value;
180 }
181
182 size_t
rctlblk_size(void)183 rctlblk_size(void)
184 {
185 return (sizeof (rctl_opaque_t));
186 }
187