]> git.sur5r.net Git - bacula/bacula/commitdiff
Fix double jobmedia bug, doc, add non-fatal error count
authorKern Sibbald <kern@sibbald.com>
Tue, 20 May 2003 19:26:29 +0000 (19:26 +0000)
committerKern Sibbald <kern@sibbald.com>
Tue, 20 May 2003 19:26:29 +0000 (19:26 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@523 91ce42f0-d328-0410-95d8-f526ca767f89

16 files changed:
bacula/kernstodo
bacula/src/dird/backup.c
bacula/src/dird/restore.c
bacula/src/filed/job.c
bacula/src/jcr.h
bacula/src/lib/message.c
bacula/src/stored/acquire.c
bacula/src/stored/append.c
bacula/src/stored/askdir.c
bacula/src/stored/block.c
bacula/src/stored/bscan.c
bacula/src/stored/btape.c
bacula/src/stored/dev.c
bacula/src/stored/device.c
bacula/src/stored/mount.c
bacula/src/stored/protos.h

index dd5833720a464beafdbac9b31b6baba47a3b4ea7..2aad564d6dbdb42d99b07b9fd1e99b4ab3716cce 100644 (file)
@@ -8,6 +8,11 @@ Documentation to do: (any release a little bit at a time)
 - Document problems with Verify and pruning.
 - Document how to use multiple databases.
 - For FreeBSD typical /dev/nrsa0 and for mtx /dev/pass1
+- VXA drives have a "cleaning required"
+  indicator, but Exabyte recommends preventive cleaning after every 75
+  hours of operation.
+- Lookup HP cleaning recommendations.
+- Lookup HP tape replacement recommendations (see trouble shooting autochanger)
 
           
 Testing to do: (painful)
@@ -15,14 +20,14 @@ Testing to do: (painful)
 - blocksize recognition code.
 - multiple simultaneous Volumes
 - Test if rewind at end of tape waits for tape to rewind.
+- Test cancel at EOM.       
 
 - Figure out how to use ssh or stunnel to protect Bacula communications.
 
 For 1.31 release:
 - Finish WIN32_DATA stream code (bextract, check if can handle stream)
 - Default duration with no qualifier is sec should be 1 day
-- Find a solution for the multiple FileSet problem (when it is changed).
-  Add date?
+- Find a solution for the multiple FileSet problem (when it is changed). Add date?
 - Cancel waiting for Client connect in SD if FD goes away.
 - Testing Tibs job erred and hung director on Storage resource.  This was
   because there were a whole pile of jobs hanging around in the SD  
@@ -34,44 +39,8 @@ For 1.31 release:
 - File the Automatically selected: xxx
   to say Automatically selected Pool: xxx
 - Should Bacula make an Append tape as Purged when purging?
-- Shell expansion failes for working_directory in SD from time to tim.
+- Shell expansion fails for working_directory in SD from time to time.
 - Possibly update all client records at startup.
-- Volume names with spaces get jammed into the catalog with 0x1 
-  i.e. the SD bashes the Volume but they are not unbased by Dir.
-  jerom-dir: MonthlySave.2003-05-10_17.12.01 Error: Unable to get Media
-  record for Volume Tape^A1: ERR=sql_get.c:788 Media record for Volume
-  "Tape^A1" not found.
-   jerom-sd: MonthlySave.2003-05-10_17.12.01 Error: Error updating Volume
-   Info: 1991 Catalog Request failed: sql_get.c:788 Media record for Volume
-   "Tape^A1" not found.
-
-- Cancellation caused JobMedia error:
-     babylon5-dir: Last FULL backup time not found. Doing FULL backup.               
-     babylon5-dir: Start Backup JobId 416, Job=Zocalo_Save.2003-05-19_02.15.06       
-     babylon5-sd: End of media on Volume VXA-V17-Inc-001 Bytes=31,982,900,672 Blocks=495,781.
-     babylon5-sd: Job Zocalo_Save.2003-05-19_02.15.06 waiting. Cannot find any appendable volumes.
-     babylon5-sd: Someone woke me up, but I cannot find any appendable volumes
-       for Job=Zocalo_Save.2003-05-19_02.15.06.                                
-     babylon5-sd: Zocalo_Save.2003-05-19_02.15.06 Fatal error: Job
-       Zocalo_Save.2003-05-19_02.15.06 canceled while waiting for mount on
-       Storage Device "Ecrix_VXA-1".
-     babylon5-sd: Zocalo_Save.2003-05-19_02.15.06 Fatal error: Cannot fixup device
-       error. Job Zocalo_Save.2003-05-19_02.15.06 canceled while waiting for
-       mount on Storage Device "Ecrix_VXA-1".
-                                                                                     
-     babylon5-dir: Zocalo_Save.2003-05-19_02.15.06 Error: Catalog error creating
-       JobMedia record. sql_create.c:125 Create JobMedia failed. Record already
-       exists.
-     babylon5-sd: Zocalo_Save.2003-05-19_02.15.06 Error: Error creating JobMedia
-       record: 1991 Update JobMedia error
-                                                                                     
-     babylon5-sd: Zocalo_Save.2003-05-19_02.15.06 Error: askdir.c:158 NULL Volume
-       name. This shouldn't happen!!!
-     zocalo-fd: Zocalo_Save.2003-05-19_02.15.06 Error: bnet.c:310 Write error
-       sending to Storage daemon:babylon5:9103: ERR=Broken pipe
-     
-
-- ChangeServiceConfig2A does not exist on WinNT (ADVAPI32.DLL).
 
 - Implement MTIOCERRSTAT on FreeBSD to clear tape error conditions.
 
@@ -87,15 +56,11 @@ For 1.31 release:
   Much like xxx_conf.c scan table.
   keyword, handler(store_routine), store_address, code, flags, default.
 
-- Fix "access not allowed" for backup of files on WinXP.
-- Check for existence of all new Win32 API's.  See LoadLibrary in 
-  winservice.cpp
 - Examine Bare Metal restore problem (a FD crash exists somewhere ...).
 - Test multiple simultaneous Volumes
 - Document FInclude ...
 - Implement timeout in response() when it should come quickly.
 - Implement console @echo command.
-- Bug: fix access problems on files restored on WinXP.
 - Implement a Slot priority (loaded/not loaded).
 - Implement "vacation" Incremental only saves.
 - Implement single pane restore (much like the Gftp panes).
@@ -202,7 +167,6 @@ For 1.31 release:
   records -- one per Job, maybe a JCR or some other structure with
   a block and a record.
 - Figure out how to do a bare metal Windows restore
-- Put system type returned by FD into catalog.
 - Possibly add email to Watchdog if drive is unmounted too
   long and a job is waiting on the drive.
 - Use read_record.c in SD code.
@@ -872,4 +836,43 @@ Done: (see kernsdone for more)
 - Document what characters can go into Volume names.
 - Getting the following on all directories on Win32
   19-May-2003 01:14 tibs-fd:      Could not access c:/cygwin/home/kern/rxvt: ERR=Permission denied
+- Cancellation caused JobMedia error:
+     babylon5-dir: Last FULL backup time not found. Doing FULL backup.               
+     babylon5-dir: Start Backup JobId 416, Job=Zocalo_Save.2003-05-19_02.15.06       
+     babylon5-sd: End of media on Volume VXA-V17-Inc-001 Bytes=31,982,900,672 Blocks=495,781.
+     babylon5-sd: Job Zocalo_Save.2003-05-19_02.15.06 waiting. Cannot find any appendable volumes.
+     babylon5-sd: Someone woke me up, but I cannot find any appendable volumes
+       for Job=Zocalo_Save.2003-05-19_02.15.06.                                
+     babylon5-sd: Zocalo_Save.2003-05-19_02.15.06 Fatal error: Job
+       Zocalo_Save.2003-05-19_02.15.06 canceled while waiting for mount on
+       Storage Device "Ecrix_VXA-1".
+     babylon5-sd: Zocalo_Save.2003-05-19_02.15.06 Fatal error: Cannot fixup device
+       error. Job Zocalo_Save.2003-05-19_02.15.06 canceled while waiting for
+       mount on Storage Device "Ecrix_VXA-1".
+                                                                                     
+     babylon5-dir: Zocalo_Save.2003-05-19_02.15.06 Error: Catalog error creating
+       JobMedia record. sql_create.c:125 Create JobMedia failed. Record already
+       exists.
+     babylon5-sd: Zocalo_Save.2003-05-19_02.15.06 Error: Error creating JobMedia
+       record: 1991 Update JobMedia error
+                                                                                     
+     babylon5-sd: Zocalo_Save.2003-05-19_02.15.06 Error: askdir.c:158 NULL Volume
+       name. This shouldn't happen!!!
+     zocalo-fd: Zocalo_Save.2003-05-19_02.15.06 Error: bnet.c:310 Write error
+       sending to Storage daemon:babylon5:9103: ERR=Broken pipe
+- Volume names with spaces get jammed into the catalog with 0x1 
+  i.e. the SD bashes the Volume but they are not unbased by Dir.
+  jerom-dir: MonthlySave.2003-05-10_17.12.01 Error: Unable to get Media
+  record for Volume Tape^A1: ERR=sql_get.c:788 Media record for Volume
+  "Tape^A1" not found.
+   jerom-sd: MonthlySave.2003-05-10_17.12.01 Error: Error updating Volume
+   Info: 1991 Catalog Request failed: sql_get.c:788 Media record for Volume
+   "Tape^A1" not found.
+- ChangeServiceConfig2A does not exist on WinNT (ADVAPI32.DLL).
+- Fix "access not allowed" for backup of files on WinXP.
+- Check for existence of all new Win32 API's.  See LoadLibrary in 
+  winservice.cpp
+- Count errors during restore and print them in the Job report.
+- Bug: fix access problems on files restored on WinXP.
+- Put system type returned by FD into catalog.
 
index dd54012c3059fe45133c5a4096a4ec4eeb73f135..04c1cc2292d9d5bd45869f968316b6045e16732e 100644 (file)
@@ -47,7 +47,7 @@ static char levelcmd[]  = "level = %s%s\n";
 static char OKbackup[]  = "2000 OK backup\n";
 static char OKstore[]   = "2000 OK storage\n";
 static char OKlevel[]   = "2000 OK level\n";
-static char EndBackup[] = "2801 End Backup Job TermCode=%d JobFiles=%u ReadBytes=%" lld " JobBytes=%" lld "\n";
+static char EndBackup[] = "2801 End Backup Job TermCode=%d JobFiles=%u ReadBytes=%" lld " JobBytes=%" lld " Errors=%u\n";
 
 
 /* Forward referenced functions */
@@ -275,7 +275,7 @@ static int wait_for_job_termination(JCR *jcr)
    /* Wait for Client to terminate */
    while ((n = bget_dirmsg(fd)) >= 0) {
       if (sscanf(fd->msg, EndBackup, &jcr->FDJobStatus, &jcr->JobFiles,
-         &jcr->ReadBytes, &jcr->JobBytes) == 4) {
+         &jcr->ReadBytes, &jcr->JobBytes, &jcr->Errors) == 5) {
         fd_ok = TRUE;
         set_jcr_job_status(jcr, jcr->FDJobStatus);
          Dmsg1(100, "FDStatus=%c\n", (char)jcr->JobStatus);
@@ -463,6 +463,7 @@ Volume names(s):        %s\n\
 Volume Session Id:      %d\n\
 Volume Session Time:    %d\n\
 Last Volume Bytes:      %s\n\
+Non-fatal FD errors:    %d\n\
 FD termination status:  %s\n\
 SD termination status:  %s\n\
 Termination:            %s\n\n"),
@@ -482,6 +483,7 @@ Termination:            %s\n\n"),
        jcr->VolSessionId,
        jcr->VolSessionTime,
        edit_uint64_with_commas(mr.VolBytes, ec3),
+       jcr->Errors,
        fd_term_msg,
        sd_term_msg,
        term_msg);
index 0e7fb9d5746e209e65bedb4f55965e2cc3ccf167..8602eb2fcbb4730003f32a7a0ebf2d6dd816e9b2 100644 (file)
@@ -52,7 +52,7 @@ static char OKrestore[]   = "2000 OK restore\n";
 static char OKstore[]     = "2000 OK storage\n";
 static char OKsession[]   = "2000 OK session\n";
 static char OKbootstrap[] = "2000 OK bootstrap\n";
-static char EndRestore[]  = "2800 End Job TermCode=%d JobFiles=%u JobBytes=%" lld "\n";
+static char EndRestore[]  = "2800 End Job TermCode=%d JobFiles=%u JobBytes=%" lld " Errors=%u\n";
 
 /* Forward referenced functions */
 static void restore_cleanup(JCR *jcr, int status);
@@ -256,7 +256,7 @@ int do_restore(JCR *jcr)
    while (bget_dirmsg(fd) >= 0) {
       Dmsg1(100, "dird<filed: %s\n", fd->msg);
       if (sscanf(fd->msg, EndRestore, &jcr->FDJobStatus, &jcr->JobFiles,
-         &jcr->JobBytes) == 3) {
+         &jcr->JobBytes, &jcr->Errors) == 4) {
         ok = TRUE;
       }
    }
