Backdated import of mt-st version 1.1

This is an import of the mt-st upstream release 1.1 as it appeared in
the Debian archives and on ftp://ftp.ibiblio.org/pub/linux/system/backup.
This commit is contained in:
Kai Mäkisara
2008-04-27 19:01:28 +02:00
committed by Iustin Pop
parent be12266b61
commit c232ed0dd2
9 changed files with 138 additions and 192 deletions

View File

@@ -1,8 +1,11 @@
CFLAGS= -Wall -O2
SBINDIR= /sbin
BINDIR= /bin
USRBINDIR= /usr/bin
MANDIR= /usr/share/man
MTDIR=$(BINDIR)
all: mt stinit
mt: mt.c
@@ -12,7 +15,7 @@ stinit: stinit.c
$(CC) $(CFLAGS) -o stinit stinit.c
install: mt stinit
install -s mt $(BINDIR)
install -s mt $(MTDIR)
install -c -m 444 mt.1 $(MANDIR)/man1
(if [ -f $(MANDIR)/man1/mt.1.gz ] ; then \
rm -f $(MANDIR)/man1/mt.1.gz; gzip $(MANDIR)/man1/mt.1; fi)

8
README
View File

@@ -29,6 +29,12 @@ Installation:
- make
- make install
Changes in version 1.1:
- unused defines removed from mtio.h (compiles also with distributions no
having linux/qic117.h)
- add support for MT_ST_SILI to mt and stinit
- add command showoptions for kernels >= 2.6.26
Changes in version 0.9b:
- only stinit changed
@@ -93,4 +99,4 @@ Changes in version 0.3:
by the command compression using a new ioctl)
- bus fixes
May 29, 2005 Kai Makisara (email Kai.Makisara@kolumbus.fi)
April 27, 2008 Kai Makisara (email Kai.Makisara@kolumbus.fi)

View File

@@ -34,6 +34,10 @@ stinit.def.examples - a file containing example definitions for
Makefile - a sample makefile for the program
README.stinit - this file
Changes in version 1.1:
- fix mode number printing in verbose mode (from Martin Jacobs)
- add support for the sili option
Changes in version 0.9b:
- fix back out to SCSI_IOCTL_SEND_COMMAND for 2.4 kernels (2.4 uses errno
EINVAL for unsupported ioctls)
@@ -64,5 +68,5 @@ Changes in version 0.6:
Initial version 0.5.
May 29, 2005 Kai M<>kisara <Kai.Makisara@kolumbus.fi>
April 27, 2008 Kai M<>kisara <Kai.Makisara@kolumbus.fi>

View File

@@ -1,16 +1,16 @@
Begin4
Title: mt-st
Version: 0.9b
Entered-date: 2005-08-21
Version: 1.1
Entered-date: 2008-04-27
Description: Magnetic tape control tools for Linux SCSI tapes.
Includes a mt-like program supporting additional commands using ioctls
specific to the Linux SCSI tape driver (up to kernel 2.6.12), and the program
specific to the Linux SCSI tape driver (up to kernel 2.6.26), and the program
stinit to define the SCSI tape devices in system startup scripts.
Keywords: tape SCSI
Author: Kai.Makisara@kolumbus.fi (Kai Makisara)
Maintained-by: Kai.Makisara@kolumbus.fi (Kai Makisara)
Primary-site: ftp://ftp.ibiblio.org/pub/linux/system/backup
37 kB mt-st-0.9b.tar.gz
0.7 kB mt-st-0.9b.lsm
36 kB mt-st-1.1.tar.gz
0.7 kB mt-st-1.1.lsm
Copying-policy: GPL
End

12
mt.1
View File

