Esempio n. 1
0
/*
 * Return the status of the device.  This was meant
 * to be a generic routine. Unfortunately, it doesn't
 * seem possible (at least I do not know how to do it
 * currently), which means that for the moment, this
 * routine has very little value.
 *
 *   Returns: status
 */
uint32_t status_dev(DEVICE *dev)
{
   struct mtget mt_stat;
   uint32_t stat = 0;

   if (dev->state & (ST_EOT | ST_WEOT)) {
      stat |= BMT_EOD;
      Pmsg0(-20, " EOD");
   }
   if (dev->state & ST_EOF) {
      stat |= BMT_EOF;
      Pmsg0(-20, " EOF");
   }
   if (dev->is_tape()) {
      stat |= BMT_TAPE;
      Pmsg0(-20,_(" Bacula status:"));
      Pmsg2(-20,_(" file=%d block=%d\n"), dev->file, dev->block_num);
      if (dev->d_ioctl(dev->fd(), MTIOCGET, (char *)&mt_stat) < 0) {
         berrno be;
         dev->dev_errno = errno;
         Mmsg2(dev->errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"),
            dev->print_name(), be.bstrerror());
         return 0;
      }
      Pmsg0(-20, _(" Device status:"));

#if defined(HAVE_LINUX_OS)
      if (GMT_EOF(mt_stat.mt_gstat)) {
         stat |= BMT_EOF;
         Pmsg0(-20, " EOF");
      }
      if (GMT_BOT(mt_stat.mt_gstat)) {
         stat |= BMT_BOT;
         Pmsg0(-20, " BOT");
      }
      if (GMT_EOT(mt_stat.mt_gstat)) {
         stat |= BMT_EOT;
         Pmsg0(-20, " EOT");
      }
      if (GMT_SM(mt_stat.mt_gstat)) {
         stat |= BMT_SM;
         Pmsg0(-20, " SM");
      }
      if (GMT_EOD(mt_stat.mt_gstat)) {
         stat |= BMT_EOD;
         Pmsg0(-20, " EOD");
      }
      if (GMT_WR_PROT(mt_stat.mt_gstat)) {
         stat |= BMT_WR_PROT;
         Pmsg0(-20, " WR_PROT");
      }
      if (GMT_ONLINE(mt_stat.mt_gstat)) {
         stat |= BMT_ONLINE;
         Pmsg0(-20, " ONLINE");
      }
      if (GMT_DR_OPEN(mt_stat.mt_gstat)) {
         stat |= BMT_DR_OPEN;
         Pmsg0(-20, " DR_OPEN");
      }
      if (GMT_IM_REP_EN(mt_stat.mt_gstat)) {
         stat |= BMT_IM_REP_EN;
         Pmsg0(-20, " IM_REP_EN");
      }
#elif defined(HAVE_WIN32)
      if (GMT_EOF(mt_stat.mt_gstat)) {
         stat |= BMT_EOF;
         Pmsg0(-20, " EOF");
      }
      if (GMT_BOT(mt_stat.mt_gstat)) {
         stat |= BMT_BOT;
         Pmsg0(-20, " BOT");
      }
      if (GMT_EOT(mt_stat.mt_gstat)) {
         stat |= BMT_EOT;
         Pmsg0(-20, " EOT");
      }
      if (GMT_EOD(mt_stat.mt_gstat)) {
         stat |= BMT_EOD;
         Pmsg0(-20, " EOD");
      }
      if (GMT_WR_PROT(mt_stat.mt_gstat)) {
         stat |= BMT_WR_PROT;
         Pmsg0(-20, " WR_PROT");
      }
      if (GMT_ONLINE(mt_stat.mt_gstat)) {
         stat |= BMT_ONLINE;
         Pmsg0(-20, " ONLINE");
      }
      if (GMT_DR_OPEN(mt_stat.mt_gstat)) {
         stat |= BMT_DR_OPEN;
         Pmsg0(-20, " DR_OPEN");
      }
      if (GMT_IM_REP_EN(mt_stat.mt_gstat)) {
         stat |= BMT_IM_REP_EN;
         Pmsg0(-20, " IM_REP_EN");
      }

#endif /* !SunOS && !OSF */
      if (dev->has_cap(CAP_MTIOCGET)) {
         Pmsg2(-20, _(" file=%d block=%d\n"), mt_stat.mt_fileno, mt_stat.mt_blkno);
      } else {
         Pmsg2(-20, _(" file=%d block=%d\n"), -1, -1);
      }
   } else {
      stat |= BMT_ONLINE | BMT_BOT;
   }
   return stat;
}
Esempio n. 2
0
static
int w32_internal_rc ( U32* pStat )
{
    ASSERT( pStat );    // (sanity check)

    // PROGRAMMING NOTE: the 'door open' (no tape in drive) and the
    // 'write protected' statuses are "sticky" in that they never change
    // until a new/different tape is mounted. All the other statuses
    // however, change dynamically as one does i/o to the tape...

    if (0
            || ERROR_BUS_RESET            == errno // (See KB 111837: "ERROR_BUS_RESET May Be Benign")
            || ERROR_MEDIA_CHANGED        == errno
            || ERROR_DEVICE_NOT_CONNECTED == errno // (shouldn't occur but we'll check anyway)
            || ERROR_DEV_NOT_EXIST        == errno // (shouldn't occur but we'll check anyway)
            || ERROR_FILE_NOT_FOUND       == errno // (shouldn't occur but we'll check anyway)
       )
    {
        *pStat  &=  ~GMT_DR_OPEN (0xFFFFFFFF);
        *pStat  &=  ~GMT_WR_PROT (0xFFFFFFFF);
    }

    // (see PROGRAMMING NOTE above)

    *pStat  &=  ~GMT_BOT (0xFFFFFFFF);
    *pStat  &=  ~GMT_SM  (0xFFFFFFFF);
    *pStat  &=  ~GMT_EOF (0xFFFFFFFF);
    *pStat  &=  ~GMT_EOT (0xFFFFFFFF);
    *pStat  &=  ~GMT_EOD (0xFFFFFFFF);

    if (0
            || ERROR_BUS_RESET            == errno // (spurious error; retry)
            || ERROR_MEDIA_CHANGED        == errno // (spurious error; retry)
//      || ERROR_DEVICE_NOT_CONNECTED == errno // (PERM ERROR! NO RETRY!)
//      || ERROR_DEV_NOT_EXIST        == errno // (PERM ERROR! NO RETRY!)
//      || ERROR_FILE_NOT_FOUND       == errno // (PERM ERROR! NO RETRY!)
       )
    {
        return EINTR;   // (Interrupted system call; Retry)
    }

    // (see PROGRAMMING NOTE further above)

    switch (errno)
    {
    default:
        break;  // (leave errno set to whatever it already is)
    case NO_ERROR:
        errno = 0;
        break;  // (normal expected i/o result)

    case ERROR_BEGINNING_OF_MEDIA:
        *pStat |= GMT_BOT     (0xFFFFFFFF);
        errno = EIO;
        break;
    case ERROR_END_OF_MEDIA:
        *pStat |= GMT_EOT     (0xFFFFFFFF);
        errno = ENOSPC;
        break;

    //  "ERROR_END_OF_MEDIA"
    //
    //      Msg:   "The physical end of the tape has been reached."
    //
    //      The EOT warning reflector has been reached or passed (i.e. you're
    //      now/still in the "EOT Warning Zone" area). Writing additional data
    //      and/or tapemarks may still be possible depending on the size of the
    //      EOT Warning Zone (as set by a SetTapeParameters call with a non-zero
    //      EOTWarningZoneSize value (if supported; see further below)) and
    //      how much data you've already written to the EOT Warning Zone area
    //      (i.e. once you're in the warning area, this "error" occurs after
    //      EACH and EVERY I/O [in the warning zone area] until the ABSOLUTE
    //      physical end-of-tape (ERROR_EOM_OVERFLOW) is reached; see below).
    //
    //
    //                       ***********************
    //                       **  IMPORTANT NOTE!  **
    //                       ***********************
    //
    //                    This is NOT actually an "error"!!!
    //
    //
    //      When this "error" occurs, your "ReadFile" and/or "WriteFile" call
    //      returns 'FALSE' even though ALL of your requested data was actually
    //      written successfully!! This can be verified by checking to ensure
    //      the returned "number of bytes written" actually matches the amount
    //      you asked to be written. If they're the same (and they ALWAYS will
    //      be for this specific "error" code), then it means this "error" is
    //      NOT actually an error at all, but rather just a WARNING instead!!
    //      (Had it been an actual i/o error, the error code would have been
    //      some other DIFFERENT error code value instead!!)
    //
    //
    //                       ***********************
    //                       **  ALSO IMPORTANT!  **
    //                       ***********************
    //      See also:
    //
    //    http://fixunix.com/storage/205622-bug-dlttape-sys-no-eot-warning.html
    //
    //      for ADDITIONAL IMPORTANT INFORMATION regarding always having to
    //      specifically request that this "error" code be returned to you:
    //
    //      Even when a drive reports it does not support the setting of the
    //      the 'EOTWarningZoneSize' value (i.e. the FeaturesLow field of the
    //      GetTapeParameters call returns '0' for TAPE_DRIVE_SET_EOT_WZ_SIZE
    //      field), it may still be possible for "ERROR_END_OF_MEDIA" warnings
    //      to be generated anyway by simply calling SetTapeParameters with a
    //      non-zero 'EOTWarningZoneSize' value anyway.
    //
    //      The reason for this is because some drives may not allow CHANGING
    //      the value (thus the reason for it reporting that setting the value
    //      is not supported), but may nevertheless still support the ENABLING
    //      of their own hard-coded internal value. That is to say, while the
    //      size of the warning zone may not be modifiable (as it may be hard-
    //      coded and thus unchangeable), the drive may still have the ability
    //      to REPORT reaching the EOT Warning zone IF SPECIFICALLY REQUESTED
    //      TO DO SO! (which is presumably what requesting a non-zero Warning
    //      Zone size would end up doing: i.e. even though such calls APPEAR
    //      to fail, they actually DO succeed in accomplishing SOMETHING, just
    //      not what you originally/specifically requested).
    //
    //      Thus calling SetTapeParameters with a non-zero 'EOTWarningZoneSize'
    //      value might very well succeed anyway even though GetTapeParameters
    //      reports that doing so is not supported, and by so doing, may cause
    //      the drive to begin reporting of "ERROR_END_OF_MEDIA" (whereas not
    //      attempting to do so would end up leaving the drive in its default
    //      non-reporting mode. That is to say, you should ALWAYS try setting
    //      a non-zero 'EOTWarningZoneSize' value, ignoring any "unsupported"
    //      error code that may be returned from such a call.)

    case ERROR_EOM_OVERFLOW:
        *pStat |= GMT_EOT     (0xFFFFFFFF);
        errno = EIO;
        break;

    //  "ERROR_EOM_OVERFLOW"
    //
    //      Msg:   "Physical end of tape encountered."
    //
    //      This error code means that the actual physical end-of-media has been
    //      reached, and no more data can be written to the tape. This includes
    //      tapemarks as well.
    //
    //                       ***********************
    //                       **  IMPORTANT NOTE!  **
    //                       ***********************
    //
    //                 This is a HARD (UNRECOVERABLE) error!!
    //
    //      To be programmatically informed of when you are coming close to the
    //      physical end-of-the-tape (such that you could be assured room still
    //      remained to write logical end-of-volume labels for example), simply
    //      call SetTapeParameters with a non-zero 'EOTWarningZoneSize' value
    //      and treat any "ERROR_END_OF_MEDIA" "errors" received when writing
    //      as warnings instead. (See prior discussion of "ERROR_END_OF_MEDIA"
    //      return code further above)

    case ERROR_NO_DATA_DETECTED:
        *pStat |= GMT_EOD     (0xFFFFFFFF);
        errno = EIO;
        break;
    case ERROR_FILEMARK_DETECTED:
        *pStat |= GMT_EOF     (0xFFFFFFFF);
        errno = EIO;
        break;
    case ERROR_SETMARK_DETECTED:
        *pStat |= GMT_SM      (0xFFFFFFFF);
        errno = EIO;
        break;
    case ERROR_NOT_READY:
        *pStat |= GMT_DR_OPEN (0xFFFFFFFF);
        errno = ENOMEDIUM;
        break;
    case ERROR_NO_MEDIA_IN_DRIVE:
        *pStat |= GMT_DR_OPEN (0xFFFFFFFF);
        errno = ENOMEDIUM;
        break;
    case ERROR_WRITE_PROTECT:
        *pStat |= GMT_WR_PROT (0xFFFFFFFF);
        errno = EROFS;
        break;
    }
    return errno;
}
uint32_t generic_tape_device::status_dev()
{
   struct mtget mt_stat;
   uint32_t status = 0;

   if (state & (ST_EOT | ST_WEOT)) {
      status |= BMT_EOD;
      Pmsg0(-20, " EOD");
   }

   if (state & ST_EOF) {
      status |= BMT_EOF;
      Pmsg0(-20, " EOF");
   }

   status |= BMT_TAPE;
   Pmsg0(-20,_(" Bareos status:"));
   Pmsg2(-20,_(" file=%d block=%d\n"), file, block_num);
   if (d_ioctl(m_fd, MTIOCGET, (char *)&mt_stat) < 0) {
      berrno be;

      dev_errno = errno;
      Mmsg2(errmsg, _("ioctl MTIOCGET error on %s. ERR=%s.\n"),
            print_name(), be.bstrerror());
      return 0;
   }
   Pmsg0(-20, _(" Device status:"));

#if defined(HAVE_LINUX_OS)
   if (GMT_EOF(mt_stat.mt_gstat)) {
      status |= BMT_EOF;
      Pmsg0(-20, " EOF");
   }
   if (GMT_BOT(mt_stat.mt_gstat)) {
      status |= BMT_BOT;
      Pmsg0(-20, " BOT");
   }
   if (GMT_EOT(mt_stat.mt_gstat)) {
      status |= BMT_EOT;
      Pmsg0(-20, " EOT");
   }
   if (GMT_SM(mt_stat.mt_gstat)) {
      status |= BMT_SM;
      Pmsg0(-20, " SM");
   }
   if (GMT_EOD(mt_stat.mt_gstat)) {
      status |= BMT_EOD;
      Pmsg0(-20, " EOD");
   }
   if (GMT_WR_PROT(mt_stat.mt_gstat)) {
      status |= BMT_WR_PROT;
      Pmsg0(-20, " WR_PROT");
   }
   if (GMT_ONLINE(mt_stat.mt_gstat)) {
      status |= BMT_ONLINE;
      Pmsg0(-20, " ONLINE");
   }
   if (GMT_DR_OPEN(mt_stat.mt_gstat)) {
      status |= BMT_DR_OPEN;
      Pmsg0(-20, " DR_OPEN");
   }
   if (GMT_IM_REP_EN(mt_stat.mt_gstat)) {
      status |= BMT_IM_REP_EN;
      Pmsg0(-20, " IM_REP_EN");
   }
#elif defined(HAVE_WIN32)
   if (GMT_EOF(mt_stat.mt_gstat)) {
      status |= BMT_EOF;
      Pmsg0(-20, " EOF");
   }
   if (GMT_BOT(mt_stat.mt_gstat)) {
      status |= BMT_BOT;
      Pmsg0(-20, " BOT");
   }
   if (GMT_EOT(mt_stat.mt_gstat)) {
      status |= BMT_EOT;
      Pmsg0(-20, " EOT");
   }
   if (GMT_EOD(mt_stat.mt_gstat)) {
      status |= BMT_EOD;
      Pmsg0(-20, " EOD");
   }
   if (GMT_WR_PROT(mt_stat.mt_gstat)) {
      status |= BMT_WR_PROT;
      Pmsg0(-20, " WR_PROT");
   }
   if (GMT_ONLINE(mt_stat.mt_gstat)) {
      status |= BMT_ONLINE;
      Pmsg0(-20, " ONLINE");
   }
   if (GMT_DR_OPEN(mt_stat.mt_gstat)) {
      status |= BMT_DR_OPEN;
      Pmsg0(-20, " DR_OPEN");
   }
   if (GMT_IM_REP_EN(mt_stat.mt_gstat)) {
      status |= BMT_IM_REP_EN;
      Pmsg0(-20, " IM_REP_EN");
   }
#endif /* HAVE_LINUX_OS || HAVE_WIN32 */

   if (has_cap(CAP_MTIOCGET)) {
      Pmsg2(-20, _(" file=%d block=%d\n"), mt_stat.mt_fileno, mt_stat.mt_blkno);
   } else {
      Pmsg2(-20, _(" file=%d block=%d\n"), -1, -1);
   }

   return status;
}