示例#1
0
/**
 * Tests the cgroup_attach_cgroup() api under different scenarios
 * @param retcode error code in case any error is expected from api
 * @param cgrp the group to assign the task to
 * @param group1 the name of the group under first (single) mountpoint
 * @param group2 the name of the group under 2nd moutpoint for multimount
 * @param i the test number
 * @param k the message enum number to print the useful message
 */
void test_cgroup_attach_task(int retcode, struct cgroup *cgrp,
	 const char *group1, const char *group2, pid_t pid, int k, int i)
{
	int retval;
	char tasksfile[FILENAME_MAX], tasksfile2[FILENAME_MAX];
	/* Check, In case some error is expected due to a negative scenario */
	if (retcode) {
		if (pid)
			retval = cgroup_attach_task_pid(cgrp, pid);
		else
			retval = cgroup_attach_task(cgrp);

		if (retval == retcode)
			message(i, PASS, "attach_task()", retval, info[k]);
		else
			message(i, FAIL, "attach_task()", retval, info[k]);

		return;
	}

	/* Now there is no error and it is a genuine call */
	if (pid)
		retval = cgroup_attach_task_pid(cgrp, pid);
	else
		retval = cgroup_attach_task(cgrp);

	/* API returned success, so perform check */
	if (retval == 0) {
		build_path(tasksfile, mountpoint,
					 group1, "tasks");

		if (check_task(tasksfile, 0)) {
			if (fs_mounted == 2) {
				/* multiple mounts */
				build_path(tasksfile2, mountpoint2,
							 group2, "tasks");
				if (check_task(tasksfile2, 0)) {
					message(i, PASS, "attach_task()",
						 retval, info[TASKINGRP]);
				} else {
					message(i, FAIL, "attach_task()",
						 retval, info[TASKNOTINANYGRP]);
				}
			} else {
				/* single mount */
				message(i, PASS, "attach_task()",
						 retval, info[TASKINGRP]);
			}
		} else {
			message(i, FAIL, "attach_task()", retval,
							 info[TASKNOTINGRP]);
		}
	} else {
		message(i, FAIL, "attach_task()", retval, (char *)"\n");
	}
}
示例#2
0
static int l_cgroup_attach_task_pid(lua_State *L)
{
  struct u_cgroup *uc = check_cgroup(L, 1);
  int pid = luaL_checkinteger(L, 2);

  lua_pushinteger(L, cgroup_attach_task_pid(uc->group, pid));
  return 1;
}
示例#3
0
文件: cgroup.c 项目: avagin/vzctl
int container_add_task(envid_t veid)
{
	char cgrp[CT_MAX_STR_SIZE];
	struct cgroup *ct;
	int ret;

	veid_to_name(cgrp, veid);
	ct = cgroup_new_cgroup(cgrp);
	ret = cgroup_get_cgroup(ct);
	if (ret)
		goto out;

	ret = cgroup_attach_task_pid(ct, getpid());
out:
	cgroup_free(&ct);
	return ret;
}
示例#4
0
static mrb_value mrb_cgroup_attach(mrb_state *mrb, mrb_value self)
{
    mrb_cgroup_context *mrb_cg_cxt = mrb_cgroup_get_context(mrb, self, "mrb_cgroup_context");
    mrb_value pid = mrb_nil_value();
    mrb_get_args(mrb, "|i", &pid);

    if (mrb_nil_p(pid)) {
        cgroup_attach_task(mrb_cg_cxt->cg);
    } else {
        cgroup_attach_task_pid(mrb_cg_cxt->cg, mrb_fixnum(pid));
    }
    mrb_iv_set(mrb
        , self
        , mrb_intern_cstr(mrb, "mrb_cgroup_context")
        , mrb_obj_value(Data_Wrap_Struct(mrb
            , mrb->object_class
            , &mrb_cgroup_context_type
            , (void *)mrb_cg_cxt)
        )
    );

    return self;
}
示例#5
0
int
ProcFamily::migrate_to_cgroup(pid_t pid)
{
	// Attempt to migrate a given process to a cgroup.
	// This can be done without regards to whether the
	// process is already in the cgroup
	if (!m_cgroup.isValid()) {
		return 1;
	}

	// We want to make sure task migration is turned on for the
	// associated memory controller.  So, we get to look up the original cgroup.
	//
	// If there is no memory controller present, we skip all this and just attempt a migrate
	int err;
	u_int64_t orig_migrate;
	bool changed_orig = false;
	char * orig_cgroup_string = NULL;
	struct cgroup * orig_cgroup;
	struct cgroup_controller * memory_controller;
	if (m_cm.isMounted(CgroupManager::MEMORY_CONTROLLER) && (err = cgroup_get_current_controller_path(pid, MEMORY_CONTROLLER_STR, &orig_cgroup_string))) {
		dprintf(D_PROCFAMILY,
			"Unable to determine current memory cgroup for PID %u (ProcFamily %u): %u %s\n",
			pid, m_root_pid, err, cgroup_strerror(err));
		return 1;
	}
	// We will migrate the PID to the new cgroup even if it is in the proper memory controller cgroup
	// It is possible for the task to be in multiple cgroups.
	if (m_cm.isMounted(CgroupManager::MEMORY_CONTROLLER) && (orig_cgroup_string != NULL) && (strcmp(m_cgroup_string.c_str(), orig_cgroup_string))) {
		// Yes, there are race conditions here - can't really avoid this.
		// Throughout this block, we can assume memory controller exists.
		// Get original value of migrate.
		orig_cgroup = cgroup_new_cgroup(orig_cgroup_string);
		ASSERT (orig_cgroup != NULL);
		if ((err = cgroup_get_cgroup(orig_cgroup))) {
			dprintf(D_PROCFAMILY,
				"Unable to read original cgroup %s (ProcFamily %u): %u %s\n",
				orig_cgroup_string, m_root_pid, err, cgroup_strerror(err));
			goto after_migrate;
		}
		if ((memory_controller = cgroup_get_controller(orig_cgroup, MEMORY_CONTROLLER_STR)) == NULL) {
			cgroup_free(&orig_cgroup);
			goto after_migrate;
		}
		if ((err = cgroup_get_value_uint64(memory_controller, "memory.move_charge_at_immigrate", &orig_migrate))) {
			if (err == ECGROUPVALUENOTEXIST) {
				// Older kernels don't have the ability to migrate memory accounting to the new cgroup.
				dprintf(D_PROCFAMILY,
					"This kernel does not support memory usage migration; cgroup %s memory statistics"
					" will be slightly incorrect (ProcFamily %u)\n",
					m_cgroup_string.c_str(), m_root_pid);
			} else {
				dprintf(D_PROCFAMILY,
					"Unable to read cgroup %s memory controller settings for "
					"migration (ProcFamily %u): %u %s\n",
					orig_cgroup_string, m_root_pid, err, cgroup_strerror(err));
			}
			cgroup_free(&orig_cgroup);
			goto after_migrate;
		}
		if (orig_migrate != 3) {
			orig_cgroup = cgroup_new_cgroup(orig_cgroup_string);
			memory_controller = cgroup_add_controller(orig_cgroup, MEMORY_CONTROLLER_STR);
			ASSERT (memory_controller != NULL); // Memory controller must already exist
			cgroup_add_value_uint64(memory_controller, "memory.move_charge_at_immigrate", 3);
			if ((err = cgroup_modify_cgroup(orig_cgroup))) {
				// Not allowed to change settings
				dprintf(D_ALWAYS,
					"Unable to change cgroup %s memory controller settings for migration. "
					"Some memory accounting will be inaccurate (ProcFamily %u): %u %s\n",
					orig_cgroup_string, m_root_pid, err, cgroup_strerror(err));
			} else {
				changed_orig = true;
			}
		}
		cgroup_free(&orig_cgroup);
	}

after_migrate:

	orig_cgroup = NULL;
	err = cgroup_attach_task_pid(& const_cast<struct cgroup &>(m_cgroup.getCgroup()), pid);
	if (err) {
		dprintf(D_PROCFAMILY,
			"Cannot attach pid %u to cgroup %s for ProcFamily %u: %u %s\n",
			pid, m_cgroup_string.c_str(), m_root_pid, err, cgroup_strerror(err));
	}

	if (changed_orig) {
		if ((orig_cgroup = cgroup_new_cgroup(orig_cgroup_string))) {
			goto after_restore;
		}
		if (((memory_controller = cgroup_add_controller(orig_cgroup, MEMORY_CONTROLLER_STR)) != NULL) &&
			(!cgroup_add_value_uint64(memory_controller, "memory.move_charge_at_immigrate", orig_migrate))) {
			cgroup_modify_cgroup(orig_cgroup);
		}
		cgroup_free(&orig_cgroup);
	}


after_restore:
	if (orig_cgroup_string != NULL) {
		free(orig_cgroup_string);
	}
	return err;
}