]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/filed/job.c
update configure
[bacula/bacula] / bacula / src / filed / job.c
index 9059314a7ae995a6b79d48aee542bbada5f7c906..417a3931de57c7114bd1a41137c190e6412ee84f 100644 (file)
@@ -1,12 +1,12 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2010 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.
 
@@ -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.
@@ -34,6 +34,7 @@
 
 #include "bacula.h"
 #include "filed.h"
+#include "ch.h"
 
 #if defined(WIN32_VSS)
 #include "vss.h"
@@ -92,7 +93,9 @@ static int restore_object_cmd(JCR *jcr);
 static int set_options(findFOPTS *fo, const char *opts);
 static void set_storage_auth_key(JCR *jcr, char *key);
 static int sm_dump_cmd(JCR *jcr);
+#ifdef DEVELOPER
 static int exit_cmd(JCR *jcr);
+#endif
 
 /* Exported functions */
 
@@ -166,7 +169,7 @@ static char OKsession[]   = "2000 OK session\n";
 static char OKstore[]     = "2000 OK storage\n";
 static char OKstoreend[]  = "2000 OK storage end\n";
 static char OKjob[]       = "2000 OK Job %s (%s) %s,%s,%s";
-static char OKsetdebug[]  = "2000 OK setdebug=%d\n";
+static char OKsetdebug[]  = "2000 OK setdebug=%d trace=%d hangup=%d\n";
 static char BADjob[]      = "2901 Bad Job\n";
 static char EndJob[]      = "2800 End Job TermCode=%d JobFiles=%u ReadBytes=%s"
                             " JobBytes=%s Errors=%u VSS=%d Encrypt=%d\n";
@@ -399,12 +402,14 @@ void *handle_client_request(void *dirp)
    Dmsg0(100, "Done with term_find_files\n");
    free_jcr(jcr);                     /* destroy JCR record */
    Dmsg0(100, "Done with free_jcr\n");
-   Dsm_check(1);
+   Dsm_check(100);
+   garbage_collect_memory_pool();
    return NULL;
 }
 
 static int sm_dump_cmd(JCR *jcr)
 {
+   close_memory_pool();
    sm_dump(false, true);
    jcr->dir_bsock->fsend("2000 sm_dump OK\n");
    return 1;
@@ -448,13 +453,13 @@ static int cancel_cmd(JCR *jcr)
       if (!(cjcr=get_jcr_by_full_name(Job))) {
          dir->fsend(_("2901 Job %s not found.\n"), Job);
       } else {
+         generate_plugin_event(cjcr, bEventCancelCommand, NULL);
+         cjcr->setJobStatus(JS_Canceled);
          if (cjcr->store_bsock) {
             cjcr->store_bsock->set_timed_out();
             cjcr->store_bsock->set_terminated();
             cjcr->my_thread_send_signal(TIMEOUT_SIGNAL);
          }
-         generate_plugin_event(cjcr, bEventCancelCommand, NULL);
-         set_jcr_job_status(cjcr, JS_Canceled);
          free_jcr(cjcr);
          dir->fsend(_("2001 Job %s marked to be canceled.\n"), Job);
       }
@@ -465,7 +470,6 @@ static int cancel_cmd(JCR *jcr)
    return 1;
 }
 
-
 /**
  * Set debug level as requested by the Director
  *
@@ -473,17 +477,29 @@ static int cancel_cmd(JCR *jcr)
 static int setdebug_cmd(JCR *jcr)
 {
    BSOCK *dir = jcr->dir_bsock;
-   int level, trace_flag;
-
-   Dmsg1(110, "setdebug_cmd: %s", dir->msg);
-   if (sscanf(dir->msg, "setdebug=%d trace=%d", &level, &trace_flag) != 2 || level < 0) {
-      pm_strcpy(jcr->errmsg, dir->msg);
-      dir->fsend(_("2991 Bad setdebug command: %s\n"), jcr->errmsg);
-      return 0;
+   int32_t level, trace, hangup;
+   int scan;
+
+   Dmsg1(50, "setdebug_cmd: %s", dir->msg);
+   scan = sscanf(dir->msg, "setdebug=%d trace=%d hangup=%d",
+       &level, &trace, &hangup);
+   if (scan != 3) {
+      Dmsg2(20, "sscanf failed: msg=%s scan=%d\n", dir->msg, scan);
+      if (sscanf(dir->msg, "setdebug=%d trace=%d", &level, &trace) != 2) {
+         pm_strcpy(jcr->errmsg, dir->msg);
+         dir->fsend(_("2991 Bad setdebug command: %s\n"), jcr->errmsg);
+         return 0;
+      } else {
+         hangup = -1;
+      }
    }
-   debug_level = level;
-   set_trace(trace_flag);
-   return dir->fsend(OKsetdebug, level);
+   if (level >= 0) {
+      debug_level = level;
+   }
+   set_trace(trace);
+   set_hangup(hangup);
+   Dmsg3(50, "level=%d trace=%d hangup=%d\n", level, get_trace(), get_hangup());
+   return dir->fsend(OKsetdebug, level, get_trace(), get_hangup());
 }
 
 
@@ -527,7 +543,11 @@ static int job_cmd(JCR *jcr)
    Mmsg(jcr->errmsg, "JobId=%d Job=%s", jcr->JobId, jcr->Job);
    new_plugins(jcr);                  /* instantiate plugins for this jcr */
    generate_plugin_event(jcr, bEventJobStart, (void *)jcr->errmsg);
