From: Mark Huang Date: Sun, 21 Aug 2005 22:21:04 +0000 (+0000) Subject: - sync to util-vserver-0.30.208 X-Git-Tag: after-util-vserver-0_30_208-revert~136 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;ds=sidebyside;h=c8e332f973e76d2fc044d281671719005ad194eb;p=util-vserver.git - sync to util-vserver-0.30.208 - mef: please verify that this version of the tool works the same as the one that you backported --- diff --git a/src/vdlimit.c b/src/vdlimit.c index beea0c5..4e5b09e 100644 --- a/src/vdlimit.c +++ b/src/vdlimit.c @@ -1,174 +1,275 @@ +// $Id: vdlimit.c,v 1.2 2005/03/24 12:44:17 ensc Exp $ --*- c -*-- + +// Copyright (C) 2005 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; version 2 of the License. +// +// 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. -/* -** (c) 2004 Herbert Poetzl -** -** V0.01 ioctls so far -** -*/ #ifdef HAVE_CONFIG_H # include #endif -#include "compat.h" -#include -#include +#include "util.h" +#include +#include + +#include + +#include +#include #include -#include -#include -#include -#include -#include -#include -#include - -#include "vserver.h" -#include "vserver-internal.h" -#include "dlimit.h" - -#ifdef O_LARGEFILE -#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE) -#else -#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK) -#endif +#include +#include -static char err_flag = 0; +#define ENSC_WRAPPERS_PREFIX "vdlimit: " +#define ENSC_WRAPPERS_UNISTD 1 +#define ENSC_WRAPPERS_VSERVER 1 +#include -static char opt_xid = 0; -static char opt_flag = 0; -static char opt_vers = 0; -static char opt_add = 0; -static char opt_rem = 0; -static char opt_set = 0; +#define CMD_HELP 0x1000 +#define CMD_VERSION 0x1001 -static char * cmd_name = NULL; -static char * set_arg = NULL; +int wrapper_exit_code = 1; -static int num_xid = 0; -static int num_flag = 0; +struct option const +CMDLINE_OPTIONS[] = { + { "help", no_argument, 0, CMD_HELP }, + { "version", no_argument, 0, CMD_VERSION }, + { "xid", required_argument, 0, 'x' }, + { "set", required_argument, 0, 's' }, + { "remove", no_argument, 0, 'd' }, + { "flags", required_argument, 0, 'f' }, + {0,0,0,0} +}; +static void +showHelp(int fd, char const *cmd) +{ + WRITE_MSG(fd, "Usage: "); + WRITE_STR(fd, cmd); + WRITE_MSG(fd, + " --xid [--flags ] (--set =|--remove) \n" + "\n" + " --set|-s = ... set to , where limit is \n" + " one of: space_used, space_total, inodes_used,\n" + " inodes_total, reserved\n" + " --remove|-d ... removes the disk limit for from \n" + "\n" + "Please report bugs to " PACKAGE_BUGREPORT "\n"); + exit(0); +} +static void +showVersion() +{ + WRITE_MSG(1, + "vdlimit " VERSION " -- manages disk limits\n" + "This program is part of " PACKAGE_STRING "\n\n" + "Copyright (C) 2005 Enrico Scholz\n" + VERSION_COPYRIGHT_DISCLAIMER); + exit(0); +} -#define OPTIONS "+hadf:x:S:V" +static void +setDlimit(char const *filename, xid_t xid, uint32_t flags, struct vc_ctx_dlimit const *limit) +{ + if (vc_get_dlimit(filename, xid, flags, 0) == -1) { + if (vc_add_dlimit(filename, xid, flags) == -1) { + perror(ENSC_WRAPPERS_PREFIX "vc_add_dlimit()"); + exit(wrapper_exit_code); + } + } + if (vc_set_dlimit(filename, xid, flags, limit) == -1) { + perror(ENSC_WRAPPERS_PREFIX "vc_set_dlimit()"); + exit(wrapper_exit_code); + } +} -int main(int argc, char *argv[]) +static void +remDlimit(char const *filename, xid_t xid, uint32_t flags) { - extern int optind; - extern char *optarg; - char c, errflg = 0; - int r; - - - cmd_name = argv[0]; - while ((c = getopt(argc, argv, OPTIONS)) != EOF) { - switch (c) { - case 'h': - fprintf(stderr, - "This is %s " VERSION "\n" - "options are:\n" - "-h print this help message\n" - "-a add dlimit entry\n" - "-d delete dlimit entry\n" - "-f flag value in decimal\n" - "-x context id\n" - "-S current/limit values\n" - "-V verify interface version\n" - "-- end of options\n" - ,cmd_name); - exit(0); - break; - case 'a': - opt_add = 1; - break; - case 'd': - opt_rem = 1; - break; - case 'f': - num_flag = atol(optarg); - opt_flag = 1; - break; - case 'x': - num_xid = atol(optarg); - opt_xid = 1; - break; - case 'S': - set_arg = optarg; - opt_set = 1; - break; - case 'V': - opt_vers = 1; - break; - case '?': - default: - errflg++; - break; - } - } - if (errflg) { - fprintf(stderr, - "Usage: %s -[" OPTIONS "] ...\n" - "%s -h for help.\n", - cmd_name, cmd_name); - exit(2); - } - - if (opt_vers) { - r = vc_get_version(); - if (r<0) - perror("vc_get_version"); - else - printf("version: %04x:%04x\n", - (r>>16)&0xFFFF, r&0xFFFF); - } + if (vc_rem_dlimit(filename, xid, flags) == -1) { + perror(ENSC_WRAPPERS_PREFIX "vc_rem_dlimit()"); + exit(wrapper_exit_code); + } +} - for (; optind < argc; optind++) { - struct vcmd_ctx_dlimit_base_v0 init; - struct vcmd_ctx_dlimit_v0 data; - - init.name = argv[optind]; - init.flags = num_flag; - - if (opt_rem) { - r = vserver(VCMD_rem_dlimit, num_xid, &init); - if (r<0) - perror("vc_rem_dlimit"); - } - if (opt_add) { - r = vserver(VCMD_add_dlimit, num_xid, &init); - if (r<0) - perror("vc_add_dlimit"); - } - - memset(&data, 0, sizeof(data)); - data.name = argv[optind]; - data.flags = num_flag; - - if (opt_set) { - sscanf(set_arg, "%u,%u,%u,%u,%u", - &data.space_used, &data.space_total, - &data.inodes_used, &data.inodes_total, - &data.reserved); - - r = vserver(VCMD_set_dlimit, num_xid, &data); - if (r<0) - perror("vc_set_dlimit"); - } - - memset(&data, 0, sizeof(data)); - data.name = argv[optind]; - data.flags = num_flag; - - r = vserver(VCMD_get_dlimit, num_xid, &data); - if (r<0) - perror("vc_get_dlimit"); - - printf("%s: %u,%u,%u,%u,%u\n", argv[optind], - data.space_used, data.space_total, - data.inodes_used, data.inodes_total, - data.reserved); - } - - exit((err_flag)?1:0); +static void +writeInt(int fd, char const *prefix, int val) +{ + char buf[sizeof(val)*3 + 2]; + size_t len = utilvserver_fmt_int(buf, val); + + if (prefix) + WRITE_STR(fd, prefix); + Vwrite(fd, buf, len); +} + +static void +printDlimit(char const *filename, xid_t xid, uint32_t flags, bool formatted) +{ + struct vc_ctx_dlimit limit; + + if (vc_get_dlimit(filename, xid, flags, &limit) == -1) { + perror(ENSC_WRAPPERS_PREFIX "vc_get_dlimit()"); + exit(wrapper_exit_code); + } + + if (formatted) { + writeInt (1, 0, xid); + WRITE_MSG(1, " "); + WRITE_STR(1, filename); + writeInt (1, "\nspace_used=", limit.space_used); + writeInt (1, "\nspace_total=", limit.space_total); + writeInt (1, "\ninodes_used=", limit.inodes_used); + writeInt (1, "\ninodes_total=", limit.inodes_total); + writeInt (1, "\nreserved=", limit.reserved); + WRITE_MSG(1, "\n"); + } + else { + writeInt (1, 0, xid); + writeInt (1, " ", limit.space_used); + writeInt (1, " ", limit.space_total); + writeInt (1, " ", limit.inodes_used); + writeInt (1, " ", limit.inodes_total); + writeInt (1, " ", limit.reserved); + WRITE_MSG(1, " "); + WRITE_STR(1, filename); + WRITE_MSG(1, "\n"); + } } + +static bool +setDLimitField(struct vc_ctx_dlimit *dst, char const *opt) +{ + uint_least32_t *ptr; + char const * const orig_opt = opt; + +#define GET_VAL_PTR(CMP, VAL) \ + (strncmp(opt, CMP "=", sizeof(CMP))==0) ? \ + (opt+=sizeof(CMP), &VAL) : 0 + + if ((ptr=GET_VAL_PTR("space_used", dst->space_used))!=0) {} + else if ((ptr=GET_VAL_PTR("space_total", dst->space_total))!=0) {} + else if ((ptr=GET_VAL_PTR("inodes_used", dst->inodes_used))!=0) {} + else if ((ptr=GET_VAL_PTR("inodes_total", dst->inodes_total))!=0) {} + else if ((ptr=GET_VAL_PTR("reserved", dst->reserved))!=0) {} + else ptr=0; + +#undef GET_VAL_PTR + + if (ptr!=0 && *ptr==VC_CDLIM_KEEP) { + char *endptr; + long val = strtol(opt, &endptr, 0); + + if (*opt==0 || *endptr!='\0') { + WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "can not parse number in '"); + WRITE_STR(2, orig_opt); + WRITE_MSG(2, "'\n"); + return false; + } + + *ptr = val; + } + else if (ptr!=0) { + WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "value already set in '"); + WRITE_STR(2, orig_opt); + WRITE_MSG(2, "'\n"); + return false; + } + else { + WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "unknown limit in '"); + WRITE_STR(2, orig_opt); + WRITE_MSG(2, "'\n"); + return false; + } + + return true; +} + +int main(int argc, char *argv[]) +{ + bool do_set = false; + bool do_remove = false; + xid_t xid = VC_NOCTX; + uint32_t flags = 0; + char *endptr; + int sum = 0; + + struct vc_ctx_dlimit limit = { + .space_used = VC_CDLIM_KEEP, + .space_total = VC_CDLIM_KEEP, + .inodes_used = VC_CDLIM_KEEP, + .inodes_total = VC_CDLIM_KEEP, + .reserved = VC_CDLIM_KEEP + }; + + while (1) { + int c = getopt_long(argc, argv, "+x:s:df:", CMDLINE_OPTIONS, 0); + if (c==-1) break; + + switch (c) { + case CMD_HELP : showHelp(1, argv[0]); + case CMD_VERSION : showVersion(); + case 'x' : xid = Evc_xidopt2xid(optarg, true); break; + case 's' : + if (!setDLimitField(&limit, optarg)) + return EXIT_FAILURE; + else + do_set = true; + break; + case 'd' : do_remove = true; break; + case 'f' : + { + flags = strtol(optarg, &endptr, 0); + if ((flags == 0 && errno != 0) || *endptr != '\0') { + WRITE_MSG(2, "Invalid flags argument: '"); + WRITE_STR(2, optarg); + WRITE_MSG(2, "'; try '--help' for more information\n"); + return EXIT_FAILURE; + } + } + break; + + default : + WRITE_MSG(2, "Try '"); + WRITE_STR(2, argv[0]); + WRITE_MSG(2, " --help' for more information.\n"); + return EXIT_FAILURE; + break; + } + } + + sum = ((do_set ? 1 : 0) + (do_remove ? 1 : 0)); + + if (sum>1) + WRITE_MSG(2, "Can not specify multiple operations; try '--help' for more information\n"); + else if (optind==argc) + WRITE_MSG(2, "No mount point specified; try '--help' for more information\n"); + else if (xid==VC_NOCTX) + WRITE_MSG(2, "No xid specified; try '--help' for more information\n"); + else { + for (; optind < argc; ++optind) { + if (do_set) setDlimit(argv[optind], xid, flags, &limit); + else if (do_remove) remDlimit(argv[optind], xid, flags); + else printDlimit(argv[optind], xid, flags, true); + } + + return EXIT_SUCCESS; + } + + return EXIT_FAILURE; +} diff --git a/src/vlimit.c b/src/vlimit.c index 6fd955b..158e166 100644 --- a/src/vlimit.c +++ b/src/vlimit.c @@ -1,4 +1,4 @@ -// $Id: vlimit.c,v 1.1.2.3 2004/02/20 19:35:50 ensc Exp $ +// $Id: vlimit.c,v 1.20 2005/03/24 12:44:17 ensc Exp $ // Copyright (C) 2003 Enrico Scholz // @@ -29,7 +29,8 @@ #include "compat.h" #include "vserver.h" -#include "vserver-internal.h" +#include "internal.h" +#include "util.h" #include #include @@ -37,26 +38,40 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include -#define VERSION_COPYRIGHT_DISCLAIMER +#define ENSC_WRAPPERS_PREFIX "vlimit: " +#define ENSC_WRAPPERS_UNISTD 1 +#define ENSC_WRAPPERS_VSERVER 1 +#include -inline static void UNUSED -writeStr(int fd, char const *cmd) -{ - (void)write(fd, cmd, strlen(cmd)); -} +#define CMD_HELP 0x1000 +#define CMD_VERSION 0x1001 +#define CMD_XID 0x4000 +#define CMD_DIR 0x8000 +#define CMD_MISSINGOK 0x8001 -#define WRITE_MSG(FD,X) (void)(write(FD,X,sizeof(X)-1)) -#define WRITE_STR(FD,X) writeStr(FD,X) +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, '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", 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), @@ -65,16 +80,57 @@ 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), + 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, - " -c [-a|--all] [-MSH -- ]*\n" + " [--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); } @@ -90,6 +146,16 @@ showVersion() 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) { @@ -97,15 +163,11 @@ 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 { - memcpy(ptr, "0x", 2); - ptr += 2; - - ptr += utilvserver_uint2str(ptr, 20, (lim>>32), 16); - ptr += utilvserver_uint2str(ptr, 20, lim&0xffffffff, 16); + ptr += (*fmt_func)(ptr, lim); *ptr = ' '; } } @@ -125,14 +187,14 @@ 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) { uint32_t bitmask = (1<0 && pathname[l_pathname-1]!='/') + buf[l_pathname++] = '/'; + + for (i=0; i