~ubuntu-branches/ubuntu/maverick/libcgroup/maverick-proposed

« back to all changes in this revision

Viewing changes to src/tools/cgset.c

  • Committer: Bazaar Package Importer
  • Author(s): Dustin Kirkland
  • Date: 2009-08-26 11:29:17 UTC
  • Revision ID: james.westby@ubuntu.com-20090826112917-402ews2uj6v350d2
Tags: upstream-0.34
ImportĀ upstreamĀ versionĀ 0.34

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <libcgroup.h>
 
2
#include <libcgroup-internal.h>
 
3
 
 
4
#include <stdio.h>
 
5
#include <stdlib.h>
 
6
#include <string.h>
 
7
#include <unistd.h>
 
8
#include <getopt.h>
 
9
 
 
10
#include "tools-common.h"
 
11
 
 
12
#define FL_RULES        1
 
13
#define FL_COPY         2
 
14
 
 
15
enum {
 
16
        COPY_FROM_OPTION = CHAR_MAX + 1
 
17
};
 
18
 
 
19
static struct option const long_options[] =
 
20
{
 
21
        {"rule", required_argument, NULL, 'r'},
 
22
        {"help", no_argument, NULL, 'h'},
 
23
        {"copy-from", required_argument, NULL, COPY_FROM_OPTION},
 
24
        {NULL, 0, NULL, 0}
 
25
};
 
26
 
 
27
int flags; /* used input method */
 
28
 
 
29
struct cgroup *copy_name_value_from_cgroup(char src_cg_path[FILENAME_MAX])
 
30
{
 
31
        int ret = 0;
 
32
        struct cgroup *src_cgroup;
 
33
 
 
34
        /* create source cgroup */
 
35
        src_cgroup = cgroup_new_cgroup(src_cg_path);
 
36
        if (!src_cgroup) {
 
37
                fprintf(stderr, "can't create cgroup: %s\n",
 
38
                        cgroup_strerror(ECGFAIL));
 
39
                goto scgroup_err;
 
40
        }
 
41
 
 
42
        /* copy the name-version values to the cgroup structure */
 
43
        ret = cgroup_get_cgroup(src_cgroup);
 
44
        if (ret != 0) {
 
45
                fprintf(stderr, "cgroup %s error: %s \n",
 
46
                        src_cg_path, cgroup_strerror(ret));
 
47
                goto scgroup_err;
 
48
        }
 
49
 
 
50
        return src_cgroup;
 
51
 
 
52
scgroup_err:
 
53
        cgroup_free(&src_cgroup);
 
54
        return NULL;
 
55
}
 
56
 
 
57
 
 
58
struct cgroup *copy_name_value_from_rules(int nv_number,
 
59
                        struct control_value *name_value)
 
60
{
 
61
        struct cgroup *src_cgroup;
 
62
        struct cgroup_controller *cgc;
 
63
        char con[FILENAME_MAX];
 
64
 
 
65
        int ret;
 
66
        int i;
 
67
 
 
68
        /* create source cgroup */
 
69
        src_cgroup = cgroup_new_cgroup("tmp");
 
70
        if (!src_cgroup) {
 
71
                fprintf(stderr, "can't create cgroup: %s\n",
 
72
                        cgroup_strerror(ECGFAIL));
 
73
                goto scgroup_err;
 
74
        }
 
75
 
 
76
        /* add pairs name-value to
 
77
           relevant controllers of this cgroup */
 
78
        for (i = 0; i < nv_number; i++) {
 
79
 
 
80
                if ((strchr(name_value[i].name, '.')) == NULL) {
 
81
                fprintf(stderr, "wrong -r  parameter (%s=%s)\n",
 
82
                                name_value[i].name, name_value[i].value);
 
83
                        goto scgroup_err;
 
84
                }
 
85
 
 
86
                strncpy(con, name_value[i].name, FILENAME_MAX);
 
87
                strtok(con, ".");
 
88
 
 
89
                /* add relevant controller */
 
90
                cgc = cgroup_add_controller(src_cgroup, con);
 
91
                if (!cgc) {
 
92
                        fprintf(stderr, "controller %s can't be add\n",
 
93
                                        con);
 
94
                        goto scgroup_err;
 
95
                }
 
96
 
 
97
                /* add name-value pair to this controller */
 
98
                ret = cgroup_add_value_string(cgc,
 
99
                        name_value[i].name, name_value[i].value);
 
100
                if (ret) {
 
101
                        fprintf(stderr, "name-value pair %s=%s can't be set\n",
 
102
                                name_value[i].name, name_value[i].value);
 
103
                        goto scgroup_err;
 
104
                }
 
105
        }
 
106
 
 
107
        return src_cgroup;
 
108
scgroup_err:
 
109
        cgroup_free(&src_cgroup);
 
110
        return NULL;
 
111
}
 
