Wed Jan 8 2020 09:49:50

Asterisk developer's documentation


res_limit.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Resource limits
5  *
6  * Copyright (c) 2006 Tilghman Lesher. All rights reserved.
7  *
8  * Tilghman Lesher <res_limit_200607@the-tilghman.com>
9  *
10  * This code is released by the author with no restrictions on usage.
11  *
12  */
13 
14 /*! \file
15  *
16  * \brief Resource limits
17  *
18  * \author Tilghman Lesher <res_limit_200607@the-tilghman.com>
19  */
20 
21 /*** MODULEINFO
22  <support_level>core</support_level>
23  ***/
24 
25 #include "asterisk.h"
26 
27 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328209 $")
28 
29 #include <ctype.h>
30 #include <sys/time.h>
31 #include <sys/resource.h>
32 #include "asterisk/module.h"
33 #include "asterisk/cli.h"
34 
35 /* Find proper rlimit for virtual memory */
36 #ifdef RLIMIT_AS
37 #define VMEM_DEF RLIMIT_AS
38 #else
39 #ifdef RLIMIT_VMEM
40 #define VMEM_DEF RLIMIT_VMEM
41 #endif
42 #endif
43 
44 static const struct limits {
45  int resource;
46  char limit[3];
47  char desc[40];
48  char clicmd[15];
49 } limits[] = {
50  { RLIMIT_CPU, "-t", "cpu time", "time" },
51  { RLIMIT_FSIZE, "-f", "file size" , "file" },
52  { RLIMIT_DATA, "-d", "program data segment", "data" },
53  { RLIMIT_STACK, "-s", "program stack size", "stack" },
54  { RLIMIT_CORE, "-c", "core file size", "core" },
55 #ifdef RLIMIT_RSS
56  { RLIMIT_RSS, "-m", "resident memory", "memory" },
57  { RLIMIT_MEMLOCK, "-l", "amount of memory locked into RAM", "locked" },
58 #endif
59 #ifdef RLIMIT_NPROC
60  { RLIMIT_NPROC, "-u", "number of processes", "processes" },
61 #endif
62  { RLIMIT_NOFILE, "-n", "number of file descriptors", "descriptors" },
63 #ifdef VMEM_DEF
64  { VMEM_DEF, "-v", "virtual memory", "virtual" },
65 #endif
66 };
67 
68 static int str2limit(const char *string)
69 {
70  size_t i;
71  for (i = 0; i < ARRAY_LEN(limits); i++) {
72  if (!strcasecmp(string, limits[i].clicmd))
73  return limits[i].resource;
74  }
75  return -1;
76 }
77 
78 static const char *str2desc(const char *string)
79 {
80  size_t i;
81  for (i = 0; i < ARRAY_LEN(limits); i++) {
82  if (!strcmp(string, limits[i].clicmd))
83  return limits[i].desc;
84  }
85  return "<unknown>";
86 }
87 
88 static char *complete_ulimit(struct ast_cli_args *a)
89 {
90  int which = 0, i;
91  int wordlen = strlen(a->word);
92 
93  if (a->pos > 1)
94  return NULL;
95  for (i = 0; i < ARRAY_LEN(limits); i++) {
96  if (!strncasecmp(limits[i].clicmd, a->word, wordlen)) {
97  if (++which > a->n)
98  return ast_strdup(limits[i].clicmd);
99  }
100  }
101  return NULL;
102 }
103 
104 static char *handle_cli_ulimit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
105 {
106  int resource;
107  struct rlimit rlimit = { 0, 0 };
108 
109  switch (cmd) {
110  case CLI_INIT:
111  e->command = "ulimit";
112  e->usage =
113  "Usage: ulimit {data|"
114 #ifdef RLIMIT_RSS
115  "limit|"
116 #endif
117  "file|"
118 #ifdef RLIMIT_RSS
119  "memory|"
120 #endif
121  "stack|time|"
122 #ifdef RLIMIT_NPROC
123  "processes|"
124 #endif
125 #ifdef VMEM_DEF
126  "virtual|"
127 #endif
128  "core|descriptors} [<num>]\n"
129  " Shows or sets the corresponding resource limit.\n"
130  " data Process data segment [readonly]\n"
131 #ifdef RLIMIT_RSS
132  " lock Memory lock size [readonly]\n"
133 #endif
134  " file File size\n"
135 #ifdef RLIMIT_RSS
136  " memory Process resident memory [readonly]\n"
137 #endif
138  " stack Process stack size [readonly]\n"
139  " time CPU usage [readonly]\n"
140 #ifdef RLIMIT_NPROC
141  " processes Child processes\n"
142 #endif
143 #ifdef VMEM_DEF
144  " virtual Process virtual memory [readonly]\n"
145 #endif
146  " core Core dump file size\n"
147  " descriptors Number of file descriptors\n";
148  return NULL;
149  case CLI_GENERATE:
150  return complete_ulimit(a);
151  }
152 
153  if (a->argc > 3)
154  return CLI_SHOWUSAGE;
155 
156  if (a->argc == 1) {
157  char arg2[15];
158  const char * const newargv[2] = { "ulimit", arg2 };
159  for (resource = 0; resource < ARRAY_LEN(limits); resource++) {
160  struct ast_cli_args newArgs = { .argv = newargv, .argc = 2 };
161  ast_copy_string(arg2, limits[resource].clicmd, sizeof(arg2));
162  handle_cli_ulimit(e, CLI_HANDLER, &newArgs);
163  }
164  return CLI_SUCCESS;
165  } else {
166  resource = str2limit(a->argv[1]);
167  if (resource == -1) {
168  ast_cli(a->fd, "Unknown resource\n");
169  return CLI_FAILURE;
170  }
171 
172  if (a->argc == 3) {
173  int x;
174 #ifdef RLIMIT_NPROC
175  if (resource != RLIMIT_NOFILE && resource != RLIMIT_CORE && resource != RLIMIT_NPROC && resource != RLIMIT_FSIZE) {
176 #else
177  if (resource != RLIMIT_NOFILE && resource != RLIMIT_CORE && resource != RLIMIT_FSIZE) {
178 #endif
179  ast_cli(a->fd, "Resource not permitted to be set\n");
180  return CLI_FAILURE;
181  }
182 
183  sscanf(a->argv[2], "%30d", &x);
184  rlimit.rlim_max = rlimit.rlim_cur = x;
185  setrlimit(resource, &rlimit);
186  return CLI_SUCCESS;
187  } else {
188  if (!getrlimit(resource, &rlimit)) {
189  char printlimit[32];
190  const char *desc;
191  if (rlimit.rlim_max == RLIM_INFINITY)
192  ast_copy_string(printlimit, "effectively unlimited", sizeof(printlimit));
193  else
194  snprintf(printlimit, sizeof(printlimit), "limited to %d", (int) rlimit.rlim_cur);
195  desc = str2desc(a->argv[1]);
196  ast_cli(a->fd, "%c%s (%s) is %s.\n", toupper(desc[0]), desc + 1, a->argv[1], printlimit);
197  } else
198  ast_cli(a->fd, "Could not retrieve resource limits for %s: %s\n", str2desc(a->argv[1]), strerror(errno));
199  return CLI_SUCCESS;
200  }
201  }
202 }
203 
204 static struct ast_cli_entry cli_ulimit =
205  AST_CLI_DEFINE(handle_cli_ulimit, "Set or show process resource limits");
206 
207 static int unload_module(void)
208 {
209  return ast_cli_unregister(&cli_ulimit);
210 }
211 
212 static int load_module(void)
213 {
215 }
216 
218 
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:396
Asterisk main include file. File version handling, generic pbx functions.
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int resource
Definition: res_limit.c:45
int ast_cli_register(struct ast_cli_entry *e)
Registers a command or an array of commands.
Definition: cli.c:2159
#define ast_strdup(a)
Definition: astmm.h:109
int ast_cli_unregister(struct ast_cli_entry *e)
Unregisters a command or an array of commands.
Definition: cli.c:2153
descriptor for a cli entry.
Definition: cli.h:165
const int argc
Definition: cli.h:154
Definition: cli.h:146
static struct ast_cli_entry cli_ulimit
Definition: res_limit.c:204
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
static int unload_module(void)
Definition: res_limit.c:207
static const char * str2desc(const char *string)
Definition: res_limit.c:78
static int str2limit(const char *string)
Definition: res_limit.c:68
char clicmd[15]
Definition: res_limit.c:48
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
static char * handle_cli_ulimit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition: res_limit.c:104
const char *const * argv
Definition: cli.h:155
static const char desc[]
Definition: cdr_radius.c:85
#define CLI_SHOWUSAGE
Definition: cli.h:44
char limit[3]
Definition: res_limit.c:46
#define CLI_FAILURE
Definition: cli.h:45
int errno
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char * complete_ulimit(struct ast_cli_args *a)
Definition: res_limit.c:88
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
char desc[40]
Definition: res_limit.c:47
const int pos
Definition: cli.h:158
static int load_module(void)
Definition: res_limit.c:212
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
Asterisk module definitions.
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180