----- Original Message ----- > 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 I went ahead and fixed the sockq.c version available from the extensions page. Dave > > -----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 > -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility