]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/dev.c
Use rentrant mysql lib, eliminate race in sql_list, Win32 streams, misc see kes-1.31
[bacula/bacula] / bacula / src / stored / dev.c
index 24572066b43e51cfe928e4cd645bae31900ed492..a6c3bee4fdb06e77e6368100c115add99f69ed27 100644 (file)
@@ -146,13 +146,12 @@ init_dev(DEVICE *dev, DEVRES *device)
    dev->capabilities = device->cap_bits;
    dev->min_block_size = device->min_block_size;
    dev->max_block_size = device->max_block_size;
-   dev->max_volume_jobs = device->max_volume_jobs;
-   dev->max_volume_files = device->max_volume_files;
    dev->max_volume_size = device->max_volume_size;
    dev->max_file_size = device->max_file_size;
    dev->volume_capacity = device->volume_capacity;
    dev->max_rewind_wait = device->max_rewind_wait;
    dev->max_open_wait = device->max_open_wait;
+   dev->max_open_vols = device->max_open_vols;
    dev->device = device;
 
    if (tape) {
@@ -259,7 +258,7 @@ open_dev(DEVICE *dev, char *VolName, int mode)
         }
         if (errno == EBUSY && timeout-- > 0) {
             Dmsg2(100, "Device %s busy. ERR=%s\n", dev->dev_name, strerror(errno));
-           sleep(1);
+           bmicrosleep(1, 0);
            continue;
         }
         dev->dev_errno = errno;
@@ -287,7 +286,7 @@ open_dev(DEVICE *dev, char *VolName, int mode)
       Dmsg1(29, "open_dev: tape %d opened\n", dev->fd);
    } else {
       /*
-       * Handle opening of file
+       * Handle opening of File Archive (not a tape)
        */
       archive_name = get_pool_memory(PM_FNAME);
       pm_strcpy(&archive_name, dev->dev_name);
@@ -305,7 +304,8 @@ open_dev(DEVICE *dev, char *VolName, int mode)
       } else {
          Emsg0(M_ABORT, 0, _("Illegal mode given to open_dev.\n")); 
       }
