lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 27 Feb 2014 13:19:22 +0900
From:	Yoshihiro YUNOMAE <yoshihiro.yunomae.ez@...achi.com>
To:	Hannes Reinecke <hare@...e.de>
Cc:	"James E.J. Bottomley" <JBottomley@...allels.com>,
	Prarit Bhargava <prarit@...hat.com>,
	linux-scsi@...r.kernel.org, Kay Sievers <kay@...y.org>,
	linux-kernel@...r.kernel.org,
	Hidehiro Kawai <hidehiro.kawai.ez@...achi.com>,
	yrl.pp-manager.tt@...achi.com,
	Masami Hiramatsu <masami.hiramatsu.pt@...achi.com>
Subject: Re: [PATCH RESEND] scsi: Output error messages using structured
 printk in single line

Hi Hannes,

Although I sent you a message 6 days ago to ask your work which
is similar to my patch, I resend my patch because I'm considering
this problem should be fixed as soon as possible.

Thank you,
Yoshihiro YUNOMAE

(2014/02/27 13:17), Yoshihiro YUNOMAE wrote:
> Output error messages using structured printk in single line.
> In SCSI drivers, some error messages which should be output in single line are
> divided in multiple lines. When user tools handle the error messages, those
> divided messages will create some inconveniences.
>
> The reason why this problem is induced is structured printk for error messages.
> Structured printk can add device information for printk, and it is used in
> scmd_printk() and sd_printk(). The printk aims at output in atomic, so we
> cannot use those functions for connecting multiple messages like KERN_CONT.
> However, some error messages is implemented as follows:
>     structured_printk("DEVICE INFORMATION:");
>     printk(KERN_CONT, "DETAIL INFORMATION\n");
> This implementation will be expected to output like "DEVICE INFORMATION: DETAIL
> INFORMATION", but actually, this will be output as follows:
>     DEVICE INFORMATION:
>     DETAIL INFORMATION
>
> For instance, in a following pseudo SCSI error test, the device information and
> the detail information are divided:
>
> -- Pseudo SCSI error test for current kernel
>    # modprobe scsi_debug
>    # cd /sys/bus/pseudo/drivers/scsi_debug
>    # echo 2 > opts
>    # dd if=/dev/sdb of=/dev/null 2> /dev/null
>
> -- Result for current kernel
>    # dmesg
>
> [   17.842110] sd 2:0:0:0: [sdb] Attached SCSI disk
> [   18.859098] sd 2:0:0:0: [sdb] Unhandled sense code
> [   18.859103] sd 2:0:0:0: [sdb]
> [   18.859106] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
> [   18.859108] sd 2:0:0:0: [sdb]
> [   18.859110] Sense Key : Medium Error [current]
> [   18.859114] Info fld=0x1234
> [   18.859116] sd 2:0:0:0: [sdb]
> [   18.859119] Add. Sense: Unrecovered read error
> [   18.859122] sd 2:0:0:0: [sdb] CDB:
> [   18.859124] Read(10): 28 00 00 00 11 e0 00 01 00 00
>
> In a SCSI device driver, sd_print_result() is implemented as follows:
>     sd_print_result()
>     {
>         sd_printk(KERN_INFO, sdkp, " ");
>         scsi_show_result(result);
>     }
> Here, first sd_printk() outputs "sd 2:0:0:0: [sdb] ", then scsi_show_sense_hdr()
> outputs "Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE". sd_printk() does not
> include "\n", but it forcibly starts a new line. Therefore, when the driver
> outputs error messages, those messages are divided.
>
> This patch makes those multiple line messages output in single line as follows:
>
>    # dmesg
>
> [   17.145085]  sdb: unknown partition table
> [   17.149096] sd 2:0:0:0: [sdb] Attached SCSI disk
> [   18.166090] sd 2:0:0:0: [sdb] Unhandled sense code
> [   18.166095] sd 2:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
> [   18.166099] sd 2:0:0:0: [sdb] Sense Key : Medium Error [current]
> [   18.166104] Info fld=0x1234
> [   18.166106] sd 2:0:0:0: [sdb] Add. Sense: Unrecovered read error
> [   18.166111] sd 2:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 11 e0 00 01 00 00
>
> Signed-off-by: Yoshihiro YUNOMAE <yoshihiro.yunomae.ez@...achi.com>
> Cc: James E.J. Bottomley <JBottomley@...allels.com>
> Cc: Hannes Reinecke <hare@...e.de>
> Cc: Kay Sievers <kay@...y.org>
> Cc: linux-kernel@...r.kernel.org
> Cc: linux-scsi@...r.kernel.org
> ---
>   drivers/scsi/constants.c |  206 ++++++++++++++++++++++++++++------------------
>   drivers/scsi/scsi.c      |   28 ++++--
>   drivers/scsi/sd.c        |   19 +++-
>   include/scsi/scsi_dbg.h  |   23 ++++-
>   4 files changed, 176 insertions(+), 100 deletions(-)
>
> diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
> index d35a5d6..cb93435 100644
> --- a/drivers/scsi/constants.c
> +++ b/drivers/scsi/constants.c
> @@ -256,8 +256,26 @@ static const char * get_sa_name(const struct value_name_pair * arr,
>   	return (k < arr_sz) ? arr->name : NULL;
>   }
>
> +/* Store a SCSI logging event to buf. */
> +__printf(2, 3)
> +void scsi_log_add(struct scsi_log_line *log, const char *fmt, ...)
> +{
> +	va_list args;
> +	int len;
> +
> +	va_start(args, fmt);
> +	len = vscnprintf(log->buf + log->offset,
> +			 SCSI_LOG_LINE_MAX - log->offset, fmt, args);
> +	WARN_ONCE(!len, "Cannot store the message '%s' in a local log buffer\n",
> +		  fmt);
> +	log->offset += len;
> +	va_end(args);
> +}
> +EXPORT_SYMBOL(scsi_log_add);
> +
>   /* attempt to guess cdb length if cdb_len==0 . No trailing linefeed. */
> -static void print_opcode_name(unsigned char * cdbp, int cdb_len)
> +static void print_opcode_name(unsigned char *cdbp, int cdb_len,
> +			      struct scsi_log_line *log)
>   {
>   	int sa, len, cdb0;
>   	int fin_name = 0;
> @@ -268,20 +286,22 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
>   	case VARIABLE_LENGTH_CMD:
>   		len = scsi_varlen_cdb_length(cdbp);
>   		if (len < 10) {
> -			printk("short variable length command, "
> -			       "len=%d ext_len=%d", len, cdb_len);
> +			scsi_log_add(log,
> +			     "short variable length command, len=%d ext_len=%d",
> +			     len, cdb_len);
>   			break;
>   		}
>   		sa = (cdbp[8] << 8) + cdbp[9];
>   		name = get_sa_name(variable_length_arr, VARIABLE_LENGTH_SZ,
>   				   sa);
>   		if (name)
> -			printk("%s", name);
> +			scsi_log_add(log, "%s", name);
>   		else
> -			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
> +			scsi_log_add(log, "cdb[0]=0x%x, sa=0x%x", cdb0, sa);
>
>   		if ((cdb_len > 0) && (len != cdb_len))
> -			printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len);
> +			scsi_log_add(log, ", in_cdb_len=%d, ext_len=%d",
> +				     len, cdb_len);
>
>   		break;
>   	case MAINTENANCE_IN:
> @@ -343,24 +363,26 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
>   		if (cdb0 < 0xc0) {
>   			name = cdb_byte0_names[cdb0];
>   			if (name)
> -				printk("%s", name);
> +				scsi_log_add(log, "%s", name);
>   			else
> -				printk("cdb[0]=0x%x (reserved)", cdb0);
> +				scsi_log_add(log, "cdb[0]=0x%x (reserved)",
> +					     cdb0);
>   		} else
> -			printk("cdb[0]=0x%x (vendor)", cdb0);
> +			scsi_log_add(log, "cdb[0]=0x%x (vendor)", cdb0);
>   		break;
>   	}
>   	if (fin_name) {
>   		if (name)
> -			printk("%s", name);
> +			scsi_log_add(log, "%s", name);
>   		else
> -			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
> +			scsi_log_add(log, "cdb[0]=0x%x, sa=0x%x", cdb0, sa);
>   	}
>   }
>
>   #else /* ifndef CONFIG_SCSI_CONSTANTS */
>
> -static void print_opcode_name(unsigned char * cdbp, int cdb_len)
> +static void print_opcode_name(unsigned char *cdbp, int cdb_len,
> +			      struct scsi_log_line *log)
>   {
>   	int sa, len, cdb0;
>
> @@ -369,14 +391,16 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
>   	case VARIABLE_LENGTH_CMD:
>   		len = scsi_varlen_cdb_length(cdbp);
>   		if (len < 10) {
> -			printk("short opcode=0x%x command, len=%d "
> -			       "ext_len=%d", cdb0, len, cdb_len);
> +			scsi_log_add(log,
> +				 "short opcode=0x%x command, len=%d ext_len=%d",
> +				 cdb0, len, cdb_len);
>   			break;
>   		}
>   		sa = (cdbp[8] << 8) + cdbp[9];
> -		printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
> +		scsi_log_add(log, "cdb[0]=0x%x, sa=0x%x", cdb0, sa);
>   		if (len != cdb_len)
> -			printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len);
> +			scsi_log_add(log, ", in_cdb_len=%d, ext_len=%d",
> +				     len, cdb_len);
>   		break;
>   	case MAINTENANCE_IN:
>   	case MAINTENANCE_OUT:
> @@ -390,46 +414,50 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len)
>   	case THIRD_PARTY_COPY_IN:
>   	case THIRD_PARTY_COPY_OUT:
>   		sa = cdbp[1] & 0x1f;
> -		printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
> +		scsi_log_add(log, "cdb[0]=0x%x, sa=0x%x", cdb0, sa);
>   		break;
>   	default:
>   		if (cdb0 < 0xc0)
> -			printk("cdb[0]=0x%x", cdb0);
> +			scsi_log_add(log, "cdb[0]=0x%x", cdb0);
>   		else
> -			printk("cdb[0]=0x%x (vendor)", cdb0);
> +			scsi_log_add(log, "cdb[0]=0x%x (vendor)", cdb0);
>   		break;
>   	}
> +	return offset;
>   }
>   #endif
>
>   void __scsi_print_command(unsigned char *cdb)
>   {
> +	struct scsi_log_line log;
>   	int k, len;
>
> -	print_opcode_name(cdb, 0);
> +	scsi_log_line_init(&log);
> +	print_opcode_name(cdb, 0, &log);
>   	len = scsi_command_size(cdb);
>   	/* print out all bytes in cdb */
>   	for (k = 0; k < len; ++k)
> -		printk(" %02x", cdb[k]);
> -	printk("\n");
> +		scsi_log_add(&log, " %02x", cdb[k]);
> +	pr_info("%s\n", log.buf);
>   }
>   EXPORT_SYMBOL(__scsi_print_command);
>
>   void scsi_print_command(struct scsi_cmnd *cmd)
>   {
> +	struct scsi_log_line log;
>   	int k;
>
>   	if (cmd->cmnd == NULL)
>   		return;
>
> -	scmd_printk(KERN_INFO, cmd, "CDB: ");
> -	print_opcode_name(cmd->cmnd, cmd->cmd_len);
> +	scsi_log_line_init(&log);
> +	print_opcode_name(cmd->cmnd, cmd->cmd_len, &log);
>
>   	/* print out all bytes in cdb */
> -	printk(":");
> +	scsi_log_add(&log, ":");
>   	for (k = 0; k < cmd->cmd_len; ++k)
> -		printk(" %02x", cmd->cmnd[k]);
> -	printk("\n");
> +		scsi_log_add(&log, " %02x", cmd->cmnd[k]);
> +	scmd_printk(KERN_INFO, cmd, "CDB: %s\n", log.buf);
>   }
>   EXPORT_SYMBOL(scsi_print_command);
>
> @@ -1368,50 +1396,50 @@ scsi_extd_sense_format(unsigned char asc, unsigned char ascq) {
>   }
>   EXPORT_SYMBOL(scsi_extd_sense_format);
>
> -void
> -scsi_show_extd_sense(unsigned char asc, unsigned char ascq)
> +void scsi_show_extd_sense(unsigned char asc, unsigned char ascq,
> +			  struct scsi_log_line *log)
>   {
>           const char *extd_sense_fmt = scsi_extd_sense_format(asc, ascq);
>
>   	if (extd_sense_fmt) {
>   		if (strstr(extd_sense_fmt, "%x")) {
> -			printk("Add. Sense: ");
> -			printk(extd_sense_fmt, ascq);
> +			scsi_log_add(log, "Add. Sense: ");
> +			scsi_log_add(log, extd_sense_fmt, ascq);
>   		} else
> -			printk("Add. Sense: %s", extd_sense_fmt);
> +			scsi_log_add(log, "Add. Sense: %s", extd_sense_fmt);
>   	} else {
>   		if (asc >= 0x80)
> -			printk("<<vendor>> ASC=0x%x ASCQ=0x%x", asc,
> -			       ascq);
> +			scsi_log_add(log, "<<vendor>> ASC=0x%x ASCQ=0x%x",
> +				     asc, ascq);
>   		if (ascq >= 0x80)
> -			printk("ASC=0x%x <<vendor>> ASCQ=0x%x", asc,
> -			       ascq);
> +			scsi_log_add(log, "ASC=0x%x <<vendor>> ASCQ=0x%x",
> +				     asc, ascq);
>   		else
> -			printk("ASC=0x%x ASCQ=0x%x", asc, ascq);
> +			scsi_log_add(log, "ASC=0x%x ASCQ=0x%x", asc, ascq);
>   	}
>
> -	printk("\n");
> +	scsi_log_add(log, "\n");
>   }
>   EXPORT_SYMBOL(scsi_show_extd_sense);
>
>   void
> -scsi_show_sense_hdr(struct scsi_sense_hdr *sshdr)
> +scsi_show_sense_hdr(struct scsi_sense_hdr *sshdr, struct scsi_log_line *log)
>   {
>   	const char *sense_txt;
>
>   	sense_txt = scsi_sense_key_string(sshdr->sense_key);
>   	if (sense_txt)
> -		printk("Sense Key : %s ", sense_txt);
> +		scsi_log_add(log, "Sense Key : %s ", sense_txt);
>   	else
> -		printk("Sense Key : 0x%x ", sshdr->sense_key);
> +		scsi_log_add(log, "Sense Key : 0x%x ", sshdr->sense_key);
>
> -	printk("%s", scsi_sense_is_deferred(sshdr) ? "[deferred] " :
> -	       "[current] ");
> +	scsi_log_add(log, "%s", scsi_sense_is_deferred(sshdr) ?
> +		     "[deferred] " : "[current] ");
>
>   	if (sshdr->response_code >= 0x72)
> -		printk("[descriptor]");
> +		scsi_log_add(log, "[descriptor]");
>
> -	printk("\n");
> +	scsi_log_add(log, "\n");
>   }
>   EXPORT_SYMBOL(scsi_show_sense_hdr);
>
> @@ -1421,10 +1449,15 @@ EXPORT_SYMBOL(scsi_show_sense_hdr);
>   void
>   scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr)
>   {
> -	printk(KERN_INFO "%s: ", name);
> -	scsi_show_sense_hdr(sshdr);
> -	printk(KERN_INFO "%s: ", name);
> -	scsi_show_extd_sense(sshdr->asc, sshdr->ascq);
> +	struct scsi_log_line log;
> +
> +	scsi_log_line_init(&log);
> +	scsi_show_sense_hdr(sshdr, &log);
> +	pr_info("%s: %s", name, log.buf);
> +
> +	scsi_log_line_init(&log);
> +	scsi_show_extd_sense(sshdr->asc, sshdr->ascq, &log);
> +	pr_info("%s: %s", name, log.buf);
>   }
>   EXPORT_SYMBOL(scsi_print_sense_hdr);
>
> @@ -1435,16 +1468,22 @@ void
>   scsi_cmd_print_sense_hdr(struct scsi_cmnd *scmd, const char *desc,
>   			  struct scsi_sense_hdr *sshdr)
>   {
> -	scmd_printk(KERN_INFO, scmd, "%s: ", desc);
> -	scsi_show_sense_hdr(sshdr);
> -	scmd_printk(KERN_INFO, scmd, "%s: ", desc);
> -	scsi_show_extd_sense(sshdr->asc, sshdr->ascq);
> +	struct scsi_log_line log;
> +
> +	scsi_log_line_init(&log);
> +	scsi_show_sense_hdr(sshdr, &log);
> +	scmd_printk(KERN_INFO, scmd, "%s: %s", desc, log.buf);
> +
> +	scsi_log_line_init(&log);
> +	scsi_show_extd_sense(sshdr->asc, sshdr->ascq, &log);
> +	scmd_printk(KERN_INFO, scmd, "%s: %s", desc, log.buf);
>   }
>   EXPORT_SYMBOL(scsi_cmd_print_sense_hdr);
>
>   static void
>   scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len,
> -		       struct scsi_sense_hdr *sshdr)
> +			 struct scsi_sense_hdr *sshdr,
> +			 struct scsi_log_line *log)
>   {
>   	int k, num, res;
>
> @@ -1452,16 +1491,13 @@ scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len,
>   	if (0 == res) {
>   		/* this may be SCSI-1 sense data */
>   		num = (sense_len < 32) ? sense_len : 32;
> -		printk("Unrecognized sense data (in hex):");
> +		scsi_log_add(log, "Unrecognized sense data (in hex):");
>   		for (k = 0; k < num; ++k) {
> -			if (0 == (k % 16)) {
> -				printk("\n");
> -				printk(KERN_INFO "        ");
> -			}
> -			printk("%02x ", sense_buffer[k]);
> +			if (0 == (k % 16))
> +				scsi_log_add(log, "\n        ");
> +			scsi_log_add(log, "%02x ", sense_buffer[k]);
>   		}
> -		printk("\n");
> -		return;
> +		scsi_log_add(log, "\n");
>   	}
>   }
>
> @@ -1531,13 +1567,17 @@ void __scsi_print_sense(const char *name, const unsigned char *sense_buffer,
>   			int sense_len)
>   {
>   	struct scsi_sense_hdr sshdr;
> +	struct scsi_log_line log;
>
> -	printk(KERN_INFO "%s: ", name);
> -	scsi_decode_sense_buffer(sense_buffer, sense_len, &sshdr);
> -	scsi_show_sense_hdr(&sshdr);
> +	scsi_log_line_init(&log);
> +	scsi_decode_sense_buffer(sense_buffer, sense_len, &sshdr, &log);
> +	scsi_show_sense_hdr(&sshdr, &log);
> +	pr_info("%s: %s", name, log.buf);
>   	scsi_decode_sense_extras(sense_buffer, sense_len, &sshdr);
> -	printk(KERN_INFO "%s: ", name);
> -	scsi_show_extd_sense(sshdr.asc, sshdr.ascq);
> +
> +	scsi_log_line_init(&log);
> +	scsi_show_extd_sense(sshdr.asc, sshdr.ascq, &log);
> +	pr_info("%s: %s", name, log.buf);
>   }
>   EXPORT_SYMBOL(__scsi_print_sense);
>
> @@ -1545,15 +1585,19 @@ EXPORT_SYMBOL(__scsi_print_sense);
>   void scsi_print_sense(char *name, struct scsi_cmnd *cmd)
>   {
>   	struct scsi_sense_hdr sshdr;
> +	struct scsi_log_line log;
>
> -	scmd_printk(KERN_INFO, cmd, " ");
> +	scsi_log_line_init(&log);
>   	scsi_decode_sense_buffer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE,
> -				 &sshdr);
> -	scsi_show_sense_hdr(&sshdr);
> +				 &sshdr, &log);
> +	scsi_show_sense_hdr(&sshdr, &log);
> +	scmd_printk(KERN_INFO, cmd, "%s", log.buf);
>   	scsi_decode_sense_extras(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE,
>   				 &sshdr);
> -	scmd_printk(KERN_INFO, cmd, " ");
> -	scsi_show_extd_sense(sshdr.asc, sshdr.ascq);
> +
> +	scsi_log_line_init(&log);
> +	scsi_show_extd_sense(sshdr.asc, sshdr.ascq, &log);
> +	scmd_printk(KERN_INFO, cmd, "%s", log.buf);
>   }
>   EXPORT_SYMBOL(scsi_print_sense);
>
> @@ -1572,31 +1616,33 @@ static const char * const driverbyte_table[]={
>   "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"};
>   #define NUM_DRIVERBYTE_STRS ARRAY_SIZE(driverbyte_table)
>
> -void scsi_show_result(int result)
> +void scsi_show_result(int result, struct scsi_log_line *log)
>   {
>   	int hb = host_byte(result);
>   	int db = driver_byte(result);
>
> -	printk("Result: hostbyte=%s driverbyte=%s\n",
> +	scsi_log_add(log, "Result: hostbyte=%s driverbyte=%s\n",
>   	       (hb < NUM_HOSTBYTE_STRS ? hostbyte_table[hb]     : "invalid"),
>   	       (db < NUM_DRIVERBYTE_STRS ? driverbyte_table[db] : "invalid"));
>   }
>
>   #else
>
> -void scsi_show_result(int result)
> +void scsi_show_result(int result, struct scsi_log_line *log)
>   {
> -	printk("Result: hostbyte=0x%02x driverbyte=0x%02x\n",
> -	       host_byte(result), driver_byte(result));
> +	scsi_log_add(log, "Result: hostbyte=0x%02x driverbyte=0x%02x\n",
> +		     host_byte(result), driver_byte(result));
>   }
>
>   #endif
>   EXPORT_SYMBOL(scsi_show_result);
>
> -
>   void scsi_print_result(struct scsi_cmnd *cmd)
>   {
> -	scmd_printk(KERN_INFO, cmd, " ");
> -	scsi_show_result(cmd->result);
> +	struct scsi_log_line log;
> +
> +	scsi_log_line_init(&log);
> +	scsi_show_result(cmd->result, &log);
> +	scmd_printk(KERN_INFO, cmd, "%s", log.buf);
>   }
>   EXPORT_SYMBOL(scsi_print_result);
> diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
> index d8afec8..40b2b23 100644
> --- a/drivers/scsi/scsi.c
> +++ b/drivers/scsi/scsi.c
> @@ -550,10 +550,13 @@ void scsi_log_send(struct scsi_cmnd *cmd)
>   		level = SCSI_LOG_LEVEL(SCSI_LOG_MLQUEUE_SHIFT,
>   				       SCSI_LOG_MLQUEUE_BITS);
>   		if (level > 1) {
> -			scmd_printk(KERN_INFO, cmd, "Send: ");
> +			struct scsi_log_line log;
> +
> +			scsi_log_line_init(&log);
>   			if (level > 2)
> -				printk("0x%p ", cmd);
> -			printk("\n");
> +				scsi_log_add(&log, "0x%p ", cmd);
> +			scsi_log_add(&log, "\n");
> +			scmd_printk(KERN_INFO, cmd, "Send: %s", log.buf);
>   			scsi_print_command(cmd);
>   			if (level > 3) {
>   				printk(KERN_INFO "buffer = 0x%p, bufflen = %d,"
> @@ -587,35 +590,38 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
>   				       SCSI_LOG_MLCOMPLETE_BITS);
>   		if (((level > 0) && (cmd->result || disposition != SUCCESS)) ||
>   		    (level > 1)) {
> -			scmd_printk(KERN_INFO, cmd, "Done: ");
> +			struct scsi_log_line log;
> +
> +			scsi_log_line_init(&log);
>   			if (level > 2)
> -				printk("0x%p ", cmd);
> +				scsi_log_add(&log, "0x%p ", cmd);
>   			/*
>   			 * Dump truncated values, so we usually fit within
>   			 * 80 chars.
>   			 */
>   			switch (disposition) {
>   			case SUCCESS:
> -				printk("SUCCESS\n");
> +				scsi_log_add(&log, "SUCCESS\n");
>   				break;
>   			case NEEDS_RETRY:
> -				printk("RETRY\n");
> +				scsi_log_add(&log, "RETRY\n");
>   				break;
>   			case ADD_TO_MLQUEUE:
> -				printk("MLQUEUE\n");
> +				scsi_log_add(&log, "MLQUEUE\n");
>   				break;
>   			case FAILED:
> -				printk("FAILED\n");
> +				scsi_log_add(&log, "FAILED\n");
>   				break;
>   			case TIMEOUT_ERROR:
>   				/*
>   				 * If called via scsi_times_out.
>   				 */
> -				printk("TIMEOUT\n");
> +				scsi_log_add(&log, "TIMEOUT\n");
>   				break;
>   			default:
> -				printk("UNKNOWN\n");
> +				scsi_log_add(&log, "UNKNOWN\n");
>   			}
> +			scmd_printk(KERN_INFO, cmd, "Done: %s", log.buf);
>   			scsi_print_result(cmd);
>   			scsi_print_command(cmd);
>   			if (status_byte(cmd->result) & CHECK_CONDITION)
> diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
> index 470954a..64d79b2 100644
> --- a/drivers/scsi/sd.c
> +++ b/drivers/scsi/sd.c
> @@ -3275,15 +3275,22 @@ module_exit(exit_sd);
>   static void sd_print_sense_hdr(struct scsi_disk *sdkp,
>   			       struct scsi_sense_hdr *sshdr)
>   {
> -	sd_printk(KERN_INFO, sdkp, " ");
> -	scsi_show_sense_hdr(sshdr);
> -	sd_printk(KERN_INFO, sdkp, " ");
> -	scsi_show_extd_sense(sshdr->asc, sshdr->ascq);
> +	struct scsi_log_line log;
> +
> +	scsi_log_line_init(&log);
> +	scsi_show_sense_hdr(sshdr, &log);
> +	sd_printk(KERN_INFO, sdkp, "%s", log.buf);
> +	scsi_log_line_init(&log);
> +	scsi_show_extd_sense(sshdr->asc, sshdr->ascq, &log);
> +	sd_printk(KERN_INFO, sdkp, "%s", log.buf);
>   }
>
>   static void sd_print_result(struct scsi_disk *sdkp, int result)
>   {
> -	sd_printk(KERN_INFO, sdkp, " ");
> -	scsi_show_result(result);
> +	struct scsi_log_line log;
> +
> +	scsi_log_line_init(&log);
> +	scsi_show_result(result, &log);
> +	sd_printk(KERN_INFO, sdkp, "%s", log.buf);
>   }
>
> diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
> index e89844c..3d8f39c 100644
> --- a/include/scsi/scsi_dbg.h
> +++ b/include/scsi/scsi_dbg.h
> @@ -1,13 +1,25 @@
>   #ifndef _SCSI_SCSI_DBG_H
>   #define _SCSI_SCSI_DBG_H
>
> +/* Maximum size of a local buffer for structured printk */
> +#define SCSI_LOG_LINE_MAX 512
> +
> +/* Local buffer for structured printk */
> +struct scsi_log_line {
> +	int offset;
> +	char buf[SCSI_LOG_LINE_MAX];
> +};
> +
>   struct scsi_cmnd;
>   struct scsi_sense_hdr;
>
> +extern void scsi_log_add(struct scsi_log_line *log, const char *fmt, ...);
>   extern void scsi_print_command(struct scsi_cmnd *);
>   extern void __scsi_print_command(unsigned char *);
> -extern void scsi_show_extd_sense(unsigned char, unsigned char);
> -extern void scsi_show_sense_hdr(struct scsi_sense_hdr *);
> +extern void scsi_show_extd_sense(unsigned char, unsigned char,
> +				 struct scsi_log_line *log);
> +extern void scsi_show_sense_hdr(struct scsi_sense_hdr *,
> +				struct scsi_log_line *log);
>   extern void scsi_print_sense_hdr(const char *, struct scsi_sense_hdr *);
>   extern void scsi_cmd_print_sense_hdr(struct scsi_cmnd *, const char *,
>   				     struct scsi_sense_hdr *);
> @@ -15,10 +27,15 @@ extern void scsi_print_sense(char *, struct scsi_cmnd *);
>   extern void __scsi_print_sense(const char *name,
>   			       const unsigned char *sense_buffer,
>   			       int sense_len);
> -extern void scsi_show_result(int);
> +extern void scsi_show_result(int, struct scsi_log_line *log);
>   extern void scsi_print_result(struct scsi_cmnd *);
>   extern void scsi_print_status(unsigned char);
>   extern const char *scsi_sense_key_string(unsigned char);
>   extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
>
> +static inline void scsi_log_line_init(struct scsi_log_line *log)
> +{
> +	log->offset = 0;
> +}
> +
>   #endif /* _SCSI_SCSI_DBG_H */
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@...r.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

-- 
Yoshihiro YUNOMAE
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: yoshihiro.yunomae.ez@...achi.com


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