Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:00:54 2007

Asterisk developer's documentation :: Codename Pineapple


res_limit.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- A telephony toolkit for Linux.
00003  *
00004  * Resource limits
00005  * 
00006  * Copyright (c) 2006 Tilghman Lesher.  All rights reserved.
00007  *
00008  * Tilghman Lesher <res_limit_200607@the-tilghman.com>
00009  *
00010  * This code is released by the author with no restrictions on usage.
00011  *
00012  */
00013 
00014 #include "asterisk.h"
00015 
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #include <unistd.h>
00019 #define _XOPEN_SOURCE 600
00020 #include <string.h>
00021 #include <ctype.h>
00022 #include <sys/time.h>
00023 #include <sys/resource.h>
00024 #include <errno.h>
00025 #include "asterisk/module.h"
00026 #include "asterisk/cli.h"
00027 
00028 /* Find proper rlimit for virtual memory */
00029 #ifdef RLIMIT_AS
00030 #define VMEM_DEF RLIMIT_AS
00031 #else
00032 #ifdef RLIMIT_VMEM
00033 #define VMEM_DEF RLIMIT_VMEM
00034 #endif
00035 #endif
00036 
00037 static struct limits {
00038    int resource;
00039    char limit[3];
00040    char desc[40];
00041 } limits[] = {
00042    { RLIMIT_CPU, "-t", "cpu time" },
00043    { RLIMIT_FSIZE, "-f", "file size" },
00044    { RLIMIT_DATA, "-d", "program data segment" },
00045    { RLIMIT_STACK, "-s", "program stack size" },
00046    { RLIMIT_CORE, "-c", "core file size" },
00047 #ifdef RLIMIT_RSS
00048    { RLIMIT_RSS, "-m", "resident memory" },
00049    { RLIMIT_NPROC, "-u", "number of processes" },
00050    { RLIMIT_MEMLOCK, "-l", "amount of memory locked into RAM" },
00051 #endif
00052    { RLIMIT_NOFILE, "-n", "number of file descriptors" },
00053 #ifdef VMEM_DEF
00054    { VMEM_DEF, "-v", "virtual memory" },
00055 #endif
00056 };
00057 
00058 static int str2limit(const char *string)
00059 {
00060    size_t i;
00061    for (i = 0; i < sizeof(limits) / sizeof(limits[0]); i++) {
00062       if (!strcasecmp(string, limits[i].limit))
00063          return limits[i].resource;
00064    }
00065    return -1;
00066 }
00067 
00068 static const char *str2desc(const char *string)
00069 {
00070    size_t i;
00071    for (i = 0; i < sizeof(limits) / sizeof(limits[0]); i++) {
00072       if (!strcmp(string, limits[i].limit))
00073          return limits[i].desc;
00074    }
00075    return "<unknown>";
00076 }
00077 
00078 static int my_ulimit(int fd, int argc, char **argv)
00079 {
00080    int resource;
00081    struct rlimit rlimit = { 0, 0 };
00082    if (argc > 3)
00083       return RESULT_SHOWUSAGE;
00084 
00085    if (argc == 1) {
00086       char arg2[3];
00087       char *newargv[2] = { "ulimit", arg2 };
00088       for (resource = 0; resource < sizeof(limits) / sizeof(limits[0]); resource++) {
00089          ast_copy_string(arg2, limits[resource].limit, sizeof(arg2));
00090          my_ulimit(fd, 2, newargv);
00091       }
00092       return RESULT_SUCCESS;
00093    } else {
00094       resource = str2limit(argv[1]);
00095       if (resource == -1) {
00096          ast_cli(fd, "Unknown resource\n");
00097          return RESULT_FAILURE;
00098       }
00099 
00100       if (argc == 3) {
00101          int x;
00102          if (resource != RLIMIT_NOFILE && resource != RLIMIT_CORE && resource != RLIMIT_NPROC && resource != RLIMIT_FSIZE) {
00103             ast_cli(fd, "Resource not permitted to be set\n");
00104             return RESULT_FAILURE;
00105          }
00106 
00107          sscanf(argv[2], "%d", &x);
00108          rlimit.rlim_max = rlimit.rlim_cur = x;
00109          setrlimit(resource, &rlimit);
00110          return RESULT_SUCCESS;
00111       } else {
00112          if (!getrlimit(resource, &rlimit)) {
00113             char printlimit[32];
00114             const char *desc;
00115             if (rlimit.rlim_max == RLIM_INFINITY)
00116                ast_copy_string(printlimit, "effectively unlimited", sizeof(printlimit));
00117             else
00118                snprintf(printlimit, sizeof(printlimit), "limited to %d", (int)rlimit.rlim_cur);
00119             desc = str2desc(argv[1]);
00120             ast_cli(fd, "%c%s (%s) is %s.\n", toupper(desc[0]), desc + 1, argv[1], printlimit);
00121          } else
00122             ast_cli(fd, "Could not retrieve resource limits for %s: %s\n", str2desc(argv[1]), strerror(errno));
00123          return RESULT_SUCCESS;
00124       }
00125    }
00126 }
00127 
00128 static char *complete_ulimit(const char *line, const char *word, int pos, int state)
00129 {
00130    int which = 0, i;
00131    int wordlen = strlen(word);
00132 
00133    if (pos > 2)
00134       return NULL;
00135    for (i = 0; i < sizeof(limits) / sizeof(limits[0]); i++) {
00136       if (!strncasecmp(limits[i].limit, word, wordlen)) {
00137          if (++which > state)
00138             return ast_strdup(limits[i].limit);
00139       }
00140    }
00141    return NULL;
00142 }
00143 
00144 static const char ulimit_usage[] =
00145 "Usage: ulimit {-d|-l|-f|-m|-s|-t|-u|-v|-c|-n} [<num>]\n"
00146 "       Shows or sets the corresponding resource limit.\n"
00147 "         -d  Process data segment [readonly]\n"
00148 "         -l  Memory lock size [readonly]\n"
00149 "         -f  File size\n"
00150 "         -m  Process resident memory [readonly]\n"
00151 "         -s  Process stack size [readonly]\n"
00152 "         -t  CPU usage [readonly]\n"
00153 "         -u  Child processes\n"
00154 #ifdef VMEM_DEF
00155 "         -v  Process virtual memory [readonly]\n"
00156 #endif
00157 "         -c  Core dump file size\n"
00158 "         -n  Number of file descriptors\n";
00159 
00160 static struct ast_cli_entry cli_ulimit = {
00161    { "ulimit", NULL }, my_ulimit,
00162    "Set or show process resource limits", ulimit_usage, complete_ulimit };
00163 
00164 static int unload_module(void)
00165 {
00166    return ast_cli_unregister(&cli_ulimit);
00167 }
00168 
00169 static int load_module(void)
00170 {
00171    return ast_cli_register(&cli_ulimit)? AST_MODULE_LOAD_FAILURE: AST_MODULE_LOAD_SUCCESS;
00172 }
00173 
00174 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Resource limits");
00175 

Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen