]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/dev.c
Add address and socket for MySQL
[bacula/bacula] / bacula / src / stored / dev.c
index f1b62ab247f22f66d73816b76fe10af432b75077..e19032544d6251c6092e8edbf9a52f437bbdeef8 100644 (file)
@@ -29,7 +29,7 @@
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -104,7 +104,7 @@ DEVICE *
 init_dev(DEVICE *dev, DEVRES *device)
 {
    struct stat statp;
-   int tape;
+   int tape, fifo;
    int errstat;
 
    /* Check that device is available */
@@ -117,10 +117,13 @@ init_dev(DEVICE *dev, DEVRES *device)
       return NULL;
    }
    tape = FALSE;
+   fifo = FALSE;
    if (S_ISDIR(statp.st_mode)) {
       tape = FALSE;
    } else if (S_ISCHR(statp.st_mode)) {
       tape = TRUE;
+   } else if (S_ISFIFO(statp.st_mode)) {
+      fifo = TRUE;
    } else {
       if (dev) {
         dev->dev_errno = ENODEV;
@@ -136,9 +139,6 @@ init_dev(DEVICE *dev, DEVRES *device)
    } else {
       memset(dev, 0, sizeof(DEVICE));
    }
-   if (tape) {
-      dev->state |= ST_TAPE;
-   }
 
    /* Copy user supplied device parameters from Resource */
    dev->dev_name = get_memory(strlen(device->device_name)+1);
@@ -153,8 +153,18 @@ init_dev(DEVICE *dev, DEVRES *device)
    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) {
+      dev->state |= ST_TAPE;
+   } else if (fifo) {
+      dev->state |= ST_FIFO;
+      dev->capabilities |= CAP_STREAM; /* set stream device */
+   } else {
+      dev->state |= ST_FILE;
+   }
+
    if (dev->max_block_size > 1000000) {
       Emsg3(M_ERROR, 0, _("Block size %u on device %s is too large, using default %u\n"), 
         dev->max_block_size, dev->dev_name, DEFAULT_BLOCK_SIZE);
@@ -215,7 +225,7 @@ open_dev(DEVICE *dev, char *VolName, int mode)
       dev->use_count++;
       Mmsg2(&dev->errmsg, _("WARNING!!!! device %s opened %d times!!!\n"), 
            dev->dev_name, dev->use_count);
-      Emsg0(M_WARNING, 0, dev->errmsg);
+      Emsg1(M_WARNING, 0, "%s", dev->errmsg);
       return dev->fd;
    }
    if (VolName) {
@@ -225,17 +235,29 @@ open_dev(DEVICE *dev, char *VolName, int mode)
    Dmsg3(29, "open_dev: tape=%d dev_name=%s vol=%s\n", dev_is_tape(dev), 
         dev->dev_name, dev->VolCatInfo.VolCatName);
    dev->state &= ~(ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
-   if (dev->state & ST_TAPE) {
+   if (dev->state & (ST_TAPE|ST_FIFO)) {
       int timeout;
       Dmsg0(29, "open_dev: device is tape\n");
-      if (mode == READ_WRITE) {
+      if (mode == OPEN_READ_WRITE) {
         dev->mode = O_RDWR | O_BINARY;
-      } else {
+      } else if (mode == OPEN_READ_ONLY) {
         dev->mode = O_RDONLY | O_BINARY;
+      } else if (mode == OPEN_WRITE_ONLY) {
+        dev->mode = O_WRONLY | O_BINARY;
+      } else {
+         Emsg0(M_ABORT, 0, _("Illegal mode given to open_dev.\n")); 
       }
       timeout = dev->max_open_wait;
       errno = 0;
+      if (dev->state & ST_FIFO && timeout) {
+        /* Set open timer */
+        dev->tid = start_thread_timer(pthread_self(), timeout);
+      }
+      /* If busy retry each second for max_open_wait seconds */
       while ((dev->fd = open(dev->dev_name, dev->mode, MODE_RW)) < 0) {
+        if (errno == EAGAIN) {
+           continue;
+        }
         if (errno == EBUSY && timeout-- > 0) {
             Dmsg2(100, "Device %s busy. ERR=%s\n", dev->dev_name, strerror(errno));
            sleep(1);
@@ -244,6 +266,11 @@ open_dev(DEVICE *dev, char *VolName, int mode)
         dev->dev_errno = errno;
          Mmsg2(&dev->errmsg, _("stored: unable to open device %s: ERR=%s\n"), 
               dev->dev_name, strerror(dev->dev_errno));
+        /* Stop any open timer we set */
+        if (dev->tid) {
+           stop_thread_timer(dev->tid);
+           dev->tid = 0;
+        }
         Emsg0(M_FATAL, 0, dev->errmsg);
         break;
       }
@@ -253,24 +280,34 @@ open_dev(DEVICE *dev, char *VolName, int mode)
         dev->use_count++;
         update_pos_dev(dev);             /* update position */
       }
+      /* Stop any open() timer we started */
+      if (dev->tid) {
+        stop_thread_timer(dev->tid);
+        dev->tid = 0;
+      }
       Dmsg1(29, "open_dev: tape %d opened\n", dev->fd);
    } else {
       /*
        * Handle opening of file
        */
       archive_name = get_pool_memory(PM_FNAME);
-      strcpy(archive_name, dev->dev_name);
+      pm_strcpy(&archive_name, dev->dev_name);
       if (archive_name[strlen(archive_name)] != '/') {
-         strcat(archive_name, "/");
+         pm_strcat(&archive_name, "/");
       }
-      strcat(archive_name, VolName);
+      pm_strcat(&archive_name, VolName);
       Dmsg1(29, "open_dev: device is disk %s\n", archive_name);
-      if (mode == READ_WRITE) {
+      if (mode == OPEN_READ_WRITE) {
         dev->mode = O_CREAT | O_RDWR | O_BINARY;
-      } else {
+      } else if (mode == OPEN_READ_ONLY) {
         dev->mode = O_RDONLY | O_BINARY;
+      } else if (mode == OPEN_WRITE_ONLY) {
+        dev->mode = O_WRONLY | O_BINARY;
+      } 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);
@@ -331,7 +368,7 @@ int rewind_dev(DEVICE *dev)
         }
         break;
       }
-   } else {
+   } else if (dev->state & ST_FILE) {
       if (lseek(dev->fd, (off_t)0, SEEK_SET) < 0) {
         dev->dev_errno = errno;
          Mmsg2(&dev->errmsg, _("lseek error on %s. ERR=%s.\n"),
@@ -362,6 +399,9 @@ eod_dev(DEVICE *dev)
    dev->state &= ~(ST_EOF);  /* remove EOF flags */
    dev->block_num = dev->file = 0;
    dev->file_addr = 0;
+   if (dev->state & (ST_FIFO | ST_PROG)) {
+      return 1;
+   }
    if (!(dev->state & ST_TAPE)) {
       pos = lseek(dev->fd, (off_t)0, SEEK_END);
 //    Dmsg1(000, "====== Seek to %lld\n", pos);
@@ -401,8 +441,8 @@ eod_dev(DEVICE *dev)
       }
       while (!(dev->state & ST_EOT)) {
          Dmsg0(200, "Do fsf 1\n");
-        if (fsf_dev(dev, 1) < 0) {
-            Dmsg0(200, "fsf_dev return < 0\n");
+        if (!fsf_dev(dev, 1)) {
+            Dmsg0(200, "fsf_dev error.\n");
            return 0;
         }
       }
@@ -413,15 +453,13 @@ eod_dev(DEVICE *dev)
 }
 
 /*
- * Set the position of the device.
+ * Set the position of the device -- only for files
+ *   For other devices, there is no generic way to do it.
  *  Returns: 1 on succes
  *          0 on error
  */
 int update_pos_dev(DEVICE *dev)
 {
-#ifdef xxxx
-   struct mtget mt_stat;
-#endif
    off_t pos;
    int stat = 0;
 
@@ -433,7 +471,7 @@ int update_pos_dev(DEVICE *dev)
    }
 
    /* Find out where we are */
-   if (!(dev->state & ST_TAPE)) {
+   if (dev->state & ST_FILE) {
       dev->file = 0;
       dev->file_addr = 0;
       pos = lseek(dev->fd, (off_t)0, SEEK_CUR);
@@ -448,18 +486,6 @@ int update_pos_dev(DEVICE *dev)
       }
       return stat;
    }
-
-#ifdef REALLY_IMPLEMENTED
-   if (ioctl(dev->fd, MTIOCGET, (char *)&mt_stat) < 0) {
-      Dmsg1(50, "MTIOCGET error: %s\n", strerror(dev->dev_errno));
-      dev->dev_errno = errno;
-      Mmsg2(&dev->errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"),
-        dev->dev_name, strerror(dev->dev_errno));
-   } else {
-      stat = 1;
-   }
-   return stat;
-#endif
    return 1;
 }
 
@@ -629,6 +655,8 @@ int offline_dev(DEVICE *dev)
 
 /* 
  * Foward space a file 
+ *   Returns: 1 on success
+ *           0 on failure
  */
 int
 fsf_dev(DEVICE *dev, int num)
@@ -641,16 +669,16 @@ fsf_dev(DEVICE *dev, int num)
       dev->dev_errno = EBADF;
       Mmsg0(&dev->errmsg, _("Bad call to fsf_dev. Archive not open\n"));
       Emsg0(M_FATAL, 0, dev->errmsg);
-      return -1;
+      return 0;
    }
 
    if (!(dev->state & ST_TAPE)) {
-      return 0;
+      return 1;
    }
    if (dev->state & ST_EOT) {
       dev->dev_errno = 0;
       Mmsg1(&dev->errmsg, _("Device %s at End of Tape.\n"), dev->dev_name);
-      return -1;
+      return 0;
    }
    if (dev->state & ST_EOF)
       Dmsg0(200, "ST_EOF set on entry to FSF\n");
@@ -736,7 +764,7 @@ fsf_dev(DEVICE *dev, int num)
    if (dev->state & ST_EOT)
       Dmsg0(200, "ST_EOT set on exit FSF\n");
    Dmsg1(200, "Return from FSF file=%d\n", dev->file);
-   return stat;
+   return stat == 0 ? 1 : 0;
 }
 
 /* 
@@ -819,6 +847,8 @@ fsr_dev(DEVICE *dev, int num)
 
 /* 
  * Backward space a record
+ *   Returns:  0 on success
+ *           -1 on failure
  */
 int
 bsr_dev(DEVICE *dev, int num)
@@ -987,13 +1017,16 @@ static void do_close(DEVICE *dev)
    /* Clean up device packet so it can be reused */
    dev->fd = -1;
    dev->state &= ~(ST_OPENED|ST_LABEL|ST_READ|ST_APPEND|ST_EOT|ST_WEOT|ST_EOF);
-   dev->block_num = 0;
-   dev->file = 0;
+   dev->file = dev->block_num = 0;
    dev->file_addr = 0;
-   dev->LastBlockNumWritten = 0;
+   dev->EndFile = dev->EndBlock = 0;
    memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo));
    memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
    dev->use_count--;
+   if (dev->tid) {
+      stop_thread_timer(dev->tid);
+      dev->tid = 0;
+   }
 }
 
 /* 
@@ -1083,7 +1116,7 @@ term_dev(DEVICE *dev)
       Emsg0(M_FATAL, 0, dev->errmsg);
       return;
    }
-   close_dev(dev);
+   do_close(dev);
    Dmsg0(29, "term_dev\n");
    if (dev->dev_name) {
       free_memory(dev->dev_name);
@@ -1093,9 +1126,6 @@ term_dev(DEVICE *dev)
       free_pool_memory(dev->errmsg);
       dev->errmsg = NULL;
    }
-#ifdef NEW_LOCK
-   rwl_destroy(&dev->lock);
-#endif
    pthread_mutex_destroy(&dev->mutex);
    pthread_cond_destroy(&dev->wait);
    pthread_cond_destroy(&dev->wait_next_vol);