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]); break; case 'f': filem_change = 1; ret = parse_mode(optarg, &file_mode, argv[0]); break; case 's': filem_change = 1; ret = parse_mode(optarg, &tasks_mode, argv[0]); 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; }
int main(int argc, char *argv[]) { int ret = 0; int i, j; int c; int flags = 0; int final_ret = 0; struct cgroup_group_spec **cgroup_list = NULL; struct cgroup *cgroup; struct cgroup_controller *cgc; /* initialize libcg */ ret = cgroup_init(); if (ret) { fprintf(stderr, "%s: " "libcgroup initialization failed: %s\n", argv[0], cgroup_strerror(ret)); goto err; } cgroup_list = calloc(argc, 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, "rhg:", long_options, NULL)) > 0) { switch (c) { case 'r': flags |= CGFLAG_DELETE_RECURSIVE; break; case 'g': ret = parse_cgroup_spec(cgroup_list, optarg, argc); if (ret != 0) { fprintf(stderr, "%s: error parsing cgroup '%s'\n", argv[0], optarg); ret = -1; goto err; } break; case 'h': usage(0, argv[0]); ret = 0; goto err; default: usage(1, argv[0]); ret = -1; goto err; } } /* parse groups on command line */ for (i = optind; i < argc; i++) { ret = parse_cgroup_spec(cgroup_list, argv[i], argc); if (ret != 0) { fprintf(stderr, "%s: error parsing cgroup '%s'\n", argv[0], argv[i]); ret = -1; goto err; } } /* for each cgroup to be deleted */ for (i = 0; i < argc; 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 create new cgroup: %s\n", argv[0], cgroup_strerror(ret)); goto err; } /* add controllers to the cgroup */ j = 0; while (cgroup_list[i]->controllers[j]) { cgc = cgroup_add_controller(cgroup, cgroup_list[i]->controllers[j]); if (!cgc) { ret = ECGFAIL; fprintf(stderr, "%s: " "controller %s can't be added\n", argv[0], cgroup_list[i]->controllers[j]); cgroup_free(&cgroup); goto err; } j++; } ret = cgroup_delete_cgroup_ext(cgroup, flags); /* * Remember the errors and continue, try to remove all groups. */ if (ret != 0) { fprintf(stderr, "%s: cannot remove group '%s': %s\n", argv[0], cgroup->name, cgroup_strerror(ret)); final_ret = ret; } cgroup_free(&cgroup); } ret = final_ret; err: if (cgroup_list) { for (i = 0; i < argc; i++) { if (cgroup_list[i]) cgroup_free_group_spec(cgroup_list[i]); } free(cgroup_list); } return ret; }
int main(int argc, char *argv[]) { int ret = 0, i; int cg_specified = 0; int flag_child = 0; uid_t uid; gid_t gid; pid_t pid; int c; struct cgroup_group_spec *cgroup_list[CG_HIER_MAX]; memset(cgroup_list, 0, sizeof(cgroup_list)); while ((c = getopt_long(argc, argv, "+g:sh", longopts, NULL)) > 0) { switch (c) { case 'g': ret = parse_cgroup_spec(cgroup_list, optarg, CG_HIER_MAX); if (ret) { fprintf(stderr, "cgroup controller and path" "parsing failed\n"); return -1; } cg_specified = 1; break; case 's': flag_child |= CGROUP_DAEMON_UNCHANGE_CHILDREN; break; case 'h': usage(0, argv[0]); exit(0); default: usage(1, argv[0]); exit(1); } } /* Executable name */ if (!argv[optind]) { usage(1, argv[0]); exit(1); } /* Initialize libcg */ ret = cgroup_init(); if (ret) { fprintf(stderr, "libcgroup initialization failed: %s\n", cgroup_strerror(ret)); return ret; } /* Just for debugging purposes. */ uid = geteuid(); gid = getegid(); cgroup_dbg("My euid and eguid is: %d,%d\n", (int) uid, (int) gid); uid = getuid(); gid = getgid(); pid = getpid(); ret = cgroup_register_unchanged_process(pid, flag_child); if (ret) { fprintf(stderr, "registration of process failed\n"); return ret; } /* * 'cgexec' command file needs the root privilege for executing * a cgroup_register_unchanged_process() by using unix domain * socket, and an euid/egid should be changed to the executing user * from a root user. */ if (setresuid(uid, uid, uid)) { fprintf(stderr, "%s", strerror(errno)); return -1; } if (setresgid(gid, gid, gid)) { fprintf(stderr, "%s", strerror(errno)); return -1; } if (cg_specified) { /* * User has specified the list of control group and * controllers * */ for (i = 0; i < CG_HIER_MAX; i++) { if (!cgroup_list[i]) break; ret = cgroup_change_cgroup_path(cgroup_list[i]->path, pid, (const char*const*) cgroup_list[i]->controllers); if (ret) { fprintf(stderr, "cgroup change of group failed\n"); return ret; } } } else { /* Change the cgroup by determining the rules based on uid */ ret = cgroup_change_cgroup_flags(uid, gid, argv[optind], pid, 0); if (ret) { fprintf(stderr, "cgroup change of group failed\n"); return ret; } } /* Now exec the new process */ ret = execvp(argv[optind], &argv[optind]); if (ret == -1) { fprintf(stderr, "%s", strerror(errno)); return -1; } return 0; }
int main(int argc, char *argv[]) { int ret = 0; int i, j; int c; int flags = 0; int final_ret = 0; int counter = 0; int max = 0; struct ext_cgroup_record *ecg_list = NULL; int skip; struct cgroup_group_spec **cgroup_list = NULL; struct cgroup *cgroup; struct cgroup_controller *cgc; /* initialize libcg */ ret = cgroup_init(); if (ret) { fprintf(stderr, "%s: " "libcgroup initialization failed: %s\n", argv[0], cgroup_strerror(ret)); goto err; } cgroup_list = calloc(argc, sizeof(struct cgroup_group_spec *)); if (cgroup_list == NULL) { fprintf(stderr, "%s: out of memory\n", argv[0]); ret = -1; goto err; } ecg_list = calloc(argc, sizeof(struct ext_cgroup_record *)); 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, "rhg:", long_options, NULL)) > 0) { switch (c) { case 'r': flags |= CGFLAG_DELETE_RECURSIVE; break; case 'g': ret = parse_cgroup_spec(cgroup_list, optarg, argc); if (ret != 0) { fprintf(stderr, "%s: error parsing cgroup '%s'\n", argv[0], optarg); ret = -1; goto err; } break; case 'h': usage(0, argv[0]); ret = 0; goto err; default: usage(1, argv[0]); ret = -1; goto err; } } /* parse groups on command line */ for (i = optind; i < argc; i++) { ret = parse_cgroup_spec(cgroup_list, argv[i], argc); if (ret != 0) { fprintf(stderr, "%s: error parsing cgroup '%s'\n", argv[0], argv[i]); ret = -1; goto err; } } /* for each cgroup to be deleted */ for (i = 0; i < argc; 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 create new cgroup: %s\n", argv[0], cgroup_strerror(ret)); goto err; } /* add controllers to the cgroup */ j = 0; while (cgroup_list[i]->controllers[j]) { skip = 0; /* * save controller name, cg name and hierarchy number * to determine whether we should skip adding controller */ if (counter == max) { /* * there is not enough space to store them, * create it */ max = max + argc; ecg_list = (struct ext_cgroup_record *) realloc(ecg_list, max * sizeof(struct ext_cgroup_record)); if (!ecg_list) { fprintf(stderr, "%s: ", argv[0]); fprintf(stderr, "not enough memory\n"); final_ret = -1; goto err; } } strncpy(ecg_list[counter].controller, cgroup_list[i]->controllers[j], FILENAME_MAX); ecg_list[counter].controller[FILENAME_MAX - 1] = '\0'; strncpy(ecg_list[counter].name, cgroup_list[i]->path, FILENAME_MAX); ecg_list[counter].name[FILENAME_MAX - 1] = '\0'; ret = skip_add_controller(counter, &skip, ecg_list); if (ret) goto err; if (skip) { /* don't add the controller, goto next one */ goto next; } cgc = cgroup_add_controller(cgroup, cgroup_list[i]->controllers[j]); if (!cgc) { ret = ECGFAIL; fprintf(stderr, "%s: " "controller %s can't be added\n", argv[0], cgroup_list[i]->controllers[j]); cgroup_free(&cgroup); goto err; } next: counter++; j++; } ret = cgroup_delete_cgroup_ext(cgroup, flags); /* * Remember the errors and continue, try to remove all groups. */ if (ret != 0) { fprintf(stderr, "%s: cannot remove group '%s': %s\n", argv[0], cgroup->name, cgroup_strerror(ret)); final_ret = ret; } cgroup_free(&cgroup); } ret = final_ret; err: if (ecg_list) free(ecg_list); if (cgroup_list) { for (i = 0; i < argc; i++) { if (cgroup_list[i]) cgroup_free_group_spec(cgroup_list[i]); } free(cgroup_list); } return ret; }