]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/label.c
Start adding back removed code.
[bacula/bacula] / bacula / src / stored / label.c
index c296e39ff77d6ffca48c642072c23129e41e69ea..32a65297bfd00756a23effb430fa252c59cec531 100644 (file)
@@ -8,11 +8,11 @@
  *   Version $Id$
  */
 /*
  *   Version $Id$
  */
 /*
-   Copyright (C) 2000-2005 Kern Sibbald
+   Copyright (C) 2000-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
-   version 2 as ammended with additional clauses defined in the
+   version 2 as amended with additional clauses defined in the
    file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
    file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
@@ -28,9 +28,6 @@
 /* Forward referenced functions */
 static void create_volume_label_record(DCR *dcr, DEV_RECORD *rec);
 
 /* Forward referenced functions */
 static void create_volume_label_record(DCR *dcr, DEV_RECORD *rec);
 
-extern char my_name[];
-extern int debug_level;
-
 /*
  * Read the volume label
  *
 /*
  * Read the volume label
  *
@@ -64,38 +61,46 @@ int read_dev_volume_label(DCR *dcr)
    DEV_BLOCK *block = dcr->block;
    int stat;
    bool want_ansi_label;
    DEV_BLOCK *block = dcr->block;
    int stat;
    bool want_ansi_label;
+   bool have_ansi_label = false;
 
 
-   Dmsg3(100, "Enter read_volume_label device=%s vol=%s dev_Vol=%s\n",
-      dev->name(), VolName, dev->VolHdr.VolName);
+   Dmsg4(100, "Enter read_volume_label res=%d device=%s vol=%s dev_Vol=%s\n",
+      dev->reserved_device, dev->print_name(), VolName, 
+      dev->VolHdr.VolumeName[0]?dev->VolHdr.VolumeName:"*NULL*");
 
    if (!dev->is_open()) {
 
    if (!dev->is_open()) {
-      Emsg0(M_ABORT, 0, _("BAD call to read_dev_volume_label\n"));
+      if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
+         return VOL_IO_ERROR;
+      }
    }
    if (dev->is_labeled()) {              /* did we already read label? */
       /* Compare Volume Names allow special wild card */
    }
    if (dev->is_labeled()) {              /* did we already read label? */
       /* Compare Volume Names allow special wild card */
-      if (VolName && *VolName && *VolName != '*' && strcmp(dev->VolHdr.VolName, VolName) != 0) {
+      if (VolName && *VolName && *VolName != '*' && strcmp(dev->VolHdr.VolumeName, VolName) != 0) {
          Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"),
          Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"),
-            dev->print_name(), VolName, dev->VolHdr.VolName);
+            dev->print_name(), VolName, dev->VolHdr.VolumeName);
          /*
           * Cancel Job if too many label errors
           *  => we are in a loop
           */
          if (!dev->poll && jcr->label_errors++ > 100) {
          /*
           * 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);
+            Jmsg(jcr, M_FATAL, 0, _("Too many tries: %s"), jcr->errmsg);
          }
          }
-         return VOL_NAME_ERROR;
+         Dmsg0(150, "return VOL_NAME_ERROR\n");
+         stat = VOL_NAME_ERROR;
+         goto bail_out;
       }
       Dmsg0(30, "Leave read_volume_label() VOL_OK\n");
       return VOL_OK;       /* label already read */
    }
 
       }
       Dmsg0(30, "Leave read_volume_label() VOL_OK\n");
       return VOL_OK;       /* label already read */
    }
 
-   dev->state &= ~(ST_LABEL|ST_APPEND|ST_READ);  /* set no label, no append */
+   dev->clear_labeled();
+   dev->clear_append();
+   dev->clear_read();
    dev->label_type = B_BACULA_LABEL;
 
    dev->label_type = B_BACULA_LABEL;
 
-   if (!rewind_dev(dev)) {
+   if (!dev->rewind(dcr)) {
       Mmsg(jcr->errmsg, _("Couldn't rewind device %s: ERR=%s\n"), 
       Mmsg(jcr->errmsg, _("Couldn't rewind device %s: ERR=%s\n"), 
-         dev->print_name(), strerror_dev(dev));
-      Dmsg1(30, "%s", jcr->errmsg);
+         dev->print_name(), dev->bstrerror());
+      Dmsg1(30, "return VOL_NO_MEDIA: %s", jcr->errmsg);
       return VOL_NO_MEDIA;
    }
    bstrncpy(dev->VolHdr.Id, "**error**", sizeof(dev->VolHdr.Id));
       return VOL_NO_MEDIA;
    }
    bstrncpy(dev->VolHdr.Id, "**error**", sizeof(dev->VolHdr.Id));
@@ -108,22 +113,20 @@ int read_dev_volume_label(DCR *dcr)
       stat = read_ansi_ibm_label(dcr);            
       /* If we want a label and didn't find it, return error */
       if (want_ansi_label && stat != VOL_OK) {
       stat = read_ansi_ibm_label(dcr);            
       /* If we want a label and didn't find it, return error */
       if (want_ansi_label && stat != VOL_OK) {
-         empty_block(block);
-         rewind_dev(dev);
-         return stat;
+         goto bail_out;
       }
       if (stat == VOL_NAME_ERROR || stat == VOL_LABEL_ERROR) {
          Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"),
       }
       if (stat == VOL_NAME_ERROR || stat == VOL_LABEL_ERROR) {
          Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"),
-              dev->print_name(), VolName, dev->VolHdr.VolName);
+              dev->print_name(), VolName, dev->VolHdr.VolumeName);
          if (!dev->poll && jcr->label_errors++ > 100) {
          if (!dev->poll && jcr->label_errors++ > 100) {
-            Jmsg(jcr, M_FATAL, 0, "Too many tries: %s", jcr->errmsg);
+            Jmsg(jcr, M_FATAL, 0, _("Too many tries: %s"), jcr->errmsg);
          }
          }
-         empty_block(block);
-         rewind_dev(dev);
-         return stat;
+         goto bail_out;
       }
       if (stat != VOL_OK) {           /* Not an ANSI/IBM label, so re-read */
       }
       if (stat != VOL_OK) {           /* Not an ANSI/IBM label, so re-read */
-         rewind_dev(dev);
+         dev->rewind(dcr);
+      } else {
+         have_ansi_label = true;
       }
    }
   
       }
    }
   
