]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/filed/job.c
BSDI changes, auto Win API detection
[bacula/bacula] / bacula / src / filed / job.c
index b0418bdcb08f99977243c41f634379efa9d4f0bc..0a8510df01e673c78d8e7525b875257d1c6a15e4 100644 (file)
@@ -7,7 +7,7 @@
  *
  */
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Copyright (C) 2000-2003 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -87,31 +87,31 @@ static struct s_cmds cmds[] = {
 };
 
 /* Commands received from director that need scanning */
-static char jobcmd[]     = "JobId=%d Job=%127s SDid=%d SDtime=%d Authorization=%100s";
-static char storaddr[]   = "storage address=%s port=%d\n";
-static char sessioncmd[] = "session %s %ld %ld %ld %ld %ld %ld\n";
-static char restorecmd[] = "restore replace=%c where=%s\n";
+static char jobcmd[]      = "JobId=%d Job=%127s SDid=%d SDtime=%d Authorization=%100s";
+static char storaddr[]    = "storage address=%s port=%d ssl=%d\n";
+static char sessioncmd[]  = "session %127s %ld %ld %ld %ld %ld %ld\n";
+static char restorecmd[]  = "restore replace=%c where=%s\n";
 static char restorecmd1[] = "restore replace=%c where=\n";
-static char verifycmd[]  = "verify level=%20s\n";
+static char verifycmd[]   = "verify level=%30s\n";
 
 /* Responses sent to Director */
-static char errmsg[]       = "2999 Invalid command\n";
-static char no_auth[]      = "2998 No Authorization\n";
-static char OKinc[]        = "2000 OK include\n";
-static char OKest[]        = "2000 OK estimate files=%ld bytes=%ld\n";
-static char OKexc[]        = "2000 OK exclude\n";
-static char OKlevel[]      = "2000 OK level\n";
-static char OKbackup[]     = "2000 OK backup\n";
-static char OKbootstrap[]  = "2000 OK bootstrap\n";
-static char OKverify[]     = "2000 OK verify\n";
-static char OKrestore[]    = "2000 OK restore\n";
-static char OKsession[]    = "2000 OK session\n";
-static char OKstore[]      = "2000 OK storage\n";
-static char OKjob[]        = "2000 OK Job " FDHOST "," DISTNAME "," DISTVER;
-static char OKsetdebug[]   = "2000 OK setdebug=%d\n";
-static char BADjob[]       = "2901 Bad Job\n";
-static char EndRestore[]   = "2800 End Job TermCode=%d JobFiles=%u JobBytes=%" lld "\n";
-static char EndBackup[]    = "2801 End Backup Job TermCode=%d JobFiles=%u ReadBytes=%" lld " JobBytes=%" lld "\n";
+static char errmsg[]      = "2999 Invalid command\n";
+static char no_auth[]     = "2998 No Authorization\n";
+static char OKinc[]       = "2000 OK include\n";
+static char OKest[]       = "2000 OK estimate files=%ld bytes=%ld\n";
+static char OKexc[]       = "2000 OK exclude\n";
+static char OKlevel[]     = "2000 OK level\n";
+static char OKbackup[]    = "2000 OK backup\n";
+static char OKbootstrap[] = "2000 OK bootstrap\n";
+static char OKverify[]    = "2000 OK verify\n";
+static char OKrestore[]   = "2000 OK restore\n";
+static char OKsession[]   = "2000 OK session\n";
+static char OKstore[]     = "2000 OK storage\n";
+static char OKjob[]       = "2000 OK Job " FDHOST "," DISTNAME "," DISTVER;
+static char OKsetdebug[]  = "2000 OK setdebug=%d\n";
+static char BADjob[]      = "2901 Bad Job\n";
+static char EndRestore[]  = "2800 End Job TermCode=%d JobFiles=%u JobBytes=%" lld "\n";
+static char EndBackup[]   = "2801 End Backup Job TermCode=%d JobFiles=%u ReadBytes=%" lld " JobBytes=%" lld "\n";
 
 /* Responses received from Storage Daemon */
 static char OK_end[]       = "3000 OK end\n";
@@ -161,7 +161,7 @@ void *handle_client_request(void *dirp)
    jcr->last_fname = get_pool_memory(PM_FNAME);
    jcr->last_fname[0] = 0;
    jcr->client_name = get_memory(strlen(my_name) + 1);
-   strcpy(jcr->client_name, my_name);
+   pm_strcpy(&jcr->client_name, my_name);
    dir->jcr = (void *)jcr;
 
    /**********FIXME******* add command handler error code */
