~ubuntu-branches/debian/squeeze/util-vserver/squeeze

« back to all changes in this revision

Viewing changes to .pc/debian-changes-0.30.216-pre2864-2/src/vdlimit.c

  • Committer: Bazaar Package Importer
  • Author(s): Micah Anderson
  • Date: 2010-04-13 12:36:17 UTC
  • Revision ID: james.westby@ubuntu.com-20100413123617-ve6wgautfmwfhnkc
Tags: 0.30.216-pre2864-2
* Switch to dpkg-source 3.0 (quilt) format
* Fix bashisms in helper scripts (Closes: #530995)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// $Id: vdlimit.c 2861 2009-11-21 13:50:32Z dhozac $    --*- c -*--
 
2
 
 
3
// Copyright (C) 2005 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
 
4
//  
 
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.
 
8
//  
 
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.
 
13
//  
 
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.
 
17
 
 
18
 
 
19
#ifdef HAVE_CONFIG_H
 
20
#  include <config.h>
 
21
#endif
 
22
 
 
23
#include "util.h"
 
24
#include <lib/internal.h>
 
25
 
 
26
#include <vserver.h>
 
27
 
 
28
#include <getopt.h>
 
29
#include <libgen.h>
 
30
#include <errno.h>
 
31
#include <signal.h>
 
32
#include <sched.h>
 
33
 
 
34
#define ENSC_WRAPPERS_PREFIX    "vdlimit: "
 
35
#define ENSC_WRAPPERS_UNISTD    1
 
36
#define ENSC_WRAPPERS_VSERVER   1
 
37
#include <wrappers.h>
 
38
 
 
39
#define CMD_HELP                0x1000
 
40
#define CMD_VERSION             0x1001
 
41
 
 
42
int             wrapper_exit_code  =  1;
 
43
 
 
44
struct option const
 
45
CMDLINE_OPTIONS[] = {
 
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' },
 
52
  {0,0,0,0}
 
53
};
 
54
 
 
55
static void
 
56
showHelp(int fd, char const *cmd)
 
57
{
 
58
  WRITE_MSG(fd, "Usage: ");
 
59
  WRITE_STR(fd, cmd);
 
60
  WRITE_MSG(fd,
 
61
            " --xid <xid> [--flags <flags>] (--set <limit>=<value>|--remove) <mount point>\n"
 
62
            "\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"
 
67
            "\n"
 
68
            "Please report bugs to " PACKAGE_BUGREPORT "\n");
 
69
 
 
70
  exit(0);
 
71
}
 
72
 
 
73
static void
 
74
showVersion()
 
75
{
 
76
  WRITE_MSG(1,
 
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);
 
81
  exit(0);
 
82
}
 
83
 
 
84
static void
 
85
setDlimit(char const *filename, xid_t xid, uint32_t flags, struct vc_ctx_dlimit const *limit)
 
86
{
 
87
  bool          was_added = false;
 
88
 
 
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);
 
93
    }
 
94
 
 
95
    was_added = true;
 
96
  }
 
97
 
 
98
  if (vc_set_dlimit(filename, xid, flags, limit) == -1) {
 
99
    perror(ENSC_WRAPPERS_PREFIX "vc_set_dlimit()");
 
100
 
 
101
    if (was_added &&
 
102
        vc_rem_dlimit(filename, xid, flags)==-1)
 
103
      perror(ENSC_WRAPPERS_PREFIX "vc_rem_dlimit()");
 
104
 
 
105
    exit(wrapper_exit_code);
 
106
  }
 
107
}
 
108
 
 
109
static void
 
110
remDlimit(char const *filename, xid_t xid, uint32_t flags)
 
111
{
 
112
  if (vc_rem_dlimit(filename, xid, flags) == -1) {
 
113
    perror(ENSC_WRAPPERS_PREFIX "vc_rem_dlimit()");
 
114
    exit(wrapper_exit_code);
 
115
  }
 
116
}
 
117
 
 
118
static void
 
119
writeInt(int fd, char const *prefix, unsigned int val)
 
120
{
 
121
  char          buf[sizeof(val)*3 + 2];
 
122
  size_t        len = utilvserver_fmt_uint(buf, val);
 
123
 
 
124
  if (prefix)
 
125
    WRITE_STR(fd, prefix);
 
126
  Vwrite(fd, buf, len);
 
127
}
 
128
 
 
129
static void
 
130
printDlimit(char const *filename, xid_t xid, uint32_t flags, bool formatted)
 
