resource.c revision 9fd4f96d2a2527ac7ca90c156bfc11ce10118684
1/* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "defs.h" 32#include <sys/resource.h> 33#include <sys/times.h> 34#include <linux/kernel.h> 35 36static const struct xlat resources[] = { 37#ifdef RLIMIT_AS 38 { RLIMIT_AS, "RLIMIT_AS" }, 39#endif 40#ifdef RLIMIT_CORE 41 { RLIMIT_CORE, "RLIMIT_CORE" }, 42#endif 43#ifdef RLIMIT_CPU 44 { RLIMIT_CPU, "RLIMIT_CPU" }, 45#endif 46#ifdef RLIMIT_DATA 47 { RLIMIT_DATA, "RLIMIT_DATA" }, 48#endif 49#ifdef RLIMIT_FSIZE 50 { RLIMIT_FSIZE, "RLIMIT_FSIZE" }, 51#endif 52#ifdef RLIMIT_LOCKS 53 { RLIMIT_LOCKS, "RLIMIT_LOCKS" }, 54#endif 55#ifdef RLIMIT_MEMLOCK 56 { RLIMIT_MEMLOCK, "RLIMIT_MEMLOCK" }, 57#endif 58#ifdef RLIMIT_MSGQUEUE 59 { RLIMIT_MSGQUEUE, "RLIMIT_MSGQUEUE" }, 60#endif 61#ifdef RLIMIT_NICE 62 { RLIMIT_NICE, "RLIMIT_NICE" }, 63#endif 64#ifdef RLIMIT_NOFILE 65 { RLIMIT_NOFILE, "RLIMIT_NOFILE" }, 66#endif 67#ifdef RLIMIT_NPROC 68 { RLIMIT_NPROC, "RLIMIT_NPROC" }, 69#endif 70#ifdef RLIMIT_RSS 71 { RLIMIT_RSS, "RLIMIT_RSS" }, 72#endif 73#ifdef RLIMIT_RTPRIO 74 { RLIMIT_RTPRIO, "RLIMIT_RTPRIO" }, 75#endif 76#ifdef RLIMIT_RTTIME 77 { RLIMIT_RTTIME, "RLIMIT_RTTIME" }, 78#endif 79#ifdef RLIMIT_SIGPENDING 80 { RLIMIT_SIGPENDING, "RLIMIT_SIGPENDING" }, 81#endif 82#ifdef RLIMIT_STACK 83 { RLIMIT_STACK, "RLIMIT_STACK" }, 84#endif 85#ifdef RLIMIT_VMEM 86 { RLIMIT_VMEM, "RLIMIT_VMEM" }, 87#endif 88 { 0, NULL } 89}; 90 91#if !(SIZEOF_RLIM_T == 4 || SIZEOF_RLIM_T == 8) 92# error "Unsupported SIZEOF_RLIM_T value" 93#endif 94 95static const char * 96sprint_rlim64(uint64_t lim) 97{ 98 static char buf[sizeof(uint64_t)*3 + sizeof("*1024")]; 99 100 if (lim == UINT64_MAX) 101 return "RLIM64_INFINITY"; 102 103 if (lim > 1024 && lim % 1024 == 0) 104 sprintf(buf, "%" PRIu64 "*1024", lim / 1024); 105 else 106 sprintf(buf, "%" PRIu64, lim); 107 return buf; 108} 109 110static void 111print_rlimit64(struct tcb *tcp, unsigned long addr) 112{ 113 struct rlimit_64 { 114 uint64_t rlim_cur; 115 uint64_t rlim_max; 116 } rlim; 117 118 if (umove(tcp, addr, &rlim) < 0) 119 tprintf("%#lx", addr); 120 else { 121 tprintf("{rlim_cur=%s,", sprint_rlim64(rlim.rlim_cur)); 122 tprintf(" rlim_max=%s}", sprint_rlim64(rlim.rlim_max)); 123 } 124} 125 126static void 127decode_rlimit64(struct tcb *tcp, unsigned long addr) 128{ 129 if (!addr) 130 tprints("NULL"); 131 else if (!verbose(tcp) || 132 (exiting(tcp) && syserror(tcp))) 133 tprintf("%#lx", addr); 134 else 135 print_rlimit64(tcp, addr); 136} 137 138#if SIZEOF_RLIM_T == 4 || SUPPORTED_PERSONALITIES > 1 139 140static const char * 141sprint_rlim32(uint32_t lim) 142{ 143 static char buf[sizeof(uint32_t)*3 + sizeof("*1024")]; 144 145 if (lim == UINT32_MAX) 146 return "RLIM_INFINITY"; 147 148 if (lim > 1024 && lim % 1024 == 0) 149 sprintf(buf, "%" PRIu32 "*1024", lim / 1024); 150 else 151 sprintf(buf, "%" PRIu32, lim); 152 return buf; 153} 154 155static void 156print_rlimit32(struct tcb *tcp, unsigned long addr) 157{ 158 struct rlimit_32 { 159 uint32_t rlim_cur; 160 uint32_t rlim_max; 161 } rlim; 162 163 if (umove(tcp, addr, &rlim) < 0) 164 tprintf("%#lx", addr); 165 else { 166 tprintf("{rlim_cur=%s,", sprint_rlim32(rlim.rlim_cur)); 167 tprintf(" rlim_max=%s}", sprint_rlim32(rlim.rlim_max)); 168 } 169} 170 171static void 172decode_rlimit(struct tcb *tcp, unsigned long addr) 173{ 174 if (!addr) 175 tprints("NULL"); 176 else if (!verbose(tcp) || 177 (exiting(tcp) && syserror(tcp))) 178 tprintf("%#lx", addr); 179 else { 180# if SIZEOF_RLIM_T == 4 181 print_rlimit32(tcp, addr); 182# else 183 if (current_wordsize == 4) 184 print_rlimit32(tcp, addr); 185 else 186 print_rlimit64(tcp, addr); 187# endif 188 } 189} 190 191#else /* SIZEOF_RLIM_T == 8 && SUPPORTED_PERSONALITIES == 1 */ 192 193# define decode_rlimit decode_rlimit64 194 195#endif /* SIZEOF_RLIM_T == 4 || SUPPORTED_PERSONALITIES > 1 */ 196 197int 198sys_getrlimit(struct tcb *tcp) 199{ 200 if (entering(tcp)) { 201 printxval(resources, tcp->u_arg[0], "RLIMIT_???"); 202 tprints(", "); 203 } 204 else { 205 decode_rlimit(tcp, tcp->u_arg[1]); 206 } 207 return 0; 208} 209 210int 211sys_setrlimit(struct tcb *tcp) 212{ 213 if (entering(tcp)) { 214 printxval(resources, tcp->u_arg[0], "RLIMIT_???"); 215 tprints(", "); 216 decode_rlimit(tcp, tcp->u_arg[1]); 217 } 218 return 0; 219} 220 221int 222sys_prlimit64(struct tcb *tcp) 223{ 224 if (entering(tcp)) { 225 tprintf("%ld, ", tcp->u_arg[0]); 226 printxval(resources, tcp->u_arg[1], "RLIMIT_???"); 227 tprints(", "); 228 decode_rlimit64(tcp, tcp->u_arg[2]); 229 tprints(", "); 230 } else { 231 decode_rlimit64(tcp, tcp->u_arg[3]); 232 } 233 return 0; 234} 235 236static const struct xlat usagewho[] = { 237 { RUSAGE_SELF, "RUSAGE_SELF" }, 238 { RUSAGE_CHILDREN, "RUSAGE_CHILDREN" }, 239#ifdef RUSAGE_BOTH 240 { RUSAGE_BOTH, "RUSAGE_BOTH" }, 241#endif 242 { 0, NULL }, 243}; 244 245#ifdef ALPHA 246void 247printrusage32(struct tcb *tcp, long addr) 248{ 249 struct timeval32 { 250 unsigned tv_sec; 251 unsigned tv_usec; 252 }; 253 struct rusage32 { 254 struct timeval32 ru_utime; /* user time used */ 255 struct timeval32 ru_stime; /* system time used */ 256 long ru_maxrss; /* maximum resident set size */ 257 long ru_ixrss; /* integral shared memory size */ 258 long ru_idrss; /* integral unshared data size */ 259 long ru_isrss; /* integral unshared stack size */ 260 long ru_minflt; /* page reclaims */ 261 long ru_majflt; /* page faults */ 262 long ru_nswap; /* swaps */ 263 long ru_inblock; /* block input operations */ 264 long ru_oublock; /* block output operations */ 265 long ru_msgsnd; /* messages sent */ 266 long ru_msgrcv; /* messages received */ 267 long ru_nsignals; /* signals received */ 268 long ru_nvcsw; /* voluntary context switches */ 269 long ru_nivcsw; /* involuntary " */ 270 } ru; 271 272 if (!addr) 273 tprints("NULL"); 274 else if (syserror(tcp) || !verbose(tcp)) 275 tprintf("%#lx", addr); 276 else if (umove(tcp, addr, &ru) < 0) 277 tprints("{...}"); 278 else if (!abbrev(tcp)) { 279 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ", 280 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec, 281 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec); 282 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ", 283 ru.ru_maxrss, ru.ru_ixrss); 284 tprintf("ru_idrss=%lu, ru_isrss=%lu, ", 285 ru.ru_idrss, ru.ru_isrss); 286 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ", 287 ru.ru_minflt, ru.ru_majflt, ru.ru_nswap); 288 tprintf("ru_inblock=%lu, ru_oublock=%lu, ", 289 ru.ru_inblock, ru.ru_oublock); 290 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ", 291 ru.ru_msgsnd, ru.ru_msgrcv); 292 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}", 293 ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw); 294 } 295 else { 296 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}", 297 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec, 298 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec); 299 } 300} 301#endif 302 303void 304printrusage(struct tcb *tcp, long addr) 305{ 306 struct rusage ru; 307 308 if (!addr) 309 tprints("NULL"); 310 else if (syserror(tcp) || !verbose(tcp)) 311 tprintf("%#lx", addr); 312 else if (umove(tcp, addr, &ru) < 0) 313 tprints("{...}"); 314 else if (!abbrev(tcp)) { 315 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ", 316 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec, 317 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec); 318 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ", 319 ru.ru_maxrss, ru.ru_ixrss); 320 tprintf("ru_idrss=%lu, ru_isrss=%lu, ", 321 ru.ru_idrss, ru.ru_isrss); 322 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ", 323 ru.ru_minflt, ru.ru_majflt, ru.ru_nswap); 324 tprintf("ru_inblock=%lu, ru_oublock=%lu, ", 325 ru.ru_inblock, ru.ru_oublock); 326 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ", 327 ru.ru_msgsnd, ru.ru_msgrcv); 328 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}", 329 ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw); 330 } 331 else { 332 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}", 333 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec, 334 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec); 335 } 336} 337 338int 339sys_getrusage(struct tcb *tcp) 340{ 341 if (entering(tcp)) { 342 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???"); 343 tprints(", "); 344 } 345 else 346 printrusage(tcp, tcp->u_arg[1]); 347 return 0; 348} 349 350#ifdef ALPHA 351int 352sys_osf_getrusage(struct tcb *tcp) 353{ 354 if (entering(tcp)) { 355 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???"); 356 tprints(", "); 357 } 358 else 359 printrusage32(tcp, tcp->u_arg[1]); 360 return 0; 361} 362#endif /* ALPHA */ 363 364int 365sys_sysinfo(struct tcb *tcp) 366{ 367 struct sysinfo si; 368 369 if (exiting(tcp)) { 370 if (syserror(tcp) || !verbose(tcp)) 371 tprintf("%#lx", tcp->u_arg[0]); 372 else if (umove(tcp, tcp->u_arg[0], &si) < 0) 373 tprints("{...}"); 374 else { 375 tprintf("{uptime=%lu, loads=[%lu, %lu, %lu] ", 376 (long) si.uptime, (long) si.loads[0], 377 (long) si.loads[1], (long) si.loads[2]); 378 tprintf("totalram=%lu, freeram=%lu, ", 379 (long) si.totalram, (long) si.freeram); 380 tprintf("sharedram=%lu, bufferram=%lu} ", 381 (long) si.sharedram, (long) si.bufferram); 382 tprintf("totalswap=%lu, freeswap=%lu, procs=%hu}", 383 (long) si.totalswap, (long) si.freeswap, 384 si.procs); 385 } 386 } 387 return 0; 388} 389 390static const struct xlat priorities[] = { 391 { PRIO_PROCESS, "PRIO_PROCESS" }, 392 { PRIO_PGRP, "PRIO_PGRP" }, 393 { PRIO_USER, "PRIO_USER" }, 394 { 0, NULL }, 395}; 396 397int 398sys_getpriority(struct tcb *tcp) 399{ 400 if (entering(tcp)) { 401 printxval(priorities, tcp->u_arg[0], "PRIO_???"); 402 tprintf(", %lu", tcp->u_arg[1]); 403 } 404 return 0; 405} 406 407int 408sys_setpriority(struct tcb *tcp) 409{ 410 if (entering(tcp)) { 411 printxval(priorities, tcp->u_arg[0], "PRIO_???"); 412 tprintf(", %lu, %ld", tcp->u_arg[1], tcp->u_arg[2]); 413 } 414 return 0; 415} 416 417int 418sys_times(struct tcb *tcp) 419{ 420 struct tms tbuf; 421 422 if (exiting(tcp)) { 423 if (tcp->u_arg[0] == 0) 424 tprints("NULL"); 425 else if (syserror(tcp)) 426 tprintf("%#lx", tcp->u_arg[0]); 427 else if (umove(tcp, tcp->u_arg[0], &tbuf) < 0) 428 tprints("{...}"); 429 else { 430 tprintf("{tms_utime=%lu, tms_stime=%lu, ", 431 tbuf.tms_utime, tbuf.tms_stime); 432 tprintf("tms_cutime=%lu, tms_cstime=%lu}", 433 tbuf.tms_cutime, tbuf.tms_cstime); 434 } 435 } 436 return 0; 437} 438