@@ -135,14 +138,14 @@ int read_dev_volume_label(DCR *dcr)
    if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
       Mmsg(jcr->errmsg, _("Requested Volume \"%s\" on %s is not a Bacula "
            "labeled Volume, because: ERR=%s"), NPRT(VolName), 
    if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
       Mmsg(jcr->errmsg, _("Requested Volume \"%s\" on %s is not a Bacula "
            "labeled Volume, because: ERR=%s"), NPRT(VolName), 
-           dev->print_name(), strerror_dev(dev));
+           dev->print_name(), dev->bstrerror());
       Dmsg1(30, "%s", jcr->errmsg);
    } else if (!read_record_from_block(block, record)) {
       Mmsg(jcr->errmsg, _("Could not read Volume label from block.\n"));
       Dmsg1(30, "%s", jcr->errmsg);
    } else if (!unser_volume_label(dev, record)) {
       Mmsg(jcr->errmsg, _("Could not unserialize Volume label: ERR=%s\n"),
       Dmsg1(30, "%s", jcr->errmsg);
    } else if (!read_record_from_block(block, record)) {
       Mmsg(jcr->errmsg, _("Could not read Volume label from block.\n"));
       Dmsg1(30, "%s", jcr->errmsg);
    } else if (!unser_volume_label(dev, record)) {
       Mmsg(jcr->errmsg, _("Could not unserialize Volume label: ERR=%s\n"),
-         strerror_dev(dev));
+         dev->bstrerror());
       Dmsg1(30, "%s", jcr->errmsg);
    } else if (strcmp(dev->VolHdr.Id, BaculaId) != 0 &&
               strcmp(dev->VolHdr.Id, OldBaculaId) != 0) {
       Dmsg1(30, "%s", jcr->errmsg);
    } else if (strcmp(dev->VolHdr.Id, BaculaId) != 0 &&
               strcmp(dev->VolHdr.Id, OldBaculaId) != 0) {
@@ -152,16 +155,17 @@ int read_dev_volume_label(DCR *dcr)
       ok = true;
    }
    free_record(record);               /* finished reading Volume record */
       ok = true;
    }
    free_record(record);               /* finished reading Volume record */
-   empty_block(block);                /* done with block */
 
    if (!ok) {
       if (forge_on || jcr->ignore_label_errors) {
          dev->set_labeled();         /* set has Bacula label */
          Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg);
 
    if (!ok) {
       if (forge_on || jcr->ignore_label_errors) {
          dev->set_labeled();         /* set has Bacula label */
          Jmsg(jcr, M_ERROR, 0, "%s", jcr->errmsg);
+         empty_block(block);
          return VOL_OK;
       }
          return VOL_OK;
       }
-      rewind_dev(dev);
-      return VOL_NO_LABEL;
+      Dmsg0(100, "No volume label - bailing out\n");
+      stat = VOL_NO_LABEL;
+      goto bail_out;
    }
 
    /* At this point, we have read the first Bacula block, and
    }
 
    /* At this point, we have read the first Bacula block, and
@@ -169,18 +173,15 @@ int read_dev_volume_label(DCR *dcr)
     * make sure we have the right Volume.
     */
 
     * make sure we have the right Volume.
     */
 
-   /* If we are a streaming device, we only get one chance to read */
-   if (!dev_cap(dev, CAP_STREAM)) {
-      rewind_dev(dev);
-   }
 
    if (dev->VolHdr.VerNum != BaculaTapeVersion &&
        dev->VolHdr.VerNum != OldCompatibleBaculaTapeVersion1 &&
        dev->VolHdr.VerNum != OldCompatibleBaculaTapeVersion2) {
       Mmsg(jcr->errmsg, _("Volume on %s has wrong Bacula version. Wanted %d got %d\n"),
          dev->print_name(), BaculaTapeVersion, dev->VolHdr.VerNum);
 
    if (dev->VolHdr.VerNum != BaculaTapeVersion &&
        dev->VolHdr.VerNum != OldCompatibleBaculaTapeVersion1 &&
        dev->VolHdr.VerNum != OldCompatibleBaculaTapeVersion2) {
       Mmsg(jcr->errmsg, _("Volume on %s has wrong Bacula version. Wanted %d got %d\n"),
          dev->print_name(), BaculaTapeVersion, dev->VolHdr.VerNum);
-      Dmsg1(30, "%s", jcr->errmsg);
-      return VOL_VERSION_ERROR;
+      Dmsg1(30, "VOL_VERSION_ERROR: %s", jcr->errmsg);
+      stat = VOL_VERSION_ERROR;
+      goto bail_out;
    }
 
    /* We are looking for either an unused Bacula tape (PRE_LABEL) or
    }
 
    /* We are looking for either an unused Bacula tape (PRE_LABEL) or
@@ -191,19 +192,21 @@ int read_dev_volume_label(DCR *dcr)
           dev->print_name(), dev->VolHdr.LabelType);
       Dmsg1(30, "%s", jcr->errmsg);
       if (!dev->poll && jcr->label_errors++ > 100) {
           dev->print_name(), dev->VolHdr.LabelType);
       Dmsg1(30, "%s", jcr->errmsg);
       if (!dev->poll && jcr->label_errors++ > 100) {
-         Jmsg(jcr, M_FATAL, 0, "Too many tries: %s", jcr->errmsg);
+         Jmsg(jcr, M_FATAL, 0, _("Too many tries: %s"), jcr->errmsg);
       }
       }
-      return VOL_LABEL_ERROR;
+      Dmsg0(150, "return VOL_LABEL_ERROR\n");
+      stat = VOL_LABEL_ERROR;
+      goto bail_out;
    }
 
    dev->set_labeled();               /* set has Bacula label */
    }
 
    dev->set_labeled();               /* set has Bacula label */
-   new_volume(dev->VolHdr.VolName, dev);
+   new_volume(dcr, dev->VolHdr.VolumeName);
 
    /* Compare Volume Names */
 
    /* Compare Volume Names */
