Hello everyone who considers using the Onstream ADR50 drive with
amanda, I won't let you wait any longer since Onstream support do not
get back to me this time.

The ADR50 drive, which is supposed to be a full linux compatible SCSI
tape drive (it should work with the standard st scsi tape driver),
does *not* work with amanda with firmware version 2.39. Although I had
posted the problem desciption some time ago in this thread, I include
it below again for completness. The problem description shows that we
have spend quite a while to track down the problem.

The problem is timeout related. It seems that the ADR50 gets into
trouble when it runs out of data during writing a file and then
receives the command to write a file mark. The drive will proceed to
write the data, but reading the tape only the first file appears to be
readable. After the first file has been read, the device reports a
media error.

Amanda *always* writes the file mark just before starting to write the
next file, not right after a file has been written completely. The
timeout in question happens after writing the tape label during the
estimate collection phase. 90 seconds are enough.

Onsteam support did respond to my inquiery two times. The second email
I have got was cc'ed to me. In that email, a staff member guessed the
problem would be firmware related and asked someone else to look into
it. This has happened a month ago. I asked them when they will look
into it but I so far haven't heared from them.

I agree the problem is likely to be firmware related. The firmware
version we can speak about is 2.39; there is currently no newer
version available.

We had asked on the amanda users list for people using the ADR50 drive
with amanda. Only one person responded, saying that after trying the
ADR drive, they had returned it and are now using a DAT drive.

I will respond to myself here if I hear anything new about the
problem.

Greetings,
Moritz

Problem description follows -----------------------
---------------------- 8< -------------------------

We have a problem with our new OnStream ADR50 tape streamer.

Brief problem description:
The ADR50 device writes data which it cannot read afterwards
under certain conditions. Those conditions are described below.

Hardware description:

AMD Duron 750. Asus A7V133 main board. 256 MB RAM.
Adaptec 29160N SCSI controller. 
SCSI LVD bus internal with 
2 devices: 
        HDD IBM 20 GB (scsi id 0), 
        tape device OnStream ADR50 internal (scsi id 5)
                Firmware rev. 2.39
                S/N EA21J290564
Other SCSI bus (narrow 50pin internal):
        CDROM drive (scsi id 6).

Software description:

OS: RedHat Linux 7.1
kernel: 2.4.2, 2.4.9 (both RedHat patched versions;
        the problem appears with both)
Tried Adaptec SCSI driver verison 6.1.7 (w/ kernel 2.4.2),
        6.2.1 and 6.2.4 (w/ kernel 2.4.9); the problem appears
        with all of them


Description of problem:
Although the problem initially appeared when using the amanda
backup software, it could be reproduced using a small C program
which simulates what amanda does. The program performs the following
steps:
        1. open the tape device (given on the command line) 
                in read/write mode
                (it remains open for all following steps)
        2. rewind the tape.
        3. read 32 KBytes of data from the tape.
        4. rewind again.
        5. write 32 KByte of data.
        6. wait for 120 seconds
        7. write an end of file mark
        8. write another 1024 KBytes of data
        9. write an end of file mark
        10. rewind the tape
        11. read 32 KBytes of data
        12. try to read 32 KBytes of data, expect to get 0 bytes but
                pass the file mark
        13. read 32 KBytes of data (file 2)

When doing this, step 13 fails reproducibly. The program gets error
code I/O error. Note that the no rewind tape device (/dev/nst0) was 
used for the tests in all cases.

The most interesting part is that everything works fine when the program
skips step 6 (wait for 120 seconds).

What I have tried without success:
        *  Replaced the SCSI controller
        *  different kernel versions (see above)
        *  different new SCSI drivers (aic7xxx, see above)

Full details follow below.

This is a transcript of a typical test program session:
-------------------------------------------8<-----
[root@hl tapetest]# ./test1 /dev/nst0
test1: rewind...  success
test1: reading 32768 bytes using 32768 byte blocks... + success
test1: rewind...  success
test1: writing 32768 bytes using 32768 byte blocks... + success
test1: sleeping for 120 s...woke up.
test1: write filemark...  success
test1: writing 1048576 bytes using 32768 byte blocks... ++++++++++++++++++++++++
++++++++ success
test1: write filemark...  success
test1: rewind...  success
test1: reading 32768 bytes using 32768 byte blocks... + success
test1: skipping file mark... done.test1: reading 1048576 bytes using 32768 byte
blocks... Input/output error
[root@hl tapetest]#
-------------------------------------------8<-----

/var/log/messages entries when the Input/Output error occurs:

