src/filed/job.c
static int level_cmd(JCR *jcr)
{
   BSOCK *dir = jcr->dir_bsock;
   POOLMEM *level, *buf = NULL;
   int mtime_only;

   level = get_memory(dir->msglen+1);
   Dmsg1(10, "level_cmd: %s", dir->msg);

   /* keep compatibility with older directors */
   if (strstr(dir->msg, "accurate")) {
      jcr->accurate = true;
   }
   if (strstr(dir->msg, "rerunning")) {
      jcr->rerunning = true;
   }
   if (sscanf(dir->msg, "level = %s ", level) != 1) {
      goto bail_out;
   }
   /* Base backup requested? */
   if (strcasecmp(level, "base") == 0) {
      jcr->setJobLevel(L_BASE);
   /* Full backup requested? */
   } else if (strcasecmp(level, "full") == 0) {
      jcr->setJobLevel(L_FULL);
   } else if (strstr(level, "differential")) {
      jcr->setJobLevel(L_DIFFERENTIAL);
      free_memory(level);
      return 1;
   } else if (strstr(level, "incremental")) {
      jcr->setJobLevel(L_INCREMENTAL);
      free_memory(level);
      return 1;
   /*
    * We get his UTC since time, then sync the clocks and correct it
    *   to agree with our clock.
    */
   } else if (strcasecmp(level, "since_utime") == 0) {
      buf = get_memory(dir->msglen+1);
      utime_t since_time, adj;
      btime_t his_time, bt_start, rt=0, bt_adj=0, his_time_prev=0, n=0;
      if (jcr->getJobLevel() == L_NONE) {
         jcr->setJobLevel(L_SINCE);     /* if no other job level set, do it now */
      }
      if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d prev_job=%127s",
                 buf, &mtime_only, jcr->PrevJob) != 3) {
         if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d",
                    buf, &mtime_only) != 2) {
            goto bail_out;
         }
      }
      since_time = str_to_uint64(buf);  /* this is the since time */
      Dmsg2(100, "since_time=%lld prev_job=%s\n", since_time, jcr->PrevJob);
      char ed1[50], ed2[50];
      /*
       * Sync clocks by polling him for the time. We take
       *   10 samples of his time throwing out the first two.
       */
      for (int i=0; i<10; i++) {
         bt_start = get_current_btime();
         dir->signal(BNET_BTIME);     /* poll for time */
         if (dir->recv() <= 0) {      /* get response */
            goto bail_out;
         }
         if (sscanf(dir->msg, "btime %s", buf) != 1) {
            goto bail_out;
         }
         his_time = str_to_uint64(buf);
         rt = get_current_btime() - bt_start; /* compute round trip time */
         /* skip first two results and check for leap second */
         /* if any of the FD or DIR went back in time, skip this iteration */
         if (i < 2 || (his_time_prev > 0 && his_time < his_time_prev) || rt<0) {
            his_time_prev = his_time;
            continue;
         }
         his_time_prev = his_time;
         n++;
         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));
      }
      adj = 0;
      if (n > 0) { /* Should be 1 in the worst case */
         bt_adj = bt_adj / n;            /* compute average time */
         Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2));
         adj = btime_to_utime(bt_adj);
         since_time += adj;              /* adjust for clock difference */
      }
      /* Don't notify if time within 3 seconds */
      if (adj > 3 || adj < -3) {
         int type;
         if (adj > 600 || adj < -600) {
            type = M_WARNING;
         } else {
            type = M_INFO;
         }
         Jmsg(jcr, type, 0, _("DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n"), adj);
      }
      dir->signal(BNET_EOD);

      Dmsg2(100, "adj=%lld since_time=%lld\n", adj, since_time);
      jcr->incremental = 1;           /* set incremental or decremental backup */
      jcr->mtime = since_time;        /* set since time */
      generate_plugin_event(jcr, bEventSince, (void *)(time_t)jcr->mtime);
   } else {
      Jmsg1(jcr, M_FATAL, 0, _("Unknown backup level: %s\n"), level);
      free_memory(level);
      return 0;
   }
   free_memory(level);
   if (buf) {
      free_memory(buf);
   }
   generate_plugin_event(jcr, bEventLevel, (void*)(intptr_t)jcr->getJobLevel());
   return dir->fsend(OKlevel);

bail_out:
   pm_strcpy(jcr->errmsg, dir->msg);
   Jmsg1(jcr, M_FATAL, 0, _("Bad level command: %s\n"), jcr->errmsg);
   free_memory(level);
   if (buf) {
      free_memory(buf);
   }
   return 0;
}
/**
 * Get backup level from Director
 *
 * Note: there are odd things such as accurate_differential,
 *  and accurate_incremental that are passed in level, thus
 *  the calls to strstr() below.
 *
 */
Get backup level from Director
Note: there are odd things such as accurate_differential,
and accurate_incremental that are passed in level, thus
the calls to strstr() below.
Get backup level from Director Note : there are odd things such as accurate_differential and accurate_incremental that are passed in level thus the calls to strstr () below .
static int level_cmd(JCR *jcr)
{
   BSOCK *dir = jcr->dir_bsock;
   POOLMEM *level, *buf = NULL;
   int mtime_only;
   level = get_memory(dir->msglen+1);
   Dmsg1(10, "level_cmd: %s", dir->msg);
   if (strstr(dir->msg, "accurate")) {
      jcr->accurate = true;
   }
   if (strstr(dir->msg, "rerunning")) {
      jcr->rerunning = true;
   }
   if (sscanf(dir->msg, "level = %s ", level) != 1) {
      goto bail_out;
   }
   if (strcasecmp(level, "base") == 0) {
      jcr->setJobLevel(L_BASE);
   } else if (strcasecmp(level, "full") == 0) {
      jcr->setJobLevel(L_FULL);
   } else if (strstr(level, "differential")) {
      jcr->setJobLevel(L_DIFFERENTIAL);
      free_memory(level);
      return 1;
   } else if (strstr(level, "incremental")) {
      jcr->setJobLevel(L_INCREMENTAL);
      free_memory(level);
      return 1;
   } else if (strcasecmp(level, "since_utime") == 0) {
      buf = get_memory(dir->msglen+1);
      utime_t since_time, adj;
      btime_t his_time, bt_start, rt=0, bt_adj=0, his_time_prev=0, n=0;
      if (jcr->getJobLevel() == L_NONE) {
         jcr->setJobLevel(L_SINCE);     
      }
      if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d prev_job=%127s",
                 buf, &mtime_only, jcr->PrevJob) != 3) {
         if (sscanf(dir->msg, "level = since_utime %s mtime_only=%d",
                    buf, &mtime_only) != 2) {
            goto bail_out;
         }
      }
      since_time = str_to_uint64(buf);  
      Dmsg2(100, "since_time=%lld prev_job=%s\n", since_time, jcr->PrevJob);
      char ed1[50], ed2[50];
      for (int i=0; i<10; i++) {
         bt_start = get_current_btime();
         dir->signal(BNET_BTIME);     
         if (dir->recv() <= 0) {      
            goto bail_out;
         }
         if (sscanf(dir->msg, "btime %s", buf) != 1) {
            goto bail_out;
         }
         his_time = str_to_uint64(buf);
         rt = get_current_btime() - bt_start; 
         if (i < 2 || (his_time_prev > 0 && his_time < his_time_prev) || rt<0) {
            his_time_prev = his_time;
            continue;
         }
         his_time_prev = his_time;
         n++;
         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));
      }
      adj = 0;
      if (n > 0) { 
         bt_adj = bt_adj / n;            
         Dmsg2(100, "rt=%s adj=%s\n", edit_uint64(rt, ed1), edit_uint64(bt_adj, ed2));
         adj = btime_to_utime(bt_adj);
         since_time += adj;              
      }
      if (adj > 3 || adj < -3) {
         int type;
         if (adj > 600 || adj < -600) {
            type = M_WARNING;
         } else {
            type = M_INFO;
         }
         Jmsg(jcr, type, 0, _("DIR and FD clocks differ by %lld seconds, FD automatically compensating.\n"), adj);
      }
      dir->signal(BNET_EOD);
      Dmsg2(100, "adj=%lld since_time=%lld\n", adj, since_time);
      jcr->incremental = 1;           
      jcr->mtime = since_time;        
      generate_plugin_event(jcr, bEventSince, (void *)(time_t)jcr->mtime);
   } else {
      Jmsg1(jcr, M_FATAL, 0, _("Unknown backup level: %s\n"), level);
      free_memory(level);
      return 0;
   }
   free_memory(level);
   if (buf) {
      free_memory(buf);
   }
   generate_plugin_event(jcr, bEventLevel, (void*)(intptr_t)jcr->getJobLevel());
   return dir->fsend(OKlevel);
