46a5e63d80096de81c9e905830b3aec1423785d1
[util-vserver.git] / src / vmemctrl.c
1 // $Id$
2
3 // Copyright (C) 2007 Daniel Hokka Zakrisson
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; either version 2, or (at your option)
8 // any later version.
9 //  
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //  
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 #ifdef HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22
23 #include "vserver.h"
24 #include "util.h"
25
26 #include <lib/internal.h>
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include <errno.h>
33 #include <getopt.h>
34
35 #define ENSC_WRAPPERS_PREFIX    "vmemctrl: "
36 #define ENSC_WRAPPERS_VSERVER   1
37 #define ENSC_WRAPPERS_UNISTD    1
38 #include "wrappers.h"
39
40 #define CMD_HELP        0x1000
41 #define CMD_VERSION     0x1001
42
43 #define CMD_SET         0x2000
44 #define CMD_GET         0x2001
45
46 #define CMD_XID         0x4000
47 #define CMD_BADNESS     0x4001
48
49 int wrapper_exit_code = 255;
50
51
52 static struct option const
53 CMDLINE_OPTIONS[] = {
54   { "help",     no_argument,        0, CMD_HELP },
55   { "version",  no_argument,        0, CMD_VERSION },
56   { "set",      no_argument,        0, CMD_SET },
57   { "get",      no_argument,        0, CMD_GET },
58   { "xid",      required_argument,  0, CMD_XID },
59   { "badness",  required_argument,  0, CMD_BADNESS },
60   { 0,0,0,0 }
61 };
62
63 struct Arguments {
64   xid_t         xid;
65   int64_t       badness;
66   bool          do_set;
67   bool          do_get;
68 };
69
70 static void
71 showHelp(int fd, char const *cmd, int res)
72 {
73   WRITE_MSG(fd, "Usage:\n  ");
74   WRITE_STR(fd, cmd);
75   WRITE_MSG(fd,
76             " (--set|--get) [--xid <xid>] [--badness <OOM bias>]\n"
77             "        [--] [<command> <args>*]\n\n"
78             "Please report bugs to " PACKAGE_BUGREPORT "\n");
79
80   exit(res);
81 }
82
83 static void
84 showVersion()
85 {
86   WRITE_MSG(1,
87             "vmemctrl " VERSION " -- \n"
88             "This program is part of " PACKAGE_STRING "\n\n"
89             "Copyright (C) 2007 Daniel Hokka Zakrisson\n"
90             VERSION_COPYRIGHT_DISCLAIMER);
91   exit(0);
92 }
93
94 static inline void
95 doset(struct Arguments *args)
96 {
97   if (vc_set_badness(args->xid, args->badness) == -1) {
98     perror(ENSC_WRAPPERS_PREFIX "vc_set_badness()");
99     exit(wrapper_exit_code);
100   }
101 }
102
103 static inline void
104 doget(struct Arguments *args)
105 {
106   int64_t badness;
107   char buf[32];
108   size_t l;
109   if (vc_get_badness(args->xid, &badness) == -1) {
110     perror(ENSC_WRAPPERS_PREFIX "vc_get_badness()");
111     exit(wrapper_exit_code);
112   }
113   l = utilvserver_fmt_int64(buf, badness);
114   buf[l] = '\0';
115   WRITE_STR(1, buf);
116   WRITE_MSG(1, "\n");
117 }
118
119 int main (int argc, char *argv[])
120 {
121   struct Arguments args = {
122     .do_set     = false,
123     .do_get     = false,
124     .xid        = VC_NOCTX,
125     .badness    = 0,
126   };
127   
128   while (1) {
129     int         c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0);
130     if (c==-1) break;
131
132     switch (c) {
133       case CMD_HELP     :  showHelp(1, argv[0], 0);
134       case CMD_VERSION  :  showVersion();
135       case CMD_XID      :  args.xid       = Evc_xidopt2xid(optarg,true); break;
136       case CMD_SET      :  args.do_set    = true; break;
137       case CMD_GET      :  args.do_get    = true; break;
138       case CMD_BADNESS  : {
139         char *endptr;
140         args.badness = strtoll(optarg, &endptr, 0);
141         if (*endptr) {
142           WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "Badness '");
143           WRITE_STR(2, optarg);
144           WRITE_MSG(2, "' is not an integer\n");
145           exit(wrapper_exit_code);
146         }
147         break;
148       }
149       default           :
150         WRITE_MSG(2, "Try '");
151         WRITE_STR(2, argv[0]);
152         WRITE_MSG(2, " --help' for more information.\n");
153         exit(wrapper_exit_code);
154         break;
155     }
156   }
157
158   if (args.xid == VC_NOCTX) args.xid = Evc_get_task_xid(0);
159
160   if (!args.do_set && !args.do_get) {
161     WRITE_MSG(2, "No operation specified; try '--help' for more information\n");
162     exit(wrapper_exit_code);
163   }
164   else if (((args.do_set ? 1 : 0) + (args.do_get ? 1 : 0)) > 1) {
165     WRITE_MSG(2, "Multiple operations specified; try '--help' for more information\n");
166     exit(wrapper_exit_code);
167   }
168
169   if (args.do_set)
170     doset(&args);
171   else if (args.do_get)
172     doget(&args);
173
174   if (optind != argc)
175     Eexecvp (argv[optind],argv+optind);
176   return EXIT_SUCCESS;
177 }