Exemplo n.º 1
0
Arquivo: dev.c Projeto: dl5rcw/bareos
/*
 * Open the device with the operating system and
 * initialize buffer pointers.
 *
 * Returns: true on success
 *          false on error
 *
 * Note, for a tape, the VolName is the name we give to the
 * volume (not really used here), but for a file, the
 * VolName represents the name of the file to be created/opened.
 * In the case of a file, the full name is the device name
 * (archive_name) with the VolName concatenated.
 */
bool DEVICE::open(DCR *dcr, int omode)
{
   char preserve[ST_BYTES];

   clear_all_bits(ST_MAX, preserve);
   if (is_open()) {
      if (open_mode == omode) {
         return true;
      } else {
         d_close(m_fd);
         clear_opened();
         Dmsg0(100, "Close fd for mode change.\n");

         if (bit_is_set(ST_LABEL, state))
            set_bit(ST_LABEL, preserve);
         if (bit_is_set(ST_APPENDREADY, state))
            set_bit(ST_APPENDREADY, preserve);
         if (bit_is_set(ST_READREADY, state))
            set_bit(ST_READREADY, preserve);
      }
   }

   if (dcr) {
      dcr->setVolCatName(dcr->VolumeName);
      VolCatInfo = dcr->VolCatInfo;    /* structure assign */
   }

   Dmsg4(100, "open dev: type=%d dev_name=%s vol=%s mode=%s\n", dev_type,
         print_name(), getVolCatName(), mode_to_str(omode));

   clear_bit(ST_LABEL, state);
   clear_bit(ST_APPENDREADY, state);
   clear_bit(ST_READREADY, state);
   clear_bit(ST_EOT, state);
   clear_bit(ST_WEOT, state);
   clear_bit(ST_EOF, state);

   label_type = B_BAREOS_LABEL;

   /*
    * We are about to open the device so let any plugin know we are.
    */
   if (dcr && generate_plugin_event(dcr->jcr, bsdEventDeviceOpen, dcr) != bRC_OK) {
      Dmsg0(100, "open_dev: bsdEventDeviceOpen failed\n");
      return false;
   }

   Dmsg1(100, "call open_device mode=%s\n", mode_to_str(omode));
   open_device(dcr, omode);

   /*
    * Reset any important state info
    */
   clone_bits(ST_MAX, preserve, state);

   Dmsg2(100, "preserve=0x%x fd=%d\n", preserve, m_fd);

   return m_fd >= 0;
}
Exemplo n.º 2
0
/*
 * Close the device
 */
bool DEVICE::close()
{
   bool ok = true;

   Dmsg4(40, "close_dev vol=%s fd=%d dev=%p dev=%s\n",
      VolHdr.VolumeName, m_fd, this, print_name());
   offline_or_rewind();

   if (!is_open()) {
      Dmsg2(200, "device %s already closed vol=%s\n", print_name(),
         VolHdr.VolumeName);
      return true;                    /* already closed */
   }

   switch (dev_type) {
   case B_VTL_DEV:
   case B_VTAPE_DEV:
   case B_TAPE_DEV:
      unlock_door();
      /* Fall through wanted */
   default:
      if (d_close(m_fd) != 0) {
         berrno be;
         dev_errno = errno;
         Mmsg2(errmsg, _("Error closing device %s. ERR=%s.\n"),
               print_name(), be.bstrerror());
         ok = false;
      }
      break; 
   }

   unmount(1);                       /* do unmount if required */
 
   /* Clean up device packet so it can be reused */
   clear_opened();

   /*
    * Be careful not to clear items needed by the DVD driver
    *    when it is closing a single part.
    */
   state &= ~(ST_LABEL|ST_READ|ST_APPEND|ST_EOT|ST_WEOT|ST_EOF|
              ST_NOSPACE|ST_MOUNTED|ST_MEDIA|ST_SHORT);
   label_type = B_BACULA_LABEL;
   file = block_num = 0;
   file_size = 0;
   file_addr = 0;
   EndFile = EndBlock = 0;
   openmode = 0;
   clear_volhdr();
   memset(&VolCatInfo, 0, sizeof(VolCatInfo));
   if (tid) {
      stop_thread_timer(tid);
      tid = 0;
   }
   return ok;
}
Exemplo n.º 3
0
Arquivo: dev.c Projeto: dl5rcw/bareos
/*
 * Open a device.
 */