+#ifdef HAVE_WIN32
+   return dir->fsend(OKjob, VERSION, LSMDATE, win_os, DISTNAME, DISTVER);
+#else
    return dir->fsend(OKjob, VERSION, LSMDATE, HOST_OS, DISTNAME, DISTVER);
+#endif
 }
 
 static int runbefore_cmd(JCR *jcr)
@@ -1213,7 +1233,7 @@ static bool term_fileset(JCR *jcr)
          }
       }
       dlistString *node;
-      foreach_dlist(node, incexe->name_list) {
+      foreach_dlist(node, &incexe->name_list) {
          Dmsg1(400, "F %s\n", node->c_str());
       }
       foreach_dlist(node, &incexe->plugin_list) {
@@ -1366,9 +1386,18 @@ static int set_options(findFOPTS *fo, const char *opts)
       case 'W':
          fo->flags |= FO_ENHANCEDWILD;
          break;
-      case 'Z':                 /* gzip compression */
-         fo->flags |= FO_GZIP;
-         fo->GZIP_level = *++p - '0';
+      case 'Z':                 /* compression */
+         p++;                   /* skip Z */
+         if (*p >= '0' && *p <= '9') {
+            fo->flags |= FO_COMPRESS;
+            fo->Compress_algo = COMPRESS_GZIP;
+            fo->Compress_level = *p - '0';
+         }
+         else if (*p == 'o') {
+            fo->flags |= FO_COMPRESS;
+            fo->Compress_algo = COMPRESS_LZO1X;
+            fo->Compress_level = 1; /* not used with LZO */
+         }
          break;
       case 'K':
          fo->flags |= FO_NOATIME;
@@ -1467,7 +1496,7 @@ static int bootstrap_cmd(JCR *jcr)
       while (dir->recv() >= 0)
         {  }
       free_bootstrap(jcr);
-      set_jcr_job_status(jcr, JS_ErrorTerminated);
+      jcr->setJobStatus(JS_ErrorTerminated);
       return 0;
    }
 
@@ -1495,27 +1524,30 @@ static int level_cmd(JCR *jcr)
    int mtime_only;
 
    level = get_memory(dir->msglen+1);
-   Dmsg1(100, "level_cmd: %s", dir->msg);
+   Dmsg1(10, "level_cmd: %s", dir->msg);
 
    /* keep compatibility with older directors */
    if (strstr(dir->msg, "accurate")) {
       jcr->accurate = true;
    }
+   if (strstr(dir->msg, "rerunning")) {
+      jcr->rerunning = true;
+   }
    if (sscanf(dir->msg, "level = %s ", level) != 1) {
       goto bail_out;
    }
    /* Base backup requested? */
    if (strcmp(level, "base") == 0) {
-      jcr->set_JobLevel(L_BASE);
+      jcr->setJobLevel(L_BASE);
    /* Full backup requested? */
    } else if (strcmp(level, "full") == 0) {
-      jcr->set_JobLevel(L_FULL);
+      jcr->setJobLevel(L_FULL);
    } else if (strstr(level, "differential")) {
-      jcr->set_JobLevel(L_DIFFERENTIAL);
+      jcr->setJobLevel(L_DIFFERENTIAL);
       free_memory(level);
       return 1;
    } else if (strstr(level, "incremental")) {
-      jcr->set_JobLevel(L_INCREMENTAL);
+      jcr->setJobLevel(L_INCREMENTAL);
       free_memory(level);
       return 1;
    /*
@@ -1527,7 +1559,7 @@ static int level_cmd(JCR *jcr)
       utime_t since_time, adj;
       btime_t his_time, bt_start, rt=0, bt_adj=0;
       if (jcr->getJobLevel() == L_NONE) {
-         jcr->set_JobLevel(L_SINCE);     /* if no other job level set, do it now */
+         jcr->setJobLevel(L_SINCE);     /* if no other job level set, do it now */
       }
       if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d",
                  buf, &mtime_only) != 2) {
@@ -1589,7 +1621,7 @@ static int level_cmd(JCR *jcr)
    if (buf) {
       free_memory(buf);
    }
-   generate_plugin_event(jcr, bEventLevel, (void *)jcr->getJobLevel());
+   generate_plugin_event(jcr, bEventLevel, (void*)(intptr_t)jcr->getJobLevel());
    return dir->fsend(OKlevel);
 
 bail_out:
@@ -1690,6 +1722,10 @@ static int storage_cmd(JCR *jcr)
    /* Try to connect for 1 hour at 10 second intervals */
 
    sd->set_source_address(me->FDsrc_addr);
+<<<<<<< HEAD
+=======
+
+>>>>>>> caaa5db... Implement RestoreObject for sqlite + cleanups
    if (!sd->connect(jcr, 10, (int)me->SDConnectTimeout, me->heartbeat_interval,
                 _("Storage daemon"), jcr->stored_addr, NULL, stored_port, 1)) {
      sd->destroy();
@@ -1733,6 +1769,7 @@ static int backup_cmd(JCR *jcr)
    BSOCK *sd = jcr->store_bsock;
    int ok = 0;
    int SDJobStatus;
+   int32_t FileIndex;
 
 #if defined(WIN32_VSS)
    // capture state here, if client is backed up by multiple directors
@@ -1744,6 +1781,11 @@ static int backup_cmd(JCR *jcr)
       P(vss_mutex);
    }
 #endif
+  
+   if (sscanf(dir->msg, "backup FileIndex=%ld\n", &FileIndex) == 1) {
+      jcr->JobFiles = FileIndex;
+      Dmsg1(100, "JobFiles=%ld\n", jcr->JobFiles);
+   }
 
    /**
     * Validate some options given to the backup make sense for the compiled in
@@ -1758,8 +1800,8 @@ static int backup_cmd(JCR *jcr)
       goto cleanup;
    }
 
-   set_jcr_job_status(jcr, JS_Blocked);
-   jcr->set_JobType(JT_BACKUP);
+   jcr->setJobStatus(JS_Blocked);
+   jcr->setJobType(JT_BACKUP);
    Dmsg1(100, "begin backup ff=%p\n", jcr->ff);
 
    if (sd == NULL) {
@@ -1814,34 +1856,35 @@ static int backup_cmd(JCR *jcr)
       if (g_pVSSClient->InitializeForBackup(jcr)) {   
         generate_plugin_event(jcr, bEventVssBackupAddComponents);
         /* tell vss which drives to snapshot */   
-        char szWinDriveLetters[27];   
+        char szWinDriveLetters[27];
+        *szWinDriveLetters=0;
+        generate_plugin_event(jcr, bEventVssPrepareSnapshot, szWinDriveLetters);
         if (get_win32_driveletters(jcr->ff, szWinDriveLetters)) {
             Jmsg(jcr, M_INFO, 0, _("Generate VSS snapshots. Driver=\"%s\", Drive(s)=\"%s\"\n"), g_pVSSClient->GetDriverName(), szWinDriveLetters);
             if (!g_pVSSClient->CreateSnapshots(szWinDriveLetters)) {               
-               Jmsg(jcr, M_WARNING, 0, _("Generate VSS snapshots failed.\n"));
-               jcr->JobErrors++;
+               berrno be;
+               Jmsg(jcr, M_FATAL, 0, _("Generate VSS snapshots failed. ERR=%s\n"), be.bstrerror());
             } else {
                /* tell user if snapshot creation of a specific drive failed */
                int i;
                for (i=0; i < (int)strlen(szWinDriveLetters); i++) {
                   if (islower(szWinDriveLetters[i])) {
-                     Jmsg(jcr, M_WARNING, 0, _("Generate VSS snapshot of drive \"%c:\\\" failed. VSS support is disabled on this drive.\n"), szWinDriveLetters[i]);
-                     jcr->JobErrors++;
+                     Jmsg(jcr, M_FATAL, 0, _("Generate VSS snapshot of drive \"%c:\\\" failed.\n"), szWinDriveLetters[i]);
                   }
                }
                /* inform user about writer states */
-               for (i=0; i < (int)g_pVSSClient->GetWriterCount(); i++)                
+               for (i=0; i < (int)g_pVSSClient->GetWriterCount(); i++) {               
                   if (g_pVSSClient->GetWriterState(i) < 1) {
                      Jmsg(jcr, M_INFO, 0, _("VSS Writer (PrepareForBackup): %s\n"), g_pVSSClient->GetWriterInfo(i));                    
-                     //jcr->JobErrors++;
                   }                            
+               }
             }
         } else {
-            Jmsg(jcr, M_INFO, 0, _("No drive letters found for generating VSS snapshots.\n"));
+            Jmsg(jcr, M_FATAL, 0, _("No drive letters found for generating VSS snapshots.\n"));
         }
       } else {
          berrno be;
-         Jmsg(jcr, M_WARNING, 0, _("VSS was not initialized properly. VSS support is disabled. ERR=%s\n"), be.bstrerror());
+         Jmsg(jcr, M_FATAL, 0, _("VSS was not initialized properly. ERR=%s\n"), be.bstrerror());
       } 
       run_scripts(jcr, jcr->RunScripts, "ClientAfterVSS");
    }
