Differences between revisions 10 and 11
Revision 10 as of 2008-01-10 19:47:28
Size: 7542
Editor: localhost
Comment: converted to 1.6 markup
Revision 11 as of 2008-01-20 05:13:59
Size: 4222
Editor: EugeneTeo
Comment:
Deletions are marked like this. Additions are marked like this.
Line 14: Line 14:
[[attachment:plimit.stp]] [[attachment:plimit.sh]]
Updated 20 Jan 2008
Line 16: Line 17:
## provide the scripts
## avoid cross-referencing via URLs since those can go stale
{{{
#!/usr/bin/env stap
# plimit.stp
# Copyright (C) 2006 Red Hat, Inc., Eugene Teo <eteo@redhat.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
%{
   #include <linux/sched.h>
   #include <linux/list.h>
%}
function getrlimit:string (rlim:long, pid:long) %{ /* pure */
        struct task_struct *p;
        struct list_head *_p, *_n;
        static char cur_buf[24], max_buf[24];
        long int cur, max;
        list_for_each_safe(_p, _n, &current->tasks) {
                p = list_entry(_p, struct task_struct, tasks);
                cur = p->signal->rlim[THIS->rlim].rlim_cur;
                max = p->signal->rlim[THIS->rlim].rlim_max;
                if (p->pid == (int)THIS->pid) {
                        if (cur == -1 && max == -1)
                                strcat(THIS->__retvalue, "unlimited unlimited");
                        else if (cur == -1)
                                snprintf(THIS->__retvalue, MAXSTRINGLEN, "%-9s %-9ld",
                                        "unlimited", max);
                        else if (max == -1)
                                snprintf(THIS->__retvalue, MAXSTRINGLEN, "%-9ld %-9s",
                                        cur, "unlimited");
                        else
                                snprintf(THIS->__retvalue, MAXSTRINGLEN, "%-9ld %-9ld",
                                        cur, max);
                }
        }
%}
function task_execname_by_pid:string (pid:long) %{ /* pure */
        struct task_struct *p;
        struct list_head *_p, *_n;
        list_for_each_safe(_p, _n, &current->tasks) {
                p = list_entry(_p, struct task_struct, tasks);
                if (p->pid == (int)THIS->pid)
                        snprintf(THIS->__retvalue, MAXSTRINGLEN, "%s", p->comm);
        }
%}
probe begin
{
        printf("%d: -%s\n", $1, task_execname_by_pid($1))
        /* include/asm-generic/resource.h */
        printf(" resource current maximum\n")
        printf("coredump(blocks) %s\n", getrlimit(4, $1))
        printf("data(bytes) %s\n", getrlimit(2, $1))
        printf("max nice %s\n", getrlimit(13, $1))
        printf("file size(blocks) %s\n", getrlimit(1, $1))
        printf("pending signals %s\n", getrlimit(11, $1))
        printf("max locked memory(bytes) %s\n", getrlimit(8, $1))
        printf("max memory size(bytes) %s\n", getrlimit(5, $1))
        printf("open files %s\n", getrlimit(7, $1))
        printf("POSIX message queues(bytes) %s\n", getrlimit(12, $1))
        printf("max rt priority %s\n", getrlimit(14, $1))
        printf("stack size(bytes) %s\n", getrlimit(3, $1))
        printf("cpu time(seconds) %s\n", getrlimit(0, $1))
        printf("max user processes %s\n", getrlimit(6, $1))
        printf("virtual memory(bytes) %s\n", getrlimit(9, $1))
        printf("file locks %s\n", getrlimit(10, $1))
        exit()
}
}}}

plimit for Linux

Problem

In Unix/Linux, ulimit(3) displays and sets user limits for the current process. In Solaris >= 8, there is another handy tool, plimit, that displays and sets per-process user limits on any running arbitrary process. This SystemTap does the display per-process user limits function of the plimit tool.

TODO: I welcome volunteers to help me finish the set per-process user limits bits.

Scripts

plimit.sh Updated 20 Jan 2008

Output

[eteo@kerndev ~]$ ./plimit.stp -g $$
9033:  -bash
 resource                    current    maximum
coredump(blocks)            0          unlimited
data(bytes)                 unlimited  unlimited
max nice                    0          0
file size(blocks)           unlimited  unlimited
pending signals             16366      16366
max locked memory(bytes)    32768      32768
max memory size(bytes)      unlimited  unlimited
open files                  1024       1024
POSIX message queues(bytes) 819200     819200
max rt priority             0          0
stack size(bytes)           10485760   unlimited
cpu time(seconds)           unlimited  unlimited
max user processes          16366      16366
virtual memory(bytes)       unlimited  unlimited
file locks                  unlimited  unlimited
[eteo@kerndev ~]$ ./plimit.stp -g `pgrep gnome-terminal`
3622:  -gnome-terminal
 resource                    current    maximum
coredump(blocks)            0          unlimited
data(bytes)                 unlimited  unlimited
max nice                    0          0
file size(blocks)           unlimited  unlimited
pending signals             16366      16366
max locked memory(bytes)    32768      32768
max memory size(bytes)      unlimited  unlimited
open files                  1024       1024
POSIX message queues(bytes) 819200     819200
max rt priority             0          0
stack size(bytes)           10485760   unlimited
cpu time(seconds)           unlimited  unlimited
max user processes          16366      16366
virtual memory(bytes)       unlimited  unlimited
file locks                  unlimited  unlimited

Patch for RHEL4

plimit.stp will need the following patch to compile on RHEL4. Instead of the patch, it is possible to put KERNEL_VERSION #if/#endif's into the embedded-C code to make it generic.

Without patch the following error occurs:

$ ./plimit.stp -g $$
# Pass 4: compilation failed.  Try again with more '-v' (verbose) options.

*** plimit.stp  2006-10-30 10:46:19.000000000 -0500
--- plimit.stp.new      2007-01-30 09:42:38.000000000 -0500
***************
*** 20,27 ****

        list_for_each_safe(_p, _n, &current->tasks) {
                p = list_entry(_p, struct task_struct, tasks);
!               cur = p->signal->rlim[THIS->rlim].rlim_cur;
!               max = p->signal->rlim[THIS->rlim].rlim_max;

                if (p->pid == (int)THIS->pid) {
                        if (cur == -1 && max == -1)
--- 20,27 ----

        list_for_each_safe(_p, _n, &current->tasks) {
                p = list_entry(_p, struct task_struct, tasks);
!               cur = p->rlim[THIS->rlim].rlim_cur;
!               max = p->rlim[THIS->rlim].rlim_max;

                if (p->pid == (int)THIS->pid) {
                        if (cur == -1 && max == -1)

Lessons

SystemTap gives you the flexibility to write kernel code with the -g guru mode, if necessary. You can start writing useful systems tools that are not available in Linux with SystemTap.


None: WSPlimit (last edited 2008-01-20 05:13:59 by EugeneTeo)