@@ -319,7 +319,11 @@ static void restore_cleanup(JCR *jcr, int TermCode)
    }
    bstrftime(sdt, sizeof(sdt), jcr->jr.StartTime);
    bstrftime(edt, sizeof(edt), jcr->jr.EndTime);
-   kbps = (double)jcr->jr.JobBytes / (1000 * (jcr->jr.EndTime - jcr->jr.StartTime));
+   if (jcr->jr.EndTime - jcr->jr.StartTime > 0) {
+      kbps = (double)jcr->jr.JobBytes / (1000 * (jcr->jr.EndTime - jcr->jr.StartTime));
+   } else {
+      kbps = 0;
+   }
    if (kbps < 0.05) {
       kbps = 0;
    }
@@ -335,6 +339,7 @@ End time:               %s\n\
 Files Restored:         %s\n\
 Bytes Restored:         %s\n\
 Rate:                   %.1f KB/s\n\
+Non-fatal Errors:       %d\n\
 FD termination status:  %s\n\
 Termination:            %s\n\n"),
        edt,
@@ -346,6 +351,7 @@ Termination:            %s\n\n"),
        edit_uint64_with_commas((uint64_t)jcr->jr.JobFiles, ec1),
        edit_uint64_with_commas(jcr->jr.JobBytes, ec2),
        (float)kbps,
+       jcr->Errors,
        fd_term_msg,
        term_msg);
 
index 814b7e003b3aff1177c2ab60d396a205c5fb9ad4..a67bca6ef3e4dba3d28198433a6b0a7c61a5b07a 100644 (file)
@@ -110,8 +110,8 @@ static char OKstore[]     = "2000 OK storage\n";
 static char OKjob[]       = "2000 OK Job " FDHOST "," DISTNAME "," DISTVER;
 static char OKsetdebug[]  = "2000 OK setdebug=%d\n";
 static char BADjob[]      = "2901 Bad Job\n";
-static char EndRestore[]  = "2800 End Job TermCode=%d JobFiles=%u JobBytes=%" lld "\n";
-static char EndBackup[]   = "2801 End Backup Job TermCode=%d JobFiles=%u ReadBytes=%" lld " JobBytes=%" lld "\n";
+static char EndRestore[]  = "2800 End Job TermCode=%d JobFiles=%u JobBytes=%s Errors=%u\n";
+static char EndBackup[]   = "2801 End Backup Job TermCode=%d JobFiles=%u ReadBytes=%s JobBytes=%s Errors=%u\n";
 
 /* Responses received from Storage Daemon */
 static char OK_end[]       = "3000 OK end\n";
@@ -516,6 +516,7 @@ static int backup_cmd(JCR *jcr)
    BSOCK *sd = jcr->store_bsock;
    int ok = 0;
    int SDJobStatus;