112
 
 
113
void usage(int status, char *program_name)
 
114
{
 
115
        if (status != 0)
 
116
                fprintf(stderr, "Wrong input parameters,"
 
117
                        " try %s --help' for more information.\n",
 
118
                        program_name);
 
119
        else {
 
120
                printf("Usage: %s [-r <name=value>]  <cgroup_path> ...\n"
 
121
                        "   or: %s --copy-from <source_cgrup_path> "
 
122
                            "<cgroup_path> ...\n",
 
123
                        program_name, program_name);
 
124
        }
 
125
}
 
126
 
 
127
int main(int argc, char *argv[])
 
128
{
 
129
        int ret = 0;
 
130
        int c;
 
131
 
 
132
        char *buf;
 
133
        struct control_value *name_value = NULL;
 
134
        int nv_number = 0;
 
135
        int nv_max = 0;
 
136
 
 
137
        char src_cg_path[FILENAME_MAX];
 
138
        struct cgroup *src_cgroup;
 
139
        struct cgroup *cgroup;
 
140
 
 
141
        /* no parametr on input */
 
142
        if (argc < 2) {
 
143
                fprintf(stderr, "Usage is %s -r <name=value> "
 
144
                        "<relative path to cgroup>\n", argv[0]);
 
145
                return -1;
 
146
        }
 
147
 
 
148
        /* parse arguments */
 
149
        while ((c = getopt_long (argc, argv,
 
150
                "r:h", long_options, NULL)) != -1) {
 
151
                switch (c) {
 
152
                case 'h':
 
153
                        usage(0, argv[0]);
 
154
                        ret = 0;
 
155
                        goto err;
 
156
                        break;
 
157
 
 
158
                case 'r':
 
159
                        if ((flags &  FL_COPY) != 0) {
 
160
                                usage(1, argv[0]);
 
161
                                ret = -1;
 
162
                                goto err;
 
163
                        }
 
164
                        flags |= FL_RULES;
 
165
 
 
166
                        /* add name-value pair to buffer
 
167
                                (= name_value variable) */
 
168
                        if (nv_number >= nv_max) {
 
169
                                nv_max += CG_NV_MAX;
 
170
                                name_value = (struct control_value *)
 
171
                                        realloc(name_value,
 
172
                                        nv_max * sizeof(struct control_value));
 
173
                                if (!name_value) {
 
174
                                        fprintf(stderr, "%s: "
 
175
                                                "not enough memory\n",
 
176
                                                argv[0]);
 
177
                                        ret = -1;
 
178
                                        goto err;
 
179
                                }
 
180
                        }
 
181
 
 
182
                        /* parse optarg value */
 
183
                        /* there is necessary to input the tuple n=v */
 
184
                        buf = strtok(optarg, "=");
 
185
                        if (buf == NULL) {
 
186
                                fprintf(stderr, "%s: "
 
187
                                        "wrong parameter of option -r: %s\n",
 
188
                                        argv[0], optarg);
 
189
                                ret = -1;
 
190
                                goto err;
 
191
                        }
 
192
 
 
193
                        strncpy(name_value[nv_number].name, buf, FILENAME_MAX);
 
194
                        name_value[nv_number].name[FILENAME_MAX-1] = '\0';
 
195
 
 
196
                        buf = strtok(NULL, "=");
 
197
                        if (buf == NULL) {
 
198
                                fprintf(stderr, "%s: "
 
199
                                        "wrong parameter of option -r: %s\n",
 
200
                                        argv[0], optarg);
 
201
                                ret = -1;
 
202
                                goto err;
 
203
                        }
 
204
 
 
205
                        strncpy(name_value[nv_number].value, buf, CG_VALUE_MAX);
 
206
                        name_value[nv_number].value[CG_VALUE_MAX-1] = '\0';
 
207
 
 
208
                        nv_number++;
 
209
                        break;
 
210
                case COPY_FROM_OPTION:
 
211
                        if (flags != 0) {
 
212
                                usage(1, argv[0]);
 
213
                                ret = -1;
 
214
                                goto err;
 
215
                        }
 
216
                        flags |= FL_COPY;
 
217
                        strncpy(src_cg_path, optarg, FILENAME_MAX);
 
218
                        src_cg_path[FILENAME_MAX-1] = '\0';
 
219
                        break;
 
220
                default:
 
221
                        usage(1, argv[0]);
 
222
                        ret = -1;
 
223
                        goto err;
 
224
                        break;
 
225
                }
 
226
        }
 
227
 
 
228
        /* no cgroup name */
 
229
        if (!argv[optind]) {
 
230
                fprintf(stderr, "%s: no cgroup specified\n", argv[0]);
 
231
                ret = -1;
 
232
                goto err;
 
233
        }
 
234
 
 
235
        if (flags == 0) {
 
236
                fprintf(stderr, "%s: no name-value pair was set\n", argv[0]);
 
237
                ret = -1;
 
238
                goto err;
 
239
        }
 
240
 
 
241
        /* initialize libcgroup */
 
242
        ret = cgroup_init();
 
243
        if (ret) {
 
244
                fprintf(stderr, "%s: libcgroup initialization failed: %s\n",
 
245
                        argv[0], cgroup_strerror(ret));
 
246
                goto err;
 
247
        }
 
248
 
 
249
        /* copy the name-value pairs from -r options */
 
250
        if ((flags & FL_RULES) != 0) {
 
251
                src_cgroup = copy_name_value_from_rules(nv_number, name_value);
 
252
                if (src_cgroup == NULL)
 
253
                        goto err;
 
254
        }
 
255
 
 
256
        /* copy the name-value from the given group */
 
257
        if ((flags & FL_COPY) != 0) {
 
258
                src_cgroup = copy_name_value_from_cgroup(src_cg_path);
 
259
                if (src_cgroup == NULL)
 
260
                        goto err;
 
261
        }
 
262
 
 
263
        while (optind < argc) {
 
264
                /* create new cgroup */
 
265
                cgroup = cgroup_new_cgroup(argv[optind]);
 
266
                if (!cgroup) {
 
267
                        ret = ECGFAIL;
 
268
                        fprintf(stderr, "%s: can't add new cgroup: %s\n",
 
269
                                argv[0], cgroup_strerror(ret));
 
270
                        goto cgroup_free_err;
 
271
                }
 
272
 
 
273
                /* copy the values from the source cgroup to new one */
 
274
                ret = cgroup_copy_cgroup(cgroup, src_cgroup);
 
275
                if (ret != 0) {
 
276
                        fprintf(stderr, "%s: cgroup %s error: %s \n",
 
277
                                argv[0], src_cg_path, cgroup_strerror(ret));
 
278
                        goto cgroup_free_err;
 
279
                }
 
280
 
 
281
                /* modify cgroup based on values of the new one */
 
282
                ret = cgroup_modify_cgroup(cgroup);
 
283
                if (ret) {
 
284
                        fprintf(stderr, "%s: "
 
285
                                "the group can't be modified\n",
 
286
                                argv[0]);
 
287
                        goto cgroup_free_err;
 
288
                }
 
289
 
 
290
                optind++;
 
291
                cgroup_free(&cgroup);
 
292
        }
 
293
 
 
294
cgroup_free_err:
 
295
        if (cgroup)
 
296
                cgroup_free(&cgroup);
 
297
        cgroup_free(&src_cgroup);
 
298
 
 
299
err:
 
300
        free(name_value);
 
301
        return ret;
 
302
}