]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/dev.c
Oops
[bacula/bacula] / bacula / src / stored / dev.c
index 52320bd725c5d90c41b15f6d2b4f5f1a38950f08..4d770d3726ef763379130eda81985a92bb675277 100644 (file)
@@ -81,6 +81,7 @@
 #include "stored.h"
 
 /* Forward referenced functions */
+void set_os_device_parameters(DEVICE *dev);
 
 /* 
  * Allocate and initialize the DEVICE structure
@@ -103,11 +104,12 @@ init_dev(DEVICE *dev, DEVRES *device)
 
    /* Check that device is available */
    if (stat(device->device_name, &statp) < 0) {
+      berrno be;
       if (dev) {
         dev->dev_errno = errno;
       } 
       Emsg2(M_FATAL, 0, "Unable to stat device %s : %s\n", device->device_name, 
-           strerror(errno));
+           be.strerror());
       return NULL;
    }
    tape = false;
@@ -178,28 +180,33 @@ init_dev(DEVICE *dev, DEVRES *device)
    *dev->errmsg = 0;
 
    if ((errstat = pthread_mutex_init(&dev->mutex, NULL)) != 0) {
+      berrno be;
       dev->dev_errno = errstat;
-      Mmsg1(&dev->errmsg, _("Unable to init mutex: ERR=%s\n"), strerror(errstat));
+      Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.strerror(errstat));
       Emsg0(M_FATAL, 0, dev->errmsg);
    }
    if ((errstat = pthread_cond_init(&dev->wait, NULL)) != 0) {
+      berrno be;
       dev->dev_errno = errstat;
-      Mmsg1(&dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), strerror(errstat));
+      Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), be.strerror(errstat));
       Emsg0(M_FATAL, 0, dev->errmsg);
    }
    if ((errstat = pthread_cond_init(&dev->wait_next_vol, NULL)) != 0) {
+      berrno be;
       dev->dev_errno = errstat;
-      Mmsg1(&dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), strerror(errstat));
+      Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), be.strerror(errstat));
       Emsg0(M_FATAL, 0, dev->errmsg);
    }
    if ((errstat = pthread_mutex_init(&dev->spool_mutex, NULL)) != 0) {
+      berrno be;
       dev->dev_errno = errstat;
-      Mmsg1(&dev->errmsg, _("Unable to init mutex: ERR=%s\n"), strerror(errstat));
+      Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.strerror(errstat));
       Emsg0(M_FATAL, 0, dev->errmsg);
    }
    if ((errstat = rwl_init(&dev->lock)) != 0) {
+      berrno be;
       dev->dev_errno = errstat;
-      Mmsg1(&dev->errmsg, _("Unable to init mutex: ERR=%s\n"), strerror(errstat));
+      Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.strerror(errstat));
       Emsg0(M_FATAL, 0, dev->errmsg);
    }
 
@@ -291,6 +298,7 @@ open_dev(DEVICE *dev, char *VolName, int mode)
         dev->state |= ST_OPENED;
         dev->use_count = 1;
         update_pos_dev(dev);             /* update position */
+        set_os_device_parameters(dev);      /* do system dependent stuff */
       }
       /* Stop any open() timer we started */
       if (dev->tid) {
@@ -308,11 +316,11 @@ open_dev(DEVICE *dev, char *VolName, int mode)
         return -1;
       }
       archive_name = get_pool_memory(PM_FNAME);
-      pm_strcpy(&archive_name, dev->dev_name);
+      pm_strcpy(archive_name, dev->dev_name);
       if (archive_name[strlen(archive_name)] != '/') {
-         pm_strcat(&archive_name, "/");
+         pm_strcat(archive_name, "/");
       }