-      if ((dev->fd = open(archive_name, dev->mode, MODE_RW)) < 0) {
+      /* If creating file, give 0640 permissions */
+      if ((dev->fd = open(archive_name, dev->mode, 0640)) < 0) {
         dev->dev_errno = errno;
          Mmsg2(&dev->errmsg, _("Could not open: %s, ERR=%s\n"), archive_name, strerror(dev->dev_errno));
         Emsg0(M_FATAL, 0, dev->errmsg);
@@ -357,7 +357,7 @@ int rewind_dev(DEVICE *dev)
            clrerror_dev(dev, MTREW);
            if (dev->dev_errno == EIO && i > 0) {
                Dmsg0(200, "Sleeping 5 seconds.\n");
-              sleep(5);
+              bmicrosleep(5, 0);
               continue;
            }
             Mmsg2(&dev->errmsg, _("Rewind error on %s. ERR=%s.\n"),
@@ -410,7 +410,8 @@ eod_dev(DEVICE *dev)
       }
       return 0;
    }
-   if (dev->capabilities & CAP_EOM) {
+#ifdef MTEOM
+   if (dev_cap(dev, CAP_EOM)) {
       mt_com.mt_op = MTEOM;
       mt_com.mt_count = 1;
       if ((stat=ioctl(dev->fd, MTIOCTOP, (char *)&mt_com)) < 0) {
@@ -434,6 +435,9 @@ eod_dev(DEVICE *dev)
     * Rewind then use FSF until EOT reached
     */
    } else {
+#else
+   {
+#endif
       if (!rewind_dev(dev)) {
         return 0;
       }
@@ -445,9 +449,20 @@ eod_dev(DEVICE *dev)
         }
       }
    }
-   update_pos_dev(dev);                     /* update position */
+   /*
+    * Some drivers leave us after second EOF when doing
+    * MTEOM, so we must backup so that appending overwrites
+    * the second EOF.
+    */
+   if (dev_cap(dev, CAP_BSFATEOM)) {
+      stat =  (bsf_dev(dev, 1) == 0);
+      dev->file++;                   /* keep same file */
+   } else {
+      update_pos_dev(dev);                  /* update position */
+      stat = 1;
+   }
    Dmsg1(200, "EOD dev->file=%d\n", dev->file);
-   return 1;
+   return stat;
 }
 
 /*
@@ -474,7 +489,7 @@ int update_pos_dev(DEVICE *dev)
       dev->file_addr = 0;
       pos = lseek(dev->fd, (off_t)0, SEEK_CUR);
       if (pos < 0) {
-         Dmsg1(000, "Seek error: ERR=%s\n", strerror(dev->dev_errno));
+         Pmsg1(000, "Seek error: ERR=%s\n", strerror(dev->dev_errno));
         dev->dev_errno = errno;
          Mmsg2(&dev->errmsg, _("lseek error on %s. ERR=%s.\n"),
            dev->dev_name, strerror(dev->dev_errno));
@@ -505,15 +520,15 @@ status_dev(DEVICE *dev, uint32_t *status)
    uint32_t stat = 0;
 
    if (dev->state & (ST_EOT | ST_WEOT)) {
-      stat |= MT_EOD;
+      stat |= BMT_EOD;
       Dmsg0(-20, " EOD");
    }
    if (dev->state & ST_EOF) {
-      stat |= MT_EOF;
+      stat |= BMT_EOF;
       Dmsg0(-20, " EOF");
    }
    if (dev->state & ST_TAPE) {
-      stat |= MT_TAPE;
+      stat |= BMT_TAPE;
       Dmsg0(-20," Driver status:");
       Dmsg2(-20," file=%d block=%d\n", dev->file, dev->block_num);
       if (ioctl(dev->fd, MTIOCGET, (char *)&mt_stat) < 0) {
@@ -526,45 +541,45 @@ status_dev(DEVICE *dev, uint32_t *status)
 
 #if defined(HAVE_LINUX_OS)
       if (GMT_EOF(mt_stat.mt_gstat)) {
-        stat |= MT_EOF;
+        stat |= BMT_EOF;
          Dmsg0(-20, " EOF");
       }
       if (GMT_BOT(mt_stat.mt_gstat)) {
-        stat |= MT_BOT;
+        stat |= BMT_BOT;
          Dmsg0(-20, " BOT");
       }
       if (GMT_EOT(mt_stat.mt_gstat)) {
-        stat |= MT_EOT;
+        stat |= BMT_EOT;
          Dmsg0(-20, " EOT");
       }
       if (GMT_SM(mt_stat.mt_gstat)) {
-        stat |= MT_SM;
+        stat |= BMT_SM;
          Dmsg0(-20, " SM");
       }
       if (GMT_EOD(mt_stat.mt_gstat)) {
-        stat |= MT_EOD;
+        stat |= BMT_EOD;
          Dmsg0(-20, " EOD");
       }
       if (GMT_WR_PROT(mt_stat.mt_gstat)) {
-        stat |= MT_WR_PROT;
+        stat |= BMT_WR_PROT;
          Dmsg0(-20, " WR_PROT");
       }
       if (GMT_ONLINE(mt_stat.mt_gstat)) {
-        stat |= MT_ONLINE;
+        stat |= BMT_ONLINE;
          Dmsg0(-20, " ONLINE");
       }
       if (GMT_DR_OPEN(mt_stat.mt_gstat)) {
-        stat |= MT_DR_OPEN;
+        stat |= BMT_DR_OPEN;
          Dmsg0(-20, " DR_OPEN");       
       }
       if (GMT_IM_REP_EN(mt_stat.mt_gstat)) {
-        stat |= MT_IM_REP_EN;
+        stat |= BMT_IM_REP_EN;
          Dmsg0(-20, " IM_REP_EN");
       }
 #endif /* !SunOS && !OSF */
       Dmsg2(-20, " file=%d block=%d\n", mt_stat.mt_fileno, mt_stat.mt_blkno);
    } else {
-      stat |= MT_ONLINE | MT_BOT;
+      stat |= BMT_ONLINE | BMT_BOT;
    }
    *status = stat; 
    return 1;
