Re: [PATCH] add a new command: ipcs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Dave,

I did some effort to change the patch. Now it can support all of the three facilitis. I also check the kernel from 2.6.18 and up to find the bugs and fix it. So please refer to the attachment.

--
--
Regards
Qiao Nuohan
--------------------------------------------------
Qiao Nuohan
Development Dept.I
Nanjing Fujitsu Nanda Software Tech. Co., Ltd.(FNST)
No. 6 Wenzhu Road, Nanjing, Nanjing, 210012, China
TEL: +86+25-86630566-8526 FUJITSU
INTERNAL: 7998-8526 FAX: +86+25-83317685
EMail: qiaonuohan@xxxxxxxxxxxxxx
--------------------------------------------------
This communication is for use by the intended
recipient(s) only and may contain information that
is privileged, confidential and exempt from
disclosure under applicable law. If you are not an
intended recipient of this communication, you are
hereby notified that any dissemination,
distribution or copying hereof is strictly
prohibited. If you have received this communication
in error, please notify me by reply e-mail,
permanently delete this communication from your
system, and destroy any hard copies you may have
printed


>From 0265da31c97814dfd9c5efa66c0b83b35a06af24 Mon Sep 17 00:00:00 2001
From: qiaonuohan <qiaonuohan@xxxxxxxxxxxxxx>
Date: Fri, 6 Apr 2012 18:01:04 +0800
Subject: [PATCH] add ipcs command

---
 Makefile      |    7 +-
 defs.h        |   49 +++
 global_data.c |    1 +
 help.c        |   85 +++++
 ipcs.c        | 1051 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 symbols.c     |   93 +++++
 6 files changed, 1284 insertions(+), 2 deletions(-)
 create mode 100644 ipcs.c

diff --git a/Makefile b/Makefile
index 37378c2..b63a940 100644
--- a/Makefile
+++ b/Makefile
@@ -68,7 +68,7 @@ CFILES=main.c tools.c global_data.c memory.c filesys.c help.c task.c \
 	netdump.c diskdump.c makedumpfile.c xendump.c unwind.c unwind_decoder.c \
 	unwind_x86_32_64.c unwind_arm.c \
 	xen_hyper.c xen_hyper_command.c xen_hyper_global_data.c \
-	xen_hyper_dump_tables.c kvmdump.c qemu.c qemu-load.c sadump.c
+	xen_hyper_dump_tables.c kvmdump.c qemu.c qemu-load.c sadump.c ipcs.c
 
 SOURCE_FILES=${CFILES} ${GENERIC_HFILES} ${MCORE_HFILES} \
 	${REDHAT_CFILES} ${REDHAT_HFILES} ${UNWIND_HFILES} \
@@ -85,7 +85,7 @@ OBJECT_FILES=main.o tools.o global_data.o memory.o filesys.o help.o task.o \
 	lkcd_x86_trace.o unwind_v1.o unwind_v2.o unwind_v3.o \
 	unwind_x86_32_64.o unwind_arm.o \
 	xen_hyper.o xen_hyper_command.o xen_hyper_global_data.o \
-	xen_hyper_dump_tables.o kvmdump.o qemu.o qemu-load.o sadump.o
+	xen_hyper_dump_tables.o kvmdump.o qemu.o qemu-load.o sadump.o ipcs.o
 
 MEMORY_DRIVER_FILES=memory_driver/Makefile memory_driver/crash.c memory_driver/README
 
@@ -485,6 +485,9 @@ xen_hyper_global_data.o: ${GENERIC_HFILES} xen_hyper_global_data.c
 xen_hyper_dump_tables.o: ${GENERIC_HFILES} xen_hyper_dump_tables.c
 	cc -c ${CRASH_CFLAGS} xen_hyper_dump_tables.c ${WARNING_OPTIONS} ${WARNING_ERROR}
 
+ipcs.o: ${GENERIC_HFILES} ipcs.c
+	cc -c ${CRASH_CFLAGS} ipcs.c ${WARNING_OPTIONS} ${WARNING_ERROR}
+
 ${PROGRAM}: force
 	@make --no-print-directory all
 
