src/dird/mac.c
bool do_mac_init(JCR *jcr)
{
   POOL *pool = NULL;
   JOB *job, *prev_job;
   JCR *wjcr;                     /* jcr of writing job */
   int count;


   apply_pool_overrides(jcr);

   if (!allow_duplicate_job(jcr)) {
      return false;
   }

   jcr->jr.PoolId = get_or_create_pool_record(jcr, jcr->pool->name());
   if (jcr->jr.PoolId == 0) {
      Dmsg1(dbglevel, "JobId=%d no PoolId\n", (int)jcr->JobId);
      Jmsg(jcr, M_FATAL, 0, _("Could not get or create a Pool record.\n"));
      return false;
   }
   /*
    * Note, at this point, pool is the pool for this job.  We
    *  transfer it to rpool (read pool), and a bit later,
    *  pool will be changed to point to the write pool,
    *  which comes from pool->NextPool.
    */
   jcr->rpool = jcr->pool;            /* save read pool */
   pm_strcpy(jcr->rpool_source, jcr->pool_source);
   Dmsg2(dbglevel, "Read pool=%s (From %s)\n", jcr->rpool->name(), jcr->rpool_source);

   if (!get_or_create_fileset_record(jcr)) {
      Dmsg1(dbglevel, "JobId=%d no FileSet\n", (int)jcr->JobId);
      Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n"));
      return false;
   }

   /* If we find a job or jobs to migrate it is previous_jr.JobId */
   count = getJob_to_migrate(jcr);
   if (count < 0) {
      return false;
   }
   if (count == 0) {
      set_mac_next_pool(jcr, &pool);
      return true;                    /* no work */
   }

   Dmsg1(dbglevel, "Back from getJob_to_migrate JobId=%d\n", (int)jcr->JobId);

   if (jcr->previous_jr.JobId == 0) {
      Dmsg1(dbglevel, "JobId=%d no previous JobId\n", (int)jcr->JobId);
      Jmsg(jcr, M_INFO, 0, _("No previous Job found to %s.\n"), jcr->get_ActionName(0));
      set_mac_next_pool(jcr, &pool);
      return true;                    /* no work */
   }

   if (create_restore_bootstrap_file(jcr) < 0) {
      Jmsg(jcr, M_FATAL, 0, _("Create bootstrap file failed.\n"));
      return false;
   }

   if (jcr->previous_jr.JobId == 0 || jcr->ExpectedFiles == 0) {
      jcr->setJobStatus(JS_Terminated);
      Dmsg1(dbglevel, "JobId=%d expected files == 0\n", (int)jcr->JobId);
      if (jcr->previous_jr.JobId == 0) {
         Jmsg(jcr, M_INFO, 0, _("No previous Job found to %s.\n"), jcr->get_ActionName(0));
      } else {
         Jmsg(jcr, M_INFO, 0, _("Previous Job has no data to %s.\n"), jcr->get_ActionName(0));
      }
      set_mac_next_pool(jcr, &pool);
      return true;                    /* no work */
   }


   Dmsg5(dbglevel, "JobId=%d: Current: Name=%s JobId=%d Type=%c Level=%c\n",
      (int)jcr->JobId,
      jcr->jr.Name, (int)jcr->jr.JobId,
      jcr->jr.JobType, jcr->jr.JobLevel);

   LockRes();
   job = (JOB *)GetResWithName(R_JOB, jcr->jr.Name);
   prev_job = (JOB *)GetResWithName(R_JOB, jcr->previous_jr.Name);
   UnlockRes();
   if (!job) {
      Jmsg(jcr, M_FATAL, 0, _("Job resource not found for \"%s\".\n"), jcr->jr.Name);
      return false;
   }
   if (!prev_job) {
      Jmsg(jcr, M_FATAL, 0, _("Previous Job resource not found for \"%s\".\n"),
           jcr->previous_jr.Name);
      return false;
   }


   /* Create a write jcr */
   wjcr = jcr->wjcr = new_jcr(sizeof(JCR), dird_free_jcr);
   memcpy(&wjcr->previous_jr, &jcr->previous_jr, sizeof(wjcr->previous_jr));

   /*
    * Turn the wjcr into a "real" job that takes on the aspects of
    *   the previous backup job "prev_job".
    */
   set_jcr_defaults(wjcr, prev_job);
   /* fix MA 987 cannot copy/migrate jobs with a Level=VF in the job resource
    * If the prev_job level definition is VirtualFull,
    * change it to Incremental, otherwise the writing SD would do a VF
    */
   if (wjcr->getJobLevel() == L_VIRTUAL_FULL) {
      wjcr->setJobLevel(L_INCREMENTAL);
   }

   /* Don't check for duplicates on this jobs. We do it before setup_job(),
    * because we check allow_duplicate_job() here.
    */
   wjcr->IgnoreDuplicateJobChecking = true;

   if (!setup_job(wjcr)) {
      Jmsg(jcr, M_FATAL, 0, _("setup job failed.\n"));
      return false;
   }

   /* Now reset the job record from the previous job */
   memcpy(&wjcr->jr, &jcr->previous_jr, sizeof(wjcr->jr));
   /* Update the jr to reflect the new values of PoolId and JobId. */
   wjcr->jr.PoolId = jcr->jr.PoolId;
   wjcr->jr.JobId = wjcr->JobId;
   wjcr->sd_client = true;
   //wjcr->setJobType(jcr->getJobType());
   wjcr->setJobLevel(jcr->getJobLevel());
   wjcr->spool_data = job->spool_data;     /* turn on spooling if requested in job */
   wjcr->spool_size = jcr->spool_size;
   jcr->spool_size = 0;

   /* Don't let WatchDog checks Max*Time value on this Job */
   wjcr->no_maxtime = true;
   Dmsg4(dbglevel, "wjcr: Name=%s JobId=%d Type=%c Level=%c\n",
      wjcr->jr.Name, (int)wjcr->jr.JobId,
      wjcr->jr.JobType, wjcr->jr.JobLevel);

   if (set_mac_next_pool(jcr, &pool)) {
      /* If pool storage specified, use it for restore */
      copy_rstorage(wjcr, pool->storage, _("Pool resource"));
      copy_rstorage(jcr, pool->storage, _("Pool resource"));

      wjcr->pool = jcr->pool;
      wjcr->next_pool = jcr->next_pool;
      wjcr->jr.PoolId = jcr->jr.PoolId;
   }

   return true;
}
/*
 * Called here before the job is run to do the job
 *   specific setup.  Note, one of the important things to
 *   complete in this init code is to make the definitive
 *   choice of input and output storage devices.  This is
 *   because immediately after the init, the job is queued
 *   in the jobq.c code, and it checks that all the resources
 *   (storage resources in particular) are available, so these
 *   must all be properly defined.
 *
 *  previous_jr refers to the job DB record of the Job that is
 *    going to be migrated.
 *  prev_job refers to the job resource of the Job that is
 *    going to be migrated.
 *  jcr is the jcr for the current "migration" job.  It is a
 *    control job that is put in the DB as a migration job, which
 *    means that this job migrated a previous job to a new job.
 *    No Volume or File data is associated with this control
 *    job.
 *  wjcr refers to the migrate/copy job that is writing and is run by
 *    the current jcr.  It is a backup job that writes the
 *    data written for the previous_jr into the new pool.  This
 *    job (wjcr) becomes the new backup job that replaces
 *    the original backup job. Note, this jcr is not really run. It
 *    is simply attached to the current jcr.  It will show up in
 *    the Director's status output, but not in the SD or FD, both of
 *    which deal only with the current migration job (i.e. jcr).
 */