@@ -181,11 +181,11 @@ void *handle_client_request(void *dirp)
               bnet_fsend(dir, no_auth);
               break;
            }
+           found = TRUE;                /* indicate command found */
            if (!cmds[i].func(jcr)) {    /* do command */
-              quit = TRUE;              /* error, get out */
-               Pmsg0(20, "Command error\n");
+              quit = TRUE;              /* error or fully terminated,  get out */
+               Pmsg0(20, "Command error or Job done.\n");
            }
-           found = TRUE;            /* indicate command found */
            break;
         }
       }
@@ -196,7 +196,7 @@ void *handle_client_request(void *dirp)
       }
    }
    Dmsg0(100, "Calling term_find_files\n");
-   term_find_files(jcr->ff);
+   term_find_files((FF_PKT *)jcr->ff);
    Dmsg0(100, "Done with term_find_files\n");
    free_jcr(jcr);                    /* destroy JCR record */
    Dmsg0(100, "Done with free_jcr\n");
@@ -231,9 +231,9 @@ static int cancel_cmd(JCR *jcr)
       if (!(cjcr=get_jcr_by_full_name(Job))) {
          bnet_fsend(dir, "2901 Job %s not found.\n", Job);
       } else {
-        cjcr->JobStatus = JS_Cancelled;
+        set_jcr_job_status(cjcr, JS_Canceled);
         free_jcr(cjcr);
-         bnet_fsend(dir, "2001 Job %s marked to be cancelled.\n", Job);
+         bnet_fsend(dir, "2001 Job %s marked to be canceled.\n", Job);
       }
    } else {
       bnet_fsend(dir, "2902 Error scanning cancel command.\n");
@@ -288,10 +288,30 @@ static int job_cmd(JCR *jcr)
    }
    jcr->sd_auth_key = bstrdup(sd_auth_key);
    free_pool_memory(sd_auth_key);
+   get_backup_privileges(jcr, 1 /* ignore_errors */);
    Dmsg2(120, "JobId=%d Auth=%s\n", jcr->JobId, jcr->sd_auth_key);
    return bnet_fsend(dir, OKjob);
 }
 
+#define INC_LIST 0
+#define EXC_LIST 1
+
+static void add_fname_to_list(JCR *jcr, char *fname, int list)
+{
+   char *p;  
+   if (list == INC_LIST) {
+      add_fname_to_include_list((FF_PKT *)jcr->ff, 1, fname);
+   } else {
+      /* Skip leading options -- currently ignored */
+      for (p=fname; *p && *p != ' '; p++)
+        { }
+      /* Skip spaces */
+      for ( ; *p && *p == ' '; p++)
+        { }
+      add_fname_to_exclude_list((FF_PKT *)jcr->ff, p);
+   }
+}
+
 /* 
  * 
  * Get list of files/directories to include from Director
@@ -302,10 +322,10 @@ static int include_cmd(JCR *jcr)
    BSOCK *dir = jcr->dir_bsock;
 
    while (bnet_recv(dir) >= 0) {
-       dir->msg[dir->msglen] = 0;
-       strip_trailing_junk(dir->msg);
-       Dmsg1(010, "include file: %s\n", dir->msg);
-       add_fname_to_include_list(jcr->ff, 1, dir->msg);
+      dir->msg[dir->msglen] = 0;
+      strip_trailing_junk(dir->msg);
+      Dmsg1(010, "include file: %s\n", dir->msg);
+      add_fname_to_list(jcr, dir->msg, INC_LIST);
    }
 
    return bnet_fsend(dir, OKinc);
@@ -318,19 +338,12 @@ static int include_cmd(JCR *jcr)
 static int exclude_cmd(JCR *jcr)
 {
    BSOCK *dir = jcr->dir_bsock;
-   char *p;  
 
    while (bnet_recv(dir) >= 0) {
-       dir->msg[dir->msglen] = 0;
-       strip_trailing_junk(dir->msg);
-       /* Skip leading options */
-       for (p=dir->msg; *p && *p != ' '; p++)
-         { }
-       /* Skip spaces */
-       for ( ; *p && *p == ' '; p++)
-         { }
-       add_fname_to_exclude_list(jcr->ff, p);
-       Dmsg1(110, "<dird: exclude file %s\n", dir->msg);
+      dir->msg[dir->msglen] = 0;
+      strip_trailing_junk(dir->msg);
+      add_fname_to_list(jcr, dir->msg, EXC_LIST);
+      Dmsg1(110, "<dird: exclude file %s\n", dir->msg);
    }
 
    return bnet_fsend(dir, OKexc);
