This patch will fix a subtle bug that was introduced in 1.36.2 which causes Bacula to be very slow restoring a few files. This is because it reads completely to the end of the Volume rather than stopping when all the files on the Volume are loaded. The introduction of the bug was caused by a patch that fixed Bacula truncating tapes after a restore. Apply the patch to 1.36.2 with the following: cd patch -p0 <1.36.2-restore-speed.patch make ... Note that all source files will be rebuilt during the make. Index: src/jcr.h =================================================================== RCS file: /cvsroot/bacula/bacula/src/jcr.h,v retrieving revision 1.76.4.1 diff -u -u -b -r1.76.4.1 jcr.h --- src/jcr.h 27 Feb 2005 21:53:28 -0000 1.76.4.1 +++ src/jcr.h 17 Mar 2005 14:14:18 -0000 @@ -243,6 +243,7 @@ /* Parmaters for Open Read Session */ BSR *bsr; /* Bootstrap record -- has everything */ + bool mount_next_volume; /* set to cause next volume mount */ uint32_t read_VolSessionId; uint32_t read_VolSessionTime; uint32_t read_StartFile; Index: src/stored/read_record.c =================================================================== RCS file: /cvsroot/bacula/bacula/src/stored/read_record.c,v retrieving revision 1.47.4.1 diff -u -u -b -r1.47.4.1 read_record.c --- src/stored/read_record.c 15 Feb 2005 11:51:04 -0000 1.47.4.1 +++ src/stored/read_record.c 17 Mar 2005 14:14:18 -0000 @@ -5,13 +5,16 @@ * archive. It uses a callback to pass you each record in turn, * as well as a callback for mounting the next tape. It takes * care of reading blocks, applying the bsr, ... + * Note, this routine is really the heart of the restore routines, + * and we are *really* bit pushing here so be careful about making + * any modifications. * * Kern E. Sibbald, August MMII * - * Version $Id: 1.36.2-restore-speed.patch 1961 2005-04-26 19:29:24Z kerns $ + * Version $Id: 1.36.2-restore-speed.patch 1961 2005-04-26 19:29:24Z kerns $ */ /* - Copyright (C) 2000-2004 Kern Sibbald and John Walker + Copyright (C) 2000-2005 Kern Sibbald This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -57,6 +60,7 @@ recs = New(dlist(rec, &rec->link)); position_to_first_file(jcr, dev); + jcr->mount_next_volume = false; for ( ; ok && !done; ) { if (job_canceled(jcr)) { @@ -66,12 +70,11 @@ if (!read_block_from_device(dcr, CHECK_BLOCK_NUMBERS)) { if (dev->at_eot()) { DEV_RECORD *trec = new_record(); - Jmsg(jcr, M_INFO, 0, "End of Volume at file %u on device %s, Volume \"%s\"\n", dev->file, dev_name(dev), dcr->VolumeName); if (!mount_cb(dcr)) { Jmsg(jcr, M_INFO, 0, "End of all volumes.\n"); - ok = false; + ok = false; /* Stop everything */ /* * Create EOT Label so that Media record may * be properly updated because this is the last @@ -81,8 +84,13 @@ trec->File = dev->file; ok = record_cb(dcr, trec); free_record(trec); + if (jcr->mount_next_volume) { + jcr->mount_next_volume = false; + dev->state &= ~ST_EOT; + } break; } + jcr->mount_next_volume = false; /* * We just have a new tape up, now read the label (first record) * and pass it off to the callback routine, then continue @@ -113,10 +121,10 @@ display_tape_error_status(jcr, dev); if (forge_on || jcr->ignore_label_errors) { fsr_dev(dev, 1); /* try skipping bad record */ - Dmsg0(000, "Did fsr\n"); + Pmsg0(000, "Did fsr\n"); continue; /* try to continue */ } - ok = false; + ok = false; /* stop everything */ break; } } @@ -259,7 +267,11 @@ Dmsg2(300, "Current postion (file:block) %d:%d\n", dev->file, dev->block_num); jcr->bsr->mount_next_volume = false; -// dev->state |= ST_EOT; + if (!dev->at_eot()) { + /* Set EOT flag to force mount of next Volume */ + jcr->mount_next_volume = true; + dev->state |= ST_EOT; + } rec->Block = 0; return 1; }