src/dird/backup.c
int wait_for_job_termination(JCR *jcr, int timeout)
{
   int32_t n = 0;
   BSOCK *fd = jcr->file_bsock;
   bool fd_ok = false;
   uint32_t JobFiles, JobErrors;
   uint32_t JobWarnings = 0;
   uint64_t ReadBytes = 0;
   uint64_t JobBytes = 0;
   uint64_t CommBytes = 0;
   uint64_t CommCompressedBytes = 0;
   int VSS = 0;                 /* or Snapshot on Unix */
   int Encrypt = 0;
   btimer_t *tid=NULL;

   if (fd) {
      if (timeout) {
         tid = start_bsock_timer(fd, timeout); /* TODO: New timeout directive??? */
      }
      /* Wait for Client to terminate */
      while ((n = bget_dirmsg(fd)) >= 0) {
         if (!fd_ok &&
             (sscanf(fd->msg, newEndJob, &jcr->FDJobStatus, &JobFiles,
                     &ReadBytes, &JobBytes, &JobErrors, &VSS, &Encrypt,
                     &CommBytes, &CommCompressedBytes) == 9 ||
              sscanf(fd->msg, EndJob, &jcr->FDJobStatus, &JobFiles,
                     &ReadBytes, &JobBytes, &JobErrors, &VSS, &Encrypt) == 7 ||
              sscanf(fd->msg, OldEndJob, &jcr->FDJobStatus, &JobFiles,
                     &ReadBytes, &JobBytes, &JobErrors) == 5)) {
            fd_ok = true;
            jcr->setJobStatus(jcr->FDJobStatus);
            Dmsg1(100, "FDStatus=%c\n", (char)jcr->JobStatus);
         } else {
            Jmsg(jcr, M_WARNING, 0, _("Unexpected Client Job message: %s\n"),
                 fd->msg);
         }
         if (job_canceled(jcr)) {
            break;
         }
      }
      if (tid) {
         stop_bsock_timer(tid);
      }

      if (fd->is_error() && jcr->getJobStatus() != JS_Canceled) {
         int i = 0;
         Jmsg(jcr, M_FATAL, 0, _("Network error with FD during %s: ERR=%s\n"),
              job_type_to_str(jcr->getJobType()), fd->bstrerror());
         while (i++ < 20 && jcr->job->RescheduleIncompleteJobs && jcr->is_canceled()) {
            bmicrosleep(3, 0);
         }
      }
      fd->signal(BNET_TERMINATE);   /* tell Client we are terminating */
   }

   /*
    * Force cancel in SD if failing, but not for Incomplete jobs
    *  so that we let the SD despool.
    */
   Dmsg5(100, "cancel=%d fd_ok=%d FDJS=%d JS=%d SDJS=%d\n", jcr->is_canceled(), fd_ok, jcr->FDJobStatus,
        jcr->JobStatus, jcr->SDJobStatus);
   if (jcr->is_canceled() || (!jcr->job->RescheduleIncompleteJobs && !fd_ok)) {
      Dmsg4(100, "fd_ok=%d FDJS=%d JS=%d SDJS=%d\n", fd_ok, jcr->FDJobStatus,
           jcr->JobStatus, jcr->SDJobStatus);
      cancel_storage_daemon_job(jcr);
   }

   /* Note, the SD stores in jcr->JobFiles/ReadBytes/JobBytes/JobErrors */
   wait_for_storage_daemon_termination(jcr);

   /* Return values from FD */
   if (fd_ok) {
      jcr->JobFiles = JobFiles;
      jcr->JobErrors += JobErrors;       /* Keep total errors */
      jcr->ReadBytes = ReadBytes;
      jcr->JobBytes = JobBytes;
      jcr->JobWarnings = JobWarnings;
      jcr->CommBytes = CommBytes;
      jcr->CommCompressedBytes = CommCompressedBytes;
      jcr->Snapshot = VSS;
      jcr->Encrypt = Encrypt;
   } else if (jcr->getJobStatus() != JS_Canceled) {
      Jmsg(jcr, M_FATAL, 0, _("No Job status returned from FD.\n"));
   }

   /* Return the first error status we find Dir, FD, or SD */
   if (!fd_ok || fd->is_error()) { /* if fd not set, that use !fd_ok */
      if (jcr->getJobStatus() == JS_Canceled) {
         jcr->FDJobStatus = JS_Canceled;
      } else {
         jcr->FDJobStatus = JS_ErrorTerminated;
      }
   }
   if (jcr->JobStatus != JS_Terminated) {
      return jcr->JobStatus;
   }
   if (jcr->FDJobStatus != JS_Terminated) {
      return jcr->FDJobStatus;
   }
   return jcr->SDJobStatus;
}
/*
 * Here we wait for the File daemon to signal termination,
 *   then we wait for the Storage daemon.  When both
 *   are done, we return the job status.
 * Also used by restore.c
 */
