]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/message.c
Make sure JobErrors is always nonzero on fatal error
[bacula/bacula] / bacula / src / lib / message.c
index 6d951e2bbfd20fec13cf0bd1f40af084ddda94bc..b13b380106c31a294fc13e3b13fd5b3d91755654 100644 (file)
@@ -6,7 +6,7 @@
    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.
@@ -56,6 +56,8 @@ bool dbg_timestamp = false;           /* print timestamp in debug output */
 bool prt_kaboom = false;              /* Print kaboom output */
 utime_t daemon_start_time = 0;        /* Daemon start time */
 const char *version = VERSION " (" BDATE ")";
+const char *dist_name = DISTNAME " " DISTVER;
+const int beef = BEEF;
 char my_name[30];                     /* daemon name is stored here */
 char host_name[50];                   /* host machine name */
 char *exepath = (char *)NULL;
@@ -89,6 +91,30 @@ const char *host_os = HOST_OS;
 const char *distname = DISTNAME;
 const char *distver = DISTVER;
 
+/* Some message class methods */
+void MSGS::lock()
+{
+   P(fides_mutex);
+}
+
+void MSGS::unlock()
+{
+   V(fides_mutex);
+}
+
+/*
+ * Wait for not in use variable to be clear
+ */
+void MSGS::wait_not_in_use()     /* leaves fides_mutex set */
+{
+   lock();
+   while (m_in_use) {
+      unlock();
+      bmicrosleep(0, 200);         /* wait */
+      lock();
+   }
+}
+
 /*
  * Handle message delivery errors
  */
@@ -300,6 +326,7 @@ init_msg(JCR *jcr, MSGS *msg)
       daemon_msgs->dest_chain = temp_chain;
       memcpy(daemon_msgs->send_msg, msg->send_msg, sizeof(msg->send_msg));
    }
+
    Dmsg2(250, "Copy message resource %p to %p\n", msg, temp_chain);
 
 }
@@ -468,7 +495,15 @@ void close_msg(JCR *jcr)
    if (msgs == NULL) {
       return;
    }
-   P(fides_mutex);
+
+   /* Wait for item to be not in use, then mark closing */
+   if (msgs->is_closing()) {
+      return;
+   }
+   msgs->wait_not_in_use();          /* leaves fides_mutex set */
+   msgs->set_closing();
+   msgs->unlock();
+
    Dmsg1(850, "===Begin close msg resource at %p\n", msgs);
    cmd = get_pool_memory(PM_MESSAGE);
    for (d=msgs->dest_chain; d; ) {
@@ -552,12 +587,13 @@ rem_temp_file:
       }
       d = d->next;                    /* point to next buffer */
    }
-   V(fides_mutex);
    free_pool_memory(cmd);
    Dmsg0(850, "Done walking message chain.\n");
    if (jcr) {
       free_msgs_res(msgs);
       msgs = NULL;
+   } else {
+      msgs->clear_closing();
    }
    Dmsg0(850, "===End close msg resource\n");
 }
@@ -697,6 +733,18 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
     if (msgs == NULL) {
        msgs = daemon_msgs;
     }
+    /*
+     * If closing this message resource, print and send to syslog,
+     *   then get out.
+     */
+    if (msgs->is_closing()) {
+       fputs(dt, stdout);
+       fputs(msg, stdout);
+       fflush(stdout);
+       syslog(LOG_DAEMON|LOG_ERR, "%s", msg);
+       return;
+    }
+
     for (d=msgs->dest_chain; d; d=d->next) {
        if (bit_is_set(type, d->msg_types)) {
           switch (d->dest_code) {
@@ -778,7 +826,10 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
              case MD_MAIL_ON_ERROR:
              case MD_MAIL_ON_SUCCESS:
                 Dmsg1(850, "MAIL for following msg: %s", msg);
-                P(fides_mutex);
+                if (msgs->is_closing()) {
+                   break;
+                }
+                msgs->set_in_use();
                 if (!d->fd) {
                    POOLMEM *name = get_pool_memory(PM_MESSAGE);
                    make_unique_mail_filename(jcr, name, d);
@@ -799,7 +850,7 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
                    d->max_len = len;      /* keep max line length */
                 }
                 fputs(msg, d->fd);
-                V(fides_mutex);
+                msgs->clear_in_use();
                 break;
              case MD_APPEND:
                 Dmsg1(850, "APPEND for following msg: %s", msg);
@@ -809,9 +860,12 @@ void dispatch_message(JCR *jcr, int type, utime_t mtime, char *msg)
                 Dmsg1(850, "FILE for following msg: %s", msg);
                 mode = "w+b";
 send_to_file:
-                P(fides_mutex);
+                if (msgs->is_closing()) {
+                   break;
+                }
+                msgs->set_in_use();
                 if (!d->fd && !open_dest_file(jcr, d, mode)) {
-                   V(fides_mutex);
+                   msgs->clear_in_use();
                    break;
                 }
                 fputs(dt, d->fd);
@@ -825,7 +879,7 @@ send_to_file:
                       fputs(msg, d->fd);
                    }
                 }
-                V(fides_mutex);
+                msgs->clear_in_use();
                 break;
              case MD_DIRECTOR:
                 Dmsg1(850, "DIRECTOR for following msg: %s", msg);
@@ -1164,11 +1218,24 @@ Jmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
        return;
     }
 
+    /* The watchdog thread can't use Jmsg directly, we always queued it */
+    if (is_watchdog()) {
+       va_start(arg_ptr, fmt);
+       bvsnprintf(rbuf,  sizeof(rbuf), fmt, arg_ptr);
+       va_end(arg_ptr);
+       Qmsg(jcr, type, mtime, "%s", rbuf);
+       return;
+    }
+
     msgs = NULL;
     if (!jcr) {
        jcr = get_jcr_from_tsd();
     }
     if (jcr) {
+       if (!jcr->dequeuing_msgs) { /* Avoid recursion */
+          /* Dequeue messages to keep the original order  */
+          dequeue_messages(jcr); 
+       }
        msgs = jcr->jcr_msgs;
        JobId = jcr->JobId;
     }
@@ -1196,6 +1263,9 @@ Jmsg(JCR *jcr, int type, utime_t mtime, const char *fmt,...)
        if (jcr) {
           set_jcr_job_status(jcr, JS_FatalError);
        }
+       if (jcr && jcr->JobErrors == 0) {
+          jcr->JobErrors = 1;
+       }
        break;
     case M_ERROR:
        len = bsnprintf(rbuf, sizeof(rbuf), _("%s JobId %u: Error: "), my_name, JobId);