Code for SCSI transaction log in dvd+rw-tools
Hi,
attached is a patch to let dvd+rw-tools report its SCSI transactions
on stderr.
The patch is based on growisofs-7.1.tar.gz of march 2008.
At least one of the changes is already addressed by Debian's dvd+rw-tools:
+/* To compensate bit rot: "INT_MAX was not declared in this scope"
+*/
+#include <limits.h>
+
Another noteworthy aspect is that the log cannot be enabled or disabled
at run time, but only at compile time. A new private variable of
class Scsi_Command and a setter method for it would be an improvement.
Have a nice day :)
Thomas
--- dvd+rw-tools-7.1.orig/transport.hxx 2008-03-01 11:34:43.000000000 +0100
+++ dvd+rw-tools-7.1.scsi_log/transport.hxx 2018-03-23 09:03:00.466581766 +0100
@@ -6,6 +6,12 @@
// For further details see http://fy.chalmers.se/~appro/linux/DVD+RW/
//
+
+/* If this is defined, then the SCSI transactions are logged to stderr.
+*/
+#define Libburnish_scsi_log_to_stderR 1
+
+
#if defined(__unix) || defined(__unix__)
#include <stdio.h>
#include <stdlib.h>
@@ -17,6 +23,10 @@
#include <poll.h>
#include <sys/time.h>
+/* To compensate bit rot: "INT_MAX was not declared in this scope"
+*/
+#include <limits.h>
+
inline long getmsecs()
{ struct timeval tv;
gettimeofday (&tv,NULL);
@@ -281,8 +291,17 @@ public:
{ sg_io.dxferp = buf;
sg_io.dxfer_len = sz;
sg_io.dxfer_direction = use_sg_io[dir];
+
+#ifdef Libburnish_scsi_log_to_stderR
+ show_cmd_text(&sg_io, stderr, 0);
+#endif /* Libburnish_scsi_log_to_stderR */
+
if (ioctl (fd,SG_IO,&sg_io)) return -1;
+#ifdef Libburnish_scsi_log_to_stderR
+ show_cmd_reply(&sg_io, stderr, 0);
+#endif /* Libburnish_scsi_log_to_stderR */
+
#if !KERNEL_BROKEN
if ((sg_io.info&SG_INFO_OK_MASK) != SG_INFO_OK)
#else
@@ -312,6 +331,136 @@ public:
}
return ret;
}
+
+#ifdef Libburnish_scsi_log_to_stderR
+#ifdef SG_IO
+ /* This is my own code from libburn adapted to Linux SG_IO rather than
+ the generic command structure of libburn.
+ Permission is granted to use it in any way.
+ Thomas Schmitt, scdbackup@gmx.net, 2009
+ */
+ char *scsi_command_name(unsigned int c, int flag)
+ {
+ switch (c) {
+ case 0x00:
+ return (char *) "TEST UNIT READY";
+ case 0x03:
+ return (char *) "REQUEST SENSE";
+ case 0x04:
+ return (char *) "FORMAT UNIT";
+ case 0x1b:
+ return (char *) "START/STOP UNIT";
+ case 0x12:
+ return (char *) "INQUIRY";
+ case 0x1e:
+ return (char *) "PREVENT/ALLOW MEDIA REMOVAL";
+ case 0x23:
+ return (char *) "READ FORMAT CAPACITIES";
+ case 0x25:
+ return (char *) "READ CAPACITY";
+ case 0x28:
+ return (char *) "READ(10)";
+ case 0x2a:
+ return (char *) "WRITE(10)";
+ case 0x35:
+ return (char *) "SYNCHRONIZE CACHE";
+ case 0x43:
+ return (char *) "READ TOC/PMA/ATIP";
+ case 0x46:
+ return (char *) "GET CONFIGURATION";
+ case 0x4a:
+ return (char *) "GET EVENT STATUS NOTIFICATION";
+ case 0x51:
+ return (char *) "READ DISC INFORMATION";
+ case 0x52:
+ return (char *) "READ TRACK INFORMATION";
+ case 0x53:
+ return (char *) "RESERVE TRACK";
+ case 0x54:
+ return (char *) "SEND OPC INFORMATION";
+ case 0x55:
+ return (char *) "MODE SELECT";
+ case 0x5a:
+ return (char *) "MODE SENSE";
+ case 0x5b:
+ return (char *) "CLOSE TRACK/SESSION";
+ case 0x5c:
+ return (char *) "READ BUFFER CAPACITY";
+ case 0x5d:
+ return (char *) "SEND CUE SHEET";
+ case 0xa1:
+ return (char *) "BLANK";
+ case 0xaa:
+ return (char *) "WRITE(12)";
+ case 0xac:
+ return (char *) "GET PERFORMANCE";
+ case 0xad:
+ return (char *) "READ DISC STRUCTURE";
+ case 0xb6:
+ return (char *) "SET STREAMING";
+ case 0xbb:
+ return (char *) "SET CD SPEED";
+ case 0xbe:
+ return (char *) "READ CD";
+ }
+ return (char *) "(NOT IN COMMAND LIST)";
+ }
+ int show_cmd_text(sg_io_hdr_t *s, FILE *fp, int flag)
+ {
+ int i;
+
+ fprintf(fp, "\n%s\n",
+ scsi_command_name((unsigned int) s->cmdp[0], 0));
+ for(i = 0; i < 16 && i < s->cmd_len; i++)
+ fprintf(fp, "%2.2x ", s->cmdp[i]);
+ if (i > 0)
+ fprintf(fp, "\n");
+ if (flag & 1)
+ return 1;
+ if (s->cmdp[0] == 0x2A) { /* WRITE 10 */
+ ;
+ } else if (s->cmdp[0] == 0xAA) { /* WRITE 12 */
+ ;
+ } else if (s->dxfer_direction == SG_DXFER_TO_DEV) {
+ fprintf(fp, "To drive: %db\n", s->dxfer_len);
+ for (i = 0; i < s->dxfer_len; i++)
+ fprintf(fp, "%2.2x%c", ((unsigned char *) s->dxferp)[i],
+ ((i % 20) == 19 ? '\n' : ' '));
+ if (i % 20)
+ fprintf(fp, "\n");
+ }
+ return 1;
+ }
+ int show_cmd_reply(sg_io_hdr_t *s, FILE *fp, int flag)
+ {
+ int i;
+ if (s->sb_len_wr) {
+ fprintf(fp,
+ "+++ key=%X asc=%2.2Xh ascq=%2.2Xh (%6d ms)\n",
+ ((unsigned char *) s->sbp)[2],
+ ((unsigned char *) s->sbp)[12],
+ ((unsigned char *) s->sbp)[13], s->duration);
+ return 0;
+ }
+ if (s->dxfer_direction != SG_DXFER_FROM_DEV) {
+ /* No reply expected */;
+ } else if (s->cmdp[0] == 0x28 || s->cmdp[0] == 0x3C ||
+ s->cmdp[0] == 0xA8 || s->cmdp[0] == 0xBE) {
+ /* READ commands */;
+ } else {
+ fprintf(fp, "From drive: %db\n", s->dxfer_len);
+ for (i = 0; i < s->dxfer_len; i++)
+ fprintf(fp, "%2.2x%c", ((unsigned char *) s->dxferp)[i],
+ ((i % 20) == 19 ? '\n' : ' '));
+ if (i % 20)
+ fprintf(fp, "\n");
+ }
+ fprintf(fp,"%6d ms\n", s->duration);
+ return 1;
+ }
+#endif /* SG_IO */
+#endif /* Libburnish_scsi_log_to_stderR */
+
int umount(int f=-1)
{ struct stat fsb,msb;
struct mntent *mb;
Reply to: