She sells C Shells by the C Shore
So, I dropped the scsi card into urchin a few days ago. Dropped the
tape drive on it. Thought I had backups working perfectly. I was wrong...
The openbsd mt utility doesn't return an error code when you reach the end of
the tape. Whoops.
Also, the OpenBSD scsi-tape driver does not implement file number counting
and block counting. Personally, I don't care about block counting, but I
do really want file counting..
So, I've spent some time hacking on the openbsd scsi tape driver today.
The hacking is slow because it requires a recompile of the kernel for any
change, ugh. I'm integrating the file number code from the netbsd scsi-tape
driver and putting in the openbsd scsi tape driver. It's still VERY beta,
but I have a preliminary version working (mt fsf correctly counts numbers
until you hit eom).
If you care, here's the current patches. The first patch is for the
mt utility to provide displaying of the file number. The second is for
the 3.0_stable kernel st driver. It's funny, it looks like back in 1997
someone thought about adding this support since the "mt_fileno" construct
was added to the scsi tape driver..
I'll continue working on them until I'm happy with the change, then I'll
go ahead and submit the patches to theo and company..
Patch for the mt utility
--- /usr/src/bin/mt/t/mt.c Sun Oct 20 16:59:04 2002
+++ /usr/src/bin/mt/mt.c Sun Oct 20 17:01:35 2002
@@ -261,6 +261,7 @@
printreg("ds", bp->mt_dsreg, mt->t_dsbits);
printreg("\ner", bp->mt_erreg, mt->t_erbits);
(void)putchar('\n');
+ (void)printf("file number=%d\n",bp->mt_fileno);
(void)printf("blocksize: %d (%d, %d, %d, %d)\n",
bp->mt_blksiz, bp->mt_mblksiz[0], bp->mt_mblksiz[1],
bp->mt_mblksiz[2], bp->mt_mblksiz[3]);
Patch for the OpenBSD 3.0_stable scsi-tape kernel driver
--- /usr/src/sys/scsi/t/st.c Sun Oct 20 16:24:21 2002
+++ /usr/src/sys/scsi/st.c Sun Oct 20 19:34:44 2002
@@ -1,3 +1,6 @@
+/* to still do -- fsf rewinding past eom switches fileno to a negative
+ #.. Should be in the st_space function */
+
/* $OpenBSD: st.c,v 1.29 2001/06/22 14:35:43 deraadt Exp $ */
/* $NetBSD: st.c,v 1.71 1997/02/21 23:03:49 thorpej Exp $ */
@@ -259,6 +262,12 @@
u_int last_dsty; /* last density opened */
short mt_resid; /* last (short) resid */
short mt_erreg; /* last error (sense key) seen */
+ /* relative to beginning of tape */
+ daddr_t fileno; /* current file number */
+ daddr_t blkno;
+ int32_t last_io_resid;
+ int32_t last_ctl_resid;
+
/*--------------------device/scsi parameters----------------------------------*/
struct scsi_link *sc_link; /* our link to the adpter etc. */
/*--------------------parameters reported by the device ----------------------*/
@@ -340,6 +349,7 @@
#define ST_2FM_AT_EOD 0x0400 /* write 2 file marks at EOD */
#define ST_MOUNTED 0x0800 /* Device is presently mounted */
#define ST_DONTBUFFER 0x1000 /* Disable buffering/caching */
+#define ST_POSUPDATED 0x8000 /* tape position has been updated */
#define ST_PER_ACTION (ST_AT_FILEMARK | ST_EIO_PENDING | ST_BLANK_READ)
#define ST_PER_MOUNT (ST_INFO_VALID | ST_BLOCK_SET | ST_WRITTEN | \
@@ -715,6 +725,7 @@
st->flags &= ~ST_NEW_MOUNT;
st->flags |= ST_MOUNTED;
sc_link->flags |= SDEV_MEDIA_LOADED; /* move earlier? */
+ st->blkno = st->fileno = (daddr_t) 0;
return 0;
}
@@ -741,8 +752,12 @@
st_rewind(st, 0, SCSI_IGNORE_NOT_READY);
scsi_prevent(sc_link, PR_ALLOW,
SCSI_IGNORE_ILLEGAL_REQUEST | SCSI_IGNORE_NOT_READY);
- if (eject)
+ if (eject) {
st_load(st, LD_UNLOAD, SCSI_IGNORE_NOT_READY);
+ st->blkno = st->fileno = (daddr_t) -1;
+ } else {
+ st->blkno = st->fileno = (daddr_t) 0;
+ }
st->flags &= ~(ST_MOUNTED | ST_NEW_MOUNT);
sc_link->flags &= ~SDEV_MEDIA_LOADED;
}
@@ -1065,6 +1080,8 @@
_lto3b(bp->b_bcount / st->blksize, cmd.len);
} else
_lto3b(bp->b_bcount, cmd.len);
+ /* clear position updated indicator */
+ st->flags &= ~ST_POSUPDATED;
/*
* go ask the adapter to do all this for us
@@ -1156,6 +1173,8 @@
g->mt_mdensity[1] = st->modes[1].density;
g->mt_mdensity[2] = st->modes[2].density;
g->mt_mdensity[3] = st->modes[3].density;
+ g->mt_fileno = st->fileno;
+ g->mt_blkno = st->blkno;
if (st->flags & ST_READONLY)
g->mt_dsreg |= MT_DS_RDONLY;
if (st->flags & ST_MOUNTED)
@@ -1641,8 +1660,37 @@
cmd.byte2 = what;
_lto3b(number, cmd.number);
- return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
+ st->flags &= ~ST_POSUPDATED;
+ st->last_ctl_resid = 0;
+
+ error=scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
sizeof(cmd), 0, 0, 0, ST_SPC_TIME, NULL, flags);
+
+ if (error == 0 && (st->flags & ST_POSUPDATED) == 0) {
+ number = number - st->last_ctl_resid;
+ if (what == SP_BLKS) {
+ if (st->blkno != -1) {
+ st->blkno += number;
+ }
+ } else if (what == SP_FILEMARKS) {
+ if (st->fileno != -1) {
+ if (number > 0) {
+ /* ks */
+ st->fileno += number;
+ st->blkno = 0;
+ } else if (number < 0) {
+ st->blkno = -1;
+ }
+ }
+ } else if (what == SP_EOM) {
+ /*
+ * This loses us relative position.
+ */
+ st->fileno = st->blkno = -1;
+ }
+ }
+ return (error);
+
}
/*
@@ -1654,6 +1702,7 @@
int flags;
int number;
{
+ int error;
struct scsi_write_filemarks cmd;
/*
@@ -1680,8 +1729,13 @@
cmd.opcode = WRITE_FILEMARKS;
_lto3b(number, cmd.number);
- return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
+ error=scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
sizeof(cmd), 0, 0, 0, ST_IO_TIME * 4, NULL, flags);
+ if (error == 0 && st->fileno != -1) {
+ st->fileno += number;
+ }
+ return (error);
+
}
/*
@@ -1778,9 +1832,20 @@
cmd.opcode = REWIND;
cmd.byte2 = immediate;
- return scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
+ error=scsi_scsi_cmd(st->sc_link, (struct scsi_generic *) &cmd,
sizeof(cmd), 0, 0, ST_RETRIES,
immediate ? ST_CTL_TIME: ST_SPC_TIME, NULL, flags);
+ if (error) {
+ printf("%s: error %d trying to rewind\n",
+ st->sc_dev.dv_xname, error);
+ /* lost position */
+ st->fileno = st->blkno = -1;
+ } else {
+ st->fileno = st->blkno = 0;
+ }
+ return (error);
+
+
}
/*
@@ -1810,15 +1875,23 @@
return SCSIRET_CONTINUE; /* let the generic code handle it */
if (st->flags & ST_FIXEDBLOCKS) {
xs->resid = info * st->blksize;
+ st->last_io_resid = xs->resid;
if (sense->flags & SSD_EOM) {
st->flags |= ST_EIO_PENDING;
if (bp)
bp->b_resid = xs->resid;
+ } else {
+ st->last_ctl_resid = xs->resid;
}
if (sense->flags & SSD_FILEMARK) {
st->flags |= ST_AT_FILEMARK;
if (bp)
bp->b_resid = xs->resid;
+ if (st->fileno != (daddr_t) -1) {
+ st->fileno++;
+ st->blkno=0;
+ st->flags |= ST_POSUPDATED;
+ }
}
if (sense->flags & SSD_ILI) {
st->flags |= ST_EIO_PENDING;
@@ -1853,10 +1926,20 @@
}
}
} else { /* must be variable mode */
+ if (bp) {
+ st->last_io_resid = xs->resid;
+ } else {
+ st->last_ctl_resid = xs->resid;
+ }
xs->resid = xs->datalen; /* to be sure */
if (sense->flags & SSD_EOM)
return EIO;
if (sense->flags & SSD_FILEMARK) {
+ if (st->fileno != (daddr_t) -1) {
+ st->fileno++;
+ st->blkno=0;
+ st->flags |= ST_POSUPDATED;
+ }
if (bp)
bp->b_resid = bp->b_bcount;
return 0;
@@ -1909,6 +1992,8 @@
bp->b_resid = xs->resid;
/* return an EOF */
}
+ /* lost position */
+ st->fileno = st->blkno = (daddr_t) -1;
return 0;
}
}
Posted at: 00:51 on 21/10/2002
[ /code ]
#
Older articles (2024):