コード例 #1
0
ファイル: mrb_cgroup.c プロジェクト: keizo042/mruby-cgroup
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;
}
コード例 #2
0
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);
	}
}
コード例 #3
0
ファイル: test_functions.c プロジェクト: j000/libcgroup
/**
 * 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]);
		}
	}

}