]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/job.c
Pull SD files from master
[bacula/bacula] / bacula / src / stored / job.c
index 965c197bea3ecd947bdb6fcee4e0ec660f21ba47..9d8cd7cab22c14a8e215428b17b9277a6a6601fd 100644 (file)
@@ -1,12 +1,12 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2011 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.
 
    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.
 
-   Bacula® is a registered trademark of John Walker.
+   Bacula® is a registered trademark of Kern Sibbald.
    The licensor of Bacula is the Free Software Foundation Europe
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
@@ -30,8 +30,6 @@
  *
  *   Kern Sibbald, MM
  *
- *   Version $Id$
- *
  */
 
 #include "bacula.h"
@@ -47,17 +45,15 @@ extern uint32_t newVolSessionId();
 extern bool do_mac(JCR *jcr);
 
 /* Requests from the Director daemon */
+/* Added in 3.1.4 14Sep09 KES */
 static char jobcmd[] = "JobId=%d job=%127s job_name=%127s client_name=%127s "
       "type=%d level=%d FileSet=%127s NoAttr=%d SpoolAttr=%d FileSetMD5=%127s "
-      "SpoolData=%d SpoolSize=%s WritePartAfterJob=%d PreferMountedVols=%d\n";
-
+      "SpoolData=%d WritePartAfterJob=%d PreferMountedVols=%d SpoolSize=%s "
+      "rerunning=%d VolSessionId=%d VolSessionTime=%d\n";
 
 /* Responses sent to Director daemon */
 static char OKjob[]     = "3000 OK Job SDid=%u SDtime=%u Authorization=%s\n";
 static char BAD_job[]   = "3915 Bad Job command. stat=%d CMD: %s\n";
-//static char OK_query[]  = "3001 OK query\n";
-//static char NO_query[]  = "3918 Query failed\n";
-//static char BAD_query[] = "3917 Bad query command: %s\n";
 
 /*
  * Director requests us to start a job
@@ -71,14 +67,14 @@ static char BAD_job[]   = "3915 Bad Job command. stat=%d CMD: %s\n";
  */
 bool job_cmd(JCR *jcr)
 {
-   int JobId;
+   int32_t JobId;
    char auth_key[100];
    char spool_size[30];
    char seed[100];
    BSOCK *dir = jcr->dir_bsock;
    POOL_MEM job_name, client_name, job, fileset_name, fileset_md5;
-   int JobType, level, spool_attributes, no_attributes, spool_data;
-   int write_part_after_job, PreferMountedVols;
+   int32_t JobType, level, spool_attributes, no_attributes, spool_data;
+   int32_t write_part_after_job, PreferMountedVols, rerunning;
    int stat;
    JCR *ojcr;
 
@@ -86,18 +82,23 @@ bool job_cmd(JCR *jcr)
     * Get JobId and permissions from Director
     */
    Dmsg1(100, "<dird: %s", dir->msg);
+   bstrncpy(spool_size, "0", sizeof(spool_size));
    stat = sscanf(dir->msg, jobcmd, &JobId, job.c_str(), job_name.c_str(),
               client_name.c_str(),
               &JobType, &level, fileset_name.c_str(), &no_attributes,
-              &spool_attributes, fileset_md5.c_str(), &spool_data, spool_size,
-              &write_part_after_job, &PreferMountedVols);
-   if (stat != 14) {
+              &spool_attributes, fileset_md5.c_str(), &spool_data,
+              &write_part_after_job, &PreferMountedVols, spool_size,
+              &rerunning, &jcr->VolSessionId, &jcr->VolSessionTime);
+   if (stat != 17) {
       pm_strcpy(jcr->errmsg, dir->msg);
       dir->fsend(BAD_job, stat, jcr->errmsg);
       Dmsg1(100, ">dird: %s", dir->msg);
-      set_jcr_job_status(jcr, JS_ErrorTerminated);
+      jcr->setJobStatus(JS_ErrorTerminated);
       return false;
    }
+   jcr->rerunning = (rerunning) ? true : false;
+   Dmsg3(100, "rerunning=%d VolSesId=%d VolSesTime=%d\n", jcr->rerunning,
+         jcr->VolSessionId, jcr->VolSessionTime);
    /*
     * Since this job could be rescheduled, we
     *  check to see if we have it already. If so
@@ -105,12 +106,22 @@ bool job_cmd(JCR *jcr)
     */
    ojcr = get_jcr_by_full_name(job.c_str());
    if (ojcr && !ojcr->authenticated) {
-      Dmsg2(100, "Found ojcr=0x%x Job %s\n", (unsigned)(long)ojcr, job.c_str());
+      Dmsg2(100, "Found ojcr=0x%x Job %s\n", (unsigned)(intptr_t)ojcr, job.c_str());
       free_jcr(ojcr);
    }
    jcr->JobId = JobId;
-   jcr->VolSessionId = newVolSessionId();
-   jcr->VolSessionTime = VolSessionTime;
+   Dmsg2(800, "Start JobId=%d %p\n", JobId, jcr);
+   set_jcr_in_tsd(jcr);
+
+   /*
+    * If job rescheduled because previous was incomplete,
+    * the Resched flag is set and VolSessionId and VolSessionTime
+    * are given to us (same as restarted job).
+    */
+   if (!jcr->rerunning) {
+      jcr->VolSessionId = newVolSessionId();
+      jcr->VolSessionTime = VolSessionTime;
+   }
    bstrncpy(jcr->Job, job, sizeof(jcr->Job));
    unbash_spaces(job_name);
    jcr->job_name = get_pool_memory(PM_NAME);
@@ -121,8 +132,8 @@ bool job_cmd(JCR *jcr)
    unbash_spaces(fileset_name);
    jcr->fileset_name = get_pool_memory(PM_NAME);
    pm_strcpy(jcr->fileset_name, fileset_name);
-   jcr->JobType = JobType;
-   jcr->JobLevel = level;
+   jcr->setJobType(JobType);
+   jcr->setJobLevel(level);
    jcr->no_attributes = no_attributes;
    jcr->spool_attributes = spool_attributes;
    jcr->spool_data = spool_data;
@@ -132,6 +143,7 @@ bool job_cmd(JCR *jcr)
    pm_strcpy(jcr->fileset_md5, fileset_md5);
    jcr->PreferMountedVols = PreferMountedVols;
 
+
    jcr->authenticated = false;
 
    /*
@@ -140,10 +152,12 @@ bool job_cmd(JCR *jcr)
    bsnprintf(seed, sizeof(seed), "%p%d", jcr, JobId);
    make_session_key(auth_key, seed, 1);
    dir->fsend(OKjob, jcr->VolSessionId, jcr->VolSessionTime, auth_key);
-   Dmsg2(100, ">dird jid=%u: %s", (uint32_t)jcr->JobId, dir->msg);
+   Dmsg2(50, ">dird jid=%u: %s", (uint32_t)jcr->JobId, dir->msg);
    jcr->sd_auth_key = bstrdup(auth_key);
    memset(auth_key, 0, sizeof(auth_key));
+   new_plugins(jcr);            /* instantiate the plugins */
    generate_daemon_event(jcr, "JobStart");
+   generate_plugin_event(jcr, bsdEventJobStart, (void *)"JobStart");
    return true;
 }
 
