]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/filed/job.c
- Start implementing Christopher's St.Bernard code.
[bacula/bacula] / bacula / src / filed / job.c
index 4665fceebcb79973200c09e9697d3f4b6941cc3b..91235844f2593e4f14a45aefca1358145f02ae8d 100644 (file)
@@ -7,11 +7,11 @@
  *
  */
 /*
-   Copyright (C) 2000-2005 Kern Sibbald
+   Copyright (C) 2000-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
-   version 2 as ammended with additional clauses defined in the
+   version 2 as amended with additional clauses defined in the
    file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
@@ -23,9 +23,9 @@
 
 #include "bacula.h"
 #include "filed.h"
-
 #ifdef WIN32_VSS
 #include "vss.h"   
+static pthread_mutex_t vss_mutex = PTHREAD_MUTEX_INITIALIZER;
 #endif
 
 extern char my_name[];
@@ -174,6 +174,11 @@ void *handle_client_request(void *dirp)
    jcr->last_fname[0] = 0;
    jcr->client_name = get_memory(strlen(my_name) + 1);
    pm_strcpy(jcr->client_name, my_name);
+   jcr->pki_sign = me->pki_sign;
+   jcr->pki_encrypt = me->pki_encrypt;
+   jcr->pki_keypair = me->pki_keypair;
+   jcr->pki_signers = me->pki_signers;
+   jcr->pki_recipients = me->pki_recipients;
    dir->jcr = jcr;
    enable_backup_privileges(NULL, 1 /* ignore_errors */);
 
@@ -233,7 +238,7 @@ void *handle_client_request(void *dirp)
    bnet_sig(dir, BNET_TERMINATE);
 
    /* Clean up fileset */
-   FF_PKT *ff = (FF_PKT *)jcr->ff;
+   FF_PKT *ff = jcr->ff;
    findFILESET *fileset = ff->fileset;
    if (fileset) {
       int i, j, k;
@@ -287,7 +292,7 @@ void *handle_client_request(void *dirp)
    }
    ff->fileset = NULL;
    Dmsg0(100, "Calling term_find_files\n");
-   term_find_files((FF_PKT *)jcr->ff);
+   term_find_files(jcr->ff);
    jcr->ff = NULL;
    Dmsg0(100, "Done with term_find_files\n");
    free_jcr(jcr);                     /* destroy JCR record */
@@ -321,19 +326,14 @@ static int cancel_cmd(JCR *jcr)
 
    if (sscanf(dir->msg, "cancel Job=%127s", Job) == 1) {
       if (!(cjcr=get_jcr_by_full_name(Job))) {
-         bnet_fsend(dir, "2901 Job %s not found.\n", Job);
+         bnet_fsend(dir, _("2901 Job %s not found.\n"), Job);
       } else {
          if (cjcr->store_bsock) {
-            P(cjcr->mutex);
             cjcr->store_bsock->timed_out = 1;
             cjcr->store_bsock->terminated = 1;
-/*
- * #if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
- */
 #if !defined(HAVE_CYGWIN)
             pthread_kill(cjcr->my_thread_id, TIMEOUT_SIGNAL);
 #endif
-            V(cjcr->mutex);
          }
          set_jcr_job_status(cjcr, JS_Canceled);
          free_jcr(cjcr);
@@ -359,7 +359,7 @@ static int setdebug_cmd(JCR *jcr)
    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);
-      bnet_fsend(dir, "2991 Bad setdebug command: %s\n", jcr->errmsg);
+      bnet_fsend(dir, _("2991 Bad setdebug command: %s\n"), jcr->errmsg);
       return 0;
    }
    debug_level = level;
@@ -376,7 +376,7 @@ static int estimate_cmd(JCR *jcr)
    if (sscanf(dir->msg, estimatecmd, &jcr->listing) != 1) {
       pm_strcpy(jcr->errmsg, dir->msg);
       Jmsg(jcr, M_FATAL, 0, _("Bad estimate command: %s"), jcr->errmsg);
-      bnet_fsend(dir, "2992 Bad estimate command.\n");
+      bnet_fsend(dir, _("2992 Bad estimate command.\n"));
       return 0;
    }
    make_estimate(jcr);
@@ -393,7 +393,7 @@ static int job_cmd(JCR *jcr)
 {
    BSOCK *dir = jcr->dir_bsock;
    POOLMEM *sd_auth_key;
-
+   
    sd_auth_key = get_memory(dir->msglen);
    if (sscanf(dir->msg, jobcmd,  &jcr->JobId, jcr->Job,
               &jcr->VolSessionId, &jcr->VolSessionTime,
@@ -420,7 +420,7 @@ static int runbefore_cmd(JCR *jcr)
    if (sscanf(dir->msg, runbefore, cmd) != 1) {
       pm_strcpy(jcr->errmsg, dir->msg);
       Jmsg1(jcr, M_FATAL, 0, _("Bad RunBeforeJob command: %s\n"), jcr->errmsg);
-      bnet_fsend(dir, "2905 Bad RunBeforeJob command.\n");
+      bnet_fsend(dir, _("2905 Bad RunBeforeJob command.\n"));
       free_memory(cmd);
       return 0;
    }
@@ -433,7 +433,7 @@ static int runbefore_cmd(JCR *jcr)
       bnet_fsend(dir, OKRunBefore);
       return 1;
    } else {
-      bnet_fsend(dir, "2905 Bad RunBeforeJob command.\n");
+      bnet_fsend(dir, _("2905 Bad RunBeforeJob command.\n"));
       return 0;
    }
 }
@@ -447,7 +447,7 @@ static int runafter_cmd(JCR *jcr)
    if (sscanf(dir->msg, runafter, msg) != 1) {
       pm_strcpy(jcr->errmsg, dir->msg);
       Jmsg1(jcr, M_FATAL, 0, _("Bad RunAfter command: %s\n"), jcr->errmsg);
-      bnet_fsend(dir, "2905 Bad RunAfterJob command.\n");
+      bnet_fsend(dir, _("2905 Bad RunAfterJob command.\n"));
       free_memory(msg);
       return 0;
    }
@@ -502,7 +502,7 @@ static bool init_fileset(JCR *jcr)
    if (!jcr->ff) {
       return false;
    }
-   ff = (FF_PKT *)jcr->ff;
+   ff = jcr->ff;
    if (ff->fileset) {
       return false;
    }
@@ -602,7 +602,7 @@ static void add_file_to_fileset(JCR *jcr, const char *fname, findFILESET *filese
 
 static void add_fileset(JCR *jcr, const char *item)
 {
-   FF_PKT *ff = (FF_PKT *)jcr->ff;
+   FF_PKT *ff = jcr->ff;
    findFILESET *fileset = ff->fileset;
    int state = fileset->state;
    findFOPTS *current_opts;
@@ -676,7 +676,7 @@ static void add_fileset(JCR *jcr, const char *item)
          regerror(rc, preg, prbuf, sizeof(prbuf));
          regfree(preg);
          free(preg);
-         Jmsg(jcr, M_FATAL, 0, "REGEX %s compile error. ERR=%s\n", item, prbuf);
+         Jmsg(jcr, M_FATAL, 0, _("REGEX %s compile error. ERR=%s\n"), item, prbuf);
          state = state_error;
          break;
       }
@@ -730,7 +730,7 @@ static void add_fileset(JCR *jcr, const char *item)
       state = state_options;
       break;
    default:
-      Jmsg(jcr, M_FATAL, 0, "Invalid FileSet command: %s\n", item);
+      Jmsg(jcr, M_FATAL, 0, _("Invalid FileSet command: %s\n"), item);
       state = state_error;
       break;
    }
@@ -739,7 +739,9 @@ static void add_fileset(JCR *jcr, const char *item)
 
 static bool term_fileset(JCR *jcr)
 {
-   FF_PKT *ff = (FF_PKT *)jcr->ff;
+   FF_PKT *ff = jcr->ff;
+
+#ifdef xxx
    findFILESET *fileset = ff->fileset;
    int i, j, k;
 
@@ -817,6 +819,7 @@ static bool term_fileset(JCR *jcr)
          Dmsg1(400, "F %s\n", (char *)incexe->name_list.get(j));
       }
    }
+#endif
    return ff->fileset->state != state_error;
 }
 
@@ -866,7 +869,32 @@ static void set_options(findFOPTS *fo, const char *opts)
          fo->flags |= FO_READFIFO;
          break;
       case 'S':
-         fo->flags |= FO_SHA1;
+         switch(*(p + 1)) {
+         case ' ':
+            /* Old director did not specify SHA variant */
+            fo->flags |= FO_SHA1;
+            break;
+         case '1':
+            fo->flags |= FO_SHA1;
+            p++;
+            break;
+#ifdef HAVE_SHA2
+         case '2':
+            fo->flags |= FO_SHA256;
+            p++;
+            break;
+         case '3':
+            fo->flags |= FO_SHA512;
+            p++;
+            break;
+#endif
+         default:
+            /* Automatically downgrade to SHA-1 if an unsupported
+             * SHA variant is specified */
+            fo->flags |= FO_SHA1;
+            p++;
+            break;
+         }
          break;
       case 's':
          fo->flags |= FO_SPARSE;
@@ -899,7 +927,7 @@ static void set_options(findFOPTS *fo, const char *opts)
          Dmsg1(200, "Compression level=%d\n", fo->GZIP_level);
          break;
       default:
-         Emsg1(M_ERROR, 0, "Unknown include/exclude option: %c\n", *p);
+         Emsg1(M_ERROR, 0, _("Unknown include/exclude option: %c\n"), *p);
          break;
       }
    }
@@ -922,7 +950,7 @@ static int fileset_cmd(JCR *jcr)
    }
    while (bnet_recv(dir) >= 0) {
       strip_trailing_junk(dir->msg);
-      Dmsg1(400, "Fileset: %s\n", dir->msg);
+      Dmsg1(500, "Fileset: %s\n", dir->msg);
       add_fileset(jcr, dir->msg);
    }
    if (!term_fileset(jcr)) {
@@ -931,6 +959,15 @@ static int fileset_cmd(JCR *jcr)
    return bnet_fsend(dir, OKinc);
 }
 
+static void free_bootstrap(JCR *jcr)
+{
+   if (jcr->RestoreBootstrap) {
+      unlink(jcr->RestoreBootstrap);
+      free_pool_memory(jcr->RestoreBootstrap);
+      jcr->RestoreBootstrap = NULL;
+   }
+}
+
 
 /* 
  * The Director sends us the bootstrap file, which
@@ -942,10 +979,7 @@ static int bootstrap_cmd(JCR *jcr)
    POOLMEM *fname = get_pool_memory(PM_FNAME);
    FILE *bs;
 
-   if (jcr->RestoreBootstrap) {
-      unlink(jcr->RestoreBootstrap);
-      free_pool_memory(jcr->RestoreBootstrap);
-   }
+   free_bootstrap(jcr);
    Mmsg(fname, "%s/%s.%s.bootstrap", me->working_directory, me->hdr.name,
       jcr->Job);
    Dmsg1(400, "bootstrap=%s\n", fname);
@@ -953,17 +987,15 @@ static int bootstrap_cmd(JCR *jcr)
    bs = fopen(fname, "a+");           /* create file */
    if (!bs) {
       berrno be;
+      Jmsg(jcr, M_FATAL, 0, _("Could not create bootstrap file %s: ERR=%s\n"),
+         jcr->RestoreBootstrap, be.strerror());
       /*
        * Suck up what he is sending to us so that he will then
        *   read our error message.
        */
       while (bnet_recv(dir) >= 0)
         {  }
-
-      Jmsg(jcr, M_FATAL, 0, _("Could not create bootstrap file %s: ERR=%s\n"),
-         jcr->RestoreBootstrap, be.strerror());
-      free_pool_memory(jcr->RestoreBootstrap);
-      jcr->RestoreBootstrap = NULL;
+      free_bootstrap(jcr);
       set_jcr_job_status(jcr, JS_ErrorTerminated);
       return 0;
    }
@@ -973,7 +1005,10 @@ static int bootstrap_cmd(JCR *jcr)
        fputs(dir->msg, bs);
    }
    fclose(bs);
-
+   /*
+    * Note, do not free the bootstrap yet -- it needs to be 
+    *  sent to the SD 
+    */
    return bnet_fsend(dir, OKbootstrap);
 }
 
@@ -1023,6 +1058,7 @@ static int level_cmd(JCR *jcr)
          goto bail_out;
       }
       since_time = str_to_uint64(buf);  /* this is the since time */
+      Dmsg1(100, "since_time=%d\n", (int)since_time);
       char ed1[50], ed2[50];
       /*
        * Sync clocks by polling him for the time. We take
@@ -1042,8 +1078,10 @@ static int level_cmd(JCR *jcr)
          }
          his_time = str_to_uint64(buf);
          rt = get_current_btime() - bt_start; /* compute round trip time */
