]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Generally clean up the manual tape loading code. The main
authorKern Sibbald <kern@sibbald.com>
Fri, 27 Jun 2008 21:03:55 +0000 (21:03 +0000)
committerKern Sibbald <kern@sibbald.com>
Fri, 27 Jun 2008 21:03:55 +0000 (21:03 +0000)
     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

15 files changed:
bacula/src/dird/autoprune.c
bacula/src/dird/next_vol.c
bacula/src/filed/job.c
bacula/src/lib/jcr.c
bacula/src/stored/acquire.c
bacula/src/stored/autochanger.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/label.c
bacula/src/stored/mount.c
bacula/src/stored/reserve.c
bacula/src/stored/vtape.c
bacula/src/stored/wait.c
bacula/src/version.h
bacula/technotes-2.5

index cc812c5cbba5e2d9f5dfd9737ff02f4ba212e934..63e8138a5ea3ea13c98a44f6c7aeabf0e1170bf6 100644 (file)
@@ -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 */
          }
          /*
index 8b54e67949ec35cc0128acc104d584c6f214290b..0f6a437e1e8a5a0b7773336f61ce2bb5e26b2fc5 100644 (file)
@@ -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;
 }
 
index 6c45c3bb9ad488f1881712b04c190f14b9526d65..3320956884b9d9ce22c3b8e66cb15224c0f5b691 100644 (file)
@@ -1203,7 +1203,7 @@ static int bootstrap_cmd(JCR *jcr)
    }
 
    while (dir->recv() >= 0) {
-       Dmsg1(200, "filed<dird: bootstrap file %s\n", dir->msg);
+       Dmsg1(200, "filed<dird: bootstrap: %s", dir->msg);
        fputs(dir->msg, bs);
    }
    fclose(bs);
index 0d31f7fa07602251f28cbe6bf0a09059b5bc6136..1e97a4e12cc0a26592c6d661732dbafcfc2c93ad 100644 (file)
@@ -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);
 }
 
index eaa09aceadff9ea8102b8d043888dccecee85f61..8c4ec90677313577677b2d56901d5d2732e6ef4c 100644 (file)
@@ -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());
index 9c0c6b8302dabea813fb34f115c0eb3d76a00562..db0f640ae25dcb93e612e02cecf2fcab3a16a8a2 100644 (file)
@@ -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();
index ebfefc00a981802978f2ec7752cc01d53fe1f136..0e72db6a84530de7182b80d605238ad46ff934b3 100644 (file)
@@ -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;
index 4abc2d7faf03d96cbaf484600c97e7105ecfd3ea..a0357649f1e7f3a4fd9e705e821ba533198cf397 100644 (file)
@@ -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 */
index d5c981bbd674d1a926c270003b36442284c87a9a..da90a41fb0f626e900ed8c820377319f102afb03 100644 (file)
@@ -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;
 
index 8ae5a0ee3b9a1cf571443ed048d3f37dc977ff47..b6f0f02e6f0fb51c52528fd15912cf60d113e49a 100644 (file)
@@ -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");
 }
 
index d161f0820f3047561ba116c0ae55821c1b5b5f68..197dbcf2543419e20c1c5b115b084189f4d2fcbc 100644 (file)
@@ -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 */
index 7af0b32bb6f7df63444843f4642b25da4b2b21a1..df044f8e46e3b20990de0f79477fc777980953d7 100644 (file)
@@ -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;
index 53fa5eba0f73a7658390238a7cbfca87fd7fa32d..b443fd335fd291ca171689cd46738b64174efa61 100644 (file)
@@ -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.
index 8cecadb8b892b262508b8b80534be16af49e8a50..5cc00cb8e5d7496f6ca70c68a0194986411d2c05 100644 (file)
@@ -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 */
index 6706193dda00561c9e5c2818ab56005162fe0c91..589c98c6c008b90dafc3fb002fe81faefe6179f2 100644 (file)
@@ -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.