@@ -152,29 +166,28 @@ bool run_cmd(JCR *jcr)
    struct timeval tv;
    struct timezone tz;
    struct timespec timeout;
-   int errstat;
+   int errstat = 0;
 
-   Dsm_check(1);
+   Dsm_check(200);
    Dmsg1(200, "Run_cmd: %s\n", jcr->dir_bsock->msg);
-   /* The following jobs don't need the FD */
-   switch (jcr->JobType) {
-   case JT_MIGRATE:
-   case JT_COPY:
-   case JT_ARCHIVE:
-      jcr->authenticated = true;
+
+   /* If we do not need the FD, we are doing a migrate, copy, or virtual
+    *   backup.
+    */
+   if (jcr->no_client_used()) {
       do_mac(jcr);
       return false;
    }
 
-   set_jcr_job_status(jcr, JS_WaitFD);          /* wait for FD to connect */
-   dir_send_job_status(jcr);
+   jcr->sendJobStatus(JS_WaitFD);          /* wait for FD to connect */
 
    gettimeofday(&tv, &tz);
    timeout.tv_nsec = tv.tv_usec * 1000;
    timeout.tv_sec = tv.tv_sec + me->client_wait;
 
-   Dmsg3(050, "%s waiting %d sec for FD to contact SD key=%s\n",
-         jcr->Job, (int)me->client_wait, jcr->sd_auth_key);
+   Dmsg3(50, "%s waiting %d sec for FD to contact SD key=%s\n",
+         jcr->Job, (int)(timeout.tv_sec-time(NULL)), jcr->sd_auth_key);
+   Dmsg2(800, "Wait FD for jid=%d %p\n", jcr->JobId, jcr);
 
    /*
     * Wait for the File daemon to contact us to start the Job,
@@ -187,15 +200,20 @@ bool run_cmd(JCR *jcr)
       if (errstat == ETIMEDOUT || errstat == EINVAL || errstat == EPERM) {
          break;
       }
+      Dmsg1(800, "=== Auth cond errstat=%d\n", errstat);
    }
+   Dmsg3(50, "Auth=%d canceled=%d errstat=%d\n", jcr->authenticated,
+      job_canceled(jcr), errstat);
    V(mutex);
+   Dmsg2(800, "Auth fail or cancel for jid=%d %p\n", jcr->JobId, jcr);
 
    memset(jcr->sd_auth_key, 0, strlen(jcr->sd_auth_key));
 
    if (jcr->authenticated && !job_canceled(jcr)) {
-      Dmsg1(100, "Running job %s\n", jcr->Job);
+      Dmsg2(800, "Running jid=%d %p\n", jcr->JobId, jcr);
       run_job(jcr);                   /* Run the job */
    }