-         bt_adj -= his_time - bt_start - rt/2;
-         Dmsg2(200, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2));
+         Dmsg2(100, "Dirtime=%s FDtime=%s\n", edit_uint64(his_time, ed1),
+               edit_uint64(bt_start, ed2));
+         bt_adj +=  bt_start - his_time - rt/2;
+         Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2));
       }
 
       bt_adj = bt_adj / 8;            /* compute average time */
@@ -1059,7 +1097,7 @@ static int level_cmd(JCR *jcr)
       jcr->incremental = 1;           /* set incremental or decremental backup */
       jcr->mtime = (time_t)since_time; /* set since time */
    } else {
-      Jmsg1(jcr, M_FATAL, 0, "Unknown backup level: %s\n", level);
+      Jmsg1(jcr, M_FATAL, 0, _("Unknown backup level: %s\n"), level);
       free_memory(level);
       return 0;
    }
@@ -1092,7 +1130,7 @@ static int session_cmd(JCR *jcr)
               &jcr->StartFile, &jcr->EndFile,
               &jcr->StartBlock, &jcr->EndBlock) != 7) {
       pm_strcpy(jcr->errmsg, dir->msg);
-      Jmsg(jcr, M_FATAL, 0, "Bad session command: %s", jcr->errmsg);
+      Jmsg(jcr, M_FATAL, 0, _("Bad session command: %s"), jcr->errmsg);
       return 0;
    }
 
@@ -1155,9 +1193,21 @@ static int backup_cmd(JCR *jcr)
    int SDJobStatus;
    char ed1[50], ed2[50];
 
+#ifdef WIN32_VSS
+   // capture state here, if client is backed up by multiple directors
+   // and one enables vss and the other does not then enable_vss can change
+   // between here and where its evaluated after the job completes.
+   bool bDoVSS = false;
+
+   bDoVSS = g_pVSSClient && enable_vss;
+   if (bDoVSS)
+      /* Run only one at a time */
+      P(vss_mutex);
+#endif
+
    set_jcr_job_status(jcr, JS_Blocked);
    jcr->JobType = JT_BACKUP;