Nov 21 15:58:06 hl kernel: st0: Error with sense data: Info fld=0x40, Current st
09:00: sense key Medium Error
Nov 21 15:58:06 hl kernel: Additional sense indicates Unrecovered read error

Attempts to read the resulting tape using dd twice 
(two files) fail:

[root@hl tapetest]# mt rewind
[root@hl tapetest]# dd if=/dev/tape |hexdump
0000000 5555 5555 5555 5555 5555 5555 5555 5555
*
64+0 records in
64+0 records out
0008000
[root@hl tapetest]# dd if=/dev/tape |hexdump
dd: reading `/dev/tape': Input/output error
0+0 records in
0+0 records out
[root@hl tapetest]# Nov 21 16:46:50 hl kernel: st0: Error with sense data: Info
fld=0x40, Current st09:00: sense key Medium Error
Nov 21 16:46:50 hl kernel: Additional sense indicates Unrecovered read error


This is the test program written in C:
-------------------------------------------8<-----
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <sys/mtio.h>
#include <fcntl.h>

#define BUFSIZE                 (32*1024)
#define BLOCKSIZE               512
#define SLEEPSIZE               120

char    *me = "test1";
char    buf[32768];
int     fd;

int tape_command(int command, int count, char *message)
{
        struct mtop m;
        int err;

        m.mt_op = command;
        m.mt_count = count;
        fprintf(stderr, "%s: %s... ", me, message);
        err = ioctl(fd, MTIOCTOP, &m);
        if (err != 0) {
                fprintf(stderr, "failed: %s\n", me, message, sys_errlist[errno]);
                exit(1);
        }
        fprintf(stderr, " success\n");
        return 0;
}

void tape_rewind() {
        tape_command(MTREW, 1, "rewind");
}

void tape_filemark() {
        tape_command(MTWEOF, 1, "write filemark");
}

void tape_read(size_t count) {
        size_t rlen, arlen;
        fprintf(stderr, "%s: reading %d bytes using %d byte blocks... ",
                        me, (int)count, (int)BUFSIZE);
        while (count > 0) {
                rlen = (count > BUFSIZE) ? BUFSIZE : count;
                if ((arlen = read(fd, buf, rlen)) == -1) {
                        fprintf(stderr, "%s\n", sys_errlist[errno]);
                        return;
                } else if (arlen < rlen) {
                        fprintf(stderr, "short read: wanted %d, read %d\n",
                                rlen, arlen);
                        return;
                }
                fprintf(stderr, "+");
                count -= arlen;
        }
        fprintf(stderr, " success\n");
}

void tape_write(size_t count) {
        size_t wlen, awlen;
        memset(buf, 0x55, BUFSIZE);
        fprintf(stderr, "%s: writing %d bytes using %d byte blocks... ",
                        me, (int)count, (int)BUFSIZE);
        while (count > 0) {
                wlen = (count > BUFSIZE) ? BUFSIZE : count;
                if ((awlen = write(fd, buf, wlen)) == -1) {
                        fprintf(stderr, "%s\n", sys_errlist[errno]);
                        return;
                }
                else if (awlen < wlen) {
                        fprintf(stderr, "short write: wanted %d, wrote %d\n",
                                wlen, awlen);
                        return;
                }
                fprintf(stderr, "+");
                count -= awlen;
        }
        fprintf(stderr, " success\n");
}

void tape_skip_filemark() {
        /* expect the tape to be at end of file */
        fprintf(stderr, "%s: skipping file mark... ", me);
        read(fd, buf, BUFSIZE);
        fprintf(stderr, "done.");
}

void dosleep(int sec) {
        fprintf(stderr, "%s: sleeping for %d s...", me, sec);
        sleep(sec);
        fprintf(stderr, "woke up.\n");
}

int main(int argc, char **argv) {
        if (argc < 2) {
                fprintf(stderr, "usage: %s /dev/tapedevice\n", me);
                exit(1);
        }

        fd = open(argv[1], O_RDWR);
        if (fd < 0) {
                fprintf(stderr, "%s: open %s: %s\n", me, argv[1],
                                sys_errlist[errno]);
                exit(1);
        }

        tape_rewind();
        tape_read(32*1024);
        tape_rewind();
        tape_write(32768);
        /* 120 s = it fails. 60 s = it does not fail */
        dosleep(120);
        tape_filemark();
        tape_write(1024*1024);
        tape_filemark();

        tape_rewind();
        tape_read(32*1024);
        tape_skip_filemark();
        tape_read(1024*1024);

        close(fd);
        return 0;
}
-------------------------------------------8<-----


Reply via email to