Example #1
0
File: bls.c Project: AlD/bareos
/* List just block information */
static void do_blocks(char *infname)
{
   DEV_BLOCK *block = dcr->block;
   char buf1[100], buf2[100];
   for ( ;; ) {
      if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
         Dmsg1(100, "!read_block(): ERR=%s\n", dev->bstrerror());
         if (dev->at_eot()) {
            if (!mount_next_read_volume(dcr)) {
               Jmsg(jcr, M_INFO, 0, _("Got EOM at file %u on device %s, Volume \"%s\"\n"),
                  dev->file, dev->print_name(), dcr->VolumeName);
               break;
            }
            /* Read and discard Volume label */
            DEV_RECORD *record;
            record = new_record();
            dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK);
            read_record_from_block(dcr, record);
            get_session_record(dev, record, &sessrec);
            free_record(record);
            Jmsg(jcr, M_INFO, 0, _("Mounted Volume \"%s\".\n"), dcr->VolumeName);
         } else if (dev->at_eof()) {
            Jmsg(jcr, M_INFO, 0, _("End of file %u on device %s, Volume \"%s\"\n"),
               dev->file, dev->print_name(), dcr->VolumeName);
            Dmsg0(20, "read_record got eof. try again\n");
            continue;
         } else if (dev->is_short_block()) {
            Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg);
            continue;
         } else {
            /* I/O error */
            display_tape_error_status(jcr, dev);
            break;
         }
      }
      if (!match_bsr_block(bsr, block)) {
         Dmsg5(100, "reject Blk=%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
            block->BlockNumber, block->block_len, block->BlockVer,
            block->VolSessionId, block->VolSessionTime);
         continue;
      }
      Dmsg5(100, "Blk=%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
        block->BlockNumber, block->block_len, block->BlockVer,
        block->VolSessionId, block->VolSessionTime);
      if (verbose == 1) {
         read_record_from_block(dcr, rec);
         Pmsg9(-1, _("File:blk=%u:%u blk_num=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n"),
              dev->file, dev->block_num,
              block->BlockNumber, block->block_len,
              FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
              stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len);
         rec->remainder = 0;
      } else if (verbose > 1) {
         dump_block(block, "");
      } else {
         printf(_("Block: %d size=%d\n"), block->BlockNumber, block->block_len);
      }

   }
   return;
}
Example #2
0
/*
 * Read the volume label
 *
 *  If dcr->VolumeName == NULL, we accept any Bareos Volume
 *  If dcr->VolumeName[0] == 0, we accept any Bareos Volume
 *  otherwise dcr->VolumeName must match the Volume.
 *
 *  If VolName given, ensure that it matches
 *
 *  Returns VOL_  code as defined in record.h
 *    VOL_NOT_READ
 *    VOL_OK                          good label found
 *    VOL_NO_LABEL                    volume not labeled
 *    VOL_IO_ERROR                    I/O error reading tape
 *    VOL_NAME_ERROR                  label has wrong name
 *    VOL_CREATE_ERROR                Error creating label
 *    VOL_VERSION_ERROR               label has wrong version
 *    VOL_LABEL_ERROR                 bad label type
 *    VOL_NO_MEDIA                    no media in drive
 *
 *  The dcr block is emptied on return, and the Volume is
 *    rewound.
 */