@@ -1,4 +1,4 @@
.TH MT 1 "August 2005" \" -*- nroff -*-
.TH MT 1 "April 2008" \" -*- nroff -*-
.SH NAME
mt \- control magnetic tape drive operation
.SH SYNOPSIS
@@ -207,6 +207,11 @@ drive can handle partitioned tapes
.IP scsi2logical
seek and tell use SCSI-2 logical block addresses instead of device
dependent addresses
.IP sili
Set the SILI bit is when reading in variable block mode. This may speed up
reading blocks shorter than the read byte count. Set this option only if
you know that the drive supports SILI and the HBA reliably returns transfer
residual byte counts. Requires kernel version >= 2.6.26.
.IP sysv
enable the System V semantics
.RE
@@ -221,6 +226,9 @@ Allowed only for the superuser.
The methods to specify the bits to clear are given above in description of
.BR stoptions.
Allowed only for the superuser.
.IP stshowoptions
(SCSI tapes) Print the currently enabled options for the device. Requires
kernel version >= 2.6.26 and sysfs must be mounted at /sys.
.IP stwrthreshold
(SCSI tapes) The write threshold for the tape device is set to
.I count
@@ -268,7 +276,7 @@ failed.
.SH AUTHOR
The program is written by Kai Makisara <Kai.Makisara@kolumbus.fi>.
.SH COPYRIGHT
The program and the manual page are copyrighted by Kai Makisara, 1998-2005.
The program and the manual page are copyrighted by Kai Makisara, 1998-2008.
They can be distributed according to the GNU Copyleft.
.SH SEE ALSO
st(4)

86
mt.c
View File

