3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 // based on setctxlimit.cc by Jacques Gelinas
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2, or (at your option)
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 Set the global per context limit of a resource (memory, file handle).
22 This utility can do it either for the current context or a selected
25 It uses the same options as ulimit, when possible
33 #include "vserver-internal.h"
42 #define VERSION_COPYRIGHT_DISCLAIMER
44 inline static void UNUSED
45 writeStr(int fd, char const *cmd)
47 (void)write(fd, cmd, strlen(cmd));
50 #define WRITE_MSG(FD,X) (void)(write(FD,X,sizeof(X)-1))
51 #define WRITE_STR(FD,X) writeStr(FD,X)
54 { #X, required_argument, 0, 2048|X }
56 static struct option const
58 { "help", no_argument, 0, 'h' },
59 { "version", no_argument, 0, 'v' },
60 { "all", no_argument, 0, 'a' },
61 NUMLIM( 0), NUMLIM( 1), NUMLIM( 2), NUMLIM( 3),
62 NUMLIM( 4), NUMLIM( 5), NUMLIM( 6), NUMLIM( 7),
63 NUMLIM( 8), NUMLIM( 9), NUMLIM(10), NUMLIM(11),
64 NUMLIM(12), NUMLIM(13), NUMLIM(14), NUMLIM(15),
65 NUMLIM(16), NUMLIM(17), NUMLIM(18), NUMLIM(19),
66 NUMLIM(20), NUMLIM(21), NUMLIM(22), NUMLIM(23),
67 NUMLIM(24), NUMLIM(25), NUMLIM(26), NUMLIM(27),
68 NUMLIM(28), NUMLIM(29), NUMLIM(30), NUMLIM(31),
73 showHelp(int fd, char const *cmd, int res)
75 WRITE_MSG(fd, "Usage: ");
78 " [-c|--ctx <ctx>] [-a|--all] [-MSH --<nr> <value>]*\n"
79 "Please report bugs to " PACKAGE_BUGREPORT "\n");
87 "ctxlimit " VERSION " -- limits context-resources\n"
88 "This program is part of " PACKAGE_STRING "\n\n"
89 "Copyright (C) 2003 Enrico Scholz\n"
90 VERSION_COPYRIGHT_DISCLAIMER);
95 appendLimit(char *ptr, bool do_it, vc_limit_t lim)
100 if (lim==VC_LIM_INFINITY) {
105 memcpy(ptr, "0x", 2);
108 ptr += utilvserver_uint2str(ptr, 20, (lim>>32), 16);
109 ptr += utilvserver_uint2str(ptr, 20, lim&0xffffffff, 16);
114 memcpy(ptr, "N/A", 3);
124 struct vc_rlimit_mask mask;
127 if (vc_get_rlimit_mask(-2, &mask)==-1) {
128 perror("vc_get_rlimit_mask()");
132 for (i=0; i<32; ++i) {
133 uint32_t bitmask = (1<<i);
134 struct vc_rlimit limit;
135 char buf[100], *ptr=buf;
137 if (vc_get_rlimit(ctx, i, &limit)==-1) {
138 perror("vc_get_rlimit()");
142 memset(buf, ' ', sizeof buf);
143 ptr += utilvserver_uint2str(ptr, 100, i, 10);
146 ptr = appendLimit(buf+10, mask.min &bitmask, limit.min);
147 ptr = appendLimit(buf+30, mask.soft&bitmask, limit.soft);
148 ptr = appendLimit(buf+50, mask.hard&bitmask, limit.hard);
151 write(1, buf, ptr-buf);
156 setLimits(int ctx, struct vc_rlimit const limits[], uint32_t mask)
159 for (i=0; i<32; ++i) {
160 if ((mask & (1<<i))==0) continue;
161 if (vc_set_rlimit(-2, i, limits+i)) {
162 perror("vc_set_rlimit()");
167 int main (int argc, char *argv[])
169 // overall used limits
170 uint32_t lim_mask = 0;
172 struct vc_rlimit limits[32];
173 bool show_all = false;
178 for (i=0; i<32; ++i) {
179 limits[i].min = VC_LIM_KEEP;
180 limits[i].soft = VC_LIM_KEEP;
181 limits[i].hard = VC_LIM_KEEP;
186 int c = getopt_long(argc, argv, "MSHhvac:", CMDLINE_OPTIONS, 0);
189 if (2048<=c && c<2048+32) {
193 if (strcmp(optarg, "inf")==0) val = VC_LIM_INFINITY;
194 else val = atoll(optarg);
196 if (set_mask & 1) limits[id].min = val;
197 if (set_mask & 2) limits[id].soft = val;
198 if (set_mask & 4) limits[id].soft = val;
204 case 'h' : showHelp(1, argv[0], 0);
205 case 'v' : showVersion();
206 case 'c' : ctx = atoi(optarg); break;
207 case 'a' : show_all = true; break;
212 case 'M' : set_mask |= 1; break;
213 case 'S' : set_mask |= 2; break;
214 case 'H' : set_mask |= 4; break;
215 default : assert(false);
220 WRITE_MSG(2, "Try '");
221 WRITE_STR(2, argv[0]);
222 WRITE_MSG(2, " --help\" for more information.\n");
228 setLimits(ctx, limits, lim_mask);
229 if (show_all) showAll(ctx);