From: Kern Sibbald Date: Tue, 20 May 2003 19:26:29 +0000 (+0000) Subject: Fix double jobmedia bug, doc, add non-fatal error count X-Git-Tag: Release-1.31~133 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=1fd377cf78296a3d93ef1bb953f54a99707f655a;p=bacula%2Fbacula Fix double jobmedia bug, doc, add non-fatal error count git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@523 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/kernstodo b/bacula/kernstodo index dd5833720a..2aad564d6d 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -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. diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c index dd54012c30..04c1cc2292 100644 --- a/bacula/src/dird/backup.c +++ b/bacula/src/dird/backup.c @@ -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); diff --git a/bacula/src/dird/restore.c b/bacula/src/dird/restore.c index 0e7fb9d574..8602eb2fcb 100644 --- a/bacula/src/dird/restore.c +++ b/bacula/src/dird/restore.c @@ -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, "dirdmsg); 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); diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index 814b7e003b..a67bca6ef3 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -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); diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index 53f9686fad..1b6a28858b 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -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 */ diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c index 83283a52ce..e47b407b8c 100755 --- a/bacula/src/lib/message.c +++ b/bacula/src/lib/message.c @@ -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: diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index 8599e0b359..7e92fed826 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -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 */ diff --git a/bacula/src/stored/append.c b/bacula/src/stored/append.c index 27650e7915..73a8c1ef7e 100644 --- a/bacula/src/stored/append.c +++ b/bacula/src/stored/append.c @@ -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); diff --git a/bacula/src/stored/askdir.c b/bacula/src/stored/askdir.c index c73dc580c5..59286b8ad4 100644 --- a/bacula/src/stored/askdir.c +++ b/bacula/src/stored/askdir.c @@ -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); diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index e21533d2cb..7815c8ebfd 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -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; diff --git a/bacula/src/stored/bscan.c b/bacula/src/stored/bscan.c index b0a4493fd0..a606979e30 100644 --- a/bacula/src/stored/bscan.c +++ b/bacula/src/stored/bscan.c @@ -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; diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index e121d642f4..860bf2620a 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -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; diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index a6c3bee4fd..b0edad2711 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -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) { diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index 9c34ea667c..f1d066c3a7 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -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); diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 5c601d3f3c..eb37ee80fb 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -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); diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index 668ad0184e..bfead35ea6 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -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 */