bail_out:
   pm_strcpy(jcr->errmsg, dir->msg);
   Jmsg1(jcr, M_FATAL, 0, _("Bad level command: %s\n"), jcr->errmsg);
   free_memory(level);
   if (buf) {
      free_memory(buf);
   }
   return 0;
}
static int level_cmd ( JCR * jcr ) { BSOCK * dir = jcr -> dir_bsock ; POOLMEM * level , * buf = NULL ; int mtime_only ; level = get_memory ( dir -> msglen + 1 ) ; Dmsg1 ( 10 , " " , dir -> msg ) ; if ( strstr ( dir -> msg , " " ) ) { jcr -> accurate = true ; } if ( strstr ( dir -> msg , " " ) ) { jcr -> rerunning = true ; } if ( sscanf ( dir -> msg , " " , level ) != 1 ) { goto bail_out ; } if ( strcasecmp ( level , " " ) == 0 ) { jcr -> setJobLevel ( L_BASE ) ; } else if ( strcasecmp ( level , " " ) == 0 ) { jcr -> setJobLevel ( L_FULL ) ; } else if ( strstr ( level , " " ) ) { jcr -> setJobLevel ( L_DIFFERENTIAL ) ; free_memory ( level ) ; return 1 ; } else if ( strstr ( level , " " ) ) { jcr -> setJobLevel ( L_INCREMENTAL ) ; free_memory ( level ) ; return 1 ; } else if ( strcasecmp ( level , " " ) == 0 ) { buf = get_memory ( dir -> msglen + 1 ) ; utime_t since_time , adj ; btime_t his_time , bt_start , rt = 0 , bt_adj = 0 , his_time_prev = 0 , n = 0 ; if ( jcr -> getJobLevel ( ) == L_NONE ) { jcr -> setJobLevel ( L_SINCE ) ; } if ( sscanf ( dir -> msg , " " , buf , & mtime_only , jcr -> PrevJob ) != 3 ) { if ( sscanf ( dir -> msg , " " , buf , & mtime_only ) != 2 ) { goto bail_out ; } } since_time = str_to_uint64 ( buf ) ; Dmsg2 ( 100 , " \n " , since_time , jcr -> PrevJob ) ; char ed1 [ 50 ] , ed2 [ 50 ] ; for ( int i = 0 ; i < 10 ; i ++ ) { bt_start = get_current_btime ( ) ; dir -> signal ( BNET_BTIME ) ; if ( dir -> recv ( ) <= 0 ) { goto bail_out ; } if ( sscanf ( dir -> msg , " " , buf ) != 1 ) { goto bail_out ; } his_time = str_to_uint64 ( buf ) ; rt = get_current_btime ( ) - bt_start ; if ( i < 2 || ( his_time_prev > 0 && his_time < his_time_prev ) || rt < 0 ) { his_time_prev = his_time ; continue ; } his_time_prev = his_time ; n ++ ; Dmsg2 ( 100 , " \n " , edit_uint64 ( his_time , ed1 ) , edit_uint64 ( bt_start , ed2 ) ) ; bt_adj += bt_start - his_time - rt / 2 ; Dmsg2 ( 100 , " \n " , edit_uint64 ( rt , ed1 ) , edit_uint64 ( bt_adj , ed2 ) ) ; } adj = 0 ; if ( n > 0 ) { bt_adj = bt_adj / n ; Dmsg2 ( 100 , " \n " , edit_uint64 ( rt , ed1 ) , edit_uint64 ( bt_adj , ed2 ) ) ; adj = btime_to_utime ( bt_adj ) ; since_time += adj ; } if ( adj > 3 || adj < -3 ) { int type ; if ( adj > 600 || adj < -600 ) { type = M_WARNING ; } else { type = M_INFO ; } Jmsg ( jcr , type , 0 , _ ( " \n " ) , adj ) ; } dir -> signal ( BNET_EOD ) ; Dmsg2 ( 100 , " \n " , adj , since_time ) ; jcr -> incremental = 1 ; jcr -> mtime = since_time ; generate_plugin_event ( jcr , bEventSince , ( void * ) ( time_t ) jcr -> mtime ) ; } else { Jmsg1 ( jcr , M_FATAL , 0 , _ ( " \n " ) , level ) ; free_memory ( level ) ; return 0 ; } free_memory ( level ) ; if ( buf ) { free_memory ( buf ) ; } generate_plugin_event ( jcr , bEventLevel , ( void * ) ( intptr_t ) jcr -> getJobLevel ( ) ) ; return dir -> fsend ( OKlevel ) ; bail_out : pm_strcpy ( jcr -> errmsg , dir -> msg ) ; Jmsg1 ( jcr , M_FATAL , 0 , _ ( " \n " ) , jcr -> errmsg ) ; free_memory ( level ) ; if ( buf ) { free_memory ( buf ) ; } return 0 ; }
Get backup level from Director
 Note: there are odd things such as accurate_differential,
  and accurate_incremental that are passed in level, thus
  the calls to strstr() below.
Get backup level from Director Note : there are odd things such as accurate_differential and accurate_incremental that are passed in level thus the calls to strstr () below .
/* keep compatibility with older directors */ /* Base backup requested? */ /* Full backup requested? */ /*
    * We get his UTC since time, then sync the clocks and correct it
    *   to agree with our clock.
    */ /* if no other job level set, do it now */ /* this is the since time */ /*
       * Sync clocks by polling him for the time. We take
       *   10 samples of his time throwing out the first two.
       */ /* poll for time */ /* get response */ /* compute round trip time */ /* skip first two results and check for leap second */ /* if any of the FD or DIR went back in time, skip this iteration */ /* Should be 1 in the worst case */ /* compute average time */ /* adjust for clock difference */ /* Don't notify if time within 3 seconds */ /* set incremental or decremental backup */ /* set since time */