From 61d542a90cbc57e53d6a6de0126237d227b7700b Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sun, 9 Mar 2008 09:57:20 +0000 Subject: [PATCH] kes Pass jcr to tls routines so debug messages can be handled better. kes Rework jobq resource allocation code, and possibly fix a bug that caused reference counts to get out of sync. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6562 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/dird/jobq.c | 48 ++++++++++++++++++++++++----------------- bacula/src/lib/bnet.c | 10 +++++---- bacula/src/lib/bsock.h | 2 +- bacula/src/lib/protos.h | 4 ++-- bacula/src/lib/tls.c | 8 +++---- bacula/src/version.h | 4 ++-- bacula/technotes-2.3 | 4 ++++ 7 files changed, 47 insertions(+), 33 deletions(-) diff --git a/bacula/src/dird/jobq.c b/bacula/src/dird/jobq.c index c4a4c8cb8b..308acd7730 100644 --- a/bacula/src/dird/jobq.c +++ b/bacula/src/dird/jobq.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2003-2007 Free Software Foundation Europe e.V. + Copyright (C) 2003-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. @@ -357,8 +357,8 @@ static int start_server(jobq_t *jq) pthread_t id; /* - * if any threads are idle, wake one -- - * actually we do a broadcast because on /lib/tls + * if any threads are idle, wake one. + * Actually we do a broadcast because on /lib/tls * these signals seem to get lost from time to time. */ if (jq->idle_workers > 0) { @@ -478,12 +478,14 @@ void *jobq_server(void *arg) */ if (jcr->acquired_resource_locks) { if (jcr->rstore) { - jcr->rstore->NumConcurrentJobs = 0; + jcr->rstore->NumConcurrentJobs--; Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs); + ASSERT(jcr->rstore->NumConcurrentJobs >= 0); } if (jcr->wstore) { jcr->wstore->NumConcurrentJobs--; Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs); + ASSERT(jcr->wstore->NumConcurrentJobs >= 0); } jcr->client->NumConcurrentJobs--; jcr->job->NumConcurrentJobs--; @@ -681,15 +683,24 @@ static bool acquire_resources(JCR *jcr) bool skip_this_jcr = false; jcr->acquired_resource_locks = false; + if (jcr->rstore == jcr->wstore) { /* deadlock */ + Jmsg(jcr, M_FATAL, 0, _("Job canceled. Attempt to read and write same device.\n" + " Read storage \"%s\" (From %s) -- Write storage \"%s\" (From %s)\n"), + jcr->rstore->name(), jcr->rstore_source, jcr->wstore->name(), jcr->wstore_source); + set_jcr_job_status(jcr, JS_Canceled); + return false; + } if (jcr->rstore) { Dmsg1(200, "Rstore=%s\n", jcr->rstore->name()); - /* - * Let only one Restore/Verify job run at a time regardless - * of MaxConcurrentjobs. - */ - if (jcr->rstore->NumConcurrentJobs == 0) { + if (jcr->rstore->NumConcurrentJobs == 0 && + jcr->rstore->NumConcurrentJobs < jcr->rstore->MaxConcurrentJobs) { + /* Simple case, first job */ jcr->rstore->NumConcurrentJobs = 1; Dmsg0(200, "Set rncj=1\n"); + /* We can do this only if multi-drive autochanger */ +// } else if (jcr->rstore->NumConcurrentJobs < jcr->rstore->MaxConcurrentJobs) { +// jcr->rstore->NumConcurrentJobs++; +// Dmsg1(200, "Inc rncj=%d\n", jcr->rstore->NumConcurrentJobs); } else { Dmsg1(200, "Fail rncj=%d\n", jcr->rstore->NumConcurrentJobs); set_jcr_job_status(jcr, JS_WaitStoreRes); @@ -699,14 +710,6 @@ static bool acquire_resources(JCR *jcr) if (jcr->wstore) { Dmsg1(200, "Wstore=%s\n", jcr->wstore->name()); - if (jcr->rstore == jcr->wstore) { /* deadlock */ - jcr->rstore->NumConcurrentJobs = 0; /* back out rstore */ - Jmsg(jcr, M_FATAL, 0, _("Job canceled. Attempt to read and write same device.\n" - " Read storage \"%s\" (From %s) -- Write storage \"%s\" (From %s)\n"), - jcr->rstore->name(), jcr->rstore_source, jcr->wstore->name(), jcr->wstore_source); - set_jcr_job_status(jcr, JS_Canceled); - return false; - } if (jcr->wstore->NumConcurrentJobs == 0 && jcr->wstore->NumConcurrentJobs < jcr->wstore->MaxConcurrentJobs) { /* Simple case, first job */ @@ -716,8 +719,9 @@ static bool acquire_resources(JCR *jcr) jcr->wstore->NumConcurrentJobs++; Dmsg1(200, "Inc wncj=%d\n", jcr->wstore->NumConcurrentJobs); } else if (jcr->rstore) { - jcr->rstore->NumConcurrentJobs = 0; /* back out rstore */ + jcr->rstore->NumConcurrentJobs--; /* back out rstore */ Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs); + ASSERT(jcr->rstore->NumConcurrentJobs >= 0); skip_this_jcr = true; } else { Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs); @@ -736,10 +740,12 @@ static bool acquire_resources(JCR *jcr) if (jcr->wstore) { jcr->wstore->NumConcurrentJobs--; Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs); + ASSERT(jcr->wstore->NumConcurrentJobs >= 0); } if (jcr->rstore) { - jcr->rstore->NumConcurrentJobs = 0; + jcr->rstore->NumConcurrentJobs--; Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs); + ASSERT(jcr->rstore->NumConcurrentJobs >= 0); } set_jcr_job_status(jcr, JS_WaitClientRes); return false; @@ -751,10 +757,12 @@ static bool acquire_resources(JCR *jcr) if (jcr->wstore) { jcr->wstore->NumConcurrentJobs--; Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs); + ASSERT(jcr->wstore->NumConcurrentJobs >= 0); } if (jcr->rstore) { - jcr->rstore->NumConcurrentJobs = 0; + jcr->rstore->NumConcurrentJobs--; Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs); + ASSERT(jcr->rstore->NumConcurrentJobs >= 0); } jcr->client->NumConcurrentJobs--; set_jcr_job_status(jcr, JS_WaitJobRes); diff --git a/bacula/src/lib/bnet.c b/bacula/src/lib/bnet.c index 1ed8e78bbf..a220cce152 100644 --- a/bacula/src/lib/bnet.c +++ b/bacula/src/lib/bnet.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2006 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. @@ -238,6 +238,7 @@ bool bnet_send(BSOCK *bsock) bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list) { TLS_CONNECTION *tls; + JCR *jcr = bsock->jcr(); tls = new_tls_connection(ctx, bsock->m_fd); if (!tls) { @@ -254,7 +255,7 @@ bool bnet_tls_server(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list) } if (verify_list) { - if (!tls_postconnect_verify_cn(tls, verify_list)) { + if (!tls_postconnect_verify_cn(jcr, tls, verify_list)) { Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed." " Peer certificate did not match a required commonName\n"), bsock->host()); @@ -278,6 +279,7 @@ err: bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list) { TLS_CONNECTION *tls; + JCR *jcr = bsock->jcr(); tls = new_tls_connection(ctx, bsock->m_fd); if (!tls) { @@ -295,14 +297,14 @@ bool bnet_tls_client(TLS_CONTEXT *ctx, BSOCK * bsock, alist *verify_list) /* If there's an Allowed CN verify list, use that to validate the remote * certificate's CN. Otherwise, we use standard host/CN matching. */ if (verify_list) { - if (!tls_postconnect_verify_cn(tls, verify_list)) { + if (!tls_postconnect_verify_cn(jcr, tls, verify_list)) { Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS certificate verification failed." " Peer certificate did not match a required commonName\n"), bsock->host()); goto err; } } else { - if (!tls_postconnect_verify_host(tls, bsock->host())) { + if (!tls_postconnect_verify_host(jcr, tls, bsock->host())) { Qmsg1(bsock->jcr(), M_FATAL, 0, _("TLS host certificate verification failed. Host %s did not match presented certificate\n"), bsock->host()); goto err; diff --git a/bacula/src/lib/bsock.h b/bacula/src/lib/bsock.h index 118da0b209..37a1075b71 100644 --- a/bacula/src/lib/bsock.h +++ b/bacula/src/lib/bsock.h @@ -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/lib/protos.h b/bacula/src/lib/protos.h index 61d248b687..8b5a1b908a 100644 --- a/bacula/src/lib/protos.h +++ b/bacula/src/lib/protos.h @@ -286,9 +286,9 @@ TLS_CONTEXT *new_tls_context (const char *ca_certfile, bool verify_peer); void free_tls_context (TLS_CONTEXT *ctx); #ifdef HAVE_TLS -bool tls_postconnect_verify_host (TLS_CONNECTION *tls, +bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host); -bool tls_postconnect_verify_cn (TLS_CONNECTION *tls, +bool tls_postconnect_verify_cn(JCR *jcr, TLS_CONNECTION *tls, alist *verify_list); TLS_CONNECTION *new_tls_connection (TLS_CONTEXT *ctx, int fd); bool tls_bsock_accept (BSOCK *bsock); diff --git a/bacula/src/lib/tls.c b/bacula/src/lib/tls.c index d70e4cb2d0..ecfed33399 100644 --- a/bacula/src/lib/tls.c +++ b/bacula/src/lib/tls.c @@ -249,7 +249,7 @@ bool get_tls_enable(TLS_CONTEXT *ctx) * Returns: true on success * false on failure */ -bool tls_postconnect_verify_cn(TLS_CONNECTION *tls, alist *verify_list) +bool tls_postconnect_verify_cn(JCR *jcr, TLS_CONNECTION *tls, alist *verify_list) { SSL *ssl = tls->openssl; X509 *cert; @@ -259,7 +259,7 @@ bool tls_postconnect_verify_cn(TLS_CONNECTION *tls, alist *verify_list) /* Check if peer provided a certificate */ if (!(cert = SSL_get_peer_certificate(ssl))) { - Jmsg0(NULL, M_ERROR, 0, _("Peer failed to present a TLS certificate\n")); + Qmsg0(jcr, M_ERROR, 0, _("Peer failed to present a TLS certificate\n")); return false; } @@ -288,7 +288,7 @@ bool tls_postconnect_verify_cn(TLS_CONNECTION *tls, alist *verify_list) * Returns: true on success * false on failure */ -bool tls_postconnect_verify_host(TLS_CONNECTION *tls, const char *host) +bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host) { SSL *ssl = tls->openssl; X509 *cert; @@ -301,7 +301,7 @@ bool tls_postconnect_verify_host(TLS_CONNECTION *tls, const char *host) /* Check if peer provided a certificate */ if (!(cert = SSL_get_peer_certificate(ssl))) { - Jmsg1(NULL, M_ERROR, 0, + Qmsg1(jcr, M_ERROR, 0, _("Peer %s failed to present a TLS certificate\n"), host); return false; } diff --git a/bacula/src/version.h b/bacula/src/version.h index 8e2bdbd01d..18e2237179 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -4,8 +4,8 @@ #undef VERSION #define VERSION "2.3.12" -#define BDATE "08 March 2008" -#define LSMDATE "08Mar08" +#define BDATE "09 March 2008" +#define LSMDATE "09Mar08" #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.3 b/bacula/technotes-2.3 index 4f81c92e71..a05b692c5c 100644 --- a/bacula/technotes-2.3 +++ b/bacula/technotes-2.3 @@ -1,6 +1,10 @@ Technical notes on version 2.3 General: +09Mar08 +kes Pass jcr to tls routines so debug messages can be handled better. +kes Rework jobq resource allocation code, and possibly fix a bug + that caused reference counts to get out of sync. 08Mar08 kes Rename fd/dir plugin to use Bacula standard underscore. kes Plugin work -- bring dir up to fd level. -- 2.39.5