| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2012-10-14 21:44:27 +00:00
										 |  |  |  * Asterisk -- An open source telephony toolkit. | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Resource limits | 
					
						
							| 
									
										
										
										
											2017-12-22 09:23:22 -05:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  |  * Copyright (c) 2006 Tilghman Lesher.  All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Tilghman Lesher <res_limit_200607@the-tilghman.com> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This code is released by the author with no restrictions on usage. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-02-24 20:29:41 +00:00
										 |  |  | /*! \file
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \brief Resource limits | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \author Tilghman Lesher <res_limit_200607@the-tilghman.com> | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-07-14 20:28:54 +00:00
										 |  |  | /*** MODULEINFO
 | 
					
						
							|  |  |  | 	<support_level>core</support_level> | 
					
						
							|  |  |  |  ***/ | 
					
						
							| 
									
										
										
										
											2007-02-24 20:29:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | #include "asterisk.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <ctype.h>
 | 
					
						
							|  |  |  | #include <sys/time.h>
 | 
					
						
							|  |  |  | #include <sys/resource.h>
 | 
					
						
							|  |  |  | #include "asterisk/module.h"
 | 
					
						
							|  |  |  | #include "asterisk/cli.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-12-19 21:59:33 +00:00
										 |  |  | /* Find proper rlimit for virtual memory */ | 
					
						
							|  |  |  | #ifdef RLIMIT_AS
 | 
					
						
							|  |  |  | #define VMEM_DEF RLIMIT_AS
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #ifdef RLIMIT_VMEM
 | 
					
						
							|  |  |  | #define VMEM_DEF RLIMIT_VMEM
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-21 21:13:09 +00:00
										 |  |  | static const struct limits { | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | 	int resource; | 
					
						
							|  |  |  | 	char limit[3]; | 
					
						
							|  |  |  | 	char desc[40]; | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 	char clicmd[15]; | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | } limits[] = { | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 	{ RLIMIT_CPU,     "-t", "cpu time", "time" }, | 
					
						
							|  |  |  | 	{ RLIMIT_FSIZE,   "-f", "file size" , "file" }, | 
					
						
							|  |  |  | 	{ RLIMIT_DATA,    "-d", "program data segment", "data" }, | 
					
						
							|  |  |  | 	{ RLIMIT_STACK,   "-s", "program stack size", "stack" }, | 
					
						
							|  |  |  | 	{ RLIMIT_CORE,    "-c", "core file size", "core" }, | 
					
						
							| 
									
										
										
										
											2006-09-26 16:28:01 +00:00
										 |  |  | #ifdef RLIMIT_RSS
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 	{ RLIMIT_RSS,     "-m", "resident memory", "memory" }, | 
					
						
							|  |  |  | 	{ RLIMIT_MEMLOCK, "-l", "amount of memory locked into RAM", "locked" }, | 
					
						
							| 
									
										
										
										
											2007-07-02 20:27:28 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef RLIMIT_NPROC
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 	{ RLIMIT_NPROC,   "-u", "number of processes", "processes" }, | 
					
						
							| 
									
										
										
										
											2006-09-26 16:28:01 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 	{ RLIMIT_NOFILE,  "-n", "number of file descriptors", "descriptors" }, | 
					
						
							| 
									
										
										
										
											2006-12-19 21:59:33 +00:00
										 |  |  | #ifdef VMEM_DEF
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 	{ VMEM_DEF,       "-v", "virtual memory", "virtual" }, | 
					
						
							| 
									
										
										
										
											2006-10-06 16:08:28 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int str2limit(const char *string) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	size_t i; | 
					
						
							| 
									
										
										
										
											2008-07-08 16:40:28 +00:00
										 |  |  | 	for (i = 0; i < ARRAY_LEN(limits); i++) { | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 		if (!strcasecmp(string, limits[i].clicmd)) | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | 			return limits[i].resource; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char *str2desc(const char *string) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	size_t i; | 
					
						
							| 
									
										
										
										
											2008-07-08 16:40:28 +00:00
										 |  |  | 	for (i = 0; i < ARRAY_LEN(limits); i++) { | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 		if (!strcmp(string, limits[i].clicmd)) | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | 			return limits[i].desc; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return "<unknown>"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | static char *complete_ulimit(struct ast_cli_args *a) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int which = 0, i; | 
					
						
							|  |  |  | 	int wordlen = strlen(a->word); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (a->pos > 1) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2008-07-08 16:40:28 +00:00
										 |  |  | 	for (i = 0; i < ARRAY_LEN(limits); i++) { | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 		if (!strncasecmp(limits[i].clicmd, a->word, wordlen)) { | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 			if (++which > a->n) | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 				return ast_strdup(limits[i].clicmd); | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *handle_cli_ulimit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	int resource; | 
					
						
							|  |  |  | 	struct rlimit rlimit = { 0, 0 }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 	case CLI_INIT: | 
					
						
							|  |  |  | 		e->command = "ulimit"; | 
					
						
							|  |  |  | 		e->usage = | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"Usage: ulimit {data|" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | #ifdef RLIMIT_RSS
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"limit|" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"file|" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | #ifdef RLIMIT_RSS
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"memory|" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"stack|time|" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | #ifdef RLIMIT_NPROC
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"processes|" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef VMEM_DEF
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"virtual|" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"core|descriptors} [<num>]\n" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 			"       Shows or sets the corresponding resource limit.\n" | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"         data          Process data segment [readonly]\n" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | #ifdef RLIMIT_RSS
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"         lock          Memory lock size [readonly]\n" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"         file          File size\n" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | #ifdef RLIMIT_RSS
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"         memory        Process resident memory [readonly]\n" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"         stack         Process stack size [readonly]\n" | 
					
						
							|  |  |  | 			"         time          CPU usage [readonly]\n" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | #ifdef RLIMIT_NPROC
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"         processes     Child processes\n" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef VMEM_DEF
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"         virtual       Process virtual memory [readonly]\n" | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			"         core          Core dump file size\n" | 
					
						
							|  |  |  | 			"         descriptors   Number of file descriptors\n"; | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 		return NULL; | 
					
						
							|  |  |  | 	case CLI_GENERATE: | 
					
						
							|  |  |  | 		return complete_ulimit(a); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (a->argc > 3) | 
					
						
							|  |  |  | 		return CLI_SHOWUSAGE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (a->argc == 1) { | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 		char arg2[15]; | 
					
						
							| 
									
										
										
										
											2009-05-21 21:13:09 +00:00
										 |  |  | 		const char * const newargv[2] = { "ulimit", arg2 }; | 
					
						
							| 
									
										
										
										
											2008-07-08 16:40:28 +00:00
										 |  |  | 		for (resource = 0; resource < ARRAY_LEN(limits); resource++) { | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 			struct ast_cli_args newArgs = { .argv = newargv, .argc = 2 }; | 
					
						
							| 
									
										
										
										
											2008-09-28 23:32:14 +00:00
										 |  |  | 			ast_copy_string(arg2, limits[resource].clicmd, sizeof(arg2)); | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 			handle_cli_ulimit(e, CLI_HANDLER, &newArgs); | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 		return CLI_SUCCESS; | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 		resource = str2limit(a->argv[1]); | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | 		if (resource == -1) { | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 			ast_cli(a->fd, "Unknown resource\n"); | 
					
						
							|  |  |  | 			return CLI_FAILURE; | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 		if (a->argc == 3) { | 
					
						
							| 
									
										
										
										
											2006-12-16 02:42:53 +00:00
										 |  |  | 			int x; | 
					
						
							| 
									
										
										
										
											2007-07-02 20:27:28 +00:00
										 |  |  | #ifdef RLIMIT_NPROC
 | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | 			if (resource != RLIMIT_NOFILE && resource != RLIMIT_CORE && resource != RLIMIT_NPROC && resource != RLIMIT_FSIZE) { | 
					
						
							| 
									
										
										
										
											2007-07-02 20:27:28 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 			if (resource != RLIMIT_NOFILE && resource != RLIMIT_CORE && resource != RLIMIT_FSIZE) { | 
					
						
							| 
									
										
										
										
											2007-07-02 20:27:28 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 				ast_cli(a->fd, "Resource not permitted to be set\n"); | 
					
						
							|  |  |  | 				return CLI_FAILURE; | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-10 19:20:57 +00:00
										 |  |  | 			sscanf(a->argv[2], "%30d", &x); | 
					
						
							| 
									
										
										
										
											2006-12-16 02:42:53 +00:00
										 |  |  | 			rlimit.rlim_max = rlimit.rlim_cur = x; | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | 			setrlimit(resource, &rlimit); | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 			return CLI_SUCCESS; | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			if (!getrlimit(resource, &rlimit)) { | 
					
						
							|  |  |  | 				char printlimit[32]; | 
					
						
							|  |  |  | 				const char *desc; | 
					
						
							|  |  |  | 				if (rlimit.rlim_max == RLIM_INFINITY) | 
					
						
							|  |  |  | 					ast_copy_string(printlimit, "effectively unlimited", sizeof(printlimit)); | 
					
						
							|  |  |  | 				else | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 					snprintf(printlimit, sizeof(printlimit), "limited to %d", (int) rlimit.rlim_cur); | 
					
						
							|  |  |  | 				desc = str2desc(a->argv[1]); | 
					
						
							|  |  |  | 				ast_cli(a->fd, "%c%s (%s) is %s.\n", toupper(desc[0]), desc + 1, a->argv[1], printlimit); | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | 			} else | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | 				ast_cli(a->fd, "Could not retrieve resource limits for %s: %s\n", str2desc(a->argv[1]), strerror(errno)); | 
					
						
							|  |  |  | 			return CLI_SUCCESS; | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-10-11 19:03:06 +00:00
										 |  |  | static struct ast_cli_entry cli_ulimit = | 
					
						
							| 
									
										
										
										
											2007-10-22 20:05:18 +00:00
										 |  |  | 	AST_CLI_DEFINE(handle_cli_ulimit, "Set or show process resource limits"); | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static int unload_module(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return ast_cli_unregister(&cli_ulimit); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int load_module(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-04-11 10:07:39 -06:00
										 |  |  | 	return ast_cli_register(&cli_ulimit) ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS; | 
					
						
							| 
									
										
										
										
											2006-09-21 23:01:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Resource limits"); |