Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/syscall/exacctsys.c
+++ new/usr/src/uts/common/syscall/exacctsys.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 22 /*
23 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 -#pragma ident "%Z%%M% %I% %E% SMI"
28 -
29 27 #include <sys/acctctl.h>
30 28 #include <sys/cmn_err.h>
31 29 #include <sys/cred.h>
32 30 #include <sys/errno.h>
33 31 #include <sys/exacct.h>
34 32 #include <sys/modctl.h>
35 33 #include <sys/procset.h>
36 34 #include <sys/sysmacros.h>
37 35 #include <sys/systm.h>
38 36 #include <sys/task.h>
39 37 #include <sys/types.h>
40 38 #include <sys/user.h>
41 39 #include <sys/policy.h>
42 40
43 41 /*
44 42 * getacct(2), putacct(2), and wracct(2) system calls
45 43 *
46 44 * The extended accounting subsystem provides three root-privileged system
47 45 * calls for interacting with the actual resource data associated with each
48 46 * task or process. getacct() copies a packed exacct record reflecting the
49 47 * resource usage out to the buffer provided by the user. wracct() writes a
50 48 * record to the appropriate extended accounting file. putacct() takes the
51 49 * buffer provided by the user, and appends a "tag" record associated with the
52 50 * specified task or project that encapsulates the user data. All three of
53 51 * these functions exit early if extended accounting is not active for the
54 52 * requested entity type.
55 53 *
56 54 * Locking
57 55 * Under the terminology introduced in os/task.c, all three of these system
58 56 * calls are task observers, when executing on an existing task.
59 57 */
60 58
61 59 /*
62 60 * getacct_callback() is used to copyout the buffer with accounting records
63 61 * from the kernel back to the user. It also sets actual to the size of the
64 62 * kernel buffer--the required minimum size for a successful outbound copy.
65 63 */
66 64 /* ARGSUSED */
67 65 static int
68 66 getacct_callback(ac_info_t *unused, void *ubuf, size_t usize, void *kbuf,
69 67 size_t ksize, size_t *actual)
70 68 {
71 69 size_t size = MIN(usize, ksize);
72 70
73 71 if (ubuf != NULL && copyout(kbuf, ubuf, size) != 0)
74 72 return (EFAULT);
75 73 *actual = ksize;
76 74 return (0);
77 75 }
78 76
79 77 static int
80 78 getacct_task(ac_info_t *ac_task, taskid_t tkid, void *buf, size_t bufsize,
81 79 size_t *sizep)
82 80 {
83 81 task_t *tk;
84 82 int error;
85 83
86 84 mutex_enter(&ac_task->ac_lock);
87 85 if (ac_task->ac_state == AC_OFF) {
88 86 mutex_exit(&ac_task->ac_lock);
89 87 return (ENOTACTIVE);
90 88 }
91 89 mutex_exit(&ac_task->ac_lock);
92 90
93 91 if ((tk = task_hold_by_id(tkid)) == NULL)
94 92 return (ESRCH);
95 93 error = exacct_assemble_task_usage(ac_task, tk,
96 94 getacct_callback, buf, bufsize, sizep, EW_PARTIAL);
97 95 task_rele(tk);
98 96
99 97 return (error);
100 98 }
101 99
102 100 static int
103 101 getacct_proc(ac_info_t *ac_proc, pid_t pid, void *buf, size_t bufsize,
104 102 size_t *sizep)
105 103 {
106 104 proc_t *p;
107 105 proc_usage_t *pu;
108 106 ulong_t mask[AC_MASK_SZ];
109 107 ulong_t *ac_mask = &mask[0];
110 108 int error;
111 109
112 110 mutex_enter(&ac_proc->ac_lock);
113 111 if (ac_proc->ac_state == AC_OFF) {
114 112 mutex_exit(&ac_proc->ac_lock);
115 113 return (ENOTACTIVE);
116 114 }
117 115 bt_copy(&ac_proc->ac_mask[0], ac_mask, AC_MASK_SZ);
118 116 mutex_exit(&ac_proc->ac_lock);
119 117
120 118 pu = kmem_zalloc(sizeof (proc_usage_t), KM_SLEEP);
121 119 pu->pu_command = kmem_zalloc(MAXCOMLEN + 1, KM_SLEEP);
122 120
123 121 mutex_enter(&pidlock);
124 122 if ((p = prfind(pid)) == NULL) {
125 123 mutex_exit(&pidlock);
126 124 kmem_free(pu->pu_command, MAXCOMLEN + 1);
127 125 kmem_free(pu, sizeof (proc_usage_t));
128 126 return (ESRCH);
129 127 }
130 128 mutex_enter(&p->p_lock);
131 129 mutex_exit(&pidlock);
132 130
133 131 exacct_calculate_proc_usage(p, pu, ac_mask, EW_PARTIAL, 0);
134 132 mutex_exit(&p->p_lock);
135 133
136 134 error = exacct_assemble_proc_usage(ac_proc, pu,
137 135 getacct_callback, buf, bufsize, sizep, EW_PARTIAL);
138 136
139 137 kmem_free(pu->pu_command, MAXCOMLEN + 1);
140 138 kmem_free(pu, sizeof (proc_usage_t));
141 139
142 140 return (error);
143 141 }
144 142
145 143 static ssize_t
146 144 getacct(idtype_t idtype, id_t id, void *buf, size_t bufsize)
147 145 {
148 146 size_t size = 0;
149 147 int error;
150 148 struct exacct_globals *acg;
151 149
152 150 if (bufsize > EXACCT_MAX_BUFSIZE)
153 151 bufsize = EXACCT_MAX_BUFSIZE;
154 152
155 153 acg = zone_getspecific(exacct_zone_key, curproc->p_zone);
156 154 switch (idtype) {
157 155 case P_PID:
158 156 error = getacct_proc(&acg->ac_proc, id, buf, bufsize, &size);
159 157 break;
160 158 case P_TASKID:
161 159 error = getacct_task(&acg->ac_task, id, buf, bufsize, &size);
162 160 break;
163 161 default:
164 162 error = EINVAL;
165 163 break;
166 164 }
167 165 return (error == 0 ? (ssize_t)size : set_errno(error));
168 166 }
169 167
170 168 static int
171 169 putacct(idtype_t idtype, id_t id, void *buf, size_t bufsize, int flags)
172 170 {
173 171 int error;
174 172 taskid_t tkid;
175 173 proc_t *p;
176 174 task_t *tk;
177 175 void *kbuf;
178 176 struct exacct_globals *acg;
179 177
180 178 if (bufsize == 0 || bufsize > EXACCT_MAX_BUFSIZE)
181 179 return (set_errno(EINVAL));
182 180
183 181 kbuf = kmem_alloc(bufsize, KM_SLEEP);
184 182 if (copyin(buf, kbuf, bufsize) != 0) {
185 183 error = EFAULT;
186 184 goto out;
187 185 }
188 186
189 187 acg = zone_getspecific(exacct_zone_key, curproc->p_zone);
190 188 switch (idtype) {
191 189 case P_PID:
192 190 mutex_enter(&pidlock);
193 191 if ((p = prfind(id)) == NULL) {
194 192 mutex_exit(&pidlock);
195 193 error = ESRCH;
196 194 } else {
197 195 zone_t *zone = p->p_zone;
198 196
199 197 tkid = p->p_task->tk_tkid;
200 198 zone_hold(zone);
201 199 mutex_exit(&pidlock);
202 200
203 201 error = exacct_tag_proc(&acg->ac_proc, id, tkid, kbuf,
204 202 bufsize, flags, zone->zone_nodename);
205 203 zone_rele(zone);
206 204 }
207 205 break;
208 206 case P_TASKID:
209 207 if ((tk = task_hold_by_id(id)) != NULL) {
210 208 error = exacct_tag_task(&acg->ac_task, tk, kbuf,
211 209 bufsize, flags);
212 210 task_rele(tk);
213 211 } else {
214 212 error = ESRCH;
215 213 }
216 214 break;
217 215 default:
218 216 error = EINVAL;
219 217 break;
220 218 }
221 219 out:
222 220 kmem_free(kbuf, bufsize);
223 221 return (error == 0 ? error : set_errno(error));
224 222 }
225 223
226 224 static int
227 225 wracct_task(ac_info_t *ac_task, taskid_t tkid, int flag, size_t *sizep)
228 226 {
229 227 task_t *tk;
230 228 int error;
231 229
232 230 mutex_enter(&ac_task->ac_lock);
233 231 if (ac_task->ac_state == AC_OFF || ac_task->ac_vnode == NULL) {
234 232 mutex_exit(&ac_task->ac_lock);
235 233 return (ENOTACTIVE);
236 234 }
237 235 mutex_exit(&ac_task->ac_lock);
238 236
239 237 if ((tk = task_hold_by_id(tkid)) == NULL)
240 238 return (ESRCH);
241 239 error = exacct_assemble_task_usage(ac_task, tk, exacct_commit_callback,
242 240 NULL, 0, sizep, flag);
243 241 task_rele(tk);
244 242
245 243 return (error);
246 244 }
247 245
248 246 static int
249 247 wracct_proc(ac_info_t *ac_proc, pid_t pid, int flag, size_t *sizep)
250 248 {
251 249 proc_t *p;
252 250 proc_usage_t *pu;
253 251 ulong_t mask[AC_MASK_SZ];
254 252 ulong_t *ac_mask = &mask[0];
255 253 int error;
256 254
257 255 mutex_enter(&ac_proc->ac_lock);
258 256 if (ac_proc->ac_state == AC_OFF || ac_proc->ac_vnode == NULL) {
259 257 mutex_exit(&ac_proc->ac_lock);
260 258 return (ENOTACTIVE);
261 259 }
262 260 bt_copy(&ac_proc->ac_mask[0], ac_mask, AC_MASK_SZ);
263 261 mutex_exit(&ac_proc->ac_lock);
264 262
265 263 pu = kmem_zalloc(sizeof (proc_usage_t), KM_SLEEP);
266 264 pu->pu_command = kmem_zalloc(MAXCOMLEN + 1, KM_SLEEP);
267 265
268 266 mutex_enter(&pidlock);
269 267 if ((p = prfind(pid)) == NULL) {
270 268 mutex_exit(&pidlock);
271 269 kmem_free(pu->pu_command, MAXCOMLEN + 1);
272 270 kmem_free(pu, sizeof (proc_usage_t));
273 271 return (ESRCH);
274 272 }
275 273 mutex_enter(&p->p_lock);
276 274 mutex_exit(&pidlock);
277 275 exacct_calculate_proc_usage(p, pu, ac_mask, flag, 0);
278 276 mutex_exit(&p->p_lock);
279 277
280 278 error = exacct_assemble_proc_usage(ac_proc, pu,
281 279 exacct_commit_callback, NULL, 0, sizep, flag);
282 280
283 281 kmem_free(pu->pu_command, MAXCOMLEN + 1);
284 282 kmem_free(pu, sizeof (proc_usage_t));
285 283
286 284 return (error);
287 285 }
288 286
289 287 static int
290 288 wracct(idtype_t idtype, id_t id, int flags)
291 289 {
292 290 int error;
293 291 size_t size = 0;
294 292 struct exacct_globals *acg;
295 293
296 294 /*
297 295 * Validate flags.
298 296 */
299 297 switch (flags) {
300 298 case EW_PARTIAL:
301 299 case EW_INTERVAL:
302 300 break;
303 301 default:
304 302 return (set_errno(EINVAL));
305 303 }
306 304
307 305 acg = zone_getspecific(exacct_zone_key, curproc->p_zone);
308 306 switch (idtype) {
309 307 case P_PID:
310 308 if (flags == EW_INTERVAL)
311 309 return (set_errno(ENOTSUP));
312 310 error = wracct_proc(&acg->ac_proc, id, flags, &size);
313 311 break;
314 312 case P_TASKID:
315 313 error = wracct_task(&acg->ac_task, id, flags, &size);
316 314 break;
317 315 default:
318 316 error = EINVAL;
319 317 break;
320 318 }
321 319
322 320 return (error == 0 ? error : set_errno(error));
323 321 }
324 322
325 323 static long
326 324 exacct(int code, idtype_t idtype, id_t id, void *buf, size_t bufsize,
327 325 int flags)
328 326 {
329 327 if (secpolicy_acct(CRED()) != 0)
330 328 return (set_errno(EPERM));
331 329
332 330 if (exacct_zone_key == ZONE_KEY_UNINITIALIZED)
333 331 return (set_errno(ENOTACTIVE));
334 332
335 333 switch (code) {
336 334 case 0:
337 335 return (getacct(idtype, id, buf, bufsize));
338 336 case 1:
339 337 return (putacct(idtype, id, buf, bufsize, flags));
340 338 case 2:
341 339 return (wracct(idtype, id, flags));
342 340 default:
343 341 return (set_errno(EINVAL));
344 342 }
345 343 }
346 344
347 345 #if defined(_LP64)
348 346 #define SE_LRVAL SE_64RVAL
349 347 #else
350 348 #define SE_LRVAL SE_32RVAL1
351 349 #endif
352 350
353 351 static struct sysent exacctsys_sysent = {
354 352 6,
355 353 SE_NOUNLOAD | SE_ARGC | SE_LRVAL,
356 354 (int (*)())exacct
357 355 };
358 356
359 357 static struct modlsys modlsys = {
360 358 &mod_syscallops,
361 359 "extended accounting facility",
362 360 &exacctsys_sysent
363 361 };
364 362
365 363 #ifdef _SYSCALL32_IMPL
366 364
367 365 static struct sysent exacctsys_sysent32 = {
368 366 6,
369 367 SE_NOUNLOAD | SE_ARGC | SE_32RVAL1,
370 368 (int (*)())exacct
371 369 };
372 370
↓ open down ↓ |
334 lines elided |
↑ open up ↑ |
373 371 static struct modlsys modlsys32 = {
374 372 &mod_syscallops32,
375 373 "32-bit extended accounting facility",
376 374 &exacctsys_sysent32
377 375 };
378 376
379 377 #endif
380 378
381 379 static struct modlinkage modlinkage = {
382 380 MODREV_1,
383 - &modlsys,
381 + { &modlsys,
384 382 #ifdef _SYSCALL32_IMPL
385 - &modlsys32,
383 + &modlsys32,
386 384 #endif
387 - NULL
385 + NULL
386 + }
388 387 };
389 388
390 389 int
391 390 _init(void)
392 391 {
393 392 return (mod_install(&modlinkage));
394 393 }
395 394
396 395 int
397 396 _fini(void)
398 397 {
399 398 return (mod_remove(&modlinkage));
400 399 }
401 400
402 401 int
403 402 _info(struct modinfo *mip)
404 403 {
405 404 return (mod_info(&modlinkage, mip));
406 405 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX