]> git.wh0rd.org - dump.git/commitdiff
Fix rmt ioctl command with UNIX clients (mtio opcodes Linux incompatibilities)
authorStelian Pop <stelian@popies.net>
Mon, 15 Apr 2002 11:57:27 +0000 (11:57 +0000)
committerStelian Pop <stelian@popies.net>
Mon, 15 Apr 2002 11:57:27 +0000 (11:57 +0000)
CHANGES
rmt/rmt.8.in
rmt/rmt.c

diff --git a/CHANGES b/CHANGES
index 82097e91c703ad7632637169a9b129c805aba9cc..e055370d6215a46659d5efab62badbe485342304 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,16 @@
-$Id: CHANGES,v 1.172 2002/04/12 12:45:50 stelian Exp $
+$Id: CHANGES,v 1.173 2002/04/15 11:57:27 stelian Exp $
 
 
+Changes between versions 0.4b28 and 0.4b29 (released ??????????????)
+====================================================================
+
+1.     Fixed a problem in the rmt ioctl command, where ioctl's issued from
+       non Linux clients were misinterpreted. The description of the problem
+       (incompatible numbering in Linux mtio opcodes) is documented at
+       ftp://ftp.fokus.gmd.de/pub/unix/star/README.mtio . Thanks to
+       Jörg Schilling <schilling@fokus.gmd.de> for reporting this bug and
+       providing an excellent, cross-platform replacement for rmt in his
+       star package.
+       
 Changes between versions 0.4b27 and 0.4b28 (released April 12, 2002)
 ====================================================================
 
 Changes between versions 0.4b27 and 0.4b28 (released April 12, 2002)
 ====================================================================
 
index be863343c2a21fa835dc79b0843acdaeee7b3845..6e93213178e2fcbce436b84b5d24eba618757e4b 100644 (file)
@@ -29,7 +29,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\"     $Id: rmt.8.in,v 1.7 2002/01/16 09:32:14 stelian Exp $
+.\"     $Id: rmt.8.in,v 1.8 2002/04/15 11:57:29 stelian Exp $
 .\"
 .Dd __DATE__
 .Dt RMT 8
 .\"
 .Dd __DATE__
 .Dt RMT 8
 .Sh SYNOPSIS
 .Nm rmt
 .Sh DESCRIPTION
 .Sh SYNOPSIS
 .Nm rmt
 .Sh DESCRIPTION
-.Nm Rmt
-is a program used by the remote dump and restore programs
-in manipulating a magnetic tape drive through an interprocess
+.Nm rmt
+is a program used by the remote 
+.Nm dump,
+.Nm restore 
+or
+.Nm tar
+programs in manipulating a magnetic tape drive through an interprocess
 communication connection.
 communication connection.
-.Nm Rmt
+.Nm rmt
 is normally started up with an
 .Xr rexec 3
 or
 is normally started up with an
 .Xr rexec 3
 or
@@ -53,12 +57,12 @@ call.
 .Pp
 The 
 .Nm
 .Pp
 The 
 .Nm
-program accepts requests specific to the manipulation of
-magnetic tapes, performs the commands, then responds with
-a status indication.  All responses are in
+program accepts requests specific to the manipulation of magnetic tapes, 
+performs the commands, then responds with a status indication.  
+All responses are in
 .Tn ASCII
 .Tn ASCII
-and in
-one of two forms. 
+and in one of the following two forms.
+.Pp
 Successful commands have responses of:
 .Bd -filled -offset indent
 .Sm off
 Successful commands have responses of:
 .Bd -filled -offset indent
 .Sm off
@@ -66,10 +70,12 @@ Successful commands have responses of:
 .Sm on
 .Ed
 .Pp
 .Sm on
 .Ed
 .Pp
-.Ar Number
+where
+.Ar number
 is an
 .Tn ASCII
 representation of a decimal number.
 is an
 .Tn ASCII
 representation of a decimal number.
+.Pp
 Unsuccessful commands are responded to with:
 .Bd -filled -offset indent
 .Sm off
 Unsuccessful commands are responded to with:
 .Bd -filled -offset indent
 .Sm off
@@ -80,15 +86,15 @@ Unsuccessful commands are responded to with:
 .Sm on
 .Ed
 .Pp
 .Sm on
 .Ed
 .Pp
-.Ar Error-number
-is one of the possible error
-numbers described in
+where
+.Ar error-number
+is one of the possible error numbers described in
 .Xr intro 2
 and
 .Ar error-message
 .Xr intro 2
 and
 .Ar error-message
-is the corresponding error string as printed
-from a call to
+is the corresponding error string as printed from a call to
 .Xr perror 3 .
 .Xr perror 3 .
+.Pp
 The protocol is comprised of the
 following commands, which are sent as indicated - no spaces are supplied
 between the command and its arguments, or between its arguments, and
 The protocol is comprised of the
 following commands, which are sent as indicated - no spaces are supplied
 between the command and its arguments, or between its arguments, and
@@ -99,6 +105,7 @@ indicates that a newline should be supplied:
 .It Xo Sy \&O Ar device
 .No \en Ar mode No \en
 .Xc
 .It Xo Sy \&O Ar device
 .No \en Ar mode No \en
 .Xc
+.Sm on
 Open the specified 
 .Ar device
 using the indicated
 Open the specified 
 .Ar device
 using the indicated
@@ -108,16 +115,18 @@ is a full pathname and
 .Ar mode
 is an
 .Tn ASCII
 .Ar mode
 is an
 .Tn ASCII
-representation of a decimal
-number suitable for passing to
+representation of a decimal number suitable for passing to
 .Xr open 2 .
 .Xr open 2 .
-If a device had already been opened, it is
-closed before a new open is performed.
+If a device had already been opened, it is closed before a 
+new open is performed.
+.Sm off
 .It Xo Sy C Ar device No \en
 .Xc
 .It Xo Sy C Ar device No \en
 .Xc
+.Sm on
 Close the currently open device.  The
 .Ar device
 specified is ignored.
 Close the currently open device.  The
 .Ar device
 specified is ignored.
+.Sm off
 .It Xo Sy L
 .Ar whence No \en
 .Ar offset No \en
 .It Xo Sy L
 .Ar whence No \en
 .Ar offset No \en
@@ -133,13 +142,11 @@ call.
 .It Sy W Ar count No \en
 .Sm on
 Write data onto the open device.
 .It Sy W Ar count No \en
 .Sm on
 Write data onto the open device.
-.Nm Rmt
+.Nm rmt
 reads
 .Ar count
 reads
 .Ar count
-bytes from the connection, aborting if
-a premature end-of-file is encountered.
-The response value is that returned from
-the
+bytes from the connection, aborting if a premature end-of-file is encountered.
+The response value is that returned from the
 .Xr write 2
 call.
 .Sm off
 .Xr write 2
 call.
 .Sm off
@@ -152,17 +159,15 @@ If
 .Ar count
 exceeds the size of the data buffer (10 kilobytes), it is
 truncated to the data buffer size.
 .Ar count
 exceeds the size of the data buffer (10 kilobytes), it is
 truncated to the data buffer size.
-.Nm Rmt
+.Nm rmt
 then performs the requested 
 .Xr read 2
 and responds with 
 .Sm off
 .Sy A Ar count-read No \en
 .Sm on
 then performs the requested 
 .Xr read 2
 and responds with 
 .Sm off
 .Sy A Ar count-read No \en
 .Sm on
-if the read was
-successful; otherwise an error in the
-standard format is returned.  If the read
-was successful, the data read is then sent.
+if the read was successful; otherwise an error in the standard format 
+is returned.  If the read was successful, the data read is then sent.
 .Sm off
 .It Xo Sy I Ar operation
 .No \en Ar count No \en
 .Sm off
 .It Xo Sy I Ar operation
 .No \en Ar count No \en
@@ -171,11 +176,72 @@ was successful, the data read is then sent.
 Perform a
 .Dv MTIOCOP
 .Xr ioctl 2
 Perform a
 .Dv MTIOCOP
 .Xr ioctl 2
+command using the specified parameters.  The parameters are interpreted as the
+.Tn ASCII
+representations of the decimal values to place in the 
+.Ar mt_op
+and
+.Ar mt_count
+fields of the structure used in the
+.Xr ioctl
+call.  The return value is the
+.Ar count
+parameter when the operation is successful.
+.Pp
+By issuing the
+.Ql I-1\en0\en
+command, a client will specify that he is using the VERSION 1 protocol.
+.Pp
+For a VERSION 0 client, the
+.Ar operation
+parameter is the platform 
+.Ar mt_op
+value (could be different if the client and the
+.Nm
+server are on two different platforms). For a VERSION 1 client,
+the 
+.Ar operation
+parameter is standardized as below:
+.Bl -tag -width Fl
+.It Ic 0
+Issue a MTWEOF command (write
+.Ar count
+end-of-file records).
+.It Ic 1
+Issue a MTFSF command (forward space over
+.Ar count
+file marks).
+.It Ic 2
+Issue a MTBSF command (backward space over
+.Ar count
+file marks).
+.It Ic 3
+Issue a MTFSR command (forward space
+.Ar count
+inter-record gaps).
+.It Ic 4
+Issue a MTBSR command (backward space
+.Ar count
+inter-record gaps).
+.It Ic 5
+Issue a MTREW command (rewind).
+.It Ic 6
+Issue a MTOFFL command (rewind and put the drive offline).
+.It Ic 7
+Issue a MTNOP command (no operation, set status only).
+.El
+.Sm off
+.It Xo Sy i Ar operation
+.No \en Ar count No \en
+.Xc
+.Sm on
+Perform an extended
+.Dv MTIOCOP
+.Xr ioctl 2
 command using the specified parameters.
 The parameters are interpreted as the
 .Tn ASCII
 command using the specified parameters.
 The parameters are interpreted as the
 .Tn ASCII
-representations of the decimal values
-to place in the 
+representations of the decimal values to place in the 
 .Ar mt_op
 and
 .Ar mt_count
 .Ar mt_op
 and
 .Ar mt_count
@@ -184,8 +250,25 @@ fields of the structure used in the
 call.  The return value is the
 .Ar count
 parameter when the operation is successful.
 call.  The return value is the
 .Ar count
 parameter when the operation is successful.
+The possible operations are:
+.Bl -tag -width Fl
+.It Ic 0
+Issue a MTCACHE command (switch cache on).
+.It Ic 1
+Issue a MTNOCACHE command (switch cache off).
+.It Ic 2
+Issue a MTRETEN command (retension the tape).
+.It Ic 3
+Issue a MTERASE command (erase the entire tape).
+.It Ic 4
+Issue a MTEOM command (position to end of media).
+.It Ic 5
+Issue a MTNBSF command (backward space count files to BOF).
+.El
 .ne 1i
 .ne 1i
+.Sm off
 .It Sy S
 .It Sy S
+.Sm on
 Return the status of the open device, as
 obtained with a
 .Dv MTIOCGET
 Return the status of the open device, as
 obtained with a
 .Dv MTIOCGET
@@ -193,7 +276,57 @@ obtained with a
 call.  If the operation was successful,
 an ``ack'' is sent with the size of the
 status buffer, then the status buffer is
 call.  If the operation was successful,
 an ``ack'' is sent with the size of the
 status buffer, then the status buffer is
-sent (in binary).
+sent (in binary, which is non-portable between different platforms).
+.Sm off
+.It Xo Sy s Ar sub-command
+.Xc
+.Sm on
+This is a replacement for the previous S command, portable across different
+platforms. If the open device is a magnetic tape, return members of the 
+magnetic tape status structure, as obtained with a
+.Dv MTIOCGET 
+ioctl call. If the open device is not a magnetic tape, an error is returned.
+If the 
+.Dv MTIOCGET
+operation was successful, the numerical value of the structure member is 
+returned in decimal. The following sub commands are supported:
+.Bl -tag -width Fl
+.It Ic T
+return the content of the structure member
+.Ar mt_type
+which contains the type of the magnetic tape device.
+.It Ic D
+return the content of the structure member
+.Ar mt_dsreg
+which contains the "drive status register".
+.It Ic E
+return the content of the structure member
+.Ar mt_erreg
+which contains the "error register". This structure member must be retrieved
+first because it is cleared after each
+.Dv MTIOCGET
+ioctl call.
+.It Ic R
+return the content of the structure member
+.Ar mt_resid
+which contains the residual count of the last I/O.
+.It Ic F
+return the content of the structure member
+.Ar mt_fileno
+which contains the file number of the current tape position.
+.It Ic B
+return the content of the structure member
+.Ar mt_blkno
+which contains the block number of the current tape position.
+.It Ic f
+return the content of the structure member
+.Ar mt_flags
+which contains MTF_ flags from the driver.
+.It Ic b
+return the content of the structure member
+.Ar mt_bf
+which contains the optimum blocking factor.
+.El
 .El
 .Sm on
 .Pp
 .El
 .Sm on
 .Pp