131
{
 
132
  struct vc_ctx_dlimit          limit;
 
133
  
 
134
  if (vc_get_dlimit(filename, xid, flags, &limit) == -1) {
 
135
    perror(ENSC_WRAPPERS_PREFIX "vc_get_dlimit()");
 
136
    exit(wrapper_exit_code);
 
137
  }
 
138
 
 
139
  if (formatted) {
 
140
    writeInt (1, 0, xid);
 
141
    WRITE_MSG(1, " ");
 
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);
 
148
    WRITE_MSG(1, "\n");
 
149
  }
 
150
  else {
 
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);
 
157
    WRITE_MSG(1, " ");
 
158
    WRITE_STR(1, filename);
 
159
    WRITE_MSG(1, "\n");
 
160
  }
 
161
}
 
162
 
 
163
 
 
164
static bool
 
165
setDLimitField(struct vc_ctx_dlimit *dst, char const *opt)
 
166
{
 
167
  uint_least32_t        *ptr;
 
168
  char const * const    orig_opt = opt;
 
169
 
 
170
#define GET_VAL_PTR(CMP, VAL)                                           \
 
171
  (strncmp(opt, CMP "=", sizeof(CMP))==0) ?                             \
 
172
  (opt+=sizeof(CMP), &VAL) : 0
 
173
  
 
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)     {}
 
179
  else      ptr=0;
 
180
 
 
181
#undef  GET_VAL_PTR  
 
182
 
 
183
  if (ptr!=0 && *ptr==VC_CDLIM_KEEP) {
 
184
    char        *endptr;
 
185
    long        val = strtol(opt, &endptr, 0);
 
186
 
 
187
    if (*opt==0 || *endptr!='\0') {
 
188
      WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "can not parse number in '");
 
189
      WRITE_STR(2, orig_opt);
 
190
      WRITE_MSG(2, "'\n");
 
191
      return false;
 
192
    }
 
193
 
 
194
    *ptr = val;
 
195
  }
 
196
  else if (ptr!=0) {
 
197
    WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "value already set in '");
 
198
    WRITE_STR(2, orig_opt);
 
199
    WRITE_MSG(2, "'\n");
 
200
    return false;
 
201
  }
 
202
  else {
 
203
    WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "unknown limit in '");
 
204
    WRITE_STR(2, orig_opt);
 
205
    WRITE_MSG(2, "'\n");
 
206
    return false;
 
207
  }
 
208
 
 
209
  return true;
 
210
}
 
211
 
 
212
bool
 
213
isHigherLimit(uint_least32_t lhs, uint_least32_t rhs)
 
214
{
 
215
  if (lhs==VC_CDLIM_KEEP || rhs==VC_CDLIM_KEEP) return false;
 
216
 
 
217
  return lhs > rhs;
 
218
}
 
219
 
 
220
int main(int argc, char *argv[])
 
221
{
 
222
  bool          do_set       = false;
 
223
  bool          do_remove    = false;
 
224
  xid_t         xid          = VC_NOCTX;
 
225
  uint32_t      flags        = 0;
 
226
  char          *endptr;
 
227
  int           sum          = 0;
 
228
 
 
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
 
235
  };
 
236
  
 
237
  while (1) {
 
238
    int         c = getopt_long(argc, argv, "+x:s:df:", CMDLINE_OPTIONS, 0);
 
239
    if (c==-1) break;
 
240
 
 
241
    switch (c) {
 
242
      case CMD_HELP     :  showHelp(1, argv[0]);
 
243
      case CMD_VERSION  :  showVersion();
 
244
      case 'x'          :  xid = Evc_xidopt2xid(optarg, true); break;
 
245
      case 's'          :
 
246
        if (!setDLimitField(&limit, optarg))
 
247
          return EXIT_FAILURE;
 
248
        else
 
249
          do_set = true;
 
250
        break;
 
251
      case 'd'          :  do_remove = true; break;
 
252
      case 'f'          :
 
253
        {
 
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");
 
259
            return EXIT_FAILURE;
 
260
          }
 
261
        }
 
262
        break;
 
263
 
 
264
      default           :
 
265
        WRITE_MSG(2, "Try '");
 
266
        WRITE_STR(2, argv[0]);
 
267
        WRITE_MSG(2, " --help' for more information.\n");
 
268
        return EXIT_FAILURE;
 
269
        break;
 
270
    }
 
271
  }
 
272
 
 
273
  sum = ((do_set ? 1 : 0) + (do_remove ? 1 : 0));
 
274
  
 
275
  if (sum>1)
 
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");
 
285
  else {
 
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);
 
290
    }
 
291
 
 
292
    return EXIT_SUCCESS;
 
293
  }
 
294
 
 
295
  return EXIT_FAILURE;
 
296
}