From d730fada1dfbeae006fa4a4ae4a285462bb3e153 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Fri, 27 Jun 2008 21:03:55 +0000 Subject: [PATCH] kes Generally clean up the manual tape loading code. The main conceptial change is that when a volume is marked to be unloaded, its volume name is retained, and it is only marked as unloaded when either the autoloader says it is unloaded or another tape is read on that drive. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@7248 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/dird/autoprune.c | 2 +- bacula/src/dird/next_vol.c | 60 ++++++++++++++++---------------- bacula/src/filed/job.c | 2 +- bacula/src/lib/jcr.c | 2 +- bacula/src/stored/acquire.c | 23 +++++++------ bacula/src/stored/autochanger.c | 8 +++-- bacula/src/stored/dev.c | 25 ++++++++++---- bacula/src/stored/dev.h | 11 +++--- bacula/src/stored/label.c | 26 +++++++------- bacula/src/stored/mount.c | 44 +++++++++++++++--------- bacula/src/stored/reserve.c | 2 -- bacula/src/stored/vtape.c | 61 +++++++++++++++++---------------- bacula/src/stored/wait.c | 2 +- bacula/src/version.h | 4 +-- bacula/technotes-2.5 | 6 ++++ 15 files changed, 156 insertions(+), 122 deletions(-) diff --git a/bacula/src/dird/autoprune.c b/bacula/src/dird/autoprune.c index cc812c5cbb..63e8138a5e 100644 --- a/bacula/src/dird/autoprune.c +++ b/bacula/src/dird/autoprune.c @@ -182,7 +182,7 @@ bool prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr) */ if (ok && lmr.PoolId == mr->PoolId) { Dmsg2(050, "Vol=%s MediaId=%d purged.\n", lmr.VolumeName, (int)lmr.MediaId); - mr = &lmr; /* struct copy */ + memcpy(mr, &lmr, sizeof(lmr)); break; /* got a volume */ } /* diff --git a/bacula/src/dird/next_vol.c b/bacula/src/dird/next_vol.c index 8b54e67949..0f6a437e1e 100644 --- a/bacula/src/dird/next_vol.c +++ b/bacula/src/dird/next_vol.c @@ -57,7 +57,7 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, STORE *store = jcr->wstore; bstrncpy(mr->MediaType, store->media_type, sizeof(mr->MediaType)); - Dmsg3(050, "find_next_vol_for_append: JobId=%u PoolId=%d, MediaType=%s\n", + Dmsg3(100, "find_next_vol_for_append: JobId=%u PoolId=%d, MediaType=%s\n", (uint32_t)jcr->JobId, (int)mr->PoolId, mr->MediaType); /* * If we are using an Autochanger, restrict Volume @@ -82,7 +82,7 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, * 2. Try finding a recycled volume */ ok = find_recycled_volume(jcr, InChanger, mr); - Dmsg2(050, "find_recycled_volume ok=%d FW=%d\n", ok, mr->FirstWritten); + Dmsg2(150, "find_recycled_volume ok=%d FW=%d\n", ok, mr->FirstWritten); if (!ok) { /* * 3. Try recycling any purged volume @@ -94,30 +94,28 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, */ if (prune) { Dmsg0(150, "Call prune_volumes\n"); - ok = prune_volumes(jcr, InChanger, mr); + prune_volumes(jcr, InChanger, mr); } - if (!ok) { - ok = recycle_oldest_purged_volume(jcr, InChanger, mr); - if (!ok && create) { - Dmsg4(050, "after prune volumes_vol ok=%d index=%d InChanger=%d Vstat=%s\n", - ok, index, InChanger, mr->VolStatus); - /* - * 5. Try pulling a volume from the Scratch pool - */ - ok = get_scratch_volume(jcr, InChanger, mr); - Dmsg4(050, "after get scratch volume ok=%d index=%d InChanger=%d Vstat=%s\n", - ok, index, InChanger, mr->VolStatus); - } - /* - * If we are using an Autochanger and have not found - * a volume, retry looking for any volume. - */ - if (!ok && InChanger) { - InChanger = false; - continue; /* retry again accepting any volume */ - } - } - } + ok = recycle_oldest_purged_volume(jcr, InChanger, mr); + if (!ok && create) { + Dmsg4(050, "after prune volumes_vol ok=%d index=%d InChanger=%d Vstat=%s\n", + ok, index, InChanger, mr->VolStatus); + /* + * 5. Try pulling a volume from the Scratch pool + */ + ok = get_scratch_volume(jcr, InChanger, mr); + } + /* + * If we are using an Autochanger and have not found + * a volume, retry looking for any volume. + */ + if (InChanger) { + InChanger = false; + if (!ok) { + continue; /* retry again accepting any volume */ + } + } + } } @@ -132,14 +130,14 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, */ if (!ok && (jcr->pool->purge_oldest_volume || jcr->pool->recycle_oldest_volume)) { - Dmsg2(050, "No next volume found. PurgeOldest=%d\n RecyleOldest=%d", + Dmsg2(200, "No next volume found. PurgeOldest=%d\n RecyleOldest=%d", jcr->pool->purge_oldest_volume, jcr->pool->recycle_oldest_volume); /* Find oldest volume to recycle */ ok = db_find_next_volume(jcr, jcr->db, -1, InChanger, mr); - Dmsg1(050, "Find oldest=%d\n", ok); + Dmsg1(400, "Find oldest=%d\n", ok); if (ok && prune) { UAContext *ua; - Dmsg0(050, "Try purge.\n"); + Dmsg0(400, "Try purge.\n"); /* * 7. Try to purging oldest volume only if not UA calling us. */ @@ -157,12 +155,12 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, free_ua_context(ua); if (ok) { ok = recycle_volume(jcr, mr); - Dmsg1(050, "Recycle after purge oldest=%d\n", ok); + Dmsg1(400, "Recycle after purge oldest=%d\n", ok); } } } } - Dmsg2(050, "VolJobs=%d FirstWritten=%d\n", mr->VolJobs, mr->FirstWritten); + Dmsg2(100, "VolJobs=%d FirstWritten=%d\n", mr->VolJobs, mr->FirstWritten); if (ok) { /* If we can use the volume, check if it is expired */ if (has_volume_expired(jcr, mr)) { @@ -177,7 +175,7 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, break; } /* end for loop */ db_unlock(jcr->db); - Dmsg1(050, "return ok=%d find_next_vol\n", ok); + Dmsg1(150, "return ok=%d find_next_vol\n", ok); return ok; } diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index 6c45c3bb9a..3320956884 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -1203,7 +1203,7 @@ static int bootstrap_cmd(JCR *jcr) } while (dir->recv() >= 0) { - Dmsg1(200, "filedmsg); + Dmsg1(200, "filedmsg); fputs(dir->msg, bs); } fclose(bs); diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 0d31f7fa07..1e97a4e12c 100644 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -695,7 +695,7 @@ void set_jcr_job_status(JCR *jcr, int JobStatus) jcr->wait_time = time(NULL); } } - Dmsg3(100, "jid=%u leave set_jcr_job_status=%c set=%c\n", (uint32_t)jcr->JobId, + Dmsg3(200, "jid=%u leave set_jcr_job_status=%c set=%c\n", (uint32_t)jcr->JobId, jcr->JobStatus, JobStatus); } diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index eaa09acead..8c4ec90677 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -70,6 +70,7 @@ bool acquire_device_for_read(DCR *dcr) dev->num_writers, jcr->JobId); goto get_out; } + dev->clear_unload(); /* Find next Volume, if any */ vol = jcr->VolList; @@ -196,6 +197,8 @@ bool acquire_device_for_read(DCR *dcr) /* Volume info is always needed because of VolParts */ Dmsg1(150, "dir_get_volume_info vol=%s\n", dcr->VolumeName); if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) { + Dmsg2(150, "dir_get_vol_info failed for vol=%s: %s\n", + dcr->VolumeName, jcr->errmsg); Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg); } dev->set_load(); /* set to load volume */ @@ -236,7 +239,7 @@ bool acquire_device_for_read(DCR *dcr) switch (vol_label_status) { case VOL_OK: ok = true; - memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo)); + dev->VolCatInfo = dcr->VolCatInfo; /* structure assignment */ break; /* got it */ case VOL_IO_ERROR: /* @@ -249,20 +252,20 @@ bool acquire_device_for_read(DCR *dcr) } goto default_path; case VOL_NAME_ERROR: - if (tape_initially_mounted) { - tape_initially_mounted = false; - goto default_path; - } - /* If polling and got a previous bad name, ignore it */ - if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolumeName) == 0) { + if (dev->is_volume_to_unload()) { goto default_path; - } else { - bstrncpy(dev->BadVolName, dev->VolHdr.VolumeName, sizeof(dev->BadVolName)); } +// if (tape_initially_mounted) { + tape_initially_mounted = false; +// goto default_path; +// } + dev->set_unload(); /* force unload of unwanted tape */ if (!unload_autochanger(dcr, -1)) { /* at least free the device so we can re-open with correct volume */ dev->close(); } + dev->set_load(); + ASSERT(0); /* Fall through */ default: Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg); @@ -288,7 +291,6 @@ default_path: } /* Try closing and re-opening */ dev->close(); - dev->clear_unload(); if (dev->open(dcr, OPEN_READ_ONLY) >= 0) { continue; } @@ -308,6 +310,7 @@ default_path: } /* end switch */ break; } /* end for loop */ + if (!ok) { Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s for reading.\n"), dev->print_name()); diff --git a/bacula/src/stored/autochanger.c b/bacula/src/stored/autochanger.c index 9c0c6b8302..db0f640ae2 100644 --- a/bacula/src/stored/autochanger.c +++ b/bacula/src/stored/autochanger.c @@ -378,7 +378,9 @@ bool unload_autochanger(DCR *dcr, int loaded) free_volume(dev); /* Free any volume associated with this drive */ free_pool_memory(changer); } - dev->clear_unload(); + if (ok) { + dev->clear_unload(); + } return ok; } @@ -496,7 +498,9 @@ bool unload_dev(DCR *dcr, DEVICE *dev) Dmsg2(100, "Slot %d unloaded %s\n", dev->get_slot(), dev->print_name()); dev->set_slot(0); /* nothing loaded */ } - dev->clear_unload(); + if (ok) { + dev->clear_unload(); + } unlock_changer(dcr); dev->dunlock(); diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index ebfefc00a9..0e72db6a84 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -287,20 +287,20 @@ void DEVICE::init_backend() } else { d_open = ::open; d_close = ::close; - d_ioctl = win32_ioctl; /* dummy function */ - d_write = win32_write; /* win32 read/write are not POSIX */ + d_ioctl = win32_ioctl; /* dummy function */ + d_write = win32_write; /* win32 read/write are not POSIX */ d_read = win32_read; } #else /* POSIX / UNIX Interface */ - if (is_vtape()) { /* test backend */ - d_open = vtape_open; /* vtape isn't available for WIN32 or FreeBSD */ + if (is_vtape()) { /* test backend */ + d_open = vtape_open; /* vtape isn't available for WIN32 or FreeBSD */ d_write = vtape_write; d_close = vtape_close; d_ioctl = vtape_ioctl; d_read = vtape_read; - } else { /* tape and file are using normal io */ + } else { /* tape and file are using normal io */ d_open = ::open; d_write = ::write; d_close = ::close; @@ -1687,7 +1687,7 @@ bool DEVICE::weof(int num) { struct mtop mt_com; int stat; - Dmsg0(129, "weof_dev\n"); + Dmsg1(129, "=== weof_dev=%s\n", print_name()); if (!is_open()) { dev_errno = EBADF; @@ -1872,6 +1872,18 @@ void DEVICE::clrerror(int func) } +/* + * Set to unload the current volume in the drive + */ +void DEVICE::set_unload() +{ + if (!m_unload && VolHdr.VolumeName[0] != 0) { + m_unload = true; + memcpy(UnloadVolName, VolHdr.VolumeName, sizeof(UnloadVolName)); + } +} + + /* * Clear volume header */ @@ -2414,7 +2426,6 @@ void init_device_wait_timers(DCR *dcr) dev->rem_wait_sec = dev->wait_sec; dev->num_wait = 0; dev->poll = false; - dev->BadVolName[0] = 0; jcr->min_wait = 60 * 60; jcr->max_wait = 24 * 60 * 60; diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 4abc2d7faf..a0357649f1 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -281,9 +281,9 @@ public: char pool_name[MAX_NAME_LENGTH]; /* pool name */ char pool_type[MAX_NAME_LENGTH]; /* pool type */ - /* Device wait times ***FIXME*** look at durations */ - char BadVolName[MAX_NAME_LENGTH]; /* Last wrong Volume mounted */ + char UnloadVolName[MAX_NAME_LENGTH]; /* Last wrong Volume mounted */ bool poll; /* set to poll Volume */ + /* Device wait times ***FIXME*** look at durations */ int min_wait; int max_wait; int max_num_wait; @@ -367,7 +367,8 @@ public: void set_part_spooled(int val) { if (val) state |= ST_PART_SPOOLED; \ else state &= ~ST_PART_SPOOLED; }; - void set_unload() { m_unload = true; }; + bool is_volume_to_unload() const { \ + return m_unload && strcmp(VolHdr.VolumeName, UnloadVolName) == 0; }; void set_load() { m_load = true; }; void inc_reserved() { m_num_reserved++; } void set_mounted(int val) { if (val) state |= ST_MOUNTED; \ @@ -384,13 +385,13 @@ public: void clear_media() { state &= ~ST_MEDIA; }; void clear_short_block() { state &= ~ST_SHORT; }; void clear_freespace_ok() { state &= ~ST_FREESPACE_OK; }; - void clear_unload() { m_unload = false; }; + void clear_unload() { m_unload = false; UnloadVolName[0] = 0; }; void clear_load() { m_load = false; }; char *bstrerror(void) { return errmsg; }; char *print_errmsg() { return errmsg; }; int32_t get_slot() const { return m_slot; }; - + void set_unload(); /* in dev.c */ void clear_volhdr(); /* in dev.c */ void close(); /* in dev.c */ void close_part(DCR *dcr); /* in dev.c */ diff --git a/bacula/src/stored/label.c b/bacula/src/stored/label.c index d5c981bbd6..da90a41fb0 100644 --- a/bacula/src/stored/label.c +++ b/bacula/src/stored/label.c @@ -168,6 +168,10 @@ int read_dev_volume_label(DCR *dcr) } free_record(record); /* finished reading Volume record */ + if (!dev->is_volume_to_unload()) { + dev->clear_unload(); + } + if (!ok) { if (forge_on || jcr->ignore_label_errors) { dev->set_labeled(); /* set has Bacula label */ @@ -212,15 +216,6 @@ int read_dev_volume_label(DCR *dcr) } dev->set_labeled(); /* set has Bacula label */ - Dmsg1(100, "Call reserve_volume=%s\n", dev->VolHdr.VolumeName); - Dmsg2(100, "=== dcr->dev=%p dev=%p\n", dcr->dev, dev); - if (reserve_volume(dcr, dev->VolHdr.VolumeName) == NULL) { - Mmsg2(jcr->errmsg, _("Could not reserve volume %s on %s\n"), - dev->VolHdr.VolumeName, dev->print_name()); - stat = VOL_NAME_ERROR; - goto bail_out; - } - Dmsg2(100, "=== dcr->dev=%p dev=%p\n", dcr->dev, dev); /* Compare Volume Names */ Dmsg2(130, "Compare Vol names: VolName=%s hdr=%s\n", VolName?VolName:"*", dev->VolHdr.VolumeName); @@ -237,10 +232,9 @@ int read_dev_volume_label(DCR *dcr) } Dmsg0(150, "return VOL_NAME_ERROR\n"); stat = VOL_NAME_ERROR; - volume_unused(dcr); /* mark volume "released" */ goto bail_out; } - Dmsg1(130, "Copy vol_name=%s\n", dev->VolHdr.VolumeName); + if (debug_level >= 10) { dump_volume_label(dev); @@ -253,11 +247,19 @@ 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 (stat != VOL_OK) { - volume_unused(dcr); /* mark volume "released" */ goto bail_out; } } } + + Dmsg1(100, "Call reserve_volume=%s\n", dev->VolHdr.VolumeName); + if (reserve_volume(dcr, dev->VolHdr.VolumeName) == NULL) { + Mmsg2(jcr->errmsg, _("Could not reserve volume %s on %s\n"), + dev->VolHdr.VolumeName, dev->print_name()); + stat = VOL_NAME_ERROR; + goto bail_out; + } + empty_block(block); return VOL_OK; diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 8ae5a0ee3b..b6f0f02e6f 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -109,7 +109,7 @@ mount_next_vol: } do_swapping(true /*writing*/); - if (!find_a_volume()) { + if (retry < 2 && !find_a_volume()) { goto no_lock_bail_out; } @@ -146,15 +146,15 @@ mount_next_vol: * we will fail, recurse and ask the operator the next time. */ if (!dev->must_unload() && dev->is_tape() && dev->has_cap(CAP_AUTOMOUNT)) { - Dmsg0(150, "(1)Ask=0\n"); + Dmsg0(250, "(1)Ask=0\n"); ask = false; /* don't ask SYSOP this time */ } /* Don't ask if not removable */ if (!dev->is_removable()) { - Dmsg0(150, "(2)Ask=0\n"); + Dmsg0(250, "(2)Ask=0\n"); ask = false; } - Dmsg2(150, "Ask=%d autochanger=%d\n", ask, autochanger); + Dmsg2(250, "Ask=%d autochanger=%d\n", ask, autochanger); if (ask) { unlock_volumes(); @@ -294,6 +294,11 @@ no_lock_bail_out: return false; } +/* + * This routine is meant to be called once the first pass + * to ensure that we have a candidate volume to mount. + * Otherwise, we ask the sysop to created one. + */ bool DCR::find_a_volume() { DCR *dcr = this; @@ -361,6 +366,12 @@ int DCR::check_volume_label(bool &ask, bool &autochanger) VOLUME_CAT_INFO dcrVolCatInfo, devVolCatInfo; char saveVolumeName[MAX_NAME_LENGTH]; + Dmsg1(150, "Vol NAME Error Name=%s\n", VolumeName); + if (dev->is_volume_to_unload()) { + ask = true; + goto check_next_volume; + } + /* If not removable, Volume is broken */ if (!dev->is_removable()) { Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"), @@ -369,13 +380,6 @@ int DCR::check_volume_label(bool &ask, bool &autochanger) goto check_next_volume; } - Dmsg1(150, "Vol NAME Error Name=%s\n", VolumeName); - /* If polling and got a previous bad name, ignore it */ - if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolumeName) == 0) { - ask = true; - Dmsg1(200, "Vol Name error supress due to poll. Name=%s\n", VolumeName); - goto check_next_volume; - } /* * OK, we got a different volume mounted. First save the * requested Volume info (dcr) structure, then query if @@ -402,7 +406,7 @@ int DCR::check_volume_label(bool &ask, bool &autochanger) mark_volume_not_inchanger(); } dev->VolCatInfo = devVolCatInfo; /* structure assignment */ - bstrncpy(dev->BadVolName, dev->VolHdr.VolumeName, sizeof(dev->BadVolName)); + dev->set_unload(); /* unload this volume */ Jmsg(jcr, M_WARNING, 0, _("Director wanted Volume \"%s\".\n" " Current Volume \"%s\" not acceptable because:\n" " %s"), @@ -420,6 +424,13 @@ int DCR::check_volume_label(bool &ask, bool &autochanger) */ Dmsg1(150, "Got new Volume name=%s\n", VolumeName); dev->VolCatInfo = VolCatInfo; /* structure assignment */ + Dmsg1(100, "Call reserve_volume=%s\n", dev->VolHdr.VolumeName); + if (reserve_volume(this, dev->VolHdr.VolumeName) == NULL) { + Jmsg2(jcr, M_WARNING, 0, _("Could not reserve volume %s on %s\n"), + dev->VolHdr.VolumeName, dev->print_name()); + ask = true; + goto check_next_volume; + } break; /* got a Volume */ /* * At this point, we assume we have a blank tape mounted. @@ -487,9 +498,8 @@ bool DCR::is_suitable_volume_mounted() void DCR::do_swapping(bool is_writing) { if (dev->must_unload()) { - Dmsg1(100, "swapping: unloading %s\n", dev->print_name()); + Dmsg1(100, "must_unload release %s\n", dev->print_name()); release_volume(); - dev->clear_unload(); } /* * See if we are asked to swap the Volume from another device @@ -513,7 +523,7 @@ void DCR::do_swapping(bool is_writing) dev->swap_dev = NULL; } if (dev->must_load()) { - Dmsg1(100, "swapping: must load %s\n", dev->print_name()); + Dmsg1(100, "Must load %s\n", dev->print_name()); if (autoload_device(this, is_writing, NULL) > 0) { dev->clear_load(); } @@ -712,8 +722,8 @@ void DCR::release_volume() if (dev->is_open()) { dev->offline_or_rewind(); } - Dmsg0(50, "set_unload\n"); - dev->set_unload(); +// Dmsg0(50, "set_unload\n"); +// dev->set_unload(); Dmsg0(190, "release_volume\n"); } diff --git a/bacula/src/stored/reserve.c b/bacula/src/stored/reserve.c index d161f0820f..197dbcf254 100644 --- a/bacula/src/stored/reserve.c +++ b/bacula/src/stored/reserve.c @@ -347,7 +347,6 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName) } Dmsg2(dbglvl, "reserve_vol free vol=%s at %p\n", vol->vol_name, vol->vol_name); free_volume(dev); -// volume_unused(dcr); Dmsg0(50, "set_unload\n"); dev->set_unload(); /* have to unload current volume */ debug_list_volumes("reserve_vol free"); @@ -389,7 +388,6 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName) Dmsg3(dbglvl, "==== Swap vol=%s from dev=%s to %s\n", VolumeName, vol->dev->print_name(), dev->print_name()); free_volume(dev); /* free any volume attached to our drive */ -// volume_unused(dcr); Dmsg0(50, "set_unload\n"); dev->set_unload(); /* Unload any volume that is on our drive */ dcr->dev = vol->dev; /* temp point to other dev */ diff --git a/bacula/src/stored/vtape.c b/bacula/src/stored/vtape.c index 7af0b32bb6..df044f8e46 100644 --- a/bacula/src/stored/vtape.c +++ b/bacula/src/stored/vtape.c @@ -195,13 +195,13 @@ int vtape::tape_op(struct mtop *mt_com) case MTFSF: /* Forward space over mt_count filemarks. */ do { - result = fsf(); + result = fsf(); } while (--count > 0 && result == 0); break; case MTBSF: /* Backward space over mt_count filemarks. */ do { - result = bsf(); + result = bsf(); } while (--count > 0 && result == 0); break; @@ -228,7 +228,7 @@ int vtape::tape_op(struct mtop *mt_com) case MTWEOF: /* Write mt_count filemarks. */ do { - result = weof(); + result = weof(); } while (result == 0 && --count > 0); break; @@ -263,19 +263,19 @@ int vtape::tape_op(struct mtop *mt_com) case MTEOM:/* Go to the end of the recorded media (for appending files). */ while (next_FM) { - lseek(fd, next_FM, SEEK_SET); - if (read_fm(VT_READ_EOF)) { - current_file++; - } + lseek(fd, next_FM, SEEK_SET); + if (read_fm(VT_READ_EOF)) { + current_file++; + } } off_t l; while (::read(fd, &l, sizeof(l)) > 0) { - if (l) { - lseek(fd, l, SEEK_CUR); - } else { - ASSERT(0); - } - Dmsg0(dbglevel, "skip 1 block\n"); + if (l) { + lseek(fd, l, SEEK_CUR); + } else { + ASSERT(0); + } + Dmsg0(dbglevel, "skip 1 block\n"); } current_block = -1; atEOF = false; @@ -460,7 +460,7 @@ ssize_t vtape::write(const void *buffer, size_t count) ssize_t nb; Dmsg3(dbglevel*2, "write len=%i %i:%i\n", - count, current_file,current_block); + count, current_file,current_block); if (atEOT) { Dmsg0(dbglevel, "write nothing, EOT !\n"); @@ -576,20 +576,20 @@ int vtape::fsf() atBOT = false; Dmsg2(dbglevel+1, "fsf %i <= %i\n", current_file, last_file); - if (next_FM > cur_FM) { /* not the last file */ + if (next_FM > cur_FM) { /* not the last file */ lseek(fd, next_FM, SEEK_SET); read_fm(VT_READ_EOF); current_file++; atEOF = true; ret = 0; - } else if (atEOF) { /* last file mark */ + } else if (atEOF) { /* last file mark */ current_block=-1; errno = EIO; atEOF = false; atEOD = true; - } else { /* last file, but no at the end */ + } else { /* last file, but no at the end */ fsr(100000); Dmsg0(dbglevel, "Try to FSF after EOT\n"); @@ -615,8 +615,8 @@ bool vtape::read_fm(VT_READ_FM_MODE read_all) if (read_all == VT_READ_EOF) { ::read(fd, &c, sizeof(c)); if (c != 0) { - lseek(fd, cur_FM, SEEK_SET); - return false; + lseek(fd, cur_FM, SEEK_SET); + return false; } } @@ -628,7 +628,7 @@ bool vtape::read_fm(VT_READ_FM_MODE read_all) current_block=0; Dmsg3(dbglevel, "Read FM cur=%lli last=%lli next=%lli\n", - cur_FM, last_FM, next_FM); + cur_FM, last_FM, next_FM); return (ret == sizeof(next_FM)); } @@ -646,7 +646,7 @@ int vtape::fsr(int count) off_t where=0; uint32_t s; Dmsg4(dbglevel, "fsr %i:%i EOF=%i c=%i\n", - current_file,current_block,atEOF,count); + current_file,current_block,atEOF,count); check_eof(); @@ -674,10 +674,10 @@ int vtape::fsr(int count) current_file, current_block, nb,s); errno = EIO; ret = -1; - if (next_FM) { + if (next_FM) { current_file++; - read_fm(VT_SKIP_EOF); - } + read_fm(VT_SKIP_EOF); + } atEOF = true; /* stop the loop */ } } @@ -726,7 +726,7 @@ int vtape::bsr(int count) lseek(fd, cur_FM, SEEK_SET); atEOF = false; if (current_file > 0) { - current_file--; + current_file--; } current_block=-1; errno = EIO; @@ -736,7 +736,7 @@ int vtape::bsr(int count) /* * First, go to cur/last_FM and read all blocks to find the good one */ - if (cur_FM == orig) { /* already just before EOF */ + if (cur_FM == orig) { /* already just before EOF */ lseek(fd, last_FM, SEEK_SET); } else { @@ -747,7 +747,7 @@ int vtape::bsr(int count) do { if (!atEOF) { - last2 = last; /* keep track of the 2 last blocs position */ + last2 = last; /* keep track of the 2 last blocs position */ last = lseek(fd, 0, SEEK_CUR); last_f = current_file; last_b = current_block; @@ -891,7 +891,7 @@ ssize_t vtape::read(void *buffer, size_t count) /* reading size of data */ nb = ::read(fd, &s, sizeof(uint32_t)); if (nb <= 0) { - atEOF = true; /* TODO: check this */ + atEOF = true; /* TODO: check this */ return 0; } @@ -905,7 +905,7 @@ ssize_t vtape::read(void *buffer, size_t count) if (!s) { /* EOF */ atEOF = true; if (read_fm(VT_SKIP_EOF)) { - current_file++; + current_file++; } return 0; @@ -919,7 +919,7 @@ ssize_t vtape::read(void *buffer, size_t count) current_block = -1; Dmsg0(dbglevel, "EOT during reading\n"); return -1; - } /* read ok */ + } /* read ok */ if (current_block >= 0) { current_block++; @@ -936,6 +936,7 @@ int vtape::open(const char *pathname, int uflags) struct stat statp; if (stat(pathname, &statp) != 0) { + fd = -1; Dmsg1(dbglevel, "Can't stat on %s\n", pathname); if (uflags & O_NONBLOCK) { online = false; diff --git a/bacula/src/stored/wait.c b/bacula/src/stored/wait.c index 53fa5eba0f..b443fd335f 100644 --- a/bacula/src/stored/wait.c +++ b/bacula/src/stored/wait.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2007 Free Software Foundation Europe e.V. + Copyright (C) 2000-2008 Free Software Foundation Europe e.V. The main author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. diff --git a/bacula/src/version.h b/bacula/src/version.h index 8cecadb8b8..5cc00cb8e5 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -4,8 +4,8 @@ #undef VERSION #define VERSION "2.5.1" -#define BDATE "22 June 2008" -#define LSMDATE "22Jun08" +#define BDATE "27 June 2008" +#define LSMDATE "27Jun08" #define PROG_COPYRIGHT "Copyright (C) %d-2008 Free Software Foundation Europe e.V.\n" #define BYEAR "2008" /* year for copyright messages in progs */ diff --git a/bacula/technotes-2.5 b/bacula/technotes-2.5 index 6706193dda..589c98c6c0 100644 --- a/bacula/technotes-2.5 +++ b/bacula/technotes-2.5 @@ -30,6 +30,12 @@ vtape driver General: +27Jun08 +kes Generally clean up the manual tape loading code. The main + conceptial change is that when a volume is marked to be unloaded, + its volume name is retained, and it is only marked as unloaded + when either the autoloader says it is unloaded or another tape + is read on that drive. 25Jun08 kes Add debug code and refactor subroutine in stored/mount.c kes Fix format problem in bscan output reported in bug #1105. -- 2.39.5