Jon LaBadie's Mail:
> On Wed, Mar 12, 2008 at 04:00:00PM +0100, Paul Bijnens wrote:
[...]
> > I seem to remember there was indeed a problem on some hosts
> > where rewind flagged success and finished, but the tape drive
> > was actually not ready to accept new requests, resulting in IO errors
> > until the tape was fully rewound.
> > 
> > But I do not remember anymore if or how it can be solved
> > (except by modifying the code and waiting longer after the rewind).
> > 
> 
> I was in that situation with a DDS3, 6 tape, tapechanger from HP.
> I ran amanda's use of mt and mtx through wrappers and inserted
> sleeps for various cmds (notably rewinds for up to 20 or 30 sec.)
> and I put in some repeats for things like status checks that
> failed the first time.

Back in May 2007 myselph wrote:

> I had a similar problem with with a DDS3 tape drive (HP-C1537A) connected
> to my alpha running (at that time) DU 4.0d.  It seemed to me that the
> drive / driver returns immediately after a rewind operation, but a
> following write on the same (kept-open) filedescriptor returns
> unsuccessfully if the rewind did not complete yet.  Amtapetype exactly
> does this.
> 
> The situation was not reproducible in my setup by a sequence of shell
> commands (like ``mt rewind; tar -c ...''), as each shell command is an own
> process and opens its own filedescriptor for accessing the tape.
The problem also existed after my box having been updated to Tru64 5.1B-3.

The attached patch (relative to 2.5.2) fixed the problem for me.

In June Ian Turner contacted me for testing alternative solutions
for the rewind / timeout / IO error problem, but on Tru64 only the
open / close workaround was fully successful.

I don't know, if the workaround has been integrated in more recent
versions of amanda.

Regards

        \franz
--- amanda-2.5.2-20070523/tape-src/tapetype.c.orig      Fri May  4 13:39:08 2007
+++ amanda-2.5.2-20070523/tape-src/tapetype.c   Wed May 30 09:30:24 2007
@@ -59,8 +59,9 @@
 static int writeblock(int fd);
 static off_t writeblocks(int fd, off_t nblks);
 static void allocrandombytes(void);
-static void do_pass0(off_t size, time_t *seconds, int dorewind);
-static void do_pass(off_t size, off_t *blocks, off_t *files, time_t *seconds);
+static void do_pass0(off_t size, time_t *seconds, int dorewind, char *tapedev);
+static void do_pass(off_t size, off_t *blocks, off_t *files, time_t *seconds,
+               char *tapedev);
 static void help(void);
 static void initnotrandombytes(void);
 static void initrandombytes(void);
@@ -143,7 +144,10 @@
   if ((w = tapefd_write(fd, getrandombytes(), blocksize)) == 
(ssize_t)blocksize) {
     return 1;
   }
-  if (w >= 0) {
+  /*
+  fprintf(stderr, "\nwriteblock(): w=%d, errno=%d\n", w, errno);
+  */
+  if (w != (size_t) -1) {
     short_write = 1;
   } else {
     short_write = 0;
@@ -222,7 +226,8 @@
     off_t      size,
     off_t *    blocks,
     off_t *    files,
-    time_t *   seconds)
+    time_t *   seconds,
+    char *     tapedev)
 {
   off_t blks;
   time_t start, end;
@@ -233,6 +238,12 @@
            sProgName, tapedev, strerror(errno));
     exit(1);
   }
+  if (((-1 == tapefd_close(fd)) ||
+       (-1 == (fd = tape_open(tapedev, O_RDWR))))) {
+    fprintf(stderr, "%s: could not re-open %s: %s\n",
+           sProgName, tapedev, strerror(errno));
+    exit(1);
+  }
 
   time(&start);
 
@@ -280,7 +291,8 @@
 do_pass0(
     off_t      size,
     time_t *   seconds,
-    int                dorewind)
+    int                dorewind,
+    char *     tapedev)
 {
   off_t blks;
   time_t start, end;
@@ -291,6 +303,13 @@
            sProgName, tapedev, strerror(errno));
     exit(1);
   }
+  if (dorewind &&
+      ((-1 == tapefd_close(fd)) ||
+       (-1 == (fd = tape_open(tapedev, O_RDWR))))) {
+    fprintf(stderr, "%s: could not re-open %s: %s\n",
+           sProgName, tapedev, strerror(errno));
+    exit(1);
+  }
 
   time(&start);
 
@@ -530,8 +549,8 @@
      * first a dummy pass to rewind, stop, start and
      * get drive streaming, then do the real timing
      */
-    do_pass0(pass0size, &pass2time, 1);
-    do_pass0(pass0size, &pass1time, 0);
+    do_pass0(pass0size, &pass2time, 1, tapedev);
+    do_pass0(pass0size, &pass1time, 0, tapedev);
     if (pass0size >= (off_t)(10 * 1024 * 1024)) {
       fprintf(stderr,
        "\rTape device is too fast to detect hardware compression...\n");
@@ -552,8 +571,8 @@
   initrandombytes();
 
   fprintf(stderr, "Estimate phase 2...");
-  do_pass0(pass0size, &pass2time, 1);  /* rewind and get drive streaming */
-  do_pass0(pass0size, &pass2time, 0);
+  do_pass0(pass0size, &pass2time, 1, tapedev); /* rewind and get drive 
streaming */
+  do_pass0(pass0size, &pass2time, 0, tapedev);
   fprintf(stderr, "\rWriting " OFF_T_FMT
        " Mbyte uncompresseable data:  " TIME_T_FMT " sec\n",
        (OFF_T_FMT_TYPE)((off_t)blockkb * pass0size / (off_t)1024),
@@ -603,13 +622,13 @@
   if(pass1size <= (off_t)0) {
     pass1size = (off_t)2;                              /* strange end case */
   }
-  do_pass(pass1size, &pass1blocks, &pass1files, &pass1time);
+  do_pass(pass1size, &pass1blocks, &pass1files, &pass1time, tapedev);
 
   /*
    * Do pass 2 -- write smaller files until error.
    */
   pass2size = pass1size / (off_t)2;
-  do_pass(pass2size, &pass2blocks, &pass2files, &pass2time);
+  do_pass(pass2size, &pass2blocks, &pass2files, &pass2time, tapedev);
 
   /*
    * Compute the size of a filemark as the difference in data written

Reply via email to