]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Fix #7629 About not using other available storages
authorMichal Rakowski <michal.rakowski@baculasystems.com>
Wed, 26 May 2021 04:45:29 +0000 (06:45 +0200)
committerEric Bollengier <eric@baculasystems.com>
Thu, 24 Mar 2022 08:03:02 +0000 (09:03 +0100)
We need to release not used Storages after staring job against one of the Storages in the list.

bacula/src/dird/backup.c
bacula/src/dird/jobq.c
bacula/src/dird/store_mngr.c
bacula/src/dird/store_mngr.h

index 15fc77c3c5d47c139d29ae3e3099b227af731c58..14f68c566ac78bfb546611bfd351314a054b1c0b 100644 (file)
@@ -603,6 +603,9 @@ bool do_backup(JCR *jcr)
       }
 
       if(sd_job_started) {
+         /* We can decrement not-used SDs since job was started against first available storage from the list */
+         jcr->store_mngr->dec_unused_wstores();
+
          /* Now break from the outer loop as well */
          break;
       }
index 0623c76fe9a03ffa8544ccc829f17ba30bba304e..91a20dfc01cee5e1d105fc9462929d44d35e5bc9 100644 (file)
@@ -805,6 +805,9 @@ static bool acquire_resources(JCR *jcr)
       }
    }
 
+   /* Temporarily increase job counter for all storages in the list.
+    * When the job is actually started, all of the storages which are not being used should be released
+    * to not block any subsequent jobs (@see StorageManager's 'release_unused_wstores()' method) */
    if (!jcr->store_mngr->inc_write_stores(jcr)) {
       if (jcr->store_mngr->get_rstore()) {
          jcr->store_mngr->dec_read_stores();
index c3e54bef480811fd49469fb339ae5e5741babe93..865491203014965c75347173b386099774ad9a54 100644 (file)
@@ -151,7 +151,7 @@ bool storage::inc_rstores(JCR *jcr) {
    {
       numread = store->incNumConcurrentReadJobs(1);
       num = store->incNumConcurrentJobs(1);
-      Dmsg1(dbglvl, "Inc rncj=%d\n", num);
+      Dmsg2(dbglvl, "Store: %s Inc rncj=%d\n", store->name(), num);
       return true;
    }
 
@@ -187,7 +187,7 @@ bool storage::inc_wstores(JCR *jcr) {
       int num = store->getNumConcurrentJobs();
       if (num < store->MaxConcurrentJobs) {
          num = store->incNumConcurrentJobs(1);
-         Dmsg1(dbglvl, "Inc wncj=%d\n", num);
+         Dmsg2(dbglvl, "Store: %s Inc wncj=%d\n", store->name(), num);
          list->append(store);
       }
    }
@@ -226,10 +226,18 @@ void storage::dec_stores() {
       return;
    }
 
-   STORE *store;
-   foreach_alist(store, list) {
-      int num = store->incNumConcurrentJobs(-1);
-      Dmsg1(dbglvl, "Dec wncj=%d\n", num);
+   if (unused_stores_decremented) {
+      /* Only currently used storage needs to be decrased, rest of it was decremented before */
+         int num = store->incNumConcurrentJobs(-1);
+         Dmsg2(dbglvl, "Store: %s Dec ncj=%d\n", store->name(), num);
+         unused_stores_decremented = false;
+   } else {
+      /* We need to decrement all storages in the list */
+      STORE *tmp_store;
+      foreach_alist(tmp_store, list) {
+         int num = tmp_store->incNumConcurrentJobs(-1);
+         Dmsg2(dbglvl, "Store: %s Dec ncj=%d\n", tmp_store->name(), num);
+      }
    }
 }
 
@@ -253,6 +261,29 @@ const char *storage::print_list() {
    return quote_string(list_str, tmp.addr());
 }
 
+void storage::dec_unused_stores() {
+   lock_guard lg(mutex);
+   STORE *tmp_store;
+
+   foreach_alist(tmp_store, list) {
+      if (store == tmp_store) {
+         /* We don't want to decrement this one since it's the one that will be used */
+         continue;
+      } else {
+         int num = tmp_store->incNumConcurrentJobs(-1);
+         Dmsg2(dbglvl, "Store: %s Dec ncj=%d\n", store->name(), num);
+      }
+   }
+
+   unused_stores_decremented = true;
+}
+
+void storage::dec_curr_store() {
+   lock_guard lg(mutex);
+
+   int num = store->incNumConcurrentJobs(-1);
+   Dmsg2(dbglvl, "Store: %s Dec ncj=%d\n", store->name(), num);
+}
 
 void LeastUsedStore::apply_policy(bool write_store) {
    alist *store = write_store ? wstore.get_list() : rstore.get_list();
@@ -378,15 +409,26 @@ bool StorageManager::inc_read_stores(JCR *jcr) {
    return rstore.inc_stores(jcr);
 }
 
+/* Decrement job counter for all of the storages in the list */
 void StorageManager::dec_read_stores() {
    return rstore.dec_stores();
 }
 
+/* Increment job counter for all of the storages in the list */
 bool StorageManager::inc_write_stores(JCR *jcr) {
    return wstore.inc_stores(jcr);
-
 }
 
 void StorageManager::dec_write_stores() {
-   return wstore.dec_stores();
+   wstore.dec_stores();
+}
+
+/* Decrement job counter for currently used write storage */
+void StorageManager::dec_curr_wstore() {
+   wstore.dec_curr_store();
+}
+
+/* Decrement job counters for write storages which won't be used */
+void StorageManager::dec_unused_wstores() {
+   wstore.dec_unused_stores();
 }
index 916c7cb15919b415b2fd1b9a0bc99f59046c49f4..876793bfb24783dcf28a736d454e2fe894bb5a63 100644 (file)
@@ -59,6 +59,7 @@ class storage {
       POOLMEM *source;       /* Where the storage came from */
       POOLMEM *list_str;     /* List of storage names in the list */
       pthread_mutex_t mutex; /* Mutex for accessing items */
+      bool unused_stores_decremented; /* Set if only currently used storage has NumConcurrentJobs incremented */
 
       /* Only when we are a read storage - increment concurrent read counters for all storages on the list */
       bool inc_rstores(JCR *jcr);
@@ -107,6 +108,10 @@ class storage {
       /* Decrement concurrent read/write counters for all storages on the list */
       void dec_stores();
 
+      void dec_unused_stores();
+
+      void dec_curr_store();
+
       /* Print all elements of the list (sample result of print_list() -> "File1, File2, File3" */
       const char *print_list();
 };
@@ -123,9 +128,9 @@ class storage {
 class StorageManager : public SMARTALLOC {
 
    protected:
-      storage rstore;   /* Read storage */
-      storage wstore;   /* Write storage */
-      const char *policy;
+      storage rstore;               /* Read storage */
+      storage wstore;               /* Write storage */
+      const char *policy;           /* Storage Group Policy used */
 
    public:
       virtual void apply_policy(bool write_store) = 0;
@@ -195,6 +200,10 @@ class StorageManager : public SMARTALLOC {
 
       void dec_write_stores();
 
+      void dec_curr_wstore();
+
+      void dec_unused_wstores();
+
       /************ GENERIC STORAGE HELPERS ************/
       void reset_rwstorage();