src/stored/vbackup.c
bool do_vbackup(JCR *jcr)
{
   bool ok = true;
   BSOCK *dir = jcr->dir_bsock;
   const char *Type;
   char ec1[50];
   DEVICE *dev;

   switch(jcr->getJobType()) {
   case JT_MIGRATE:
      Type = "Migration";
      break;
   case JT_ARCHIVE:
      Type = "Archive";
      break;
   case JT_COPY:
      Type = "Copy";
      break;
   case JT_BACKUP:
      Type = "Virtual Backup";
      break;
   default:
      Type = "Unknown";
      break;
   }

   /* TODO: Remove when the new match_all is well tested */
   jcr->use_new_match_all = use_new_match_all;

   Dmsg1(20, "Start read data. newbsr=%d\n", jcr->use_new_match_all);

   if (!jcr->read_dcr || !jcr->dcr) {
      Jmsg(jcr, M_FATAL, 0, _("Read and write devices not properly initialized.\n"));
      goto bail_out;
   }
   Dmsg2(100, "read_dcr=%p write_dcr=%p\n", jcr->read_dcr, jcr->dcr);

   if (jcr->NumReadVolumes == 0) {
      Jmsg(jcr, M_FATAL, 0, _("No Volume names found for %s.\n"), Type);
      goto bail_out;
   }

   Dmsg3(200, "Found %d volumes names for %s. First=%s\n", jcr->NumReadVolumes,
      jcr->VolList->VolumeName, Type);

   ASSERT(jcr->read_dcr != jcr->dcr);
   ASSERT(jcr->read_dcr->dev != jcr->dcr->dev);
   /* Ready devices for reading and writing */
   if (!acquire_device_for_read(jcr->read_dcr) ||
       !acquire_device_for_append(jcr->dcr)) {
      jcr->setJobStatus(JS_ErrorTerminated);
      goto bail_out;
   }
   jcr->dcr->dev->start_of_job(jcr->dcr);

   Dmsg2(200, "===== After acquire pos %u:%u\n", jcr->dcr->dev->file, jcr->dcr->dev->block_num);
   jcr->sendJobStatus(JS_Running);

   begin_data_spool(jcr->dcr);
   begin_attribute_spool(jcr);

   jcr->dcr->VolFirstIndex = jcr->dcr->VolLastIndex = 0;
   jcr->run_time = time(NULL);
   set_start_vol_position(jcr->dcr);

   jcr->JobFiles = 0;
   jcr->dcr->set_ameta();
   jcr->read_dcr->set_ameta();
   ok = read_records(jcr->read_dcr, record_cb, mount_next_read_volume);
   goto ok_out;

bail_out:
   ok = false;

ok_out:
   if (jcr->dcr) {
      jcr->dcr->set_ameta();
      dev = jcr->dcr->dev;
      Dmsg1(100, "ok=%d\n", ok);
      if (ok || dev->can_write()) {
         if (!dev->flush_before_eos(jcr->dcr)) {
            Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
                  dev->print_name(), dev->bstrerror());
            Dmsg0(100, _("Set ok=FALSE after write_block_to_device.\n"));
            //possible_incomplete_job(jcr, last_file_index);
            ok = false;
         }
         /* Flush out final ameta partial block of this session */
         if (!jcr->dcr->write_final_block_to_device()) {
            Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
                  dev->print_name(), dev->bstrerror());
            Dmsg0(100, _("Set ok=FALSE after write_final_block_to_device.\n"));
            ok = false;
         }
         Dmsg2(200, "Flush block to device pos %u:%u\n", dev->file, dev->block_num);
      }
      flush_jobmedia_queue(jcr);
      if (!ok) {
         discard_data_spool(jcr->dcr);
      } else {
         /* Note: if commit is OK, the device will remain blocked */
         commit_data_spool(jcr->dcr);
      }

      /*
       * Don't use time_t for job_elapsed as time_t can be 32 or 64 bits,
       *   and the subsequent Jmsg() editing will break
       */
      int32_t job_elapsed = time(NULL) - jcr->run_time;

      if (job_elapsed <= 0) {
         job_elapsed = 1;
      }

      Jmsg(jcr, M_INFO, 0, _("Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n"),
            job_elapsed / 3600, job_elapsed % 3600 / 60, job_elapsed % 60,
            edit_uint64_with_suffix(jcr->JobBytes / job_elapsed, ec1));

      /* Release the device -- and send final Vol info to DIR */
      release_device(jcr->dcr);

      if (!ok || job_canceled(jcr)) {
         discard_attribute_spool(jcr);
      } else {
         commit_attribute_spool(jcr);
      }
   }

   if (jcr->read_dcr) {
      if (!release_device(jcr->read_dcr)) {
         ok = false;
      }
   }

   jcr->sendJobStatus();              /* update director */

   Dmsg0(30, "Done reading.\n");
   jcr->end_time = time(NULL);
   dequeue_messages(jcr);             /* send any queued messages */
   if (ok) {
      jcr->setJobStatus(JS_Terminated);
   }
   generate_daemon_event(jcr, "JobEnd");
   generate_plugin_event(jcr, bsdEventJobEnd);
   dir->fsend(Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles,
      edit_uint64(jcr->JobBytes, ec1), jcr->JobErrors, jcr->StatusErrMsg);
   Dmsg6(100, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, ec1, jcr->JobErrors, jcr->StatusErrMsg);
   dequeue_daemon_messages(jcr);

   dir->signal(BNET_EOD);             /* send EOD to Director daemon */
   free_plugins(jcr);                 /* release instantiated plugins */

   return ok;
}
/*
 *  Read Data and send to File Daemon
 *   Returns: false on failure
 *            true  on success
 */
Read Data and send to File Daemon
Returns: false on failure
true  on success
Read Data and send to File Daemon Returns : false on failure true on success
bool do_vbackup(JCR *jcr)
{
   bool ok = true;
   BSOCK *dir = jcr->dir_bsock;
   const char *Type;
   char ec1[50];
   DEVICE *dev;
   switch(jcr->getJobType()) {
   case JT_MIGRATE:
      Type = "Migration";
      break;
   case JT_ARCHIVE:
      Type = "Archive";
      break;
   case JT_COPY:
      Type = "Copy";
      break;
   case JT_BACKUP:
      Type = "Virtual Backup";
      break;
   default:
      Type = "Unknown";
      break;
   }
   jcr->use_new_match_all = use_new_match_all;
   Dmsg1(20, "Start read data. newbsr=%d\n", jcr->use_new_match_all);
   if (!jcr->read_dcr || !jcr->dcr) {
      Jmsg(jcr, M_FATAL, 0, _("Read and write devices not properly initialized.\n"));
      goto bail_out;
   }
   Dmsg2(100, "read_dcr=%p write_dcr=%p\n", jcr->read_dcr, jcr->dcr);
   if (jcr->NumReadVolumes == 0) {
      Jmsg(jcr, M_FATAL, 0, _("No Volume names found for %s.\n"), Type);
      goto bail_out;
   }
   Dmsg3(200, "Found %d volumes names for %s. First=%s\n", jcr->NumReadVolumes,
      jcr->VolList->VolumeName, Type);
   ASSERT(jcr->read_dcr != jcr->dcr);
   ASSERT(jcr->read_dcr->dev != jcr->dcr->dev);
   if (!acquire_device_for_read(jcr->read_dcr) ||
       !acquire_device_for_append(jcr->dcr)) {
      jcr->setJobStatus(JS_ErrorTerminated);
      goto bail_out;
   }
   jcr->dcr->dev->start_of_job(jcr->dcr);
   Dmsg2(200, "===== After acquire pos %u:%u\n", jcr->dcr->dev->file, jcr->dcr->dev->block_num);
   jcr->sendJobStatus(JS_Running);
   begin_data_spool(jcr->dcr);
   begin_attribute_spool(jcr);
   jcr->dcr->VolFirstIndex = jcr->dcr->VolLastIndex = 0;
   jcr->run_time = time(NULL);
   set_start_vol_position(jcr->dcr);
   jcr->JobFiles = 0;
   jcr->dcr->set_ameta();
   jcr->read_dcr->set_ameta();
   ok = read_records(jcr->read_dcr, record_cb, mount_next_read_volume);
   goto ok_out;
bail_out:
   ok = false;
ok_out:
   if (jcr->dcr) {
      jcr->dcr->set_ameta();
      dev = jcr->dcr->dev;
      Dmsg1(100, "ok=%d\n", ok);
      if (ok || dev->can_write()) {
         if (!dev->flush_before_eos(jcr->dcr)) {
            Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
                  dev->print_name(), dev->bstrerror());
            Dmsg0(100, _("Set ok=FALSE after write_block_to_device.\n"));
            ok = false;
         }
         if (!jcr->dcr->write_final_block_to_device()) {
            Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
                  dev->print_name(), dev->bstrerror());
            Dmsg0(100, _("Set ok=FALSE after write_final_block_to_device.\n"));
            ok = false;
         }
         Dmsg2(200, "Flush block to device pos %u:%u\n", dev->file, dev->block_num);
      }
      flush_jobmedia_queue(jcr);
      if (!ok) {
         discard_data_spool(jcr->dcr);
      } else {
         commit_data_spool(jcr->dcr);
      }
      int32_t job_elapsed = time(NULL) - jcr->run_time;
      if (job_elapsed <= 0) {
         job_elapsed = 1;
      }
      Jmsg(jcr, M_INFO, 0, _("Elapsed time=%02d:%02d:%02d, Transfer rate=%s Bytes/second\n"),
            job_elapsed / 3600, job_elapsed % 3600 / 60, job_elapsed % 60,
            edit_uint64_with_suffix(jcr->JobBytes / job_elapsed, ec1));
      release_device(jcr->dcr);
      if (!ok || job_canceled(jcr)) {
         discard_attribute_spool(jcr);
      } else {
         commit_attribute_spool(jcr);
      }
   }
   if (jcr->read_dcr) {
      if (!release_device(jcr->read_dcr)) {
         ok = false;
      }
   }
   jcr->sendJobStatus();              
   Dmsg0(30, "Done reading.\n");
   jcr->end_time = time(NULL);
   dequeue_messages(jcr);             
   if (ok) {
      jcr->setJobStatus(JS_Terminated);
   }
   generate_daemon_event(jcr, "JobEnd");
   generate_plugin_event(jcr, bsdEventJobEnd);
   dir->fsend(Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles,
      edit_uint64(jcr->JobBytes, ec1), jcr->JobErrors, jcr->StatusErrMsg);
   Dmsg6(100, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, ec1, jcr->JobErrors, jcr->StatusErrMsg);
   dequeue_daemon_messages(jcr);
   dir->signal(BNET_EOD);             
   free_plugins(jcr);                 
   return ok;
}
bool do_vbackup ( JCR * jcr ) { bool ok = true ; BSOCK * dir = jcr -> dir_bsock ; const char * Type ; char ec1 [ 50 ] ; DEVICE * dev ; switch ( jcr -> getJobType ( ) ) { case JT_MIGRATE : Type = " " ; break ; case JT_ARCHIVE : Type = " " ; break ; case JT_COPY : Type = " " ; break ; case JT_BACKUP : Type = " " ; break ; default : Type = " " ; break ; } jcr -> use_new_match_all = use_new_match_all ; Dmsg1 ( 20 , " \n " , jcr -> use_new_match_all ) ; if ( ! jcr -> read_dcr || ! jcr -> dcr ) { Jmsg ( jcr , M_FATAL , 0 , _ ( " \n " ) ) ; goto bail_out ; } Dmsg2 ( 100 , " \n " , jcr -> read_dcr , jcr -> dcr ) ; if ( jcr -> NumReadVolumes == 0 ) { Jmsg ( jcr , M_FATAL , 0 , _ ( " \n " ) , Type ) ; goto bail_out ; } Dmsg3 ( 200 , " \n " , jcr -> NumReadVolumes , jcr -> VolList -> VolumeName , Type ) ; ASSERT ( jcr -> read_dcr != jcr -> dcr ) ; ASSERT ( jcr -> read_dcr -> dev != jcr -> dcr -> dev ) ; if ( ! acquire_device_for_read ( jcr -> read_dcr ) || ! acquire_device_for_append ( jcr -> dcr ) ) { jcr -> setJobStatus ( JS_ErrorTerminated ) ; goto bail_out ; } jcr -> dcr -> dev -> start_of_job ( jcr -> dcr ) ; Dmsg2 ( 200 , " \n " , jcr -> dcr -> dev -> file , jcr -> dcr -> dev -> block_num ) ; jcr -> sendJobStatus ( JS_Running ) ; begin_data_spool ( jcr -> dcr ) ; begin_attribute_spool ( jcr ) ; jcr -> dcr -> VolFirstIndex = jcr -> dcr -> VolLastIndex = 0 ; jcr -> run_time = time ( NULL ) ; set_start_vol_position ( jcr -> dcr ) ; jcr -> JobFiles = 0 ; jcr -> dcr -> set_ameta ( ) ; jcr -> read_dcr -> set_ameta ( ) ; ok = read_records ( jcr -> read_dcr , record_cb , mount_next_read_volume ) ; goto ok_out ; bail_out : ok = false ; ok_out : if ( jcr -> dcr ) { jcr -> dcr -> set_ameta ( ) ; dev = jcr -> dcr -> dev ; Dmsg1 ( 100 , " \n " , ok ) ; if ( ok || dev -> can_write ( ) ) { if ( ! dev -> flush_before_eos ( jcr -> dcr ) ) { Jmsg2 ( jcr , M_FATAL , 0 , _ ( " \n " ) , dev -> print_name ( ) , dev -> bstrerror ( ) ) ; Dmsg0 ( 100 , _ ( " \n " ) ) ; ok = false ; } if ( ! jcr -> dcr -> write_final_block_to_device ( ) ) { Jmsg2 ( jcr , M_FATAL , 0 , _ ( " \n " ) , dev -> print_name ( ) , dev -> bstrerror ( ) ) ; Dmsg0 ( 100 , _ ( " \n " ) ) ; ok = false ; } Dmsg2 ( 200 , " \n " , dev -> file , dev -> block_num ) ; } flush_jobmedia_queue ( jcr ) ; if ( ! ok ) { discard_data_spool ( jcr -> dcr ) ; } else { commit_data_spool ( jcr -> dcr ) ; } int32_t job_elapsed = time ( NULL ) - jcr -> run_time ; if ( job_elapsed <= 0 ) { job_elapsed = 1 ; } Jmsg ( jcr , M_INFO , 0 , _ ( " \n " ) , job_elapsed / 3600 , job_elapsed % 3600 / 60 , job_elapsed % 60 , edit_uint64_with_suffix ( jcr -> JobBytes / job_elapsed , ec1 ) ) ; release_device ( jcr -> dcr ) ; if ( ! ok || job_canceled ( jcr ) ) { discard_attribute_spool ( jcr ) ; } else { commit_attribute_spool ( jcr ) ; } } if ( jcr -> read_dcr ) { if ( ! release_device ( jcr -> read_dcr ) ) { ok = false ; } } jcr -> sendJobStatus ( ) ; Dmsg0 ( 30 , " \n " ) ; jcr -> end_time = time ( NULL ) ; dequeue_messages ( jcr ) ; if ( ok ) { jcr -> setJobStatus ( JS_Terminated ) ; } generate_daemon_event ( jcr , " " ) ; generate_plugin_event ( jcr , bsdEventJobEnd ) ; dir -> fsend ( Job_end , jcr -> Job , jcr -> JobStatus , jcr -> JobFiles , edit_uint64 ( jcr -> JobBytes , ec1 ) , jcr -> JobErrors , jcr -> StatusErrMsg ) ; Dmsg6 ( 100 , Job_end , jcr -> Job , jcr -> JobStatus , jcr -> JobFiles , ec1 , jcr -> JobErrors , jcr -> StatusErrMsg ) ; dequeue_daemon_messages ( jcr ) ; dir -> signal ( BNET_EOD ) ; free_plugins ( jcr ) ; return ok ; }
Read Data and send to File Daemon
   Returns: false on failure
            true  on success
Read Data and send to File Daemon Returns : false on failure true on success
/* TODO: Remove when the new match_all is well tested */ /* Ready devices for reading and writing */ //possible_incomplete_job(jcr, last_file_index); /* Flush out final ameta partial block of this session */ /* Note: if commit is OK, the device will remain blocked */ /*
       * Don't use time_t for job_elapsed as time_t can be 32 or 64 bits,
       *   and the subsequent Jmsg() editing will break
       */ /* Release the device -- and send final Vol info to DIR */ /* update director */ /* send any queued messages */ /* send EOD to Director daemon */ /* release instantiated plugins */