@@ -1852,11 +1895,11 @@ static int backup_cmd(JCR *jcr)
     */
    Dmsg1(110, "begin blast ff=%p\n", (FF_PKT *)jcr->ff);
    if (!blast_data_to_storage_daemon(jcr, NULL)) {
-      set_jcr_job_status(jcr, JS_ErrorTerminated);
+      jcr->setJobStatus(JS_ErrorTerminated);
       bnet_suppress_error_messages(sd, 1);
       Dmsg0(110, "Error in blast_data.\n");
    } else {
-      set_jcr_job_status(jcr, JS_Terminated);
+      jcr->setJobStatus(JS_Terminated);
       /* Note, the above set status will not override an error */
       if (!(jcr->JobStatus == JS_Terminated || jcr->JobStatus == JS_Warnings)) {
          bnet_suppress_error_messages(sd, 1);
@@ -1866,7 +1909,7 @@ static int backup_cmd(JCR *jcr)
        * Expect to get response to append_data from Storage daemon
        */
       if (!response(jcr, sd, OK_append, "Append Data")) {
-         set_jcr_job_status(jcr, JS_ErrorTerminated);
+         jcr->setJobStatus(JS_ErrorTerminated);
          goto cleanup;
       }
 
@@ -1876,7 +1919,7 @@ static int backup_cmd(JCR *jcr)
       sd->fsend(append_end, jcr->Ticket);
       /* Get end OK */
       if (!response(jcr, sd, OK_end, "Append End")) {
-         set_jcr_job_status(jcr, JS_ErrorTerminated);
+         jcr->setJobStatus(JS_ErrorTerminated);
          goto cleanup;
       }
 
@@ -1904,6 +1947,7 @@ cleanup:
 #if defined(WIN32_VSS)
    if (jcr->VSS) {
       Win32ConvCleanupCache();
+      g_pVSSClient->DestroyWriterInfo();
       V(vss_mutex);
    }
 #endif
@@ -1922,22 +1966,22 @@ static int verify_cmd(JCR *jcr)
    BSOCK *sd  = jcr->store_bsock;
    char level[100];
 
-   jcr->set_JobType(JT_VERIFY);
+   jcr->setJobType(JT_VERIFY);
    if (sscanf(dir->msg, verifycmd, level) != 1) {
       dir->fsend(_("2994 Bad verify command: %s\n"), dir->msg);
       return 0;
    }
 
    if (strcasecmp(level, "init") == 0) {
-      jcr->set_JobLevel(L_VERIFY_INIT);
+      jcr->setJobLevel(L_VERIFY_INIT);
    } else if (strcasecmp(level, "catalog") == 0){
-      jcr->set_JobLevel(L_VERIFY_CATALOG);
+      jcr->setJobLevel(L_VERIFY_CATALOG);
    } else if (strcasecmp(level, "volume") == 0){
-      jcr->set_JobLevel(L_VERIFY_VOLUME_TO_CATALOG);
+      jcr->setJobLevel(L_VERIFY_VOLUME_TO_CATALOG);
    } else if (strcasecmp(level, "data") == 0){
-      jcr->set_JobLevel(L_VERIFY_DATA);
+      jcr->setJobLevel(L_VERIFY_DATA);
    } else if (strcasecmp(level, "disk_to_catalog") == 0) {
-      jcr->set_JobLevel(L_VERIFY_DISK_TO_CATALOG);
+      jcr->setJobLevel(L_VERIFY_DISK_TO_CATALOG);
    } else {
       dir->fsend(_("2994 Bad verify level: %s\n"), dir->msg);
       return 0;
@@ -1946,7 +1990,7 @@ static int verify_cmd(JCR *jcr)
    dir->fsend(OKverify);
 
    generate_daemon_event(jcr, "JobStart");
-   generate_plugin_event(jcr, bEventLevel, (void *)jcr->getJobLevel());
+   generate_plugin_event(jcr, bEventLevel,(void *)(intptr_t)jcr->getJobLevel());
    generate_plugin_event(jcr, bEventStartVerifyJob);
 
    Dmsg1(110, "filed>dird: %s", dir->msg);
@@ -2082,16 +2126,16 @@ static int restore_cmd(JCR *jcr)
    dir->fsend(OKrestore);
    Dmsg1(110, "filed>dird: %s", dir->msg);
 
-   jcr->set_JobType(JT_RESTORE);
+   jcr->setJobType(JT_RESTORE);
 
-   set_jcr_job_status(jcr, JS_Blocked);
+   jcr->setJobStatus(JS_Blocked);
 
    if (!open_sd_read_session(jcr)) {
-      set_jcr_job_status(jcr, JS_ErrorTerminated);
+      jcr->setJobStatus(JS_ErrorTerminated);
       goto bail_out;
    }
 
-   set_jcr_job_status(jcr, JS_Running);
+   jcr->setJobStatus(JS_Running);
 
    /**
     * Do restore of files and data
@@ -2131,7 +2175,7 @@ static int restore_cmd(JCR *jcr)
    do_restore(jcr);
    stop_dir_heartbeat(jcr);
 
-   set_jcr_job_status(jcr, JS_Terminated);
+   jcr->setJobStatus(JS_Terminated);
    if (jcr->JobStatus != JS_Terminated) {
       bnet_suppress_error_messages(sd, 1);
    }
@@ -2150,11 +2194,12 @@ static int restore_cmd(JCR *jcr)
 #if defined(WIN32_VSS)
    /* STOP VSS ON WIN32 */
    /* tell vss to close the restore session */
-   Dmsg0(0, "About to call CloseRestore\n");
+   Dmsg0(100, "About to call CloseRestore\n");
    if (jcr->VSS) {
-      Dmsg0(0, "Really about to call CloseRestore\n");
+      generate_plugin_event(jcr, bEventVssBeforeCloseRestore);
+      Dmsg0(100, "Really about to call CloseRestore\n");
       if (g_pVSSClient->CloseRestore()) {
-         Dmsg0(0, "CloseRestore success\n");
+         Dmsg0(100, "CloseRestore success\n");
          /* inform user about writer states */
          for (int i=0; i<(int)g_pVSSClient->GetWriterCount(); i++) {
             int msg_type = M_INFO;
@@ -2166,7 +2211,7 @@ static int restore_cmd(JCR *jcr)
          }
       }
       else
-         Dmsg1(0, "CloseRestore fail - %08x\n", errno);
+         Dmsg1(100, "CloseRestore fail - %08x\n", errno);
       V(vss_mutex);
    }
 #endif
@@ -2175,7 +2220,7 @@ bail_out:
    bfree_and_null(jcr->where);
 
    if (jcr->JobErrors) {
-      set_jcr_job_status(jcr, JS_ErrorTerminated);
+      jcr->setJobStatus(JS_ErrorTerminated);
    }
 
    Dmsg0(100, "Done in job.c\n");
@@ -2190,6 +2235,10 @@ bail_out:
       ret = 0;     /* we stop here */
    }
 
+   if (job_canceled(jcr)) {
+      ret = 0;     /* we stop here */
+   }
+
    return ret;
 }
 
@@ -2323,7 +2372,7 @@ static int send_bootstrap_file(JCR *jcr)
       berrno be;
       Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"),
          jcr->RestoreBootstrap, be.bstrerror());
-      set_jcr_job_status(jcr, JS_ErrorTerminated);
+      jcr->setJobStatus(JS_ErrorTerminated);
       goto bail_out;
    }
    sd->msglen = pm_strcpy(sd->msg, bootstrap);
@@ -2335,7 +2384,7 @@ static int send_bootstrap_file(JCR *jcr)
    sd->signal(BNET_EOD);
    fclose(bs);
    if (!response(jcr, sd, OKSDbootstrap, "Bootstrap")) {
-      set_jcr_job_status(jcr, JS_ErrorTerminated);
+      jcr->setJobStatus(JS_ErrorTerminated);
       goto bail_out;
    }
    stat = 1;