+   char ed1[50], ed2[50];
 
    set_jcr_job_status(jcr, JS_Blocked);
    jcr->JobType = JT_BACKUP;
@@ -622,7 +623,9 @@ static int backup_cmd(JCR *jcr)
 
 cleanup:
 
-   bnet_fsend(dir, EndBackup, jcr->JobStatus, jcr->JobFiles, jcr->ReadBytes, jcr->JobBytes);
+   bnet_fsend(dir, EndBackup, jcr->JobStatus, jcr->JobFiles, 
+      edit_uint64(jcr->ReadBytes, ed1), 
+      edit_uint64(jcr->JobBytes, ed2), jcr->Errors);   
 
    return 0;                         /* return and stop command loop */
 }
@@ -703,6 +706,7 @@ static int restore_cmd(JCR *jcr)
    BSOCK *sd = jcr->store_bsock;
    POOLMEM *where;
    char replace;
+   char ed1[50];
 
    /*
     * Scan WHERE (base directory for restore) from command
@@ -768,7 +772,7 @@ static int restore_cmd(JCR *jcr)
 bail_out:
    /* Send termination status back to Dir */
    bnet_fsend(dir, EndRestore, jcr->JobStatus, jcr->num_files_examined, 
-             jcr->JobBytes);
+      edit_uint64(jcr->JobBytes, ed1), jcr->Errors);
 
    /* Inform Director that we are done */
    bnet_sig(dir, BNET_TERMINATE);
