// $Id: vlimit.c 2403 2006-11-24 23:06:08Z dhozac $ // 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; #ifndef RLIMIT_MSGQUEUE # define RLIMIT_MSGQUEUE 12 #endif #define NUMLIM(X) \ { #X, required_argument, 0, 2048|X } #define OPT_RESLIM(RES,V) \ { #RES, required_argument, 0, 2048|RLIMIT_##V } #define OPT_VLIMIT(RES,V) \ { #RES, required_argument, 0, 2048|VC_VLIMIT_##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), OPT_RESLIM(msgqueue, MSGQUEUE), OPT_VLIMIT(nsock, NSOCK), OPT_VLIMIT(openfd, OPENFD), OPT_VLIMIT(anon, ANON), OPT_VLIMIT(shmem, SHMEM), OPT_VLIMIT(semary, SEMARY), OPT_VLIMIT(nsems, NSEMS), OPT_VLIMIT(dentry, DENTRY), { 0,0,0,0 } }; #define REV_RESLIM(X) [RLIMIT_##X] = #X #define REV_VLIMIT(X) [VC_VLIMIT_##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), REV_RESLIM(MSGQUEUE), REV_VLIMIT(NSOCK), REV_VLIMIT(OPENFD), REV_VLIMIT(ANON), REV_VLIMIT(SHMEM), REV_VLIMIT(SEMARY), REV_VLIMIT(NSEMS), REV_VLIMIT(DENTRY), }; 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, locks, msgqueue, nsock, openfd, anon, shmem, semary,\n" "nsems, and dentry.\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) { memcpy(ptr, "inf", 3); 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