@@ -5,10 +5,10 @@
tape drive.
Maintained by Kai M<>kisara (email Kai.Makisara@kolumbus.fi)
Copyright by Kai M<>kisara, 1998 - 2005. The program may be distributed
Copyright by Kai M<>kisara, 1998 - 2008. The program may be distributed
according to the GNU Public License
Last Modified: Sun Aug 21 21:48:06 2005 by kai.makisara
Last Modified: Sun Apr 27 19:49:00 2008 by kai.makisara
*/
#include <stdio.h>
@@ -20,6 +20,8 @@
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include "mtio.h"
@@ -27,7 +29,7 @@
#define DEFTAPE "/dev/tape" /* default tape device */
#endif /* DEFTAPE */
#define VERSION "0.9b"
#define VERSION "1.1"
typedef int (* cmdfunc)(/* int, struct cmdef_tr *, int, char ** */);
@@ -66,6 +68,7 @@ static int do_partseek(int, cmdef_tr *, int, char **);
static int do_status(int, cmdef_tr *, int, char **);
static int print_densities(int, cmdef_tr *, int, char **);
static int do_asf(int, cmdef_tr *, int, char **);
static int do_show_options(int, cmdef_tr *, int, char **);
static void test_error(int, cmdef_tr *);
static cmdef_tr cmds[] = {
@@ -159,6 +162,8 @@ static cmdef_tr cmds[] = {
ET_ONLINE },
{ "asf", 0, do_asf, MTREW, FD_RDONLY, ONE_ARG,
ET_ONLINE },
{ "stshowopt", 0, do_show_options, 0, FD_RDONLY, ONE_ARG,
0 },
{ NULL, 0, 0, 0 }
};
@@ -210,14 +215,18 @@ static struct densities {
{0x29, "QIC-3080MC"},
{0x30, "AIT-1 or MLR3"},
{0x31, "AIT-2"},
{0x32, "AIT-3"},
{0x32, "AIT-3 or SLR7"},
{0x33, "SLR6"},
{0x34, "SLR100"},
{0x40, "DLT1 40 GB, or Ultrium"},
{0x41, "DLT 40GB, or Ultrium2"},
{0x42, "LTO-2"},
{0x44, "LTO-3"},
{0x45, "QIC-3095-MC (TR-4)"},
{0x47, "TR-5"},
{0x46, "LTO-4"},
{0x47, "DDS-5 or TR-5"},
{0x51, "IBM 3592 J1A"},
{0x52, "IBM 3592 E05"},
{0x80, "DLT 15GB uncomp. or Ecrix"},
{0x81, "DLT 15GB compressed"},
{0x82, "DLT 20GB uncompressed"},
@@ -258,6 +267,7 @@ static struct booleans {
#ifdef MT_ST_SYSV
{"sysv", MT_ST_SYSV, "enable the SystemV semantics"},
#endif
{"sili", MT_ST_SILI, "enable SILI for variable block mode"},
{"cleaning", MT_ST_SET_CLN, "set the cleaning bit location and mask"},
{NULL, 0}};
@@ -673,6 +683,72 @@ do_status(int mtfd, cmdef_tr *cmd, int argc, char **argv)
}
/* From linux/drivers/scsi/st.[ch] */
#define ST_NBR_MODE_BITS 2
#define ST_NBR_MODES (1 << ST_NBR_MODE_BITS)
#define ST_MODE_SHIFT (7 - ST_NBR_MODE_BITS)
#define ST_MODE_MASK ((ST_NBR_MODES - 1) << ST_MODE_SHIFT)
#define TAPE_NR(minor) ( (((minor) & ~255) >> (ST_NBR_MODE_BITS + 1)) | \
((minor) & ~(-1 << ST_MODE_SHIFT)) )
#define TAPE_MODE(minor) (((minor) & ST_MODE_MASK) >> ST_MODE_SHIFT)
static const char *st_formats[] = {
"", "r", "k", "s", "l", "t", "o", "u",
"m", "v", "p", "x", "a", "y", "q", "z"};
/* Show the options if visible in sysfs */
static int do_show_options(int mtfd, cmdef_tr *cmd, int argc, char **argv)
{
int i, fd, options, tapeminor, tapeno, tapemode;
struct stat stat;
struct utsname uts;
char fname[100], buf[20];
if (uname(&uts) < 0) {
perror(tape_name);
return 2;
}
sscanf(uts.release, "%d.%d.%d", &i, &tapeno, &tapemode);
if (i < 2 || tapeno < 6 || tapemode < 26)
printf("Your kernel (%d.%d.%d) may be too old for this command.\n",
i, tapeno, tapemode);
if (fstat(mtfd, &stat) < 0) {
perror(tape_name);
return 1;
}
if (!(stat.st_mode & S_IFCHR)) {
fprintf(stderr, "mt: not a character device.\n");
return 1;
}
tapeminor = minor(stat.st_rdev);
tapeno = TAPE_NR(tapeminor);
tapemode = TAPE_MODE(tapeminor);
tapemode <<= 4 - ST_NBR_MODE_BITS; /* from st.c */
sprintf(fname, "/sys/class/scsi_tape/st%d%s/options", tapeno,
st_formats[tapemode]);
/* printf("Trying file '%s' (st_rdev 0x%lx).\n", fname, stat.st_rdev); */
if ((fd = open(fname, O_RDONLY)) < 0 ||
read(fd, buf, 20) < 0) {
fprintf(stderr, "Can't read the sysfs file '%s'.\n", fname);
return 2;
}
close(fd);
options = strtol(buf, NULL, 0);
printf("The options set:");
for (i=0; boolean_tbl[i].name != NULL; i++)
if (options & boolean_tbl[i].bitmask)
printf(" %s", boolean_tbl[i].name);
printf("\n");
return 0;
}
/* Print a list of possible density codes */
static int
print_densities(int fd, cmdef_tr *cmd, int argc, char **argv)

172
mtio.h
View File

