]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Rework class structures for VOLRES, DCR, and DEVICE to make
authorKern Sibbald <kern@sibbald.com>
Sat, 12 Apr 2008 20:59:25 +0000 (20:59 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 12 Apr 2008 20:59:25 +0000 (20:59 +0000)
     the method names a bit more logical, and for more logically
     handling the responsibilities.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6802 91ce42f0-d328-0410-95d8-f526ca767f89

13 files changed:
bacula/src/stored/acquire.c
bacula/src/stored/append.c
bacula/src/stored/askdir.c
bacula/src/stored/autochanger.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/device.c
bacula/src/stored/label.c
bacula/src/stored/mount.c
bacula/src/stored/read_record.c
bacula/src/stored/reserve.c
bacula/src/stored/status.c
bacula/technotes-2.3

index 58ed74db62c0d7486f2ed562f21952065fc5b996..67080def3d4b02395c38883f2bd06a292124421a 100644 (file)
@@ -286,11 +286,7 @@ default_path:
 
 get_out:
    dev->dlock();
-   if (dcr && dcr->reserved_device) {
-      dev->reserved_device--;
-      Dmsg2(50, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
-      dcr->reserved_device = false;
-   }
+   dcr->clear_reserved();
    /* 
     * Normally we are blocked, but in at least one error case above 
     *   we are not blocked because we unsuccessfully tried changing
@@ -317,6 +313,7 @@ DCR *acquire_device_for_append(DCR *dcr)
 {
    DEVICE *dev = dcr->dev;
    JCR *jcr = dcr->jcr;
+   bool ok = false;
 
    init_device_wait_timers(dcr);
 
@@ -358,8 +355,8 @@ DCR *acquire_device_for_append(DCR *dcr)
             /* Reduce "noise" -- don't print if job canceled */
             Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
                dev->print_name());
-            Dmsg2(200, "jid=%u Could not ready device %s for append.\n", 
-               (uint32_t)jcr->JobId, dev->print_name());
+            Dmsg1(200, "Could not ready device %s for append.\n", 
+               dev->print_name());
          }
          goto get_out;
       }
@@ -372,29 +369,13 @@ DCR *acquire_device_for_append(DCR *dcr)
    }
    dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs on vol */
    dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
-   dev->dlock();
-   if (dcr->reserved_device) {
-      dev->reserved_device--;
-      Dmsg3(100, "jid=%u Dec reserve=%d dev=%s\n", (uint32_t)jcr->JobId,
-            dev->reserved_device, dev->print_name());
-      dcr->reserved_device = false;
-   }
-   dev->dunblock(DEV_LOCKED);
-   return dcr;
+   ok = true;
 
-/*
- * Error return
- */
 get_out:
    dev->dlock();
-   if (dcr->reserved_device) {
-      dev->reserved_device--;
-      Dmsg3(100, "jid=%u Dec reserve=%d dev=%s\n", (uint32_t)jcr->JobId, 
-            dev->reserved_device, dev->print_name());
-      dcr->reserved_device = false;
-   }
+   dcr->clear_reserved();
    dev->dunblock(DEV_LOCKED);
-   return NULL;
+   return ok ? dcr : NULL;
 }
 
 /*
@@ -447,11 +428,7 @@ bool release_device(DCR *dcr)
    Dmsg2(100, "release_device device %s is %s\n", dev->print_name(), dev->is_tape()?"tape":"disk");
 
    /* if device is reserved, job never started, so release the reserve here */
-   if (dcr->reserved_device) {
-      dev->reserved_device--;
-      Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
-      dcr->reserved_device = false;
-   }
+   dcr->clear_reserved();
 
    if (dev->can_read()) {
       dev->clear_read();              /* clear read bit */
@@ -664,7 +641,7 @@ void detach_dcr_from_dev(DCR *dcr)
    /* Detach this dcr only if attached */
    if (dcr->attached_to_dev && dev) {
       dev->dlock();
-      unreserve_device(dcr);
+      dcr->unreserve_device();
       dcr->dev->attached_dcrs->remove(dcr);  /* detach dcr from device */
       dcr->attached_to_dev = false;
 //    remove_dcr_from_dcrs(dcr);      /* remove dcr from jcr list */
index a6ff753814252371cc9644817e93161a409cb969..382dd2d556a8b0a1e46ca7ca33e11b9c501b330a 100644 (file)
@@ -70,7 +70,7 @@ bool do_append_data(JCR *jcr)
       return false;
    }                                              
 
-   Dmsg1(100, "Start append data. res=%d\n", dev->reserved_device);
+   Dmsg1(100, "Start append data. res=%d\n", dev->num_reserved());
 
    memset(&rec, 0, sizeof(rec));
 
index 8d993457e09215f295894dd4a16cf6a600b57aeb..dcaa00b8d8b1bc2325caf5eee2839ddce9fd4dd6 100644 (file)
@@ -242,7 +242,7 @@ bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
  * Returns: true  on success dcr->VolumeName is volume
  *                reserve_volume() called on Volume name
  *          false on failure dcr->VolumeName[0] == 0
- *                also sets dcr->volume_in_use if at least one 
+ *                also sets dcr->found_in_use if at least one 
  *                in use volume was found.
  *
  *          Volume information returned in dcr
@@ -255,7 +255,7 @@ bool dir_find_next_appendable_volume(DCR *dcr)
     bool rtn;
 
     Dmsg2(200, "dir_find_next_appendable_volume: reserved=%d Vol=%s\n", 
-       dcr->reserved_device, dcr->VolumeName);
+       dcr->is_reserved(), dcr->VolumeName);
 
     /*
      * Try the forty oldest or most available volumes.  Note,
@@ -264,7 +264,7 @@ bool dir_find_next_appendable_volume(DCR *dcr)
      */
     lock_volumes();
     P(vol_info_mutex);
