X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=util-vserver%2Fsrc%2Fvlimit.c;h=9ff8921330718784489dcefbc18356cd9999dc44;hb=a917f24ef7b003dcef54a3db2644cf9cb4bc2db2;hp=cf1b536f4bc6b797515606a077d7151430ca4d28;hpb=fa4001e7f2b8556105c213f239b35ac2065dcf12;p=util-vserver.git diff --git a/util-vserver/src/vlimit.c b/util-vserver/src/vlimit.c index cf1b536..9ff8921 100644 --- a/util-vserver/src/vlimit.c +++ b/util-vserver/src/vlimit.c @@ -41,17 +41,37 @@ #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 RESLIM(RES,V) \ +#define OPT_RESLIM(RES,V) \ { #RES, required_argument, 0, 2048|RLIMIT_##V } static struct option const CMDLINE_OPTIONS[] = { - { "help", no_argument, 0, 'h' }, - { "version", no_argument, 0, 'v' }, - { "all", no_argument, 0, 'a' }, + { "help", no_argument, 0, CMD_HELP }, + { "version", no_argument, 0, CMD_VERSION }, + { "all", no_argument, 0, 'a' }, + { "xid", no_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), @@ -60,17 +80,17 @@ CMDLINE_OPTIONS[] = { NUMLIM(20), NUMLIM(21), NUMLIM(22), NUMLIM(23), NUMLIM(24), NUMLIM(25), NUMLIM(26), NUMLIM(27), NUMLIM(28), NUMLIM(29), NUMLIM(30), NUMLIM(31), - RESLIM(cpu, CPU), - RESLIM(fsize, FSIZE), - RESLIM(data, DATA), - RESLIM(stack, STACK), - RESLIM(core, CORE), - RESLIM(rss, RSS), - RESLIM(nproc, NPROC), - RESLIM(nofile, NOFILE), - RESLIM(memlock, MEMLOCK), - RESLIM(as, AS), - RESLIM(locks, LOCKS), + 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 } }; @@ -89,9 +109,11 @@ showHelp(int fd, char const *cmd, int res) WRITE_MSG(fd, "Usage: "); WRITE_STR(fd, cmd); WRITE_MSG(fd, - " -c [-nd] [-a|--all] [[-MSH] --(|) ]*\n\n" + " [--xid|-c ] [-nd] [-a|--all] [[-MSH] --(|) ]*\n" + " [--dir [--missingok]] [--] [ *]\n\n" "Options:\n" - " -c ... operate on context \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" @@ -99,6 +121,12 @@ showHelp(int fd, char const *cmd, int res) " -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" @@ -135,7 +163,7 @@ appendLimit(char *ptr, bool do_it, vc_limit_t lim) ptr += 2; if (do_it) { if (lim==VC_LIM_INFINITY) { - strcpy(ptr, "INF"); + strcpy(ptr, "inf"); ptr += 3; } else { @@ -159,7 +187,7 @@ showAll(int ctx) if (vc_get_rlimit_mask(ctx, &mask)==-1) { perror("vc_get_rlimit_mask()"); - exit(1); + exit(wrapper_exit_code); } for (i=0; i<32; ++i) { @@ -205,14 +233,103 @@ setLimits(int ctx, struct vc_rlimit const limits[], uint32_t mask) } } +static vc_limit_t +readValue(int fd, char const *filename) +{ + char buf[128]; + size_t len = Eread(fd, buf, sizeof(buf)-1); + vc_limit_t res; + + buf[len] = '\0'; + + if (!vc_parseLimit(buf, &res)) { + WRITE_MSG(2, "Invalid limit in '"); + WRITE_STR(2, filename); + WRITE_STR(2, "'\n"); + exit(wrapper_exit_code); + } + + return res; +} + +static bool +readFile(char const *file, char *base, char const *suffix, + vc_limit_t *limit) +{ + int fd; + + strcpy(base, suffix); + fd = open(file, O_RDONLY); + if (fd!=-1) { + *limit = readValue(fd, file); + Eclose(fd); + } + + return fd!=-1; +} + +static void +readFromDir(struct vc_rlimit limits[32], uint_least32_t *mask, + char const *pathname, bool missing_ok) +{ + struct stat st; + size_t i; + size_t l_pathname = strlen(pathname); + char buf[l_pathname + sizeof("/memlock.hard") + 32]; + + if (stat(pathname, &st)==-1) { + if (errno==ENOENT && missing_ok) return; + PERROR_Q("vlimit: fstat", pathname); + exit(wrapper_exit_code); + } + + memcpy(buf, pathname, l_pathname); + if (l_pathname>0 && pathname[l_pathname-1]!='/') + buf[l_pathname++] = '/'; + + for (i=0; i