@@ -357,6 +370,7 @@ static int bootstrap_cmd(JCR *jcr)
         jcr->RestoreBootstrap, strerror(errno));
       free_pool_memory(jcr->RestoreBootstrap);
       jcr->RestoreBootstrap = NULL;
+      set_jcr_job_status(jcr, JS_ErrorTerminated);
       return 0;
    }
 
@@ -377,21 +391,22 @@ static int bootstrap_cmd(JCR *jcr)
 static int level_cmd(JCR *jcr)
 {
    BSOCK *dir = jcr->dir_bsock;
-   char *level;
+   POOLMEM *level;
    struct tm tm;
    time_t mtime;
 
-   level = (char *) get_memory(dir->msglen);
+   level = get_memory(dir->msglen+1);
    Dmsg1(110, "level_cmd: %s", dir->msg);
    if (sscanf(dir->msg, "level = %s ", level) != 1) {
       Jmsg1(jcr, M_FATAL, 0, _("Bad level command: %s\n"), dir->msg);
       free_memory(level);
       return 0;
    }
-   /*
-    * Full backup requested
-    */
-   if (strcmp(level, "full") == 0) {
+   /* Base backup requested? */
+   if (strcmp(level, "base") == 0) {
+      jcr->save_level = L_BASE;
+   /* Full backup requested? */ 
+   } else if (strcmp(level, "full") == 0) {
       jcr->save_level = L_FULL;
    /* 
     * Backup requested since <date> <time>
@@ -402,7 +417,7 @@ static int level_cmd(JCR *jcr)
       if (sscanf(dir->msg, "level = since %d-%d-%d %d:%d:%d", 
                 &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
                 &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
-         Jmsg1(jcr, M_FATAL, 0, "Bad scan of date/time: %s\n", dir->msg);
+         Jmsg1(jcr, M_FATAL, 0, _("Bad scan of date/time: %s\n"), dir->msg);
         free_memory(level);
         return 0;
       }
@@ -412,8 +427,8 @@ static int level_cmd(JCR *jcr)
       tm.tm_isdst = -1;
       mtime = mktime(&tm);
       Dmsg1(100, "Got since time: %s", ctime(&mtime));
-      jcr->incremental = 1;
-      jcr->mtime = mtime;
+      jcr->incremental = 1;          /* set incremental or decremental backup */
+      jcr->mtime = mtime;            /* set since time */
    } else {
       Jmsg1(jcr, M_FATAL, 0, "Unknown backup level: %s\n", level);
       free_memory(level);
@@ -449,15 +464,16 @@ static int session_cmd(JCR *jcr)
 static int storage_cmd(JCR *jcr)
 {
    int stored_port;               /* storage daemon port */
+   int enable_ssl;                /* enable ssl to sd */
    BSOCK *dir = jcr->dir_bsock;
    BSOCK *sd;                        /* storage daemon bsock */
 
    Dmsg1(100, "StorageCmd: %s", dir->msg);
-   if (sscanf(dir->msg, storaddr, &jcr->stored_addr, &stored_port) != 2) {
+   if (sscanf(dir->msg, storaddr, &jcr->stored_addr, &stored_port, &enable_ssl) != 3) {
       Jmsg(jcr, M_FATAL, 0, _("Bad storage command: %s"), dir->msg);
       return 0;
    }
-   Dmsg2(110, "Open storage: %s:%d\n", jcr->stored_addr, stored_port);
+   Dmsg3(110, "Open storage: %s:%d ssl=%d\n", jcr->stored_addr, stored_port, enable_ssl);
    /* Open command communications with Storage daemon */
    /* Try to connect for 1 hour at 10 second intervals */
    sd = bnet_connect(jcr, 10, 3600, _("Storage daemon"), 
@@ -492,13 +508,13 @@ static int backup_cmd(JCR *jcr)
    int ok = 0;
    int SDJobStatus;
 
-   jcr->JobStatus = JS_Blocked;
+   set_jcr_job_status(jcr, JS_Blocked);
    jcr->JobType = JT_BACKUP;
-   Dmsg1(100, "begin backup ff=%p\n", jcr->ff);
+   Dmsg1(100, "begin backup ff=%p\n", (FF_PKT *)jcr->ff);
 
    if (sd == NULL) {
       Jmsg(jcr, M_FATAL, 0, _("Cannot contact Storage daemon\n"));
-      jcr->JobStatus = JS_ErrorTerminated;
+      set_jcr_job_status(jcr, JS_ErrorTerminated);
       goto cleanup;
    }
 
@@ -513,17 +529,17 @@ static int backup_cmd(JCR *jcr)
    /* 
     * Expect to receive back the Ticket number
     */
-   if (bnet_recv(sd) >= 0) {
+   if (bget_msg(sd) >= 0) {
       Dmsg1(110, "<stored: %s", sd->msg);
       if (sscanf(sd->msg, OK_open, &jcr->Ticket) != 1) {
          Jmsg(jcr, M_FATAL, 0, _("Bad response to append open: %s\n"), sd->msg);
-        jcr->JobStatus = JS_ErrorTerminated;
+        set_jcr_job_status(jcr, JS_ErrorTerminated);
         goto cleanup;
       }
       Dmsg1(110, "Got Ticket=%d\n", jcr->Ticket);
    } else {
       Jmsg(jcr, M_FATAL, 0, _("Bad response from stored to open command\n"));
-      jcr->JobStatus = JS_ErrorTerminated;
+      set_jcr_job_status(jcr, JS_ErrorTerminated);
       goto cleanup;
    }
 
@@ -538,23 +554,28 @@ static int backup_cmd(JCR *jcr)
     */
    Dmsg1(110, "<stored: %s", sd->msg);
    if (!response(jcr, sd, OK_data, "Append Data")) {
-      jcr->JobStatus = JS_ErrorTerminated;
+      set_jcr_job_status(jcr, JS_ErrorTerminated);
       goto cleanup;
    }
       
    /*
     * Send Files to Storage daemon
     */
-   Dmsg1(110, "begin blast ff=%p\n", jcr->ff);
+   Dmsg1(110, "begin blast ff=%p\n", (FF_PKT *)jcr->ff);
    if (!blast_data_to_storage_daemon(jcr, NULL)) {
-      jcr->JobStatus = JS_ErrorTerminated;
+      set_jcr_job_status(jcr, JS_ErrorTerminated);
+      bnet_suppress_error_messages(sd, 1);
    } else {
-      jcr->JobStatus = JS_Terminated;
+      set_jcr_job_status(jcr, JS_Terminated);
+      if (jcr->JobStatus != JS_Terminated) {
+        bnet_suppress_error_messages(sd, 1);
+        goto cleanup;                /* bail out now */
+      }
       /* 
        * Expect to get response to append_data from Storage daemon
        */
       if (!response(jcr, sd, OK_append, "Append Data")) {
-        jcr->JobStatus = JS_ErrorTerminated;
+        set_jcr_job_status(jcr, JS_ErrorTerminated);
         goto cleanup;
       }
      
@@ -564,7 +585,7 @@ static int backup_cmd(JCR *jcr)
       bnet_fsend(sd, append_end, jcr->Ticket);
       /* Get end OK */
       if (!response(jcr, sd, OK_end, "Append End")) {
-        jcr->JobStatus = JS_ErrorTerminated;
+        set_jcr_job_status(jcr, JS_ErrorTerminated);
         goto cleanup;
       }
 
@@ -572,7 +593,7 @@ static int backup_cmd(JCR *jcr)
        * Send Append Close to Storage daemon
        */
       bnet_fsend(sd, append_close, jcr->Ticket);
-      while (bnet_recv(sd) >= 0) {    /* stop on signal or error */
+      while (bget_msg(sd) >= 0) {    /* stop on signal or error */
         if (sscanf(sd->msg, OK_close, &SDJobStatus) == 1) {
            ok = 1;
             Dmsg2(200, "SDJobStatus = %d %c\n", SDJobStatus, (char)SDJobStatus);
@@ -580,13 +601,13 @@ static int backup_cmd(JCR *jcr)
       }
       if (!ok) {
          Jmsg(jcr, M_FATAL, 0, _("Append Close with SD failed.\n"));
-        jcr->JobStatus = JS_ErrorTerminated;
+        set_jcr_job_status(jcr, JS_ErrorTerminated);
         goto cleanup;
       }
       if (SDJobStatus != JS_Terminated) {
          Jmsg(jcr, M_FATAL, 0, _("Bad status %d returned from Storage Daemon.\n"),
            SDJobStatus);
-        jcr->JobStatus = JS_ErrorTerminated;
+        set_jcr_job_status(jcr, JS_ErrorTerminated);
       }
    }
 
@@ -602,7 +623,7 @@ cleanup:
    /* Inform Director that we are done */
    bnet_sig(dir, BNET_TERMINATE);
 
-   return jcr->JobStatus == JS_Terminated;
+   return 0;                         /* return and stop command loop */
 }
 
 /*  
@@ -645,7 +666,9 @@ static int verify_cmd(JCR *jcr)
       if (!open_sd_read_session(jcr)) {
         return 0;
       }
+      start_dir_heartbeat(jcr);
       do_verify_volume(jcr);
+      stop_dir_heartbeat(jcr);
       /* 
        * Send Close session command to Storage daemon
        */
@@ -653,7 +676,7 @@ static int verify_cmd(JCR *jcr)
       Dmsg1(130, "bfiled>stored: %s", sd->msg);
 
       /* ****FIXME**** check response */
-      bnet_recv(sd);                    /* get OK */
+      bget_msg(sd);                     /* get OK */
 
       /* Inform Storage daemon that we are done */
       bnet_sig(sd, BNET_TERMINATE);
@@ -665,7 +688,8 @@ static int verify_cmd(JCR *jcr)
    }
 
    /* Inform Director that we are done */
-   return bnet_sig(dir, BNET_TERMINATE);
+   bnet_sig(dir, BNET_TERMINATE);
+   return 0;                         /* return and terminate command loop */
 }
 
 /*  
@@ -708,16 +732,26 @@ static int restore_cmd(JCR *jcr)
    Dmsg1(110, "bfiled>dird: %s", dir->msg);
 
    jcr->JobType = JT_RESTORE;
-   jcr->JobStatus = JS_Blocked;
 
+   set_jcr_job_status(jcr, JS_Blocked);
    if (!open_sd_read_session(jcr)) {
-      return 0;
+      set_jcr_job_status(jcr, JS_ErrorTerminated);
+      goto bail_out;
    }
 
+   set_jcr_job_status(jcr, JS_Running);
+
    /* 
     * Do restore of files and data
     */
+   start_dir_heartbeat(jcr);
    do_restore(jcr);
+   stop_dir_heartbeat(jcr);
+   
+   set_jcr_job_status(jcr, JS_Terminated);
+   if (jcr->JobStatus != JS_Terminated) {
+      bnet_suppress_error_messages(sd, 1);
+   }
 
    /* 
     * Send Close session command to Storage daemon
@@ -725,19 +759,21 @@ static int restore_cmd(JCR *jcr)
    bnet_fsend(sd, read_close, jcr->Ticket);
    Dmsg1(130, "bfiled>stored: %s", sd->msg);
 
-   /* ****FIXME**** check response */
-   bnet_recv(sd);                    /* get OK */
+   bget_msg(sd);                     /* get OK */
 
    /* Inform Storage daemon that we are done */
    bnet_sig(sd, BNET_TERMINATE);
 
-   bnet_fsend(dir, EndRestore, jcr->JobStatus, jcr->num_files_examined, jcr->JobBytes);
+bail_out:
+   /* Send termination status back to Dir */
+   bnet_fsend(dir, EndRestore, jcr->JobStatus, jcr->num_files_examined, 
+             jcr->JobBytes);
 
    /* Inform Director that we are done */
    bnet_sig(dir, BNET_TERMINATE);
 
    Dmsg0(130, "Done in job.c\n");
-   return 1;
+   return 0;                         /* return and terminate command loop */
 }
 
 static int open_sd_read_session(JCR *jcr)
@@ -762,7 +798,7 @@ static int open_sd_read_session(JCR *jcr)
    /* 
     * Get ticket number
     */
-   if (bnet_recv(sd) >= 0) {
+   if (bget_msg(sd) >= 0) {
       Dmsg1(110, "bfiled<stored: %s", sd->msg);
       if (sscanf(sd->msg, OK_open, &jcr->Ticket) != 1) {
          Jmsg(jcr, M_FATAL, 0, _("Bad response to SD read open: %s\n"), sd->msg);
@@ -829,7 +865,7 @@ int response(JCR *jcr, BSOCK *sd, char *resp, char *cmd)
    if (sd->errors) {
       return 0;
    }
-   if ((n = bnet_recv(sd)) > 0) {
+   if ((n = bget_msg(sd)) > 0) {
       Dmsg0(110, sd->msg);
       if (strcmp(sd->msg, resp) == 0) {
         return 1;
@@ -860,7 +896,7 @@ static int send_bootstrap_file(JCR *jcr)
    if (!bs) {
       Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"), 
         jcr->RestoreBootstrap, strerror(errno));
-      jcr->JobStatus = JS_ErrorTerminated;
+      set_jcr_job_status(jcr, JS_ErrorTerminated);
       return 0;
    }
    strcpy(sd->msg, bootstrap); 
@@ -873,7 +909,7 @@ static int send_bootstrap_file(JCR *jcr)
    bnet_sig(sd, BNET_EOD);
    fclose(bs);
    if (!response(jcr, sd, OKSDbootstrap, "Bootstrap")) {
-      jcr->JobStatus = JS_ErrorTerminated;
+      set_jcr_job_status(jcr, JS_ErrorTerminated);
       return 0;
    }
    return 1;