]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/jcr.c
Fix get_basename() -- rewrite
[bacula/bacula] / bacula / src / lib / jcr.c
index 988566ecfd3fc64d8d33a2a9a750d5ab720be20e..d895ba13ccfb982e6eaf14bc7ae7fc2709c4d0fd 100644 (file)
@@ -1,12 +1,12 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2012 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.
    This program is Free Software; you can redistribute it and/or
-   modify it under the terms of version two of the GNU General Public
+   modify it under the terms of version three of the GNU Affero General Public
    License as published by the Free Software Foundation and included
    in the file LICENSE.
 
@@ -15,7 +15,7 @@
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
+   You should have received a copy of the GNU Affero General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
@@ -87,6 +87,8 @@ static pthread_key_t jcr_key;         /* Pointer to jcr for each thread */
 
 pthread_once_t key_once = PTHREAD_ONCE_INIT; 
 
+static char Job_status[]     = "Status Job=%s JobStatus=%d\n";
+
 
 void lock_jobs()
 {
@@ -342,7 +344,6 @@ JCR *new_jcr(int size, JCR_free_HANDLER *daemon_free_jcr)
    }
    jcr = (JCR *)malloc(size);
    memset(jcr, 0, size);
-   jcr->my_thread_id = pthread_self();
    jcr->msg_queue = New(dlist(item, &item->link));
    if ((status = pthread_mutex_init(&jcr->msg_queue_mutex, NULL)) != 0) {
       berrno be;
@@ -366,7 +367,6 @@ JCR *new_jcr(int size, JCR_free_HANDLER *daemon_free_jcr)
    jcr->setJobType(JT_SYSTEM);           /* internal job until defined */
    jcr->setJobLevel(L_NONE);
    jcr->setJobStatus(JS_Created);        /* ready to run */
-   set_jcr_in_tsd(jcr);
    sigtimer.sa_flags = 0;
    sigtimer.sa_handler = timeout_handler;
    sigfillset(&sigtimer.sa_mask);
@@ -412,6 +412,10 @@ static void remove_jcr(JCR *jcr)
  */
 static void free_common_jcr(JCR *jcr)
 {
+   /* Uses jcr lock/unlock */
+   remove_jcr_from_tsd(jcr);
+   jcr->set_killable(false);
+
    jcr->destroy_mutex();
 
    if (jcr->msg_queue) {
@@ -475,7 +479,6 @@ static void free_common_jcr(JCR *jcr)
       free_pool_memory(jcr->comment);
       jcr->comment = NULL;
    }
-   remove_jcr_from_tsd(jcr);
    free(jcr);
 }
 
@@ -575,7 +578,6 @@ void free_jcr(JCR *jcr)
 
    free_common_jcr(jcr);
    close_msg(NULL);                   /* flush any daemon messages */
-   garbage_collect_memory_pool();
    Dmsg0(dbglvl, "Exit free_jcr\n");
 }
 
@@ -591,16 +593,47 @@ void remove_jcr_from_tsd(JCR *jcr)
    }
 }
 
+void JCR::set_killable(bool killable)
+{
+   JCR *jcr = this;
+   jcr->lock();
+   jcr->my_thread_killable = killable;
+   if (killable) {
+      jcr->my_thread_id = pthread_self();
+   } else {
+      memset(&jcr->my_thread_id, 0, sizeof(jcr->my_thread_id));
+   }
+   jcr->unlock();
+}
+
 /*
- * Put this jcr in the thread specifc data 
+ * Put this jcr in the thread specifc data
+ *  if update_thread_info is true and the jcr is valide,
+ *  we update the my_thread_id in the JCR
  */
 void set_jcr_in_tsd(JCR *jcr)
 {
    int status = pthread_setspecific(jcr_key, (void *)jcr);
    if (status != 0) {
       berrno be;
-      Jmsg1(jcr, M_ABORT, 0, _("pthread_setspecific failed: ERR=%s\n"), be.bstrerror(status));
+      Jmsg1(jcr, M_ABORT, 0, _("pthread_setspecific failed: ERR=%s\n"), 
+            be.bstrerror(status));
+   }
+}
+
+void JCR::my_thread_send_signal(int sig)
+{
+   this->lock();
+   if (this->is_killable() &&
+       !pthread_equal(this->my_thread_id, pthread_self()))
+   {
+      Dmsg1(800, "Send kill to jid=%d\n", this->JobId);
+      pthread_kill(this->my_thread_id, sig);
+
+   } else if (!this->is_killable()) {
+      Dmsg1(10, "Warning, can't send kill to jid=%d\n", this->JobId);
    }
+   this->unlock();
 }
 
 /*
@@ -814,11 +847,13 @@ static int get_status_priority(int JobStatus)
 {
    int priority = 0;
    switch (JobStatus) {
+   case JS_Incomplete:
+      priority = 10;
+      break;
    case JS_ErrorTerminated:
    case JS_FatalError:
    case JS_Canceled:
-   case JS_Incomplete:
-      priority = 10;
+      priority = 9;
       break;
    case JS_Error:
       priority = 8;
@@ -830,12 +865,34 @@ static int get_status_priority(int JobStatus)
    return priority;
 }
 
+/*
+ * Send Job status to Director
+ */
+bool JCR::sendJobStatus()
+{
+   JCR *jcr = this;
+   if (jcr->dir_bsock) {
+      return jcr->dir_bsock->fsend(Job_status, jcr->Job, jcr->JobStatus);
+   }
+   return true; 
+}
 
