src/dird/job.c
static void *job_thread(void *arg)
{
   JCR *jcr = (JCR *)arg;

   pthread_detach(pthread_self());
   Dsm_check(100);

   Dmsg0(200, "=====Start Job=========\n");
   jcr->setJobStatus(JS_Running);   /* this will be set only if no error */
   jcr->start_time = time(NULL);      /* set the real start time */
   jcr->jr.StartTime = jcr->start_time;

   if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay <
       (utime_t)(jcr->start_time - jcr->sched_time)) {
      jcr->setJobStatus(JS_Canceled);
      Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
   }

   if (job_check_maxrunschedtime(jcr)) {
      jcr->setJobStatus(JS_Canceled);
      Jmsg(jcr, M_FATAL, 0, _("Job canceled because max run sched time exceeded.\n"));
   }

   /* TODO : check if it is used somewhere */
   if (jcr->job->RunScripts == NULL) {
      Dmsg0(200, "Warning, job->RunScripts is empty\n");
      jcr->job->RunScripts = New(alist(10, not_owned_by_alist));
   }

   if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
      Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
   }

   /* Run any script BeforeJob on dird */
   run_scripts(jcr, jcr->job->RunScripts, "BeforeJob");

   /*
    * We re-update the job start record so that the start
    *  time is set after the run before job.  This avoids
    *  that any files created by the run before job will
    *  be saved twice.  They will be backed up in the current
    *  job, but not in the next one unless they are changed.
    *  Without this, they will be backed up in this job and
    *  in the next job run because in that case, their date
    *   is after the start of this run.
    */
   jcr->start_time = time(NULL);
   jcr->jr.StartTime = jcr->start_time;
   if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
      Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
   }
   generate_plugin_event(jcr, bDirEventJobRun);

   switch (jcr->getJobType()) {
   case JT_BACKUP:
      if (!job_canceled(jcr) && do_backup(jcr)) {
         do_autoprune(jcr);
      } else {
         backup_cleanup(jcr, JS_ErrorTerminated);
      }
      break;
   case JT_VERIFY:
      if (!job_canceled(jcr) && do_verify(jcr)) {
         do_autoprune(jcr);
      } else {
         verify_cleanup(jcr, JS_ErrorTerminated);
      }
      break;
   case JT_RESTORE:
      if (!job_canceled(jcr) && do_restore(jcr)) {
         do_autoprune(jcr);
      } else {
         restore_cleanup(jcr, JS_ErrorTerminated);
      }
      break;
   case JT_ADMIN:
      if (!job_canceled(jcr) && do_admin(jcr)) {
         do_autoprune(jcr);
      } else {
         admin_cleanup(jcr, JS_ErrorTerminated);
      }
      break;
   case JT_COPY:
   case JT_MIGRATE:
      if (!job_canceled(jcr) && do_mac(jcr)) {
         do_autoprune(jcr);
      } else {
         mac_cleanup(jcr, JS_ErrorTerminated, JS_ErrorTerminated);
      }
      break;
   default:
      Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->getJobType());
      break;
   }

   run_scripts(jcr, jcr->job->RunScripts, "AfterJob");

   /* Send off any queued messages */
   if (jcr->msg_queue && jcr->msg_queue->size() > 0) {
      dequeue_messages(jcr);
   }

   generate_daemon_event(jcr, "JobEnd");
   generate_plugin_event(jcr, bDirEventJobEnd);
   Dmsg1(50, "======== End Job stat=%c ==========\n", jcr->JobStatus);
   dequeue_daemon_messages(jcr);
   Dsm_check(100);
   return NULL;
}
/*
 * This is the engine called by jobq.c:jobq_add() when we were pulled
 *  from the work queue.
 *  At this point, we are running in our own thread and all
 *    necessary resources are allocated -- see jobq.c
 */
