aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2012-09-18 12:39:47 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2012-09-18 12:39:47 +0000
commitd2105f93d0db6ddbdcf262be13fbabe4000e6149 (patch)
tree33ac0c6d8f069af2677c3e6a0fa2d7371a25d158
parent19776eb6029a597dcec752989933a8c12a9be0a8 (diff)
downloadsg3_utils-d2105f93d0db6ddbdcf262be13fbabe4000e6149.tar.gz
sg_copy_results: source and manpage updates
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@455 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--CREDITS2
-rw-r--r--ChangeLog2
-rw-r--r--README2
-rw-r--r--debian/changelog2
-rw-r--r--doc/sg_copy_results.856
-rw-r--r--sg3_utils.spec2
-rw-r--r--src/sg_copy_results.c72
7 files changed, 113 insertions, 25 deletions
diff --git a/CREDITS b/CREDITS
index cd27d11c..7f9dfa4e 100644
--- a/CREDITS
+++ b/CREDITS
@@ -107,4 +107,4 @@ Trent Piepho <xyzzy at speakeasy dot org> print out some "sense key specific"
Douglas Gilbert
-22nd February 2012
+22nd March 2012
diff --git a/ChangeLog b/ChangeLog
index e9b26c53..3be298e5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,7 @@ Each utility has its own version number, date of last change and
some description at the top of its ".c" file. All utilities in the main
directory have their own "man" pages. There is also a sg3_utils man page.
-Changelog for sg3_utils-1.34 [20120914] [svn: r454]
+Changelog for sg3_utils-1.34 [20120918] [svn: r455]
- sg_xcopy: new dd like utility for extended copy command
- sg_copy_results: new utility for receive copy results
- sg_verify: add 16 byte cdb, bytchk (data-out buffer)
diff --git a/README b/README
index da66a0a5..9a6a4aba 100644
--- a/README
+++ b/README
@@ -373,4 +373,4 @@ See http://sg.danny.cz/sg/tools.html
Douglas Gilbert
-7th September 2012
+18th September 2012
diff --git a/debian/changelog b/debian/changelog
index ce4abd08..baf1c54f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,7 +2,7 @@ sg3-utils (1.34-0.1) unstable; urgency=low
* New upstream version
- -- Douglas Gilbert <dgilbert@interlog.com> Fri, 14 Sep 2012 15:00:00 +0200
+ -- Douglas Gilbert <dgilbert@interlog.com> Tue, 18 Sep 2012 14:00:00 +0200
sg3-utils (1.33-0.1) unstable; urgency=low
diff --git a/doc/sg_copy_results.8 b/doc/sg_copy_results.8
index 68c95cf3..ad6c7c56 100644
--- a/doc/sg_copy_results.8
+++ b/doc/sg_copy_results.8
@@ -9,11 +9,31 @@ sg_copy_results \- sends a SCSI RECEIVE COPY RESULTS command
.SH DESCRIPTION
.\" Add any additional description here
.PP
-This utility is designed to be used after the sg_xcopy utility which
-invokes the SCSI Extended Copy facility (see SPC\-3 revision 23 sections
-6.3 and 6.17). This utility sends a SCSI RECEIVE COPY RESULTS command
-to the given \fIDEVICE\fR and displays the response.
-xxxx
+This utility is designed to query the status of the SCSI Extended Copy
+facility (see SPC\-3 revision 23 sections 6.3 and 6.17), present in
+some modern storage arrays. This utility sends a SCSI RECEIVE COPY
+RESULTS command to the given \fIDEVICE\fR and displays the response.
+.PP
+The command has four distinct modes of operation, distinguished by
+the service action field:
+.TP
+\fBCOPY STATUS\fR
+Displays the current status of the EXTENDED COPY command identified by
+the list id field.
+.TP
+\fBRECEIVE DATA\fR
+Return the held data read by the EXTENDED COPY command identified by
+the list id field. This option is only meaningful if the respective
+segment descriptor are supported.
+.TP
+\fBOPERATING PARAMETERS\fR
+Return copy manager operating parameters. This option is also useful
+to determine if the SCSI Extended Copy facility is supported.
+.TP
+\fBFAILED SEGMENT DETAILS\fR
+Return copy target device sense data and other information about any
+failed segments.
+
.SH OPTIONS
Arguments to long options are mandatory for short options as well.
.TP
@@ -31,6 +51,7 @@ sets the list identifier field to \fIID\fR (default: 0).
.TP
\fB\-p\fR, \fB\-\-params\fR
sets the service action field to OPERATING PARAMETERS [3].
+This is the default.
.TP
\fB\-r\fR, \fB\-\-receive\fR
sets the service action field to RECEIVE DATA [1].
@@ -49,9 +70,30 @@ sets the allocation length field to \fIBTL\fR. It is the byte transfer
length and is the maximum (byte) size of the response. \fIBTL\fR must be
less than 10000 and defaults to 520.
.SH NOTES
-xxxxxxxxx
+Decoding of \fIRECEIVE DATA\fR service action is not implemented.
.SH EXAMPLES
-xxxxxxx Some examples would be useful!
+Query the operating parameters for a device:
+.PP
+# sg_copy_results -p /dev/sdo
+.br
+Receive copy results (report operating parameters):
+ Supports no list identifier: no
+ Maximum target descriptor count: 2
+ Maximum segment descriptor count: 1
+ Maximum descriptor list length: 92 bytes
+ Maximum segment length: 33553920 bytes
+ Inline data not supported
+ Held data limit: 0 bytes
+ Maximum stream device transfer size: 0 bytes
+ Total concurrent copies: 0
+ Maximum concurrent copies: 255
+ Data segment granularity: 512 bytes
+ Inline data granularity: 1 bytes
+ Held data granularity: 1 bytes
+ Implemented descriptor list:
+ Segment descriptor 0x02: Copy from block device to block device
+ Target descriptor 0xe4: Identification descriptor
+
.SH EXIT STATUS
The exit status of sg_copy_results is 0 when it is successful. Otherwise see
the sg3_utils(8) man page.
diff --git a/sg3_utils.spec b/sg3_utils.spec
index 0e1db854..f648ce14 100644
--- a/sg3_utils.spec
+++ b/sg3_utils.spec
@@ -79,7 +79,7 @@ fi
%{_libdir}/*.la
%changelog
-* Fri Sep 14 2012 - dgilbert at interlog dot com
+* Tue Sep 18 2012 - dgilbert at interlog dot com
- add sg_xcopy and sg_copy_results; track t10 changes
* sg3_utils-1.34
diff --git a/src/sg_copy_results.c b/src/sg_copy_results.c
index 5b986958..2a3bae81 100644
--- a/src/sg_copy_results.c
+++ b/src/sg_copy_results.c
@@ -47,10 +47,10 @@ static char * version_str = "1.1 20120905";
struct descriptor_type {
int code;
- char desc[];
+ char desc[124];
};
-struct descriptor_type target_descriptor_codes [] = {
+struct descriptor_type target_descriptor_codes[] = {
{ 0xe0, "Fibre Channel N_Port_Name"},
{ 0xe1, "Fibre Channel N_port_ID"},
{ 0xe2, "Fibre Channesl N_port_ID with N_Port_Name checking"},
@@ -62,7 +62,8 @@ struct descriptor_type target_descriptor_codes [] = {
{ 0xe8, "IEEE 1395 EUI-64" },
{ 0xe9, "SAS Serial SCSI Protocol" },
{ 0xea, "IPv6" },
- { 0xeb, "IP Copy Service" }
+ { 0xeb, "IP Copy Service" },
+ { -1, "" }
};
struct descriptor_type segment_descriptor_codes [] = {
@@ -93,10 +94,40 @@ struct descriptor_type segment_descriptor_codes [] = {
{ 0x13, "Image copy from sequential-access device to sequential-access "
"device" },
{ 0x14, "Register persistent reservation key" },
- { 0x15, "Third party persistent reservations source I_T nexus" }
+ { 0x15, "Third party persistent reservations source I_T nexus" },
+ { -1, "" }
};
static void
+scsi_failed_segment_details(unsigned char *rcBuff, unsigned int rcBuffLen)
+{
+ unsigned int len;
+ char senseBuff[1024];
+ int senseLen;
+
+ if (rcBuffLen < 4) {
+ fprintf(stderr, " <<not enough data to procedd report>>\n");
+ return;
+ }
+ len = (rcBuff[0] << 24) | (rcBuff[1] << 16) | (rcBuff[2] << 8) |
+ rcBuff[3];
+ if (len + 3 > rcBuffLen) {
+ fprintf(stderr, " <<report too long for internal buffer,"
+ " output truncated\n");
+ }
+ if (len < 52) {
+ fprintf(stderr, " <<no segment details, response data length %d\n",
+ len);
+ return;
+ }
+ printf("Receive copy results (failed segment details):\n");
+ printf(" Extended copy command status: %d\n", rcBuff[56]);
+ senseLen = (rcBuff[58] << 8) | rcBuff[59];
+ sg_get_sense_str(" ", &rcBuff[60], senseLen, 0, 1024, senseBuff);
+ printf("%s", senseBuff);
+}
+
+static void
scsi_copy_status(unsigned char *rcBuff, unsigned int rcBuffLen)
{
unsigned int len;
@@ -181,22 +212,33 @@ scsi_operating_parameters(unsigned char *rcBuff, unsigned int rcBuffLen)
printf(" Held data granularity: %lu bytes\n",
(unsigned long)(1 << rcBuff[39]));
- printf(" Implemented descriptor list:\n ");
+ printf(" Implemented descriptor list:\n");
for (n = 0; n < rcBuff[43]; n++) {
int code = rcBuff[44 + n];
if (code < 0x16) {
- printf("Segment descriptor 0x%02x: %s\n",
- code, segment_descriptor_codes[code].desc);
+ struct descriptor_type *seg_desc = segment_descriptor_codes;
+ while (strlen(seg_desc->desc)) {
+ if (seg_desc->code == code)
+ break;
+ seg_desc++;
+ }
+ printf(" Segment descriptor 0x%02x: %s\n", code,
+ strlen(seg_desc->desc) ? seg_desc->desc : "Reserved");
} else if (code < 0xc0) {
- printf("Segment descriptor 0x%02x: Reserved\n", code);
+ printf(" Segment descriptor 0x%02x: Reserved\n", code);
} else if (code < 0xe0) {
- printf("Vendor specific descriptor 0x%02x\n", code);
- } else if (code < 0xec) {
- printf("Target descriptor 0x%02x: %s\n",
- code, target_descriptor_codes[code - 0xe0].desc);
+ printf(" Vendor specific descriptor 0x%02x\n", code);
} else {
- printf("Target descriptor 0x%02x: Reserved\n", code);
+ struct descriptor_type *tgt_desc = target_descriptor_codes;
+
+ while (strlen(tgt_desc->desc)) {
+ if (tgt_desc->code == code)
+ break;
+ tgt_desc++;
+ }
+ printf(" Target descriptor 0x%02x: %s\n", code,
+ strlen(tgt_desc->desc) ? tgt_desc->desc : "Reserved");
}
}
printf("\n");
@@ -396,6 +438,10 @@ main(int argc, char * argv[])
goto finish;
}
switch (sa) {
+ case 4: /* Failed segment details */
+ scsi_failed_segment_details(cpResultBuff, xfer_len);
+ res = 0;
+ break;
case 3: /* Operating parameters */
scsi_operating_parameters(cpResultBuff, xfer_len);
res = 0;