@@ -1,8 +1,9 @@
/*
* linux/mtio.h header file for Linux. Written by H. Bergman
*
* Modified for special ioctls provided by zftape in September 1997
* by C.-J. Heine.
* Sanitized version for mt/stinit (definitions not used by these
* programs have been removed) 7 Oct 2007/Kai M<>kisara
*
*/
#ifndef _LINUX_MTIO_H
@@ -10,7 +11,6 @@
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/qic117.h>
/*
* Structures and definitions for mag tape io control commands
@@ -110,38 +110,6 @@ struct mtget {
#define MT_ISSCSI1 0x71 /* Generic ANSI SCSI-1 tape unit */
#define MT_ISSCSI2 0x72 /* Generic ANSI SCSI-2 tape unit */
/* QIC-40/80/3010/3020 ftape supported drives.
* 20bit vendor ID + 0x800000 (see ftape-vendors.h)
*/
#define MT_ISFTAPE_UNKNOWN 0x800000 /* obsolete */
#define MT_ISFTAPE_FLAG 0x800000
struct mt_tape_info {
long t_type; /* device type id (mt_type) */
char *t_name; /* descriptive name */
};
#define MT_TAPE_INFO { \
{MT_ISUNKNOWN, "Unknown type of tape device"}, \
{MT_ISQIC02, "Generic QIC-02 tape streamer"}, \
{MT_ISWT5150, "Wangtek 5150, QIC-150"}, \
{MT_ISARCHIVE_5945L2, "Archive 5945L-2"}, \
{MT_ISCMSJ500, "CMS Jumbo 500"}, \
{MT_ISTDC3610, "Tandberg TDC 3610, QIC-24"}, \
{MT_ISARCHIVE_VP60I, "Archive VP60i, QIC-02"}, \
{MT_ISARCHIVE_2150L, "Archive Viper 2150L"}, \
{MT_ISARCHIVE_2060L, "Archive Viper 2060L"}, \
{MT_ISARCHIVESC499, "Archive SC-499 QIC-36 controller"}, \
{MT_ISQIC02_ALL_FEATURES, "Generic QIC-02 tape, all features"}, \
{MT_ISWT5099EEN24, "Wangtek 5099-een24, 60MB"}, \
{MT_ISTEAC_MT2ST, "Teac MT-2ST 155mb data cassette drive"}, \
{MT_ISEVEREX_FT40A, "Everex FT40A, QIC-40"}, \
{MT_ISONSTREAM_SC, "OnStream SC-, DI-, DP-, or USB tape drive"}, \
{MT_ISSCSI1, "Generic SCSI-1 tape"}, \
{MT_ISSCSI2, "Generic SCSI-2 tape"}, \
{0, NULL} \
}
/* structure for MTIOCPOS - mag tape get position command */
@@ -149,139 +117,6 @@ struct mtpos {
long mt_blkno; /* current block number */
};
/* structure for MTIOCGETCONFIG/MTIOCSETCONFIG primarily intended
* as an interim solution for QIC-02 until DDI is fully implemented.
*/
struct mtconfiginfo {
long mt_type; /* drive type */
long ifc_type; /* interface card type */
unsigned short irqnr; /* IRQ number to use */
unsigned short dmanr; /* DMA channel to use */
unsigned short port; /* IO port base address */
unsigned long debug; /* debugging flags */
unsigned have_dens:1;
unsigned have_bsf:1;
unsigned have_fsr:1;
unsigned have_bsr:1;
unsigned have_eod:1;
unsigned have_seek:1;
unsigned have_tell:1;
unsigned have_ras1:1;
unsigned have_ras2:1;
unsigned have_ras3:1;
unsigned have_qfa:1;
unsigned pad1:5;
char reserved[10];
};
/* structure for MTIOCVOLINFO, query information about the volume
* currently positioned at (zftape)
*/
struct mtvolinfo {
unsigned int mt_volno; /* vol-number */
unsigned int mt_blksz; /* blocksize used when recording */
unsigned int mt_rawsize; /* raw tape space consumed, in kb */
unsigned int mt_size; /* volume size after decompression, in kb */
unsigned int mt_cmpr:1; /* this volume has been compressed */
};
/* raw access to a floppy drive, read and write an arbitrary segment.
* For ftape/zftape to support formatting etc.
*/
#define MT_FT_RD_SINGLE 0
#define MT_FT_RD_AHEAD 1
#define MT_FT_WR_ASYNC 0 /* start tape only when all buffers are full */
#define MT_FT_WR_MULTI 1 /* start tape, continue until buffers are empty */
#define MT_FT_WR_SINGLE 2 /* write a single segment and stop afterwards */
#define MT_FT_WR_DELETE 3 /* write deleted data marks, one segment at time */
struct mtftseg
{
unsigned mt_segno; /* the segment to read or write */
unsigned mt_mode; /* modes for read/write (sync/async etc.) */
int mt_result; /* result of r/w request, not of the ioctl */
void *mt_data; /* User space buffer: must be 29kb */
};
/* get tape capacity (ftape/zftape)
*/
struct mttapesize {
unsigned long mt_capacity; /* entire, uncompressed capacity
* of a cartridge
*/
unsigned long mt_used; /* what has been used so far, raw
* uncompressed amount
*/
};
/* possible values of the ftfmt_op field
*/
#define FTFMT_SET_PARMS 1 /* set software parms */
#define FTFMT_GET_PARMS 2 /* get software parms */
#define FTFMT_FORMAT_TRACK 3 /* start formatting a tape track */
#define FTFMT_STATUS 4 /* monitor formatting a tape track */
#define FTFMT_VERIFY 5 /* verify the given segment */
struct ftfmtparms {
unsigned char ft_qicstd; /* QIC-40/QIC-80/QIC-3010/QIC-3020 */
unsigned char ft_fmtcode; /* Refer to the QIC specs */
unsigned char ft_fhm; /* floppy head max */
unsigned char ft_ftm; /* floppy track max */
unsigned short ft_spt; /* segments per track */
unsigned short ft_tpc; /* tracks per cartridge */
};
struct ftfmttrack {
unsigned int ft_track; /* track to format */
unsigned char ft_gap3; /* size of gap3, for FORMAT_TRK */
};
struct ftfmtstatus {
unsigned int ft_segment; /* segment currently being formatted */
};
struct ftfmtverify {
unsigned int ft_segment; /* segment to verify */
unsigned long ft_bsm; /* bsm as result of VERIFY cmd */
};
struct mtftformat {
unsigned int fmt_op; /* operation to perform */
union fmt_arg {
struct ftfmtparms fmt_parms; /* format parameters */
struct ftfmttrack fmt_track; /* ctrl while formatting */
struct ftfmtstatus fmt_status;
struct ftfmtverify fmt_verify; /* for verifying */
} fmt_arg;
};
struct mtftcmd {
unsigned int ft_wait_before; /* timeout to wait for drive to get ready
* before command is sent. Milliseconds
*/
qic117_cmd_t ft_cmd; /* command to send */
unsigned char ft_parm_cnt; /* zero: no parm is sent. */
unsigned char ft_parms[3]; /* parameter(s) to send to
* the drive. The parms are nibbles
* driver sends cmd + 2 step pulses */
unsigned int ft_result_bits; /* if non zero, number of bits
* returned by the tape drive
*/
unsigned int ft_result; /* the result returned by the tape drive*/
unsigned int ft_wait_after; /* timeout to wait for drive to get ready
* after command is sent. 0: don't wait */
int ft_status; /* status returned by ready wait
* undefined if timeout was 0.
*/
int ft_error; /* error code if error status was set by
* command
*/
};
/* mag tape io control commands */
#define MTIOCTOP _IOW('m', 1, struct mtop) /* do a mag tape op */
#define MTIOCGET _IOR('m', 2, struct mtget) /* get tape status */
@@ -366,6 +201,7 @@ struct mtftcmd {
#define MT_ST_SCSI2LOGICAL 0x800
#define MT_ST_SYSV 0x1000
#define MT_ST_NOWAIT 0x2000
#define MT_ST_SILI 0x4000
/* The mode parameters to be controlled. Parameter chosen with bits 20-28 */
#define MT_ST_CLEAR_DEFAULT 0xfffff

View File

@@ -1,4 +1,4 @@
.TH STINIT 8 "August 2005" \" -*- nroff -*-
.TH STINIT 8 "April 2008" \" -*- nroff -*-
.SH NAME
stinit \- initialize SCSI magnetic tape drives
.SH SYNOPSIS
@@ -234,6 +234,13 @@ Logical block addresses are used in the MTSEEK and MTIOCPOS
commands if
.I value
is non-zero. The default is to use the device-specific addresses.
.IP sili=value
If
.I value
is non-zero, the SILI bit is set when reading in variable block mode. This
may speed up reading blocks shorter than the read byte count. Set this only if
you know that the drive supports SILI and the HBA reliably returns transfer
residual byte counts. Requires kernel version >= 2.6.26.
.IP defs-for-w[rites]=value
The parameters defining the tape format (density, block size, etc.)
are forced when writing starts at the beginning of a tape if
@@ -266,7 +273,7 @@ for the superuser.
.SH AUTHOR
The program is written by Kai Makisara <Kai.Makisara@kolumbus.fi>.
.SH COPYRIGHT
The program and the manual page are copyrighted by Kai Makisara, 1998-2005.
The program and the manual page are copyrighted by Kai Makisara, 1998-2008.
They can be distributed according to the GNU Copyleft.
.SH SEE ALSO
st(4) mt(1)

View File

@@ -1,11 +1,11 @@
/* This program initializes Linux SCSI tape drives using the
inquiry data from the devices and a text database.
Copyright 1996-2005 by Kai M<>kisara (email Kai.Makisara@kolumbus.fi)
Copyright 1996-2008 by Kai M<>kisara (email Kai.Makisara@kolumbus.fi)
Distribution of this program is allowed according to the
GNU Public Licence.
Last modified: Sun Aug 21 21:47:51 2005 by kai.makisara
Last modified: Sun Apr 27 14:24:16 2008 by kai.makisara
*/
#include <stdio.h>
@@ -30,7 +30,7 @@
#endif
#define SKIP_WHITE(p) for ( ; *p == ' ' || *p == '\t'; p++)
#define VERSION "0.9b"
#define VERSION "1.1"
typedef struct _modepar_tr {
int defined;
@@ -58,6 +58,7 @@ typedef struct _devdef_tr {
int long_timeout;
int cleaning;
int nowait;
int sili;
modepar_tr modedefs[4];
} devdef_tr;
@@ -265,6 +266,7 @@ find_pars(FILE *dbf, char *company, char *product, char *rev, devdef_tr *defs,
defs->long_timeout = (-1);
defs->cleaning = (-1);
defs->nowait = (-1);
defs->sili = (-1);
for (i=0; i < NBR_MODES; i++) {
defs->modedefs[i].defined = FALSE;
defs->modedefs[i].blocksize = (-1);
@@ -370,6 +372,8 @@ find_pars(FILE *dbf, char *company, char *product, char *rev, devdef_tr *defs,
defs->cleaning = num_arg(t);
if ((t = find_string(defstr, "no-w", line, LINEMAX)) != NULL)
defs->nowait = num_arg(t);
if ((t = find_string(defstr, "sili", line, LINEMAX)) != NULL)
defs->sili = num_arg(t);
defs->modedefs[mode].defined = TRUE;
if ((t = find_string(defstr, "block", line, LINEMAX)) != NULL)
@@ -521,10 +525,10 @@ do_inquiry(char *tname, char *company, char *product, char *rev, int print_non_f
}
if (result) {
close(fn);
sprintf(buffer,
sprintf((char *)buffer,
"The SCSI INQUIRY for device '%s' failed (power off?)",
tname);
perror(buffer);
perror((char *)buffer);
return FALSE;
}
}
@@ -570,7 +574,7 @@ tapenum(char *name)
return dev;
}
else { /* Search from the device directories */
for (dvd=devdirs; dvd->dir != NULL; dvd++) {
for (dvd=devdirs; dvd->dir[0] != 0; dvd++) {
dn = dvd->dir;
if ((dirp = opendir(dn)) == NULL)
continue;
@@ -758,6 +762,8 @@ set_defs(devdef_tr *defs, char **fnames)
clear_set[0] = clear_set[1] = 0;
if (defs->nowait >= 0)
clear_set[defs->nowait != 0] |= MT_ST_NOWAIT;
if (defs->sili >= 0)
clear_set[defs->sili != 0] |= MT_ST_SILI;
if (defs->modedefs[i].buffer_writes >= 0)
clear_set[defs->modedefs[i].buffer_writes != 0] |= MT_ST_BUFFER_WRITES;
if (defs->modedefs[i].async_writes >= 0)
@@ -852,7 +858,7 @@ define_tape(int tapeno, FILE *dbf, devdef_tr *defptr, int print_non_found)
}
if (verbose > 1)
for (i=0; i < NBR_MODES; i++)
printf("Mode %d, name '%s'\n", i, fnames[i]);
printf("Mode %d, name '%s'\n", i + 1, fnames[i]);
tname = fnames[0];
if (!do_inquiry(tname, company, product, rev, print_non_found)) {