/*
 * Copyright IBM Corporation. 2008
 *
 * Author:	Sudhir Kumar <skumar@linux.vnet.ibm.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.
 *
 * Description: This file contains the test code for testing libcgroup apis.
 */

#include "libcgrouptest.h"
#include <errno.h>

int cpu, memory;
int fs_mounted;
/* We use mountpoint for single mount.
 * For multimount we use mountpoint and mountpoint2.
 */
char mountpoint[FILENAME_MAX], mountpoint2[FILENAME_MAX];

int main(int argc, char *argv[])
{
	int retval;
	struct uid_gid_t ids = {0}; /* Set default control permissions */

	struct cntl_val_t cval;
	cval.val_int64 = 200000;
	cval.val_uint64 = 200000;
	cval.val_bool = 1;
	strcpy(cval.val_string, "200000");

	struct cgroup *cgroup1, *cgroup2, *cgroup3, *nullcgroup = NULL;
	struct cgroup_controller *sec_controller;
	/* In case of multimount for readability we use the controller name
	 * before the cgroup structure name */
	struct cgroup *ctl1_cgroup1, *ctl2_cgroup1, *ctl2_cgroup2;
	struct cgroup *mod_ctl1_cgroup1, *mod_ctl2_cgroup1, *mod_common_cgroup;
	struct cgroup *common_cgroup;
	char controller_name[FILENAME_MAX], control_file[FILENAME_MAX];
	char path_control_file[FILENAME_MAX];

	/* Get controllers name from script */
	int ctl1 = CPU, ctl2 = MEMORY;

	if ((argc < 2) || (argc > 6) || (atoi(argv[1]) < 0)) {
		printf("ERROR: Wrong no of parameters recieved from script\n");
		printf("Exiting the libcgroup testset\n");
		exit(1);
	}
	fs_mounted = atoi(argv[1]);
	cgroup_dbg("C:DBG: fs_mounted as recieved from script=%d\n",
								fs_mounted);
	/* All possible controller will be element of an enum */
	if (fs_mounted) {
		ctl1 = atoi(argv[2]);
		ctl2 = atoi(argv[3]);
		strncpy(mountpoint, argv[4], sizeof(mountpoint));
		cgroup_dbg("C:DBG: mountpoint1 as recieved from script=%s\n",
								 mountpoint);
		if (fs_mounted == FS_MULTI_MOUNTED) {
			strncpy(mountpoint2, argv[5], sizeof(mountpoint2));
			cgroup_dbg("C:DBG: mountpoint2 as recieved from "
					"script=%s\n", mountpoint2);
		}

	}

	/*
	 * check if one of the supported controllers is cpu or memory
	 */
	is_subsystem_enabled("cpu", &cpu);
	is_subsystem_enabled("memory", &memory);
	if (cpu == 0 && memory == 0) {
		fprintf(stderr, "none of cpu and memory controllers"
						" is enabled in kernel\n");
		fprintf(stderr, "Exiting the libcgroup testcases......\n");
		exit(1);
	}

	/*
	 * Testsets: Testcases are broadly devided into 3 categories based on
	 * filesystem(fs) mount scenario. fs not mounted, fs mounted, fs multi
	 * mounted. Call different apis in these different scenarios.
	 */

	switch (fs_mounted) {

	case FS_NOT_MOUNTED:

		/*
		 * Test01: call cgroup_init() and check return values
		 * Exp outcome: error ECGROUPNOTMOUNTED
		 */

		test_cgroup_init(ECGROUPNOTMOUNTED, 1);

		/*
		 * Test02: call cgroup_attach_task() with null group
		 * Exp outcome: error non zero return value
		 */

		test_cgroup_attach_task(ECGROUPNOTINITIALIZED, nullcgroup,
						 NULL, NULL, 0, NULLGRP, 2);

		/*
		 * Test03: Create a valid cgroup ds and check all return values
		 * Exp outcome: no error
		 */

		cgroup1 = create_new_cgroup_ds(0, "group1",
						 STRING, cval, ids, 3);

		/*
		 * Test04: Then Call cgroup_create_cgroup() with this valid grp
		 * Exp outcome: non zero return value
		 */
		test_cgroup_create_cgroup(ECGROUPNOTINITIALIZED, cgroup1,
							 "group1", 0, 1, 1, 4);

		/*
		 * Test05: delete cgroup
		 * Exp outcome: non zero return value but what ?
		 */
		test_cgroup_delete_cgroup(ECGROUPNOTINITIALIZED, cgroup1,
							 "group1", 0, 1, 1, 5);

		/*
		 * Test06: Check if cgroup_create_cgroup() handles a NULL cgroup
		 * Exp outcome: error ECGROUPNOTALLOWED
		 */
		test_cgroup_create_cgroup(ECGROUPNOTINITIALIZED, nullcgroup,
							 "group1", 0, 1, 1, 6);

		/*
		 * Test07: delete nullcgroup
		 */
		test_cgroup_delete_cgroup(ECGROUPNOTINITIALIZED, nullcgroup,
							 "group1", 0, 1, 1, 7);
		/* Test08: test the wrapper */
		test_cgroup_add_free_controller(8);

		cgroup_free(&nullcgroup);
		cgroup_free(&cgroup1);

		break;

	case FS_MOUNTED:

		/* Do a sanity check if cgroup fs is mounted */
		if (check_fsmounted(0)) {
			printf("Sanity check fails. cgroup fs not mounted\n");
			printf("Exiting without running this set of tests\n");
			exit(1);
		}

		/*
		 * Test01: call cgroup_attach_task() with null group
		 * without calling cgroup_init(). We can check other apis too.
		 * Exp outcome: error ECGROUPNOTINITIALIZED
		 */

		test_cgroup_attach_task(ECGROUPNOTINITIALIZED, nullcgroup,
						 NULL, NULL, 0, NULLGRP, 1);

		/*
		 * Test02: call cgroup_init() and check return values
		 * Exp outcome:  no error. return value 0
		 */

		test_cgroup_init(0, 2);

		/*
		 * Test03: Call cgroup_attach_task() with null group and check
		 * if return values are correct. If yes check if task exists in
		 * root group tasks file
		 * TODO: This test needs some modification in script
		 * Exp outcome: current task should be attached to root group
		 */

		test_cgroup_attach_task(0, nullcgroup, NULL, NULL, 0,
							 NULLGRP, 3);
		/*
		 * Test04: Call cgroup_attach_task_pid() with null group
		 * and invalid pid
		 * Exp outcome: error
		 */
		retval = cgroup_attach_task_pid(nullcgroup, -1);
		if (retval != 0)
			message(4, PASS, "attach_task_pid()", retval,
							 info[NOMESSAGE]);
		else
			message(4, FAIL, "attach_task_pid()", retval,
							 info[NOMESSAGE]);

		/*
		 * Test05: Create a valid cgroup structure
		 * Exp outcome: no error. 0 return value
		 */
		cgroup1 = create_new_cgroup_ds(ctl1, "group1",
							 STRING, cval, ids, 5);
		if (!cgroup1) {
			fprintf(stderr, "Failed to create new cgroup ds. "
					"Trying with second controller\n");
			cgroup1 = create_new_cgroup_ds(ctl2, "group1", STRING,
								cval, ids, 5);
			if (!cgroup1) {
				fprintf(stderr, "Failed to create cgroup ds. "
					"Tests dependent on this structure "
					"will fail. So exiting...\n");
				exit(1);
			}
		}

		/*
		 * Test06: Then Call cgroup_create_cgroup() with this group
		 * Exp outcome: zero return value
		 */
		test_cgroup_create_cgroup(0, cgroup1, "group1", 0, 1, 1, 6);

		/*
		 * Test07: Call cgroup_attach_task() with valid cgroup and check
		 * if return values are correct. If yes check if task exists in
		 * that group's tasks file
		 * Exp outcome: current task should be attached to that group
		 */

		test_cgroup_attach_task(0, cgroup1, "group1", NULL,
							 0, NOMESSAGE, 7);

		/*
		 * Test08: modify cgroup with the same cgroup
		 * Exp outcome: zero return value. No change.
		 */
		set_controller(ctl1, controller_name, control_file);
		build_path(path_control_file, mountpoint,
						 "group1", control_file);
		strncpy(cval.val_string, "260000", sizeof(cval.val_string));
		retval = cgroup_modify_cgroup(cgroup1);
		/* Check if the values are changed. cval contains orig values */
		if (!retval && !group_modified(path_control_file, STRING, cval))
			message(8, PASS, "modify_cgroup()", retval,
							 info[SAMEGRP]);
		else
			message(8, FAIL, "modify_cgroup()", retval,
							 info[SAMEGRP]);

		/*
		 * Create another valid cgroup structure with same group
		 * to modify the existing group
		 */
		cgroup2 = create_new_cgroup_ds(ctl1, "group1",
						 STRING, cval, ids, 9);
		if (!cgroup2) {
			fprintf(stderr, "Failed to create new cgroup ds. "
					"Trying with second controller\n");
			cgroup2 = create_new_cgroup_ds(ctl2, "group1",
							 STRING, cval, ids, 9);
			if (!cgroup2) {
				fprintf(stderr, "Failed to create cgroup ds. "
					"Tests dependent on this structure "
					"will fail. So exiting...\n");
				exit(1);
			}
		}

		/*
		 * Test10: modify cgroup with this new cgroup
		 * Exp outcome: zero return value
		 * Drawback: In case of first attempt failure above for
		 * create_new_cgroup_ds(), this test will fail
		 */
		test_cgroup_modify_cgroup(0, cgroup2, "group1",
					 1, ctl1, ctl2, STRING, 10);

		/*
		 * Test11: modify cgroup with the null cgroup
		 * Exp outcome: zero return value.
		 */

		test_cgroup_modify_cgroup(ECGROUPNOTALLOWED, nullcgroup,
					 "group1", 1, ctl1, ctl2, STRING, 11);

		/*
		 * Create another valid cgroup structure with diff controller
		 * to modify the existing group
		 */
		cval.val_int64 = 262144;
		cgroup3 = create_new_cgroup_ds(ctl2, "group1",
						 INT64, cval, ids, 12);
		if (!cgroup3) {
			fprintf(stderr, "Failed to create new cgroup ds. "
					"Tests dependent on this structure "
					"will fail. So exiting...\n");
			exit(1);
		}

		/*
		 * Test13: modify existing group with this cgroup
		 * Exp outcome: zero return value
		 */
		test_cgroup_modify_cgroup(0, cgroup3, "group1",
						 2, ctl1, ctl2, INT64, 13);

		/* Test14: Test cgroup_get_cgroup() api
		 * The group group1 has been created and modified in the
		 * filesystem. Read it using the api and check if the values
		 * are correct as we know all the control values now.
		 * WARN: If any of the previous api fails and control reaches
		 * here, this api also will fail. Also the test function assumes
		 * that "group1" exists in fs. So call cgroup_create_cgroup()
		 * with "group1" named group before calling this test function.
		 */
		test_cgroup_get_cgroup(ctl1, ctl2, ids, 14);

		/*
		 * Test16: delete cgroup
		 * Exp outcome: zero return value
		 */
		test_cgroup_delete_cgroup(0, cgroup1, "group1", 0, 1, 1, 16);

		/*
		 * Test16: Check if cgroup_create_cgroup() handles a NULL cgroup
		 * Exp outcome: error ECGROUPNOTALLOWED
		 */
		test_cgroup_create_cgroup(ECGROUPNOTALLOWED, nullcgroup,
							 "group1", 0, 1, 1, 17);

		/*
		 * Test16: delete nullcgroup
		 */
		test_cgroup_delete_cgroup(ECGROUPNOTALLOWED, NULL,
							 "group1", 0, 1, 1, 18);

		/* Test17: Test the wrapper to compare cgroup
		 * Create 2 cgroups and test it
		 */
		test_cgroup_compare_cgroup(ctl1, ctl2, 19);

		cgroup_free(&nullcgroup);
		cgroup_free(&cgroup1);
		cgroup_free(&cgroup2);
		cgroup_free(&cgroup3);

		break;

	case FS_MULTI_MOUNTED:

		/* Do a sanity check if cgroup fs is multi mounted */
		if (check_fsmounted(1)) {
			printf("Sanity check fails. cgroup fs is not multi "
				"mounted. Exiting without running this set "
					"of testcases\n");
			exit(1);
		}

		/*
		 * Test01: call apis and check return values
		 * Exp outcome:
		 */

		/*
		 * Scenario 1: cgroup fs is multi mounted
		 * Exp outcome: no error. 0 return value
		 */

		test_cgroup_init(0, 1);

		/*
		 * Test02: Call cgroup_attach_task() with null group and check
		 * if return values are correct. If yes check if task exists in
		 * root group tasks file for each controller
		 * TODO: This test needs some modification in script
		 * Exp outcome: current task should be attached to root groups
		 */

		test_cgroup_attach_task(0, nullcgroup, NULL, NULL,
							 0, NULLGRP, 2);

		/*
		 * Test03: Create a valid cgroup structure
		 * Exp outcome: no error. 0 return value
		 */
		ctl1_cgroup1 = create_new_cgroup_ds(ctl1, "ctl1_group1",
							 STRING, cval, ids, 3);
		if (!ctl1_cgroup1) {
			fprintf(stderr, "Failed to create new cgroup ds. "
					"Tests dependent on this structure "
					"will fail. So exiting...\n");
			exit(1);
		}

		/*
		 * Test04: Then Call cgroup_create_cgroup() with this valid grp
		 * Exp outcome: zero return value
		 */
		test_cgroup_create_cgroup(0, ctl1_cgroup1,
						 "ctl1_group1", 0, 1, 1, 4);

		/*
		 * Test05: Create a valid cgroup structure
		 * Exp outcome: no error. 0 return value
		 */
		ctl2_cgroup1 = create_new_cgroup_ds(ctl2, "ctl2_group1",
							 STRING, cval, ids, 5);
		if (!ctl2_cgroup1) {
			fprintf(stderr, "Failed to create new cgroup ds. "
					"Tests dependent on this structure "
					"will fail. So exiting...\n");
			exit(1);
		}

		/*
		 * Test06: Then Call cgroup_create_cgroup() with this valid grp
		 * Exp outcome: zero return value
		 */
		test_cgroup_create_cgroup(0, ctl2_cgroup1,
						 "ctl2_group1", 0, 2, 1, 6);

		/*
		 * Test07: Call cgroup_create_cgroup() with the same group
		 * Exp outcome: zero return value as the latest changes in api
		 */
		test_cgroup_create_cgroup(0, ctl2_cgroup1,
						 "ctl2_group1", 0, 2, 1, 7);

		/*
		 * Test06: Call cgroup_attach_task() with a group with ctl1
		 * controller and check if return values are correct. If yes
		 * check if task exists in that group under only ctl1 controller
		 * hierarchy and in the root group under other controllers
		 * hierarchy.
		 */

		test_cgroup_attach_task(0, ctl1_cgroup1, "ctl1_group1",
						 NULL, 0, NOMESSAGE, 8);

		/*
		 * Test07: Call cgroup_attach_task() with a group with ctl2
		 * controller and check if return values are correct. If yes
		 * check if task exists in the groups under both controller's
		 * hierarchy.
		 */

		test_cgroup_attach_task(0, ctl2_cgroup1, "ctl1_group1",
					 "ctl2_group1", 0, NOMESSAGE, 9);

		/*
		 * Test: Create a valid cgroup structure
		 * Exp outcome: no error. 0 return value
		 */
		ctl2_cgroup2 = create_new_cgroup_ds(ctl2, "ctl2_group2",
							 STRING, cval, ids, 10);
		if (!ctl2_cgroup2) {
			fprintf(stderr, "Failed to create new cgroup ds. "
					"Tests dependent on this structure "
					"will fail. So exiting...\n");
			exit(1);
		}

		/*
		 * Test08: Try to attach a task to this non existing group.
		 * Group does not exist in fs so should return ECGROUPNOTEXIST
		 */

		test_cgroup_attach_task(ECGROUPNOTEXIST, ctl2_cgroup2,
					 NULL, NULL, 0, NOTCRTDGRP, 11);

		/*
		 * Create another valid cgroup structure with same group name
		 * to modify the existing group ctl1_group1
		 * Exp outcome: no error. 0 return value
		 */
		mod_ctl1_cgroup1 = create_new_cgroup_ds(ctl1, "ctl1_group1",
							 STRING, cval, ids, 12);
		if (!mod_ctl1_cgroup1) {
			fprintf(stderr, "Failed to create new cgroup ds. "
					"Tests dependent on this structure "
					"will fail. So exiting...\n");
			exit(1);
		}

		/*
		 * Test09: modify existing cgroup with this new cgroup
		 * Exp outcome: zero return value and control value modified
		 */
		test_cgroup_modify_cgroup(0, mod_ctl1_cgroup1, "ctl1_group1",
						 1, ctl1, ctl2, STRING, 13);

		/*
		 * Create another valid cgroup structure with same group name
		 * to modify the existing group ctl2_group1
		 * Exp outcome: no error. 0 return value
		 */
		mod_ctl2_cgroup1 = create_new_cgroup_ds(ctl2, "ctl2_group1",
							 STRING, cval, ids, 14);
		if (!mod_ctl2_cgroup1) {
			fprintf(stderr, "Failed to create new cgroup ds. "
					"Tests dependent on this structure "
					"will fail. So exiting...\n");
			exit(1);
		}

		/*
		 * Test10: modify existing cgroup with this new cgroup
		 * Exp outcome: zero return value and control value modified
		 */
		test_cgroup_modify_cgroup(0, mod_ctl2_cgroup1, "ctl2_group1",
						 2, ctl1, ctl2, STRING, 15);

		/*
		 * Test11: delete cgroups
		 * Exp outcome: zero return value
		 */
		test_cgroup_delete_cgroup(0, ctl1_cgroup1,
						 "ctl1_group1", 0, 1, 1, 16);

		/*
		 * Test09: delete other cgroups too
		 * Exp outcome: zero return value
		 */
		test_cgroup_delete_cgroup(0, ctl2_cgroup1,
						 "ctl2_group1", 0, 1, 1, 17);

		/*
		 * Test15: Create a valid cgroup structure
		 * which has multiple controllers
		 * Exp outcome: no error. 0 return value
		 */
		common_cgroup = create_new_cgroup_ds(ctl1, "commongroup",
							 STRING, cval, ids, 18);
		if (!common_cgroup) {
			fprintf(stderr, "Failed to create new cgroup ds. "
					"Tests dependent on this structure "
					"will fail. So exiting...\n");
			exit(1);
		}

		/* Add one more controller to the cgroup */
		/* This also needs to be a function.. will do?? */
		retval = set_controller(ctl2, controller_name, control_file);
		if (retval) {
			fprintf(stderr, "Setting controller failled "
				" Exiting without running further testcases\n");
			exit(1);
		}
		if (!cgroup_add_controller(common_cgroup, controller_name)) {
			message(15, FAIL, "add_controller()", retval,
							 info[NOMESSAGE]);
			fprintf(stderr, "Adding second controller failled "
				" Exiting without running further testcases\n");
			exit(1);
		}

		/*
		 * Test11: Then Call cgroup_create_cgroup() with this valid grp
		 * Exp outcome: zero return value
		 */
		test_cgroup_create_cgroup(0, common_cgroup,
						 "commongroup", 1, 2, 1, 19);

		/*
		 * Test12: Call cgroup_attach_task() with this common group
		 * and check if return values are correct. If yes check if
		 * task exists in the group under both controller's hierarchy
		 */

		test_cgroup_attach_task(0, common_cgroup, "commongroup",
					 "commongroup", 0, COMMONGRP, 20);

		/*
		 * Test18: Create a valid cgroup structure to modify the
		 * commongroup which is under multiple controllers
		 * Exp outcome: no error. 0 return value
		 */
		mod_common_cgroup = create_new_cgroup_ds(ctl1, "commongroup",
							 STRING, cval, ids, 21);
		if (!common_cgroup) {
			fprintf(stderr, "Failed to create new cgroup ds. "
					"Tests dependent on this structure "
					"will fail. So exiting...\n");
			exit(1);
		}

		/* Add one more controller to the cgroup */
		/* This also needs to be a function.. will do?? */
		retval = set_controller(ctl2, controller_name, control_file);
		if (retval) {
			fprintf(stderr, "Setting controller failled "
				" Exiting without running further testcases\n");
			exit(1);
		}
		sec_controller = cgroup_add_controller(mod_common_cgroup,
							 controller_name);
		if (!sec_controller) {
			message(18, FAIL, "add_controller()", retval,
							 info[NOMESSAGE]);
			fprintf(stderr, "Adding second controller failled "
				" Exiting without running further testcases\n");
			exit(1);
		}

		strncpy(cval.val_string, "7000064", sizeof(cval.val_string));
		retval = cgroup_add_value_string(sec_controller,
						 control_file, cval.val_string);
		if (retval)
			printf("The cgroup_modify_cgroup() test will fail\n");

		/*
		 * Test14: modify existing cgroup with this new cgroup
		 * Exp outcome: zero return value and control value modified
		 */
		test_cgroup_modify_cgroup(0, mod_common_cgroup, "commongroup",
						 0, ctl1, ctl2, STRING, 22);

		/*
		 * Test15: delete this common cgroup
		 * Exp outcome: zero return value
		 */
		test_cgroup_delete_cgroup(0, common_cgroup,
						 "commongroup", 1, 2, 1, 23);
		test_cgroup_get_cgroup(ctl1, ctl2, ids, 24);

		/* Free the cgroup structures */
		cgroup_free(&nullcgroup);
		cgroup_free(&ctl1_cgroup1);
		cgroup_free(&ctl2_cgroup1);
		cgroup_free(&ctl2_cgroup2);

		break;

	default:
		fprintf(stderr, "ERROR: Wrong parameters recieved from script. \
						Exiting tests\n");
		exit(1);
		break;
	}
	return 0;
}