int read_dev_volume_label(DCR *dcr)
{
   JCR *jcr = dcr->jcr;
   DEVICE * volatile dev = dcr->dev;
   char *VolName = dcr->VolumeName;
   DEV_RECORD *record;
   bool ok = false;
   DEV_BLOCK *block = dcr->block;
   int status;
   bool want_ansi_label;
   bool have_ansi_label = false;

   Dmsg4(100, "Enter read_volume_label res=%d device=%s vol=%s dev_Vol=%s\n",
      dev->num_reserved(), dev->print_name(), VolName,
      dev->VolHdr.VolumeName[0]?dev->VolHdr.VolumeName:"*NULL*");

   if (!dev->is_open()) {
      if (!dev->open(dcr, OPEN_READ_ONLY)) {
         return VOL_IO_ERROR;
      }
   }

   dev->clear_labeled();
   dev->clear_append();
   dev->clear_read();
   dev->label_type = B_BAREOS_LABEL;

   if (!dev->rewind(dcr)) {
      Mmsg(jcr->errmsg, _("Couldn't rewind device %s: ERR=%s\n"),
         dev->print_name(), dev->print_errmsg());
      Dmsg1(130, "return VOL_NO_MEDIA: %s", jcr->errmsg);
      return VOL_NO_MEDIA;
   }
   bstrncpy(dev->VolHdr.Id, "**error**", sizeof(dev->VolHdr.Id));

   /*
    * The stored plugin handling the bsdEventLabelRead event can abort
    * the reading of the label by returning a non bRC_OK.
    */
   if (generate_plugin_event(jcr, bsdEventLabelRead, dcr) != bRC_OK) {
      Dmsg0(200, "Error from bsdEventLabelRead plugin event.\n");
      return VOL_NO_MEDIA;
   }

   /*
    * Read ANSI/IBM label if so requested
    */
   want_ansi_label = dcr->VolCatInfo.LabelType != B_BAREOS_LABEL ||
                     dcr->device->label_type != B_BAREOS_LABEL;
   if (want_ansi_label || dev->has_cap(CAP_CHECKLABELS)) {
      status = read_ansi_ibm_label(dcr);
      /*
       * If we want a label and didn't find it, return error
       */
      if (want_ansi_label && status != VOL_OK) {
         goto bail_out;
      }
      if (status == VOL_NAME_ERROR || status == VOL_LABEL_ERROR) {
         Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"),
              dev->print_name(), VolName, dev->VolHdr.VolumeName);
         if (!dev->poll && jcr->label_errors++ > 100) {
            Jmsg(jcr, M_FATAL, 0, _("Too many tries: %s"), jcr->errmsg);
         }
         goto bail_out;
      }
      if (status != VOL_OK) {        /* Not an ANSI/IBM label, so re-read */
         dev->rewind(dcr);
      } else {
         have_ansi_label = true;
      }
   }

   /*
    * Read the Bareos Volume label block
    */
   record = new_record();
   empty_block(block);

   Dmsg0(130, "Big if statement in read_volume_label\n");
   if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) {
      Mmsg(jcr->errmsg, _("Requested Volume \"%s\" on %s is not a Bareos "
           "labeled Volume, because: ERR=%s"), NPRT(VolName),
           dev->print_name(), dev->print_errmsg());
      Dmsg1(130, "%s", jcr->errmsg);
   } else if (!read_record_from_block(dcr, record)) {
      Mmsg(jcr->errmsg, _("Could not read Volume label from block.\n"));
      Dmsg1(130, "%s", jcr->errmsg);
   } else if (!unser_volume_label(dev, record)) {
      Mmsg(jcr->errmsg, _("Could not unserialize Volume label: ERR=%s\n"),
         dev->print_errmsg());
      Dmsg1(130, "%s", jcr->errmsg);
   } else if (!bstrcmp(dev->VolHdr.Id, BareosId) &&
              !bstrcmp(dev->VolHdr.Id, OldBaculaId) &&
              !bstrcmp(dev->VolHdr.Id, OlderBaculaId)) {
      Mmsg(jcr->errmsg, _("Volume Header Id bad: %s\n"), dev->VolHdr.Id);
      Dmsg1(130, "%s", jcr->errmsg);
   } else {
      ok = true;
   }
   free_record(record);              /* finished reading Volume record */

   if (!dev->is_volume_to_unload()) {
      dev->clear_unload();
   }

   if (!ok) {
      if (forge_on || jcr->ignore_label_errors) {
         dev->set_labeled();         /* set has Bareos label */
         Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg);
         goto ok_out;
      }
      Dmsg0(100, "No volume label - bailing out\n");
      status = VOL_NO_LABEL;
      goto bail_out;
   }

   /*
    * At this point, we have read the first Bareos block, and
    * then read the Bareos Volume label. Now we need to
    * make sure we have the right Volume.
    */
   if (dev->VolHdr.VerNum != BareosTapeVersion &&
       dev->VolHdr.VerNum != OldCompatibleBareosTapeVersion1 &&
       dev->VolHdr.VerNum != OldCompatibleBareosTapeVersion2 &&
       dev->VolHdr.VerNum != OldCompatibleBareosTapeVersion3) {
      Mmsg(jcr->errmsg, _("Volume on %s has wrong Bareos version. Wanted %d got %d\n"),
           dev->print_name(), BareosTapeVersion, dev->VolHdr.VerNum);
      Dmsg1(130, "VOL_VERSION_ERROR: %s", jcr->errmsg);
      status = VOL_VERSION_ERROR;
      goto bail_out;
   }

   /*
    * We are looking for either an unused Bareos tape (PRE_LABEL) or
    * a Bareos volume label (VOL_LABEL)
    */
   if (dev->VolHdr.LabelType != PRE_LABEL && dev->VolHdr.LabelType != VOL_LABEL) {
      Mmsg(jcr->errmsg, _("Volume on %s has bad Bareos label type: %x\n"),
          dev->print_name(), dev->VolHdr.LabelType);
      Dmsg1(130, "%s", jcr->errmsg);
      if (!dev->poll && jcr->label_errors++ > 100) {
         Jmsg(jcr, M_FATAL, 0, _("Too many tries: %s"), jcr->errmsg);
      }
      Dmsg0(150, "return VOL_LABEL_ERROR\n");
      status = VOL_LABEL_ERROR;
      goto bail_out;
   }

   dev->set_labeled();               /* set has Bareos label */

   /* Compare Volume Names */
   Dmsg2(130, "Compare Vol names: VolName=%s hdr=%s\n", VolName?VolName:"*", dev->VolHdr.VolumeName);
   if (VolName && *VolName && *VolName != '*' && !bstrcmp(dev->VolHdr.VolumeName, VolName)) {
      Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"),
           dev->print_name(), VolName, dev->VolHdr.VolumeName);
      Dmsg1(130, "%s", jcr->errmsg);
      /*
       * Cancel Job if too many label errors
       *  => we are in a loop
       */
      if (!dev->poll && jcr->label_errors++ > 100) {
         Jmsg(jcr, M_FATAL, 0, "Too many tries: %s", jcr->errmsg);
      }
      Dmsg0(150, "return VOL_NAME_ERROR\n");
      status = VOL_NAME_ERROR;
      goto bail_out;
   }

   if (debug_level >= 200) {
      dump_volume_label(dev);
   }

   Dmsg0(130, "Leave read_volume_label() VOL_OK\n");
   /*
    * If we are a streaming device, we only get one chance to read
    */
   if (!dev->has_cap(CAP_STREAM)) {
      dev->rewind(dcr);
      if (have_ansi_label) {
         status = read_ansi_ibm_label(dcr);
         /*
          * If we want a label and didn't find it, return error
          */
         if (status != VOL_OK) {
            goto bail_out;
         }
      }
   }

   Dmsg1(100, "Call reserve_volume=%s\n", dev->VolHdr.VolumeName);
   if (reserve_volume(dcr, dev->VolHdr.VolumeName) == NULL) {
      Mmsg2(jcr->errmsg, _("Could not reserve volume %s on %s\n"),
           dev->VolHdr.VolumeName, dev->print_name());
      Dmsg2(150, "Could not reserve volume %s on %s\n", dev->VolHdr.VolumeName, dev->print_name());
      status = VOL_NAME_ERROR;
      goto bail_out;
   }

ok_out:
   /*
    * The stored plugin handling the bsdEventLabelVerified event can override
    * the return value e.g. although we think the volume label is ok the plugin
    * has reasons to override that. So when the plugin returns something else
    * then bRC_OK it want to tell us the volume is not OK to use and as
    * such we return VOL_NAME_ERROR as error although it might not be te
    * best error it should be sufficient.
    */
   if (generate_plugin_event(jcr, bsdEventLabelVerified, dcr) != bRC_OK) {
      Dmsg0(200, "Error from bsdEventLabelVerified plugin event.\n");
      status = VOL_NAME_ERROR;
      goto bail_out;
   }
   empty_block(block);
   return VOL_OK;

bail_out:
   empty_block(block);
   dev->rewind(dcr);
   Dmsg1(150, "return %d\n", status);
   return status;
}