This is the engine called by jobq.c:jobq_add() when we were pulled
from the work queue.
At this point, we are running in our own thread and all
necessary resources are allocated -- see jobq.c
This is the engine called by jobq . c : jobq_add () when we were pulled from the work queue . At this point we are running in our own thread and all necessary resources are allocated -- see jobq . c
static void *job_thread(void *arg)
{
   JCR *jcr = (JCR *)arg;
   pthread_detach(pthread_self());
   Dsm_check(100);
   Dmsg0(200, "=====Start Job=========\n");
   jcr->setJobStatus(JS_Running);   
   jcr->start_time = time(NULL);      
   jcr->jr.StartTime = jcr->start_time;
   if (jcr->job->MaxStartDelay != 0 && jcr->job->MaxStartDelay <
       (utime_t)(jcr->start_time - jcr->sched_time)) {
      jcr->setJobStatus(JS_Canceled);
      Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
   }
   if (job_check_maxrunschedtime(jcr)) {
      jcr->setJobStatus(JS_Canceled);
      Jmsg(jcr, M_FATAL, 0, _("Job canceled because max run sched time exceeded.\n"));
   }
   if (jcr->job->RunScripts == NULL) {
      Dmsg0(200, "Warning, job->RunScripts is empty\n");
      jcr->job->RunScripts = New(alist(10, not_owned_by_alist));
   }
   if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
      Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
   }
   run_scripts(jcr, jcr->job->RunScripts, "BeforeJob");
   jcr->start_time = time(NULL);
   jcr->jr.StartTime = jcr->start_time;
   if (!db_update_job_start_record(jcr, jcr->db, &jcr->jr)) {
      Jmsg(jcr, M_FATAL, 0, "%s", db_strerror(jcr->db));
   }
   generate_plugin_event(jcr, bDirEventJobRun);
   switch (jcr->getJobType()) {
   case JT_BACKUP:
      if (!job_canceled(jcr) && do_backup(jcr)) {
         do_autoprune(jcr);
      } else {
         backup_cleanup(jcr, JS_ErrorTerminated);
      }
      break;
   case JT_VERIFY:
      if (!job_canceled(jcr) && do_verify(jcr)) {
         do_autoprune(jcr);
      } else {
         verify_cleanup(jcr, JS_ErrorTerminated);
      }
      break;
   case JT_RESTORE:
      if (!job_canceled(jcr) && do_restore(jcr)) {
         do_autoprune(jcr);
      } else {
         restore_cleanup(jcr, JS_ErrorTerminated);
      }
      break;
   case JT_ADMIN:
      if (!job_canceled(jcr) && do_admin(jcr)) {
         do_autoprune(jcr);
      } else {
         admin_cleanup(jcr, JS_ErrorTerminated);
      }
      break;
   case JT_COPY:
   case JT_MIGRATE:
      if (!job_canceled(jcr) && do_mac(jcr)) {
         do_autoprune(jcr);
      } else {
         mac_cleanup(jcr, JS_ErrorTerminated, JS_ErrorTerminated);
      }
      break;
   default:
      Pmsg1(0, _("Unimplemented job type: %d\n"), jcr->getJobType());
      break;
   }
   run_scripts(jcr, jcr->job->RunScripts, "AfterJob");
   if (jcr->msg_queue && jcr->msg_queue->size() > 0) {
      dequeue_messages(jcr);
   }
   generate_daemon_event(jcr, "JobEnd");
   generate_plugin_event(jcr, bDirEventJobEnd);
   Dmsg1(50, "======== End Job stat=%c ==========\n", jcr->JobStatus);
   dequeue_daemon_messages(jcr);
   Dsm_check(100);
   return NULL;
}
static void * job_thread ( void * arg ) { JCR * jcr = ( JCR * ) arg ; pthread_detach ( pthread_self ( ) ) ; Dsm_check ( 100 ) ; Dmsg0 ( 200 , " \n " ) ; jcr -> setJobStatus ( JS_Running ) ; jcr -> start_time = time ( NULL ) ; jcr -> jr . StartTime = jcr -> start_time ; if ( jcr -> job -> MaxStartDelay != 0 && jcr -> job -> MaxStartDelay < ( utime_t ) ( jcr -> start_time - jcr -> sched_time ) ) { jcr -> setJobStatus ( JS_Canceled ) ; Jmsg ( jcr , M_FATAL , 0 , _ ( " \n " ) ) ; } if ( job_check_maxrunschedtime ( jcr ) ) { jcr -> setJobStatus ( JS_Canceled ) ; Jmsg ( jcr , M_FATAL , 0 , _ ( " \n " ) ) ; } if ( jcr -> job -> RunScripts == NULL ) { Dmsg0 ( 200 , " \n " ) ; jcr -> job -> RunScripts = New ( alist ( 10 , not_owned_by_alist ) ) ; } if ( ! db_update_job_start_record ( jcr , jcr -> db , & jcr -> jr ) ) { Jmsg ( jcr , M_FATAL , 0 , " " , db_strerror ( jcr -> db ) ) ; } run_scripts ( jcr , jcr -> job -> RunScripts , " " ) ; jcr -> start_time = time ( NULL ) ; jcr -> jr . StartTime = jcr -> start_time ; if ( ! db_update_job_start_record ( jcr , jcr -> db , & jcr -> jr ) ) { Jmsg ( jcr , M_FATAL , 0 , " " , db_strerror ( jcr -> db ) ) ; } generate_plugin_event ( jcr , bDirEventJobRun ) ; switch ( jcr -> getJobType ( ) ) { case JT_BACKUP : if ( ! job_canceled ( jcr ) && do_backup ( jcr ) ) { do_autoprune ( jcr ) ; } else { backup_cleanup ( jcr , JS_ErrorTerminated ) ; } break ; case JT_VERIFY : if ( ! job_canceled ( jcr ) && do_verify ( jcr ) ) { do_autoprune ( jcr ) ; } else { verify_cleanup ( jcr , JS_ErrorTerminated ) ; } break ; case JT_RESTORE : if ( ! job_canceled ( jcr ) && do_restore ( jcr ) ) { do_autoprune ( jcr ) ; } else { restore_cleanup ( jcr , JS_ErrorTerminated ) ; } break ; case JT_ADMIN : if ( ! job_canceled ( jcr ) && do_admin ( jcr ) ) { do_autoprune ( jcr ) ; } else { admin_cleanup ( jcr , JS_ErrorTerminated ) ; } break ; case JT_COPY : case JT_MIGRATE : if ( ! job_canceled ( jcr ) && do_mac ( jcr ) ) { do_autoprune ( jcr ) ; } else { mac_cleanup ( jcr , JS_ErrorTerminated , JS_ErrorTerminated ) ; } break ; default : Pmsg1 ( 0 , _ ( " \n " ) , jcr -> getJobType ( ) ) ; break ; } run_scripts ( jcr , jcr -> job -> RunScripts , " " ) ; if ( jcr -> msg_queue && jcr -> msg_queue -> size ( ) > 0 ) { dequeue_messages ( jcr ) ; } generate_daemon_event ( jcr , " " ) ; generate_plugin_event ( jcr , bDirEventJobEnd ) ; Dmsg1 ( 50 , " \n " , jcr -> JobStatus ) ; dequeue_daemon_messages ( jcr ) ; Dsm_check ( 100 ) ; return NULL ; }
This is the engine called by jobq.c:jobq_add() when we were pulled
  from the work queue.
This is the engine called by jobq . c : jobq_add () when we were pulled from the work queue .
/* this will be set only if no error */ /* set the real start time */ /* TODO : check if it is used somewhere */ /* Run any script BeforeJob on dird */ /*
    * We re-update the job start record so that the start
    *  time is set after the run before job.  This avoids
    *  that any files created by the run before job will
    *  be saved twice.  They will be backed up in the current
    *  job, but not in the next one unless they are changed.
    *  Without this, they will be backed up in this job and
    *  in the next job run because in that case, their date
    *   is after the start of this run.
    */ /* Send off any queued messages */