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 #include "lint.h"
28 #include <sys/rctl_impl.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <rctl.h>
32
33 /*
34 * Resource control routines
35 *
36 * rctl_walk(3C)
37 *
38 * Resource control block manipulation routines
39 * The setrctl(2) and getrctl(2) interfaces are accessed via opaque resource
40 * control blocks, the characteristics of which are in turn set and fetched
41 * using the following functions. Applications using the following interfaces
42 * will be binary compatible across enhancements to the resource control
43 * subsystem that involve modification of the control block.
44 */
45 int
rctl_walk(int (* callback)(const char * rctlname,void * walk_data),void * init_data)46 rctl_walk(int (*callback)(const char *rctlname, void *walk_data),
47 void *init_data)
48 {
49 int ret = 0;
50 char *ctl_names, *curr_name;
51 size_t sz = rctllist(NULL, 0);
52
53 if ((ctl_names = malloc(sz)) == NULL)
54 return (-1);
55
56 (void) rctllist(ctl_names, sz);
57
58 for (curr_name = ctl_names;
59 curr_name < ctl_names + sz;
60 curr_name += strlen(curr_name) + 1) {
61 ret = callback(curr_name, init_data);
62 if (ret != 0) {
63 free(ctl_names);
64 return (ret);
65 }
66 }
67
68 free(ctl_names);
69 return (ret);
70 }
71
72 uint_t
rctlblk_get_global_action(rctlblk_t * rblk)73 rctlblk_get_global_action(rctlblk_t *rblk)
74 {
75 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
76
77 return (ropaque->rcq_global_flagaction & (~RCTL_GLOBAL_ACTION_MASK));
78 }
79
80 uint_t
rctlblk_get_local_action(rctlblk_t * rblk,int * signal)81 rctlblk_get_local_action(rctlblk_t *rblk, int *signal)
82 {
83 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
84
85 if (signal != NULL)
86 *signal = ropaque->rcq_local_signal;
87 return (ropaque->rcq_local_flagaction & (~RCTL_LOCAL_ACTION_MASK));
88 }
89
90 uint_t
rctlblk_get_global_flags(rctlblk_t * rblk)91 rctlblk_get_global_flags(rctlblk_t *rblk)
92 {
93 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
94
95 return (ropaque->rcq_global_flagaction & RCTL_GLOBAL_ACTION_MASK);
96 }
97
98 uint_t
rctlblk_get_local_flags(rctlblk_t * rblk)99 rctlblk_get_local_flags(rctlblk_t *rblk)
100 {
101 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
102
103 return (ropaque->rcq_local_flagaction & RCTL_LOCAL_ACTION_MASK);
104 }
105
106 hrtime_t
rctlblk_get_firing_time(rctlblk_t * rblk)107 rctlblk_get_firing_time(rctlblk_t *rblk)
108 {
109 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
110
111 return (ropaque->rcq_firing_time);
112 }
113
114 id_t
rctlblk_get_recipient_pid(rctlblk_t * rblk)115 rctlblk_get_recipient_pid(rctlblk_t *rblk)
116 {
117 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
118
119 return (ropaque->rcq_local_recipient_pid);
120 }
121
122 rctl_priv_t
rctlblk_get_privilege(rctlblk_t * rblk)123 rctlblk_get_privilege(rctlblk_t *rblk)
124 {
125 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
126 return (ropaque->rcq_privilege);
127 }
128
129 rctl_qty_t
rctlblk_get_value(rctlblk_t * rblk)130 rctlblk_get_value(rctlblk_t *rblk)
131 {
132 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
133 return (ropaque->rcq_value);
134 }
135
136 rctl_qty_t
rctlblk_get_enforced_value(rctlblk_t * rblk)137 rctlblk_get_enforced_value(rctlblk_t *rblk)
138 {
139 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
140 return (ropaque->rcq_enforced_value);
141 }
142
143 void
rctlblk_set_local_action(rctlblk_t * rblk,uint_t action,int signal)144 rctlblk_set_local_action(rctlblk_t *rblk, uint_t action, int signal)
145 {
146 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
147 ropaque->rcq_local_signal = signal;
148 ropaque->rcq_local_flagaction = (ropaque->rcq_local_flagaction &
149 RCTL_LOCAL_ACTION_MASK) | (action & ~RCTL_LOCAL_ACTION_MASK);
150 }
151
152 void
rctlblk_set_local_flags(rctlblk_t * rblk,uint_t flags)153 rctlblk_set_local_flags(rctlblk_t *rblk, uint_t flags)
154 {
155 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
156 ropaque->rcq_local_flagaction = (ropaque->rcq_local_flagaction &
157 ~RCTL_LOCAL_ACTION_MASK) | (flags & RCTL_LOCAL_ACTION_MASK);
158 }
159
160 void
rctlblk_set_recipient_pid(rctlblk_t * rblk,id_t pid)161 rctlblk_set_recipient_pid(rctlblk_t *rblk, id_t pid)
162 {
163 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
164 ropaque->rcq_local_recipient_pid = pid;
165 }
166
167 void
rctlblk_set_privilege(rctlblk_t * rblk,rctl_priv_t privilege)168 rctlblk_set_privilege(rctlblk_t *rblk, rctl_priv_t privilege)
169 {
170 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
171 ropaque->rcq_privilege = privilege;
172 }
173
174 void
rctlblk_set_value(rctlblk_t * rblk,rctl_qty_t value)175 rctlblk_set_value(rctlblk_t *rblk, rctl_qty_t value)
176 {
177 rctl_opaque_t *ropaque = (rctl_opaque_t *)rblk;
178 ropaque->rcq_value = value;
179 }
180
181 size_t
rctlblk_size(void)182 rctlblk_size(void)
183 {
184 return (sizeof (rctl_opaque_t));
185 }
186