-      pm_strcat(&archive_name, VolName);
+      pm_strcat(archive_name, VolName);
       Dmsg1(29, "open_dev: device is disk %s\n", archive_name);
       if (mode == OPEN_READ_WRITE) {
         dev->mode = O_CREAT | O_RDWR | O_BINARY;
@@ -516,7 +524,7 @@ eod_dev(DEVICE *dev)
             Dmsg1(100, "fsf_dev did not advance from file %d\n", file_num);
            if (ioctl(dev->fd, MTIOCGET, (char *)&mt_stat) == 0 && 
                      mt_stat.mt_fileno >= 0) {
-               Dmsg2(000, "Adjust file from %d to %d\n", dev->file , mt_stat.mt_fileno);
+               Dmsg2(100, "Adjust file from %d to %d\n", dev->file , mt_stat.mt_fileno);
               dev->file = mt_stat.mt_fileno;
            }
            stat = 0;
@@ -786,7 +794,7 @@ fsf_dev(DEVICE *dev, int num)
    }
    if (dev->state & ST_EOT) {
       dev->dev_errno = 0;
-      Mmsg1(&dev->errmsg, _("Device %s at End of Tape.\n"), dev->dev_name);
+      Mmsg1(dev->errmsg, _("Device %s at End of Tape.\n"), dev->dev_name);
       return false;
    }
    if (dev->state & ST_EOF) {
@@ -807,11 +815,12 @@ fsf_dev(DEVICE *dev, int num)
       mt_com.mt_count = num;
       stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
       if (stat < 0 || ioctl(dev->fd, MTIOCGET, (char *)&mt_stat) < 0) {
+        berrno be;
         dev->state |= ST_EOT;
          Dmsg0(200, "Set ST_EOT\n");
         clrerror_dev(dev, MTFSF);
-         Mmsg2(&dev->errmsg, _("ioctl MTFSF error on %s. ERR=%s.\n"),
-           dev->dev_name, strerror(dev->dev_errno));
+         Mmsg2(dev->errmsg, _("ioctl MTFSF error on %s. ERR=%s.\n"),
+           dev->dev_name, be.strerror());
          Dmsg1(200, "%s", dev->errmsg);
         return false;
       }
@@ -846,12 +855,13 @@ fsf_dev(DEVICE *dev, int num)
            if (errno == ENOMEM) {     /* tape record exceeds buf len */
               stat = rbuf_len;        /* This is OK */
            } else {
+              berrno be;
               dev->state |= ST_EOT;
               clrerror_dev(dev, -1);
                Dmsg2(200, "Set ST_EOT read errno=%d. ERR=%s\n", dev->dev_errno,
-                 strerror(dev->dev_errno));
-               Mmsg2(&dev->errmsg, _("read error on %s. ERR=%s.\n"),
-                 dev->dev_name, strerror(dev->dev_errno));
+                 be.strerror());
+               Mmsg2(dev->errmsg, _("read error on %s. ERR=%s.\n"),
+                 dev->dev_name, be.strerror(dev->dev_errno));
                Dmsg1(200, "%s", dev->errmsg);
               break;
            }
