1
// $Id: vdlimit.c 2861 2009-11-21 13:50:32Z dhozac $ --*- c -*--
3
// Copyright (C) 2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
5
// This program is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation; version 2 of the License.
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
// GNU General Public License for more details.
14
// You should have received a copy of the GNU General Public License
15
// along with this program; if not, write to the Free Software
16
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
#include <lib/internal.h>
34
#define ENSC_WRAPPERS_PREFIX "vdlimit: "
35
#define ENSC_WRAPPERS_UNISTD 1
36
#define ENSC_WRAPPERS_VSERVER 1
39
#define CMD_HELP 0x1000
40
#define CMD_VERSION 0x1001
42
int wrapper_exit_code = 1;
46
{ "help", no_argument, 0, CMD_HELP },
47
{ "version", no_argument, 0, CMD_VERSION },
48
{ "xid", required_argument, 0, 'x' },
49
{ "set", required_argument, 0, 's' },
50
{ "remove", no_argument, 0, 'd' },
51
{ "flags", required_argument, 0, 'f' },
56
showHelp(int fd, char const *cmd)
58
WRITE_MSG(fd, "Usage: ");
61
" --xid <xid> [--flags <flags>] (--set <limit>=<value>|--remove) <mount point>\n"
63
" --set|-s <limit>=<value> ... set <limit> to <value>, where limit is \n"
64
" one of: space_used, space_total, inodes_used,\n"
65
" inodes_total, reserved\n"
66
" --remove|-d ... removes the disk limit for <xid> from <mount point>\n"
68
"Please report bugs to " PACKAGE_BUGREPORT "\n");
77
"vdlimit " VERSION " -- manages disk limits\n"
78
"This program is part of " PACKAGE_STRING "\n\n"
79
"Copyright (C) 2005 Enrico Scholz\n"
80
VERSION_COPYRIGHT_DISCLAIMER);
85
setDlimit(char const *filename, xid_t xid, uint32_t flags, struct vc_ctx_dlimit const *limit)
87
bool was_added = false;
89
if (vc_get_dlimit(filename, xid, flags, 0) == -1) {
90
if (vc_add_dlimit(filename, xid, flags) == -1) {
91
perror(ENSC_WRAPPERS_PREFIX "vc_add_dlimit()");
92
exit(wrapper_exit_code);
98
if (vc_set_dlimit(filename, xid, flags, limit) == -1) {
99
perror(ENSC_WRAPPERS_PREFIX "vc_set_dlimit()");
102
vc_rem_dlimit(filename, xid, flags)==-1)
103
perror(ENSC_WRAPPERS_PREFIX "vc_rem_dlimit()");
105
exit(wrapper_exit_code);
110
remDlimit(char const *filename, xid_t xid, uint32_t flags)
112
if (vc_rem_dlimit(filename, xid, flags) == -1) {
113
perror(ENSC_WRAPPERS_PREFIX "vc_rem_dlimit()");
114
exit(wrapper_exit_code);
119
writeInt(int fd, char const *prefix, unsigned int val)
121
char buf[sizeof(val)*3 + 2];
122
size_t len = utilvserver_fmt_uint(buf, val);
125
WRITE_STR(fd, prefix);
126
Vwrite(fd, buf, len);
130
printDlimit(char const *filename, xid_t xid, uint32_t flags, bool formatted)
132
struct vc_ctx_dlimit limit;
134
if (vc_get_dlimit(filename, xid, flags, &limit) == -1) {
135
perror(ENSC_WRAPPERS_PREFIX "vc_get_dlimit()");
136
exit(wrapper_exit_code);
140
writeInt (1, 0, xid);
142
WRITE_STR(1, filename);
143
writeInt (1, "\nspace_used=", limit.space_used);
144
writeInt (1, "\nspace_total=", limit.space_total);
145
writeInt (1, "\ninodes_used=", limit.inodes_used);
146
writeInt (1, "\ninodes_total=", limit.inodes_total);
147
writeInt (1, "\nreserved=", limit.reserved);
151
writeInt (1, 0, xid);
152
writeInt (1, " ", limit.space_used);
153
writeInt (1, " ", limit.space_total);
154
writeInt (1, " ", limit.inodes_used);
155
writeInt (1, " ", limit.inodes_total);
156
writeInt (1, " ", limit.reserved);
158
WRITE_STR(1, filename);
165
setDLimitField(struct vc_ctx_dlimit *dst, char const *opt)
168
char const * const orig_opt = opt;
170
#define GET_VAL_PTR(CMP, VAL) \
171
(strncmp(opt, CMP "=", sizeof(CMP))==0) ? \
172
(opt+=sizeof(CMP), &VAL) : 0
174
if ((ptr=GET_VAL_PTR("space_used", dst->space_used))!=0) {}
175
else if ((ptr=GET_VAL_PTR("space_total", dst->space_total))!=0) {}
176
else if ((ptr=GET_VAL_PTR("inodes_used", dst->inodes_used))!=0) {}
177
else if ((ptr=GET_VAL_PTR("inodes_total", dst->inodes_total))!=0) {}
178
else if ((ptr=GET_VAL_PTR("reserved", dst->reserved))!=0) {}
183
if (ptr!=0 && *ptr==VC_CDLIM_KEEP) {
185
long val = strtol(opt, &endptr, 0);
187
if (*opt==0 || *endptr!='\0') {
188
WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "can not parse number in '");
189
WRITE_STR(2, orig_opt);
197
WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "value already set in '");
198
WRITE_STR(2, orig_opt);
203
WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "unknown limit in '");
204
WRITE_STR(2, orig_opt);
213
isHigherLimit(uint_least32_t lhs, uint_least32_t rhs)
215
if (lhs==VC_CDLIM_KEEP || rhs==VC_CDLIM_KEEP) return false;
220
int main(int argc, char *argv[])
223
bool do_remove = false;
224
xid_t xid = VC_NOCTX;
229
struct vc_ctx_dlimit limit = {
230
.space_used = VC_CDLIM_KEEP,
231
.space_total = VC_CDLIM_KEEP,
232
.inodes_used = VC_CDLIM_KEEP,
233
.inodes_total = VC_CDLIM_KEEP,
234
.reserved = VC_CDLIM_KEEP
238
int c = getopt_long(argc, argv, "+x:s:df:", CMDLINE_OPTIONS, 0);
242
case CMD_HELP : showHelp(1, argv[0]);
243
case CMD_VERSION : showVersion();
244
case 'x' : xid = Evc_xidopt2xid(optarg, true); break;
246
if (!setDLimitField(&limit, optarg))
251
case 'd' : do_remove = true; break;
254
flags = strtol(optarg, &endptr, 0);
255
if ((flags == 0 && errno != 0) || *endptr != '\0') {
256
WRITE_MSG(2, "Invalid flags argument: '");
257
WRITE_STR(2, optarg);
258
WRITE_MSG(2, "'; try '--help' for more information\n");
265
WRITE_MSG(2, "Try '");
266
WRITE_STR(2, argv[0]);
267
WRITE_MSG(2, " --help' for more information.\n");
273
sum = ((do_set ? 1 : 0) + (do_remove ? 1 : 0));
276
WRITE_MSG(2, "Can not specify multiple operations; try '--help' for more information\n");
277
else if (optind==argc)
278
WRITE_MSG(2, "No mount point specified; try '--help' for more information\n");
279
else if (xid==VC_NOCTX)
280
WRITE_MSG(2, "No xid specified; try '--help' for more information\n");
281
else if (isHigherLimit(limit.space_used, limit.space_total))
282
WRITE_MSG(2, "invalid parameters: 'space_used' is larger than 'space_total'\n");
283
else if (isHigherLimit(limit.inodes_used, limit.inodes_total))
284
WRITE_MSG(2, "invalid parameters: 'inodes_used' is larger than 'inodes_total'\n");
286
for (; optind < argc; ++optind) {
287
if (do_set) setDlimit(argv[optind], xid, flags, &limit);
288
else if (do_remove) remDlimit(argv[optind], xid, flags);
289
else printDlimit(argv[optind], xid, flags, true);