-   Dmsg1(100, "begin backup ff=%p\n", (FF_PKT *)jcr->ff);
+   Dmsg1(100, "begin backup ff=%p\n", jcr->ff);
 
    if (sd == NULL) {
       Jmsg(jcr, M_FATAL, 0, _("Cannot contact Storage daemon\n"));
@@ -1205,35 +1255,38 @@ static int backup_cmd(JCR *jcr)
 
 #ifdef WIN32_VSS
    /* START VSS ON WIN 32 */
-   if (g_pVSSClient) {
-      if (g_pVSSClient->InitializeForBackup()) {
-         /* tell vss which drives to snapshot */   
-         char szWinDriveLetters[27];   
-         if (get_win32_driveletters((FF_PKT *)jcr->ff, szWinDriveLetters)) {
+   if (bDoVSS) {      
+      if (g_pVSSClient->InitializeForBackup()) {   
+        /* tell vss which drives to snapshot */   
+        char szWinDriveLetters[27];   
+        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"));
-            }
-            else {
+            if (!g_pVSSClient->CreateSnapshots(szWinDriveLetters)) {               
+               Jmsg(jcr, M_WARNING, 0, _("Generate VSS snapshots failed.\n"));
+               jcr->Errors++;
+            } else {
                /* tell user if snapshot creation of a specific drive failed */
-               for (size_t i=0; i<strlen (szWinDriveLetters); i++) {
-                  if (islower(szWinDriveLetters[i]))
-                     Jmsg(jcr, M_WARNING, 0, _("Generate VSS snapshot of drive \"%c:\\\" failed\n"), szWinDriveLetters[i]);
+               size_t i;
+               for (i=0; i<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->Errors++;
+                  }
                }
                /* inform user about writer states */
-               for (size_t i=0; i<g_pVSSClient->GetWriterCount(); i++) {
-                  int msg_type = M_INFO;
-                  if (g_pVSSClient->GetWriterState(i) < 0)
-                     msg_type = M_WARNING;
-
-                  Jmsg(jcr, msg_type, 0, _("VSS Writer: %s\n"), g_pVSSClient->GetWriterInfo(i));
-               }
+               for (i=0; i<g_pVSSClient->GetWriterCount(); i++)                
+                  if (g_pVSSClient->GetWriterState(i) < 1) {
+                     Jmsg(jcr, M_WARNING, 0, _("VSS Writer (PrepareForBackup): %s\n"), g_pVSSClient->GetWriterInfo(i));                    
+                     jcr->Errors++;
+                  }                            
             }
-         }
+        } else {
+            Jmsg(jcr, M_INFO, 0, _("No drive letters found for generating VSS snapshots.\n"));
+        }
       } else {
-         Jmsg(jcr, M_WARNING, 0, _("VSS was not initialized properly. VSS support is disabled."));
-      }
+         berrno be;
+         Jmsg(jcr, M_WARNING, 0, _("VSS was not initialized properly. VSS support is disabled. ERR=%s\n"), be.strerror());
+      } 
    }
 #endif
 
@@ -1294,8 +1347,20 @@ cleanup:
 #ifdef WIN32_VSS
    /* STOP VSS ON WIN 32 */
    /* tell vss to close the backup session */
-   if (g_pVSSClient)
-      g_pVSSClient->CloseBackup();
+   if (bDoVSS) {
+      if (g_pVSSClient->CloseBackup()) {             
+         /* inform user about writer states */
+         for (size_t i=0; i<g_pVSSClient->GetWriterCount(); i++) {
+            int msg_type = M_INFO;
+            if (g_pVSSClient->GetWriterState(i) < 1) {
+               msg_type = M_WARNING;
+               jcr->Errors++;
+            }
+            Jmsg(jcr, msg_type, 0, _("VSS Writer (BackupComplete): %s\n"), g_pVSSClient->GetWriterInfo(i));
+         }
+      }
+      V(vss_mutex);
+   }
 #endif
 
    bnet_fsend(dir, EndJob, jcr->JobStatus, jcr->JobFiles,
@@ -1318,7 +1383,7 @@ static int verify_cmd(JCR *jcr)
 
    jcr->JobType = JT_VERIFY;
    if (sscanf(dir->msg, verifycmd, level) != 1) {
-      bnet_fsend(dir, "2994 Bad verify command: %s\n", dir->msg);
+      bnet_fsend(dir, _("2994 Bad verify command: %s\n"), dir->msg);
       return 0;
    }
 
@@ -1333,7 +1398,7 @@ static int verify_cmd(JCR *jcr)
    } else if (strcasecmp(level, "disk_to_catalog") == 0) {
       jcr->JobLevel = L_VERIFY_DISK_TO_CATALOG;
    } else {
-      bnet_fsend(dir, "2994 Bad verify level: %s\n", dir->msg);
+      bnet_fsend(dir, _("2994 Bad verify level: %s\n"), dir->msg);
       return 0;
    }
 
@@ -1372,7 +1437,7 @@ static int verify_cmd(JCR *jcr)
       do_verify(jcr);
       break;
    default:
-      bnet_fsend(dir, "2994 Bad verify level: %s\n", dir->msg);
+      bnet_fsend(dir, _("2994 Bad verify level: %s\n"), dir->msg);
       return 0;
    }
 
@@ -1498,7 +1563,7 @@ static int open_sd_read_session(JCR *jcr)
    /*
     * Open Read Session with Storage daemon
     */
-   bnet_fsend(sd, read_open, jcr->VolumeName,
+   bnet_fsend(sd, read_open, "DummyVolume",
       jcr->VolSessionId, jcr->VolSessionTime, jcr->StartFile, jcr->EndFile,
       jcr->StartBlock, jcr->EndBlock);
    Dmsg1(110, ">stored: %s", sd->msg);
@@ -1546,11 +1611,7 @@ static void filed_free_jcr(JCR *jcr)
    if (jcr->store_bsock) {
       bnet_close(jcr->store_bsock);
    }
-   if (jcr->RestoreBootstrap) {
-      unlink(jcr->RestoreBootstrap);
-      free_pool_memory(jcr->RestoreBootstrap);
-      jcr->RestoreBootstrap = NULL;
-   }
+   free_bootstrap(jcr);
    if (jcr->last_fname) {
       free_pool_memory(jcr->last_fname);
    }
@@ -1628,11 +1689,6 @@ static int send_bootstrap_file(JCR *jcr)
    stat = 1;
 
 bail_out:
-   if (jcr->RestoreBootstrap) {
-      unlink(jcr->RestoreBootstrap);
-      free_pool_memory(jcr->RestoreBootstrap);
-      jcr->RestoreBootstrap = NULL;
-   }
-
+   free_bootstrap(jcr);
    return stat;
 }