@@ -902,7 +912,7 @@ fsf_dev(DEVICE *dev, int num)
       }
       if (dev->state & ST_EOT) {
         dev->dev_errno = 0;
-         Mmsg1(&dev->errmsg, _("Device %s at End of Tape.\n"), dev->dev_name);
+         Mmsg1(dev->errmsg, _("Device %s at End of Tape.\n"), dev->dev_name);
         stat = -1;
       } else {
         stat = 0;
@@ -931,13 +941,13 @@ bsf_dev(DEVICE *dev, int num)
 
    if (dev->fd < 0) {
       dev->dev_errno = EBADF;
-      Mmsg0(&dev->errmsg, _("Bad call to bsf_dev. Archive device not open\n"));
+      Mmsg0(dev->errmsg, _("Bad call to bsf_dev. Archive device not open\n"));
       Emsg0(M_FATAL, 0, dev->errmsg);
       return false;
    }
 
    if (!(dev_state(dev, ST_TAPE))) {
-      Mmsg1(&dev->errmsg, _("Device %s cannot BSF because it is not a tape.\n"),
+      Mmsg1(dev->errmsg, _("Device %s cannot BSF because it is not a tape.\n"),
         dev->dev_name);
       return false;
    }
@@ -950,7 +960,7 @@ bsf_dev(DEVICE *dev, int num)
    stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
    if (stat < 0) {
       clrerror_dev(dev, MTBSF);
-      Mmsg2(&dev->errmsg, _("ioctl MTBSF error on %s. ERR=%s.\n"),
+      Mmsg2(dev->errmsg, _("ioctl MTBSF error on %s. ERR=%s.\n"),
         dev->dev_name, strerror(dev->dev_errno));
    }
    update_pos_dev(dev);
@@ -971,7 +981,7 @@ fsr_dev(DEVICE *dev, int num)
 
    if (dev->fd < 0) {
       dev->dev_errno = EBADF;
-      Mmsg0(&dev->errmsg, _("Bad call to fsr_dev. Archive not open\n"));
+      Mmsg0(dev->errmsg, _("Bad call to fsr_dev. Archive not open\n"));
       Emsg0(M_FATAL, 0, dev->errmsg);
       return false;
    }
@@ -980,7 +990,7 @@ fsr_dev(DEVICE *dev, int num)
       return false;
    }
    if (!dev_cap(dev, CAP_FSR)) {
-      Mmsg1(&dev->errmsg, _("ioctl MTFSR not permitted on %s.\n"), dev->dev_name);
+      Mmsg1(dev->errmsg, _("ioctl MTFSR not permitted on %s.\n"), dev->dev_name);
       return false;
    }
 
@@ -1009,7 +1019,7 @@ fsr_dev(DEVICE *dev, int num)
         }
       }
       clrerror_dev(dev, MTFSR);
-      Mmsg2(&dev->errmsg, _("ioctl MTFSR error on %s. ERR=%s.\n"),
+      Mmsg2(dev->errmsg, _("ioctl MTFSR error on %s. ERR=%s.\n"),
         dev->dev_name, strerror(dev->dev_errno));
    }
    update_pos_dev(dev);
@@ -1029,7 +1039,7 @@ bsr_dev(DEVICE *dev, int num)
 
    if (dev->fd < 0) {
       dev->dev_errno = EBADF;
-      Mmsg0(&dev->errmsg, _("Bad call to bsr_dev. Archive not open\n"));
+      Mmsg0(dev->errmsg, _("Bad call to bsr_dev. Archive not open\n"));
       Emsg0(M_FATAL, 0, dev->errmsg);
       return false;
    }
@@ -1039,7 +1049,7 @@ bsr_dev(DEVICE *dev, int num)
    }
 
    if (!dev_cap(dev, CAP_BSR)) {
-      Mmsg1(&dev->errmsg, _("ioctl MTBSR not permitted on %s.\n"), dev->dev_name);
+      Mmsg1(dev->errmsg, _("ioctl MTBSR not permitted on %s.\n"), dev->dev_name);
       return false;
    }
 
