resource.c revision 3b09ebe724b1ee233ce2314a8b70a4dfdf9d2b07
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 XLAT(RLIMIT_AS), 39#endif 40#ifdef RLIMIT_CORE 41 XLAT(RLIMIT_CORE), 42#endif 43#ifdef RLIMIT_CPU 44 XLAT(RLIMIT_CPU), 45#endif 46#ifdef RLIMIT_DATA 47 XLAT(RLIMIT_DATA), 48#endif 49#ifdef RLIMIT_FSIZE 50 XLAT(RLIMIT_FSIZE), 51#endif 52#ifdef RLIMIT_LOCKS 53 XLAT(RLIMIT_LOCKS), 54#endif 55#ifdef RLIMIT_MEMLOCK 56 XLAT(RLIMIT_MEMLOCK), 57#endif 58#ifdef RLIMIT_MSGQUEUE 59 XLAT(RLIMIT_MSGQUEUE), 60#endif 61#ifdef RLIMIT_NICE 62 XLAT(RLIMIT_NICE), 63#endif 64#ifdef RLIMIT_NOFILE 65 XLAT(RLIMIT_NOFILE), 66#endif 67#ifdef RLIMIT_NPROC 68 XLAT(RLIMIT_NPROC), 69#endif 70#ifdef RLIMIT_RSS 71 XLAT(RLIMIT_RSS), 72#endif 73#ifdef RLIMIT_RTPRIO 74 XLAT(RLIMIT_RTPRIO), 75#endif 76#ifdef RLIMIT_RTTIME 77 XLAT(RLIMIT_RTTIME), 78#endif 79#ifdef RLIMIT_SIGPENDING 80 XLAT(RLIMIT_SIGPENDING), 81#endif 82#ifdef RLIMIT_STACK 83 XLAT(RLIMIT_STACK), 84#endif 85#ifdef RLIMIT_VMEM 86 XLAT(RLIMIT_VMEM), 87#endif 88 XLAT_END 89}; 90 91static const char * 92sprint_rlim64(uint64_t lim) 93{ 94 static char buf[sizeof(uint64_t)*3 + sizeof("*1024")]; 95 96 if (lim == UINT64_MAX) 97 return "RLIM64_INFINITY"; 98 99 if (lim > 1024 && lim % 1024 == 0) 100 sprintf(buf, "%" PRIu64 "*1024", lim / 1024); 101 else 102 sprintf(buf, "%" PRIu64, lim); 103 return buf; 104} 105 106static void 107print_rlimit64(struct tcb *tcp, unsigned long addr) 108{ 109 struct rlimit_64 { 110 uint64_t rlim_cur; 111 uint64_t rlim_max; 112 } rlim; 113 114 if (umove(tcp, addr, &rlim) < 0) 115 tprintf("%#lx", addr); 116 else { 117 tprintf("{rlim_cur=%s,", sprint_rlim64(rlim.rlim_cur)); 118 tprintf(" rlim_max=%s}", sprint_rlim64(rlim.rlim_max)); 119 } 120} 121 122static void 123decode_rlimit64(struct tcb *tcp, unsigned long addr) 124{ 125 if (!addr) 126 tprints("NULL"); 127 else if (!verbose(tcp) || 128 (exiting(tcp) && syserror(tcp))) 129 tprintf("%#lx", addr); 130 else 131 print_rlimit64(tcp, addr); 132} 133 134#if !defined(current_wordsize) || current_wordsize == 4 135 136static const char * 137sprint_rlim32(uint32_t lim) 138{ 139 static char buf[sizeof(uint32_t)*3 + sizeof("*1024")]; 140 141 if (lim == UINT32_MAX) 142 return "RLIM_INFINITY"; 143 144 if (lim > 1024 && lim % 1024 == 0) 145 sprintf(buf, "%" PRIu32 "*1024", lim / 1024); 146 else 147 sprintf(buf, "%" PRIu32, lim); 148 return buf; 149} 150 151static void 152print_rlimit32(struct tcb *tcp, unsigned long addr) 153{ 154 struct rlimit_32 { 155 uint32_t rlim_cur; 156 uint32_t rlim_max; 157 } rlim; 158 159 if (umove(tcp, addr, &rlim) < 0) 160 tprintf("%#lx", addr); 161 else { 162 tprintf("{rlim_cur=%s,", sprint_rlim32(rlim.rlim_cur)); 163 tprintf(" rlim_max=%s}", sprint_rlim32(rlim.rlim_max)); 164 } 165} 166 167static void 168decode_rlimit(struct tcb *tcp, unsigned long addr) 169{ 170 if (!addr) 171 tprints("NULL"); 172 else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp))) 173 tprintf("%#lx", addr); 174 else { 175# if defined(X86_64) || defined(X32) 176 /* 177 * i386 is the only personality on X86_64 and X32 178 * with 32-bit rlim_t. 179 * When current_personality is X32, current_wordsize 180 * equals to 4 but rlim_t is 64-bit. 181 */ 182 if (current_personality == 1) 183# else 184 if (current_wordsize == 4) 185# endif 186 print_rlimit32(tcp, addr); 187 else 188 print_rlimit64(tcp, addr); 189 } 190} 191 192#else /* defined(current_wordsize) && current_wordsize != 4 */ 193 194# define decode_rlimit decode_rlimit64 195 196#endif 197 198int 199sys_getrlimit(struct tcb *tcp) 200{ 201 if (entering(tcp)) { 202 printxval(resources, tcp->u_arg[0], "RLIMIT_???"); 203 tprints(", "); 204 } 205 else { 206 decode_rlimit(tcp, tcp->u_arg[1]); 207 } 208 return 0; 209} 210 211int 212sys_setrlimit(struct tcb *tcp) 213{ 214 if (entering(tcp)) { 215 printxval(resources, tcp->u_arg[0], "RLIMIT_???"); 216 tprints(", "); 217 decode_rlimit(tcp, tcp->u_arg[1]); 218 } 219 return 0; 220} 221 222int 223sys_prlimit64(struct tcb *tcp) 224{ 225 if (entering(tcp)) { 226 tprintf("%ld, ", tcp->u_arg[0]); 227 printxval(resources, tcp->u_arg[1], "RLIMIT_???"); 228 tprints(", "); 229 decode_rlimit64(tcp, tcp->u_arg[2]); 230 tprints(", "); 231 } else { 232 decode_rlimit64(tcp, tcp->u_arg[3]); 233 } 234 return 0; 235} 236 237static const struct xlat usagewho[] = { 238 XLAT(RUSAGE_SELF), 239 XLAT(RUSAGE_CHILDREN), 240#ifdef RUSAGE_BOTH 241 XLAT(RUSAGE_BOTH), 242#endif 243 XLAT_END 244}; 245 246#ifdef ALPHA 247void 248printrusage32(struct tcb *tcp, long addr) 249{ 250 struct timeval32 { 251 unsigned tv_sec; 252 unsigned tv_usec; 253 }; 254 struct rusage32 { 255 struct timeval32 ru_utime; /* user time used */ 256 struct timeval32 ru_stime; /* system time used */ 257 long ru_maxrss; /* maximum resident set size */ 258 long ru_ixrss; /* integral shared memory size */ 259 long ru_idrss; /* integral unshared data size */ 260 long ru_isrss; /* integral unshared stack size */ 261 long ru_minflt; /* page reclaims */ 262 long ru_majflt; /* page faults */ 263 long ru_nswap; /* swaps */ 264 long ru_inblock; /* block input operations */ 265 long ru_oublock; /* block output operations */ 266 long ru_msgsnd; /* messages sent */ 267 long ru_msgrcv; /* messages received */ 268 long ru_nsignals; /* signals received */ 269 long ru_nvcsw; /* voluntary context switches */ 270 long ru_nivcsw; /* involuntary " */ 271 } ru; 272 273 if (!addr) 274 tprints("NULL"); 275 else if (syserror(tcp) || !verbose(tcp)) 276 tprintf("%#lx", addr); 277 else if (umove(tcp, addr, &ru) < 0) 278 tprints("{...}"); 279 else if (!abbrev(tcp)) { 280 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ", 281 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec, 282 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec); 283 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ", 284 ru.ru_maxrss, ru.ru_ixrss); 285 tprintf("ru_idrss=%lu, ru_isrss=%lu, ", 286 ru.ru_idrss, ru.ru_isrss); 287 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ", 288 ru.ru_minflt, ru.ru_majflt, ru.ru_nswap); 289 tprintf("ru_inblock=%lu, ru_oublock=%lu, ", 290 ru.ru_inblock, ru.ru_oublock); 291 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ", 292 ru.ru_msgsnd, ru.ru_msgrcv); 293 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}", 294 ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw); 295 } 296 else { 297 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}", 298 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec, 299 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec); 300 } 301} 302#endif 303 304void 305printrusage(struct tcb *tcp, long addr) 306{ 307 struct rusage ru; 308 309 if (!addr) 310 tprints("NULL"); 311 else if (syserror(tcp) || !verbose(tcp)) 312 tprintf("%#lx", addr); 313 else if (umove(tcp, addr, &ru) < 0) 314 tprints("{...}"); 315 else if (!abbrev(tcp)) { 316 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ", 317 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec, 318 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec); 319 tprintf("ru_maxrss=%lu, ru_ixrss=%lu, ", 320 ru.ru_maxrss, ru.ru_ixrss); 321 tprintf("ru_idrss=%lu, ru_isrss=%lu, ", 322 ru.ru_idrss, ru.ru_isrss); 323 tprintf("ru_minflt=%lu, ru_majflt=%lu, ru_nswap=%lu, ", 324 ru.ru_minflt, ru.ru_majflt, ru.ru_nswap); 325 tprintf("ru_inblock=%lu, ru_oublock=%lu, ", 326 ru.ru_inblock, ru.ru_oublock); 327 tprintf("ru_msgsnd=%lu, ru_msgrcv=%lu, ", 328 ru.ru_msgsnd, ru.ru_msgrcv); 329 tprintf("ru_nsignals=%lu, ru_nvcsw=%lu, ru_nivcsw=%lu}", 330 ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw); 331 } 332 else { 333 tprintf("{ru_utime={%lu, %lu}, ru_stime={%lu, %lu}, ...}", 334 (long) ru.ru_utime.tv_sec, (long) ru.ru_utime.tv_usec, 335 (long) ru.ru_stime.tv_sec, (long) ru.ru_stime.tv_usec); 336 } 337} 338 339int 340sys_getrusage(struct tcb *tcp) 341{ 342 if (entering(tcp)) { 343 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???"); 344 tprints(", "); 345 } 346 else 347 printrusage(tcp, tcp->u_arg[1]); 348 return 0; 349} 350 351#ifdef ALPHA 352int 353sys_osf_getrusage(struct tcb *tcp) 354{ 355 if (entering(tcp)) { 356 printxval(usagewho, tcp->u_arg[0], "RUSAGE_???"); 357 tprints(", "); 358 } 359 else 360 printrusage32(tcp, tcp->u_arg[1]); 361 return 0; 362} 363#endif /* ALPHA */ 364 365int 366sys_sysinfo(struct tcb *tcp) 367{ 368 struct sysinfo si; 369 370 if (exiting(tcp)) { 371 if (syserror(tcp) || !verbose(tcp)) 372 tprintf("%#lx", tcp->u_arg[0]); 373 else if (umove(tcp, tcp->u_arg[0], &si) < 0) 374 tprints("{...}"); 375 else { 376 tprintf("{uptime=%lu, loads=[%lu, %lu, %lu] ", 377 (long) si.uptime, (long) si.loads[0], 378 (long) si.loads[1], (long) si.loads[2]); 379 tprintf("totalram=%lu, freeram=%lu, ", 380 (long) si.totalram, (long) si.freeram); 381 tprintf("sharedram=%lu, bufferram=%lu} ", 382 (long) si.sharedram, (long) si.bufferram); 383 tprintf("totalswap=%lu, freeswap=%lu, procs=%u}", 384 (long) si.totalswap, (long) si.freeswap, 385 (unsigned)si.procs); 386 } 387 } 388 return 0; 389} 390 391static const struct xlat priorities[] = { 392 XLAT(PRIO_PROCESS), 393 XLAT(PRIO_PGRP), 394 XLAT(PRIO_USER), 395 XLAT_END 396}; 397 398int 399sys_getpriority(struct tcb *tcp) 400{ 401 if (entering(tcp)) { 402 printxval(priorities, tcp->u_arg[0], "PRIO_???"); 403 tprintf(", %lu", tcp->u_arg[1]); 404 } 405 return 0; 406} 407 408int 409sys_setpriority(struct tcb *tcp) 410{ 411 if (entering(tcp)) { 412 printxval(priorities, tcp->u_arg[0], "PRIO_???"); 413 tprintf(", %lu, %ld", tcp->u_arg[1], tcp->u_arg[2]); 414 } 415 return 0; 416} 417 418int 419sys_times(struct tcb *tcp) 420{ 421 struct tms tbuf; 422 423 if (exiting(tcp)) { 424 if (tcp->u_arg[0] == 0) 425 tprints("NULL"); 426 else if (syserror(tcp)) 427 tprintf("%#lx", tcp->u_arg[0]); 428 else if (umove(tcp, tcp->u_arg[0], &tbuf) < 0) 429 tprints("{...}"); 430 else { 431 tprintf("{tms_utime=%llu, tms_stime=%llu, ", 432 (unsigned long long) tbuf.tms_utime, 433 (unsigned long long) tbuf.tms_stime); 434 tprintf("tms_cutime=%llu, tms_cstime=%llu}", 435 (unsigned long long) tbuf.tms_cutime, 436 (unsigned long long) tbuf.tms_cstime); 437 } 438 } 439 return 0; 440} 441