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