@@ -1051,7 +1061,7 @@ bsr_dev(DEVICE *dev, int num)
    stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
    if (stat < 0) {
       clrerror_dev(dev, MTBSR);
-      Mmsg2(&dev->errmsg, _("ioctl MTBSR error on %s. ERR=%s.\n"),
+      Mmsg2(dev->errmsg, _("ioctl MTBSR error on %s. ERR=%s.\n"),
         dev->dev_name, strerror(dev->dev_errno));
    }
    update_pos_dev(dev);
@@ -1068,7 +1078,7 @@ reposition_dev(DEVICE *dev, uint32_t file, uint32_t block)
 { 
    if (dev->fd < 0) {
       dev->dev_errno = EBADF;
-      Mmsg0(&dev->errmsg, _("Bad call to reposition_dev. Archive not open\n"));
+      Mmsg0(dev->errmsg, _("Bad call to reposition_dev. Archive not open\n"));
       Emsg0(M_FATAL, 0, dev->errmsg);
       return false;
    }
@@ -1078,7 +1088,7 @@ reposition_dev(DEVICE *dev, uint32_t file, uint32_t block)
       Dmsg1(100, "===== lseek to %d\n", (int)pos);
       if (lseek(dev->fd, pos, SEEK_SET) == (off_t)-1) {
         dev->dev_errno = errno;
-         Mmsg2(&dev->errmsg, _("lseek error on %s. ERR=%s.\n"),
+         Mmsg2(dev->errmsg, _("lseek error on %s. ERR=%s.\n"),
            dev->dev_name, strerror(dev->dev_errno));
         return false;
       }
@@ -1105,7 +1115,7 @@ reposition_dev(DEVICE *dev, uint32_t file, uint32_t block)
       bsf_dev(dev, 1);
       fsf_dev(dev, 1);
    }
-   if (block > dev->block_num) {
+   if (dev_cap(dev, CAP_POSITIONBLOCKS) && block > dev->block_num) {
       /* Ignore errors as Bacula can read to the correct block */
       Dmsg1(100, "fsr %d\n", block-dev->block_num);
       return fsr_dev(dev, block-dev->block_num);
@@ -1128,7 +1138,7 @@ weof_dev(DEVICE *dev, int num)
 
    if (dev->fd < 0) {
       dev->dev_errno = EBADF;
-      Mmsg0(&dev->errmsg, _("Bad call to weof_dev. Archive drive not open\n"));
+      Mmsg0(dev->errmsg, _("Bad call to weof_dev. Archive drive not open\n"));
       Emsg0(M_FATAL, 0, dev->errmsg);
       return -1;
    }
@@ -1146,10 +1156,11 @@ weof_dev(DEVICE *dev, int num)
       dev->file += num;
       dev->file_addr = 0;
    } else {
+      berrno be;
       clrerror_dev(dev, MTWEOF);
       if (stat == -1) {
-         Mmsg2(&dev->errmsg, _("ioctl MTWEOF error on %s. ERR=%s.\n"),
-           dev->dev_name, strerror(dev->dev_errno));
+         Mmsg2(dev->errmsg, _("ioctl MTWEOF error on %s. ERR=%s.\n"),
+           dev->dev_name, be.strerror());
        }
    }
    return stat;
@@ -1176,6 +1187,7 @@ void
 clrerror_dev(DEVICE *dev, int func)
 {
    const char *msg = NULL;
+   struct mtget mt_stat;
 
    dev->dev_errno = errno;        /* save errno */
    if (errno == EIO) {
@@ -1226,6 +1238,9 @@ clrerror_dev(DEVICE *dev, int func)
         Emsg0(M_ERROR, 0, dev->errmsg);
       }
    }
+   /* On some systems such as NetBSD, this clears all errors */
+   ioctl(dev->fd, MTIOCGET, (char *)&mt_stat);     
+
 /* Found on Linux */
 #ifdef MTIOCLRERR
 {
@@ -1248,6 +1263,18 @@ clrerror_dev(DEVICE *dev, int func)
    ioctl(dev->fd, MTIOCERRSTAT, (char *)&mt_errstat);
 }
 #endif
+
+/* Clear Subsystem Exception OSF1 */
+#ifdef MTCSE
+{
+   struct mtop mt_com;
+   mt_com.mt_op = MTCSE;
+   mt_com.mt_count = 1;
+   /* Clear any error condition on the tape */
+   ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
+   Dmsg0(200, "Did MTCSE\n");
+}
+#endif
 }
 
 /*
@@ -1418,47 +1445,6 @@ term_dev(DEVICE *dev)
    }
 }
 
-#ifdef xxxx
-/*
- * We attach a jcr to the device so that when
- *   the Volume is full during writing, a  
- *   JobMedia record will be created for this 
- *   Job.
- */
-void attach_jcr_to_device(DEVICE *dev, JCR *jcr)
-{
-   jcr->prev_dev = (JCR *)NULL;
-   jcr->next_dev = dev->attached_jcrs;
-   if (dev->attached_jcrs) {
-      dev->attached_jcrs->prev_dev = jcr;
-   }
-   dev->attached_jcrs = jcr;
-   Dmsg1(100, "Attached Job %s\n", jcr->Job);
-}
-
-void detach_jcr_from_device(DEVICE *dev, JCR *jcr)
-{
-   if (!jcr->prev_dev) {
-      dev->attached_jcrs = jcr->next_dev;
-   } else {
-      jcr->prev_dev->next_dev = jcr->next_dev;
-   }
-   if (jcr->next_dev) {
-      jcr->next_dev->prev_dev = jcr->prev_dev; 
-   }
-   jcr->next_dev = jcr->prev_dev = NULL;
-   Dmsg1(100, "Detached Job %s\n", jcr->Job);
-}
-
-JCR *next_attached_jcr(DEVICE *dev, JCR *jcr)
-{
-   if (jcr == (JCR *)NULL) {
-      return dev->attached_jcrs;
-   }
-   return jcr->next_dev;
-}
-#endif
-
 /*
  * This routine initializes the device wait timers
  */
@@ -1492,3 +1478,76 @@ bool double_dev_wait_time(DEVICE *dev)
    }
    return true;
 }
