For 1.28 release:
-- Make BSR accept count (total files to be restored).
-- Make BSR return next_block when it knows record is not
- in block, done when count is reached, and possibly other
- optimizations. I.e. add a state word.
-- Continue improving the restore process (handling
- of tapes, efficiency improvements e.g. use FSF to
- position the tape, ...)
-- Add code to fast seek to proper place on tape/file
- when doing Restore. If it doesn't work, try linear
- search as before.
+- Add code to put VolFile in bsr for restore command.
- Add code to reject whole blocks if not wanted on restore.
+- Add watchdog timeout for child processes start_child_timer()
+ end_child_timer();
- Figure out how to allow multiple simultaneous file Volumes on
a single device.
- Start working on Base jobs.
- Implement FileOptions (see end of this document)
-- Replace popen() and pclose() -- fail safe and timeout, no SIG dep.
- Ensure that restore of differential jobs works (check SQL).
- Make sure the MaxVolFiles is fully implemented in SD
- Flush all the daemon messages at the end of every job.
- Need return status on read_cb() from read_records(). Need multiple
records -- one per Job, maybe a JCR or some other structure with
a block and a record.
-- Think about how to make Bacula work better with File archives.
- Work more on how to to a Bacula restore beginning with
just a Bacula tape and a boot floppy (bare metal recovery).
- Handle ctl-c in Console
- Implement LabelTemplate (at least first cut).
- Implement script driven addition of File daemon to config files.
+- Think about how to make Bacula work better with File archives.
- see setgroup and user for Bacula p4-5 of stunnel.c
- Implement new serialize subroutines
- Make Job err if WriteBootstrap fails.
- Test that mod of restore options works.
- Test that week position schedule code works.
+- Make BSR accept count (total files to be restored).
+- Add code to fast seek to proper place on tape/file when doing Restore.
+- Replace popen() and pclose() -- fail safe and timeout, no SIG dep.
+
{
int stat = 0;
int tape_previously_mounted;
+ VOL_LIST *vol;
lock_device(dev);
block_device(dev, BST_DOING_ACQUIRE);
goto get_out;
}
+ /* Find next Volume, if any */
+ vol = jcr->VolList;
+ jcr->CurVolume++;
+ for (int i=1; i<jcr->CurVolume; i++) {
+ vol = vol->next;
+ }
+ pm_strcpy(&jcr->VolumeName, vol->VolumeName);
+
for (;;) {
if (job_cancelled(jcr)) {
Mmsg0(&dev->errmsg, _("Job cancelled.\n"));
}
Dmsg1(129, "open_dev %s OK\n", dev_name(dev));
}
- /* ***FIXME*** this is probably not necessary */
dev->state &= ~ST_LABEL; /* force reread of label */
Dmsg0(200, "calling read-vol-label\n");
switch (read_dev_volume_label(jcr, dev, block)) {
dev->state |= ST_READ;
attach_jcr_to_device(dev, jcr); /* attach jcr to device */
stat = 1; /* good return */
+ if ((dev->state & ST_TAPE) && vol->start_file > 0) {
+ Dmsg1(100, "====== Got start_file = %d\n", vol->start_file);
+ fsf_dev(dev, vol->start_file);
+ }
get_out:
P(dev->mutex);
end_of_tape = 0;
get_cmd("Mount first of two tapes. Press enter when ready: ");
+ free_vol_list(jcr);
pm_strcpy(&jcr->VolumeName, "TestVolume1");
+ jcr->bsr = NULL;
+ create_vol_list(jcr);
close_dev(dev);
dev->state &= ~ST_READ;
if (!acquire_device_for_read(jcr, dev, block)) {
end_of_tape = 1;
return 0;
}
+
+ free_vol_list(jcr);
pm_strcpy(&jcr->VolumeName, "TestVolume2");
+ jcr->bsr = NULL;
+ create_vol_list(jcr);
close_dev(dev);
dev->state &= ~ST_READ;
if (!acquire_device_for_read(jcr, dev, block)) {
create_vol_list(jcr);
- Dmsg1(100, "Volume=%s\n", jcr->VolumeName);
if (read_access) {
if (!acquire_device_for_read(jcr, dev, block)) {
Emsg0(M_ERROR, 0, dev->errmsg);
* End Of Tape -- mount next Volume (if another specified)
*/
if (jcr->NumVolumes > 1 && jcr->CurVolume < jcr->NumVolumes) {
- VOL_LIST *vol = jcr->VolList;
- /* Find next Volume */
- jcr->CurVolume++;
- for (int i=1; i<jcr->CurVolume; i++) {
- vol = vol->next;
- }
- pm_strcpy(&jcr->VolumeName, vol->VolumeName);
- Dmsg1(400, "There is another volume %s.\n", jcr->VolumeName);
-
close_dev(dev);
dev->state &= ~ST_READ;
if (!acquire_device_for_read(jcr, dev, block)) {
jcr->VolList = NULL;
}
+/*
+ * Create a list of Volumes (and Slots and Start positions) to be
+ * used in the current restore job.
+ */
void create_vol_list(JCR *jcr)
{
char *p, *n;
* Build a list of volumes to be processed
*/
jcr->NumVolumes = 0;
- jcr->CurVolume = 1;
+ jcr->CurVolume = 0;
if (jcr->bsr) {
BSR *bsr = jcr->bsr;
if (!bsr->volume || !bsr->volume->VolumeName) {
return;
}
- strcpy(jcr->VolumeName, bsr->volume->VolumeName); /* setup first volume */
for ( ; bsr; bsr=bsr->next) {
BSR_VOLUME *bsrvol;
BSR_VOLFILE *volfile;
- uint32_t sfile = 0;
+ uint32_t sfile = UINT32_MAX;
/* Find minimum start file so that we can forward space to it */
for (volfile = bsr->volfile; volfile; volfile=volfile->next) {