Called here before the job is run to do the job
specific setup.  Note, one of the important things to
complete in this init code is to make the definitive
choice of input and output storage devices.  This is
because immediately after the init, the job is queued
in the jobq.c code, and it checks that all the resources
(storage resources in particular) are available, so these
must all be properly defined.

previous_jr refers to the job DB record of the Job that is
going to be migrated.
prev_job refers to the job resource of the Job that is
going to be migrated.
jcr is the jcr for the current "migration" job.  It is a
control job that is put in the DB as a migration job, which
means that this job migrated a previous job to a new job.
No Volume or File data is associated with this control
job.
wjcr refers to the migrate/copy job that is writing and is run by
the current jcr.  It is a backup job that writes the
data written for the previous_jr into the new pool.  This
job (wjcr) becomes the new backup job that replaces
the original backup job. Note, this jcr is not really run. It
is simply attached to the current jcr.  It will show up in
the Director's status output, but not in the SD or FD, both of
which deal only with the current migration job .
Called here before the job is run to do the job specific setup . Note one of the important things to complete in this init code is to make the definitive choice of input and output storage devices . This is because immediately after the init the job is queued in the jobq . c code and it checks that all the resources ( storage resources in particular ) are available so these must all be properly defined . previous_jr refers to the job DB record of the Job that is going to be migrated . prev_job refers to the job resource of the Job that is going to be migrated . jcr is the jcr for the current " migration " job . It is a control job that is put in the DB as a migration job which means that this job migrated a previous job to a new job . No Volume or File data is associated with this control job . wjcr refers to the migrate / copy job that is writing and is run by the current jcr . It is a backup job that writes the data written for the previous_jr into the new pool . This job ( wjcr ) becomes the new backup job that replaces the original backup job . Note this jcr is not really run . It is simply attached to the current jcr . It will show up in the Director ' s status output but not in the SD or FD both of which deal only with the current migration job .
bool do_mac_init(JCR *jcr)
{
   POOL *pool = NULL;
   JOB *job, *prev_job;
   JCR *wjcr;                     
   int count;
   apply_pool_overrides(jcr);
   if (!allow_duplicate_job(jcr)) {
      return false;
   }
   jcr->jr.PoolId = get_or_create_pool_record(jcr, jcr->pool->name());
   if (jcr->jr.PoolId == 0) {
      Dmsg1(dbglevel, "JobId=%d no PoolId\n", (int)jcr->JobId);
      Jmsg(jcr, M_FATAL, 0, _("Could not get or create a Pool record.\n"));
      return false;
   }
   jcr->rpool = jcr->pool;            
   pm_strcpy(jcr->rpool_source, jcr->pool_source);
   Dmsg2(dbglevel, "Read pool=%s (From %s)\n", jcr->rpool->name(), jcr->rpool_source);
   if (!get_or_create_fileset_record(jcr)) {
      Dmsg1(dbglevel, "JobId=%d no FileSet\n", (int)jcr->JobId);
      Jmsg(jcr, M_FATAL, 0, _("Could not get or create the FileSet record.\n"));
      return false;
   }
   count = getJob_to_migrate(jcr);
   if (count < 0) {
      return false;
   }
   if (count == 0) {
      set_mac_next_pool(jcr, &pool);
      return true;                    
   }
   Dmsg1(dbglevel, "Back from getJob_to_migrate JobId=%d\n", (int)jcr->JobId);
   if (jcr->previous_jr.JobId == 0) {
      Dmsg1(dbglevel, "JobId=%d no previous JobId\n", (int)jcr->JobId);
      Jmsg(jcr, M_INFO, 0, _("No previous Job found to %s.\n"), jcr->get_ActionName(0));
      set_mac_next_pool(jcr, &pool);
      return true;                    
   }
   if (create_restore_bootstrap_file(jcr) < 0) {
      Jmsg(jcr, M_FATAL, 0, _("Create bootstrap file failed.\n"));
      return false;
   }
   if (jcr->previous_jr.JobId == 0 || jcr->ExpectedFiles == 0) {
      jcr->setJobStatus(JS_Terminated);
      Dmsg1(dbglevel, "JobId=%d expected files == 0\n", (int)jcr->JobId);
      if (jcr->previous_jr.JobId == 0) {
         Jmsg(jcr, M_INFO, 0, _("No previous Job found to %s.\n"), jcr->get_ActionName(0));
      } else {
         Jmsg(jcr, M_INFO, 0, _("Previous Job has no data to %s.\n"), jcr->get_ActionName(0));
      }
      set_mac_next_pool(jcr, &pool);
      return true;                    
   }
   Dmsg5(dbglevel, "JobId=%d: Current: Name=%s JobId=%d Type=%c Level=%c\n",
      (int)jcr->JobId,
      jcr->jr.Name, (int)jcr->jr.JobId,
      jcr->jr.JobType, jcr->jr.JobLevel);
   LockRes();
   job = (JOB *)GetResWithName(R_JOB, jcr->jr.Name);
   prev_job = (JOB *)GetResWithName(R_JOB, jcr->previous_jr.Name);
   UnlockRes();
   if (!job) {
      Jmsg(jcr, M_FATAL, 0, _("Job resource not found for \"%s\".\n"), jcr->jr.Name);
      return false;
   }
   if (!prev_job) {
      Jmsg(jcr, M_FATAL, 0, _("Previous Job resource not found for \"%s\".\n"),
           jcr->previous_jr.Name);
      return false;
   }
   wjcr = jcr->wjcr = new_jcr(sizeof(JCR), dird_free_jcr);
   memcpy(&wjcr->previous_jr, &jcr->previous_jr, sizeof(wjcr->previous_jr));
   set_jcr_defaults(wjcr, prev_job);
   if (wjcr->getJobLevel() == L_VIRTUAL_FULL) {
      wjcr->setJobLevel(L_INCREMENTAL);
   }
   wjcr->IgnoreDuplicateJobChecking = true;
   if (!setup_job(wjcr)) {
      Jmsg(jcr, M_FATAL, 0, _("setup job failed.\n"));
      return false;
   }
   memcpy(&wjcr->jr, &jcr->previous_jr, sizeof(wjcr->jr));
   wjcr->jr.PoolId = jcr->jr.PoolId;
   wjcr->jr.JobId = wjcr->JobId;
   wjcr->sd_client = true;
   wjcr->setJobLevel(jcr->getJobLevel());
   wjcr->spool_data = job->spool_data;     
   wjcr->spool_size = jcr->spool_size;
   jcr->spool_size = 0;
   wjcr->no_maxtime = true;
   Dmsg4(dbglevel, "wjcr: Name=%s JobId=%d Type=%c Level=%c\n",
      wjcr->jr.Name, (int)wjcr->jr.JobId,
      wjcr->jr.JobType, wjcr->jr.JobLevel);
   if (set_mac_next_pool(jcr, &pool)) {
      copy_rstorage(wjcr, pool->storage, _("Pool resource"));
      copy_rstorage(jcr, pool->storage, _("Pool resource"));
      wjcr->pool = jcr->pool;
      wjcr->next_pool = jcr->next_pool;
      wjcr->jr.PoolId = jcr->jr.PoolId;
   }
   return true;
}
bool do_mac_init ( JCR * jcr ) { POOL * pool = NULL ; JOB * job , * prev_job ; JCR * wjcr ; int count ; apply_pool_overrides ( jcr ) ; if ( ! allow_duplicate_job ( jcr ) ) { return false ; } jcr -> jr . PoolId = get_or_create_pool_record ( jcr , jcr -> pool -> name ( ) ) ; if ( jcr -> jr . PoolId == 0 ) { Dmsg1 ( dbglevel , " \n " , ( int ) jcr -> JobId ) ; Jmsg ( jcr , M_FATAL , 0 , _ ( " \n " ) ) ; return false ; } jcr -> rpool = jcr -> pool ; pm_strcpy ( jcr -> rpool_source , jcr -> pool_source ) ; Dmsg2 ( dbglevel , " \n " , jcr -> rpool -> name ( ) , jcr -> rpool_source ) ; if ( ! get_or_create_fileset_record ( jcr ) ) { Dmsg1 ( dbglevel , " \n " , ( int ) jcr -> JobId ) ; Jmsg ( jcr , M_FATAL , 0 , _ ( " \n " ) ) ; return false ; } count = getJob_to_migrate ( jcr ) ; if ( count < 0 ) { return false ; } if ( count == 0 ) { set_mac_next_pool ( jcr , & pool ) ; return true ; } Dmsg1 ( dbglevel , " \n " , ( int ) jcr -> JobId ) ; if ( jcr -> previous_jr . JobId == 0 ) { Dmsg1 ( dbglevel , " \n " , ( int ) jcr -> JobId ) ; Jmsg ( jcr , M_INFO , 0 , _ ( " \n " ) , jcr -> get_ActionName ( 0 ) ) ; set_mac_next_pool ( jcr , & pool ) ; return true ; } if ( create_restore_bootstrap_file ( jcr ) < 0 ) { Jmsg ( jcr , M_FATAL , 0 , _ ( " \n " ) ) ; return false ; } if ( jcr -> previous_jr . JobId == 0 || jcr -> ExpectedFiles == 0 ) { jcr -> setJobStatus ( JS_Terminated ) ; Dmsg1 ( dbglevel , " \n " , ( int ) jcr -> JobId ) ; if ( jcr -> previous_jr . JobId == 0 ) { Jmsg ( jcr , M_INFO , 0 , _ ( " \n " ) , jcr -> get_ActionName ( 0 ) ) ; } else { Jmsg ( jcr , M_INFO , 0 , _ ( " \n " ) , jcr -> get_ActionName ( 0 ) ) ; } set_mac_next_pool ( jcr , & pool ) ; return true ; } Dmsg5 ( dbglevel , " \n " , ( int ) jcr -> JobId , jcr -> jr . Name , ( int ) jcr -> jr . JobId , jcr -> jr . JobType , jcr -> jr . JobLevel ) ; LockRes ( ) ; job = ( JOB * ) GetResWithName ( R_JOB , jcr -> jr . Name ) ; prev_job = ( JOB * ) GetResWithName ( R_JOB , jcr -> previous_jr . Name ) ; UnlockRes ( ) ; if ( ! job ) { Jmsg ( jcr , M_FATAL , 0 , _ ( " \" \" \n " ) , jcr -> jr . Name ) ; return false ; } if ( ! prev_job ) { Jmsg ( jcr , M_FATAL , 0 , _ ( " \" \" \n " ) , jcr -> previous_jr . Name ) ; return false ; } wjcr = jcr -> wjcr = new_jcr ( sizeof ( JCR ) , dird_free_jcr ) ; memcpy ( & wjcr -> previous_jr , & jcr -> previous_jr , sizeof ( wjcr -> previous_jr ) ) ; set_jcr_defaults ( wjcr , prev_job ) ; if ( wjcr -> getJobLevel ( ) == L_VIRTUAL_FULL ) { wjcr -> setJobLevel ( L_INCREMENTAL ) ; } wjcr -> IgnoreDuplicateJobChecking = true ; if ( ! setup_job ( wjcr ) ) { Jmsg ( jcr , M_FATAL , 0 , _ ( " \n " ) ) ; return false ; } memcpy ( & wjcr -> jr , & jcr -> previous_jr , sizeof ( wjcr -> jr ) ) ; wjcr -> jr . PoolId = jcr -> jr . PoolId ; wjcr -> jr . JobId = wjcr -> JobId ; wjcr -> sd_client = true ; wjcr -> setJobLevel ( jcr -> getJobLevel ( ) ) ; wjcr -> spool_data = job -> spool_data ; wjcr -> spool_size = jcr -> spool_size ; jcr -> spool_size = 0 ; wjcr -> no_maxtime = true ; Dmsg4 ( dbglevel , " \n " , wjcr -> jr . Name , ( int ) wjcr -> jr . JobId , wjcr -> jr . JobType , wjcr -> jr . JobLevel ) ; if ( set_mac_next_pool ( jcr , & pool ) ) { copy_rstorage ( wjcr , pool -> storage , _ ( " " ) ) ; copy_rstorage ( jcr , pool -> storage , _ ( " " ) ) ; wjcr -> pool = jcr -> pool ; wjcr -> next_pool = jcr -> next_pool ; wjcr -> jr . PoolId = jcr -> jr . PoolId ; } return true ; }
Called here before the job is run to do the job
   specific setup.
Called here before the job is run to do the job specific setup .
/* jcr of writing job */ /*
    * Note, at this point, pool is the pool for this job.  We
    *  transfer it to rpool (read pool), and a bit later,
    *  pool will be changed to point to the write pool,
    *  which comes from pool->NextPool.
    */ /* save read pool */ /* If we find a job or jobs to migrate it is previous_jr.JobId */ /* no work */ /* no work */ /* no work */ /* Create a write jcr */ /*
    * Turn the wjcr into a "real" job that takes on the aspects of
    *   the previous backup job "prev_job".
    */ /* fix MA 987 cannot copy/migrate jobs with a Level=VF in the job resource
    * If the prev_job level definition is VirtualFull,
    * change it to Incremental, otherwise the writing SD would do a VF
    */ /* Don't check for duplicates on this jobs. We do it before setup_job(),
    * because we check allow_duplicate_job() here.
    */ /* Now reset the job record from the previous job */ /* Update the jr to reflect the new values of PoolId and JobId. */ //wjcr->setJobType(jcr->getJobType()); /* turn on spooling if requested in job */ /* Don't let WatchDog checks Max*Time value on this Job */ /* If pool storage specified, use it for restore */