@@ -205,7 +338,7 @@ All responses are of the form described above.
 .Sh SEE ALSO
 .Xr rcmd 3 ,
 .Xr rexec 3 ,
 .Sh SEE ALSO
 .Xr rcmd 3 ,
 .Xr rexec 3 ,
-.Xr mtio 4 ,
+.Xr /usr/include/sys/mtio.h ,
 .Xr rdump 8 ,
 .Xr rrestore 8
 .Sh BUGS
 .Xr rdump 8 ,
 .Xr rrestore 8
 .Sh BUGS
index 2af48e3e0cd7f8560c2946a1faeb449c5da66169..acacb2d4f865d6a7d3d8f54fbfa887dbaccd5588 100644 (file)
--- a/rmt/rmt.c
+++ b/rmt/rmt.c
@@ -41,7 +41,7 @@
 
 #ifndef lint
 static const char rcsid[] =
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: rmt.c,v 1.17 2002/04/12 13:02:16 stelian Exp $";
+       "$Id: rmt.c,v 1.18 2002/04/15 11:57:29 stelian Exp $";
 #endif /* not linux */
 
 /*
 #endif /* not linux */
 
 /*
@@ -62,18 +62,18 @@ static const char rcsid[] =
 #include <string.h>
 #include <unistd.h>
 
 #include <string.h>
 #include <unistd.h>
 
-int    tape = -1;
+static int     tape = -1;
 
 
-char   *record;
-int    maxrecsize = -1;
+static char    *record;
+static int     maxrecsize = -1;
 
 #define        SSIZE   64
 
 #define        SSIZE   64
-char   device[SSIZE];
-char   count[SSIZE], filemode[SSIZE], pos[SSIZE], op[SSIZE];
+static char    device[SSIZE];
+static char    count[SSIZE], filemode[SSIZE], pos[SSIZE], op[SSIZE];
 
 
-char   resp[BUFSIZ];
+static char    resp[BUFSIZ];
 
 
-FILE   *debug;
+static FILE    *debug;
 #define        DEBUG(f)        if (debug) fprintf(debug, f)
 #define        DEBUG1(f,a)     if (debug) fprintf(debug, f, a)
 #define        DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2)
 #define        DEBUG(f)        if (debug) fprintf(debug, f)
 #define        DEBUG1(f,a)     if (debug) fprintf(debug, f, a)
 #define        DEBUG2(f,a1,a2) if (debug) fprintf(debug, f, a1, a2)
@@ -82,27 +82,37 @@ FILE        *debug;
  * Support for Sun's extended RMT protocol
  *     code originally written by Jörg Schilling <schilling@fokus.gmd.de>
  *     and relicensed by his permission from GPL to BSD for use in dump.
  * Support for Sun's extended RMT protocol
  *     code originally written by Jörg Schilling <schilling@fokus.gmd.de>
  *     and relicensed by his permission from GPL to BSD for use in dump.
+ *
+ *     rmt_version is 0 for regular clients (Linux included)
+ *     rmt_version is 1 for extended clients (Sun especially). In this cas
+ *             we support some extended commands (see below) and we remap
+ *             the ioctl commands to the UNIX "standard", as per:
+ *                     ftp://ftp.fokus.gmd.de/pub/unix/star/README.mtio
+ *
+ *     In order to use rmt version 1, a client must send "I-1\n0\n" 
+ *     before issuing the other I commands.
  */
  */