void test_cgroup_modify_cgroup(int retcode, struct cgroup *cgrp,
			 const char *name, int which_ctl, int ctl1,
					 int ctl2, int value_type, int i)
{
	int retval;
	struct cntl_val_t cval = {0, 0, 0, "1000"};
	char path1_control_file[FILENAME_MAX], path2_control_file[FILENAME_MAX];
	char controller_name[FILENAME_MAX], control_file[FILENAME_MAX];

	/* Check, In case some error is expected due to a negative scenario */
	if (retcode) {
		retval = cgroup_modify_cgroup(cgrp);
		if (retval == retcode)
			message(i, PASS, "modify_cgroup()", retval,
							 info[NOMESSAGE]);
		else
			message(i, FAIL, "modify_cgroup()", retval,
							 info[NOMESSAGE]);

		return;
	}

	/* Now there is no error and it is a genuine call */
	retval = cgroup_modify_cgroup(cgrp);
	if (retval) {
		message(i, FAIL, "modify_cgroup()", retval,  info[NOMESSAGE]);
		return;
	}

	/* Let us now check if the group modified in file system */
	switch (which_ctl) { /* group modified under which controllers */

	case 1: /* group is modified under ctl1 which is always
		 * mounted at mountpoint in both cases */
		set_controller(ctl1, controller_name, control_file);
		build_path(path1_control_file, mountpoint, name, control_file);
		/* this approach will be changed in coming patches */
		strncpy(cval.val_string, "260000", sizeof(cval.val_string));

		if (!group_modified(path1_control_file, value_type, cval))
			message(i, PASS, "modify_cgroup()", retval,
							 info[NOMESSAGE]);
		else
			message(i, FAIL, "modify_cgroup()", retval,
							 info[NOMESSAGE]);

		break;
	case 2: /* group is modified under ctl2 which may be
		 * mounted at mountpoint or mountpoint2 */
		set_controller(ctl2, controller_name, control_file);

		if (fs_mounted == FS_MOUNTED)	/* group under mountpoint */
			build_path(path2_control_file, mountpoint,
						 name, control_file);
		else	/* group under mountpoint2 */
			build_path(path2_control_file, mountpoint2,
						 name, control_file);

		/* this approach will be changed in coming patches */
		strncpy(cval.val_string, "7000064", sizeof(cval.val_string));
		cval.val_int64 = 262144;
		if (!group_modified(path2_control_file, value_type, cval))
			message(i, PASS, "modify_cgroup()", retval,
							 info[NOMESSAGE]);
		else
			message(i, FAIL, "modify_cgroup()", retval,
							 info[NOMESSAGE]);

		break;
	case 0:
		/* ctl1 is always mounted at mountpoint */
		set_controller(ctl1, controller_name, control_file);
		build_path(path1_control_file, mountpoint,
						 name, control_file);
		/* ctl2 may be mounted at mountpoint or mountpoint2 depending
		 * on single or multiple mount case */
		if (fs_mounted == FS_MOUNTED) {	/* group under mountpoint */
			set_controller(ctl2, controller_name, control_file);
			build_path(path2_control_file, mountpoint,
						 name, control_file);
		} else {	/* group under mountpoint2 */
			set_controller(ctl2, controller_name, control_file);
			build_path(path2_control_file, mountpoint2,
						 name, control_file);
		}
		/* this approach will be changed in coming patches */
		strncpy(cval.val_string, "260000", sizeof(cval.val_string));
		if (!group_modified(path1_control_file, value_type, cval)) {
			strncpy(cval.val_string, "7000064",
						 sizeof(cval.val_string));
			if (!group_modified(path2_control_file,
							 value_type, cval))
				message(i, PASS, "modify_cgroup()",
					 retval, info[GRPMODINBOTHCTLS]);
			else
				message(i, FAIL, "modify_cgroup()",
					 retval, info[GRPNOTMODIN2NDCTL]);
		} else {
			message(i, FAIL, "modify_cgroup()", retval,
						 info[GRPNOTMODINANYCTL]);
		}

		break;
	default:
		printf("Wrong controller parameter received....\n");
		message(i, FAIL, "modify_cgroup()", retval, info[NOMESSAGE]);
		break;
	}

	return;
}