void DEVICE::open_device(DCR *dcr, int omode)
{
   POOL_MEM archive_name(PM_FNAME);

   get_autochanger_loaded_slot(dcr);

   /*
    * Handle opening of File Archive (not a tape)
    */
   pm_strcpy(archive_name, dev_name);

   /*
    * If this is a virtual autochanger (i.e. changer_res != NULL) we simply use
    * the device name, assuming it has been appropriately setup by the "autochanger".
    */
   if (!device->changer_res || device->changer_command[0] == 0) {
      if (VolCatInfo.VolCatName[0] == 0) {
         Mmsg(errmsg, _("Could not open file device %s. No Volume name given.\n"),
            print_name());
         clear_opened();
         return;
      }

      if (!IsPathSeparator(archive_name.c_str()[strlen(archive_name.c_str())-1])) {
         pm_strcat(archive_name, "/");
      }
      pm_strcat(archive_name, getVolCatName());
   }

   mount(dcr, 1);                     /* do mount if required */

   open_mode = omode;
   set_mode(omode);

   /*
    * If creating file, give 0640 permissions
    */
   Dmsg3(100, "open disk: mode=%s open(%s, 0x%x, 0640)\n", mode_to_str(omode),
         archive_name.c_str(), oflags);

   if ((m_fd = d_open(archive_name.c_str(), oflags, 0640)) < 0) {
      berrno be;
      dev_errno = errno;
      Mmsg2(errmsg, _("Could not open: %s, ERR=%s\n"), archive_name.c_str(),
            be.bstrerror());
      Dmsg1(100, "open failed: %s", errmsg);
   }

   if (m_fd >= 0) {
      dev_errno = 0;
      file = 0;
      file_addr = 0;
   }

   Dmsg1(100, "open dev: disk fd=%d opened\n", m_fd);
}
Exemplo n.º 4
0
/*
 * Open the device with the operating system and
 * initialize buffer pointers.
 *
 * Returns:  true on success
 *           false on error
 *
 * Note, for a tape, the VolName is the name we give to the
 *    volume (not really used here), but for a file, the
 *    VolName represents the name of the file to be created/opened.
 *    In the case of a file, the full name is the device name
 *    (archive_name) with the VolName concatenated.
 */
