Exemplo n.º 1
40
/*
 * Read Data and send to File Daemon
 *
 * Returns: false on failure
 *          true  on success
 */
bool do_read_data(JCR *jcr)
{
   BSOCK *fd = jcr->file_bsock;
   DCR *dcr = jcr->read_dcr;
   bool ok = true;

   Dmsg0(20, "Start read data.\n");

   if (!bnet_set_buffer_size(fd, dcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) {
      return false;
   }

   if (jcr->NumReadVolumes == 0) {
      Jmsg(jcr, M_FATAL, 0, _("No Volume names found for restore.\n"));
      fd->fsend(FD_error);
      return false;
   }

   Dmsg2(200, "Found %d volumes names to restore. First=%s\n",
         jcr->NumReadVolumes, jcr->VolList->VolumeName);

   /*
    * Ready device for reading
    */
   if (!acquire_device_for_read(dcr)) {
      fd->fsend(FD_error);
      return false;
   }

   /*
    * Let any SD plugin know now its time to setup the record translation infra.
    */
   if (generate_plugin_event(jcr, bsdEventSetupRecordTranslation, dcr) != bRC_OK) {
      jcr->setJobStatus(JS_ErrorTerminated);
      return false;
   }

   /*
    * Tell File daemon we will send data
    */
   fd->fsend(OK_data);
   jcr->sendJobStatus(JS_Running);
   ok = read_records(dcr, record_cb, mount_next_read_volume);

   /*
    * Send end of data to FD
    */
   fd->signal(BNET_EOD);

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

   Dmsg0(30, "Done reading.\n");
   return ok;
}
Exemplo n.º 2
11
/*
 *  Read Data and send to File Daemon
 *   Returns: false on failure
 *            true  on success
 */
bool do_read_data(JCR *jcr)
{
   BSOCK *fd = jcr->file_bsock;
   bool ok = true;
   DCR *dcr = jcr->read_dcr;

   Dmsg0(20, "Start read data.\n");

   if (!bnet_set_buffer_size(fd, dcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) {
      return false;
   }

   if (jcr->NumReadVolumes == 0) {
      Jmsg(jcr, M_FATAL, 0, _("No Volume names found for restore.\n"));
      fd->fsend(FD_error);
      return false;
   }

   Dmsg2(200, "Found %d volumes names to restore. First=%s\n", jcr->NumReadVolumes,
      jcr->VolList->VolumeName);

   /* Ready device for reading */
   if (!acquire_device_for_read(dcr)) {
      fd->fsend(FD_error);
      return false;
   }

   /* Tell File daemon we will send data */
   fd->fsend(OK_data);
   jcr->sendJobStatus(JS_Running);
   ok = read_records(dcr, record_cb, mount_next_read_volume);

   /* Send end of data to FD */
   fd->signal(BNET_EOD);

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

   Dmsg0(30, "Done reading.\n");
   return ok;
}
Exemplo n.º 3
0
/*
 * If we are reading, we come here at the end of the tape
 *  and see if there are more volumes to be mounted.
 */
bool mount_next_read_volume(DCR *dcr)
{
   DEVICE *dev = dcr->dev;
   JCR *jcr = dcr->jcr;
   Dmsg2(90, "NumReadVolumes=%d CurReadVolume=%d\n", jcr->NumReadVolumes, jcr->CurReadVolume);

   volume_unused(dcr);                /* release current volume */
   /*
    * End Of Tape -- mount next Volume (if another specified)
    */
   if (jcr->NumReadVolumes > 1 && jcr->CurReadVolume < jcr->NumReadVolumes) {
      dev->close();
      if (!acquire_device_for_read(dcr)) {
         Jmsg2(jcr, M_FATAL, 0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(),
               dcr->VolumeName);
         return false;
      }
      return true;                    /* next volume mounted */
   }
   Dmsg0(90, "End of Device reached.\n");
   return false;
}
Exemplo n.º 4
0
/*
 * Setup device, jcr, and prepare to access device.
 *   If the caller wants read access, acquire the device, otherwise,
 *     the caller will do it.
 */
static DCR *setup_to_access_device(JCR *jcr, char *dev_name,
              const char *VolumeName, int mode)
{
   DEVICE *dev;
   char *p;
   DEVRES *device;
   DCR *dcr;
   char VolName[MAX_NAME_LENGTH];

   init_reservations_lock();

   /*
    * If no volume name already given and no bsr, and it is a file,
    * try getting name from Filename
    */
   if (VolumeName) {
      bstrncpy(VolName, VolumeName, sizeof(VolName));
      if (strlen(VolumeName) >= MAX_NAME_LENGTH) {
         Jmsg0(jcr, M_ERROR, 0, _("Volume name or names is too long. Please use a .bsr file.\n"));
      }
   } else {
      VolName[0] = 0;
   }
   if (!jcr->bsr && VolName[0] == 0) {
      if (!bstrncmp(dev_name, "/dev/", 5)) {
         /* Try stripping file part */
         p = dev_name + strlen(dev_name);

         while (p >= dev_name && !IsPathSeparator(*p))
            p--;
         if (IsPathSeparator(*p)) {
            bstrncpy(VolName, p+1, sizeof(VolName));
            *p = 0;
         }
      }
   }

   if ((device=find_device_res(dev_name, mode)) == NULL) {
      Jmsg2(jcr, M_FATAL, 0, _("Cannot find device \"%s\" in config file %s.\n"),
           dev_name, configfile);
      return NULL;
   }

   dev = init_dev(jcr, device);
   if (!dev) {
      Jmsg1(jcr, M_FATAL, 0, _("Cannot init device %s\n"), dev_name);
      return NULL;
   }
   device->dev = dev;
   jcr->dcr = dcr = new_dcr(jcr, NULL, dev);
   if (VolName[0]) {
      bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
   }
   bstrncpy(dcr->dev_name, device->device_name, sizeof(dcr->dev_name));

   create_restore_volume_list(jcr);

   if (mode) {                        /* read only access? */
      Dmsg0(100, "Acquire device for read\n");
      if (!acquire_device_for_read(dcr)) {
         return NULL;
      }
      jcr->read_dcr = dcr;
   } else {
      if (!first_open_device(dcr)) {
         Jmsg1(jcr, M_FATAL, 0, _("Cannot open %s\n"), dev->print_name());
         return NULL;
      }
      jcr->dcr = dcr;        /* write dcr */
   }
   return dcr;
}
Exemplo n.º 5
0
Arquivo: mac.c Projeto: AlD/bareos
/*
 * Read Data and commit to new job.
 */
bool do_mac_run(JCR *jcr)
{
   DEVICE *dev;
   char ec1[50];
   const char *Type;
   bool ok = true;
   BSOCK *dir = jcr->dir_bsock;

   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;
   }

   Dmsg0(20, "Start read data.\n");

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

   /*
    * Check autoinflation/autodeflation settings.
    */
   check_auto_xflation(jcr);

   /*
    * See if we perform both read and write or read only.
    */
   if (jcr->remote_replicate) {
      BSOCK *sd;

      if (!jcr->read_dcr) {
         Jmsg(jcr, M_FATAL, 0, _("Read device not properly initialized.\n"));
         goto bail_out;
      }

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

      /*
       * Ready devices for reading.
       */
      if (!acquire_device_for_read(jcr->read_dcr)) {
         ok = false;
         goto bail_out;
      }

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

      jcr->sendJobStatus(JS_Running);

      /*
       * Set network buffering.
       */
      sd = jcr->store_bsock;
      if (!sd->set_buffer_size(me->max_network_buffer_size, BNET_SETBUF_WRITE)) {
         Jmsg(jcr, M_FATAL, 0, _("Cannot set buffer size SD->SD.\n"));
         ok = false;
         goto bail_out;
      }

      /*
       * Let the remote SD know we are about to start the replication.
       */
      sd->fsend(start_replicate);
      Dmsg1(110, ">stored: %s", sd->msg);

      /*
       * Expect to receive back the Ticket number.
       */
      if (bget_msg(sd) >= 0) {
         Dmsg1(110, "<stored: %s", sd->msg);
         if (sscanf(sd->msg, OK_start_replicate, &jcr->Ticket) != 1) {
            Jmsg(jcr, M_FATAL, 0, _("Bad response to start replicate: %s\n"), sd->msg);
            goto bail_out;
         }
         Dmsg1(110, "Got Ticket=%d\n", jcr->Ticket);
      } else {
         Jmsg(jcr, M_FATAL, 0, _("Bad response from stored to start replicate command\n"));
         goto bail_out;
      }

      /*
       * Let the remote SD know we are now really going to send the data.
       */
      sd->fsend(replicate_data, jcr->Ticket);
      Dmsg1(110, ">stored: %s", sd->msg);

      /*
       * Expect to get response to the replicate data cmd from Storage daemon
       */
      if (!response(jcr, sd, OK_data, "replicate data")) {
         ok = false;
         goto bail_out;
      }

      /*
       * Read all data and send it to remote SD.
       */
      ok = read_records(jcr->read_dcr, clone_record_to_remote_sd, mount_next_read_volume);

      /*
       * Send the last EOD to close the last data transfer and a next EOD to
       * signal the remote we are done.
       */
      if (!sd->signal(BNET_EOD) || !sd->signal(BNET_EOD)) {
         if (!jcr->is_job_canceled()) {
            Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
                  sd->bstrerror());
         }
         goto bail_out;
      }

      /*
       * Expect to get response that the replicate data succeeded.
       */
      if (!response(jcr, sd, OK_replicate, "replicate data")) {
         ok = false;
         goto bail_out;
      }

      /*
       * End replicate session.
       */
      sd->fsend(end_replicate);
      Dmsg1(110, ">stored: %s", sd->msg);

      /*
       * Expect to get response to the end replicate cmd from Storage daemon
       */
      if (!response(jcr, sd, OK_end_replicate, "end replicate")) {
         ok = false;
         goto bail_out;
      }

      /* Inform Storage daemon that we are done */
      sd->signal(BNET_TERMINATE);
   } else {
      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);
      Dmsg3(200, "Found %d volumes names for %s. First=%s\n",
            jcr->NumReadVolumes, Type, jcr->VolList->VolumeName);

      /*
       * Ready devices for reading and writing.
       */
      if (!acquire_device_for_read(jcr->read_dcr) ||
          !acquire_device_for_append(jcr->dcr)) {
         ok = false;
         goto bail_out;
      }

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

      jcr->sendJobStatus(JS_Running);

      if (!begin_data_spool(jcr->dcr) ) {
         ok = false;
         goto bail_out;
      }

      if (!begin_attribute_spool(jcr)) {
         ok = false;
         goto bail_out;
      }

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

      /*
       * Read all data and make a local clone of it.
       */
      ok = read_records(jcr->read_dcr, clone_record_internally, mount_next_read_volume);
   }

bail_out:
   if (!ok) {
      jcr->setJobStatus(JS_ErrorTerminated);
   }

   if (!jcr->remote_replicate && 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;

      dev = jcr->dcr->dev;
      Dmsg1(100, "ok=%d\n", ok);
      if (ok || dev->can_write()) {
         /*
          * Flush out final partial block of this session
          */
         if (!jcr->dcr->write_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_block_to_device.\n"));
            ok = false;
         }
         Dmsg2(200, "Flush block to device pos %u:%u\n", dev->file, dev->block_num);
      }

      if (!ok) {
         discard_data_spool(jcr->dcr);
      } else {
         /*
          * Note: if commit is OK, the device will remain blocked
          */
         commit_data_spool(jcr->dcr);
      }

      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_plugin_event(jcr, bsdEventJobEnd);
   dir->fsend(Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles,
              edit_uint64(jcr->JobBytes, ec1), jcr->JobErrors);
   Dmsg4(100, Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles, ec1);

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

   return false;                      /* Continue DIR session ? */
}