abrantes's Mail:
> 
> The tape drive is OK. Some tests:
> 
> [... deleted ...]
> 
> # amtapetype -o -b 10240 -e 40g -f /dev/nst0 -t
> "DELL_POWERVAULT_110T_DLT_VS_80"
> Estimate phase 1...amtapetype: could not write any data in this pass:
> Success
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.

For me, the attached patch fixed the problem.

Bye
        \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