]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/fd_cmds.c
Rename incomplete to rerunning for clarity
[bacula/bacula] / bacula / src / dird / fd_cmds.c
index 57c38ddca86f02959b70d6bc76fb80faa704e544..3a8072ba4a355a9fa6fbcf1f0e91c567f936703d 100644 (file)
@@ -103,7 +103,7 @@ int connect_to_file_daemon(JCR *jcr, int retry_interval, int max_retry_time,
       }
 
       if (fd == NULL) {
-         set_jcr_job_status(jcr, JS_ErrorTerminated);
+         jcr->setJobStatus(JS_ErrorTerminated);
          return 0;
       }
       Dmsg0(10, "Opened connection with File daemon\n");
@@ -112,10 +112,10 @@ int connect_to_file_daemon(JCR *jcr, int retry_interval, int max_retry_time,
    }
    fd->res = (RES *)jcr->client;      /* save resource in BSOCK */
    jcr->file_bsock = fd;
-   set_jcr_job_status(jcr, JS_Running);
+   jcr->setJobStatus(JS_Running);
 
    if (!authenticate_file_daemon(jcr)) {
-      set_jcr_job_status(jcr, JS_ErrorTerminated);
+      jcr->setJobStatus(JS_ErrorTerminated);
       return 0;
    }
 