-void set_jcr_job_status(JCR *jcr, int JobStatus)
+/*
+ * Set and send Job status to Director
+ */
+bool JCR::sendJobStatus(int newJobStatus)
 {
-   jcr->setJobStatus(JobStatus);
+   JCR *jcr = this;
+   if (!jcr->is_JobStatus(newJobStatus)) {
+      setJobStatus(newJobStatus);
+      if (jcr->dir_bsock) {
+         return jcr->dir_bsock->fsend(Job_status, jcr->Job, jcr->JobStatus);
+      }
+   }
+   return true; 
 }
 
+
 void JCR::setJobStatus(int newJobStatus)
 {
    JCR *jcr = this;
@@ -869,7 +926,7 @@ void JCR::setJobStatus(int newJobStatus)
    }
 
    if (oldJobStatus != jcr->JobStatus) {
-      Dmsg2(800, "leave set_job_status old=%c new=%c\n", oldJobStatus, newJobStatus);
+      Dmsg2(800, "leave setJobStatus old=%c new=%c\n", oldJobStatus, newJobStatus);
 //    generate_plugin_event(jcr, bEventStatusChange, NULL);
    }
 }
@@ -1039,7 +1096,7 @@ static void jcr_timeout_check(watchdog_t *self)
             Qmsg(jcr, M_ERROR, 0, _(
 "Watchdog sending kill after %d secs to thread stalled reading Storage daemon.\n"),
                  watchdog_time - timer_start);
-            pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
+            jcr->my_thread_send_signal(TIMEOUT_SIGNAL);
          }
       }
       bs = jcr->file_bsock;
@@ -1051,7 +1108,7 @@ static void jcr_timeout_check(watchdog_t *self)
             Qmsg(jcr, M_ERROR, 0, _(
 "Watchdog sending kill after %d secs to thread stalled reading File daemon.\n"),
                  watchdog_time - timer_start);
-            pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
+            jcr->my_thread_send_signal(TIMEOUT_SIGNAL);
          }
       }
       bs = jcr->dir_bsock;
@@ -1063,7 +1120,7 @@ static void jcr_timeout_check(watchdog_t *self)
             Qmsg(jcr, M_ERROR, 0, _(
 "Watchdog sending kill after %d secs to thread stalled reading Director.\n"),
                  watchdog_time - timer_start);
-            pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
+            jcr->my_thread_send_signal(TIMEOUT_SIGNAL);
          }
       }
    }
@@ -1141,11 +1198,15 @@ void dbg_print_jcr(FILE *fp)
       return;
    }
 
-   fprintf(fp, "Attempt to dump current JCRs\n");
+   fprintf(fp, "Attempt to dump current JCRs. njcrs=%d\n", jcrs->size());
 
    for (JCR *jcr = (JCR *)jcrs->first(); jcr ; jcr = (JCR *)jcrs->next(jcr)) {
-      fprintf(fp, "JCR=%p JobId=%d name=%s JobStatus=%c\n", 
-              jcr, (int)jcr->JobId, jcr->Job, jcr->JobStatus);
+      fprintf(fp, "threadid=%p JobId=%d JobStatus=%c jcr=%p name=%s\n", 
+              (void *)jcr->my_thread_id, (int)jcr->JobId, jcr->JobStatus, jcr, jcr->Job);
+      fprintf(fp, "threadid=%p killable=%d JobId=%d JobStatus=%c "
+                  "jcr=%p name=%s\n",
+              (void *)jcr->my_thread_id, jcr->is_killable(),
+              (int)jcr->JobId, jcr->JobStatus, jcr, jcr->Job);
       fprintf(fp, "\tuse_count=%i\n", jcr->use_count());
       fprintf(fp, "\tJobType=%c JobLevel=%c\n",
               jcr->getJobType(), jcr->getJobLevel());