static mrb_value mrb_cgroup_delete(mrb_state *mrb, mrb_value self) { int code; mrb_cgroup_context *mrb_cg_cxt = mrb_cgroup_get_context(mrb, self, "mrb_cgroup_context"); // BUG1 : cgroup_delete_cgroup returns an error(No such file or directory:50016:ECGOTHER), despite actually succeeding if ((code = cgroup_delete_cgroup(mrb_cg_cxt->cg, 1)) && code != ECGOTHER) { mrb_raisef(mrb , E_RUNTIME_ERROR , "cgroup_delete faild: %S(%S)" , mrb_str_new_cstr(mrb, cgroup_strerror(code)) , mrb_fixnum_value(code) ); } return self; }
int main(int argc, char** argv) { static struct option longopts[] = { { "daemonize", no_argument, NULL, 'd' }, { "cgroup", required_argument, NULL, 'g' }, { "pidfile", required_argument, NULL, 'p'}, { "restart_on_crash", no_argument, NULL, 'r'}, { "verbose", no_argument, NULL, 'v'}, { NULL, 0, NULL, 0} }; int cl; char* event_command; char* event_control_path; char* oom_control_path; char* pidfile = NULL; uint64_t efdcounter; struct sigaction sa; int flag; assert(argc > 1); exit_flag = 0; restart_flag = 0; char daemon_flag = 0; char restart_on_crash_flg = 0; struct cgroup_context cgc; char verbose_log = 0; cgc.cgroup_name = NULL; int ch; while((ch = getopt_long(argc, argv, "rvdg:p:", longopts, NULL)) != -1) { switch(ch) { case 'd': daemon_flag = 1; break; case 'g': asprintf(&cgc.cgroup_name, "%s", optarg); break; case 'p': asprintf(&pidfile, "%s", optarg); break; case 'r': restart_on_crash_flg = 1; break; case 'v': verbose_log = 1; break; default: break; } } if(cgc.cgroup_name == NULL) { slog(LOG_ALERT, "FATAL: No cgroup specified, exiting"); abort(); } if(daemon_flag) { if(daemon(0,0) == -1) { slog(LOG_ALERT, "FATAL: failed to daemonize!"); abort(); } if(pidfile) { pid_t pid = getpid(); FILE* f = fopen(pidfile, "w"); if(!f) { slog(LOG_ALERT, "FATAL: Failed to write to pidfile"); abort(); } fprintf(f, "%d", pid); fclose(f); free(pidfile); pidfile = NULL; } } cgc.efd = eventfd(0,0); assert(cgc.efd != -1); cgroup_init(); cgroup_get_subsys_mount_point("memory", &((cgc.cgroup_path))); cgroup_get_subsys_mount_point("freezer", &((cgc.freezer_path))); cgc.purgatory = cgroup_new_cgroup("purgatory"); cgroup_add_controller(cgc.purgatory, "freezer"); cgroup_create_cgroup(cgc.purgatory,1); char* purgatory_freeze_path; FILE* freezer_fd; asprintf(&purgatory_freeze_path, "/%s/purgatory/freezer.state", cgc.freezer_path); freezer_fd = fopen(purgatory_freeze_path,"w"); fprintf(freezer_fd, "FROZEN"); fclose(freezer_fd); free(purgatory_freeze_path); asprintf(&event_control_path, "/%s/%s/cgroup.event_control", cgc.cgroup_path, cgc.cgroup_name); cgc.ecfd = open(event_control_path, O_WRONLY); if(cgc.ecfd < 0) { slog(LOG_ALERT, "FATAL: failed to open cgroup event control: %s\n", event_control_path); perror("cgroup.event_control"); } asprintf(&oom_control_path, "/%s/%s/memory.oom_control", cgc.cgroup_path, cgc.cgroup_name); cgc.oomfd = open(oom_control_path, O_RDONLY); if(!(cgc.oomfd >=0)) { slog(LOG_ALERT, "FATAL: Failed to open oom_control"); abort(); } cl = asprintf(&event_command, "%d %d", cgc.efd, cgc.oomfd); write(cgc.ecfd, event_command, cl); free(event_control_path); free(event_command); free(oom_control_path); setjmp(exit_stack); sigemptyset(&sa.sa_mask); sa.sa_flags = SA_NOMASK; sa.sa_handler = exit_handler; sigaction(SIGINT, &sa, NULL); if(restart_on_crash_flg) //optionally make an effort to handle crashes { sa.sa_handler = crash_handler; sigaction(SIGSEGV, &sa, NULL); sigaction(SIGBUS, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); sigaction(SIGABRT, &sa, NULL); } if(restart_flag < 2) //try to handle recursive faults { stop_oomkiller(&cgc); while(!exit_flag) { read(cgc.efd, &efdcounter, sizeof(uint64_t)); flag = 0; //stop killing if the task list is empty (shouldn't happen) if(verbose_log) log_process_table(); //dump process list to syslog while(is_oom(&cgc) && flag >= 0) { flag = find_victim(&cgc); usleep(100); //give processes a chance to die } } cgroup_delete_cgroup(cgc.purgatory, 0); start_oomkiller(&cgc); close(cgc.oomfd); close(cgc.ecfd); } if(restart_flag) { char* args[argc+1]; int i; for(i=0;i<argc;i++) { asprintf(&(args[i]), "%s", argv[i]); } args[argc] = NULL; execv(argv[0], args); } }
/** * Tests the cgroup_delete_cgroup() api under different scenarios * @param retcode error code in case any error is expected from api * @param cgrp the group to be deleted * @param name the name of the group * @param common to test if group was created under one or both mountpoints * @param mpnt to test if group under mountpoint or mountpoint2 * @param ign parameter for api if to ignore the ownership * @param the test number */ void test_cgroup_delete_cgroup(int retcode, struct cgroup *cgrp, const char *name, int common, int mpnt, int ign, int i) { int retval; char path1_group[FILENAME_MAX], path2_group[FILENAME_MAX]; /* Check, In case some error is expected due to a negative scenario */ if (retcode) { retval = cgroup_delete_cgroup(cgrp, ign); if (retval == retcode) message(i, PASS, "delete_cgroup()", retval, info[NOMESSAGE]); else message(i, FAIL, "delete_cgroup()", retval, info[NOMESSAGE]); return; } /* Now there is no error and it is a genuine call */ retval = cgroup_delete_cgroup(cgrp, ign); if (retval) { message(i, FAIL, "delete_cgroup()", retval, info[NOMESSAGE]); return; } /* Let us now check if the group has been deleted from file system */ if (!common) { /* check only under one mountpoint */ if (mpnt == 1) /* check group under mountpoint */ build_path(path1_group, mountpoint, name, NULL); else /* check group under mountpoint2 */ build_path(path1_group, mountpoint2, name, NULL); if (group_exist(path1_group) == ENOENT) message(i, PASS, "delete_cgroup()", retval, info[GRPDELETEDINFS]); else message(i, FAIL, "delete_cgroup()", retval, info[GRPNOTDELETEDINFS]); } else { /* check group under both mountpoints */ /* Check if the group deleted under both mountpoints */ build_path(path1_group, mountpoint, name, NULL); if (group_exist(path1_group) == ENOENT) { build_path(path2_group, mountpoint2, name, NULL); if (group_exist(path2_group) == ENOENT) message(i, PASS, "delete_cgroup()", retval, info[GRPDELETEDINFS]); else message(i, FAIL, "delete_cgroup()", retval, info[GRPNOTDELETEDGLOBALY]); } else { message(i, FAIL, "delete_cgroup()", retval, info[GRPNOTDELETEDINFS]); } } }