index 53f9686fad95ef30cdf79d5df485d93585926b65..1b6a28858bb5101ad6f5f7d1370637754a13ee4d 100644 (file)
@@ -209,7 +209,7 @@ struct s_jcr {
    int session_opened;
    DEV_RECORD rec;                    /* Read/Write record */
    long Ticket;                       /* ticket for this job */
-   uint32_t VolFirstFile;             /* First file index this Volume */
+   uint32_t VolFirstIndex;            /* First file index this Volume */
    uint32_t FileIndex;                /* Current File Index */
    uint32_t EndFile;                  /* End file written */
    uint32_t StartFile;                /* Start write file */
index 83283a52ceb97b92c526ccec8246aa56ab3ab713..e47b407b8c349ebf139ab77f7dc441e991162a5c 100755 (executable)
@@ -920,6 +920,7 @@ Jmsg(void *vjcr, int type, int level, char *fmt,...)
        len = sprintf(rbuf, "%s: %s Fatal error: ", my_name, job);
        if (jcr) {
          set_jcr_job_status(jcr, JS_FatalError);
+         jcr->Errors++;
        }
        break;
     case M_ERROR:
index 8599e0b35921ac22793fe1aa7eaf96291e3c9e3c..7e92fed82638adffaef5c6dd04064afae3f764e1 100644 (file)
@@ -289,7 +289,9 @@ int release_device(JCR *jcr, DEVICE *dev)
       if (dev->num_writers == 0) {
          Dmsg0(100, "dir_create_jobmedia_record. Release\n");
         dir_create_jobmedia_record(jcr);
-        weof_dev(dev, 1);
+        if (dev_can_write(dev)) {
+           weof_dev(dev, 1);
+        }
         dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
         dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs */
         /* Note! do volume update before close, which zaps VolCatInfo */
index 27650e7915e3de5cfef74925f00825b7ff7aab2f..73a8c1ef7e61ff0a03ee1ef382bfa3ade0128f09 100644 (file)
@@ -108,7 +108,7 @@ int do_append_data(JCR *jcr)
     *  file. 1. for the Attributes, 2. for the file data if any, 
     *  and 3. for the MD5 if any.
     */
-   jcr->VolFirstFile = 0;
+   jcr->VolFirstIndex = 0;
    time(&jcr->run_time);             /* start counting time for rates */
    for (last_file_index = 0; ok && !job_canceled(jcr); ) {
       char info[100];
@@ -145,8 +145,8 @@ int do_append_data(JCR *jcr)
       }
       if (file_index != last_file_index) {
         jcr->JobFiles = file_index;
-        if (jcr->VolFirstFile == 0) {
-           jcr->VolFirstFile = file_index;
+        if (jcr->VolFirstIndex == 0) {
+           jcr->VolFirstIndex = file_index;
         }
         last_file_index = file_index;
       }
@@ -225,17 +225,23 @@ int do_append_data(JCR *jcr)
 
    Dmsg1(200, "Write session label JobStatus=%d\n", jcr->JobStatus);
 
-   if (!write_session_label(jcr, block, EOS_LABEL)) {
-      Jmsg1(jcr, M_FATAL, 0, _("Error writting end session label. ERR=%s\n"),
-         strerror_dev(dev));
-      set_jcr_job_status(jcr, JS_ErrorTerminated);
-      ok = FALSE;
-   }
-   /* Write out final block of this session */
-   if (!write_block_to_device(jcr, dev, block)) {
-      Pmsg0(000, _("Set ok=FALSE after write_block_to_device.\n"));
-      set_jcr_job_status(jcr, JS_ErrorTerminated);
-      ok = FALSE;
+   /*
+    * If !OK, check if we can still write. This may not be the case
+    *  if we are at the end of the tape or we got a fatal I/O error.
+    */
+   if (ok || dev_can_write(dev)) {
+      if (!write_session_label(jcr, block, EOS_LABEL)) {
+         Jmsg1(jcr, M_FATAL, 0, _("Error writting end session label. ERR=%s\n"),
+            strerror_dev(dev));
+        set_jcr_job_status(jcr, JS_ErrorTerminated);
+        ok = FALSE;
+      }
+      /* Write out final block of this session */
+      if (!write_block_to_device(jcr, dev, block)) {
+         Pmsg0(000, _("Set ok=FALSE after write_block_to_device.\n"));
+        set_jcr_job_status(jcr, JS_ErrorTerminated);
+        ok = FALSE;
+      }
    }
 
    Dmsg1(200, "release device JobStatus=%d\n", jcr->JobStatus);
index c73dc580c5e5754a6d5335eb896322cceae9dbde..59286b8ad40903987500cc677179d50224d941c3 100644 (file)
@@ -188,8 +188,12 @@ int dir_create_jobmedia_record(JCR *jcr)
 {
    BSOCK *dir = jcr->dir_bsock;
 
+   if (jcr->VolFirstIndex == 0) {
+      return 1;                      /* nothing written to tape */
+   }
+
    bnet_fsend(dir, Create_job_media, jcr->Job, 
-      jcr->VolFirstFile, jcr->JobFiles,
+      jcr->VolFirstIndex, jcr->JobFiles,
       jcr->StartFile, jcr->EndFile,
       jcr->StartBlock, jcr->EndBlock);
    Dmsg1(100, "create_jobmedia(): %s", dir->msg);
index e21533d2cb2e7fefa353b4159ebcc9593d4738bb..7815c8ebfd3dcfa5ed991e9377c04d03ee051a29 100644 (file)
@@ -304,7 +304,7 @@ int write_block_to_dev(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
    /* dump_block(block, "before write"); */
    if (dev->state & ST_WEOT) {
       Dmsg0(100, "return write_block_to_dev with ST_WEOT\n");
-      Jmsg(&dev->errmsg, M_FATAL, 0,  _("Cannot write block. Device at EOF.\n"));
+      Jmsg(&dev->errmsg, M_FATAL, 0,  _("Cannot write block. Device at EOM.\n"));
       return 0;
    }
    wlen = block->binbuf;
index b0a4493fd05c6cc5fbd2542549ddd30ee9fb7d34..a606979e3070b28d75455cc8c47fec955a8e72ff 100644 (file)
@@ -354,7 +354,7 @@ static void record_cb(JCR *bjcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
            }
            /* Reset some JCR variables */
            for (mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
-              mjcr->VolFirstFile = mjcr->FileIndex = 0;
+              mjcr->VolFirstIndex = mjcr->FileIndex = 0;
               mjcr->StartBlock = mjcr->EndBlock = 0;
               mjcr->StartFile = mjcr->EndFile = 0;
            }
@@ -697,8 +697,8 @@ static int create_file_attributes_record(B_DB *db, JCR *mjcr,
    ar.Stream = rec->Stream;
    ar.FileIndex = rec->FileIndex;
    ar.attr = ap;
-   if (mjcr->VolFirstFile == 0) {
-      mjcr->VolFirstFile = rec->FileIndex;
+   if (mjcr->VolFirstIndex == 0) {
+      mjcr->VolFirstIndex = rec->FileIndex;
    }
    mjcr->FileIndex = rec->FileIndex;
    mjcr->JobFiles++;
@@ -1031,7 +1031,7 @@ static int create_jobmedia_record(B_DB *db, JCR *mjcr)
    memset(&jmr, 0, sizeof(jmr));
    jmr.JobId = mjcr->JobId;
    jmr.MediaId = mr.MediaId;
-   jmr.FirstIndex = mjcr->VolFirstFile;
+   jmr.FirstIndex = mjcr->VolFirstIndex;
    jmr.LastIndex = mjcr->FileIndex;
    jmr.StartFile = mjcr->StartFile;
    jmr.EndFile = mjcr->EndFile;
index e121d642f4cc605c65790e844758961f2f733d26..860bf2620ad12fee40fcf6c3a72161f4209798e9 100644 (file)
@@ -1155,7 +1155,7 @@ This may take a long time. I.e. hours! ...\n\n");
    /* 
     * Get Data from File daemon, write to device   
     */
-   jcr->VolFirstFile = 0;
+   jcr->VolFirstIndex = 0;
    time(&jcr->run_time);             /* start counting time for rates */
    for (file_index = 0; ok && !job_canceled(jcr); ) {
       uint64_t *lp;
index a6c3bee4fdb06e77e6368100c115add99f69ed27..b0edad2711bca202a62f3013225a2ddc46edd2e9 100644 (file)
@@ -1108,6 +1108,24 @@ dev_is_tape(DEVICE *dev)
    return (dev->state & ST_TAPE) ? 1 : 0;
 }
 
+
+/*
+ * return 1 if the device is read for write, and 0 otherwise
+ *   This is meant for checking at the end of a job to see
+ *   if we still have a tape (perhaps not if at end of tape
+ *   and the job is canceled).
+ */
+int
+dev_can_write(DEVICE *dev)
+{
+   if ((dev->state & ST_OPENED) &&  (dev->state & ST_APPEND) &&
+       (dev->state & ST_LABEL) && !(dev->state & ST_WEOT)) {
+      return 1;
+   } else {
+      return 0;
+   }
+}
+
 char *
 dev_name(DEVICE *dev)
 {
index 9c34ea667cb9d8ee1f71f5369d185ddb5345bc30..f1d066c3a73b1ddd14a36d79c4502dcfbdd0e5fb 100644 (file)
@@ -107,6 +107,7 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
            unblock_device(dev);
            return 0;
         }
+        mjcr->VolFirstIndex = 0;      /* prevent writing jobmedia second time */
       }
 
       strcpy(dev->VolCatInfo.VolCatStatus, "Full");
@@ -176,7 +177,8 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
            mjcr->StartBlock = (uint32_t)dev->file_addr;
            mjcr->StartFile  = (uint32_t)(dev->file_addr >> 32);
         }
-        mjcr->VolFirstFile = mjcr->JobFiles;
+        /* Set first FirstIndex for new Volume */
+        mjcr->VolFirstIndex = mjcr->JobFiles;
         mjcr->run_time += time(NULL) - wait_time; /* correct run time */
       }
       unblock_device(dev);
index 5c601d3f3c1d9d00246b965e4d7a9cd2428d291e..eb37ee80fb09f5162f754983c0109604099476f1 100644 (file)
@@ -131,7 +131,7 @@ mount_next_vol:
 
    dev->state &= ~(ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
 
-   jcr->VolFirstFile = jcr->JobFiles; /* first update of Vol FileIndex */
+   jcr->VolFirstIndex = jcr->JobFiles; /* first update of Vol FileIndex */
    for ( ;; ) {
       int vol_label_status;
       autochanger = autoload_device(jcr, dev, 1, NULL);
index 668ad0184e635dffedb60a23137f28af503658a9..bfead35ea6279b997908a352343faf48089d67d0 100644 (file)
@@ -92,6 +92,7 @@ int    bsr_dev(DEVICE *dev, int num);
 void    attach_jcr_to_device(DEVICE *dev, JCR *jcr);
 void    detach_jcr_from_device(DEVICE *dev, JCR *jcr);
 JCR    *next_attached_jcr(DEVICE *dev, JCR *jcr);
+int    dev_can_write(DEVICE *dev);
 
 
 /* Get info about device */