--- ../crash/extensions/cgget.c	2013-03-08 14:22:56.902931000 +0800
+++ extensions/cgget.c	2013-03-08 14:29:21.434098147 +0800
@@ -36,6 +36,7 @@
 #define ACC_MKNOD 1
 #define ACC_READ  2
 #define ACC_WRITE 4
+#define ACC_MASK (ACC_MKNOD|ACC_READ|ACC_WRITE)
 
 #define LRU_BASE 0
 #define LRU_ACTIVE 1
@@ -110,6 +111,8 @@
 struct memory_offset_table {
 	long memory_res;
 	long memory_memsw;
+	long memory_kmem;
+	long memory_tcp_mem;
 	long memory_info;
 	long memory_stat;
 	long memory_oom_kill_disable;
@@ -127,6 +130,12 @@
 
 struct devices_offset_table {
 	long devices_whitelist;
+	long devices_behavior;
+	long item_major;
+	long item_minor;
+	long item_type;
+	long item_access;
+	long item_list;
 };
 
 struct freezer_offset_table {
@@ -242,6 +251,14 @@
 };
 
 enum memory_param_id {
+	MEM_TMEM_FAILCNT,
+	MEM_TMEM_LIMIT,
+	MEM_TMEM_MAX_USAGE,
+	MEM_TMEM_USAGE,
+	MEM_KMEM_FAILCNT,
+	MEM_KMEM_LIMIT,
+	MEM_KMEM_MAX_USAGE,
+	MEM_KMEM_USAGE,
 	MEM_MEMSW_FAILCNT,
 	MEM_MEMSW_LIMIT,
 	MEM_MEMSW_MAX_USAGE,
@@ -262,6 +279,14 @@
 };
 
 static const char *memory_params[] = {
+	"kmem.tcp.failcnt",
+	"kmem.tcp.limit_in_bytes",
+	"kmem.tcp.max_usage_in_bytes",
+	"kmem.tcp.usage_in_bytes",
+	"kmem.failcnt",
+	"kmem.limit_in_bytes",
+	"kmem.max_usage_in_bytes",
+	"kmem.usage_in_bytes",
 	"memsw.failcnt",
 	"memsw.limit_in_bytes",
 	"memsw.max_usage_in_bytes",
@@ -517,7 +542,7 @@
 static void netprio_offset_table_init();
 
 /* printing-assisted functions */
-static int read_whitelist(struct cgroup_spec *, ulong);
+static int read_whitelist(struct cgroup_spec *, ulong, int);
 static char *hugepage_fmt(char *, uint64_t);
 static inline int is_root_mem_cgroup(ulong);
 static uint64_t read_res_counter(ulong, long, char *);
@@ -876,41 +901,48 @@
 }
 
 static int
-read_whitelist(struct cgroup_spec *group_list, ulong whitelist_addr)
+read_whitelist(struct cgroup_spec *group_list, ulong whitelist_addr, int behavior)
 {
-	int ret = 0;
 	uint32_t major, minor;
 	short type, access;
 	char maj[MAJMINLEN], min[MAJMINLEN], acc[ACCLEN];
 
 	if (!whitelist_addr)
 		return -1;
-	if (!readmem(whitelist_addr + MEMBER_OFFSET("dev_whitelist_item", "major"),
-		KVADDR, &major, sizeof(uint32_t), "whitelist_item_major",
-		FAULT_ON_ERROR))
-		return -1;
-	set_majmin(maj, major);
+	if (behavior == 0) {
+		set_majmin(maj, ~0);
+		set_majmin(min, ~0);
+		set_access(acc, ACC_MASK);
+		fprintf(fp, "%s.list: %c %s:%s %s\n", group_list->subsys_str,
+			type_to_char(DEV_ALL), maj, min, acc);
+	} else {
+		if (!readmem(whitelist_addr + devices_offset_table.item_major,
+			KVADDR, &major, sizeof(uint32_t), "item_major",
+			FAULT_ON_ERROR))
+			return -1;
+		set_majmin(maj, major);
 
-	if (!readmem(whitelist_addr + MEMBER_OFFSET("dev_whitelist_item", "minor"),
-		KVADDR, &minor, sizeof(uint32_t), "whitelist_item_minor",
-		FAULT_ON_ERROR))
-		return -1;
-	set_majmin(min, minor);
+		if (!readmem(whitelist_addr + devices_offset_table.item_minor,
+			KVADDR, &minor, sizeof(uint32_t), "item_minor",
+			FAULT_ON_ERROR))
+			return -1;
+		set_majmin(min, minor);
 
-	if (!readmem(whitelist_addr + MEMBER_OFFSET("dev_whitelist_item", "access"),
-		KVADDR, &access, sizeof(short), "whitelist_item_access",
-		FAULT_ON_ERROR))
-		return -1;
-	set_access(acc, access);
+		if (!readmem(whitelist_addr + devices_offset_table.item_access,
+			KVADDR, &access, sizeof(short), "item_access",
+			FAULT_ON_ERROR))
+			return -1;
+		set_access(acc, access);
 
-	if (!readmem(whitelist_addr + MEMBER_OFFSET("dev_whitelist_item", "type"),
-		KVADDR, &type, sizeof(short), "whitelist_item_type",
-		FAULT_ON_ERROR))
-		return -1;
-	fprintf(fp, "%s.list: %c %s:%s %s\n", group_list->subsys_str,
-		type_to_char(type), maj, min, acc);
+		if (!readmem(whitelist_addr + devices_offset_table.item_type,
+			KVADDR, &type, sizeof(short), "item_type",
+			FAULT_ON_ERROR))
+			return -1;
+		fprintf(fp, "%s.list: %c %s:%s %s\n", group_list->subsys_str,
+			type_to_char(type), maj, min, acc);
+	}
 
-	return ret;
+	return 0;
 }
 
 /*
@@ -2554,7 +2586,7 @@
 cmd_cgget(void)
 {
 	int c;
-	int ret = 0;
+	int ret = 0, help_flag = 0;
 	int idx, i = 0, j = 0, k = 0;
 	int dis_all_param = 0, group_flag = 0, var_flag = 0;
 	struct cgroup_spec *group_list[CGROUP_HIER_MAX] = {NULL};
@@ -2595,9 +2627,10 @@
 			dis_all_param = 1;
 			break;
 		case 'h':
+			help_flag = 1;
 		default:
 			argerrs++;
-			break;
+			goto err;
 		}
 	}
 
@@ -2647,8 +2680,11 @@
 		free(subsys_str[j]);
 	while (--k >= 0)
 		free(path[k]);
-	if (argerrs)
+	if (argerrs) {
+		if (!help_flag)
+			fprintf(stderr, "Invalid commandline specified.\n");
 		cmd_usage(pc->curcmd, SYNOPSIS);
+	}
 }
 
 /* strip off the same string */
@@ -2850,7 +2886,7 @@
 
 	for (i = 0; i < var_num[subsys_id]; i++) {
 		if (!test_bit(i, found))
-			fprintf(pc->saved_fp, "Can not find param '%s'.\n",
+			fprintf(pc->saved_fp, "Cannot find param '%s'.\n",
 				variable_str[subsys_id][i]);
 	}
 	if (linebuf) {
@@ -3032,7 +3068,7 @@
 	css_addr = get_css_addr(group_list, subsys_id, root_addr);
 	if (!css_addr) {
 		if (!disp_flag)
-			fprintf(fp, "%s: can not find controller '%s' "
+			fprintf(fp, "%s: Cannot find controller '%s' "
 				"in group '%s'\n", cmd_name,
 				group_list->subsys_str,
 				group_list->path);
@@ -3066,7 +3102,7 @@
 	else if (0 == strcmp(group_list->subsys_str, subsys_name[net_prio_subsys_id]))
 		print_net_prio(group_list, subsys_id, css_addr);
 	else
-		fprintf(fp, "not supported controller %s.\n",
+		fprintf(fp, "Not supported controller %s.\n",
 			group_list->subsys_str);
 
 }
@@ -3334,7 +3370,8 @@
 static void
 print_memory(struct cgroup_spec *group_list, int subsys_id, ulong subsys_addr)
 {
-	ulong mem_res_addr, mem_memsw_addr, ptr;
+	ulong mem_res_addr, mem_memsw_addr, mem_kmem_addr,
+	      mem_tmem_addr, ptr;
 	uint64_t val64 = 0, usage = 0, mem_limit, memsw_limit;
 	int i, j, val32 = 0, do_swap_account = 0;
 	int64_t lstats[NR_MCS_STAT] = {0}, tstats[NR_MCS_STAT] = {0};
@@ -3362,20 +3399,70 @@
 		return;
 	}
 
-	/* address of memsw and res */
+	/* address of memsw, res, kmem and tcp_mem */
 	if(memory_offset_table.memory_memsw != -1)
 		mem_memsw_addr = subsys_addr + memory_offset_table.memory_memsw;
 	else
 		mem_memsw_addr = -1;
+	if(memory_offset_table.memory_kmem != -1)
+		mem_kmem_addr = subsys_addr + memory_offset_table.memory_kmem;
+	else
+		mem_kmem_addr = -1;
+	if(memory_offset_table.memory_tcp_mem != -1)
+		mem_tmem_addr = subsys_addr + memory_offset_table.memory_tcp_mem +
+				MEMBER_OFFSET("tcp_memcontrol",
+					      "tcp_memory_allocated");
+	else
+		mem_tmem_addr = -1;
 	mem_res_addr = subsys_addr + memory_offset_table.memory_res;
 
-	for (i = MEM_MEMSW_FAILCNT; i < MEM_NR_PARAMS; i++) {
+	for (i = MEM_TMEM_FAILCNT; i < MEM_NR_PARAMS; i++) {
 		/* format string of the parameter */
 		memset(buf, 0, FILENAME_MAX);
 		sprintf(buf, "%s.%s", group_list->subsys_str,
 			memory_params[i]);
 		switch (i)
 		{
+		case MEM_TMEM_FAILCNT:
+			read_res_counter(mem_tmem_addr,
+					 memory_offset_table.counter_failcnt,
+					 buf);
+			break;
+		case MEM_TMEM_LIMIT:
+			read_res_counter(mem_tmem_addr,
+					 memory_offset_table.counter_limit,
+					 buf);
+			break;
+		case MEM_TMEM_MAX_USAGE:
+			read_res_counter(mem_tmem_addr,
+					 memory_offset_table.counter_max_usage,
+					 buf);
+			break;
+		case MEM_TMEM_USAGE:
+			read_res_counter(mem_tmem_addr,
+					 memory_offset_table.counter_usage,
+					 buf);
+			break;
+		case MEM_KMEM_FAILCNT:
+			read_res_counter(mem_kmem_addr,
+					 memory_offset_table.counter_failcnt,
+					 buf);
+			break;
+		case MEM_KMEM_LIMIT:
+			read_res_counter(mem_kmem_addr,
+					 memory_offset_table.counter_limit,
+					 buf);
+			break;
+		case MEM_KMEM_MAX_USAGE:
+			read_res_counter(mem_kmem_addr,
+					 memory_offset_table.counter_max_usage,
+					 buf);
+			break;
+		case MEM_KMEM_USAGE:
+			read_res_counter(mem_kmem_addr,
+					 memory_offset_table.counter_usage,
+					 buf);
+			break;
 		case MEM_MEMSW_FAILCNT:
 			read_res_counter(mem_memsw_addr,
 					 memory_offset_table.counter_failcnt,
@@ -3513,6 +3600,7 @@
 print_devices(struct cgroup_spec *group_list, int subsys_id, ulong subsys_addr)
 {
 	ulong whitelist_addr, list_head;
+	int behavior = -1;
 
 	fprintf(fp, "%s:\n", group_list->path);
 
@@ -3522,18 +3610,24 @@
 
 	list_head = subsys_addr + devices_offset_table.devices_whitelist;
 	whitelist_addr = (ulong)list_next((void *)list_head, NULL,
-				MEMBER_OFFSET("dev_whitelist_item", "list"));
+					  devices_offset_table.item_list);
+
+	if (devices_offset_table.devices_behavior != -1)
+		readmem(subsys_addr + devices_offset_table.devices_behavior,
+			KVADDR, &behavior, sizeof(int), "dev_cgroup behavior",
+			FAULT_ON_ERROR);
+
 	do {
-		if (0 != read_whitelist(group_list, whitelist_addr)) {
+		if (0 != read_whitelist(group_list, whitelist_addr, behavior)) {
 			fprintf(fp, "get parameters failed.\n");
-			return;
+			break;
 		}
 		fprintf(fp, "%s.deny: \n", group_list->subsys_str);
 		fprintf(fp, "%s.allow: \n", group_list->subsys_str);
 		whitelist_addr = (ulong)list_next(NULL, (void *)whitelist_addr,
-					MEMBER_OFFSET("dev_whitelist_item", "list"));
+					devices_offset_table.item_list);
 	} while (list_head != whitelist_addr +
-			MEMBER_OFFSET("dev_whitelist_item", "list"));
+			      devices_offset_table.item_list);
 
 	/* second, output the needed param */
 	if (test_bit(devices_subsys_id, variable_flag)) {
@@ -3613,6 +3707,9 @@
 
 	fprintf(fp, "%s:\n", group_list->path);
 
+	if (netprio_offset_table.netprio_prioidx == -1)
+		return;
+
 	/* if some param is specified, first output all into a tmpfile. */
 	if (test_bit(net_prio_subsys_id, variable_flag))
 		open_tmpfile();
@@ -3738,7 +3835,7 @@
 		}
 
 		if (!found && !disp_flag) {
-			fprintf(fp, "%s: can not find controller '%s' "
+			fprintf(fp, "%s: Cannot find controller '%s' "
 				"in group '%s'\n", cmd_name,
 				group_list[j]->subsys_str,
 				group_list[j]->path);
@@ -3872,12 +3969,15 @@
 {
 	CGGET_MEMBER_OFFSET_INIT(memory_offset_table, memory_res,
 				 "mem_cgroup", "res");
-	if (MEMBER_EXISTS("mem_cgroup", "tcp_mem"))
+	if (MEMBER_EXISTS("mem_cgroup", "swappiness"))
 		memory_offset_table.memory_memsw = memory_offset_table.memory_res +
 						   STRUCT_SIZE("res_counter");
 	else
-		CGGET_MEMBER_OFFSET_INIT(memory_offset_table, memory_memsw,
-					 "mem_cgroup", "memsw");
+		memory_offset_table.memory_memsw = -1;
+	CGGET_MEMBER_OFFSET_INIT(memory_offset_table, memory_tcp_mem,
+				 "mem_cgroup", "tcp_mem");
+	CGGET_MEMBER_OFFSET_INIT(memory_offset_table, memory_kmem,
+				 "mem_cgroup", "kmem");
 	CGGET_MEMBER_OFFSET_INIT(memory_offset_table, memory_info,
 				 "mem_cgroup", "info");
 	CGGET_MEMBER_OFFSET_INIT(memory_offset_table, memory_stat,
@@ -3908,7 +4008,7 @@
 				 "res_counter", "failcnt");
 	CGGET_MEMBER_OFFSET_INIT(memory_offset_table, perzone_count,
 				 "mem_cgroup_per_zone", "count");
-	if(memory_offset_table.perzone_count == -1)
+	if (memory_offset_table.perzone_count == -1)
 		CGGET_MEMBER_OFFSET_INIT(memory_offset_table, perzone_count,
 					 "mem_cgroup_per_zone", "lru_size");
 }
@@ -3916,8 +4016,37 @@
 static void
 devices_offset_table_init()
 {
-	CGGET_MEMBER_OFFSET_INIT(devices_offset_table, devices_whitelist,
-				 "dev_cgroup", "whitelist");
+	if (STRUCT_EXISTS("dev_whitelist_item")) {
+		CGGET_MEMBER_OFFSET_INIT(devices_offset_table, devices_whitelist,
+					 "dev_cgroup", "whitelist");
+		CGGET_MEMBER_OFFSET_INIT(devices_offset_table, devices_behavior,
+					 "dev_cgroup", "behavior");
+		CGGET_MEMBER_OFFSET_INIT(devices_offset_table, item_major,
+					 "dev_whitelist_item", "major");
+		CGGET_MEMBER_OFFSET_INIT(devices_offset_table, item_minor,
+					 "dev_whitelist_item", "minor");
+		CGGET_MEMBER_OFFSET_INIT(devices_offset_table, item_type,
+					 "dev_whitelist_item", "type");
+		CGGET_MEMBER_OFFSET_INIT(devices_offset_table, item_access,
+					 "dev_whitelist_item", "access");
+		CGGET_MEMBER_OFFSET_INIT(devices_offset_table, item_list,
+					 "dev_whitelist_item", "list");
+	} else if (STRUCT_EXISTS("dev_exception_item")) {
+		CGGET_MEMBER_OFFSET_INIT(devices_offset_table, devices_whitelist,
+					 "dev_cgroup", "exceptions");
+		CGGET_MEMBER_OFFSET_INIT(devices_offset_table, devices_behavior,
+					 "dev_cgroup", "behavior");
+		CGGET_MEMBER_OFFSET_INIT(devices_offset_table, item_major,
+					 "dev_exception_item", "major");
+		CGGET_MEMBER_OFFSET_INIT(devices_offset_table, item_minor,
+					 "dev_exception_item", "minor");
+		CGGET_MEMBER_OFFSET_INIT(devices_offset_table, item_type,
+					 "dev_exception_item", "type");
+		CGGET_MEMBER_OFFSET_INIT(devices_offset_table, item_access,
+					 "dev_exception_item", "access");
+		CGGET_MEMBER_OFFSET_INIT(devices_offset_table, item_list,
+					 "dev_exception_item", "list");
+	}
 }
 
 static void