@@ -661,7 +676,6 @@ fsf_dev(DEVICE *dev, int num)
 { 
    struct mtop mt_com;
    int stat = 0;
-   char rbuf[1024];
 
    if (dev->fd < 0) {
       dev->dev_errno = EBADF;
@@ -678,26 +692,37 @@ fsf_dev(DEVICE *dev, int num)
       Mmsg1(&dev->errmsg, _("Device %s at End of Tape.\n"), dev->dev_name);
       return 0;
    }
-   if (dev->state & ST_EOF)
+   if (dev->state & ST_EOF) {
       Dmsg0(200, "ST_EOF set on entry to FSF\n");
-   if (dev->state & ST_EOT)
+   }
+   if (dev->state & ST_EOT) {
       Dmsg0(200, "ST_EOT set on entry to FSF\n");
+   }
       
    Dmsg0(29, "fsf_dev\n");
    dev->block_num = 0;
-   if (dev->capabilities & CAP_FSF) {
+   if (dev_cap(dev, CAP_FSF)) {
+      POOLMEM *rbuf;
+      int rbuf_len;
       Dmsg0(200, "FSF has cap_fsf\n");
+      if (dev->max_block_size == 0) {
+        rbuf_len = DEFAULT_BLOCK_SIZE;
+      } else {
+        rbuf_len = dev->max_block_size;
+      }
+      rbuf = get_memory(rbuf_len);
       mt_com.mt_op = MTFSF;
       mt_com.mt_count = 1;
       while (num-- && !(dev->state & ST_EOT)) {
-         Dmsg0(200, "Doing read for fsf\n");
-        if ((stat = read(dev->fd, rbuf, sizeof(rbuf))) < 0) {
+         Dmsg0(200, "Doing read before fsf\n");
+        if ((stat = read(dev->fd, (char *)rbuf, rbuf_len)) < 0) {
            if (errno == ENOMEM) {     /* tape record exceeds buf len */
-              stat = sizeof(rbuf);   /* This is OK */
+              stat = rbuf_len;        /* This is OK */
            } else {
               dev->state |= ST_EOT;
               clrerror_dev(dev, -1);
-               Dmsg1(200, "Set ST_EOT read error %d\n", dev->dev_errno);
+               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));
                Dmsg1(200, "%s", dev->errmsg);
@@ -722,7 +747,7 @@ fsf_dev(DEVICE *dev, int num)
            dev->state &= ~(ST_EOF|ST_EOT);
         }
 
-         Dmsg0(200, "Doing MT_FSF\n");
+         Dmsg0(200, "Doing MTFSF\n");
         stat = ioctl(dev->fd, MTIOCTOP, (char *)&mt_com);
         if (stat < 0) {                 /* error => EOT */
            dev->state |= ST_EOT;
@@ -730,7 +755,7 @@ fsf_dev(DEVICE *dev, int num)
            clrerror_dev(dev, MTFSF);
             Mmsg2(&dev->errmsg, _("ioctl MTFSF error on %s. ERR=%s.\n"),
               dev->dev_name, strerror(dev->dev_errno));
-            Dmsg0(200, "Got < 0 for MT_FSF\n");
+            Dmsg0(200, "Got < 0 for MTFSF\n");
             Dmsg1(200, "%s", dev->errmsg);
         } else {
            dev->state |= ST_EOF;     /* just read EOF */
@@ -738,6 +763,7 @@ fsf_dev(DEVICE *dev, int num)
            dev->file_addr = 0;
         }   
       }
+      free_memory(rbuf);
    
    /*
     * No FSF, so use FSR to simulate it
@@ -883,6 +909,8 @@ bsr_dev(DEVICE *dev, int num)
 
 /*
  * Write an end of file on the device
+ *   Returns: 0 on success
+ *           non-zero on failure
  */
 int 
 weof_dev(DEVICE *dev, int num)
@@ -956,10 +984,12 @@ clrerror_dev(DEVICE *dev, int func)
             msg = "WTWEOF";
            dev->capabilities &= ~CAP_EOF; /* turn off feature */
            break;
+#ifdef MTEOM
         case MTEOM:
             msg = "WTEOM";
            dev->capabilities &= ~CAP_EOM; /* turn off feature */
            break;
+#endif 
         case MTFSF:
             msg = "MTFSF";
            dev->capabilities &= ~CAP_FSF; /* turn off feature */