+   Dmsg2(800, "Done jid=%d %p\n", jcr->JobId, jcr);
    return false;
 }
 
@@ -207,38 +225,47 @@ void handle_filed_connection(BSOCK *fd, char *job_name)
 {
    JCR *jcr;
 
-   bmicrosleep(0, 50000);             /* wait 50 millisecs */
+/*
+ * With the following bmicrosleep on, running the 
+ * SD under the debugger fails.   
+ */ 
+// bmicrosleep(0, 50000);             /* wait 50 millisecs */
    if (!(jcr=get_jcr_by_full_name(job_name))) {
       Jmsg1(NULL, M_FATAL, 0, _("FD connect failed: Job name not found: %s\n"), job_name);
-      Dmsg1(3, "**** Job \"%s\" not found", job_name);
+      Dmsg1(3, "**** Job \"%s\" not found.\n", job_name);
+      fd->close();
       return;
    }
 
-   jcr->file_bsock = fd;
-   jcr->file_bsock->set_jcr(jcr);
 
-   Dmsg1(110, "Found Job %s\n", job_name);
+   Dmsg1(50, "Found Job %s\n", job_name);
 
    if (jcr->authenticated) {
       Jmsg2(jcr, M_FATAL, 0, _("Hey!!!! JobId %u Job %s already authenticated.\n"),
          (uint32_t)jcr->JobId, jcr->Job);
+      Dmsg2(50, "Hey!!!! JobId %u Job %s already authenticated.\n",
+         (uint32_t)jcr->JobId, jcr->Job);
+      fd->close();
       free_jcr(jcr);
       return;
    }
 
+   jcr->file_bsock = fd;
+   jcr->file_bsock->set_jcr(jcr);
+
    /*
     * Authenticate the File daemon
     */
    if (jcr->authenticated || !authenticate_filed(jcr)) {
-      Dmsg1(100, "Authentication failed Job %s\n", jcr->Job);
+      Dmsg1(50, "Authentication failed Job %s\n", jcr->Job);
       Jmsg(jcr, M_FATAL, 0, _("Unable to authenticate File daemon\n"));
    } else {
       jcr->authenticated = true;
-      Dmsg2(110, "OK Authentication jid=%u Job %s\n", (uint32_t)jcr->JobId, jcr->Job);
+      Dmsg2(50, "OK Authentication jid=%u Job %s\n", (uint32_t)jcr->JobId, jcr->Job);
    }
 
    if (!jcr->authenticated) {
-      set_jcr_job_status(jcr, JS_ErrorTerminated);
+      jcr->setJobStatus(JS_ErrorTerminated);
    }
    pthread_cond_signal(&jcr->job_start_wait); /* wake waiting job */
    free_jcr(jcr);
@@ -325,7 +352,12 @@ bool query_cmd(JCR *jcr)
  */
 void stored_free_jcr(JCR *jcr)
 {
-   Dmsg1(900, "stored_free_jcr JobId=%u\n", jcr->JobId);
+   Dmsg2(800, "End Job JobId=%u %p\n", jcr->JobId, jcr);
+   if (jcr->dir_bsock) {
+      Dmsg2(800, "Send terminate jid=%d %p\n", jcr->JobId, jcr);
+      jcr->dir_bsock->signal(BNET_EOD);
+      jcr->dir_bsock->signal(BNET_TERMINATE);
+   }
    if (jcr->file_bsock) {
       jcr->file_bsock->close();
       jcr->file_bsock = NULL;
@@ -347,6 +379,8 @@ void stored_free_jcr(JCR *jcr)
       free_bsr(jcr->bsr);
       jcr->bsr = NULL;
    }
+   /* Free any restore volume list created */
+   free_restore_volume_list(jcr);
    if (jcr->RestoreBootstrap) {
       unlink(jcr->RestoreBootstrap);
       free_pool_memory(jcr->RestoreBootstrap);
@@ -392,6 +426,10 @@ void stored_free_jcr(JCR *jcr)
       delete jcr->write_store;
       jcr->write_store = NULL;
    }
-   Dsm_check(1);
+   Dsm_check(200);
+
+   if (jcr->JobId != 0)
+      write_state_file(me->working_directory, "bacula-sd", get_first_port_host_order(me->sdaddrs));
+
    return;
 }