bool DEVICE::open(DCR *dcr, int omode)
{
   int preserve = 0;
   if (is_open()) {
      if (openmode == omode) {
         return true;
      } else {
         Dmsg1(200, "Close fd=%d for mode change in open().\n", m_fd);
         d_close(m_fd);
         clear_opened();
         preserve = state & (ST_LABEL|ST_APPEND|ST_READ);
      }
   }
   if (dcr) {
      dcr->setVolCatName(dcr->VolumeName);
      VolCatInfo = dcr->VolCatInfo;    /* structure assign */
   }

   state &= ~(ST_NOSPACE|ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
   label_type = B_BACULA_LABEL;

   if (is_tape() || is_fifo()) {
      open_tape_device(dcr, omode);
   } else if (is_ftp()) {
      open_device(dcr, omode);
   } else {
      Dmsg1(100, "call open_file_device mode=%s\n", mode_to_str(omode));
      open_file_device(dcr, omode);
   }
   state |= preserve;                 /* reset any important state info */
   Dmsg2(100, "preserve=0x%x fd=%d\n", preserve, m_fd);

   Dmsg7(100, "open dev: fd=%d dev=%p dcr=%p vol=%s type=%d dev_name=%s mode=%s\n",
         m_fd, getVolCatName(), this, dcr, dev_type, print_name(), mode_to_str(omode));
   return m_fd >= 0;
}
Exemplo n.º 5
0
Arquivo: dev.c Projeto: dl5rcw/bareos
/*
 * Close the device.
 */
bool DEVICE::close(DCR *dcr)
{
   bool retval = true;
   int status;
   Dmsg1(100, "close_dev %s\n", print_name());

   if (!is_open()) {
      Dmsg2(100, "device %s already closed vol=%s\n", print_name(), VolHdr.VolumeName);
      goto bail_out;                  /* already closed */
   }

   if (!norewindonclose) {
      offline_or_rewind();
   }

   switch (dev_type) {
   case B_VTL_DEV:
   case B_TAPE_DEV:
      unlock_door();
      /*
       * Fall through wanted
       */
   default:
      status = d_close(m_fd);
      if (status < 0) {
         berrno be;

         Mmsg2(errmsg, _("Unable to close device %s. ERR=%s\n"),
               print_name(), be.bstrerror());
         dev_errno = errno;
         retval = false;
      }
      break;
   }

   unmount(dcr, 1);                   /* do unmount if required */

   /*
    * Clean up device packet so it can be reused.
    */
   clear_opened();

   clear_bit(ST_LABEL, state);
   clear_bit(ST_READREADY, state);
   clear_bit(ST_APPENDREADY, state);
   clear_bit(ST_EOT, state);
   clear_bit(ST_WEOT, state);
   clear_bit(ST_EOF, state);
   clear_bit(ST_MOUNTED, state);
   clear_bit(ST_MEDIA, state);
   clear_bit(ST_SHORT, state);

   label_type = B_BAREOS_LABEL;
   file = block_num = 0;
   file_size = 0;
   file_addr = 0;
   EndFile = EndBlock = 0;
   open_mode = 0;
   clear_volhdr();
   memset(&VolCatInfo, 0, sizeof(VolCatInfo));
   if (tid) {
      stop_thread_timer(tid);
      tid = 0;
   }

   /*
    * We closed the device so let any plugin know we did.
    */
   if (dcr) {
      generate_plugin_event(dcr->jcr, bsdEventDeviceClose, dcr);
   }

bail_out:
   return retval;
}
/*
 * Open a tape device
 */
void generic_tape_device::open_device(DCR *dcr, int omode)
{
   file_size = 0;
   int timeout = max_open_wait;
#if !defined(HAVE_WIN32)
   struct mtop mt_com;
   utime_t start_time = time(NULL);
#endif

   mount(dcr, 1);                     /* do mount if required */

   Dmsg0(100, "Open dev: device is tape\n");

   get_autochanger_loaded_slot(dcr);

   open_mode = omode;
   set_mode(omode);

   if (timeout < 1) {
      timeout = 1;
   }
   errno = 0;
   Dmsg2(100, "Try open %s mode=%s\n", prt_name, mode_to_str(omode));
#if defined(HAVE_WIN32)
   /*
    * Windows Code
    */
   if ((m_fd = d_open(dev_name, oflags, 0)) < 0) {
      dev_errno = errno;
   }
#else
   /*
    * UNIX Code
    *
    * If busy retry each second for max_open_wait seconds
    */
   for ( ;; ) {
      /*
       * Try non-blocking open
       */
      m_fd = d_open(dev_name, oflags | O_NONBLOCK, 0);
      if (m_fd < 0) {
         berrno be;
         dev_errno = errno;
         Dmsg5(100, "Open error on %s omode=%d oflags=%x errno=%d: ERR=%s\n",
               prt_name, omode, oflags, errno, be.bstrerror());
      } else {
         /*
          * Tape open, now rewind it
          */
         Dmsg0(100, "Rewind after open\n");
         mt_com.mt_op = MTREW;
         mt_com.mt_count = 1;

         /*
          * Rewind only if dev is a tape
          */
         if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
            berrno be;
            dev_errno = errno;           /* set error status from rewind */
            d_close(m_fd);
            clear_opened();
            Dmsg2(100, "Rewind error on %s close: ERR=%s\n", prt_name, be.bstrerror(dev_errno));
            /*
             * If we get busy, device is probably rewinding, try again
             */
            if (dev_errno != EBUSY) {
               break;                    /* error -- no medium */
            }
         } else {
            /*
             * Got fd and rewind worked, so we must have medium in drive
             */
            d_close(m_fd);
            m_fd = d_open(dev_name, oflags, 0); /* open normally */
            if (m_fd < 0) {
               berrno be;
               dev_errno = errno;
               Dmsg5(100, "Open error on %s omode=%d oflags=%x errno=%d: ERR=%s\n",
                     prt_name, omode, oflags, errno, be.bstrerror());
               break;
            }
            dev_errno = 0;
            lock_door();
            set_os_device_parameters(dcr);       /* do system dependent stuff */
            break;                               /* Successfully opened and rewound */
         }
      }
      bmicrosleep(5, 0);

      /*
       * Exceed wait time ?
       */
      if (time(NULL) - start_time >= max_open_wait) {
         break;                       /* yes, get out */
      }
   }
#endif

   if (!is_open()) {
      berrno be;
      Mmsg2(errmsg, _("Unable to open device %s: ERR=%s\n"),
            prt_name, be.bstrerror(dev_errno));
      Dmsg1(100, "%s", errmsg);
   }

   Dmsg1(100, "open dev: tape %d opened\n", m_fd);
}
/*
 * Rewind the device.
 *
 * Returns: true  on success
 *          false on failure
 */