-   Dmsg2(30, "Compare Vol names: VolName=%s hdr=%s\n", VolName?VolName:"*", dev->VolHdr.VolName);
-   if (VolName && *VolName && *VolName != '*' && strcmp(dev->VolHdr.VolName, VolName) != 0) {
+   Dmsg2(30, "Compare Vol names: VolName=%s hdr=%s\n", VolName?VolName:"*", dev->VolHdr.VolumeName);
+   if (VolName && *VolName && *VolName != '*' && strcmp(dev->VolHdr.VolumeName, VolName) != 0) {
       Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"),
       Mmsg(jcr->errmsg, _("Wrong Volume mounted on device %s: Wanted %s have %s\n"),
-           dev->print_name(), VolName, dev->VolHdr.VolName);
+           dev->print_name(), VolName, dev->VolHdr.VolumeName);
       Dmsg1(30, "%s", jcr->errmsg);
       /*
        * Cancel Job if too many label errors
       Dmsg1(30, "%s", jcr->errmsg);
       /*
        * Cancel Job if too many label errors
@@ -212,105 +215,35 @@ int read_dev_volume_label(DCR *dcr)
       if (!dev->poll && jcr->label_errors++ > 100) {
          Jmsg(jcr, M_FATAL, 0, "Too many tries: %s", jcr->errmsg);
       }
       if (!dev->poll && jcr->label_errors++ > 100) {
          Jmsg(jcr, M_FATAL, 0, "Too many tries: %s", jcr->errmsg);
       }
-      return VOL_NAME_ERROR;
+      Dmsg0(150, "return VOL_NAME_ERROR\n");
+      stat = VOL_NAME_ERROR;
+      goto bail_out;
    }
    }
-   Dmsg1(30, "Copy vol_name=%s\n", dev->VolHdr.VolName);
+   Dmsg1(30, "Copy vol_name=%s\n", dev->VolHdr.VolumeName);
 
    if (debug_level >= 10) {
       dump_volume_label(dev);
    }
    Dmsg0(30, "Leave read_volume_label() VOL_OK\n");
 
    if (debug_level >= 10) {
       dump_volume_label(dev);
    }
    Dmsg0(30, "Leave read_volume_label() VOL_OK\n");
-   return VOL_OK;
-}
-
-/* Read the volume label by guessing the volume name. (only for DVD devices)
- * write is true if we are reading the label before writing to the device.
- *
- * If the volume name cannot be guessed :
- *  Writing : returns the label of the current file (on the harddisk).
- *  Reading : returns an error
- */
-int read_dev_volume_label_guess(DCR *dcr, bool write) 
-{
-   int vol_label_status;
-   DEVICE *dev = dcr->dev;
-   JCR *jcr = dcr->jcr;
-   Dmsg3(100, "Enter read_dev_volume_label_guess device=%s vol=%s dev_Vol=%s\n",
-         dev->print_name(), dcr->VolumeName, dev->VolHdr.VolName);
-   
-   if (!dev->is_dvd()) {
-      Dmsg0(100, "Leave read_dev_volume_label_guess !CAP_REQMOUNT\n");
-      return read_dev_volume_label(dcr);
-   }
-   
-   if (!write && (dcr->VolCatInfo.VolCatParts == 0)) {
-      Dmsg0(100, "Leave read_dev_volume_label_guess !writing, and VolCatParts == 0\n");
-      return read_dev_volume_label(dcr);
-   }
-   
-   /* For mounted devices, tries to guess the volume name, and read the label if possible.
-   */
-   if (open_guess_name_dev(dev) < 0) {     
-      if (!write || dcr->VolCatInfo.VolCatParts > 0) {
-         Mmsg2(jcr->errmsg, _("Requested Volume \"%s\" on %s is not a Bacula labeled Volume."),
-               dev->print_name(), dcr->VolumeName);
-         Dmsg0(100, "Leave read_dev_volume_label_guess VOL_NO_LABEL (!open_guess_name_dev)\n");
-         return VOL_NO_LABEL;
-      }
-      
-      if (write && dev->free_space_errno < 0) {
-         Dmsg0(100, "Leave read_dev_volume_label_guess !free_space VOL_NO_MEDIA\n");
-         Mmsg2(jcr->errmsg, _("free_space error on %s. The current medium is probably not writable: ERR=%s.\n"),
-               dev->print_name(), dev->errmsg);
-         return VOL_NO_MEDIA;
-      }
-      
-      /* If we can't guess the name, and we are writing, just reopen the right file with open_first_part. */
-      if (open_first_part(dev) < 0) {
-         berrno be;
-         Mmsg2(jcr->errmsg, _("open_first_part error on %s: ERR=%s.\n"),
-               dev->print_name(), be.strerror());
-         Dmsg0(100, "Leave read_dev_volume_label_guess VOL_IO_ERROR (!open_guess_name_dev && !open_first_part)\n");
-         return VOL_IO_ERROR;
-      }
-      
-      Dmsg0(100, "Leave read_dev_volume_label_guess !open_guess_name_dev\n");
-      return read_dev_volume_label(dcr);
-   } else {
-      if (write && dcr->dev->free_space_errno < 0) {
-         Dmsg0(100, "Leave read_dev_volume_label_guess !free_space VOL_NO_MEDIA\n");
-         Mmsg2(jcr->errmsg, _("free_space error on %s. The current medium is probably not writable: ERR=%s.\n"),
-               dev->print_name(), dev->errmsg);
-         return VOL_NO_MEDIA;
-      }
-      
-      vol_label_status = read_dev_volume_label(dcr);
-
-      if (!write || dcr->VolCatInfo.VolCatParts > 0) {
-         Dmsg0(100, "Leave read_dev_volume_label_guess (open_guess_name_dev && (!write || dcr->VolCatInfo.VolCatParts > 0))\n");
-         return vol_label_status;
-      }
-      
-      if (open_first_part(dcr->dev) < 0) {
-         berrno be;
-         Mmsg2(jcr->errmsg, _("open_first_part error on %s: ERR=%s.\n"),
-               dev->print_name(), be.strerror());
-         Dmsg0(100, "Leave read_dev_volume_label_guess VOL_IO_ERROR (open_guess_name_dev && !open_first_part)\n");
-         return VOL_IO_ERROR;
-      }
-      
-      /* When writing, if the guessed volume name is no the right volume name, 
-       * report the error, otherwise, just continue with the right file.
-       */
-      if (vol_label_status != VOL_NAME_ERROR) {
-         Dmsg0(100, "Leave read_dev_volume_label_guess (open_guess_name_dev && !VOL_NAME_ERROR)\n");
-         dev->clear_labeled();   
-         return read_dev_volume_label(dcr);
-      } else {
-         Dmsg0(100, "Leave read_dev_volume_label_guess (open_guess_name_dev && VOL_NAME_ERROR)\n");
-         return vol_label_status;
+   /* If we are a streaming device, we only get one chance to read */
+   if (!dev_cap(dev, CAP_STREAM)) {
+      dev->rewind(dcr);
+      if (have_ansi_label) {
+         stat = read_ansi_ibm_label(dcr);            
+         /* If we want a label and didn't find it, return error */
+         if (stat != VOL_OK) {
+            goto bail_out;
+         }
       }
    }
       }
    }
+   empty_block(block);
+   return VOL_OK;
+
+bail_out:
+   empty_block(block);
+   dev->rewind(dcr);
+   Dmsg1(150, "return %d\n", stat);
+   return stat;
 }
 
 /*
 }
 
 /*
@@ -354,11 +287,10 @@ bool write_volume_label_to_block(DCR *dcr)
  *            after the label will be destroyed,
  *            in fact, we write the label 5 times !!!!
  *
  *            after the label will be destroyed,
  *            in fact, we write the label 5 times !!!!
  *
- *  This routine expects that open_device() was previously called.
- *
  *  This routine should be used only when labeling a blank tape.
  */
  *  This routine should be used only when labeling a blank tape.
  */
-bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName)
+bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, 
+                                   const char *PoolName, bool dvdnow)
 {
    DEVICE *dev = dcr->dev;
 
 {
    DEVICE *dev = dcr->dev;
 
@@ -366,17 +298,24 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *Po
    Dmsg0(99, "write_volume_label()\n");
    empty_block(dcr->block);
 
    Dmsg0(99, "write_volume_label()\n");
    empty_block(dcr->block);
 
-   Dmsg1(100, "Label type=%d\n", dev->label_type);
-   if (!rewind_dev(dev)) {
+   if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
+      /* If device is not tape, attempt to create it */
+      if (dev->is_tape() || dev->open(dcr, CREATE_READ_WRITE) < 0) {
+         goto bail_out;
+      }
+   }
+   Dmsg1(150, "Label type=%d\n", dev->label_type);
+   if (!dev->rewind(dcr)) {
+      free_volume(dev);
       memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
       memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
-      Dmsg2(30, "Bad status on %s from rewind: ERR=%s\n", dev->print_name(), strerror_dev(dev));
+      Dmsg2(30, "Bad status on %s from rewind: ERR=%s\n", dev->print_name(), dev->bstrerror());
       if (!forge_on) {
          goto bail_out;
       }
    }
 
       if (!forge_on) {
          goto bail_out;
       }
    }
 
-   /* Create PRE_LABEL */
-   create_volume_label(dev, VolName, PoolName);
+   /* Create PRE_LABEL or VOL_LABEL if DVD */
+   create_volume_label(dev, VolName, PoolName, dvdnow);
 
    /*
     * If we have already detected an ANSI label, re-read it
 
    /*
     * If we have already detected an ANSI label, re-read it
@@ -385,7 +324,7 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *Po
     */
    if (dev->label_type != B_BACULA_LABEL) {
       if (read_ansi_ibm_label(dcr) != VOL_OK) {
     */
    if (dev->label_type != B_BACULA_LABEL) {
       if (read_ansi_ibm_label(dcr) != VOL_OK) {
-         rewind_dev(dev);
+         dev->rewind(dcr);
          goto bail_out;
       }
    } else if (!write_ansi_ibm_labels(dcr, ANSI_VOL_LABEL, VolName)) {
          goto bail_out;
       }
    } else if (!write_ansi_ibm_labels(dcr, ANSI_VOL_LABEL, VolName)) {
@@ -398,7 +337,7 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *Po
    /* Temporarily mark in append state to enable writing */
    dev->set_append();
    if (!write_record_to_block(dcr->block, dcr->rec)) {
    /* Temporarily mark in append state to enable writing */
    dev->set_append();
    if (!write_record_to_block(dcr->block, dcr->rec)) {
-      Dmsg2(30, "Bad Label write on %s: ERR=%s\n", dev->print_name(), strerror_dev(dev));
+      Dmsg2(30, "Bad Label write on %s: ERR=%s\n", dev->print_name(), dev->bstrerror());
       goto bail_out;
    } else {
       Dmsg2(30, "Wrote label of %d bytes to %s\n", dcr->rec->data_len, dev->print_name());
       goto bail_out;
    } else {
       Dmsg2(30, "Wrote label of %d bytes to %s\n", dcr->rec->data_len, dev->print_name());
@@ -406,23 +345,34 @@ bool write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *Po
 
    Dmsg0(99, "Call write_block_to_dev()\n");
    if (!write_block_to_dev(dcr)) {
 
    Dmsg0(99, "Call write_block_to_dev()\n");
    if (!write_block_to_dev(dcr)) {
-      Dmsg2(30, "Bad Label write on %s: ERR=%s\n", dev->print_name(), strerror_dev(dev));
+      Dmsg2(30, "Bad Label write on %s: ERR=%s\n", dev->print_name(), dev->bstrerror());
       goto bail_out;
    }
       goto bail_out;
    }
+
+   /* Now commit block to DVD if we should write now */
+   if (dev->is_dvd() && dvdnow) {
+      if (!dvd_write_part(dcr)) {
+         Dmsg2(30, "Bad DVD write on %s: ERR=%s\n", dev->print_name(), dev->bstrerror());
+         goto bail_out;
+      }
+   }
+
    Dmsg0(99, " Wrote block to device\n");
 
    Dmsg0(99, " Wrote block to device\n");
 
-   if (weof_dev(dev, 1) == 0) {
+   if (dev->weof(1)) {
       dev->set_labeled();
       dev->set_labeled();
-      write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolName);
+      write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName);
    }
 
    if (debug_level >= 20)  {
       dump_volume_label(dev);
    }
    }
 
    if (debug_level >= 20)  {
       dump_volume_label(dev);
    }
+   new_volume(dcr, VolName);
    dev->clear_append();               /* remove append since this is PRE_LABEL */
    return true;
 
 bail_out:
    dev->clear_append();               /* remove append since this is PRE_LABEL */
    return true;
 
 bail_out:
+   free_volume(dev);
    memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
    dev->clear_append();               /* remove append since this is PRE_LABEL */
    return false;
    memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
    dev->clear_append();               /* remove append since this is PRE_LABEL */
    return false;
@@ -439,13 +389,19 @@ bool rewrite_volume_label(DCR *dcr, bool recycle)
    DEVICE *dev = dcr->dev;
    JCR *jcr = dcr->jcr;
 
    DEVICE *dev = dcr->dev;
    JCR *jcr = dcr->jcr;
 
-   Dmsg1(190, "set append found freshly labeled volume. dev=%x\n", dev);
+   if (dev->open(dcr, OPEN_READ_WRITE) < 0) {
+      return false;
+   }
+   Dmsg2(190, "set append found freshly labeled volume. fd=%d dev=%x\n", dev->fd, dev);
    dev->VolHdr.LabelType = VOL_LABEL; /* set Volume label */
    dev->set_append();
    if (!write_volume_label_to_block(dcr)) {
       Dmsg0(200, "Error from write volume label.\n");
       return false;
    }
    dev->VolHdr.LabelType = VOL_LABEL; /* set Volume label */
    dev->set_append();
    if (!write_volume_label_to_block(dcr)) {
       Dmsg0(200, "Error from write volume label.\n");
       return false;
    }
+
+   dev->VolCatInfo.VolCatBytes = 0;        /* reset byte count */
+
    /*
     * If we are not dealing with a streaming device,
     *  write the block now to ensure we have write permission.
    /*
     * If we are not dealing with a streaming device,
     *  write the block now to ensure we have write permission.
@@ -454,14 +410,16 @@ bool rewrite_volume_label(DCR *dcr, bool recycle)
     *  avoids re-writing the ANSI label, which we do not want to do.
     */
    if (!dev_cap(dev, CAP_STREAM)) {
     *  avoids re-writing the ANSI label, which we do not want to do.
     */
    if (!dev_cap(dev, CAP_STREAM)) {
-      if (!rewind_dev(dev)) {
-         Jmsg2(jcr, M_WARNING, 0, _("Rewind error on device %s: ERR=%s\n"),
-               dev->print_name(), strerror_dev(dev));
+      if (!dev->rewind(dcr)) {
+         Jmsg2(jcr, M_FATAL, 0, _("Rewind error on device %s: ERR=%s\n"),
+               dev->print_name(), dev->bstrerror());
+         return false;
       }
       if (recycle) {
       }
       if (recycle) {
-         if (!truncate_dev(dev)) {
-            Jmsg2(jcr, M_WARNING, 0, _("Truncate error on device %s: ERR=%s\n"),
-                  dev->print_name(), strerror_dev(dev));
+         if (!dev->truncate(dcr)) {
+            Jmsg2(jcr, M_FATAL, 0, _("Truncate error on device %s: ERR=%s\n"),
+                  dev->print_name(), dev->bstrerror());
+            return false;
          }
       }
 
          }
       }
 
@@ -472,18 +430,18 @@ bool rewrite_volume_label(DCR *dcr, bool recycle)
        */
       if (dev->label_type != B_BACULA_LABEL) {
          if (read_ansi_ibm_label(dcr) != VOL_OK) {
        */
       if (dev->label_type != B_BACULA_LABEL) {
          if (read_ansi_ibm_label(dcr) != VOL_OK) {
-            rewind_dev(dev);
+            dev->rewind(dcr);
             return false;
          }
             return false;
          }
-      } else if (!write_ansi_ibm_labels (dcr, ANSI_VOL_LABEL, dev->VolHdr.VolName)) {
+      } else if (!write_ansi_ibm_labels(dcr, ANSI_VOL_LABEL, dev->VolHdr.VolumeName)) {
          return false;
       }
 
       /* Attempt write to check write permission */
          return false;
       }
 
       /* Attempt write to check write permission */
-      Dmsg0(200, "Attempt to write to device.\n");
+      Dmsg1(200, "Attempt to write to device fd=%d.\n", dev->fd);
       if (!write_block_to_dev(dcr)) {
          Jmsg2(jcr, M_ERROR, 0, _("Unable to write device %s: ERR=%s\n"),
       if (!write_block_to_dev(dcr)) {
          Jmsg2(jcr, M_ERROR, 0, _("Unable to write device %s: ERR=%s\n"),
-            dev->print_name(), strerror_dev(dev));
+            dev->print_name(), dev->bstrerror());
          Dmsg0(200, "===ERROR write block to dev\n");
          return false;
       }
          Dmsg0(200, "===ERROR write block to dev\n");
          return false;
       }
@@ -491,7 +449,6 @@ bool rewrite_volume_label(DCR *dcr, bool recycle)
    /* Set or reset Volume statistics */
    dev->VolCatInfo.VolCatJobs = 0;
    dev->VolCatInfo.VolCatFiles = 0;
    /* Set or reset Volume statistics */
    dev->VolCatInfo.VolCatJobs = 0;
    dev->VolCatInfo.VolCatFiles = 0;
-   dev->VolCatInfo.VolCatBytes = 1;
    dev->VolCatInfo.VolCatErrors = 0;
    dev->VolCatInfo.VolCatBlocks = 0;
    dev->VolCatInfo.VolCatRBytes = 0;
    dev->VolCatInfo.VolCatErrors = 0;
    dev->VolCatInfo.VolCatBlocks = 0;
    dev->VolCatInfo.VolCatRBytes = 0;
@@ -504,7 +461,7 @@ bool rewrite_volume_label(DCR *dcr, bool recycle)
       dev->VolCatInfo.VolCatWrites = 1;
       dev->VolCatInfo.VolCatReads = 1;
    }
       dev->VolCatInfo.VolCatWrites = 1;
       dev->VolCatInfo.VolCatReads = 1;
    }
-   Dmsg0(100, "dir_update_vol_info. Set Append\n");
+   Dmsg0(150, "dir_update_vol_info. Set Append\n");
    bstrncpy(dev->VolCatInfo.VolCatStatus, "Append", sizeof(dev->VolCatInfo.VolCatStatus));
    if (!dir_update_volume_info(dcr, true)) {  /* indicate doing relabel */
       return false;
    bstrncpy(dev->VolCatInfo.VolCatStatus, "Append", sizeof(dev->VolCatInfo.VolCatStatus));
    if (!dir_update_volume_info(dcr, true)) {  /* indicate doing relabel */
       return false;
@@ -520,7 +477,7 @@ bool rewrite_volume_label(DCR *dcr, bool recycle)
     * End writing real Volume label (from pre-labeled tape), or recycling
     *  the volume.
     */
     * End writing real Volume label (from pre-labeled tape), or recycling
     *  the volume.
     */
-   Dmsg0(200, "OK from rewite vol label.\n");
+   Dmsg0(200, "OK from rewrite vol label.\n");
    return true;
 }
 
    return true;
 }
 
@@ -537,6 +494,7 @@ static void create_volume_label_record(DCR *dcr, DEV_RECORD *rec)
    struct date_time dt;
    DEVICE *dev = dcr->dev;
    JCR *jcr = dcr->jcr;
    struct date_time dt;
    DEVICE *dev = dcr->dev;
    JCR *jcr = dcr->jcr;
+   char buf[100];
 
    /* Serialize the label into the device record. */
 
 
    /* Serialize the label into the device record. */
 
@@ -563,8 +521,8 @@ static void create_volume_label_record(DCR *dcr, DEV_RECORD *rec)
    ser_float64(dev->VolHdr.write_date);   /* 0 if VerNum >= 11 */
    ser_float64(dev->VolHdr.write_time);   /* 0  if VerNum >= 11 */
 
    ser_float64(dev->VolHdr.write_date);   /* 0 if VerNum >= 11 */
    ser_float64(dev->VolHdr.write_time);   /* 0  if VerNum >= 11 */
 
-   ser_string(dev->VolHdr.VolName);
-   ser_string(dev->VolHdr.PrevVolName);
+   ser_string(dev->VolHdr.VolumeName);
+   ser_string(dev->VolHdr.PrevVolumeName);
    ser_string(dev->VolHdr.PoolName);
    ser_string(dev->VolHdr.PoolType);
    ser_string(dev->VolHdr.MediaType);
    ser_string(dev->VolHdr.PoolName);
    ser_string(dev->VolHdr.PoolType);
    ser_string(dev->VolHdr.MediaType);
@@ -580,7 +538,7 @@ static void create_volume_label_record(DCR *dcr, DEV_RECORD *rec)
    rec->VolSessionId = jcr->VolSessionId;
    rec->VolSessionTime = jcr->VolSessionTime;
    rec->Stream = jcr->NumVolumes;
    rec->VolSessionId = jcr->VolSessionId;
    rec->VolSessionTime = jcr->VolSessionTime;
    rec->Stream = jcr->NumVolumes;
-   Dmsg2(100, "Created Vol label rec: FI=%s len=%d\n", FI_to_ascii(rec->FileIndex),
+   Dmsg2(150, "Created Vol label rec: FI=%s len=%d\n", FI_to_ascii(buf, rec->FileIndex),
       rec->data_len);
 }
 
       rec->data_len);
 }
 
@@ -588,7 +546,8 @@ static void create_volume_label_record(DCR *dcr, DEV_RECORD *rec)
 /*
  * Create a volume label in memory
  */
 /*
  * Create a volume label in memory
  */
-void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName)
+void create_volume_label(DEVICE *dev, const char *VolName, 
+                         const char *PoolName, bool dvdnow)
 {
    DEVRES *device = (DEVRES *)dev->device;
 
 {
    DEVRES *device = (DEVRES *)dev->device;
 
@@ -596,12 +555,18 @@ void create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName)
 
    ASSERT(dev != NULL);
 
 
    ASSERT(dev != NULL);
 
+   free_volume(dev);         /* release any old volume */
    memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
 
    bstrncpy(dev->VolHdr.Id, BaculaId, sizeof(dev->VolHdr.Id));
    dev->VolHdr.VerNum = BaculaTapeVersion;
    memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
 
    bstrncpy(dev->VolHdr.Id, BaculaId, sizeof(dev->VolHdr.Id));
    dev->VolHdr.VerNum = BaculaTapeVersion;
-   dev->VolHdr.LabelType = PRE_LABEL;  /* Mark tape as unused */
-   bstrncpy(dev->VolHdr.VolName, VolName, sizeof(dev->VolHdr.VolName));
+   if (dev->is_dvd() && dvdnow) {
+      /* We do not want to re-label a DVD so write VOL_LABEL now */
+      dev->VolHdr.LabelType = VOL_LABEL;
+   } else {
+      dev->VolHdr.LabelType = PRE_LABEL;  /* Mark tape as unused */
+   }
+   bstrncpy(dev->VolHdr.VolumeName, VolName, sizeof(dev->VolHdr.VolumeName));
    bstrncpy(dev->VolHdr.PoolName, PoolName, sizeof(dev->VolHdr.PoolName));
    bstrncpy(dev->VolHdr.MediaType, device->media_type, sizeof(dev->VolHdr.MediaType));
 
    bstrncpy(dev->VolHdr.PoolName, PoolName, sizeof(dev->VolHdr.PoolName));
    bstrncpy(dev->VolHdr.MediaType, device->media_type, sizeof(dev->VolHdr.MediaType));
 
@@ -686,6 +651,7 @@ bool write_session_label(DCR *dcr, int label)
    DEVICE *dev = dcr->dev;
    DEV_RECORD *rec;
    DEV_BLOCK *block = dcr->block;
    DEVICE *dev = dcr->dev;
    DEV_RECORD *rec;
    DEV_BLOCK *block = dcr->block;
+   char buf1[100], buf2[100];
 
    rec = new_record();
    Dmsg1(90, "session_label record=%x\n", rec);
 
    rec = new_record();
    Dmsg1(90, "session_label record=%x\n", rec);
@@ -723,7 +689,7 @@ bool write_session_label(DCR *dcr, int label)
     *  read the next block).
     */
    if (!can_write_record_to_block(block, rec)) {
     *  read the next block).
     */
    if (!can_write_record_to_block(block, rec)) {
-      Dmsg0(100, "Cannot write session label to block.\n");
+      Dmsg0(150, "Cannot write session label to block.\n");
       if (!write_block_to_device(dcr)) {
          Dmsg0(90, "Got session label write_block_to_dev error.\n");
          /* ****FIXME***** errno is not set here */
       if (!write_block_to_device(dcr)) {
          Dmsg0(90, "Got session label write_block_to_dev error.\n");
          /* ****FIXME***** errno is not set here */
@@ -740,15 +706,15 @@ bool write_session_label(DCR *dcr, int label)
       return false;
    }
 
       return false;
    }
 
-   Dmsg6(20, "Write sesson_label record JobId=%d FI=%s SessId=%d Strm=%s len=%d "
+   Dmsg6(50, "Write sesson_label record JobId=%d FI=%s SessId=%d Strm=%s len=%d "
              "remainder=%d\n", jcr->JobId,
              "remainder=%d\n", jcr->JobId,
-      FI_to_ascii(rec->FileIndex), rec->VolSessionId,
-      stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len,
+      FI_to_ascii(buf1, rec->FileIndex), rec->VolSessionId,
+      stream_to_ascii(buf2, rec->Stream, rec->FileIndex), rec->data_len,
       rec->remainder);
 
    free_record(rec);
       rec->remainder);
 
    free_record(rec);
-   Dmsg2(20, "Leave write_session_label Block=%d File=%d\n",
-      dev->block_num, dev->file);
+   Dmsg2(50, "Leave write_session_label Block=%ud File=%ud\n",
+      dev->get_block(), dev->get_file());
    return true;
 }
 
    return true;
 }
 
