Dave Anderson | 27 May 17:22 2015
Picon

[ANNOUNCE] crash version 7.1.1 is available


Download from: http://people.redhat.com/anderson
                 or
               https://github.com/crash-utility/crash/releases

The master branch serves as a development branch that will contain all 
patches that are queued for the next release:

  $ git clone git://github.com/crash-utility/crash.git

Changelog:

  - Fix for two minor issues with the "net" command.  Without the patch,
   the "net -a" option appends its correct output with the command's 
   "Usage:" message; and if either the "net -x" or "net -d" options are
   used without also specifying "-s" or "-S", the error message would
   indicate "net: illegal flag: 800000" or "net: illegal flag: 1000000"
   instead of showing the command's "Usage:" message.
   (anderson <at> redhat.com)

 - If the kernel (live or dumpfile) has the TAINT_LIVEPATCH bit set, or
   if the Red Hat "kpatch" module is installed, the tag "[LIVEPATCH]" 
   will be displayed next to the kernel name in the initial system 
   banner and by the "sys" command.  This new tag replaces the 
   "[KPATCH]" tag that was introduced in crash-7.0.7.
   (anderson <at> redhat.com)

 - Addressed three Coverity Scan complaints in vmware_vmss.c:
     50:leaked_storage: Variable "fp" going out of scope leaks the 
        storage it points to.
(Continue reading)

Derek Cheng | 20 May 19:51 2015
Picon

right shift of the subtraction result


Hi Dave,

Does this sound like a bug, it need right shift of the subtraction result,

crash-git> pd (678324157984276 >> 32)
$10 = 157934
crash-git> pd ((681670518181331-678324157984276) >> 32)
p: gdb request failed: p ((681670518181331-678324157984276)
crash-git> 


It might be lacking support of some advanced arithmetic, so what is a proper way
to do some arithmetic like this?
<div><div>
<div class=""><br></div>
<div class="">Hi Dave,</div>
<div class=""><br></div>
<div class="">Does this sound like a bug, it need right shift of the subtraction result,</div>
<div class=""><br></div>
<div class="">crash-git&gt; pd (678324157984276 &gt;&gt; 32)</div>
<div class="">$10 = 157934</div>
<div class="">crash-git&gt; pd ((681670518181331-678324157984276) &gt;&gt; 32)</div>
<div class="">p: gdb request failed: p ((681670518181331-678324157984276)</div>
<div class="">crash-git&gt;&nbsp;</div>
<div dir="ltr" class=""><br class=""></div>
<div dir="ltr" class=""><br></div>
<div dir="ltr" class="">It might be lacking support of some advanced arithmetic, so what is a proper way</div>
<div dir="ltr" class="">to do some arithmetic like this?</div>
</div></div>
Michael Holzheu | 20 May 18:28 2015
Picon

New crash release for kernels >= 4.0?

Hello Dave,

At least on s390 the latest crash version 7.1 does not work with kernels >= 4.0:

 WARNING: kernels compiled by different gcc versions:
   /boot/vmlinux: (unknown)
   vmcore kernel: 4.9.2

 WARNING: kernel version inconsistency between vmlinux and dumpfile

 crash: incompatible arguments:  /boot/vmlinux is not SMP -- vmcore is SMP

The git master branch seems to have a patch that solves this problem.

IMO it would be good to have a new crash release with that fix.
What do you think?

Michael

Rabin Vincent | 13 May 22:16 2015
Picon

[PATCH] MIPS: support getting regs from kdump dumpfiles

Add support for using the notes in MIPS' kdump compressed format
dumpfiles.
---
 diskdump.c |   19 +++++++++++++++----
 mips.c     |    4 ++++
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/diskdump.c b/diskdump.c
index 585aaa9..90f3bff 100644
--- a/diskdump.c
+++ b/diskdump.c
 <at>  <at>  -1285,14 +1285,11  <at>  <at>  extern void get_netdump_regs_x86(struct bt_info *, ulong *, ulong *);
 extern void get_netdump_regs_x86_64(struct bt_info *, ulong *, ulong *);

 static void
-get_diskdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp)
+get_diskdump_regs_32(struct bt_info *bt, ulong *eip, ulong *esp)
 {
 	Elf32_Nhdr *note;
 	int len;

-	if (KDUMP_CMPRS_VALID())
-		ppc_relocate_nt_prstatus_percpu(dd->nt_prstatus_percpu,
-						&dd->num_prstatus_notes);
 	if (KDUMP_CMPRS_VALID() &&
 		(bt->task == tt->panic_task || 
 		(is_task_active(bt->task) && dd->num_prstatus_notes > 1))) {
 <at>  <at>  -1313,6 +1310,16  <at>  <at>  get_diskdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp)
 }

 static void
+get_diskdump_regs_ppc(struct bt_info *bt, ulong *eip, ulong *esp)
+{
+	if (KDUMP_CMPRS_VALID())
+		ppc_relocate_nt_prstatus_percpu(dd->nt_prstatus_percpu,
+						&dd->num_prstatus_notes);
+
+	get_diskdump_regs_32(bt, eip, esp);
+}
+
+static void
 get_diskdump_regs_ppc64(struct bt_info *bt, ulong *eip, ulong *esp)
 {
 	if ((bt->task == tt->panic_task) && DISKDUMP_VALID())
 <at>  <at>  -1346,6 +1353,10  <at>  <at>  get_diskdump_regs(struct bt_info *bt, ulong *eip, ulong *esp)
 		get_diskdump_regs_arm(bt, eip, esp);
 		break;

+	case EM_MIPS:
+		return get_diskdump_regs_32(bt, eip, esp);
+		break;
+
 	case EM_386:
 		return get_netdump_regs_x86(bt, eip, esp);
 		break;
diff --git a/mips.c b/mips.c
index 77077fb..4b62d1e 100644
--- a/mips.c
+++ b/mips.c
 <at>  <at>  -833,6 +833,10  <at>  <at>  mips_init(int when)
 #endif

 	switch (when) {
+	case SETUP_ENV:
+		machdep->process_elf_notes = process_elf32_notes;
+		break;
+
 	case PRE_SYMTAB:
 		machdep->verify_symbol = mips_verify_symbol;
 		machdep->machspec = &mips_machine_specific;
--

-- 
1.7.10.4

Dave Anderson | 12 May 21:22 2015
Picon

Re: [PATCH v2] kmem: Introduce -m option


Aaron Tomlin and I have been collaborating offline/in-house with respect
to this patch, and we've finally come up with an implementation that is
queued for crash-7.1.1:

  https://github.com/crash-utility/crash/commit/a8e7fc1e580122fac032c80f789026dfe3f1fc4d

  - Implemented a new "kmem -m" option that is similar to "kmem -p",
    but it allows the user to specify the page struct members to be
    displayed.  The option takes a comma-separated list of one or
    more page struct members, which will be displayed following the
    page structure address.  The "flags" member will always be expressed
    in hexadecimal format, and the "_count" and "_mapcount" members will
    always be expressed in decimal format.  Otherwise, all other members
    will be displayed in hexadecimal format unless the current output
    radix is 10 and the member is a signed/unsigned integer.  Members
    that are data structures may be specified by the data structure's
    member name, or expanded to specify a member of that data structure.
    For example, "-m lru" refers to a list_head data structure, in which
    case both the list_head.next and list_head.prev pointer values will
    be displayed; if "-m lru.next" is specified, just the list_head.next
    value will be displayed.
    (atomlin <at> redhat.com, anderson <at> redhat.com)

Alexandr Terekhov | 11 May 15:13 2015

[PATCH 1/1] Resend CLI list command, print deep structure members

Hello Dave,

here is the second reincarnation of the parser. I've updated
`task` and `struct` handlers along with the `list` handler:

crash> list task_struct.tasks -s task_struct.comm,pid,thread.cr2 -H 0xde83a1e0
de840aa0
  comm = "ksoftirqd/0\000\000\000\000"
  pid = 4
  thread.cr2 = 0,
de840550
  comm = "stopper/0\000\000\000\000\000\000"
  pid = 5
  thread.cr2 = 0,
..................

crash> task -R restart_block.fn,restart_block.futex,thread.tls_array[0].base1,cpu_timers[2].next
  restart_block.fn = 0xc046fe10 <do_no_restart_syscall>,
  restart_block.futex = {
    uaddr = 0x0,
    val = 0,
    flags = 0,
    bitset = 0,
    time = 0,
    uaddr2 = 0x0
  },
  thread.tls_array[0].base1 = 112,
  cpu_timers[2].next = 0xdb9a7838,

crash> task_struct.comm,thread.tls_array[0].dpl 0xdb9a7550
  comm = "bash\000\000\000\000\000\000\000\000\000\000\000"
  thread.tls_array[0].dpl = 3,

I'm looking forward to your comments/suggestions.

Best regards,
Alexandr

--- crash-7.1.0.orig/symbols.c	2015-02-06 21:44:11.000000000 +0300
+++ crash-7.1.0/symbols.c	2015-05-11 16:11:56.587128595 +0300
 <at>  <at>  -93,6 +93,7  <at>  <at>  static int dereference_pointer(ulong, st
 #define PARSE_FOR_DATA        (1)
 #define PARSE_FOR_DECLARATION (2)
 static void parse_for_member(struct datatype_member *, ulong);
+void parse_for_member_new(struct datatype_member *, ulong);
 static int show_member_offset(FILE *, struct datatype_member *, char *);

 
 <at>  <at>  -5576,17 +5577,18  <at>  <at>  dump_struct_member(char *s, ulong addr,
 		FREEBUF(buf);
                 error(FATAL, "invalid structure name: %s\n", dm->name);
 	}
-	if (!MEMBER_EXISTS(dm->name, dm->member)) {
-		FREEBUF(buf);
-                error(FATAL, "invalid structure member name: %s\n", 
-			dm->member);
-	}

 	set_temporary_radix(radix, &restore_radix);

         open_tmpfile();
         print_struct(dm->name, addr);
-        parse_for_member(dm, PARSE_FOR_DATA);
+
+	if (MEMBER_EXISTS(dm->name, dm->member)) {
+		parse_for_member(dm, PARSE_FOR_DATA);
+	} else {
+		parse_for_member_new(dm, PARSE_FOR_DATA);
+        }
+
         close_tmpfile();

 	restore_current_radix(restore_radix);
 <at>  <at>  -6026,8 +6028,7  <at>  <at>  cmd_datatype_common(ulong flags)
         if ((count_chars(args[optind], ',')+1) > MAXARGS)
                 error(FATAL, "too many members in comma-separated list!\n");

-	if ((count_chars(args[optind], '.') > 1) ||
-	    (LASTCHAR(args[optind]) == ',') ||
+	if ((LASTCHAR(args[optind]) == ',') ||
 	    (LASTCHAR(args[optind]) == '.'))
 		error(FATAL, "invalid format: %s\n", args[optind]);

 <at>  <at>  -6219,6 +6220,10  <at>  <at>  do_datatype_addr(struct datatype_member
 		i = 0;
         	do {
                 	if (argc_members) {
+                                /* This call works fine with fields
+                                 * of the second, third, ... levels.
+                                 * There is no need to fix it
+                                 */
 				if (!member_to_datatype(memberlist[i], dm,
 							ANON_MEMBER_QUERY))
 					error(FATAL, "invalid data structure reference: %s.%s\n",
 <at>  <at>  -6250,7 +6255,12  <at>  <at>  do_datatype_addr(struct datatype_member
 				if (dm->member) {
 					if (!((flags & DEREF_POINTERS) &&
 				    	    dereference_pointer(addr, dm, flags)))
-						parse_for_member(dm, PARSE_FOR_DATA);
+                                        {
+                                                if (count_chars(dm->member, '.'))
+                                                    parse_for_member_new(dm, PARSE_FOR_DATA);
+                                                else
+                                                    parse_for_member(dm, PARSE_FOR_DATA);
+                                        }
 					close_tmpfile();
 				}

 <at>  <at>  -6275,6 +6285,10  <at>  <at>  do_datatype_declaration(struct datatype_
 	if (CRASHDEBUG(1))
 		dump_datatype_member(fp, dm);

+        if (dm->member && count_chars(dm->member, '.'))
+            error(FATAL, "invalid data structure reference: %s.%s\n",
+                    dm->name, dm->member);
+
         open_tmpfile();
         whatis_datatype(dm->name, flags, pc->tmpfile);
         rewind(pc->tmpfile);
 <at>  <at>  -7383,6 +7397,270  <at>  <at>  next_item:
 	}
 }

+struct struct_elem {
+    char field_name[BUFSIZE];
+    unsigned char field_len;
+    char value[BUFSIZE];
+    unsigned char is_array_root:1;
+
+    struct struct_elem *parent;
+    struct struct_elem *inner;
+    struct struct_elem *next;
+    struct struct_elem *prev;
+};
+
+#define ALLOC_XXX_ELEMENT(xxx, clone_parent) \
+{ \
+    if (NULL == current) { \
+        error(FATAL, "Internal error while parsing structure %s\n", dm->name); \
+    } \
+    current->xxx = calloc(1, sizeof(struct struct_elem)); \
+    if (clone_parent) current->xxx->parent = current->parent; \
+    else current->xxx->parent = current; \
+    current = current->xxx; \
+}
+
+#define ALLOC_INNER_ELEMENT { ALLOC_XXX_ELEMENT(inner, 0) }
+#define ALLOC_NEXT_ELEMENT { ALLOC_XXX_ELEMENT(next, 1) }
+
+void free_structure(struct struct_elem *p) {
+    if (p == NULL)
+        return;
+    free_structure(p->inner);
+    free_structure(p->next);
+    free(p);
+}
+
+unsigned char is_right_brace(const char *b) {
+    unsigned char r = 0;
+    for (; *b == ' '; b++);
+    if (*b == '}') {
+        b++;
+        r = 1;
+        if (*b == '}') {
+            r = 2;
+            b++;
+        }
+    }
+
+    if (*b == ',')
+        b++;
+
+    if (*b == '\0')
+        return r;
+    else
+        return 0;
+}
+
+struct struct_elem *find_node(struct struct_elem *s, char *n) {
+    char *p, *b, *e;
+    struct struct_elem *t = s;
+    unsigned i;
+
+    if (('\0' == *n) || (NULL == s))
+        return s;
+
+    /* [n .. p) - struct member with index*/
+    if (NULL == (p = strstr(n, ".")))
+        p = n + strlen(n);
+
+    /* [n .. b) - struct member without index*/
+    for (b = n; (b < p) && (*b != '['); b++);
+
+    /* s - is the current level of items [s, s->next, ..., s->...->next] */
+    for (; s; s = s->next) {
+        if (*s->field_name == '\0')
+            continue;
+
+        /* `field_name` doesn't match */
+        if (((b - n) != s->field_len) || memcmp(s->field_name, n, b - n))
+            continue;
+
+        if (*b == '[') { /* Array */
+            i = strtol(b + 1, &e, 10);
+            /* Check if the current node is array and
+             * we've parsed index more or less correctly
+             */
+            if (!(s->is_array_root && *e == ']'&& (e != b + 1)))
+                return NULL;
+
+            /* Look for the i-th element */
+            for (s = s->inner; s && i; s = s->next, i--);
+            if (i || (NULL == s))
+                return NULL;
+        }
+        
+        /* Ok. We've found node, it's - the last member
+         * in our search string, let's return it.
+         */
+        if ('\0' == *p)
+            return s;
+        else
+            return find_node(s->inner, p + 1);
+    }
+
+    // We haven't found any field.
+    // Might happen, we've encountered anonymous structure
+    // of union. Lets try every record without `field_name`
+    s = t;
+    t = NULL;
+    for(; s; s = s->next) {
+        if (*s->field_name)
+            continue;
+        t = find_node(s->inner, n);
+        if (t)
+            break;
+    }
+
+    return t;
+}
+
+void dump_node(struct struct_elem *p, char *f, unsigned char level, unsigned char is_array) {
+    unsigned int i;
+    if (p == NULL)
+        return;
+    do {
+#define PUT_INDENTED_STRING(m, ...) { \
+        for (i = 0; i++ < 2 + 2 * (m * is_array + level); printf(" ")); \
+        printf(__VA_ARGS__); }
+
+        if (p->inner) {
+            if (*p->field_name) {
+                PUT_INDENTED_STRING(1, "%s = %s\n", f ? f : p->field_name, p->inner->is_array_root ? "{{" : "{");
+            } else {
+                if (f) /* For union */
+                    PUT_INDENTED_STRING(1, "%s = ", f);
+                PUT_INDENTED_STRING(1, "%s\n", p->inner->is_array_root ? "{{" : "{");
+            }
+            dump_node(p->inner, NULL, is_array + level + 1, p->inner->is_array_root);
+            PUT_INDENTED_STRING(1, "%s%s\n", p->inner->is_array_root ? "}}" : "}", (p->next &&
!p->next->is_array_root) ? "," : "");
+        } else {
+            PUT_INDENTED_STRING(1, "%s = %s%s", f ? f : p->field_name, p->value, p->next ? ",\n" : "\n");
+        }
+        if (level) {
+            p = p->next;
+            if (p && p->is_array_root)
+                PUT_INDENTED_STRING(0, "}, {\n");
+        }
+    } while (p && level);
+}
+
+void parse_for_member_new(struct datatype_member *dm,
+				ulong __attribute__ ((unused)) flag)
+{
+    struct struct_elem *i, *current = NULL, *root = NULL;
+
+    char buf[BUFSIZE];
+    char *p, *p1;
+    char *s_e; // structure_element
+    unsigned int len;
+    unsigned char trailing_comma, braces, found = 0;
+
+    rewind(pc->tmpfile);
+
+    root = calloc(1, sizeof(struct struct_elem));
+    current = root;
+    ALLOC_INNER_ELEMENT;
+
+    while (fgets(buf, BUFSIZE, pc->tmpfile)) {
+        len = strlen(buf) - 1;
+        for (; buf[len] <= ' '; buf[len--] = '\0');
+        if ((trailing_comma = (buf[len] == ',')))
+            buf[len--] = '\0';
+
+        if ((braces = is_right_brace(buf))) {
+            for (; braces && current; braces--)
+                current = current->parent;
+
+            if ((current->parent == root) || trailing_comma)
+                ALLOC_NEXT_ELEMENT;
+            continue;
+        }
+
+        for (p1 = buf; *p1 == ' '; p1++);
+        
+        if (NULL != (p = strstr(buf, " = "))) {
+            s_e = p + 3;
+        } else {
+            s_e = p1;
+        }
+
+        /*
+         * After that we have pointers:
+         *      foobar = bazzz
+         * -----^     ^  ^
+         * |    ------|  |
+         * |    |        |
+         * p1   p        s_e
+         *
+         * OR
+         *
+         *      {
+         *      ^
+         *      |
+         *  ---------
+         *  |       |
+         *  p1      s_e
+         *      
+         *      p == NULL
+         *
+         *
+         * p1   - the first non-whitespace symbol in line
+         * p    - pointer to line ' = '. If not NULL, there is identifier
+         * s_e  - element of structure (brace / double brace / array separator / scalar :))
+         *
+         */
+
+        if (current && p) strncpy(current->field_name, p1, p - p1);
+        current->field_len = p - p1;
+
+        if ( p && (*s_e != '{' || (*s_e == '{' && buf[len] == '}') )) {
+            /* Scalar or one-line array
+             * next = 0x0 
+             *   or 
+             * files = {0x0, 0x0}
+             */
+            strcpy(current->value, s_e);
+            if (trailing_comma) ALLOC_NEXT_ELEMENT;
+        }
+        else
+        if ( *s_e == '{' ) {
+            ALLOC_INNER_ELEMENT;
+            if (*(s_e + 1) == '{') {
+                current->parent->is_array_root = 1;
+                ALLOC_INNER_ELEMENT;
+            }
+        }
+        else
+        if (strstr(s_e, "}, {")) {
+            /* Next array element */
+            current = current->parent;
+            ALLOC_NEXT_ELEMENT;
+            ALLOC_INNER_ELEMENT;
+        }
+        else 
+        if (buf == (p = strstr(buf, "struct "))) {
+            p += 7; /* strlen "struct " */
+            p1 = strstr(buf, " {");
+            strncpy(current->field_name, p, p1 - p);
+            ALLOC_INNER_ELEMENT;
+        }
+    }
+
+    for (i = root->inner; i; i = i->next) {
+        if ((current = find_node(i->inner, dm->member))) {
+            dump_node(current, dm->member, 0, 0);
+            found = 1;
+            break;
+        }
+    }
+    
+    free_structure(root);
+
+    if (!found)
+        error(WARNING, "invalid structure reference: %s\n", dm->member);
+}
+
 /*
  *  Dig out a member name from a formatted gdb structure declaration dump,
  *  and print its offset from the named structure passed in.
--- crash-7.1.0.orig/task.c	2015-02-06 21:44:11.000000000 +0300
+++ crash-7.1.0/task.c	2015-05-11 15:52:57.387111513 +0300
 <at>  <at>  -107,6 +107,8  <at>  <at>  static int sort_by_last_run(const void *
 static void sort_context_array_by_last_run(void);
 static void show_ps_summary(ulong);
 static void irqstacks_init(void);
+static void parse_task_thread(int argcnt, char *arglist[], struct task_context *);
+void parse_for_member_new(struct datatype_member *, ulong);

 /*
  *  Figure out how much space will be required to hold the task context
 <at>  <at>  -2746,13 +2748,9  <at>  <at>  task_struct_member(struct task_context *
 	int argcnt;
 	char *arglist[MAXARGS];
 	char *refcopy;
-	char buf[BUFSIZE];
-	char lookfor1[BUFSIZE];
-	char lookfor2[BUFSIZE];
-	char lookfor3[BUFSIZE];
-	int header_printed;
-
-	header_printed = FALSE;
+        unsigned char call_new_parser = 0;
+        struct datatype_member dm;
+        char *member = GETBUF(BUFSIZE);

 	if ((count_chars(ref->str, ',')+1) > MAXARGS) {
 		error(INFO, 
 <at>  <at>  -2767,14 +2765,39  <at>  <at>  task_struct_member(struct task_context *
 	argcnt = parse_line(refcopy, arglist);
 	for (i = 0; i < argcnt; i++)
 		if (!MEMBER_EXISTS("task_struct", arglist[i]) &&
-		    !MEMBER_EXISTS("thread_info", arglist[i]))
-			error(INFO, "%s: not a task_struct or thread_info member\n", 
-				arglist[i]);
-
+		    !MEMBER_EXISTS("thread_info", arglist[i])) {
+			if (count_chars(arglist[i], '.') || count_chars(arglist[i], '['))
+				call_new_parser = 1;
+			else
+                                error(INFO, "%s: not a task_struct or "
+                                        "thread_info member\n", arglist[i]);
+                }
         open_tmpfile();
         dump_struct("task_struct", tc->task, radix);
-	if (tt->flags & THREAD_INFO)
-		dump_struct("thread_info", tc->thread_info, radix);
+        if (tt->flags & THREAD_INFO)
+                dump_struct("thread_info", tc->thread_info, radix);
+        if (call_new_parser) {
+                for (i = 0; i < argcnt; i++) {
+                        dm.member = arglist[i];
+                        parse_for_member_new(&dm, 0);
+                }
+        } else {
+                parse_task_thread(argcnt, arglist, tc);
+        }
+        close_tmpfile();
+
+        FREEBUF(member);
+
+}
+
+static void parse_task_thread(int argcnt, char *arglist[], struct task_context *tc) {
+	char buf[BUFSIZE];
+	char lookfor1[BUFSIZE];
+	char lookfor2[BUFSIZE];
+	char lookfor3[BUFSIZE];
+	int header_printed = FALSE;
+        int i;
+
         rewind(pc->tmpfile);

 	BZERO(lookfor1, BUFSIZE);
 <at>  <at>  -2825,7 +2848,6  <at>  <at>  task_struct_member(struct task_context *
 			}
 		}
 	}
-	close_tmpfile();
 }

 static char *ps_exclusive = 
--- crash-7.1.0.orig/tools.c	2015-02-06 21:44:11.000000000 +0300
+++ crash-7.1.0/tools.c	2015-05-11 15:52:57.391111513 +0300
 <at>  <at>  -3526,13 +3526,9  <at>  <at>  do_list(struct list_data *ld)
 						dump_struct(ld->structname[i], 
 							next - ld->list_head_offset, radix);
 						break;
-					case 1:
+                                        default:
 						dump_struct_members(ld, i, next);
 						break;
-					default:
-						error(FATAL, 
-						    "invalid structure reference: %s\n",
-							ld->structname[i]);
 					}
 				}
 			}

Karlsson, Jan | 11 May 12:55 2015

Fix in bt for ARM64

Hi Dave

 

I found an ARM64 problem for bt when a function belongs to a module.

 

Printout before fix given below:

#16 [ffffffc0be96f8d0] __this_module at ffffffbffc15a2f8 [wlan]

#17 [ffffffc0be96f9b0] __this_module at ffffffbffc161b18 [wlan]

#18 [ffffffc0be96f9c0] __this_module at ffffffbffc16033c [wlan]

#19 [ffffffc0be96fa10] __this_module at ffffffbffc1630f8 [wlan]

#20 [ffffffc0be96fab0] __this_module at ffffffbffc156ff8 [wlan]

#21 [ffffffc0be96faf0] __this_module at ffffffbffc15aa58 [wlan]

#22 [ffffffc0be96fb20] __this_module at ffffffbffc15bfc8 [wlan]

#23 [ffffffc0be96fb60] __this_module at ffffffbffc115fac [wlan]

#24 [ffffffc0be96fb90] tasklet_action at ffffffc000223738

#25 [ffffffc0be96fbb0] __do_softirq at ffffffc000222e94

 

Printout after fix:

#16 [ffffffc0be96f8d0] dhd_bus_rx_frame at ffffffbffc15a2f8 [wlan]

#17 [ffffffc0be96f9b0] dhd_update_flow_prio_map at ffffffbffc161b18 [wlan]

#18 [ffffffc0be96f9c0] dhd_update_flow_prio_map at ffffffbffc16033c [wlan]

#19 [ffffffc0be96fa10] dhd_prot_process_ctrlbuf at ffffffbffc1630f8 [wlan]

#20 [ffffffc0be96fab0] dhd_bus_ringbell at ffffffbffc156ff8 [wlan]

#21 [ffffffc0be96faf0] dhd_bus_console_in at ffffffbffc15aa58 [wlan]

#22 [ffffffc0be96fb20] dhd_bus_dpc at ffffffbffc15bfc8 [wlan]

#23 [ffffffc0be96fb60] dhd_sched_dpc at ffffffbffc115fac [wlan]

#24 [ffffffc0be96fb90] tasklet_action at ffffffc000223738

#25 [ffffffc0be96fbb0] __do_softirq at ffffffc000222e94

 

From arm64.c:

 

static int

arm64_print_stackframe_entry(struct bt_info *bt, int level, struct arm64_stackframe *frame)

{

                           char *name, *name_plus_offset;

                           ulong symbol_offset;

                           struct syment *sp;

                           struct load_module *lm;

                           char buf[BUFSIZE];

 

        name = closest_symbol(frame->pc);

        name_plus_offset = NULL;

 

        if (bt->flags & BT_SYMBOL_OFFSET) {

              /*ADDED*/

              if (module_symbol(frame->pc, NULL, &lm, NULL, 0))

                sp = value_search_module(frame->pc, &symbol_offset);

              else

              /*END ADDED*/

                sp = value_search(frame->pc, &symbol_offset);

 

You probably also want to prevent calling module_symbol a second time later in the function.

 

Jan

 

Jan Karlsson

Senior Software Engineer

System Assurance

 

Sony Mobile Communications

Tel: +46 703 062 174

jan.karlsson <at> sonymobile.com

 

sonymobile.com

 

 

<div><div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US">Hi Dave<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">I found an ARM64 problem for bt when a function belongs to a module.<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">Printout before fix given below:<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#16 [ffffffc0be96f8d0] __this_module at ffffffbffc15a2f8 [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#17 [ffffffc0be96f9b0] __this_module at ffffffbffc161b18 [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#18 [ffffffc0be96f9c0] __this_module at ffffffbffc16033c [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#19 [ffffffc0be96fa10] __this_module at ffffffbffc1630f8 [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#20 [ffffffc0be96fab0] __this_module at ffffffbffc156ff8 [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#21 [ffffffc0be96faf0] __this_module at ffffffbffc15aa58 [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#22 [ffffffc0be96fb20] __this_module at ffffffbffc15bfc8 [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#23 [ffffffc0be96fb60] __this_module at ffffffbffc115fac [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#24 [ffffffc0be96fb90] tasklet_action at ffffffc000223738<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#25 [ffffffc0be96fbb0] __do_softirq at ffffffc000222e94<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">Printout after fix:<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#16 [ffffffc0be96f8d0] dhd_bus_rx_frame at ffffffbffc15a2f8 [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#17 [ffffffc0be96f9b0] dhd_update_flow_prio_map at ffffffbffc161b18 [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#18 [ffffffc0be96f9c0] dhd_update_flow_prio_map at ffffffbffc16033c [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#19 [ffffffc0be96fa10] dhd_prot_process_ctrlbuf at ffffffbffc1630f8 [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#20 [ffffffc0be96fab0] dhd_bus_ringbell at ffffffbffc156ff8 [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#21 [ffffffc0be96faf0] dhd_bus_console_in at ffffffbffc15aa58 [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#22 [ffffffc0be96fb20] dhd_bus_dpc at ffffffbffc15bfc8 [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#23 [ffffffc0be96fb60] dhd_sched_dpc at ffffffbffc115fac [wlan]<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#24 [ffffffc0be96fb90] tasklet_action at ffffffc000223738<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">#25 [ffffffc0be96fbb0] __do_softirq at ffffffc000222e94<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">From arm64.c:<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">static int <p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">arm64_print_stackframe_entry(struct bt_info *bt, int level, struct arm64_stackframe *frame)<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">{<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char *name, *name_plus_offset;<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ulong symbol_offset;<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct syment *sp;<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct load_module *lm;<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char buf[BUFSIZE];<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name = closest_symbol(frame-&gt;pc);<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name_plus_offset = NULL;<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (bt-&gt;flags &amp; BT_SYMBOL_OFFSET) {<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*ADDED*/<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (module_symbol(frame-&gt;pc, NULL, &amp;lm, NULL, 0))<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sp = value_search_module(frame-&gt;pc, &amp;symbol_offset);<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*END ADDED*/<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sp = value_search(frame-&gt;pc, &amp;symbol_offset);<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">You probably also want to prevent calling module_symbol a second time later in the function.<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">Jan<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">Jan Karlsson</span><span lang="EN-US"><p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">Senior Software Engineer<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">System Assurance<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">Sony Mobile Communications<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">Tel: +46 703 062 174<p></p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><a href="mailto:Firstname.Lastname <at> sonymobile.com"><span>jan.karlsson <at> sonymobile.com</span></a><p></p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span><a href="http://sonymobile.com/"><span lang="EN-US">sonymobile.com</span></a></span><span lang="EN-US"><p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span></span><span><p></p></span></p>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div></div>
Vasily Averin | 30 Apr 16:46 2015

[PATCH RFC] vz extension: vzlist, ctid, vzps commands

vz extension contains OpenVZ specific commands:
  vzlist	shows list of OpenVZ containers,
  vzps		shows all tasks executed inside of specified container,
  ctid		shows ContainerID of given task.

Signed-off-by: Vasily Averin <vvs <at> parallels.com>
---
 extensions/vz.c | 345 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 345 insertions(+)
 create mode 100644 extensions/vz.c

diff --git a/extensions/vz.c b/extensions/vz.c
new file mode 100644
index 0000000..f48d428
--- /dev/null
+++ b/extensions/vz.c
 <at>  <at>  -0,0 +1,345  <at>  <at> 
+/* vz.c - crash extension for OpenVZ containers
+ *
+ * Copyright (C) 2015 Vasily Averin
+ * Copyright (C) 2015 Parallels IP Holdings GmbH.
+ *
+ * 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 VZ_MEMBER_OFFSET_INIT(X,Y,Z) (vz_offset_table.X=MEMBER_OFFSET(Y,Z))
+#define VZ_OFFSET(X)	(OFFSET_verify(vz_offset_table.X, (char *)__FUNCTION__, __FILE__,
__LINE__, #X))
+#define VZ_INIT 0x1
+
+struct vz_offset_table {
+	long task_veinfo;
+	long veinfo_ve;
+	long ve_veid;
+	long ve_nsproxy;
+	long nsproxy_pidns;
+	long pidns_init;
+};
+
+static struct vz_offset_table vz_offset_table = { 0 };
+static int init_flags = 0;
+static int id_size;
+
+void vz_init(void);
+void vz_fini(void);
+
+static ulong
+ve_to_task(ulong ve)
+{
+	ulong ns, pidns, task;
+
+	readmem(ve + VZ_OFFSET(ve_nsproxy), KVADDR, &ns,
+		sizeof(ulong), "ve_struct.ve_ns", FAULT_ON_ERROR);
+	readmem(ns + VZ_OFFSET(nsproxy_pidns), KVADDR, &pidns,
+		sizeof(ulong), "nsproxy.ve_pidns", FAULT_ON_ERROR);
+	readmem(pidns + VZ_OFFSET(pidns_init), KVADDR, &task,
+		sizeof(ulong), "pid_namespace.child_reaper", FAULT_ON_ERROR);
+
+	return task;
+}
+
+#define VZLIST_HEADER \
+"     CTID     VE_STRUCT            TASK          PID  COMM\n"
+
+static void
+show_container(ulong ve, ulong ctid, ulong flag)
+{
+	ulong task;
+	struct task_context *tc;
+
+	task = ve_to_task(ve);
+	tc = task_to_context(task);
+
+	if (!(flag & PS_NO_HEADER))
+		fprintf(fp, VZLIST_HEADER);
+
+	fprintf(fp, "%9ld  %16lx  %16lx  %6ld  %s\n",
+		ctid, ve, tc->task, tc->pid, tc->comm);
+	return;
+}
+
+static void
+show_containers(ulong ctid)
+{
+	struct list_data list_data, *ld;
+	ulong ve, id, flag = 0;
+	int i, cnt;
+
+	ld = &list_data;
+	BZERO(ld, sizeof(struct list_data));
+	ld->flags |= LIST_ALLOCATE;
+
+	ld->start = ld->end = symbol_value("ve_list_head");
+	ld->list_head_offset = 0;
+
+	cnt = do_list(ld);
+
+	for (i = 1; i < cnt; i++) {
+		id = 0;
+		ve = ld->list_ptr[i];
+		readmem(ve + VZ_OFFSET(ve_veid), KVADDR, &id,
+			id_size, "ve_struct.veid", FAULT_ON_ERROR);
+		if ((ctid == -1) || ctid == id) {
+			show_container(ve, id, flag);
+			flag = PS_NO_HEADER;
+		}
+	}
+	return;
+}
+
+void
+cmd_vzlist(void)
+{
+	int c;
+	ulong ctid = -1;
+
+	while ((c = getopt(argcnt, args, "E:")) != EOF) {
+		switch(c)
+		{
+		case 'E':
+			ctid = stol(optarg, FAULT_ON_ERROR, NULL);
+			break;
+		default:
+			argerrs++;
+			break;
+		}
+	}
+	if (argerrs) {
+		cmd_usage(pc->curcmd, SYNOPSIS);
+		return;
+	}
+
+	show_containers(ctid);
+	return;
+}
+
+char *help_vzlist[] = {
+"vzlist",
+"shows list of runnig OpenVZ containers",
+"[-E CTID]",
+"If no argument is entered, command shows IDs of all running containers\n",
+"  -E  Container ID",
+"\nEXAMPLES",
+"%s> vzlist",
+"     CTID     VE_STRUCT            TASK          PID  COMM",
+"      121  ffff8801491e7000  ffff8801493d0ff0   95990  init",
+"      123  ffff880135a37000  ffff8803fb0a3470   95924  init",
+"      321  ffff88045a778000  ffff880400616300   95923  init",
+"      700  ffff88019ddae000  ffff88019ddd4fb0   95882  init",
+"      503  ffff88045a84e800  ffff8803c3c782c0   95902  init",
+"      122  ffff8804004ea000  ffff88045612afb0   95886  init",
+"      600  ffff88016e467000  ffff880459d653f0   95885  init",
+"        0  ffffffff81aaa220  ffff88045e530b30       1  init",
+NULL
+};
+
+static ulong
+task_to_ctid(ulong task)
+{
+	ulong veinfo, ve, ctid = 0;
+
+	veinfo = task + VZ_OFFSET(task_veinfo);
+	readmem(veinfo + VZ_OFFSET(veinfo_ve), KVADDR, &ve,
+		sizeof(ulong), "ve_task_info.exec_env", FAULT_ON_ERROR);
+	readmem(ve + VZ_OFFSET(ve_veid), KVADDR, &ctid,
+		id_size, "ve_struct.veid", FAULT_ON_ERROR);
+
+	return ctid;
+}
+
+static void
+show_ctid(struct task_context *tc, ulong flag)
+{
+	ulong ctid;
+
+	ctid = task_to_ctid(tc->task);
+	if (!(flag & PS_NO_HEADER))
+		fprintf(fp, "     CTID    PID         TASK        COMM\n");
+
+	fprintf(fp, "%9ld  %6ld  %16lx  %s\n",
+		ctid, tc->pid, tc->task, tc->comm);
+	return;
+}
+
+void
+cmd_ctid(void)
+{
+	ulong value, flag = 0;
+	struct task_context *tc;
+	int c;
+
+	while ((c = getopt(argcnt, args, "")) != EOF) {
+		switch(c)
+		{
+		default:
+			cmd_usage(pc->curcmd, SYNOPSIS);
+			return;
+		}
+	}
+
+	if (!args[optind]) {
+		tc = task_to_context(CURRENT_TASK());
+		show_ctid(tc, flag);
+	}
+	while (args[optind]) {
+		switch (str_to_context(args[optind], &value, &tc))
+		{
+		case STR_PID:
+		case STR_TASK:
+			break;
+		case STR_INVALID:
+			error(INFO, "invalid task or pid value: %s\n",
+				   args[optind]);
+		default:
+			argerrs++;
+			 break;
+		}
+		if (argerrs)
+			break;
+		show_ctid(tc, flag);
+		flag = PS_NO_HEADER;
+		optind++;
+	}
+	if (argerrs)
+		cmd_usage(pc->curcmd, SYNOPSIS);
+
+	return;
+}
+
+char *help_ctid[] = {
+"ctid",
+"shows Container ID of given tasks",
+"[task|pid]",
+"     If no argument is entered, command shows CTID of current task",
+"\nEXAMPLES",
+"%s> ctid 99583",
+"     CTID    PID         TASK        COMM",
+"      121   99583  ffff880203e56f30  httpd",
+NULL
+};
+
+static void
+show_vzps(ulong ctid)
+{
+	struct task_context *tc;
+	ulong flag;
+	int i;
+
+	tc = FIRST_CONTEXT();
+	for (i = 0; i < RUNNING_TASKS(); i++, tc++) {
+		ulong id = task_to_ctid(tc->task);
+		if ((ctid == -1) || (ctid == id)) {
+			show_ctid(tc, flag);
+			flag = PS_NO_HEADER;
+		}
+	}
+	return;
+}
+
+void
+cmd_vzps(void)
+{
+	ulong ctid = -1;
+	int c;
+
+	while ((c = getopt(argcnt, args, "E:")) != EOF) {
+		switch(c)
+		{
+		case 'E':
+			ctid = stol(optarg, FAULT_ON_ERROR, NULL);
+			break;
+		default:
+			argerrs++;
+			break;
+		}
+	}
+	if (argerrs)
+		cmd_usage(pc->curcmd, SYNOPSIS);
+
+	show_vzps(ctid);
+	return;
+}
+
+char *help_vzps[] = {
+"vzps",
+"shows list of tasks related to specified CTID",
+" [ -E CTID]",
+"     If no argument is entered, command shows CTID for all processes\n",
+"\nEXAMPLES",
+"%s> vzps -E 121",
+"     CTID    PID         TASK        COMM",
+"      121   95990  ffff8801493d0ff0  init",
+"      121   95996  ffff8803c3e3b0f0  kthreadd/121",
+"      121   95997  ffff8803cd3aacb0  khelper/121",
+"      121   97267  ffff880405e4b2f0  udevd",
+"      121   99341  ffff8803c3fd2440  syslogd",
+"      121   99404  ffff880405e0c2c0  klogd",
+"      121   99424  ffff8803fb0f68c0  sshd",
+"      121   99445  ffff8801493d0500  xinetd",
+"      121   99557  ffff8804599f9230  sendmail",
+"      121   99568  ffff8804591b00c0  sendmail",
+"      121   99583  ffff880203e56f30  httpd",
+"      121   99594  ffff88016e4e01c0  crond",
+"      121   99614  ffff8803fb26cf70  xfs",
+"      121   99624  ffff88045a6ce2c0  saslauthd",
+"      121   99625  ffff8801ce134ff0  saslauthd",
+"      121  248691  ffff88040e2ee9c0  httpd",
+NULL
+};
+
+static struct command_table_entry command_table[] = {
+	{ "vzlist", cmd_vzlist, help_vzlist, 0},
+	{ "ctid", cmd_ctid, help_ctid, 0},
+	{ "vzps", cmd_vzps, help_vzps, 0},
+	{ NULL },
+};
+
+void __attribute__((constructor))
+vz_init(void)
+{
+	if (init_flags & VZ_INIT)
+		return;
+
+	if (!symbol_exists("ve_list_head")) {
+		fprintf(fp, "vz commands only work on OpenVZ kernels\n");
+		return;
+	}
+	init_flags |= VZ_INIT;
+
+	BNEG(&vz_offset_table, sizeof(vz_offset_table));
+
+	if (STRUCT_EXISTS("ve_task_info")) {
+		VZ_MEMBER_OFFSET_INIT(task_veinfo,
+					 "task_struct", "ve_task_info");
+		VZ_MEMBER_OFFSET_INIT(veinfo_ve, "ve_task_info", "exec_env");
+	}
+	if (STRUCT_EXISTS("ve_struct")) {
+		VZ_MEMBER_OFFSET_INIT(ve_veid, "ve_struct", "veid");
+		VZ_MEMBER_OFFSET_INIT(ve_nsproxy, "ve_struct", "ve_ns");
+		id_size = MEMBER_SIZE("ve_struct", "veid");
+	}
+	if (STRUCT_EXISTS("nsproxy")) {
+		VZ_MEMBER_OFFSET_INIT(nsproxy_pidns, "nsproxy", "pid_ns");
+	}
+	if (STRUCT_EXISTS("pid_namespace"))
+		VZ_MEMBER_OFFSET_INIT(pidns_init,
+					"pid_namespace", "child_reaper");
+
+	register_extension(command_table);
+}
+
+void __attribute__((destructor))
+vz_fini(void) { }
--

-- 
1.7.12.4

Vasily Averin | 30 Apr 16:46 2015

crash: vz extension for OpenVZ kernels

Dear Dave,

I've prepared vz crash extension with commands 
useful for troubleshooting of OpenVZ kernel crashes.

Could you please review the patch and advise how it's better
to distribute this extension.

vz extension uses openVZ-specific kernel structures 
and works on OpenVZ kernels only.

It implements vzlist, vzps and ctid commands:

vzlist -- shows list of OpenVZ containers,
contains Container ID, references to ve_struct 
and parent task inside container.

crash> vzlist
     CTID     VE_STRUCT            TASK          PID  COMM
      121  ffff8801491e7000  ffff8801493d0ff0   95990  init
      123  ffff880135a37000  ffff8803fb0a3470   95924  init
      321  ffff88045a778000  ffff880400616300   95923  init
      700  ffff88019ddae000  ffff88019ddd4fb0   95882  init
      503  ffff88045a84e800  ffff8803c3c782c0   95902  init
      122  ffff8804004ea000  ffff88045612afb0   95886  init
      600  ffff88016e467000  ffff880459d653f0   95885  init
        0  ffffffff81aaa220  ffff88045e530b30       1  init

vzps  -- shows list of processes inside of specified container

crash> vzps -E 121
     CTID    PID         TASK        COMM
      121   95990  ffff8801493d0ff0  init
      121   95996  ffff8803c3e3b0f0  kthreadd/121
      121   95997  ffff8803cd3aacb0  khelper/121
      121   97267  ffff880405e4b2f0  udevd
      121   99341  ffff8803c3fd2440  syslogd
      121   99404  ffff880405e0c2c0  klogd
      121   99424  ffff8803fb0f68c0  sshd
      121   99445  ffff8801493d0500  xinetd
      121   99557  ffff8804599f9230  sendmail
      121   99568  ffff8804591b00c0  sendmail
      121   99583  ffff880203e56f30  httpd
      121   99594  ffff88016e4e01c0  crond
      121   99614  ffff8803fb26cf70  xfs
      121   99624  ffff88045a6ce2c0  saslauthd
      121   99625  ffff8801ce134ff0  saslauthd
      121  248691  ffff88040e2ee9c0  httpd

ctid -- shows ContainerID for given task
crash> ctid 99614
     CTID    PID         TASK        COMM
      121   99614  ffff8803fb26cf70  xfs

Thank you,
	Vasily Averin

Dave Anderson | 30 Apr 16:38 2015
Picon

Re: [PATCH] cmd_ps message cleanup


----- Original Message -----
> ps -L no longer exists
> 
> Signed-off-by: Vasily Averin <vvs <at> parallels.com>
> ---
>  task.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/task.c b/task.c
> index c875bb9..bc7911b 100644
> --- a/task.c
> +++ b/task.c
>  <at>  <at>  -2843,7 +2843,7  <at>  <at>  task_struct_member(struct task_context *tc, unsigned
> int radix, struct reference
>  }
>  
>  static char *ps_exclusive =
> -    "-a, -t, -c, -p, -g, -l, -m, -L, -S and -r flags are all mutually-exclusive\n";
> +    "-a, -t, -c, -p, -g, -l, -m, -S and -r flags are all mutually-exclusive\n";
>  
>  static void
>  check_ps_exclusive(ulong flag, ulong thisflag)
> --
> 1.7.12.4

Done -- queued for crash-7.1.1:

  https://github.com/crash-utility/crash/commit/f1dbe49fa87682c2deee79a96e2e53a63080834e

Thanks,
  Dave

Karlsson, Jan | 30 Apr 09:12 2015

Value of

Hi Dave

 

I was looking in the file arm64.c at function arm64_translate_pte and saw the line:

 

  if (!page_present && (pte & PTE_FILE)) {

 

I also saw that there are two versions of the value PTE_FILE (see also defs.h) and the following code is included in arm64.c in arm64_init:

 

    if (THIS_KERNEL_VERSION >= LINUX(3,10,0)) {

      machdep->machspec->pte_protnone = PTE_PROT_NONE_3_10;

      machdep->machspec->pte_file = PTE_FILE_3_10;

    } else {

      machdep->machspec->pte_protnone = PTE_PROT_NONE;

      machdep->machspec->pte_file = PTE_FILE;

    }

 

So should not the first mentioned line be changed to:

 

  if (!page_present && (pte & machdep->machspec->pte_file)) {

 

Jan

 

Jan Karlsson

Senior Software Engineer

System Assurance

 

Sony Mobile Communications

Tel: +46 703 062 174

jan.karlsson <at> sonymobile.com

 

sonymobile.com

 

 

<div><div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US">Hi Dave<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">I was looking in the file arm64.c at function </span><span lang="EN-US">arm64_translate_pte</span><span lang="EN-US"> and saw the line:<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp; if (!page_present &amp;&amp; (pte &amp; PTE_FILE)) {<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">I also saw that there are two versions of the value PTE_FILE (see also defs.h) and the following code is included in arm64.c in </span><span lang="EN-US">arm64_init</span><span lang="EN-US">:<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp; if (THIS_KERNEL_VERSION &gt;= LINUX(3,10,0)) {<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; machdep-&gt;machspec-&gt;pte_protnone = PTE_PROT_NONE_3_10;<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; machdep-&gt;machspec-&gt;pte_file = PTE_FILE_3_10;<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp; } else {<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; machdep-&gt;machspec-&gt;pte_protnone = PTE_PROT_NONE;<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; machdep-&gt;machspec-&gt;pte_file = PTE_FILE;<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp;&nbsp;&nbsp; }<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">So should not the first mentioned line be changed to:<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">&nbsp; if (!page_present &amp;&amp; (pte &amp; machdep-&gt;machspec-&gt;pte_file)) {<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">Jan<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">Jan Karlsson</span><span lang="EN-US"><p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">Senior Software Engineer<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">System Assurance<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span lang="EN-US">Sony Mobile Communications<p></p></span></p>
<p class="MsoNormal"><span lang="EN-US">Tel: +46 703 062 174<p></p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><a href="mailto:Firstname.Lastname <at> sonymobile.com"><span>jan.karlsson <at> sonymobile.com</span></a><p></p></span></p>
<p class="MsoNormal"><span lang="EN-GB"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span><a href="http://sonymobile.com/"><span lang="EN-US">sonymobile.com</span></a></span><span lang="EN-US"><p></p></span></p>
<p class="MsoNormal"><span lang="EN-US"><p>&nbsp;</p></span></p>
<p class="MsoNormal"><span></span><span><p></p></span></p>
<p class="MsoNormal"><p>&nbsp;</p></p>
</div></div>

Gmane