From: Michal Rakowski Date: Wed, 26 May 2021 04:45:29 +0000 (+0200) Subject: Fix #7629 About not using other available storages X-Git-Tag: Release-11.3.2~526 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=291dabc75cd27dad0173a940f32790a4a3f251b8;p=thirdparty%2Fbacula.git Fix #7629 About not using other available storages We need to release not used Storages after staring job against one of the Storages in the list. --- diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c index 15fc77c3c..14f68c566 100644 --- a/bacula/src/dird/backup.c +++ b/bacula/src/dird/backup.c @@ -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; } diff --git a/bacula/src/dird/jobq.c b/bacula/src/dird/jobq.c index 0623c76fe..91a20dfc0 100644 --- a/bacula/src/dird/jobq.c +++ b/bacula/src/dird/jobq.c @@ -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(); diff --git a/bacula/src/dird/store_mngr.c b/bacula/src/dird/store_mngr.c index c3e54bef4..865491203 100644 --- a/bacula/src/dird/store_mngr.c +++ b/bacula/src/dird/store_mngr.c @@ -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(); } diff --git a/bacula/src/dird/store_mngr.h b/bacula/src/dird/store_mngr.h index 916c7cb15..876793bfb 100644 --- a/bacula/src/dird/store_mngr.h +++ b/bacula/src/dird/store_mngr.h @@ -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();