// $Id: vlimit.c,v 1.20 2005/03/24 12:44:17 ensc Exp $ // Copyright (C) 2003 Enrico Scholz // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /* Set the global per context limit of a resource (memory, file handle). This utility can do it either for the current context or a selected one. It uses the same options as ulimit, when possible */ #ifdef HAVE_CONFIG_H # include #endif #include "compat.h" #include "vserver.h" #include "internal.h" #include "util.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #define ENSC_WRAPPERS_PREFIX "vlimit: " #define ENSC_WRAPPERS_UNISTD 1 #define ENSC_WRAPPERS_VSERVER 1 #include #define CMD_HELP 0x1000 #define CMD_VERSION 0x1001 #define CMD_XID 0x4000 #define CMD_DIR 0x8000 #define CMD_MISSINGOK 0x8001 int wrapper_exit_code = 255; #define NUMLIM(X) \ { #X, required_argument, 0, 2048|X } #define OPT_RESLIM(RES,V) \ { #RES, required_argument, 0, 2048|RLIMIT_##V } static struct option const CMDLINE_OPTIONS[] = { { "help", no_argument, 0, CMD_HELP }, { "version", no_argument, 0, CMD_VERSION }, { "all", no_argument, 0, 'a' }, { "xid", required_argument, 0, CMD_XID }, { "dir", required_argument, 0, CMD_DIR }, { "missingok", no_argument, 0, CMD_MISSINGOK }, NUMLIM( 0), NUMLIM( 1), NUMLIM( 2), NUMLIM( 3), NUMLIM( 4), NUMLIM( 5), NUMLIM( 6), NUMLIM( 7), NUMLIM( 8), NUMLIM( 9), NUMLIM(10), NUMLIM(11), NUMLIM(12), NUMLIM(13), NUMLIM(14), NUMLIM(15), NUMLIM(16), NUMLIM(17), NUMLIM(18), NUMLIM(19), NUMLIM(20), NUMLIM(21), NUMLIM(22), NUMLIM(23), NUMLIM(24), NUMLIM(25), NUMLIM(26), NUMLIM(27), NUMLIM(28), NUMLIM(29), NUMLIM(30), NUMLIM(31), OPT_RESLIM(cpu, CPU), OPT_RESLIM(fsize, FSIZE), OPT_RESLIM(data, DATA), OPT_RESLIM(stack, STACK), OPT_RESLIM(core, CORE), OPT_RESLIM(rss, RSS), OPT_RESLIM(nproc, NPROC), OPT_RESLIM(nofile, NOFILE), OPT_RESLIM(memlock, MEMLOCK), OPT_RESLIM(as, AS), OPT_RESLIM(locks, LOCKS), { 0,0,0,0 } }; #define REV_RESLIM(X) [RLIMIT_##X] = #X static char const * const LIMIT_STR[] = { REV_RESLIM(CPU), REV_RESLIM(FSIZE), REV_RESLIM(DATA), REV_RESLIM(STACK), REV_RESLIM(CORE), REV_RESLIM(RSS), REV_RESLIM(NPROC), REV_RESLIM(NOFILE), REV_RESLIM(MEMLOCK), REV_RESLIM(AS), REV_RESLIM(LOCKS) }; static void showHelp(int fd, char const *cmd, int res) { VSERVER_DECLARE_CMD(cmd); WRITE_MSG(fd, "Usage: "); WRITE_STR(fd, cmd); WRITE_MSG(fd, " [--xid|-c ] [-nd] [-a|--all] [[-MSH] --(|) ]*\n" " [--dir [--missingok]] [--] [ *]\n\n" "Options:\n" " -c|--xid \n" " ... operate on context \n" " -a|--all ... show all available limits\n" " -n ... do not resolve limit-names\n" " -d ... show limits in decimal\n" " -M ... set Minimum limit\n" " -S ... set Soft limit\n" " -H ... set Hard limit (assumed by default, when neither\n" " M nor S was requested)\n" " --dir \n" " ... read limits from /; allowed filenames are\n" " and .{min,soft,hard}. When a limit\n" " was set by the CLI already, the corresponding file\n" " will be ignored\n" " --missingok ... do not fail when does not exist\n" " --| \n" " ... set specified (MSH) limit for to \n\n" "Valid values for resource are cpu, fsize, data, stack, core, rss, nproc,\n" "nofile, memlock, as and locks.\n\n" "Please report bugs to " PACKAGE_BUGREPORT "\n"); exit(res); } static void showVersion() { WRITE_MSG(1, "vlimit " VERSION " -- limits context-resources\n" "This program is part of " PACKAGE_STRING "\n\n" "Copyright (C) 2003 Enrico Scholz\n" VERSION_COPYRIGHT_DISCLAIMER); exit(0); } static size_t fmtHex(char *ptr, vc_limit_t lim) { memcpy(ptr, "0x", 2); return utilvserver_fmt_xuint64(ptr+2, lim) + 2; } static bool do_resolve = true; static size_t (*fmt_func)(char *, vc_limit_t) = fmtHex; static void * appendLimit(char *ptr, bool do_it, vc_limit_t lim) { memcpy(ptr, " ", 2); ptr += 2; if (do_it) { if (lim==VC_LIM_INFINITY) { strcpy(ptr, "inf"); ptr += 3; } else { ptr += (*fmt_func)(ptr, lim); *ptr = ' '; } } else { memcpy(ptr, "N/A", 3); ptr += 3; } return ptr; } static void showAll(int ctx) { struct vc_rlimit_mask mask; size_t i; if (vc_get_rlimit_mask(ctx, &mask)==-1) { perror("vc_get_rlimit_mask()"); exit(wrapper_exit_code); } for (i=0; i<32; ++i) { uint32_t bitmask = (1<0 && pathname[l_pathname-1]!='/') buf[l_pathname++] = '/'; for (i=0; i