-    dcr->volume_in_use = false;
+    dcr->clear_found_in_use();
     for (int vol_index=1;  vol_index < 40; vol_index++) {
        bash_spaces(dcr->media_type);
        bash_spaces(dcr->pool_name);
@@ -273,7 +273,7 @@ bool dir_find_next_appendable_volume(DCR *dcr)
        unbash_spaces(dcr->pool_name);
        Dmsg1(100, ">dird %s", dir->msg);
        if (do_get_volume_info(dcr)) {
-          if (!is_volume_in_use(dcr)) {
+          if (dcr->can_i_use_volume()) {
              Dmsg1(100, "Call reserve_volume. Vol=%s\n", dcr->VolumeName);
              if (reserve_volume(dcr, dcr->VolumeName) == 0) {
                 Dmsg2(100, "Could not reserve volume %s on %s\n", dcr->VolumeName,
@@ -286,7 +286,8 @@ bool dir_find_next_appendable_volume(DCR *dcr)
              goto get_out;
           } else {
              Dmsg1(100, "Volume %s is in use.\n", dcr->VolumeName);
-             dcr->volume_in_use = true;
+             /* If volume is not usable, it is in use by someone else */
+             dcr->set_found_in_use();
              continue;
           }
        }
index a6f37b671675216edf4b35bba60ea46c8f7cf9bf..9ed6c8f7680e858606eca64069034f32ba508ba9 100644 (file)
@@ -136,6 +136,7 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir)
       if (dir) {
          return 0;                    /* For user, bail out right now */
       }
+      /* ***FIXME*** this really should not be here */
       if (dir_find_next_appendable_volume(dcr)) {
          slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0;
       } else {
@@ -367,6 +368,7 @@ bool unload_autochanger(DCR *dcr, int loaded)
       } else {
          dev->Slot = 0;            /* nothing loaded */
       }
+      dev->clear_unload();
       free_volume(dev);            /* Free any volume associated with this drive */
       free_pool_memory(changer);
       unlock_changer(dcr);
@@ -421,7 +423,7 @@ static bool unload_other_drive(DCR *dcr, int slot)
            dcr->VolumeName, dev->print_name());
       Dmsg4(100, "Vol %s for dev=%s is busy dev=%s slot=%d\n",
            dcr->VolumeName, dcr->dev->print_name(), dev->print_name(), dev->Slot);
-      Dmsg2(100, "num_writ=%d reserv=%d\n", dev->num_writers, dev->reserved_device);
+      Dmsg2(100, "num_writ=%d reserv=%d\n", dev->num_writers, dev->num_reserved());
       return false;
    }
    return unload_dev(dcr, dev);
@@ -459,7 +461,7 @@ bool unload_dev(DCR *dcr, DEVICE *dev)
                 dcr->device->changer_command, "unload");
    dev->close();
    Dmsg2(200, "close dev=%s reserve=%d\n", dev->print_name(), 
-      dev->reserved_device);
+      dev->num_reserved());
    Dmsg1(100, "Run program=%s\n", changer_cmd);
    int stat = run_program_full_output(changer_cmd, timeout, results.addr());
    dcr->VolCatInfo.Slot = save_slot;
@@ -479,6 +481,7 @@ bool unload_dev(DCR *dcr, DEVICE *dev)
       Dmsg0(100, "Slot unloaded\n");
    }
    free_volume(dev);               /* Free any volume associated with this drive */
+   dev->clear_unload();
    unlock_changer(dcr);
    dev->dunlock();
    free_pool_memory(changer_cmd);
index 7c1410b41069f8d5ff7de01c03389ee82f64f3da..99eee1f09ca88efd2cc8f0dc5ad935154b6bcefe 100644 (file)
@@ -711,7 +711,7 @@ bool DEVICE::rewind(DCR *dcr)
    unsigned int i;
    bool first = true;
 
-   Dmsg3(400, "rewind res=%d fd=%d %s\n", reserved_device, m_fd, print_name());
+   Dmsg3(400, "rewind res=%d fd=%d %s\n", num_reserved(), m_fd, print_name());
    state &= ~(ST_EOT|ST_EOF|ST_WEOT);  /* remove EOF/EOT flags */
    block_num = file = 0;
    file_size = 0;
index edb13c7e39e06ba0d5e84728f389155119ded19b..a8f7bdf84e905128a64f75848a6b8e39d137b72b 100644 (file)
  *
  */
 
+/*
+ * Some details of how volume and device reservations work
+ *
+ * class VOLRES:
+ *   set_in_use()     volume being used on current drive
+ *   clear_in_use()   no longer being used.  Can be re-used or moved.
+ *   set_swapping()   set volume being moved to another drive
+ *   is_swapping()    volume is being moved to another drive
+ *   clear_swapping() volume normal
+ *
+ * class DEVICE:
+ *   set_load()       set to load volume
+ *   needs_load()     volume must be loaded (i.e. set_load done)
+ *   clear_load()     load done.
+ *   set_unload()     set to unload volume
+ *   needs_unload()    volume must be unloaded
+ *   clear_unload()   volume unloaded
+ *
+ *    reservations are temporary until the drive is acquired
+ *   inc_reserved()   increments num of reservations
+ *   dec_reserved()   decrements num of reservations
+ *   num_reserved()   number of reservations
+ *
+ * class DCR:
+ *   set_reserved()   sets local reserve flag and calls dev->inc_reserved()
+ *   clear_reserved() clears local reserve flag and calls dev->dec_reserved()
+ *   is_reserved()    returns local reserved flag
+ *   unreserve_device()  much more complete unreservation
+ *
+ */
+
 
 #ifndef __DEV_H
 #define __DEV_H 1
@@ -182,7 +213,11 @@ private:
    int m_blocked;                     /* set if we must wait (i.e. change tape) */
    int m_count;                       /* Mutex use count -- DEBUG only */
    pthread_t m_pid;                   /* Thread that locked -- DEBUG only */
+   bool m_unload;                     /* set when Volume must be unloaded */
+   bool m_load;                       /* set when Volume must be loaded */
+   int m_num_reserved;                /* counter of device reservations */
 public:
+   DEVICE * volatile swap_dev;        /* Swap vol from this device */
    dlist *attached_dcrs;              /* attached DCR list */
    pthread_mutex_t m_mutex;           /* access control */
    pthread_mutex_t spool_mutex;       /* mutex for updating spool_size */
@@ -192,7 +227,6 @@ public:
    int dev_prev_blocked;              /* previous blocked state */
    int num_waiting;                   /* number of threads waiting */
    int num_writers;                   /* number of writing threads */
-   int reserved_device;               /* number of device reservations */
    int capabilities;                  /* capabilities mask */
    int state;                         /* state mask */
    int dev_errno;                     /* Our own errno */
@@ -283,10 +317,11 @@ public:
    int is_labeled() const { return state & ST_LABEL; }
    int is_mounted() const { return state & ST_MOUNTED; }
    int is_unmountable() const { return (is_dvd() || (is_file() && is_removable())); }
+   int num_reserved() const { return m_num_reserved; };
    int is_part_spooled() const { return state & ST_PART_SPOOLED; }
    int have_media() const { return state & ST_MEDIA; }
    int is_short_block() const { return state & ST_SHORT; }
-   int is_busy() const { return (state & ST_READ) || num_writers || reserved_device; }
+   int is_busy() const { return (state & ST_READ) || num_writers || num_reserved(); }
    int at_eof() const { return state & ST_EOF; }
    int at_eot() const { return state & ST_EOT; }
    int at_weot() const { return state & ST_WEOT; }
@@ -308,6 +343,8 @@ public:
                     (m_blocked == BST_UNMOUNTED ||
                      m_blocked == BST_WAITING_FOR_SYSOP ||
                      m_blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP); };
+   bool must_unload() const { return m_unload; };
+   bool must_load() const { return m_load; };
    const char *strerror() const;
    const char *archive_name() const;
    const char *name() const;
@@ -327,8 +364,12 @@ public:
    void set_part_spooled(int val) { if (val) state |= ST_PART_SPOOLED; \
           else state &= ~ST_PART_SPOOLED;
    };
+   void set_unload() { m_unload = true; };
+   void set_load() { m_load = true; };
+   void inc_reserved() { m_num_reserved++; }
    void set_mounted(int val) { if (val) state |= ST_MOUNTED; \
           else state &= ~ST_MOUNTED; };
+   void dec_reserved() { m_num_reserved--; ASSERT(m_num_reserved>=0); };
    void clear_append() { state &= ~ST_APPEND; };
    void clear_read() { state &= ~ST_READ; };
    void clear_labeled() { state &= ~ST_LABEL; };
@@ -340,6 +381,8 @@ 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_load() { m_load = false; };
    char *bstrerror(void) { return errmsg; };
    char *print_errmsg() { return errmsg; };
 
@@ -421,12 +464,13 @@ inline const char *DEVICE::print_name() const { return prt_name; }
 class DCR {
 private:
    bool m_dev_locked;                 /* set if dev already locked */
+   bool m_reserved;                   /* set if reserved device */
+   bool m_found_in_use;               /* set if a volume found in use */
 
 public:
    dlink dev_link;                    /* link to attach to dev */
    JCR *jcr;                          /* pointer to JCR */
    DEVICE * volatile dev;             /* pointer to device */
-   DEVICE * volatile swap_dev;        /* Swap vol from this device */
    DEVRES *device;                    /* pointer to device resource */
    DEV_BLOCK *block;                  /* pointer to block */
    DEV_RECORD *rec;                   /* pointer to record */
@@ -439,13 +483,10 @@ public:
    bool NewVol;                       /* set if new Volume mounted */
    bool WroteVol;                     /* set if Volume written */
    bool NewFile;                      /* set when EOF written */
-   bool reserved_device;              /* set if reserve done */
    bool reserved_volume;              /* set if we reserved a volume */
    bool any_volume;                   /* Any OK for dir_find_next... */
    bool attached_to_dev;              /* set when attached to dev */
-   bool volume_in_use;                /* set in dir_find_next_appendable_volume() */
    bool keep_dcr;                     /* do not free dcr in release_dcr */
-   bool unload_device;                /* set if device must be unloaded */
    uint32_t VolFirstIndex;            /* First file index this Volume */
    uint32_t VolLastIndex;             /* Last file index this Volume */
    uint32_t FileIndex;                /* Current File Index */
@@ -466,11 +507,22 @@ public:
    VOLUME_CAT_INFO VolCatInfo;        /* Catalog info for desired volume */
 
    /* Methods */
+   bool found_in_use() const { return m_found_in_use; };
+   void set_found_in_use() { m_found_in_use = true; };
+   void clear_found_in_use() { m_found_in_use = false; };
+   bool is_reserved() const { return m_reserved; };
    bool is_dev_locked() { return m_dev_locked; }
    void dlock() { dev->dlock(); m_dev_locked = true; }
    void dunlock() { m_dev_locked = false; dev->dunlock(); }
    void dblock(int why) { dev->dblock(why); }
 
+
+   /* Methods in reserve.c */
+   void clear_reserved();
+   void set_reserved();
+   void unreserve_device();
+   bool can_i_use_volume();
+
    /* Methods in mount.c */
    bool mount_next_write_volume();
    bool mount_next_read_volume();
@@ -488,7 +540,7 @@ public:
  */
 class VOLRES { 
    bool m_swapping;                   /* set when swapping to another drive */
-   bool m_reserved;                   /* set when volume reserved */
+   bool m_in_use;                     /* set when volume reserved or in use */
 public:
    dlink link;
    char *vol_name;                    /* Volume name */
@@ -497,9 +549,9 @@ public:
    bool is_swapping() const { return m_swapping; };
    void set_swapping() { m_swapping = true; };
    void clear_swapping() { m_swapping = false; };
-   bool is_reserved() const { return m_reserved; };
-   void set_reserved() { m_reserved = true; };
-   void clear_reserved() { m_reserved = false; };
+   bool is_in_use() const { return m_in_use; };
+   void set_in_use() { m_in_use = true; };
+   void clear_in_use() { m_in_use = false; };
 };
 
 
index 0006cdf6d1fd9dd9960fb5909caf7e1707678b14..b3c4c91fc420502d3ebf2607a1bc372d33aafb22 100644 (file)
@@ -122,8 +122,7 @@ bool fixup_device_block_write_error(DCR *dcr)
         edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
         bstrftime(dt, sizeof(dt), time(NULL)));
 
-   /* Called with have_vol=false, release=true */
-   dcr->unload_device = true;
+   dev->set_unload();
    if (!dcr->mount_next_write_volume()) {
       free_block(label_blk);
       dcr->block = block;
index 9f47dbe88f886e1611363dd0f0e5afe57643e2ae..d1bcec110301287d4072e2e8537f1ddb349169b8 100644 (file)
@@ -77,7 +77,7 @@ int read_dev_volume_label(DCR *dcr)
    bool have_ansi_label = false;
 
    Dmsg4(100, "Enter read_volume_label res=%d device=%s vol=%s dev_Vol=%s\n",
-      dev->reserved_device, dev->print_name(), VolName, 
+      dev->num_reserved(), dev->print_name(), VolName, 
       dev->VolHdr.VolumeName[0]?dev->VolHdr.VolumeName:"*NULL*");
 
    if (!dev->is_open()) {
index 6055ddb2428abca83d44711962aca5dbd3338dbe..17a34d5d78c3ac40cef5984884409f2adcfc51a7 100644 (file)
@@ -72,7 +72,7 @@ bool DCR::mount_next_write_volume()
    int mode;
    DCR *dcr = this;
 
-   Dmsg2(150, "Enter mount_next_volume(release=%d) dev=%s\n", unload_device,
+   Dmsg2(150, "Enter mount_next_volume(release=%d) dev=%s\n", dev->must_unload(),
       dev->print_name());
 
    init_device_wait_timers(dcr);
@@ -100,27 +100,29 @@ mount_next_vol:
       goto bail_out;
    }
    recycle = false;
-   if (unload_device) {
+   if (dev->must_unload()) {
       Dmsg0(150, "mount_next_volume release=1\n");
       unload_autochanger(dcr, -1);
       release_volume();
-      unload_device = false;
+      dev->clear_unload();
       ask = true;                     /* ask operator to mount tape */
    }
-
    /*
     * See if we are asked to swap the Volume from another device
     *  if so, unload the other device here, and attach the
     *  volume to our drive.
     */
-   if (swap_dev) {
-      Dmsg1(150, "Swap vol=%d\n", swap_dev->vol->vol_name);
-      dev->vol = swap_dev->vol;      /* take its volume */
-      swap_dev->vol = NULL;
-      unload_dev(dcr, swap_dev);
-      swap_dev = NULL;
-      dev->vol->clear_swapping();
-      dev->VolHdr.VolumeName[0] = 0;  /* don't yet have right Volume */
+   if (dev->swap_dev) {
+      Dmsg1(100, "Swap unloading %s\n", dev->swap_dev->print_name());
+      if (dev->swap_dev->must_unload()) {
+         unload_dev(dcr, dev->swap_dev);
+      }
+      if (dev->vol) {
+         dev->vol->clear_swapping();
+         dev->vol->set_in_use();
+         dev->VolHdr.VolumeName[0] = 0;  /* don't yet have right Volume */
+      }
+      dev->swap_dev = NULL;
    }
    if (!is_suitable_volume_mounted()) {
       bool have_vol = false;
@@ -176,7 +178,7 @@ mount_next_vol:
     *   and read the label. If there is no tape in the drive,
     *   we will fail, recurse and ask the operator the next time.
     */
-   if (!unload_device && dev->is_tape() && dev->has_cap(CAP_AUTOMOUNT)) {
+   if (!dev->must_unload() && dev->is_tape() && dev->has_cap(CAP_AUTOMOUNT)) {
       Dmsg0(150, "(1)Ask=0\n");
       ask = false;                 /* don't ask SYSOP this time */
    }
@@ -186,7 +188,7 @@ mount_next_vol:
       ask = false;
    }
    Dmsg2(150, "Ask=%d autochanger=%d\n", ask, autochanger);
-   unload_device = true;     /* release next time if we "recurse" */
+   dev->must_unload();       /* release next time if we "recurse" */
 
    if (ask && !dir_ask_sysop_to_mount_volume(dcr, ST_APPEND)) {
       Dmsg0(150, "Error return ask_sysop ...\n");
@@ -470,7 +472,7 @@ bool DCR::is_suitable_volume_mounted()
 {
 
    /* Volume mounted? */
-   if (dev->VolHdr.VolumeName[0] == 0 || swap_dev || unload_device) {
+   if (dev->VolHdr.VolumeName[0] == 0 || dev->swap_dev || dev->must_unload()) {
       return false;                      /* no */
    }
    bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName));
index 4190d11848b4d62f94bcd618a8917e10e680e95a..8cd7b4f0b56e1789a0b92c64372dfeeb318eeb9a 100644 (file)
@@ -228,11 +228,13 @@ bool read_records(DCR *dcr,
              *  he wants to know if they matched the bsr, then he must
              *  check the match_stat in the record */
             ok = record_cb(dcr, rec);
+#ifdef xxx
             /*
              * If this is the end of the Session (EOS) for this record
              *  we can remove the record.  Note, there is a separate
              *  record to read each session. If a new session is seen
              *  a new record will be created at approx line 157 above.
+             * However, it seg faults in the for line at lineno 196.
              */
             if (rec->FileIndex == EOS_LABEL) {
                Dmsg2(dbglvl, "Remove EOS rec. SI=%d ST=%d\n", rec->VolSessionId,
@@ -240,6 +242,7 @@ bool read_records(DCR *dcr,
                recs->remove(rec);
                free_record(rec);
             }
+#endif
             continue;
          } /* end if label record */
 
index f2c81f4f31b8d679a35c16503d020e7a6633e938..5a3d2cf47a51eda8ab89c5bc559511ad34d63f9a 100644 (file)
@@ -53,7 +53,7 @@ static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
 static bool use_storage_cmd(JCR *jcr);
 static void queue_reserve_message(JCR *jcr);
 static void pop_reserve_messages(JCR *jcr);
-void switch_device(DCR *dcr, DEVICE *dev);
+//void switch_device(DCR *dcr, DEVICE *dev);
 
 /* Requests from the Director daemon */
 static char use_storage[]  = "use storage=%127s media_type=%127s "
@@ -178,11 +178,11 @@ static void debug_list_volumes(const char *imsg)
    lock_volumes();
    foreach_dlist(vol, vol_list) {
       if (vol->dev) {
-         Mmsg(msg, "List %s: %s reserved=%d on device %s\n", imsg, 
-              vol->vol_name, vol->is_reserved(), vol->dev->print_name());
+         Mmsg(msg, "List %s: %s in_use=%d on device %s\n", imsg, 
+              vol->vol_name, vol->is_in_use(), vol->dev->print_name());
       } else {
-         Mmsg(msg, "List %s: %s reserved=%d no dev\n", imsg, vol->vol_name, 
-              vol->is_reserved());
+         Mmsg(msg, "List %s: %s in_use=%d no dev\n", imsg, vol->vol_name, 
+              vol->is_in_use());
       }
       Dmsg1(dbglvl, "%s", msg.c_str());
    }
@@ -217,13 +217,13 @@ void list_volumes(void sendit(const char *msg, int len, void *sarg), void *arg)
       if (dev) {
          len = Mmsg(msg, "%s on device %s\n", vol->vol_name, dev->print_name());
          sendit(msg.c_str(), len, arg);
-         len = Mmsg(msg, "    Reader=%d writers=%d devres=%d volres=%d\n", 
-            dev->can_read()?1:0, dev->num_writers, dev->reserved_device, 
-            vol->is_reserved());
+         len = Mmsg(msg, "    Reader=%d writers=%d devres=%d volinuse=%d\n", 
+            dev->can_read()?1:0, dev->num_writers, dev->num_reserved(),   
+            vol->is_in_use());
          sendit(msg.c_str(), len, arg);
       } else {
-         len = Mmsg(msg, "%s no device. volres= %d\n", vol->vol_name, 
-            vol->is_reserved());
+         len = Mmsg(msg, "%s no device. volinuse= %d\n", vol->vol_name, 
+            vol->is_in_use());
          sendit(msg.c_str(), len, arg);
       }
    }
@@ -260,7 +260,6 @@ static void free_vol_item(VOLRES *vol)
    }
 }
 
-
 /*
  * Put a new Volume entry in the Volume list. This
  *  effectively reserves the volume so that it will
@@ -277,7 +276,7 @@ static void free_vol_item(VOLRES *vol)
  *
  *  1. The Volume list entry must be attached to the drive (rather than 
  *       attached to a job as it currently is. I.e. the drive that "owns" 
- *       the volume (reserved, in use, mounted)
+ *       the volume (in use, mounted)
  *       must point to the volume (still to be maintained in a list).
  *
  *  2. The Volume is entered in the list when a drive is reserved.  
@@ -337,8 +336,8 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName)
     */
    if (dev->vol) {
       vol = dev->vol;
-      Dmsg4(dbglvl, "Vol attached=%s, newvol=%s volres=%d on %s\n",
-         vol->vol_name, VolumeName, vol->is_reserved(), dev->print_name());
+      Dmsg4(dbglvl, "Vol attached=%s, newvol=%s volinuse=%d on %s\n",
+         vol->vol_name, VolumeName, vol->is_in_use(), dev->print_name());
       /*
        * Make sure we don't remove the current volume we are inserting
        *  because it was probably inserted by another job, or it
@@ -347,19 +346,19 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName)
       if (strcmp(vol->vol_name, VolumeName) == 0) {
          Dmsg2(dbglvl, "=== set reserved vol=%s dev=%s\n", VolumeName,
                vol->dev->print_name());
-         vol->set_reserved();           /* retake vol if released previously */
+         vol->set_in_use();             /* retake vol if released previously */
          dcr->reserved_volume = true;   /* reserved volume */
          goto get_out;                  /* Volume already on this device */
       } else {
          /* Don't release a volume if it was reserved by someone other than us */
-         if (vol->is_reserved() && !dcr->reserved_volume) { 
+         if (vol->is_in_use() && !dcr->reserved_volume) { 
             Dmsg1(dbglvl, "Cannot free vol=%s. It is reserved.\n", vol->vol_name);
             vol = NULL;                  /* vol in use */
             goto get_out;
          }
          Dmsg2(dbglvl, "reserve_vol free vol=%s at %p\n", vol->vol_name, vol->vol_name);
          free_volume(dev);
-         dcr->unload_device = true;     /* have to unload current volume */
+         dev->set_unload();             /* have to unload current volume */
          debug_list_volumes("reserve_vol free");
       }
    }
@@ -391,14 +390,21 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName)
       if (dev != vol->dev) {
          /* Caller wants to switch Volume to another device */
          if (!vol->dev->is_busy() && !vol->is_swapping()) {
+            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 */
             vol->set_swapping();
-            dcr->swap_dev = vol->dev;   /* remember to get this vol */
+            vol->dev->set_unload();
+            dev->swap_dev = vol->dev;    /* remember to get this vol */
+            vol->dev->vol = NULL;        /* take volume */
+            vol->dev = dev;
+            dev->vol = vol;
             Dmsg3(dbglvl, "==== Swap vol=%s from dev=%s to %s\n", 
                VolumeName, vol->dev->print_name(), dev->print_name());
          } else {
             Dmsg3(dbglvl, "==== Swap not possible Vol busy vol=%s from dev=%s to %s\n", 
                VolumeName, vol->dev->print_name(), dev->print_name());
-            vol = NULL;                 /* device busy */
+            vol = NULL;                  /* device busy */
             goto get_out;
          }
       } else {
@@ -410,9 +416,9 @@ VOLRES *reserve_volume(DCR *dcr, const char *VolumeName)
 
 get_out:
    if (vol) {
-      Dmsg2(dbglvl, "=== set reserved. vol=%s dev=%s\n", vol->vol_name,
+      Dmsg2(dbglvl, "=== set in_use. vol=%s dev=%s\n", vol->vol_name,
             vol->dev->print_name());
-      vol->set_reserved();
+      vol->set_in_use();
       dcr->reserved_volume = true;
    }
    debug_list_volumes("end new volume");
@@ -424,6 +430,7 @@ get_out:
  * Switch from current device to given device  
  *   (not yet used) 
  */
+#ifdef xxx
 void switch_device(DCR *dcr, DEVICE *dev)
 {
    DCR save_dcr;
@@ -443,11 +450,11 @@ void switch_device(DCR *dcr, DEVICE *dev)
    bstrncpy(dcr->pool_type, save_dcr.pool_type, sizeof(dcr->pool_type));
    bstrncpy(dcr->dev_name, dev->dev_name, sizeof(dcr->dev_name));
 
-   dev->reserved_device++;
-   dcr->reserved_device = true;
+// dcr->set_reserved();
 
    dev->dunlock();
 }
+#endif
 
 /*
  * Search for a Volume name in the Volume list.
@@ -455,43 +462,56 @@ void switch_device(DCR *dcr, DEVICE *dev)
  *  Returns: VOLRES entry on success
  *           NULL if the Volume is not in the list
  */
-VOLRES *find_volume(DCR *dcr)
+VOLRES *find_volume(const char *VolumeName) 
 {
    VOLRES vol, *fvol;
    /* Do not lock reservations here */
    lock_volumes();
-   vol.vol_name = bstrdup(dcr->VolumeName);
+   vol.vol_name = bstrdup(VolumeName);
    fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
    free(vol.vol_name);
-   Dmsg2(dbglvl, "find_vol=%s found=%d\n", dcr->VolumeName, fvol!=NULL);
+   Dmsg2(dbglvl, "find_vol=%s found=%d\n", VolumeName, fvol!=NULL);
    debug_list_volumes("find_volume");
    unlock_volumes();
    return fvol;
 }
 
+void DCR::set_reserved()
+{
+   m_reserved = true;
+   Dmsg2(dbglvl, "Inc reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name());
+   dev->inc_reserved();
+}
+
+void DCR::clear_reserved()
+{
+   if (m_reserved) {
+      m_reserved = false;
+      dev->dec_reserved();
+      Dmsg2(dbglvl, "Dec reserve=%d dev=%s\n", dev->num_reserved(), dev->print_name());
+   }
+}
+
 /* 
  * Remove any reservation from a drive and tell the system
  *  that the volume is unused at least by us.
  */
-void unreserve_device(DCR *dcr)
+void DCR::unreserve_device()
 {
-   DEVICE *dev = dcr->dev;
    lock_volumes();
-   if (dcr->reserved_device) {
-      dcr->reserved_device = false;
-      dcr->reserved_volume = false;
-      dev->reserved_device--;
-      Dmsg2(dbglvl, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
+   if (is_reserved()) {
+      clear_reserved();
+      reserved_volume = false;
       /* If we set read mode in reserving, remove it */
       if (dev->can_read()) {
          dev->clear_read();
       }
       if (dev->num_writers < 0) {
-         Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
+         Jmsg1(jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
          dev->num_writers = 0;
       }
-      if (dev->reserved_device == 0 && dev->num_writers == 0) {
-         volume_unused(dcr);
+      if (dev->num_reserved() == 0 && dev->num_writers == 0) {
+         volume_unused(this);
       }
    }
    unlock_volumes();
@@ -530,7 +550,7 @@ bool volume_unused(DCR *dcr)
    }
 #endif
 #ifdef xxx
-   if (dev->num_writers > 0 || dev->reserved_device > 0) {
+   if (dev->num_writers > 0 || dev->num_reserved() > 0) {
       ASSERT(0);
    }
 #endif
@@ -542,8 +562,8 @@ bool volume_unused(DCR *dcr)
     *  where the tapes are or last were.
     */
    Dmsg3(dbglvl, "=== mark not reserved vol=%s num_writers=%d dev_reserved=%d\n",
-      dev->vol->vol_name, dev->num_writers, dev->reserved_device);
-   dev->vol->clear_reserved();
+      dev->vol->vol_name, dev->num_writers, dev->num_reserved());
+   dev->vol->clear_in_use();
    Dmsg2(dbglvl, "=== set not reserved. Vol=%s dev=%s\n", dev->vol->vol_name,
          dev->print_name());
    if (dev->is_tape() || dev->is_autochanger()) {
@@ -611,34 +631,35 @@ void free_volume_list()
    unlock_volumes();
 }
 
-bool is_volume_in_use(DCR *dcr)
+bool DCR::can_i_use_volume()
 {
-   bool rtn = false;
+   bool rtn = true;
    VOLRES *vol;
 
    lock_volumes();
-   vol = find_volume(dcr);
+   vol = find_volume(VolumeName);
    if (!vol) {
-      Dmsg1(dbglvl, "Vol=%s not in use.\n", dcr->VolumeName);
+      Dmsg1(dbglvl, "Vol=%s not in use.\n", VolumeName);
       goto get_out;                   /* vol not in list */
    }
    ASSERT(vol->dev != NULL);
 
-   if (dcr->dev == vol->dev) {        /* same device OK */
-      Dmsg1(dbglvl, "Vol=%s on same dev.\n", dcr->VolumeName);
+   if (dev == vol->dev) {        /* same device OK */
+      Dmsg1(dbglvl, "Vol=%s on same dev.\n", VolumeName);
       goto get_out;
    } else {
-      Dmsg3(dbglvl, "Vol=%s on %s we have %s\n", dcr->VolumeName,
-            vol->dev->print_name(), dcr->dev->print_name());
+      Dmsg3(dbglvl, "Vol=%s on %s we have %s\n", VolumeName,
+            vol->dev->print_name(), dev->print_name());
    }
+   /* ***FIXME*** check this ... */
    if (!vol->dev->is_busy()) {
-      Dmsg2(dbglvl, "Vol=%s dev=%s not busy.\n", dcr->VolumeName, vol->dev->print_name());
+      Dmsg2(dbglvl, "Vol=%s dev=%s not busy.\n", VolumeName, vol->dev->print_name());
       goto get_out;
    } else {
-      Dmsg2(dbglvl, "Vol=%s dev=%s busy.\n", dcr->VolumeName, vol->dev->print_name());
+      Dmsg2(dbglvl, "Vol=%s dev=%s busy.\n", VolumeName, vol->dev->print_name());
    }
-   Dmsg2(dbglvl, "Vol=%s in use by %s.\n", dcr->VolumeName, vol->dev->print_name());
-   rtn = true;
+   Dmsg2(dbglvl, "Vol=%s in use by %s.\n", VolumeName, vol->dev->print_name());
+   rtn = false;
 
 get_out:
    unlock_volumes();
@@ -1090,10 +1111,10 @@ int search_res_for_device(RCTX &rctx)
             /* Debug code */
             if (rctx.store->append == SD_APPEND) {
                Dmsg2(dbglvl, "Device %s reserved=%d for append.\n", 
-                  rctx.device->hdr.name, rctx.jcr->dcr->dev->reserved_device);
+                  rctx.device->hdr.name, rctx.jcr->dcr->dev->num_reserved());
             } else {
                Dmsg2(dbglvl, "Device %s reserved=%d for read.\n", 
-                  rctx.device->hdr.name, rctx.jcr->read_dcr->dev->reserved_device);
+                  rctx.device->hdr.name, rctx.jcr->read_dcr->dev->num_reserved());
             }
             return stat;
          }
@@ -1113,10 +1134,10 @@ int search_res_for_device(RCTX &rctx)
             /* Debug code */
             if (rctx.store->append == SD_APPEND) {
                Dmsg2(dbglvl, "Device %s reserved=%d for append.\n", 
-                  rctx.device->hdr.name, rctx.jcr->dcr->dev->reserved_device);
+                  rctx.device->hdr.name, rctx.jcr->dcr->dev->num_reserved());
             } else {
                Dmsg2(dbglvl, "Device %s reserved=%d for read.\n", 
-                  rctx.device->hdr.name, rctx.jcr->read_dcr->dev->reserved_device);
+                  rctx.device->hdr.name, rctx.jcr->read_dcr->dev->num_reserved());
             }
             return stat;
          }
@@ -1184,7 +1205,7 @@ static int reserve_device(RCTX &rctx)
 
       rctx.jcr->dcr = dcr;
       Dmsg5(dbglvl, "Reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
-               dcr->dev->reserved_device,
+               dcr->dev->num_reserved(),
                dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
       Dmsg3(dbglvl, "Vol=%s num_writers=%d, have_vol=%d\n", 
          rctx.VolumeName, dcr->dev->num_writers, rctx.have_volume);
@@ -1214,10 +1235,10 @@ static int reserve_device(RCTX &rctx)
              *   non-used drive and our one and only volume is mounted
              *   elsewhere, so we bail out and retry using that drive.
              */
-            if (dcr->volume_in_use && !rctx.PreferMountedVols) {
+            if (dcr->found_in_use() && !rctx.PreferMountedVols) {
                rctx.PreferMountedVols = true;
                if (dcr->VolumeName[0]) {
-                  unreserve_device(dcr);
+                  dcr->unreserve_device();
                }
                goto bail_out;
             }
@@ -1234,7 +1255,7 @@ static int reserve_device(RCTX &rctx)
              */
             if (dcr->dev->num_writers != 0) {
                if (dcr->VolumeName[0]) {
-                  unreserve_device(dcr);
+                  dcr->unreserve_device();
                }
                goto bail_out;
             }
@@ -1245,7 +1266,7 @@ static int reserve_device(RCTX &rctx)
       if (ok) {
          rctx.jcr->read_dcr = dcr;
          Dmsg5(dbglvl, "Read reserved=%d dev_name=%s mediatype=%s pool=%s ok=%d\n",
-               dcr->dev->reserved_device,
+               dcr->dev->num_reserved(),
                dcr->dev_name, dcr->media_type, dcr->pool_name, ok);
       }
    }
@@ -1299,7 +1320,7 @@ static bool reserve_device_for_read(DCR *dcr)
    if (dev->is_busy()) {
       Dmsg4(dbglvl, "Device %s is busy ST_READ=%d num_writers=%d reserved=%d.\n", 
          dev->print_name(),
-         dev->state & ST_READ?1:0, dev->num_writers, dev->reserved_device);
+         dev->state & ST_READ?1:0, dev->num_writers, dev->num_reserved());
       Mmsg(jcr->errmsg, _("3602 JobId=%u device %s is busy (already reading/writing).\n"),
             jcr->JobId, dev->print_name());
       queue_reserve_message(jcr);
@@ -1309,9 +1330,7 @@ static bool reserve_device_for_read(DCR *dcr)
    dev->clear_append();
    dev->set_read();
    ok = true;
-   dev->reserved_device++;
-   Dmsg3(dbglvl, "Inc reserve=%d dev=%s %p\n", dev->reserved_device, dev->print_name(), dev);
-   dcr->reserved_device = true;
+   dcr->set_reserved();
 
 bail_out:
    dev->dunlock();
@@ -1370,10 +1389,7 @@ static bool reserve_device_for_append(DCR *dcr, RCTX &rctx)
       goto bail_out;
    }
 
-   dev->reserved_device++;
-   Dmsg3(dbglvl, "Inc reserve=%d dev=%s %p\n", dev->reserved_device, 
-      dev->print_name(), dev);
-   dcr->reserved_device = true;
+   dcr->set_reserved();
    ok = true;
 
 bail_out:
@@ -1397,7 +1413,7 @@ static int is_pool_ok(DCR *dcr)
       Mmsg(jcr->errmsg, _(
 "3608 JobId=%u wants Pool=\"%s\" but have Pool=\"%s\" nreserve=%d on drive %s.\n"), 
             (uint32_t)jcr->JobId, dcr->pool_name, dev->pool_name,
-            dev->reserved_device, dev->print_name());
+            dev->num_reserved(), dev->print_name());
       queue_reserve_message(jcr);
       Dmsg2(dbglvl, "failed: busy num_writers=0, reserved, pool=%s wanted=%s\n",
          dev->pool_name, dcr->pool_name);
@@ -1412,10 +1428,10 @@ static bool is_max_jobs_ok(DCR *dcr)
 
    Dmsg4(dbglvl, "MaxJobs=%d Jobs=%d reserves=%d Vol=%s\n",
          dcr->VolCatInfo.VolCatMaxJobs,
-         dcr->VolCatInfo.VolCatJobs, dev->reserved_device,
+         dcr->VolCatInfo.VolCatJobs, dev->num_reserved(),
          dcr->VolumeName);
    if (dcr->VolCatInfo.VolCatMaxJobs > 0 && dcr->VolCatInfo.VolCatMaxJobs <=
-        (dcr->VolCatInfo.VolCatJobs + dev->reserved_device)) {
+        (dcr->VolCatInfo.VolCatJobs + dev->num_reserved())) {
       /* Max Job Vols depassed or already reserved */
       Mmsg(jcr->errmsg, _("3610 JobId=%u Volume max jobs exceeded on drive %s.\n"), 
             (uint32_t)jcr->JobId, dev->print_name());
@@ -1461,13 +1477,13 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx)
       /* If he wants a free drive, but this one is busy, no go */
       if (!rctx.PreferMountedVols && dev->is_busy()) {
          /* Save least used drive */
-         if ((dev->num_writers + dev->reserved_device) < rctx.num_writers) {
-            rctx.num_writers = dev->num_writers + dev->reserved_device;
+         if ((dev->num_writers + dev->num_reserved()) < rctx.num_writers) {
+            rctx.num_writers = dev->num_writers + dev->num_reserved();
             rctx.low_use_drive = dev;
             Dmsg2(dbglvl, "set low use drive=%s num_writers=%d\n", 
                dev->print_name(), rctx.num_writers);
          } else {
-            Dmsg1(dbglvl, "not low use num_writers=%d\n", dev->num_writers+dev->reserved_device);
+            Dmsg1(dbglvl, "not low use num_writers=%d\n", dev->num_writers+dev->num_reserved());
          }
          Dmsg0(dbglvl, "failed: !prefMnt && busy.\n");
          Mmsg(jcr->errmsg, _("3605 JobId=%u wants free drive but device %s is busy.\n"), 
@@ -1508,7 +1524,7 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx)
                   dev->VolHdr.VolumeName, dev->vol?dev->vol->vol_name:"*none*", rctx.VolumeName);
             return 0;
          }
-         if (is_volume_in_use(dcr)) {
+         if (!dcr->can_i_use_volume()) {
             return 0;              /* fail if volume on another drive */
          }
       }
@@ -1529,7 +1545,7 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx)
     */
    if (dev->num_writers == 0) {
       /* Now check if there are any reservations on the drive */
-      if (dev->reserved_device) {           
+      if (dev->num_reserved()) {           
          return is_pool_ok(dcr);
       } else if (dev->can_append()) {
          if (is_pool_ok(dcr)) {
@@ -1537,6 +1553,7 @@ static int can_reserve_drive(DCR *dcr, RCTX &rctx)
          } else {
             /* Changing pool, unload old tape if any in drive */
             Dmsg0(dbglvl, "OK dev: num_writers=0, not reserved, pool change, unload changer\n");
+            /* ***FIXME*** use set_unload() */
             unload_autochanger(dcr, 0);
          }
       }
index deea17e9145bacf3f728131d84ccc01f38c44953..f91444e4e985d490312634acd3406862df35c0ea 100644 (file)
@@ -367,7 +367,8 @@ static void send_device_status(DEVICE *dev, STATUS_PKT *sp)
       dev->state & ST_MOUNTED ? "" : "!");
    sendit(msg, len, sp);
 
-   len = Mmsg(msg, _("num_writers=%d block=%d\n\n"), dev->num_writers, dev->blocked());
+   len = Mmsg(msg, _("num_writers=%d reserved=%d block=%d\n\n"), dev->num_writers, 
+              dev->num_reserved(), dev->blocked());
    sendit(msg, len, sp);
 
    len = Mmsg(msg, _("Device parameters:\n"));
index e19ebe7860c4ceaadcfbb0333305107329ba70b9..cfa908b0d6ec5fec1e87844718f0be9ed9371f4d 100644 (file)
@@ -24,6 +24,10 @@ Add long term statistics job table
 
 
 General:
+12Apr08
+kes  Rework class structures for VOLRES, DCR, and DEVICE to make
+     the method names a bit more logical, and for more logically
+     handling the responsibilities.
 11Apr08
 kes  Remove redundant code in terminating the scheduler that just
      causes a seg fault in many cases.