diff --git a/defs.h b/defs.h
index 4089779..4fb6f0d 100755
--- a/defs.h
+++ b/defs.h
@@ -1682,6 +1682,48 @@ struct offset_table {                    /* stash of commonly-used offsets */
 	long mount_mnt;
 	long task_struct_exit_state;
 	long timekeeper_xtime;
+
+	long file_f_op;
+	long file_private_data;
+	long hstate_order;
+	long hugetlbfs_sb_info_hstate;
+	long idr_layer_ary;
+	long idr_layer_layer;
+	long idr_layers;
+	long idr_top;
+	long ipc_id_ary_p;
+	long ipc_ids_entries;
+	long ipc_ids_max_id;
+	long ipc_ids_ipcs_idr;
+	long ipc_ids_in_use;
+	long ipc_namespace_ids;
+	long ipc_namespace_shm_tot;
+	long ipc_namespace_used_sems;
+	long ipc_namespace_msg_hdrs;
+	long ipc_namespace_msg_bytes;
+	long kern_ipc_perm_deleted;
+	long kern_ipc_perm_key;
+	long kern_ipc_perm_mode;
+	long kern_ipc_perm_seq;
+	long kern_ipc_perm_uid;
+	long kern_ipc_perm_id;
+	long nsproxy_ipc_ns;
+	long shmem_inode_info_swapped;
+	long shmem_inode_info_vfs_inode;
+	long shm_file_data_file;
+	long shmid_kernel_shm_file;
+	long shmid_kernel_shm_nattch;
+	long shmid_kernel_shm_perm;
+	long shmid_kernel_shm_segsz;
+	long shmid_kernel_id;
+	long sem_array_sem_perm;
+	long sem_array_sem_id;
+	long sem_array_sem_nsems;
+	long msg_queue_q_perm;
+	long msg_queue_q_id;
+	long msg_queue_q_cbytes;
+	long msg_queue_q_qnum;
+	long super_block_s_fs_info;
 };
 
 struct size_table {         /* stash of commonly-used sizes */
@@ -1809,6 +1851,11 @@ struct size_table {         /* stash of commonly-used sizes */
 	long rq_in_flight;
 	long class_private_devices;
 	long mount;
+	long hstate;
+	long ipc_ids;
+	long shmid_kernel;
+	long sem_array;
+	long msg_queue;
 };
 
 struct array_table {
@@ -3660,6 +3707,7 @@ void cmd_dev(void);          /* dev.c */
 void cmd_gdb(void);          /* gdb_interface.c */
 void cmd_net(void);          /* net.c */
 void cmd_extend(void);       /* extensions.c */
+void cmd_ipcs(void);         /* ipcs.c */
 #if defined(S390) || defined(S390X)
 void cmd_s390dbf(void);
 #endif
@@ -4140,6 +4188,7 @@ extern char *help_vtop[];
 extern char *help_waitq[];
 extern char *help_whatis[];
 extern char *help_wr[];
+extern char *help_ipcs[];
 #if defined(S390) || defined(S390X)
 extern char *help_s390dbf[];
 #endif
diff --git a/global_data.c b/global_data.c
index 98a5a79..e697f8e 100755
--- a/global_data.c
+++ b/global_data.c
@@ -118,6 +118,7 @@ struct command_table_entry linux_command_table[] = {
 	{"waitq",   cmd_waitq,   help_waitq,   REFRESH_TASK_TABLE},
 	{"whatis",  cmd_whatis,  help_whatis,  0},
 	{"wr",      cmd_wr,      help_wr,      0},
+	{"ipcs",    cmd_ipcs,    help_ipcs,    REFRESH_TASK_TABLE},
 #if defined(S390) || defined(S390X)
         {"s390dbf", cmd_s390dbf, help_s390dbf, 0},
 #endif
diff --git a/help.c b/help.c
index e97c6b4..b8217e1 100755
--- a/help.c
+++ b/help.c
@@ -5566,6 +5566,91 @@ char *help_waitq[] = {
 NULL
 };
 
+char *help_ipcs[] = {
+"ipcs",
+"provide information on ipc facilities(shared memory)",                        
+" [[-u] [-smqM]] | [-i id [-smq]]",
+"  This command provides information on the ipc facilities. Without specified",
+"  one of -s -m -q, the command will show all of three facilities.",
+" ",
+"       -u  shows summary information",
+"       -s  shows semaphore arrays",
+"       -m  shows shared memory segments",
+"       -M  shows shared memory segments' other information"
+"       -q  shows message queue",
+"    -i id  it allows a specific resource id to be specified, and the",
+"           information on this id will be printed",
+"\nEXAMPLE",
+"  display all ipc facilities:\n",
+"    %s> ipcs",
+"    ------ Shared Memory Segments ------",
+"    KEY        SHMID      UID        PERMS      BYTES      NATTCH     STATUS       ",
+"    0x00000000 0          0          600        393216     2          dest         ",
+"    0x00000000 32769      0          600        393216     2          dest         ",
+"    0x00000000 65538      0          600        393216     2          dest         ",
+"    0x00000000 98307      0          600        393216     2          dest         ",
+"    0x00000000 131076     0          600        393216     2          dest         ",
+"    0x00000000 163845     0          600        393216     2          dest         ",
+"    0x00000000 196614     0          600        393216     2          dest         ",
+"    0x00000000 229383     0          600        393216     2          dest         ",
+"    0x00000000 262152     0          600        393216     2          dest         ",
+"    0x00000000 294921     0          600        393216     2          dest         ",
+"    0x00000000 327690     0          600        393216     2          dest         ",
+"    0x00000000 360459     0          600        393216     2          dest         ",
+"    0x00000000 393228     0          600        393216     2          dest         ",
+"    0x00000000 425997     0          600        393216     2          dest         ",
+"    0x00000000 458766     0          600        393216     2          dest         ",
+"    0x00000000 491535     0          600        393216     2          dest         ",
+"    0x00000000 524304     0          600        393216     2          dest         ",
+"    0x00000000 557073     0          600        393216     2          dest         ",
+"    0x00000000 589842     0          600        393216     2          dest         ",
+"    0x00000000 4423699    0          666        1024       0                       ",
+"    0x00000000 720916     0          600        393216     2          dest         ",
+"    0x00000000 753685     0          600        393216     2          dest         ",
+"    0x00000000 10747926   0          600        1152000    2          dest         ",
+"    0x00000001 4456471    0          666        1024       0                       ",
+"    0x00000002 4489240    0          666        1024       0                       ",
+"    0x00000003 4522009    0          666        1024       0                       ",
+"    0x00000004 4554778    0          666        1024       0                       ",
+"    ------ Semaphore Arrays --------",
+"    KEY        SEMID      UID        PERMS      NSEMS     ",
+"    0x00000000 0          0          600        1         ",
+"    0x00000000 32769      0          600        1         ",
+"    ------ Message Queues --------",
+"    KEY        MSQID      UID        PERMS      USED-BYTES   MESSAGES    ",
+"    (none allocated)",
+" ",
+"  display summary:\n",
+"    %s> ipcs -u",
+"    ------ Shared Memroy Status --------",
+"    segments allocated 27",
+"    pages allocatd 2303",
+"    pages resident 3612",
+"    pages swapped  969",
+"    swap performance attemts   0",
+"    swap performance successes 0",
+" ",
+"    ------ Semaphore Status --------",
+"    used arrays = 2",
+"    allocated semaphores = 2",
+" ",
+"    ------ Messages Status --------",
+"    allocated queues = 0",
+"    used headers = 0",
+"    used space = 0 bytes",
+" ",
+"  display a specified resource:\n",
+"    %s> ipcs -u -i 458766",
+"    SHMID: 458766",
+"    ------ Shared Memroy Status --------",
+"    segments allocated 27",
+"    pages allocatd 96",
+"    pages resident 26",
+"    pages swapped  22",
+"    swap performance attemts   0",
+"    swap performance successes 0",
+};
+
 
 /*
  *  Find out what the help request is looking for, accepting aliases as well,
diff --git a/ipcs.c b/ipcs.c
new file mode 100644
index 0000000..d0b6be2
--- /dev/null
+++ b/ipcs.c
@@ -0,0 +1,1051 @@
+/* ipcs.c - core analysis suite 
+ *
+ * Copyright (C) 2012 FUJITSU LIMITED
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "defs.h"
+
+#define IPCS_INIT 0x1
+#define MAX_ID_SHIFT (sizeof(int)*8 - 1)
+#define MAX_ID_BIT (1U << MAX_ID_SHIFT)
+#define MAX_ID_MASK (MAX_ID_BIT - 1)
+
+#define SHM_DEST   01000
+#define SHM_LOCKED 02000
+
+/*
+ * struct declaration
+ */
+struct shm_info {
+	ulong shm_kernel;
+	int key;
+	int shmid;
+	ulong rss;
+	ulong swap;
+	unsigned int uid;
+	unsigned int perms;
+	ulong bytes;
+	ulong nattch;
+	ulong shm_inode;
+	int deleted;
+};
+
+struct sem_info {
+	int key;
+	int semid;
+	unsigned int uid;
+	unsigned int perms;
+	ulong nsems;
+	int deleted;
+};
+
+struct msg_info {
+	int key;
+	int msgid;
+	unsigned int uid;
+	unsigned int perms;
+	ulong bytes;
+	ulong messages;
+	int deleted;
+};
+
+struct total_shm_info {
+	int used_ids;
+	ulong shm_tot;
+	ulong shm_rss;
+	ulong shm_swp;
+	ulong swap_attempts;
+	ulong swap_successes;
+};
+
+struct total_sem_info {
+	int semusz;
+	int semaem;
+};
+
+struct total_msg_info {
+	int msgpool;
+	int msgmap;
+	int msgtql;
+};
+
+struct ipcs_table {
+	int idr_bits;
+	ulong init_flags;
+	ulong hugetlbfs_f_op_addr;
+	ulong shm_f_op_addr;
+	ulong shm_f_op_huge_addr;
+	int use_shm_f_op;
+};
+
+/*
+ * function declaration
+ */
+static void dump_shared_memory(int, int, int);
+static void dump_semaphore_arrays(int, int);
+static void dump_message_queues(int, int);
+static void ipc_search_idr(ulong, int, int, int (*)(ulong, int));
+static void ipc_search_array(ulong, int, int, int (*)(ulong, int));
+static ulong idr_find(ulong, int);
+static int dump_single_shm(ulong, int);
+static int dump_single_shm_verbose(ulong, int);
+static int dump_specified_shm(ulong, int);
+static int dump_single_sem(ulong, int);
+static int dump_specified_sem(ulong, int);
+static int dump_single_msg(ulong, int);
+static int dump_specified_msg(ulong, int);
+static void get_shm_info(struct shm_info *, ulong);
+static void get_sem_info(struct sem_info *, ulong);
+static void get_msg_info(struct msg_info *, ulong);
+static void add_rss_swap(ulong, int, ulong *, ulong *);
+static int is_file_hugepages(ulong);
+static void display_shm_summary(void);
+static void display_sem_summary(void);
+static void display_msg_summary(void);
+
+/*
+ * global data
+ */
+static struct total_shm_info total_shm_info = { 0 };
+static struct total_sem_info total_sem_info = { 0 };
+static struct total_msg_info total_msg_info = { 0 };
+static struct ipcs_table ipcs_table = { 0 };
+
+static void
+ipcs_init(void)
+{
+	if (ipcs_table.init_flags & IPCS_INIT) {
+		return;
+	}
+
+	ipcs_table.init_flags |= IPCS_INIT;
+
+	MEMBER_OFFSET_INIT(nsproxy_ipc_ns, "nsproxy", "ipc_ns");
+	MEMBER_OFFSET_INIT(ipc_namespace_ids, "ipc_namespace", "ids");
+	MEMBER_OFFSET_INIT(ipc_namespace_shm_tot, "ipc_namespace", "shm_tot");
+	MEMBER_OFFSET_INIT(ipc_namespace_used_sems, "ipc_namespace", "used_sems");
+	MEMBER_OFFSET_INIT(ipc_namespace_msg_hdrs, "ipc_namespace", "msg_hdrs");
+	MEMBER_OFFSET_INIT(ipc_namespace_msg_bytes, "ipc_namespace", "msg_bytes");
+	MEMBER_OFFSET_INIT(ipc_ids_entries, "ipc_ids", "entries");
+	MEMBER_OFFSET_INIT(ipc_ids_max_id, "ipc_ids", "max_id");
+	MEMBER_OFFSET_INIT(ipc_ids_in_use, "ipc_ids", "in_use");
+	MEMBER_OFFSET_INIT(ipc_ids_ipcs_idr, "ipc_ids", "ipcs_idr");
+	MEMBER_OFFSET_INIT(ipc_id_ary_p, "ipc_id_ary", "p");
+	MEMBER_OFFSET_INIT(idr_top, "idr", "top");
+	MEMBER_OFFSET_INIT(idr_layers, "idr", "layers");
+	MEMBER_OFFSET_INIT(idr_layer_layer, "idr_layer", "layer");
+	MEMBER_OFFSET_INIT(idr_layer_ary, "idr_layer", "ary");
+	MEMBER_OFFSET_INIT(shmid_kernel_shm_perm, "shmid_kernel", "shm_perm");
+	MEMBER_OFFSET_INIT(shmid_kernel_shm_segsz, "shmid_kernel", "shm_segsz");
+	MEMBER_OFFSET_INIT(shmid_kernel_shm_nattch, "shmid_kernel", "shm_nattch");
+	MEMBER_OFFSET_INIT(shmid_kernel_shm_file, "shmid_kernel", "shm_file");
+	MEMBER_OFFSET_INIT(shmid_kernel_id, "shmid_kernel", "id");
+	MEMBER_OFFSET_INIT(sem_array_sem_perm, "sem_array", "sem_perm");
+	MEMBER_OFFSET_INIT(sem_array_sem_id, "sem_array", "sem_id");
+	MEMBER_OFFSET_INIT(sem_array_sem_nsems, "sem_array", "sem_nsems");
+	MEMBER_OFFSET_INIT(msg_queue_q_perm, "msg_queue", "q_perm");
+	MEMBER_OFFSET_INIT(msg_queue_q_cbytes, "msg_queue", "q_cbytes");
+	MEMBER_OFFSET_INIT(msg_queue_q_qnum, "msg_queue", "q_qnum");
+	MEMBER_OFFSET_INIT(kern_ipc_perm_key, "kern_ipc_perm", "key");
+	MEMBER_OFFSET_INIT(kern_ipc_perm_id, "kern_ipc_perm", "id");
+	MEMBER_OFFSET_INIT(kern_ipc_perm_uid, "kern_ipc_perm", "uid");
+	MEMBER_OFFSET_INIT(kern_ipc_perm_mode, "kern_ipc_perm", "mode");
+	MEMBER_OFFSET_INIT(kern_ipc_perm_deleted, "kern_ipc_perm", "deleted");
+	MEMBER_OFFSET_INIT(file_f_op, "file", "f_op");
+	MEMBER_OFFSET_INIT(file_private_data, "file", "private_data");
+	MEMBER_OFFSET_INIT(shm_file_data_file, "shm_file_data", "file");
+	MEMBER_OFFSET_INIT(super_block_s_fs_info, "super_block", "s_fs_info");
+	MEMBER_OFFSET_INIT(hstate_order, "hstate", "order");
+	MEMBER_OFFSET_INIT(shmem_inode_info_vfs_inode, "shmem_inode_info", "vfs_inode");
+	MEMBER_OFFSET_INIT(shmem_inode_info_swapped, "shmem_inode_info", "swapped");
+
+	/*
+	 * struct size
+	 */
+	STRUCT_SIZE_INIT(ipc_ids, "ipc_ids");
+	STRUCT_SIZE_INIT(shmid_kernel, "shmid_kernel");
+	STRUCT_SIZE_INIT(sem_array, "sem_array");
+	STRUCT_SIZE_INIT(msg_queue, "msg_queue");
+	STRUCT_SIZE_INIT(hstate, "hstate");
+
+	ipcs_table.hugetlbfs_f_op_addr =
+		symbol_value("hugetlbfs_file_operations");
+	if (symbol_exists("is_file_shm_hugepages")) {
+		ipcs_table.use_shm_f_op = TRUE;
+		ipcs_table.shm_f_op_addr =
+			symbol_value("shm_file_operations");
+		if (symbol_exists("shm_file_operations_huge")) {
+			ipcs_table.shm_f_op_huge_addr =
+				symbol_value("shm_file_operations_huge");
+		} else {
+			ipcs_table.shm_f_op_huge_addr = -1;
+		}
+	} else {
+		ipcs_table.use_shm_f_op = FALSE;
+		ipcs_table.shm_f_op_addr = -1;
+		ipcs_table.shm_f_op_huge_addr = -1;
+	}
+
+	if (BITS32())
+		ipcs_table.idr_bits = 5;
+	else if (BITS64())
+		ipcs_table.idr_bits = 6;
+	else
+		error(FATAL, "machdep->bits is not 32 or 64");
+}
+
+void
+cmd_ipcs(void)
+{
+	int show_summary, specified_id;
+	int id;
+	int c;
+	int shm, sem, msg;
+	int shm_v;
+
+	id = 0;
+	show_summary = 0;
+	specified_id = 0;
+	shm = 0;
+	sem = 0;
+	msg = 0;
+	shm_v = 0;
+	
+	while ((c = getopt(argcnt, args, "ui:smqM")) != EOF) {
+		switch(c) {
+			case 'u':
+				show_summary = 1;
+				break;
+			case 'i':
+				id = dtoi(optarg, FAULT_ON_ERROR, NULL);
+				specified_id = 1;
+				break;
+			case 's':
+				sem = 1;
+				break;
+			case 'm':
+				shm = 1;
+				break;
+			case 'q':
+				msg = 1;
+				break;
+			case 'M':
+				shm = 1;
+				shm_v = 1;
+				break;
+			default:
+				cmd_usage(pc->curcmd, SYNOPSIS);;
+				return;
+		}
+	}
+
+	if (specified_id && (shm + sem + msg) != 1) {
+		error(INFO, "specified one of -s -m -q together with -i option\n");
+		cmd_usage(pc->curcmd, SYNOPSIS);
+	}
+
+	ipcs_init();
+
+	if (!shm && !sem && !msg)
+		shm = sem = msg = 1;
+
+	if (show_summary && !specified_id)
+		open_tmpfile();
+
+	if (shm)
+		dump_shared_memory(specified_id, id, shm_v);
+	if (sem)
+		dump_semaphore_arrays(specified_id, id);
+	if (msg)
+		dump_message_queues(specified_id, id);
+
+	if (show_summary && !specified_id) {
+		close_tmpfile();
+		if (shm)
+			display_shm_summary();
+		if (sem)
+			display_sem_summary();
+		if (msg)
+			display_msg_summary();
+	}
+}
+
+static void
+dump_shared_memory(int specified_id, int id, int shm_v)
+{
+	ulong cur_task = CURRENT_TASK();
+	ulong nsproxy_p, ipc_ns_p;
+	ulong ipc_ids_p;
+	void (*ipc_search)(ulong, int, int, int (*)(ulong, int));
+	int (*dump_shm)(ulong, int);
+	char buf0[BUFSIZE];
+	char buf1[BUFSIZE];
+	char buf2[BUFSIZE];
+	char buf3[BUFSIZE];
+	char buf4[BUFSIZE];
+	char buf5[BUFSIZE];
+	char buf6[BUFSIZE];
+
+	if (!specified_id) {
+		fprintf(fp, "------ Shared Memory Segments ------\n");
+
+		if (shm_v) {
+			fprintf(fp, "%s %s %s %s %s\n",
+				mkstring(buf0, VADDR_PRLEN <= 10 ? 10 : VADDR_PRLEN,
+					LJUST, "SHM_KERNEL"),
+				mkstring(buf1, 10, LJUST, "SHMID"),
+				mkstring(buf2, 10, LJUST, "RSS"),
+				mkstring(buf3, 10, LJUST, "SWAP"),
+				mkstring(buf4, VADDR_PRLEN <= 10 ? 10 : VADDR_PRLEN,
+					LJUST, "SHM_INODE"));
+			dump_shm = dump_single_shm_verbose;
+		}
+		else {
+			fprintf(fp, "%s %s %s %s %s %s %s\n",
+				mkstring(buf0, 10, LJUST, "KEY"),
+				mkstring(buf1, 10, LJUST, "SHMID"),
+				mkstring(buf2, 10, LJUST, "UID"),
+				mkstring(buf3, 10, LJUST, "PERMS"),
+				mkstring(buf4, 10, LJUST, "BYTES"),
+				mkstring(buf5, 10, LJUST, "NATTCH"),
+				mkstring(buf6, 12, LJUST, "STATUS"));
+			dump_shm = dump_single_shm;
+		}
+	} else
+		dump_shm = dump_specified_shm;
+
+	if (VALID_MEMBER(kern_ipc_perm_id)) {
+		ipc_search = ipc_search_idr;
+	} else {
+		ipc_search = ipc_search_array;
+	}
+
+	if (symbol_exists("shm_ids")) {
+		ipc_ids_p = symbol_value("shm_ids");
+		int shm_tot;
+		readmem(symbol_value("shm_tot"), KVADDR, &shm_tot, sizeof(int),
+			"shm_tot", FAULT_ON_ERROR);
+		total_shm_info.shm_tot = shm_tot;
+	} else {
+		readmem(cur_task + OFFSET(task_struct_nsproxy), KVADDR,
+			&nsproxy_p, sizeof(ulong), "task_struct.nsproxy",
+			FAULT_ON_ERROR);
+		readmem(nsproxy_p + OFFSET(nsproxy_ipc_ns), KVADDR, &ipc_ns_p,
+			sizeof(ulong), "nsproxy.ipc_ns", FAULT_ON_ERROR);
+		int shm_tot;
+		readmem(ipc_ns_p + OFFSET(ipc_namespace_shm_tot), KVADDR,
+			&shm_tot, sizeof(int),
+			"ipc_namespace.shm_tot", FAULT_ON_ERROR);
+		total_shm_info.shm_tot = shm_tot;
+
+		if (MEMBER_SIZE("ipc_namespace","ids") == sizeof(ulong) * 3)
+			readmem(ipc_ns_p + OFFSET(ipc_namespace_ids) +
+				sizeof(ulong) * 2, KVADDR, &ipc_ids_p,
+				sizeof(ulong), "ipc_namespace.ids[2]",
+				FAULT_ON_ERROR);
+		else
+			ipc_ids_p = ipc_ns_p + OFFSET(ipc_namespace_ids) +
+				2 * SIZE(ipc_ids);
+	}
+
+	int in_use;
+	readmem(ipc_ids_p + OFFSET(ipc_ids_in_use), KVADDR, &in_use,
+		sizeof(int), "ipc_ids.in_use", FAULT_ON_ERROR);
+	total_shm_info.used_ids = in_use;
+
+	ipc_search(ipc_ids_p, specified_id, id, dump_shm);
+}
+
+static void
+dump_semaphore_arrays(int specified_id, int id)
+{
+	ulong cur_task = CURRENT_TASK();
+	ulong nsproxy_p, ipc_ns_p;
+	ulong ipc_ids_p;
+	void (*ipc_search)(ulong, int, int, int (*)(ulong, int));
+	int (*dump_sem)(ulong, int);
+	char buf0[BUFSIZE];
+	char buf1[BUFSIZE];
+	char buf2[BUFSIZE];
+	char buf3[BUFSIZE];
+	char buf4[BUFSIZE];
+
+	if(!specified_id) {
+		fprintf(fp, "------ Semaphore Arrays --------\n");
+		fprintf(fp, "%s %s %s %s %s\n",
+			mkstring(buf0, 10, LJUST, "KEY"),
+			mkstring(buf1, 10, LJUST, "SEMID"),
+			mkstring(buf2, 10, LJUST, "UID"),
+			mkstring(buf3, 10, LJUST, "PERMS"),
+			mkstring(buf4, 10, LJUST, "NSEMS"));
+		dump_sem = dump_single_sem;;
+	} else
+		dump_sem = dump_specified_sem;
+	
+	if (VALID_MEMBER(kern_ipc_perm_id)) {
+		ipc_search = ipc_search_idr;
+	} else {
+		ipc_search = ipc_search_array;
+	}
+
+	if (symbol_exists("sem_ids")) {
+		ipc_ids_p = symbol_value("sem_ids");
+		int semaem;
+		readmem(symbol_value("used_sems"), KVADDR, &semaem, sizeof(int),
+			"used_sems", FAULT_ON_ERROR);
+		total_sem_info.semaem = semaem;
+	} else {
+		readmem(cur_task + OFFSET(task_struct_nsproxy), KVADDR,
+			&nsproxy_p, sizeof(ulong), "task_struct.nsproxy",
+			FAULT_ON_ERROR);
+		
+		readmem(nsproxy_p + OFFSET(nsproxy_ipc_ns), KVADDR, &ipc_ns_p,
+			sizeof(ulong), "nsproxy.ipc_ns", FAULT_ON_ERROR);
+
+		int semaem;
+		readmem(ipc_ns_p + OFFSET(ipc_namespace_used_sems), KVADDR,
+			&semaem, sizeof(int), "ipc_namespace.used_sems",
+			FAULT_ON_ERROR);
+		total_sem_info.semaem = semaem;
+
+		if (MEMBER_SIZE("ipc_namespace","ids") == sizeof(ulong) * 3)
+			readmem(ipc_ns_p + OFFSET(ipc_namespace_ids), KVADDR,
+				&ipc_ids_p, sizeof(ulong),
+				"ipc_namespace.ids[2]",	FAULT_ON_ERROR);
+		else
+			ipc_ids_p = ipc_ns_p + OFFSET(ipc_namespace_ids);
+	}
+
+	int semusz;
+	readmem(ipc_ids_p + OFFSET(ipc_ids_in_use), KVADDR, &semusz,
+			sizeof(int), "ipc_ids.in_use", FAULT_ON_ERROR);
+	total_sem_info.semusz = semusz;
+
+	ipc_search(ipc_ids_p, specified_id, id, dump_sem);
+}
+
+static void
+dump_message_queues(int specified_id, int id)
+{
+	ulong cur_task = CURRENT_TASK();
+	ulong nsproxy_p, ipc_ns_p;
+	ulong ipc_ids_p;
+	void (*ipc_search)(ulong, int, int, int (*)(ulong, int));
+	int (*dump_msg)(ulong, int);
+	char buf0[BUFSIZE];
+	char buf1[BUFSIZE];
+	char buf2[BUFSIZE];
+	char buf3[BUFSIZE];
+	char buf4[BUFSIZE];
+	char buf5[BUFSIZE];
+
+	if(!specified_id) {
+		fprintf(fp, "------ Message Queues --------\n");
+		fprintf(fp, "%s %s %s %s %s %s\n",
+			mkstring(buf0, 10, LJUST, "KEY"),
+			mkstring(buf1, 10, LJUST, "MSQID"),
+			mkstring(buf2, 10, LJUST, "UID"),
+			mkstring(buf3, 10, LJUST, "PERMS"),
+			mkstring(buf4, 12, LJUST, "USED-BYTES"),
+			mkstring(buf5, 12, LJUST, "MESSAGES"));
+		dump_msg = dump_single_msg;
+	} else
+		dump_msg = dump_specified_msg;
+	
+	if (VALID_MEMBER(kern_ipc_perm_id)) {
+		ipc_search = ipc_search_idr;
+	} else {
+		ipc_search = ipc_search_array;
+	}
+
+	if (symbol_exists("msg_ids")) {
+		ipc_ids_p = symbol_value("msg_ids");
+	} else {
+		readmem(cur_task + OFFSET(task_struct_nsproxy), KVADDR,
+			&nsproxy_p, sizeof(ulong), "task_struct.nsproxy",
+			FAULT_ON_ERROR);
+		readmem(nsproxy_p + OFFSET(nsproxy_ipc_ns), KVADDR, &ipc_ns_p,
+			sizeof(ulong), "nsproxy.ipc_ns", FAULT_ON_ERROR);
+
+		if (MEMBER_SIZE("ipc_namespace","ids") == sizeof(ulong) * 3)
+			readmem(ipc_ns_p + OFFSET(ipc_namespace_ids) +
+				sizeof(ulong), KVADDR, &ipc_ids_p,
+				sizeof(ulong), "ipc_namespace.ids[2]",
+				FAULT_ON_ERROR);
+		else
+			ipc_ids_p = ipc_ns_p + OFFSET(ipc_namespace_ids) +
+				SIZE(ipc_ids);
+	}
+
+	int msgmap;
+	int msgtql;
+
+	if (VALID_MEMBER(ipc_namespace_msg_hdrs)) {
+		readmem(ipc_ns_p + OFFSET(ipc_namespace_msg_hdrs), KVADDR,
+			&msgmap, sizeof(int), "ipc_namespace.msg_hdrs",
+			FAULT_ON_ERROR);
+		readmem(ipc_ns_p + OFFSET(ipc_namespace_msg_bytes), KVADDR,
+			&msgtql, sizeof(int), "ipc_namespace.msg_bytes",
+			FAULT_ON_ERROR);
+	} else {
+		readmem(symbol_value("msg_hdrs"), KVADDR, &msgmap, sizeof(int),
+			"msg_hdrs", FAULT_ON_ERROR);
+		readmem(symbol_value("msg_bytes"), KVADDR, &msgtql, sizeof(int),
+			"msg_bytes", FAULT_ON_ERROR);
+	}
+
+	total_msg_info.msgmap = msgmap;
+	total_msg_info.msgtql = msgtql;
+
+	int msgpool;
+	readmem(ipc_ids_p + OFFSET(ipc_ids_in_use), KVADDR, &msgpool,
+		sizeof(int), "ipc_ids.in_use", FAULT_ON_ERROR);
+	total_msg_info.msgpool = msgpool;
+
+	ipc_search(ipc_ids_p, specified_id, id, dump_msg);
+}
+
+/*
+ * if shared memory information is stored in an array, use this function.
+ */
+static void
+ipc_search_array(ulong ipc_ids_p, int specified_id, int id, int (*fn)(ulong, int))
+{
+	ulong entries_p;
+	int max_id, i;
+	ulong *array;
+	int found = 0;
+
+	readmem(ipc_ids_p + OFFSET(ipc_ids_entries), KVADDR, &entries_p,
+		sizeof(ulong), "ipc_ids.entries", FAULT_ON_ERROR);
+	readmem(ipc_ids_p + OFFSET(ipc_ids_max_id), KVADDR, &max_id,
+		sizeof(int), "ipc_ids.max_id", FAULT_ON_ERROR);
+
+	if (!specified_id && max_id < 0) {
+		fprintf(fp, "(none allocated)");
+		return;
+	}
+
+	array = (ulong *)GETBUF(sizeof(ulong *) * (max_id + 1));
+	readmem(entries_p + OFFSET(ipc_id_ary_p), KVADDR, array,
+		sizeof(ulong *) * (max_id + 1), "ipc_id_ary.p", FAULT_ON_ERROR);
+
+	for (i=0; i<=max_id; i++) {
+		if (array[i] == 0)
+			continue;
+		if (fn(array[i], id)) {
+			found = 1;
+			break;
+		}
+	}
+
+	if (specified_id && !found)
+		fprintf(fp, "(none found)\n");
+
+	FREEBUF(array);
+}
+
+/*
+ * if shared memory information is stored by using idr, use this function to
+ * get data.
+ */
+static void
+ipc_search_idr(ulong ipc_ids_p, int specified_id, int id, int (*fn)(ulong, int))
+{
+	int in_use;
+	ulong ipcs_idr_p;
+	ulong ipc;
+	int next_id, total;
+	int found = 0;
+
+	readmem(ipc_ids_p + OFFSET(ipc_ids_in_use), KVADDR, &in_use, 
+		sizeof(int), "ipc_ids.in_use", FAULT_ON_ERROR);
+
+	ipcs_idr_p = ipc_ids_p + OFFSET(ipc_ids_ipcs_idr);
+
+	if (!specified_id && !in_use)
+		fprintf(fp, "(none allocated)\n");
+
+	for (total = 0, next_id = 0; total < in_use; next_id++) {
+		ipc = idr_find(ipcs_idr_p, next_id);
+		if (ipc == 0)
+			continue;
+		
+		total++;
+		if (fn(ipc, id)) {
+			found = 1;
+			break;
+		}
+	}
+	
+	if (specified_id && !found)
+		fprintf(fp, "(none found)\n");
+}
+
+/*
+ * search every idr_layer
+ */
+static ulong
+idr_find(ulong idp, int id)
+{
+	ulong idr_layer_p;
+	int layer;
+	int idr_layers;
+	int n;
+	int index;
+
+	readmem(idp + OFFSET(idr_top), KVADDR, &idr_layer_p, sizeof(ulong),
+		"idr.top", FAULT_ON_ERROR);
+
+	if (!idr_layer_p)
+		return 0;
+
+	if (VALID_MEMBER(idr_layer_layer)) {
+		readmem(idr_layer_p + OFFSET(idr_layer_layer), KVADDR, &layer,
+			sizeof(int), "idr_layer.layer", FAULT_ON_ERROR);
+		n = (layer + 1) * ipcs_table.idr_bits;
+	} else {
+		readmem(idp + OFFSET(idr_layers), KVADDR, &idr_layers,
+			sizeof(int), "idr.layers", FAULT_ON_ERROR);
+		n = idr_layers * ipcs_table.idr_bits;
+	}
+	id &= MAX_ID_MASK;
+
+	if (id >= (1 << n))
+		return 0;
+
+	while (n > 0 && idr_layer_p) {
+		n -= ipcs_table.idr_bits;
+		index = (id >> n) & ((1 << ipcs_table.idr_bits) - 1);
+		readmem(idr_layer_p + OFFSET(idr_layer_ary) +
+			sizeof(ulong) * index, KVADDR, &idr_layer_p,
+			sizeof(ulong), "idr_layer.ary", FAULT_ON_ERROR);
+	}
+	
+	return idr_layer_p;
+}
+
+static int
+dump_single_shm(ulong shp, int id)
+{
+	struct shm_info shm_info;
+
+	get_shm_info(&shm_info, shp);
+	
+	if (shm_info.deleted)
+		return 0;
+
+	fprintf(fp, "0x%08x %-10d %-10d %-10o %-10ld %-10ld %-6s %-6s\n",
+		shm_info.key,
+		shm_info.shmid,
+		shm_info.uid,
+		shm_info.perms & 0777,
+		shm_info.bytes,
+		shm_info.nattch,
+		shm_info.perms & SHM_DEST ? "dest" : " ",
+		shm_info.perms & SHM_LOCKED ? "locked" : " ");
+
+	return 0;
+}
+
+static int
+dump_single_shm_verbose(ulong shp, int id)
+{
+	struct shm_info shm_info;
+	char buf0[BUFSIZE];
+	char buf1[BUFSIZE];
+
+	get_shm_info(&shm_info, shp);
+
+	if (shm_info.deleted)
+		return 0;
+
+	fprintf(fp, "%s %-10d %-10ld %-10ld %s\n",
+		mkstring(buf0, VADDR_PRLEN <= 10 ? 10 : VADDR_PRLEN,
+			LJUST|LONG_HEX,	(char *)shm_info.shm_kernel),
+		shm_info.shmid,
+		shm_info.rss,
+		shm_info.swap,
+		mkstring(buf1, VADDR_PRLEN <= 10 ? 10 : VADDR_PRLEN,
+			LJUST|LONG_HEX,	(char *)shm_info.shm_inode));
+
+	return 0;
+}
+
+/*
+ * if the resource is specified, use this function to output information
+ */
+static int
+dump_specified_shm(ulong shp, int id)
+{
+	struct shm_info shm_info;
+
+	get_shm_info(&shm_info, shp);
+
+	if(shm_info.shmid == id) {
+		fprintf(fp, "SHMID: %d\n", shm_info.shmid);
+		fprintf(fp, "------ Shared Memroy Status --------\n");
+		fprintf(fp, "segments allocated %d\n", total_shm_info.used_ids);
+		fprintf(fp, "pages allocatd %ld\n",
+			(shm_info.bytes + PAGESIZE() - 1) >> PAGESHIFT());
+		fprintf(fp, "pages resident %ld\n", shm_info.rss);
+		fprintf(fp, "pages swapped  %ld\n", shm_info.swap);
+		fprintf(fp, "swap performance attemts   %ld\n",
+			total_shm_info.swap_attempts);
+		fprintf(fp, "swap performance successes %ld\n",
+			total_shm_info.swap_successes);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int
+dump_single_sem(ulong shp, int id)
+{
+	struct sem_info sem_info;
+
+	get_sem_info(&sem_info, shp);
+
+	if (sem_info.deleted)
+		return 0;
+
+	fprintf(fp, "0x%08x %-10d %-10d %-10o %-10ld\n",
+		sem_info.key,
+		sem_info.semid,
+		sem_info.uid,
+		sem_info.perms & 0777,
+		sem_info.nsems);
+
+	return 0;
+}
+
+static int
+dump_specified_sem(ulong shp, int id)
+{
+	struct sem_info sem_info;
+
+	get_sem_info(&sem_info, shp);
+
+	if (sem_info.semid == id) {
+		fprintf(fp, "SEMID: %d\n", sem_info.semid);
+		fprintf(fp ,"------ Semaphore Status --------\n");
+		fprintf(fp, "used arrays          %d\n", total_sem_info.semusz);
+		fprintf(fp, "allocated semaphores %ld\n", sem_info.nsems);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int
+dump_single_msg(ulong shp, int id)
+{
+	struct msg_info msg_info;
+
+	get_msg_info(&msg_info, shp);
+
+	if (msg_info.deleted)
+		return 0;
+
+	fprintf(fp, "0x%08x %-10d %-10d %-10o %-12ld %-12ld\n",
+		msg_info.key,
+		msg_info.msgid,
+		msg_info.uid,
+		msg_info.perms & 0777,
+		msg_info.bytes,
+		msg_info.messages);
+
+	return 0;
+}
+
+static int
+dump_specified_msg(ulong shp, int id)
+{
+	struct msg_info msg_info;
+
+	get_msg_info(&msg_info, shp);
+
+	if (msg_info.msgid == id) {
+		fprintf(fp, "MSGID: %d\n", msg_info.msgid);
+		fprintf(fp ,"------ Message Status --------\n");
+		fprintf(fp, "allocated queues %d\n", total_msg_info.msgpool);
+		fprintf(fp, "used headers     %ld\n", msg_info.messages);
+		fprintf(fp, "used space       %ld\n", msg_info.bytes);
+		return 1;
+	}
+
+	return 0;
+}
+
+static void
+get_shm_info(struct shm_info *shm_info, ulong shp)
+{
+	char buf[BUFSIZE];
+	ulong filep, dentryp, inodep;
+
+	shm_info->shm_kernel = shp - OFFSET(shmid_kernel_shm_perm);
+
+	//cache shmid_kernel
+	readmem(shm_info->shm_kernel, KVADDR, buf, SIZE(shmid_kernel),
+		"shmid_kernel", FAULT_ON_ERROR);
+
+	shm_info->key = INT(buf + OFFSET(shmid_kernel_shm_perm) +
+			OFFSET(kern_ipc_perm_key));
+	if (VALID_MEMBER(shmid_kernel_id))
+		shm_info->shmid = INT(buf + OFFSET(shmid_kernel_id));
+	else
+		shm_info->shmid = INT(buf + OFFSET(shmid_kernel_shm_perm) +
+				OFFSET(kern_ipc_perm_id));
+
+	shm_info->uid = UINT(buf + OFFSET(shmid_kernel_shm_perm) +
+			OFFSET(kern_ipc_perm_uid));
+
+	if (BITS32())
+		shm_info->perms = USHORT(buf + OFFSET(shmid_kernel_shm_perm) +
+				OFFSET(kern_ipc_perm_mode));
+	else
+		shm_info->perms = UINT(buf + OFFSET(shmid_kernel_shm_perm) +
+				OFFSET(kern_ipc_perm_mode));
+
+	shm_info->bytes = ULONG(buf + OFFSET(shmid_kernel_shm_segsz));
+
+	shm_info->nattch = ULONG(buf + OFFSET(shmid_kernel_shm_nattch));
+
+	filep = ULONG(buf + OFFSET(shmid_kernel_shm_file));
+	readmem(filep + OFFSET(file_f_dentry), KVADDR, &dentryp, sizeof(ulong),
+		"file.f_dentry", FAULT_ON_ERROR);
+	readmem(dentryp + OFFSET(dentry_d_inode), KVADDR, &inodep,
+		sizeof(ulong), "dentry.d_inode", FAULT_ON_ERROR);
+	// shm_inode here is the vfs_inode of struct shmem_inode_info
+	shm_info->shm_inode = inodep;
+
+	shm_info->rss = 0;
+	shm_info->swap = 0;
+
+	add_rss_swap(inodep, is_file_hugepages(filep), &shm_info->rss,
+                 &shm_info->swap);
+
+	shm_info->deleted = UINT(buf + OFFSET(shmid_kernel_shm_perm) +
+				OFFSET(kern_ipc_perm_deleted));
+}
+
+static void
+get_sem_info(struct sem_info *sem_info, ulong shp)
+{
+	ulong sem_array_p;
+	char buf[BUFSIZE];
+	
+	sem_array_p = shp - OFFSET(sem_array_sem_perm);
+
+	//cache sem_array
+	readmem(sem_array_p, KVADDR, buf, SIZE(sem_array), "sem_array",
+		FAULT_ON_ERROR);
+
+	sem_info->key = INT(buf + OFFSET(sem_array_sem_perm) +
+			OFFSET(kern_ipc_perm_key));
+
+	if (VALID_MEMBER(sem_array_sem_id))
+		sem_info->semid = INT(buf + OFFSET(sem_array_sem_id));
+	else
+		sem_info->semid = INT(buf + OFFSET(sem_array_sem_perm) +
+				OFFSET(kern_ipc_perm_id));
+
+	sem_info->uid = UINT(buf + OFFSET(sem_array_sem_perm) +
+			OFFSET(kern_ipc_perm_uid));
+
+	if (BITS32())
+		sem_info->perms = USHORT(buf + OFFSET(sem_array_sem_perm) +
+				OFFSET(kern_ipc_perm_mode));
+	else
+		sem_info->perms = UINT(buf + OFFSET(sem_array_sem_perm) +
+				OFFSET(kern_ipc_perm_mode));
+
+	sem_info->nsems = ULONG(buf + OFFSET(sem_array_sem_nsems));
+
+	sem_info->deleted = UINT(buf + OFFSET(sem_array_sem_perm) +
+				OFFSET(kern_ipc_perm_deleted));
+}
+
+static void
+get_msg_info(struct msg_info *msg_info, ulong shp)
+{
+	ulong msg_queue_p;
+	char buf[BUFSIZE];
+
+	msg_queue_p = shp - OFFSET(msg_queue_q_perm);
+
+	//cache msg_queue;
+	readmem(msg_queue_p, KVADDR, buf, SIZE(msg_queue), "msg_queue",
+		FAULT_ON_ERROR);
+
+	msg_info->key = INT(buf + OFFSET(msg_queue_q_perm) +
+			OFFSET(kern_ipc_perm_key));
+
+	if (VALID_MEMBER(msg_queue_q_id))
+		msg_info->msgid = INT(buf + OFFSET(msg_queue_q_id));
+	else
+		msg_info->msgid = INT(buf + OFFSET(msg_queue_q_perm) +
+				OFFSET(kern_ipc_perm_id));
+
+	msg_info->uid = UINT(buf + OFFSET(msg_queue_q_perm) +
+			OFFSET(kern_ipc_perm_uid));
+
+	if (BITS32())
+		msg_info->perms = USHORT(buf + OFFSET(msg_queue_q_perm) +
+				OFFSET(kern_ipc_perm_mode));
+	else
+		msg_info->perms = UINT(buf + OFFSET(msg_queue_q_perm) +
+				OFFSET(kern_ipc_perm_mode));
+
+	msg_info->bytes = ULONG(buf + OFFSET(msg_queue_q_cbytes));
+
+	msg_info->messages = ULONG(buf + OFFSET(msg_queue_q_qnum));
+	
+	msg_info->deleted = UINT(buf + OFFSET(msg_queue_q_perm) +
+				OFFSET(kern_ipc_perm_deleted));
+}
+
+/*
+ * get rss & swap related to every shared memory, and get the total number of rss
+ * & swap
+ */
+static void
+add_rss_swap(ulong inode_p, int hugepage, ulong *rss, ulong *swap)
+{
+	unsigned long mapping_p, nr_pages;
+
+	readmem(inode_p + OFFSET(inode_i_mapping), KVADDR, &mapping_p,
+		sizeof(ulong), "inode.i_mapping", FAULT_ON_ERROR);
+	readmem(mapping_p + OFFSET(address_space_nrpages), KVADDR, &nr_pages,
+		sizeof(ulong), "address_space.nrpages", FAULT_ON_ERROR);
+
+	if (hugepage) {
+		unsigned long pages_per_hugepage;
+		if (VALID_SIZE(hstate)) {
+			unsigned long i_sb_p, hsb_p, hstate_p;
+			unsigned int order;
+
+			readmem(inode_p + OFFSET(inode_i_sb), KVADDR, &i_sb_p,
+				sizeof(ulong), "inode.i_sb", FAULT_ON_ERROR);
+			readmem(i_sb_p + OFFSET(super_block_s_fs_info), KVADDR,
+				&hsb_p, sizeof(ulong), "super_block.s_fs_info",
+				FAULT_ON_ERROR);
+			readmem(hsb_p + OFFSET(hugetlbfs_sb_info_hstate),
+				KVADDR,	&hstate_p, sizeof(ulong),
+				"hugetlbfs_sb_info.hstate", FAULT_ON_ERROR);
+			readmem(hstate_p + OFFSET(hstate_order), KVADDR, &order,
+				sizeof(uint), "hstate.order", FAULT_ON_ERROR);
+			pages_per_hugepage = 1 << order;
+		} else {
+			unsigned long hpage_shift;
+			/*
+			 * HPAGE_SHIFT is 21 after commit 83a5101b(kernel > 2.6.24)
+			 */
+			if (THIS_KERNEL_VERSION > LINUX(2, 6, 24)) {
+				hpage_shift = 21;
+			} else {
+				/*
+				 * HPAGE_SHIFT:
+				 *   x86(PAE): 21
+				 *   x86(no PAE): 22
+				 *   x86_64: 21
+				 */
+				if ((machine_type("X86") &&
+					!(machdep->flags & PAE)))
+					hpage_shift = 22;
+				else
+					hpage_shift = 21;
+			}
+			pages_per_hugepage = (1 << hpage_shift) / PAGESIZE();
+		}
+		*rss += pages_per_hugepage * nr_pages;
+		total_shm_info.shm_rss += *rss;
+	} else {
+		unsigned long swapped;
+
+		*rss += nr_pages;
+		total_shm_info.shm_rss += *rss;
+		readmem(inode_p - OFFSET(shmem_inode_info_vfs_inode) +
+			OFFSET(shmem_inode_info_swapped), KVADDR, &swapped,
+			sizeof(ulong), "shmem_inode_info.swapped",
+			FAULT_ON_ERROR);
+		*swap += swapped;
+		total_shm_info.shm_swp += *swap;
+    }
+}
+
+static int
+is_file_hugepages(ulong file_p)
+{
+	unsigned long f_op, sfd_p;
+
+again:
+	readmem(file_p + OFFSET(file_f_op), KVADDR, &f_op, sizeof(ulong),
+		"file.f_op", FAULT_ON_ERROR);
+	if (f_op == ipcs_table.hugetlbfs_f_op_addr)
+		return 1;
+
+	if (ipcs_table.use_shm_f_op) {
+		if (ipcs_table.shm_f_op_huge_addr != -1) {
+			if (f_op == ipcs_table.shm_f_op_huge_addr)
+				return 1;
+		} else {
+			if (f_op == ipcs_table.shm_f_op_addr) {
+				readmem(file_p + OFFSET(file_private_data),
+					KVADDR,	&sfd_p, sizeof(ulong),
+					"file.private_data", FAULT_ON_ERROR);
+				readmem(sfd_p + OFFSET(shm_file_data_file),
+					KVADDR,	&file_p, sizeof(ulong),
+					"shm_file_data.file", FAULT_ON_ERROR);
+				goto again;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static void
+display_shm_summary()
+{
+	fprintf(fp, "------ Shared Memroy Status --------\n");
+	fprintf(fp, "segments allocated %d\n", total_shm_info.used_ids);
+	fprintf(fp, "pages allocatd %ld\n", total_shm_info.shm_tot);
+	fprintf(fp, "pages resident %ld\n", total_shm_info.shm_rss);
+	fprintf(fp, "pages swapped  %ld\n", total_shm_info.shm_swp);
+	fprintf(fp, "swap performance attemts   %ld\n",
+			total_shm_info.swap_attempts);
+	fprintf(fp, "swap performance successes %ld\n",
+			total_shm_info.swap_successes);
+	fprintf(fp ,"\n");
+}
+
+static void
+display_sem_summary()
+{
+	fprintf(fp, "------ Semaphore Status --------\n");
+	fprintf(fp, "used arrays = %d\n", total_sem_info.semusz);
+	fprintf(fp, "allocated semaphores = %d\n", total_sem_info.semaem);
+	fprintf(fp, "\n");
+}
+
+static void
+display_msg_summary()
+{
+	fprintf(fp, "------ Messages Status --------\n");
+	fprintf(fp, "allocated queues = %d\n", total_msg_info.msgpool);
+	fprintf(fp, "used headers = %d\n", total_msg_info.msgmap);
+	fprintf(fp, "used space = %d bytes", total_msg_info.msgtql);
+	fprintf(fp, "\n");
+}
diff --git a/symbols.c b/symbols.c
index 69a54f6..0dac66b 100755
--- a/symbols.c
+++ b/symbols.c
@@ -8684,6 +8684,89 @@ dump_offset_table(char *spec, ulong makestruct)
 	fprintf(fp, "                subsystem_kset: %ld\n",
 		OFFSET(subsystem_kset));
 
+	fprintf(fp, "                     file_f_op: %ld\n",
+		OFFSET(file_f_op));
+	fprintf(fp, "             file_private_data: %ld\n",
+		OFFSET(file_private_data));
+	fprintf(fp, "                  hstate_order: %ld\n",
+		OFFSET(hstate_order));
+	fprintf(fp, "      hugetlbfs_sb_info_hstate: %ld\n",
+		OFFSET(hugetlbfs_sb_info_hstate));
+	fprintf(fp, "                 idr_layer_ary: %ld\n",
+		OFFSET(idr_layer_ary));
+	fprintf(fp, "               idr_layer_layer: %ld\n",
+		OFFSET(idr_layer_layer));
+	fprintf(fp, "                    idr_layers: %ld\n",
+		OFFSET(idr_layers));
+	fprintf(fp, "                       idr_top: %ld\n",
+		OFFSET(idr_top));
+	fprintf(fp, "                  ipc_id_ary_p: %ld\n",
+		OFFSET(ipc_id_ary_p));
+	fprintf(fp, "               ipc_ids_entries: %ld\n",
+		OFFSET(ipc_ids_entries));
+	fprintf(fp, "                ipc_ids_max_id: %ld\n",
+		OFFSET(ipc_ids_max_id));
+	fprintf(fp, "              ipc_ids_ipcs_idr: %ld\n",
+		OFFSET(ipc_ids_ipcs_idr));
+	fprintf(fp, "                ipc_ids_in_use: %ld\n",
+		OFFSET(ipc_ids_in_use));
+	fprintf(fp, "             ipc_namespace_ids: %ld\n",
+		OFFSET(ipc_namespace_ids));
+	fprintf(fp, "         ipc_namespace_shm_tot: %ld\n",
+		OFFSET(ipc_namespace_shm_tot));
+	fprintf(fp, "       ipc_namespace_used_sems: %ld\n",
+		OFFSET(ipc_namespace_used_sems));
+	fprintf(fp, "        ipc_namespace_msg_hdrs: %ld\n",
+		OFFSET(ipc_namespace_msg_hdrs));
+	fprintf(fp, "       ipc_namespace_msg_bytes: %ld\n",
+		OFFSET(ipc_namespace_msg_bytes));
+	fprintf(fp, "         kern_ipc_perm_deleted: %ld\n",
+		OFFSET(kern_ipc_perm_deleted));
+	fprintf(fp, "             kern_ipc_perm_key: %ld\n",
+		OFFSET(kern_ipc_perm_key));
+	fprintf(fp, "            kern_ipc_perm_mode: %ld\n",
+		OFFSET(kern_ipc_perm_mode));
+	fprintf(fp, "             kern_ipc_perm_seq: %ld\n",
+		OFFSET(kern_ipc_perm_seq));
+	fprintf(fp, "             kern_ipc_perm_uid: %ld\n",
+		OFFSET(kern_ipc_perm_uid));
+	fprintf(fp, "              kern_ipc_perm_id: %ld\n",
+		OFFSET(kern_ipc_perm_id));
+	fprintf(fp, "                nsproxy_ipc_ns: %ld\n",
+		OFFSET(nsproxy_ipc_ns));
+	fprintf(fp, "      shmem_inode_info_swapped: %ld\n",
+		OFFSET(shmem_inode_info_swapped));
+	fprintf(fp, "    shmem_inode_info_vfs_inode: %ld\n",
+		OFFSET(shmem_inode_info_vfs_inode));
+	fprintf(fp, "            shm_file_data_file: %ld\n",
+		OFFSET(shm_file_data_file));
+	fprintf(fp, "         shmid_kernel_shm_file: %ld\n",
+		OFFSET(shmid_kernel_shm_file));
+	fprintf(fp, "       shmid_kernel_shm_nattch: %ld\n",
+		OFFSET(shmid_kernel_shm_nattch));
+	fprintf(fp, "         shmid_kernel_shm_perm: %ld\n",
+		OFFSET(shmid_kernel_shm_perm));
+	fprintf(fp, "        shmid_kernel_shm_segsz: %ld\n",
+		OFFSET(shmid_kernel_shm_segsz));
+	fprintf(fp, "               shmid_kernel_id: %ld\n",
+		OFFSET(shmid_kernel_id));
+	fprintf(fp, "            sem_array_sem_perm: %ld\n",
+		OFFSET(sem_array_sem_perm));
+	fprintf(fp, "              sem_array_sem_id: %ld\n",
+		OFFSET(sem_array_sem_id));
+	fprintf(fp, "           sem_array_sem_nsems: %ld\n",
+		OFFSET(sem_array_sem_nsems));
+	fprintf(fp, "              msg_queue_q_perm: %ld\n",
+		OFFSET(msg_queue_q_perm));
+	fprintf(fp, "                msg_queue_q_id: %ld\n",
+		OFFSET(msg_queue_q_id));
+	fprintf(fp, "            msg_queue_q_cbytes: %ld\n",
+		OFFSET(msg_queue_q_cbytes));
+	fprintf(fp, "              msg_queue_q_qnum: %ld\n",
+		OFFSET(msg_queue_q_qnum));
+	fprintf(fp, "         super_block_s_fs_info: %ld\n",
+		OFFSET(super_block_s_fs_info));
+
 	fprintf(fp, "\n                    size_table:\n");
 	fprintf(fp, "                          page: %ld\n", SIZE(page));
 	fprintf(fp, "                    page_flags: %ld\n", SIZE(page_flags));
@@ -8884,6 +8967,16 @@ dump_offset_table(char *spec, ulong makestruct)
 		SIZE(rq_in_flight));
 	fprintf(fp, "         class_private_devices: %ld\n",
 		SIZE(class_private_devices));
+	fprintf(fp, "                        hstate: %ld\n",
+		SIZE(hstate));
+	fprintf(fp, "                       ipc_ids: %ld\n",
+		SIZE(ipc_ids));
+	fprintf(fp, "                  shmid_kernel: %ld\n",
+		SIZE(shmid_kernel));
+	fprintf(fp, "                     sem_array: %ld\n",
+		SIZE(sem_array));
+	fprintf(fp, "                     msg_queue: %ld\n",
+		SIZE(msg_queue));
 
         fprintf(fp, "\n                   array_table:\n");
 	/*
-- 
1.7.1

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/crash-utility

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux