Hi Qiao, Can you fix a typo in one of the strings (doesn't affect the functionality of the extension module and isn't likely to confuse anyone): fprintf(fp, "cannot get private_datad of file structure\n"); This line should have private_data not private_datad in the string. Thanks Shane -----Original Message----- From: crash-utility-bounces@xxxxxxxxxx [mailto:crash-utility-bounces@xxxxxxxxxx] On Behalf Of Dave Anderson Sent: Wednesday, April 23, 2014 1:26 AM To: Discussion list for crash utility usage, maintenance and development Subject: Re: [PATCH] extension: get socket receive queue into a file Thanks Qiao -- I've posted the module in the extensions page: http://people.redhat.com/anderson/extensions.html#SOCKQ Dave ----- Original Message ----- > syslog() can be used to send messages to the system logger, and a > socket is used to do the deliverying. So such a situation may be > existed that the message is sent to the socket, but not received by > syslogd yet. This module is used to dump the messages left in the socket. > > This module has been tested on RHEL5/6 x86/x64. The following program > is used to generate a kdump core that got log messages left in socket. > > 1. compile the following c program to a.out <cut> > > int main(int argc, char **argv) > { > char buf[256]; > int i = 0; > > for (i = 0; i < 1; i++) { > openlog("syslog", LOG_CONS , 0); > sprintf(buf, "[TEST] a very long test message is appropriate, but I > do " > "not know such a message (No.%d)\n", i); > syslog(LOG_INFO, buf); > closelog(); > } > > return 0; > } > <cut> > > 2. run the following bash code to panic and generate a kdump core > <cut> > i=0 > while [[ $i -lt 1000 ]];do > ./a.out & > echo $i > i=$((i+1)) > done > echo c > /proc/sysrq-trigger > i=0 > while [[ $i -lt 1000 ]];do > ./a.out & > echo $i > i=$((i+1)) > done > <cut> > > 3. run crash with the vmcore generated in step 2 and load sockq > module. Then run command like below to get left log message <cut> > crash> ps | grep syslog > 1121 1 0 ffff880037ac2080 IN 0.2 249080 1740 rsyslogd > 1123 1 1 ffff880037a00040 RU 0.2 249080 1740 rsyslogd > 1124 1 1 ffff8800375f9540 IN 0.2 249080 1740 rsyslogd > crash> files 1121 > PID: 1121 TASK: ffff880037ac2080 CPU: 0 COMMAND: "rsyslogd" > ROOT: / CWD: / > FD FILE DENTRY INODE TYPE PATH > 0 ffff88003e0d0b40 ffff88003ef29a80 ffff88003ef8c688 SOCK > 1 ffff88003d8f1140 ffff88003efc3800 ffff88003d3d44c0 REG /var/log/messages > 2 ffff88003d859180 ffff88003efadb40 ffff88003d3d40c0 REG /var/log/secure > 3 ffff88003d8590c0 ffff88003ef29b40 ffff88003ef917f8 REG /proc/kmsg > 4 ffff88003dfd1b40 ffff88003d1a7500 ffff88003d004cc0 REG /var/log/maillog > 5 ffff88003dee7180 ffff88003d0b6980 ffff88003d0048c0 REG > /var/log/cron > > crash> sockq ffff88003e0d0b40 out > crash> cat out > <14>Apr 17 16:32:56 syslog: [TEST] a very long test message is > appropriate, but I do not know such a message (No.48) <14>Apr 17 > 16:32:56 syslog: [TEST] a very long test message is appropriate, but I > do not know such a message (No.44) <14>Apr 17 16:32:56 syslog: [TEST] > a very long test message is appropriate, but I do not know such a > message (No.12) <14>Apr 17 16:32:56 syslog: [TEST] a very long test > message is appropriate, but I do not know such a message (No.13) > <14>Apr 17 16:32:56 syslog: [TEST] a very long test message is > appropriate, but I do not know such a message (No.21) <14>Apr 17 > 16:32:56 syslog: [TEST] a very long test message is appropriate, but I > do not know such a message (No.21) <14>Apr 17 16:32:56 syslog: [TEST] > a very long test message is appropriate, but I do not know such a > message (No.18) <14>Apr 17 16:32:56 syslog: [TEST] a very long test > message is appropriate, but I do not know such a message (No.1) > <14>Apr 17 16:32:56 syslog: [TEST] a very long test message is > appropriate, but I do not know such a message (No.18) <14>Apr 17 > 16:32:56 syslog: [TEST] a very long test message is appropriate, but I > do not know such a message (No.18) <14>Apr 17 16:32:56 syslog: [TEST] > a very long test message is appropriate, but I do not know such a > message (No.2) > crash> > <cut> > > Signed-off-by: Qiao Nuohan <qiaonuohan@xxxxxxxxxxxxxx> > --- > extensions/sockq.c | 203 > +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 203 insertions(+) > create mode 100644 extensions/sockq.c > > diff --git a/extensions/sockq.c b/extensions/sockq.c new file mode > 100644 index 0000000..3784413 > --- /dev/null > +++ b/extensions/sockq.c > @@ -0,0 +1,203 @@ > +/* sockq.c - sockq extension module for crash > + * > + * Copyright (C) 2014 FUJITSU LIMITED > + * Author: Qiao Nuohan <qiaonuohan@xxxxxxxxxxxxxx> > + * > + * 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" /* From the crash source top-level directory */ > + > +void sockq_init(void); /* constructor function */ > +void sockq_fini(void); /* destructor function (optional) */ > + > +void cmd_sockq(void); /* Declare the commands and their help data. */ > +char *help_sockq[]; > + > +static struct command_table_entry command_table[] = { > + { "sockq", cmd_sockq, help_sockq, 0}, /* One or more commands, */ > + { NULL }, /* terminated by NULL, */ > +}; > + > +char *help_sockq[] = { > +"sockq", /* command name */ > +"get socket receive queue into a file", /* short description */ > +"file_address outfile", /* argument synopsis */ > + > +" This command gets the data from the socket receive queue.", " ", > +" file_address A hexadecimal value of socket's file structure > address.", > +" outfile A name of output file. If the file already exists,", > +" it is overwritten.", > +NULL > +}; > + > +void __attribute__((constructor)) > +sockq_init(void) /* Register the command set. */ { > + register_extension(command_table); > +} > + > +/* > + * This function is called if the shared object is unloaded. > + * If desired, perform any cleanups here. > + */ > +void __attribute__((destructor)) > +sockq_fini(void) { } > + > +static int > +get_member_data(ulonglong addr, char *name, char *member, void* buf) > +{ > + ulong member_offset; > + > + member_offset = MEMBER_OFFSET(name, member); > + > + if (!readmem(addr + member_offset, KVADDR, buf, > + MEMBER_SIZE(name, member), name, FAULT_ON_ERROR)) > + return FALSE; > + > + return TRUE; > +} > + > +/* > + * write receive data in the specified file */ static int > +write_data(int fd, char *buf, ulong addr, ulong size) { > + ulong wsize; > + > + while (size > 0) { > + /* size of the buffer is pagesize */ > + wsize = (size > PAGESIZE()) ? PAGESIZE() : size; > + > + if (!readmem(addr, KVADDR, buf, wsize, "vaddr", FAULT_ON_ERROR)) { > + fprintf(fp, "cannot read data from packet buffer\n"); > + return 1; > + } > + > + if (write(fd, buf, wsize) < 0) { > + fprintf(fp, "cannot write data in a file\n"); > + return 1; > + } > + > + addr += wsize; > + size -= wsize; > + } > + > + return 0; > +} > + > +int > +do_sockq(ulong file_addr, char *output_file, int fd) { > + int rc = 1; > + ulong pd, sk; > + uint qlen; > + char *buf = NULL; > + ulong next, head; > + unsigned int len; > + ulong wnext; > + > + if (!get_member_data(file_addr, "file", "private_data", &pd)) { > + fprintf(fp, "cannot get private_datad of file structure\n"); > + goto cleanup; > + } > + > + if (!get_member_data(pd, "socket", "sk", &sk)) { > + fprintf(fp, "cannot get sk of socket structure\n"); > + goto cleanup; > + } > + > + if (!get_member_data(sk + MEMBER_OFFSET("sock", "sk_receive_queue"), > + "sk_buff_head", "next", &next)) { > + fprintf(fp, "cannot get the first queue of sock structure\n"); > + goto cleanup; > + } > + > + if (!get_member_data(sk + MEMBER_OFFSET("sock", "sk_receive_queue"), > + "sk_buff_head", "qlen", &qlen)) { > + fprintf(fp, "cannot get the number of queue list\n"); > + goto cleanup; > + } > + > + /* create a output file */ > + if (output_file != NULL && > + (fd = open(output_file, > + O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR)) < 0) { > + fprintf(fp, "cannot create %s\n", output_file); > + goto cleanup; > + } > + > + if (qlen == 0) { > + /* receive queue is empty */ > + rc = 0; > + goto cleanup; > + } > + > + /* get work area */ > + buf = GETBUF(PAGESIZE()); > + > + while (qlen-- > 0) { > + /* get packet buffer are info */ > + if (!get_member_data(next, "sk_buff", "head", &head)) { > + fprintf(fp, "cannot head of sk_buff structure\n"); > + goto cleanup; > + } > + > + if (!get_member_data(next, "sk_buff", "len", &len)) { > + fprintf(fp, "cannot tail of sk_buff structure\n"); > + goto cleanup; > + } > + > + /* write data in the output file */ > + if (write_data(fd, buf, head, len)) > + goto cleanup; > + > + /* next receive queue */ > + wnext = next; > + if (!get_member_data(wnext, "sk_buff", "next", &next)) { > + fprintf(fp, "cannot get next of sk_buff structure\n"); > + goto cleanup; > + } > + } > + > + /* all process normally ends */ > + rc = 0; > + > +cleanup: > + if (output_file != NULL) > + close(fd); > + if (buf) > + FREEBUF(buf); > + > + return rc; > +} > + > +void > +cmd_sockq(void) > +{ > + ulong file_addr; > + > + if (argcnt != 3) > + cmd_usage(pc->curcmd, SYNOPSIS); > + > + optind++; > + file_addr = htol(args[optind], FAULT_ON_ERROR, NULL); > + > + optind++; > + if (strlen(args[optind]) > PATH_MAX) { > + fprintf(fp, "cannot create specified output file\n"); > + return; > + } > + > + do_sockq(file_addr, args[optind], -1); } > -- > 1.8.5.3 > > -- > Crash-utility mailing list > Crash-utility@xxxxxxxxxx > https://www.redhat.com/mailman/listinfo/crash-utility > -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility