From 8b3d08637b553ef932d34ca030e381065588c3d3 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 15 Feb 2010 18:18:47 +0100 Subject: [PATCH] Fix Allow Duplicates bug --- bacula/src/dird/getmsg.c | 7 ++++--- bacula/src/dird/job.c | 27 +++++++++++++++++++++------ bacula/src/lib/jcr.c | 4 +--- bacula/src/stored/dircmd.c | 17 +++++++++++------ 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/bacula/src/dird/getmsg.c b/bacula/src/dird/getmsg.c index 60e7aed439..1dd0687e6a 100644 --- a/bacula/src/dird/getmsg.c +++ b/bacula/src/dird/getmsg.c @@ -125,7 +125,7 @@ void set_jcr_sd_job_status(JCR *jcr, int SDJobStatus) */ int bget_dirmsg(BSOCK *bs) { - int32_t n; + int32_t n = BNET_TERMINATE; char Job[MAX_NAME_LENGTH]; char MsgType[20]; int type; @@ -133,11 +133,11 @@ int bget_dirmsg(BSOCK *bs) JCR *jcr = bs->jcr(); char *msg; - for (;;) { + for ( ; !bs->is_stop() && !bs->is_timed_out(); ) { n = bs->recv(); Dmsg2(100, "bget_dirmsg %d: %s\n", n, bs->msg); - if (is_bnet_stop(bs)) { + if (bs->is_stop() || bs->is_timed_out()) { return n; /* error or terminate */ } if (n == BNET_SIGNAL) { /* handle signal */ @@ -328,6 +328,7 @@ int bget_dirmsg(BSOCK *bs) #endif return n; } + return n; } static char *find_msg_start(char *msg) diff --git a/bacula/src/dird/job.c b/bacula/src/dird/job.c index ab49fd6383..efd663ba4a 100644 --- a/bacula/src/dird/job.c +++ b/bacula/src/dird/job.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2009 Free Software Foundation Europe e.V. + Copyright (C) 2000-2010 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. @@ -31,7 +31,6 @@ * * Kern Sibbald, October MM * - * Version $Id$ */ #include "bacula.h" @@ -412,6 +411,11 @@ bool cancel_job(UAContext *ua, JCR *jcr) fd->signal(BNET_TERMINATE); fd->close(); ua->jcr->file_bsock = NULL; + jcr->file_bsock->set_terminated(); + if (jcr->my_thread_id) { + pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL); + Dmsg1(800, "Send kill to jid=%d\n", jcr->JobId); + } } /* Cancel Storage daemon */ @@ -445,6 +449,10 @@ bool cancel_job(UAContext *ua, JCR *jcr) sd->signal(BNET_TERMINATE); sd->close(); ua->jcr->store_bsock = NULL; + jcr->store_bsock->set_terminated(); + if (jcr->my_thread_id) { + pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL); + } } break; } @@ -680,6 +688,7 @@ bool allow_duplicate_job(JCR *jcr) if (job->AllowDuplicateJobs) { return true; } + Dmsg0(800, "Enter allow_duplicate_job\n"); /* * After this point, we do not want to allow any duplicate * job to run. @@ -691,7 +700,7 @@ bool allow_duplicate_job(JCR *jcr) } if (strcmp(job->name(), djcr->job->name()) == 0) { bool cancel_dup = false; - bool cancel_me = false; + bool cancel_me = false; if (job->DuplicateJobProximity > 0) { utime_t now = (utime_t)time(NULL); if ((now - djcr->start_time) > job->DuplicateJobProximity) { @@ -750,17 +759,23 @@ bool allow_duplicate_job(JCR *jcr) } if (cancel_dup || job->CancelRunningDuplicates) { /* Zap the duplicated job djcr */ - UAContext *ua = new_ua_context(djcr); + UAContext *ua = new_ua_context(jcr); Jmsg(jcr, M_INFO, 0, _("Cancelling duplicate JobId=%d.\n"), djcr->JobId); - ua->jcr = djcr; cancel_job(ua, djcr); free_ua_context(ua); - Dmsg2(800, "Have cancelled JCR %p JobId=%d\n", djcr, djcr->JobId); + if (djcr->my_thread_id) { + pthread_kill(djcr->my_thread_id, TIMEOUT_SIGNAL); + Dmsg1(800, "Send kill to jid=%d\n", djcr->JobId); + } + Dmsg2(800, "Cancel dup %p JobId=%d\n", djcr, djcr->JobId); } else { /* Zap current job */ Jmsg(jcr, M_FATAL, 0, _("JobId %d already running. Duplicate job not allowed.\n"), djcr->JobId); + Dmsg2(800, "Cancel me %p JobId=%d\n", jcr, jcr->JobId); } + Dmsg4(800, "curJobId=%d use_cnt=%d dupJobId=%d use_cnt=%d\n", + jcr->JobId, jcr->use_count(), djcr->JobId, djcr->use_count()); break; /* did our work, get out of foreach loop */ } } diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 7bf2ac08e5..4e5b4c06e8 100644 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2000-2009 Free Software Foundation Europe e.V. + Copyright (C) 2000-2010 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. @@ -31,8 +31,6 @@ * * Kern E. Sibbald, December 2000 * - * Version $Id$ - * * These routines are thread safe. * * The job list routines were re-written in May 2005 to diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 8cf6ac8d09..6097b8af8b 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2001-2009 Free Software Foundation Europe e.V. + Copyright (C) 2001-2010 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. @@ -43,8 +43,6 @@ * * Kern Sibbald, May MMI * - * Version $Id$ - * */ #include "bacula.h" @@ -58,7 +56,7 @@ extern struct s_last_job last_job; extern bool init_done; /* Static variables */ -static char derrmsg[] = "3900 Invalid command\n"; +static char derrmsg[] = "3900 Invalid command:"; static char OKsetdebug[] = "3000 OK setdebug=%d\n"; static char invalid_cmd[] = "3997 Invalid command for a Director with Monitor directive enabled.\n"; static char OK_bootstrap[] = "3000 OK bootstrap\n"; @@ -241,7 +239,9 @@ void *handle_connection_request(void *arg) } } if (!found) { /* command not found */ - bs->fsend(derrmsg); + POOL_MEM err_msg; + Mmsg(err_msg, "%s %s\n", derrmsg, bs->msg); + bs->fsend(err_msg.c_str()); break; } } @@ -307,14 +307,19 @@ static bool cancel_cmd(JCR *cjcr) } else { oldStatus = jcr->JobStatus; set_jcr_job_status(jcr, JS_Canceled); + Dmsg2(800, "Cancel JobId=%d %p\n", jcr->JobId, jcr); if (!jcr->authenticated && oldStatus == JS_WaitFD) { pthread_cond_signal(&jcr->job_start_wait); /* wake waiting thread */ } if (jcr->file_bsock) { - bnet_sig(jcr->file_bsock, BNET_TERMINATE); + jcr->file_bsock->signal(BNET_TERMINATE); + jcr->file_bsock->set_terminated(); + Dmsg2(800, "Term bsock jid=%d %p\n", jcr->JobId, jcr); } else { /* Still waiting for FD to connect, release it */ + bmicrosleep(0, 50000); pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */ + Dmsg2(800, "Signal FD connect jid=%d %p\n", jcr->JobId, jcr); } /* If thread waiting on mount, wake him */ if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->waiting_for_mount()) { -- 2.39.2