+
+void set_os_device_parameters(DEVICE *dev)
+{
+#ifdef HAVE_LINUX_OS
+   struct mtop mt_com;
+   if (dev->min_block_size == dev->max_block_size &&
+       dev->min_block_size == 0) {    /* variable block mode */
+      mt_com.mt_op = MTSETBLK;
+      mt_com.mt_count = 0;
+      if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
+        clrerror_dev(dev, MTSETBLK);
+      }
+      mt_com.mt_op = MTSETDRVBUFFER;
+      mt_com.mt_count = MT_ST_CLEARBOOLEANS;
+      if (!dev_cap(dev, CAP_TWOEOF)) {
+        mt_com.mt_count |= MT_ST_TWO_FM;
+      }
+      if (dev_cap(dev, CAP_EOM)) {
+        mt_com.mt_count |= MT_ST_FAST_MTEOM;
+      }
+      if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
+        clrerror_dev(dev, MTSETBLK);
+      }
+   }
+   return;
+#endif
+
+#ifdef HAVE_NETBSD_OS
+   struct mtop mt_com;
+   if (dev->min_block_size == dev->max_block_size &&
+       dev->min_block_size == 0) {    /* variable block mode */
+      mt_com.mt_op = MTSETBSIZ;
+      mt_com.mt_count = 0;
+      if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
+        clrerror_dev(dev, MTSETBSIZ);
+      }
+      /* Get notified at logical end of tape */
+      mt_com.mt_op = MTEWARN;
+      mt_com.mt_count = 1;
+      if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
+        clrerror_dev(dev, MTEWARN);
+      }
+   }
+   return;
+#endif
+
+#if HAVE_FREEBSD_OS || HAVE_OPENBSD_OS
+   struct mtop mt_com;
+   if (dev->min_block_size == dev->max_block_size &&
+       dev->min_block_size == 0) {    /* variable block mode */
+      mt_com.mt_op = MTSETBSIZ;
+      mt_com.mt_count = 0;
+      if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
+        clrerror_dev(dev, MTSETBSIZ);
+      }
+   }
+   return;
+#endif
+
+#ifdef HAVE_SUN_OS
+   struct mtop mt_com;
+   if (dev->min_block_size == dev->max_block_size &&
+       dev->min_block_size == 0) {    /* variable block mode */
+      mt_com.mt_op = MTSRSZ;
+      mt_com.mt_count = 0;
+      if (ioctl(dev->fd, MTIOCTOP, (char *)&mt_com) < 0) {
+        clrerror_dev(dev, MTSRSZ);
+      }
+   }
+   return;
+#endif
+
+}