libcgroup/libcgroup-0.41/src/tools/cgcreate.c
2014-02-05 16:04:04 +01:00

236 lines
5.4 KiB
C

/*
* Copyright Red Hat, Inc. 2009
*
* Authors: Ivana Hutarova Varekova <varekova@redhat.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it would be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#include <libcgroup.h>
#include <libcgroup-internal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pwd.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <grp.h>
#include <getopt.h>
#include "tools-common.h"
/*
* Display the usage
*/
static void usage(int status, const char *program_name)
{
if (status != 0) {
fprintf(stderr, "Wrong input parameters,"
" try %s -h' for more information.\n",
program_name);
return;
}
printf("Usage: %s [-h] [-f mode] [-d mode] [-s mode] "\
"[-t <tuid>:<tgid>] [-a <agid>:<auid>] "\
"-g <controllers>:<path> [-g ...]\n", program_name);
printf("Create control group(s)\n");
printf(" -a <tuid>:<tgid> Owner of the group and all "\
"its files\n");
printf(" -d, --dperm=mode Group directory permissions\n");
printf(" -f, --fperm=mode Group file permissions\n");
printf(" -g <controllers>:<path> Control group which should be "\
"added\n");
printf(" -h, --help Display this help\n");
printf(" -s, --tperm=mode Tasks file permissions\n");
printf(" -t <tuid>:<tgid> Owner of the tasks file\n");
}
int main(int argc, char *argv[])
{
int ret = 0;
int i, j;
int c;
static struct option long_opts[] = {
{"help", no_argument, NULL, 'h'},
{"task", required_argument, NULL, 't'},
{"admin", required_argument, NULL, 'a'},
{"", required_argument, NULL, 'g'},
{"dperm", required_argument, NULL, 'd'},
{"fperm", required_argument, NULL, 'f' },
{"tperm", required_argument, NULL, 's' },
{0, 0, 0, 0},
};
uid_t tuid = CGRULE_INVALID, auid = CGRULE_INVALID;
gid_t tgid = CGRULE_INVALID, agid = CGRULE_INVALID;
struct cgroup_group_spec **cgroup_list;
struct cgroup *cgroup;
struct cgroup_controller *cgc;
/* approximation of max. numbers of groups that will be created */
int capacity = argc;
/* permission variables */
mode_t dir_mode = NO_PERMS;
mode_t file_mode = NO_PERMS;
mode_t tasks_mode = NO_PERMS;
int dirm_change = 0;
int filem_change = 0;
/* no parametr on input */
if (argc < 2) {
usage(1, argv[0]);
return -1;
}
cgroup_list = calloc(capacity, sizeof(struct cgroup_group_spec *));
if (cgroup_list == NULL) {
fprintf(stderr, "%s: out of memory\n", argv[0]);
ret = -1;
goto err;
}
/* parse arguments */
while ((c = getopt_long(argc, argv, "a:t:g:hd:f:s:", long_opts, NULL))
> 0) {
switch (c) {
case 'h':
usage(0, argv[0]);
ret = 0;
goto err;
case 'a':
/* set admin uid/gid */
if (parse_uid_gid(optarg, &auid, &agid, argv[0]))
goto err;
break;
case 't':
/* set task uid/gid */
if (parse_uid_gid(optarg, &tuid, &tgid, argv[0]))
goto err;
break;
case 'g':
ret = parse_cgroup_spec(cgroup_list, optarg, capacity);
if (ret) {
fprintf(stderr, "%s: "
"cgroup controller and path"
"parsing failed (%s)\n",
argv[0], argv[optind]);
ret = -1;
goto err;
}
break;
case 'd':
dirm_change = 1;
ret = parse_mode(optarg, &dir_mode, argv[0]);
if (ret)
goto err;
break;
case 'f':
filem_change = 1;
ret = parse_mode(optarg, &file_mode, argv[0]);
if (ret)
goto err;
break;
case 's':
filem_change = 1;
ret = parse_mode(optarg, &tasks_mode, argv[0]);
if (ret)
goto err;
break;
default:
usage(1, argv[0]);
ret = -1;
goto err;
}
}
/* no cgroup name */
if (argv[optind]) {
fprintf(stderr, "%s: "
"wrong arguments (%s)\n",
argv[0], argv[optind]);
ret = -1;
goto err;
}
/* initialize libcg */
ret = cgroup_init();
if (ret) {
fprintf(stderr, "%s: "
"libcgroup initialization failed: %s\n",
argv[0], cgroup_strerror(ret));
goto err;
}
/* for each new cgroup */
for (i = 0; i < capacity; i++) {
if (!cgroup_list[i])
break;
/* create the new cgroup structure */
cgroup = cgroup_new_cgroup(cgroup_list[i]->path);
if (!cgroup) {
ret = ECGFAIL;
fprintf(stderr, "%s: can't add new cgroup: %s\n",
argv[0], cgroup_strerror(ret));
goto err;
}
/* set uid and gid for the new cgroup based on input options */
ret = cgroup_set_uid_gid(cgroup, tuid, tgid, auid, agid);
if (ret)
goto err;
/* add controllers to the new cgroup */
j = 0;
while (cgroup_list[i]->controllers[j]) {
cgc = cgroup_add_controller(cgroup,
cgroup_list[i]->controllers[j]);
if (!cgc) {
ret = ECGINVAL;
fprintf(stderr, "%s: "
"controller %s can't be add\n",
argv[0],
cgroup_list[i]->controllers[j]);
cgroup_free(&cgroup);
goto err;
}
j++;
}
/* all variables set so create cgroup */
if (dirm_change | filem_change)
cgroup_set_permissions(cgroup, dir_mode, file_mode,
tasks_mode);
ret = cgroup_create_cgroup(cgroup, 0);
if (ret) {
fprintf(stderr, "%s: "
"can't create cgroup %s: %s\n",
argv[0], cgroup->name, cgroup_strerror(ret));
cgroup_free(&cgroup);
goto err;
}
cgroup_free(&cgroup);
}
err:
if (cgroup_list) {
for (i = 0; i < capacity; i++) {
if (cgroup_list[i])
cgroup_free_group_spec(cgroup_list[i]);
}
free(cgroup_list);
}
return ret;
}