bool generic_tape_device::rewind(DCR *dcr)
{
   struct mtop mt_com;
   unsigned int i;
   bool first = true;

   Dmsg3(400, "rewind res=%d fd=%d %s\n", num_reserved(), m_fd, prt_name);
   state &= ~(ST_EOT | ST_EOF | ST_WEOT); /* Remove EOF/EOT flags */
   block_num = file = 0;
   file_size = 0;
   file_addr = 0;
   if (m_fd < 0) {
      return false;
   }

   mt_com.mt_op = MTREW;
   mt_com.mt_count = 1;

   /*
    * If we get an I/O error on rewind, it is probably because
    * the drive is actually busy. We loop for (about 5 minutes)
    * retrying every 5 seconds.
    */
   for (i = max_rewind_wait; ; i -= 5) {
      if (d_ioctl(m_fd, MTIOCTOP, (char *)&mt_com) < 0) {
         berrno be;

         clrerror(mt_com.mt_op);
         if (i == max_rewind_wait) {
            Dmsg1(200, "Rewind error, %s. retrying ...\n", be.bstrerror());
         }
         /*
          * This is a gross hack, because if the user has the
          * device mounted (i.e. open), then uses mtx to load
          * a tape, the current open file descriptor is invalid.
          * So, we close the drive and re-open it.
          */
         if (first && dcr) {
            int oo_mode = open_mode;
            d_close(m_fd);
            clear_opened();
            open(dcr, oo_mode);
            if (m_fd < 0) {
               return false;
            }
            first = false;
            continue;
         }
#ifdef HAVE_SUN_OS
         if (dev_errno == EIO) {
            Mmsg1(errmsg, _("No tape loaded or drive offline on %s.\n"), prt_name);
            return false;
         }
#else
         if (dev_errno == EIO && i > 0) {
            Dmsg0(200, "Sleeping 5 seconds.\n");
            bmicrosleep(5, 0);
            continue;
         }
#endif
         Mmsg2(errmsg, _("Rewind error on %s. ERR=%s.\n"), prt_name, be.bstrerror());
         return false;
      }
      break;
   }

   return true;
}