@@ -766,11 +732,12 @@ bool write_session_label(DCR *dcr, int label)
 bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec)
 {
    ser_declare;
 bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec)
 {
    ser_declare;
+   char buf1[100], buf2[100];
 
    if (rec->FileIndex != VOL_LABEL && rec->FileIndex != PRE_LABEL) {
       Mmsg3(dev->errmsg, _("Expecting Volume Label, got FI=%s Stream=%s len=%d\n"),
 
    if (rec->FileIndex != VOL_LABEL && rec->FileIndex != PRE_LABEL) {
       Mmsg3(dev->errmsg, _("Expecting Volume Label, got FI=%s Stream=%s len=%d\n"),
-              FI_to_ascii(rec->FileIndex),
-              stream_to_ascii(rec->Stream, rec->FileIndex),
+              FI_to_ascii(buf1, rec->FileIndex),
+              stream_to_ascii(buf2, rec->Stream, rec->FileIndex),
               rec->data_len);
       if (!forge_on) {
          return false;
               rec->data_len);
       if (!forge_on) {
          return false;
@@ -797,8 +764,8 @@ bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec)
    unser_float64(dev->VolHdr.write_date);    /* Unused with VerNum >= 11 */
    unser_float64(dev->VolHdr.write_time);    /* Unused with VerNum >= 11 */
 
    unser_float64(dev->VolHdr.write_date);    /* Unused with VerNum >= 11 */
    unser_float64(dev->VolHdr.write_time);    /* Unused with VerNum >= 11 */
 
-   unser_string(dev->VolHdr.VolName);
-   unser_string(dev->VolHdr.PrevVolName);
+   unser_string(dev->VolHdr.VolumeName);
+   unser_string(dev->VolHdr.PrevVolumeName);
    unser_string(dev->VolHdr.PoolName);
    unser_string(dev->VolHdr.PoolType);
    unser_string(dev->VolHdr.MediaType);
    unser_string(dev->VolHdr.PoolName);
    unser_string(dev->VolHdr.PoolType);
    unser_string(dev->VolHdr.MediaType);
@@ -809,8 +776,8 @@ bool unser_volume_label(DEVICE *dev, DEV_RECORD *rec)
    unser_string(dev->VolHdr.ProgDate);
 
    ser_end(rec->data, SER_LENGTH_Volume_Label);
    unser_string(dev->VolHdr.ProgDate);
 
    ser_end(rec->data, SER_LENGTH_Volume_Label);
-   Dmsg0(90, "ser_read_vol\n");
-   if (debug_level >= 90) {
+   Dmsg0(190, "unser_vol_label\n");
+   if (debug_level >= 190) {
       dump_volume_label(dev);
    }
    return true;
       dump_volume_label(dev);
    }
    return true;
@@ -895,11 +862,11 @@ void dump_volume_label(DEVICE *dev)
       goto bail_out;
    default:
       LabelType = buf;
       goto bail_out;
    default:
       LabelType = buf;
-      sprintf(buf, "Unknown %d", dev->VolHdr.LabelType);
+      sprintf(buf, _("Unknown %d"), dev->VolHdr.LabelType);
       break;
    }
 
       break;
    }
 
-   Pmsg11(-1, "\nVolume Label:\n"
+   Pmsg11(-1, _("\nVolume Label:\n"
 "Id                : %s"
 "VerNo             : %d\n"
 "VolName           : %s\n"
 "Id                : %s"
 "VerNo             : %d\n"
 "VolName           : %s\n"
@@ -911,9 +878,9 @@ void dump_volume_label(DEVICE *dev)
 "MediaType         : %s\n"
 "PoolType          : %s\n"
 "HostName          : %s\n"
 "MediaType         : %s\n"
 "PoolType          : %s\n"
 "HostName          : %s\n"
-"",
+""),
              dev->VolHdr.Id, dev->VolHdr.VerNum,
              dev->VolHdr.Id, dev->VolHdr.VerNum,
-             dev->VolHdr.VolName, dev->VolHdr.PrevVolName,
+             dev->VolHdr.VolumeName, dev->VolHdr.PrevVolumeName,
              File, LabelType, dev->VolHdr.LabelSize,
              dev->VolHdr.PoolName, dev->VolHdr.MediaType,
              dev->VolHdr.PoolType, dev->VolHdr.HostName);
              File, LabelType, dev->VolHdr.LabelSize,
              dev->VolHdr.PoolName, dev->VolHdr.MediaType,
              dev->VolHdr.PoolType, dev->VolHdr.HostName);
@@ -921,13 +888,13 @@ void dump_volume_label(DEVICE *dev)
    if (dev->VolHdr.VerNum >= 11) {
       char dt[50];
       bstrftime(dt, sizeof(dt), btime_to_unix(dev->VolHdr.label_btime));
    if (dev->VolHdr.VerNum >= 11) {
       char dt[50];
       bstrftime(dt, sizeof(dt), btime_to_unix(dev->VolHdr.label_btime));
-      Pmsg1(-1, "Date label written: %s\n", dt);
+      Pmsg1(-1, _("Date label written: %s\n"), dt);
    } else {
    dt.julian_day_number   = dev->VolHdr.label_date;
    dt.julian_day_fraction = dev->VolHdr.label_time;
    tm_decode(&dt, &tm);
    Pmsg5(-1,
    } else {
    dt.julian_day_number   = dev->VolHdr.label_date;
    dt.julian_day_fraction = dev->VolHdr.label_time;
    tm_decode(&dt, &tm);
    Pmsg5(-1,
-"Date label written: %04d-%02d-%02d at %02d:%02d\n",
+_("Date label written: %04d-%02d-%02d at %02d:%02d\n"),
       tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min);
    }
 
       tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min);
    }
 
@@ -947,28 +914,28 @@ static void dump_session_label(DEV_RECORD *rec, const char *type)
    unser_session_label(&label, rec);
    dbl = debug_level;
    debug_level = 1;
    unser_session_label(&label, rec);
    dbl = debug_level;
    debug_level = 1;
-   Pmsg7(-1, "\n%s Record:\n"
+   Pmsg7(-1, _("\n%s Record:\n"
 "JobId             : %d\n"
 "VerNum            : %d\n"
 "PoolName          : %s\n"
 "PoolType          : %s\n"
 "JobName           : %s\n"
 "ClientName        : %s\n"
 "JobId             : %d\n"
 "VerNum            : %d\n"
 "PoolName          : %s\n"
 "PoolType          : %s\n"
 "JobName           : %s\n"
 "ClientName        : %s\n"
-"",    type, label.JobId, label.VerNum,
+""),    type, label.JobId, label.VerNum,
       label.PoolName, label.PoolType,
       label.JobName, label.ClientName);
 
    if (label.VerNum >= 10) {
       label.PoolName, label.PoolType,
       label.JobName, label.ClientName);
 
    if (label.VerNum >= 10) {
-      Pmsg4(-1, ""
+      Pmsg4(-1, _(
 "Job (unique name) : %s\n"
 "FileSet           : %s\n"
 "JobType           : %c\n"
 "JobLevel          : %c\n"
 "Job (unique name) : %s\n"
 "FileSet           : %s\n"
 "JobType           : %c\n"
 "JobLevel          : %c\n"
-"", label.Job, label.FileSetName, label.JobType, label.JobLevel);
+""), label.Job, label.FileSetName, label.JobType, label.JobLevel);
    }
 
    if (rec->FileIndex == EOS_LABEL) {
    }
 
    if (rec->FileIndex == EOS_LABEL) {
-      Pmsg8(-1, ""
+      Pmsg8(-1, _(
 "JobFiles          : %s\n"
 "JobBytes          : %s\n"
 "StartBlock        : %s\n"
 "JobFiles          : %s\n"
 "JobBytes          : %s\n"
 "StartBlock        : %s\n"
@@ -977,7 +944,7 @@ static void dump_session_label(DEV_RECORD *rec, const char *type)
 "EndFile           : %s\n"
 "JobErrors         : %s\n"
 "JobStatus         : %c\n"
 "EndFile           : %s\n"
 "JobErrors         : %s\n"
 "JobStatus         : %c\n"
-"",
+""),
          edit_uint64_with_commas(label.JobFiles, ec1),
          edit_uint64_with_commas(label.JobBytes, ec2),
          edit_uint64_with_commas(label.StartBlock, ec3),
          edit_uint64_with_commas(label.JobFiles, ec1),
          edit_uint64_with_commas(label.JobBytes, ec2),
          edit_uint64_with_commas(label.StartBlock, ec3),
@@ -995,8 +962,7 @@ static void dump_session_label(DEV_RECORD *rec, const char *type)
       dt.julian_day_number   = label.write_date;
       dt.julian_day_fraction = label.write_time;
       tm_decode(&dt, &tm);
       dt.julian_day_number   = label.write_date;
       dt.julian_day_fraction = label.write_time;
       tm_decode(&dt, &tm);
-      Pmsg5(-1, _(""
-"Date written      : %04d-%02d-%02d at %02d:%02d\n"),
+      Pmsg5(-1, _("Date written      : %04d-%02d-%02d at %02d:%02d\n"),
       tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min);
    }
 
       tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min);
    }
 
@@ -1008,6 +974,9 @@ void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose)
    const char *type;
    int dbl;
 
    const char *type;
    int dbl;
 
+   if (rec->FileIndex == 0 && rec->VolSessionId == 0 && rec->VolSessionTime == 0) {
+      return;
+   }
    dbl = debug_level;
    debug_level = 1;
    switch (rec->FileIndex) {
    dbl = debug_level;
    debug_level = 1;
    switch (rec->FileIndex) {
@@ -1027,7 +996,7 @@ void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose)
       type = _("End of Media");
       break;
    case EOT_LABEL:
       type = _("End of Media");
       break;
    case EOT_LABEL:
-      type = ("End of Tape");
+      type = _("End of Tape");
       break;
    default:
       type = _("Unknown");
       break;
    default:
       type = _("Unknown");
@@ -1047,33 +1016,39 @@ void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose)
          dump_session_label(rec, type);
          break;
       case EOM_LABEL:
          dump_session_label(rec, type);
          break;
       case EOM_LABEL:
-         Pmsg5(-1, "%s Record: SessId=%d SessTime=%d JobId=%d DataLen=%d\n",
-            type, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
+         Pmsg7(-1, _("%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n"),
+            type, dev->file, dev->block_num, rec->VolSessionId, 
+            rec->VolSessionTime, rec->Stream, rec->data_len);
          break;
       case EOT_LABEL:
          Pmsg0(-1, _("End of physical tape.\n"));
          break;
       default:
          break;
       case EOT_LABEL:
          Pmsg0(-1, _("End of physical tape.\n"));
          break;
       default:
-         Pmsg5(-1, "%s Record: SessId=%d SessTime=%d JobId=%d DataLen=%d\n",
-            type, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
+         Pmsg7(-1, _("%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n"),
+            type, dev->file, dev->block_num, rec->VolSessionId, 
+            rec->VolSessionTime, rec->Stream, rec->data_len);
          break;
       }
    } else {
       SESSION_LABEL label;
          break;
       }
    } else {
       SESSION_LABEL label;
+      char dt[50];
       switch (rec->FileIndex) {
       case SOS_LABEL:
          unser_session_label(&label, rec);
       switch (rec->FileIndex) {
       case SOS_LABEL:
          unser_session_label(&label, rec);
-         Pmsg6(-1, "%s Record: SessId=%d SessTime=%d JobId=%d Level=%c Type=%c\n",
-            type, rec->VolSessionId, rec->VolSessionTime, rec->Stream,
-            label.JobLevel, label.JobType);
+         bstrftimes(dt, sizeof(dt), btime_to_unix(label.write_btime));
+         Pmsg6(-1, _("%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n"),
+            type, dev->file, dev->block_num, rec->VolSessionId, rec->VolSessionTime, label.JobId);
+         Pmsg4(-1, _("   Job=%s Date=%s Level=%c Type=%c\n"),
+            label.Job, dt, label.JobLevel, label.JobType);
          break;
       case EOS_LABEL:
          char ed1[30], ed2[30];
          unser_session_label(&label, rec);
          break;
       case EOS_LABEL:
          char ed1[30], ed2[30];
          unser_session_label(&label, rec);
-         Pmsg6(-1, "%s Record: SessId=%d SessTime=%d JobId=%d Level=%c Type=%c\n",
-            type, rec->VolSessionId, rec->VolSessionTime, rec->Stream,
-            label.JobLevel, label.JobType);
-         Pmsg4(-1, "   Files=%s Bytes=%s Errors=%d Status=%c\n",
+         bstrftimes(dt, sizeof(dt), btime_to_unix(label.write_btime));
+         Pmsg6(-1, _("%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d\n"),
+            type, dev->file, dev->block_num, rec->VolSessionId, rec->VolSessionTime, label.JobId);
+         Pmsg7(-1, _("   Date=%s Level=%c Type=%c Files=%s Bytes=%s Errors=%d Status=%c\n"),
+            dt, label.JobLevel, label.JobType,
             edit_uint64_with_commas(label.JobFiles, ed1),
             edit_uint64_with_commas(label.JobBytes, ed2),
             label.JobErrors, (char)label.JobStatus);
             edit_uint64_with_commas(label.JobFiles, ed1),
             edit_uint64_with_commas(label.JobBytes, ed2),
             label.JobErrors, (char)label.JobStatus);
@@ -1082,8 +1057,9 @@ void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose)
       case PRE_LABEL:
       case VOL_LABEL:
       default:
       case PRE_LABEL:
       case VOL_LABEL:
       default:
-         Pmsg5(-1, "%s Record: SessId=%d SessTime=%d JobId=%d DataLen=%d\n",
-      type, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
+         Pmsg7(-1, _("%s Record: File:blk=%u:%u SessId=%d SessTime=%d JobId=%d DataLen=%d\n"),
+            type, dev->file, dev->block_num, rec->VolSessionId, rec->VolSessionTime, 
+            rec->Stream, rec->data_len);
          break;
       case EOT_LABEL:
          break;
          break;
       case EOT_LABEL:
          break;