Here we wait for the File daemon to signal termination,
then we wait for the Storage daemon.  When both
are done, we return the job status.
Here we wait for the File daemon to signal termination then we wait for the Storage daemon . When both are done we return the job status .
int wait_for_job_termination(JCR *jcr, int timeout)
{
   int32_t n = 0;
   BSOCK *fd = jcr->file_bsock;
   bool fd_ok = false;
   uint32_t JobFiles, JobErrors;
   uint32_t JobWarnings = 0;
   uint64_t ReadBytes = 0;
   uint64_t JobBytes = 0;
   uint64_t CommBytes = 0;
   uint64_t CommCompressedBytes = 0;
   int VSS = 0;                 
   int Encrypt = 0;
   btimer_t *tid=NULL;
   if (fd) {
      if (timeout) {
         tid = start_bsock_timer(fd, timeout); 
      }
      while ((n = bget_dirmsg(fd)) >= 0) {
         if (!fd_ok &&
             (sscanf(fd->msg, newEndJob, &jcr->FDJobStatus, &JobFiles,
                     &ReadBytes, &JobBytes, &JobErrors, &VSS, &Encrypt,
                     &CommBytes, &CommCompressedBytes) == 9 ||
              sscanf(fd->msg, EndJob, &jcr->FDJobStatus, &JobFiles,
                     &ReadBytes, &JobBytes, &JobErrors, &VSS, &Encrypt) == 7 ||
              sscanf(fd->msg, OldEndJob, &jcr->FDJobStatus, &JobFiles,
                     &ReadBytes, &JobBytes, &JobErrors) == 5)) {
            fd_ok = true;
            jcr->setJobStatus(jcr->FDJobStatus);
            Dmsg1(100, "FDStatus=%c\n", (char)jcr->JobStatus);
         } else {
            Jmsg(jcr, M_WARNING, 0, _("Unexpected Client Job message: %s\n"),
                 fd->msg);
         }
         if (job_canceled(jcr)) {
            break;
         }
      }
      if (tid) {
         stop_bsock_timer(tid);
      }
      if (fd->is_error() && jcr->getJobStatus() != JS_Canceled) {
         int i = 0;
         Jmsg(jcr, M_FATAL, 0, _("Network error with FD during %s: ERR=%s\n"),
              job_type_to_str(jcr->getJobType()), fd->bstrerror());
         while (i++ < 20 && jcr->job->RescheduleIncompleteJobs && jcr->is_canceled()) {
            bmicrosleep(3, 0);
         }
      }
      fd->signal(BNET_TERMINATE);   
   }
   Dmsg5(100, "cancel=%d fd_ok=%d FDJS=%d JS=%d SDJS=%d\n", jcr->is_canceled(), fd_ok, jcr->FDJobStatus,
        jcr->JobStatus, jcr->SDJobStatus);
   if (jcr->is_canceled() || (!jcr->job->RescheduleIncompleteJobs && !fd_ok)) {
      Dmsg4(100, "fd_ok=%d FDJS=%d JS=%d SDJS=%d\n", fd_ok, jcr->FDJobStatus,
           jcr->JobStatus, jcr->SDJobStatus);
      cancel_storage_daemon_job(jcr);
   }
   wait_for_storage_daemon_termination(jcr);
   if (fd_ok) {
      jcr->JobFiles = JobFiles;
      jcr->JobErrors += JobErrors;       
      jcr->ReadBytes = ReadBytes;
      jcr->JobBytes = JobBytes;
      jcr->JobWarnings = JobWarnings;
      jcr->CommBytes = CommBytes;
      jcr->CommCompressedBytes = CommCompressedBytes;
      jcr->Snapshot = VSS;
      jcr->Encrypt = Encrypt;
   } else if (jcr->getJobStatus() != JS_Canceled) {
      Jmsg(jcr, M_FATAL, 0, _("No Job status returned from FD.\n"));
   }
   if (!fd_ok || fd->is_error()) { 
      if (jcr->getJobStatus() == JS_Canceled) {
         jcr->FDJobStatus = JS_Canceled;
      } else {
         jcr->FDJobStatus = JS_ErrorTerminated;
      }
   }
   if (jcr->JobStatus != JS_Terminated) {
      return jcr->JobStatus;
   }
   if (jcr->FDJobStatus != JS_Terminated) {
      return jcr->FDJobStatus;
   }
   return jcr->SDJobStatus;
}
int wait_for_job_termination ( JCR * jcr , int timeout ) { int32_t n = 0 ; BSOCK * fd = jcr -> file_bsock ; bool fd_ok = false ; uint32_t JobFiles , JobErrors ; uint32_t JobWarnings = 0 ; uint64_t ReadBytes = 0 ; uint64_t JobBytes = 0 ; uint64_t CommBytes = 0 ; uint64_t CommCompressedBytes = 0 ; int VSS = 0 ; int Encrypt = 0 ; btimer_t * tid = NULL ; if ( fd ) { if ( timeout ) { tid = start_bsock_timer ( fd , timeout ) ; } while ( ( n = bget_dirmsg ( fd ) ) >= 0 ) { if ( ! fd_ok && ( sscanf ( fd -> msg , newEndJob , & jcr -> FDJobStatus , & JobFiles , & ReadBytes , & JobBytes , & JobErrors , & VSS , & Encrypt , & CommBytes , & CommCompressedBytes ) == 9 || sscanf ( fd -> msg , EndJob , & jcr -> FDJobStatus , & JobFiles , & ReadBytes , & JobBytes , & JobErrors , & VSS , & Encrypt ) == 7 || sscanf ( fd -> msg , OldEndJob , & jcr -> FDJobStatus , & JobFiles , & ReadBytes , & JobBytes , & JobErrors ) == 5 ) ) { fd_ok = true ; jcr -> setJobStatus ( jcr -> FDJobStatus ) ; Dmsg1 ( 100 , " \n " , ( char ) jcr -> JobStatus ) ; } else { Jmsg ( jcr , M_WARNING , 0 , _ ( " \n " ) , fd -> msg ) ; } if ( job_canceled ( jcr ) ) { break ; } } if ( tid ) { stop_bsock_timer ( tid ) ; } if ( fd -> is_error ( ) && jcr -> getJobStatus ( ) != JS_Canceled ) { int i = 0 ; Jmsg ( jcr , M_FATAL , 0 , _ ( " \n " ) , job_type_to_str ( jcr -> getJobType ( ) ) , fd -> bstrerror ( ) ) ; while ( i ++ < 20 && jcr -> job -> RescheduleIncompleteJobs && jcr -> is_canceled ( ) ) { bmicrosleep ( 3 , 0 ) ; } } fd -> signal ( BNET_TERMINATE ) ; } Dmsg5 ( 100 , " \n " , jcr -> is_canceled ( ) , fd_ok , jcr -> FDJobStatus , jcr -> JobStatus , jcr -> SDJobStatus ) ; if ( jcr -> is_canceled ( ) || ( ! jcr -> job -> RescheduleIncompleteJobs && ! fd_ok ) ) { Dmsg4 ( 100 , " \n " , fd_ok , jcr -> FDJobStatus , jcr -> JobStatus , jcr -> SDJobStatus ) ; cancel_storage_daemon_job ( jcr ) ; } wait_for_storage_daemon_termination ( jcr ) ; if ( fd_ok ) { jcr -> JobFiles = JobFiles ; jcr -> JobErrors += JobErrors ; jcr -> ReadBytes = ReadBytes ; jcr -> JobBytes = JobBytes ; jcr -> JobWarnings = JobWarnings ; jcr -> CommBytes = CommBytes ; jcr -> CommCompressedBytes = CommCompressedBytes ; jcr -> Snapshot = VSS ; jcr -> Encrypt = Encrypt ; } else if ( jcr -> getJobStatus ( ) != JS_Canceled ) { Jmsg ( jcr , M_FATAL , 0 , _ ( " \n " ) ) ; } if ( ! fd_ok || fd -> is_error ( ) ) { if ( jcr -> getJobStatus ( ) == JS_Canceled ) { jcr -> FDJobStatus = JS_Canceled ; } else { jcr -> FDJobStatus = JS_ErrorTerminated ; } } if ( jcr -> JobStatus != JS_Terminated ) { return jcr -> JobStatus ; } if ( jcr -> FDJobStatus != JS_Terminated ) { return jcr -> FDJobStatus ; } return jcr -> SDJobStatus ; }
Here we wait for the File daemon to signal termination,
   then we wait for the Storage daemon.
Here we wait for the File daemon to signal termination then we wait for the Storage daemon .
/* or Snapshot on Unix */ /* TODO: New timeout directive??? */ /* Wait for Client to terminate */ /* tell Client we are terminating */ /*
    * Force cancel in SD if failing, but not for Incomplete jobs
    *  so that we let the SD despool.
    */ /* Note, the SD stores in jcr->JobFiles/ReadBytes/JobBytes/JobErrors */ /* Return values from FD */ /* Keep total errors */ /* Return the first error status we find Dir, FD, or SD */ /* if fd not set, that use !fd_ok */