@@ -136,7 +136,7 @@ int connect_to_file_daemon(JCR *jcr, int retry_interval, int max_retry_time,
        if (strncmp(fd->msg, OKjob, strlen(OKjob)) != 0) {
           Jmsg(jcr, M_FATAL, 0, _("File daemon \"%s\" rejected Job command: %s\n"),
              jcr->client->hdr.name, fd->msg);
-          set_jcr_job_status(jcr, JS_ErrorTerminated);
+          jcr->setJobStatus(JS_ErrorTerminated);
           return 0;
        } else if (jcr->db) {
           CLIENT_DBR cr;
@@ -154,7 +154,7 @@ int connect_to_file_daemon(JCR *jcr, int retry_interval, int max_retry_time,
    } else {
       Jmsg(jcr, M_FATAL, 0, _("FD gave bad response to JobId command: %s\n"),
          bnet_strerror(fd));
-      set_jcr_job_status(jcr, JS_ErrorTerminated);
+      jcr->setJobStatus(JS_ErrorTerminated);
       return 0;
    }
    return 1;
@@ -246,13 +246,13 @@ void get_level_since_time(JCR *jcr, char *since, int since_len)
          Jmsg(jcr, M_INFO, 0, _("No prior or suitable Full backup found in catalog. Doing FULL backup.\n"));
          bsnprintf(since, since_len, _(" (upgraded from %s)"),
             level_to_str(jcr->getJobLevel()));
-         jcr->set_JobLevel(jcr->jr.JobLevel = L_FULL);
+         jcr->setJobLevel(jcr->jr.JobLevel = L_FULL);
        } else if (do_diff) {
          /* No recent diff job found, so upgrade this one to Diff */
          Jmsg(jcr, M_INFO, 0, _("No prior or suitable Differential backup found in catalog. Doing Differential backup.\n"));
          bsnprintf(since, since_len, _(" (upgraded from %s)"),
             level_to_str(jcr->getJobLevel()));
-         jcr->set_JobLevel(jcr->jr.JobLevel = L_DIFFERENTIAL);
+         jcr->setJobLevel(jcr->jr.JobLevel = L_DIFFERENTIAL);
       } else {
          if (jcr->job->rerun_failed_levels) {
             if (db_find_failed_job_since(jcr, jcr->db, &jcr->jr, jcr->stime, JobLevel)) {
@@ -260,7 +260,7 @@ void get_level_since_time(JCR *jcr, char *since, int since_len)
                   level_to_str(JobLevel));
                bsnprintf(since, since_len, _(" (upgraded from %s)"),
                   level_to_str(jcr->getJobLevel()));
-               jcr->set_JobLevel(jcr->jr.JobLevel = JobLevel);
+               jcr->setJobLevel(jcr->jr.JobLevel = JobLevel);
                jcr->jr.JobId = jcr->JobId;
                break;
             }
@@ -296,24 +296,25 @@ bool send_level_command(JCR *jcr)
    BSOCK   *fd = jcr->file_bsock;
    const char *accurate = jcr->accurate?"accurate_":"";
    const char *not_accurate = "";
+   const char *rerunning = jcr->rerunning?" incomplete ":" ";
    /*
     * Send Level command to File daemon
     */
    switch (jcr->getJobLevel()) {
    case L_BASE:
-      fd->fsend(levelcmd, not_accurate, "base", " ", 0);
+      fd->fsend(levelcmd, not_accurate, "base", rerunning, 0);
       break;
    /* L_NONE is the console, sending something off to the FD */
    case L_NONE:
    case L_FULL:
-      fd->fsend(levelcmd, not_accurate, "full", " ", 0);
+      fd->fsend(levelcmd, not_accurate, "full", rerunning, 0);
       break;
    case L_DIFFERENTIAL:
-      fd->fsend(levelcmd, accurate, "differential", " ", 0);
+      fd->fsend(levelcmd, accurate, "differential", rerunning, 0);
       send_since_time(jcr);
       break;
    case L_INCREMENTAL:
-      fd->fsend(levelcmd, accurate, "incremental", " ", 0);
+      fd->fsend(levelcmd, accurate, "incremental", rerunning, 0);
       send_since_time(jcr);
       break;
    case L_SINCE:
@@ -470,7 +471,7 @@ static bool send_fileset(JCR *jcr)
    return true;
 
 bail_out:
-   set_jcr_job_status(jcr, JS_ErrorTerminated);
+   jcr->setJobStatus(JS_ErrorTerminated);
    return false;
 
 }
@@ -668,15 +669,29 @@ bail_out:
    return 0;
 }
 
+struct OBJ_CTX {
+   JCR *jcr;
+   int count;
+};
+
 static int restore_object_handler(void *ctx, int num_fields, char **row)
 {
-   JCR *jcr = (JCR *)ctx;
+   OBJ_CTX *octx = (OBJ_CTX *)ctx;
+   JCR *jcr = octx->jcr;
    BSOCK *fd;
 
    fd = jcr->file_bsock;
    if (jcr->is_job_canceled()) {
       return 1;
    }
+   /* Old File Daemon doesn't handle restore objects */
+   if (jcr->FDVersion < 3) {
+      Jmsg(jcr, M_WARNING, 0, _("Client \"%s\" may not be used to restore "
+                                "this job. Please upgrade your client.\n"), 
+           jcr->client->name());
+      return 1;
+   }
+
    fd->fsend("restoreobject JobId=%s %s,%s,%s,%s,%s,%s\n",
       row[0], row[1], row[2], row[3], row[4], row[5], row[6]);
 
@@ -696,6 +711,7 @@ static int restore_object_handler(void *ctx, int num_fields, char **row)
                       str_to_uint64(row[1]), /* Object length */
                       &fd->msg, &fd->msglen);
    fd->send();                           /* send object */
+   octx->count++;
 
    if (debug_level) {
       for (int i=0; i < fd->msglen; i++)
@@ -711,11 +727,13 @@ bool send_restore_objects(JCR *jcr)
 {
    POOL_MEM query(PM_MESSAGE);
    BSOCK *fd;
+   OBJ_CTX octx;
 
-// Dmsg0(000, "Enter send_restore_objects\n");
    if (!jcr->JobIds || !jcr->JobIds[0]) {
       return true;
    }
+   octx.jcr = jcr;
+   octx.count = 0;
    Mmsg(query, "SELECT JobId,ObjectLength,ObjectFullLength,ObjectIndex,"
                       "ObjectType,ObjectCompression,FileIndex,ObjectName,"
                       "RestoreObject "
@@ -724,15 +742,20 @@ bool send_restore_objects(JCR *jcr)
               "ORDER BY ObjectIndex ASC", jcr->JobIds);
    
    /* restore_object_handler is called for each file found */
-   db_sql_query(jcr->db, query.c_str(), restore_object_handler, (void *)jcr);
-// Dmsg0(000, "All restore objects sent, looking for OKRestoreObject\n");
-   fd = jcr->file_bsock;
-   fd->fsend("restoreobject end\n");
-   if (!response(jcr, fd, OKRestoreObject, "RestoreObject", DISPLAY_ERROR)) {
-      Jmsg(jcr, M_FATAL, 0, _("RestoreObject failed.\n"));
-      return false;
+   db_sql_query(jcr->db, query.c_str(), restore_object_handler, (void *)&octx);
+
+   /*
+    * Send to FD only if we have at least one restore object.
+    * This permits backward compatibility with older FDs.
+    */
+   if (octx.count > 0) {
+      fd = jcr->file_bsock;
+      fd->fsend("restoreobject end\n");
+      if (!response(jcr, fd, OKRestoreObject, "RestoreObject", DISPLAY_ERROR)) {
+         Jmsg(jcr, M_FATAL, 0, _("RestoreObject failed.\n"));
+         return false;
+      }
    }
-// Dmsg0(000, "got for OKRestoreObject\n");
    return true;
 }
 
@@ -767,7 +790,7 @@ int get_attributes_and_put_in_catalog(JCR *jcr)
       if ((len = sscanf(fd->msg, "%ld %d %s", &file_index, &stream, Digest)) != 3) {
          Jmsg(jcr, M_FATAL, 0, _("<filed: bad attributes, expected 3 fields got %d\n"
 "msglen=%d msg=%s\n"), len, fd->msglen, fd->msg);
-         set_jcr_job_status(jcr, JS_ErrorTerminated);
+         jcr->setJobStatus(JS_ErrorTerminated);
          return 0;
       }
       p = fd->msg;
@@ -846,6 +869,6 @@ int get_attributes_and_put_in_catalog(JCR *jcr)
       }
       jcr->cached_attribute = false; 
    }
-   set_jcr_job_status(jcr, JS_Terminated);
+   jcr->setJobStatus(JS_Terminated);
    return 1;
 }