-#define RMTI_VERSION    -1
-#define RMT_VERSION 1
+static int     rmt_version = 0;
+#define RMTI_VERSION   -1
+#define RMT_VERSION    1
  
 /* Extended 'i' commands */
  
 /* Extended 'i' commands */
-#define RMTI_CACHE  0
-#define RMTI_NOCACHE    1
-#define RMTI_RETEN  2
-#define RMTI_ERASE  3
-#define RMTI_EOM    4
-#define RMTI_NBSF   5
+#define RMTI_CACHE     0
+#define RMTI_NOCACHE   1
+#define RMTI_RETEN     2
+#define RMTI_ERASE     3
+#define RMTI_EOM       4
+#define RMTI_NBSF      5
  
 /* Extended 's' comands */
  
 /* Extended 's' comands */
-#define MTS_TYPE    'T'
-#define MTS_DSREG   'D'
-#define MTS_ERREG   'E'
-#define MTS_RESID   'R'
-#define MTS_FILENO  'F'
-#define MTS_BLKNO   'B'
-#define MTS_FLAGS   'f'
-#define MTS_BF      'b'
+#define MTS_TYPE       'T'
+#define MTS_DSREG      'D'
+#define MTS_ERREG      'E'
+#define MTS_RESID      'R'
+#define MTS_FILENO     'F'
+#define MTS_BLKNO      'B'
+#define MTS_FLAGS      'f'
+#define MTS_BF         'b'
 
 char   *checkbuf __P((char *, int));
 void    error __P((int));
 
 char   *checkbuf __P((char *, int));
 void    error __P((int));
@@ -203,13 +213,68 @@ top:
                DEBUG2("rmtd: I %s %s\n", op, count);
                if (atoi(op) == RMTI_VERSION) {
                        rval = RMT_VERSION;
                DEBUG2("rmtd: I %s %s\n", op, count);
                if (atoi(op) == RMTI_VERSION) {
                        rval = RMT_VERSION;
-               } else { 
-                 struct mtop mtop;
-                 mtop.mt_op = atoi(op);
-                 mtop.mt_count = atoi(count);
-                 if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
-                       goto ioerror;
-                 rval = mtop.mt_count;
+                       rmt_version = 1;
+               } 
+               else { 
+                       struct mtop mtop;
+                       mtop.mt_op = -1;
+                       if (rmt_version) {
+                               /* rmt version 1, assume UNIX client */
+                               switch (atoi(op)) {
+#ifdef  MTWEOF
+                                       case 0:
+                                               mtop.mt_op = MTWEOF;
+                                               break;
+#endif
+#ifdef  MTFSF
+                                       case 1:
+                                               mtop.mt_op = MTFSF;
+                                               break;
+#endif
+#ifdef  MTBSF
+                                       case 2:
+                                               mtop.mt_op = MTBSF;
+                                               break;
+#endif
+#ifdef  MTFSR
+                                       case 3:
+                                               mtop.mt_op = MTFSR;
+                                               break;
+#endif
+#ifdef  MTBSR
+                                       case 4:
+                                               mtop.mt_op = MTBSR;
+                                               break;
+#endif
+#ifdef  MTREW
+                                       case 5:
+                                               mtop.mt_op = MTREW;
+                                               break;
+#endif
+#ifdef  MTOFFL
+                                       case 6:
+                                               mtop.mt_op = MTOFFL;
+                                               break;
+#endif
+#ifdef  MTNOP
+                                       case 7:
+                                               mtop.mt_op = MTNOP;
+                                               break;
+#endif
+                               }
+                               if (mtop.mt_op == -1) {
+                                       errno = EINVAL;
+                                       goto ioerror;
+                               }
+                       }
+                       else {
+                               /* rmt version 0, assume linux client */
+                               mtop.mt_op = atoi(op);
+                       }
+                       mtop.mt_count = atoi(count);
+                       if (ioctl(tape, MTIOCTOP, (char *)&mtop) < 0)
+                               goto ioerror;
+                       rval = mtop.mt_count;
                }
                goto respond;
 
                }
                goto respond;