Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
Archivo: askdir.c Proyecto: AlD/bareos
/**
 * After writing a Volume, create the JobMedia record.
 */
bool dir_create_jobmedia_record(DCR *dcr, bool zero)
{
   JCR *jcr = dcr->jcr;
   BSOCK *dir = jcr->dir_bsock;
   char ed1[50];

   /* If system job, do not update catalog */
   if (jcr->is_JobType(JT_SYSTEM)) {
      return true;
   }

   /* Throw out records where FI is zero -- i.e. nothing done */
   if (!zero && dcr->VolFirstIndex == 0 &&
        (dcr->StartBlock != 0 || dcr->EndBlock != 0)) {
      Dmsg0(dbglvl, "JobMedia FI=0 StartBlock!=0 record suppressed\n");
      return true;
   }

   if (!dcr->WroteVol) {
      return true;                    /* nothing written to tape */
   }

   dcr->WroteVol = false;
   if (zero) {
      /* Send dummy place holder to avoid purging */
      dir->fsend(Create_job_media, jcr->Job,
         0 , 0, 0, 0, 0, 0, 0, 0, edit_uint64(dcr->VolMediaId, ed1));
   } else {
      dir->fsend(Create_job_media, jcr->Job,
         dcr->VolFirstIndex, dcr->VolLastIndex,
         dcr->StartFile, dcr->EndFile,
         dcr->StartBlock, dcr->EndBlock,
         dcr->Copy, dcr->Stripe,
         edit_uint64(dcr->VolMediaId, ed1));
   }
   Dmsg1(dbglvl, ">dird %s", dir->msg);
   if (dir->recv() <= 0) {
      Dmsg0(dbglvl, "create_jobmedia error bnet_recv\n");
      Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: ERR=%s\n"),
           dir->bstrerror());
      return false;
   }
   Dmsg1(dbglvl, "<dird %s", dir->msg);
   if (!bstrcmp(dir->msg, OK_create)) {
      Dmsg1(dbglvl, "Bad response from Dir: %s\n", dir->msg);
      Jmsg(jcr, M_FATAL, 0, _("Error creating JobMedia record: %s\n"), dir->msg);
      return false;
   }
   return true;
}
Ejemplo n.º 3
0
/*
 *   Read Data command
 *     Open Data Channel, read the data from
 *     the archive device and send to File
 *     daemon.
 */
static bool read_data_cmd(JCR *jcr)
{
   BSOCK *fd = jcr->file_bsock;

   Dmsg1(120, "Read data: %s", fd->msg);
   if (jcr->session_opened) {
      Dmsg1(120, "<bfiled: %s", fd->msg);
      return do_read_data(jcr);
   } else {
      pm_strcpy(jcr->errmsg, _("Attempt to read on non-open session.\n"));
      fd->fsend(NOT_opened);
      return false;
   }
}
Ejemplo n.º 4
0
/*
 * Initiate the message channel with the Director.
 * It has made a connection to our server.
 *
 * Basic tasks done here:
 *   - Assume the Hello message is already in the input buffer.
 *   - Authenticate
 *   - Get device
 *   - Get media
 *   - Get pool information
 *
 * This is the channel across which we will send error
 * messages and job status information.
 */
bool authenticate_director(JCR *jcr)
{
   BSOCK *dir = jcr->dir_bsock;

   if (!two_way_authenticate(R_DIRECTOR, dir, jcr)) {
      dir->fsend("%s", Dir_sorry);
      Dmsg1(dbglvl, "Unable to authenticate Director at %s.\n", dir->who());
      Jmsg1(jcr, M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who());
      bmicrosleep(5, 0);
      return false;
   }

   return dir->fsend("%s", OK_hello);
}
Ejemplo n.º 5
0
void cancel_storage_daemon_job(JCR *jcr)
{
   if (jcr->sd_canceled) { 
      return;                   /* cancel only once */
   }

   UAContext *ua = new_ua_context(jcr);
   JCR *control_jcr = new_control_jcr("*JobCancel*", JT_SYSTEM);
   BSOCK *sd;

   ua->jcr = control_jcr;
   if (jcr->store_bsock) {
      if (!ua->jcr->wstorage) {
         if (jcr->rstorage) {
            copy_wstorage(ua->jcr, jcr->rstorage, _("Job resource")); 
         } else {
            copy_wstorage(ua->jcr, jcr->wstorage, _("Job resource")); 
         }
      } else {
         USTORE store;
         if (jcr->rstorage) {
            store.store = jcr->rstore;
         } else {
            store.store = jcr->wstore;
         }
         set_wstorage(ua->jcr, &store);
      }

      if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) {
         goto bail_out;
      }
      Dmsg0(200, "Connected to storage daemon\n");
      sd = ua->jcr->store_bsock;
      sd->fsend("cancel Job=%s\n", jcr->Job);
      while (sd->recv() >= 0) {
      }
      sd->signal(BNET_TERMINATE);
      sd->close();
      ua->jcr->store_bsock = NULL;
      jcr->sd_canceled = true;
      jcr->store_bsock->set_timed_out();
      jcr->store_bsock->set_terminated();
      sd_msg_thread_send_signal(jcr, TIMEOUT_SIGNAL);
      jcr->my_thread_send_signal(TIMEOUT_SIGNAL);
   }
bail_out:
   free_jcr(control_jcr);
   free_ua_context(ua);
}
Ejemplo n.º 6
0
/*
 * Cancel a running job on a storage daemon. The silent flag sets
 * if we need to be silent or not e.g. when doing an interactive cancel
 * or a system invoked one.
 */
bool cancel_storage_daemon_job(UAContext *ua, JCR *jcr, bool silent)
{
   BSOCK *sd;
   USTORERES store;

   if (!ua->jcr->wstorage) {
      if (jcr->rstorage) {
         copy_wstorage(ua->jcr, jcr->rstorage, _("Job resource"));
      } else {
         copy_wstorage(ua->jcr, jcr->wstorage, _("Job resource"));
      }
   } else {
      if (jcr->rstorage) {
         store.store = jcr->res.rstore;
      } else {
         store.store = jcr->res.wstore;
      }
      set_wstorage(ua->jcr, &store);
   }

   if (!connect_to_storage_daemon(ua->jcr, 10, me->SDConnectTimeout, true)) {
      if (!silent) {
         ua->error_msg(_("Failed to connect to Storage daemon.\n"));
      }
      return false;
   }
   Dmsg0(200, "Connected to storage daemon\n");
   sd = ua->jcr->store_bsock;
   sd->fsend(canceljobcmd, jcr->Job);
   while (sd->recv() >= 0) {
      if (!silent) {
         ua->send_msg("%s", sd->msg);
      }
   }
   sd->signal(BNET_TERMINATE);
   sd->close();
   delete ua->jcr->store_bsock;
   ua->jcr->store_bsock = NULL;
   if (silent) {
      jcr->sd_canceled = true;
   }
   jcr->store_bsock->set_timed_out();
   jcr->store_bsock->set_terminated();
   sd_msg_thread_send_signal(jcr, TIMEOUT_SIGNAL);
   jcr->my_thread_send_signal(TIMEOUT_SIGNAL);

   return true;
}
Ejemplo n.º 7
0
/*
 * Execute a command from the UA
 */
bool do_a_dot_command(UAContext *ua)
{
   int i;
   int len;
   bool ok = false;
   bool found = false;
   BSOCK *user = ua->UA_sock;

   Dmsg1(1400, "Dot command: %s\n", user->msg);
   if (ua->argc == 0) {
      return false;
   }

   len = strlen(ua->argk[0]);
   if (len == 1) {
      if (ua->api) user->signal(BNET_CMD_BEGIN);
      if (ua->api) user->signal(BNET_CMD_OK);
      return true;                    /* no op */
   }
   for (i=0; i<comsize; i++) {     /* search for command */
      if (bstrncasecmp(ua->argk[0],  _(commands[i].key), len)) {
         /* Check if this command is authorized in RunScript */
         if (ua->runscript && !commands[i].use_in_rs) {
            ua->error_msg(_("Can't use %s command in a runscript"), ua->argk[0]);
            break;
         }
         bool gui = ua->gui;
         /* Check if command permitted, but "quit" is always OK */
         if (!bstrcmp(ua->argk[0], NT_(".quit")) &&
             !acl_access_ok(ua, Command_ACL, ua->argk[0], len)) {
            break;
         }
         Dmsg1(100, "Cmd: %s\n", ua->cmd);
         ua->gui = true;
         if (ua->api) user->signal(BNET_CMD_BEGIN);
         ok = (*commands[i].func)(ua, ua->cmd);   /* go execute command */
         if (ua->api) user->signal(ok?BNET_CMD_OK:BNET_CMD_FAILED);
         ua->gui = gui;
         found = true;
         break;
      }
   }
   if (!found) {
      ua->error_msg("%s%s", ua->argk[0], _(": is an invalid command.\n"));
      ok = false;
   }
   return ok;
}
Ejemplo n.º 8
0
Archivo: askdir.c Proyecto: AlD/bareos
/**
 * Get Volume info for a specific volume from the Director's Database
 *
 * Returns: true  on success   (Director guarantees that Pool and MediaType
 *                              are correct and VolStatus==Append or
 *                              VolStatus==Recycle)
 *          false on failure
 *
 *          Volume information returned in dcr->VolCatInfo
 */
bool dir_get_volume_info(DCR *dcr, enum get_vol_info_rw writing)
{
   JCR *jcr = dcr->jcr;
   BSOCK *dir = jcr->dir_bsock;

   P(vol_info_mutex);
   dcr->setVolCatName(dcr->VolumeName);
   bash_spaces(dcr->getVolCatName());
   dir->fsend(Get_Vol_Info, jcr->Job, dcr->getVolCatName(),
      writing==GET_VOL_INFO_FOR_WRITE?1:0);
   Dmsg1(dbglvl, ">dird %s", dir->msg);
   unbash_spaces(dcr->getVolCatName());
   bool ok = do_get_volume_info(dcr);
   V(vol_info_mutex);
   return ok;
}
Ejemplo n.º 9
0
/*
 * Now talk to the FD and do what he says
 */
void do_fd_commands(JCR *jcr)
{
   int i;
   bool found, quit;
   BSOCK *fd = jcr->file_bsock;

   fd->set_jcr(jcr);
   for (quit=false; !quit;) {
      int stat;

      /* Read command coming from the File daemon */
      stat = fd->recv();
      if (is_bnet_stop(fd)) {         /* hardeof or error */
         break;                       /* connection terminated */
      }
      if (stat <= 0) {
         continue;                    /* ignore signals and zero length msgs */
      }
      Dmsg1(110, "<filed: %s", fd->msg);
      found = false;
      for (i=0; fd_cmds[i].cmd; i++) {
         if (strncmp(fd_cmds[i].cmd, fd->msg, strlen(fd_cmds[i].cmd)) == 0) {
            found = true;               /* indicate command found */
            jcr->errmsg[0] = 0;
            if (!fd_cmds[i].func(jcr) || job_canceled(jcr)) {    /* do command */
               /* Note fd->msg command may be destroyed by comm activity */
               if (jcr->errmsg[0]) {
                  Jmsg1(jcr, M_FATAL, 0, _("Command error with FD, hanging up. %s\n"),
                        jcr->errmsg);
               } else {
                  Jmsg0(jcr, M_FATAL, 0, _("Command error with FD, hanging up.\n"));
               }
               set_jcr_job_status(jcr, JS_ErrorTerminated);
               quit = true;
            }
            break;
         }
      }
      if (!found) {                   /* command not found */
         Jmsg1(jcr, M_FATAL, 0, _("FD command not found: %s\n"), fd->msg);
         Dmsg1(110, "<filed: Command not found: %s\n", fd->msg);
         fd->fsend(ferrmsg);
         break;
      }
   }
   fd->signal(BNET_TERMINATE);        /* signal to FD job is done */
}
Ejemplo n.º 10
0
/**
 * Get Volume info for a specific volume from the Director's Database
 *
 * Returns: true  on success   (Director guarantees that Pool and MediaType
 *                              are correct and VolStatus==Append or
 *                              VolStatus==Recycle)
 *          false on failure
 *
 * Volume information returned in dcr->VolCatInfo
 */
bool SD_DCR::dir_get_volume_info(enum get_vol_info_rw writing)
{
   bool ok;
   BSOCK *dir = jcr->dir_bsock;

   P(vol_info_mutex);
   setVolCatName(VolumeName);
   bash_spaces(getVolCatName());
   dir->fsend(Get_Vol_Info, jcr->Job, getVolCatName(),
              (writing == GET_VOL_INFO_FOR_WRITE) ? 1 : 0);
   Dmsg1(dbglvl, ">dird %s", dir->msg);
   unbash_spaces(getVolCatName());
   ok = do_get_volume_info(this);
   V(vol_info_mutex);

   return ok;
}
Ejemplo n.º 11
0
bool finish_cmd(JCR *jcr)
{
   BSOCK *dir = jcr->dir_bsock;
   char ec1[30];

   /*
    * See if the Job has a certain protocol. Some protocols allow the
    * finish cmd some do not (Native backup for example does NOT)
    */
   switch (jcr->getJobProtocol()) {
   case PT_NDMP:
      Dmsg1(200, "Finish_cmd: %s", jcr->dir_bsock->msg);

      jcr->end_time = time(NULL);
      dequeue_messages(jcr);             /* send any queued messages */
      jcr->setJobStatus(JS_Terminated);

      switch (jcr->getJobType()) {
      case JT_BACKUP:
         end_of_ndmp_backup(jcr);
         break;
      case JT_RESTORE:
         end_of_ndmp_restore(jcr);
         break;
      default:
         break;
      }

      generate_plugin_event(jcr, bsdEventJobEnd);

      dir->fsend(Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles,
                 edit_uint64(jcr->JobBytes, ec1), jcr->JobErrors);
      dir->signal(BNET_EOD);             /* send EOD to Director daemon */

      free_plugins(jcr);                 /* release instantiated plugins */

      Dmsg2(800, "Done jid=%d %p\n", jcr->JobId, jcr);

      return false;                      /* Continue DIR session ? */
   default:
      Dmsg1(200, "Finish_cmd: %s", jcr->dir_bsock->msg);
      Jmsg2(jcr, M_FATAL, 0, _("Hey!!!! JobId %u Job %s tries to use finish cmd while not part of protocol.\n"),
            (uint32_t)jcr->JobId, jcr->Job);
      return false;                      /* Continue DIR session ? */
   }
}
Ejemplo n.º 12
0
/*
 * Authenticate Director
 */
static int authenticate_director(JCR *jcr)
{
   const MONITORRES *monitor = MonitorItemThread::instance()->getMonitor();

   BSOCK *dir = jcr->dir_bsock;
   int tls_local_need = BNET_TLS_NONE;
   int tls_remote_need = BNET_TLS_NONE;
   bool compatible = true;
   char bashed_name[MAX_NAME_LENGTH];
   char *password;

   bstrncpy(bashed_name, monitor->hdr.name, sizeof(bashed_name));
   bash_spaces(bashed_name);
   password = monitor->password;

   /* Timeout Hello after 5 mins */
   btimer_t *tid = start_bsock_timer(dir, 60 * 5);
   dir->fsend(DIRhello, bashed_name);

   if (!cram_md5_respond(dir, password, &tls_remote_need, &compatible) ||
       !cram_md5_challenge(dir, password, tls_local_need, compatible)) {
      stop_bsock_timer(tid);
      Jmsg1(jcr, M_FATAL, 0, _("Director authorization problem.\n"
         "Most likely the passwords do not agree.\n"
         "Please see %s for help.\n"), MANUAL_AUTH_URL);
      return 0;
   }

   Dmsg1(6, ">dird: %s", dir->msg);
   if (dir->recv() <= 0) {
      stop_bsock_timer(tid);
      Jmsg1(jcr, M_FATAL, 0, _("Bad response to Hello command: ERR=%s\n"),
         dir->bstrerror());
      return 0;
   }
   Dmsg1(10, "<dird: %s", dir->msg);
   stop_bsock_timer(tid);
   if (strncmp(dir->msg, DIROKhello, sizeof(DIROKhello)-1) != 0) {
      Jmsg0(jcr, M_FATAL, 0, _("Director rejected Hello command\n"));
      return 0;
   } else {
      Jmsg0(jcr, M_INFO, 0, dir->msg);
   }
   return 1;
}
Ejemplo n.º 13
0
BSOCK *dup_bsock(BSOCK *osock)
{
   BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
   memcpy(bsock, osock, sizeof(BSOCK));
   bsock->msg = get_pool_memory(PM_BSOCK);
   bsock->errmsg = get_pool_memory(PM_MESSAGE);
   if (osock->who()) {
      bsock->set_who(bstrdup(osock->who()));
   }
   if (osock->host()) {
      bsock->set_host(bstrdup(osock->host()));
   }
   if (osock->src_addr) {
      bsock->src_addr = New( IPADDR( *(osock->src_addr)) );
   }
   bsock->set_duped();
   return bsock;
}
Ejemplo n.º 14
0
/*
 *   Read Close session command
 *      Close the read session
 */
static bool read_close_session(JCR *jcr)
{
   BSOCK *fd = jcr->file_bsock;

   Dmsg1(120, "Read close session: %s\n", fd->msg);
   if (!jcr->session_opened) {
      fd->fsend(NOT_opened);
      return false;
   }
   /* Send final close msg to File daemon */
   fd->fsend(OK_close, jcr->JobStatus);
   Dmsg1(160, ">filed: %s\n", fd->msg);

   fd->signal(BNET_EOD);            /* send EOD to File daemon */

   jcr->session_opened = false;
   return true;
}
Ejemplo n.º 15
0
/*
 * Authenticate File daemon connection
 */
static int authenticate_file_daemon(JCR *jcr, CLIENTRES* client)
{
   const MONITORRES *monitor = MonitorItemThread::instance()->getMonitor();

   BSOCK *fd = jcr->file_bsock;
   char dirname[MAX_NAME_LENGTH];
   int tls_local_need = BNET_TLS_NONE;
   int tls_remote_need = BNET_TLS_NONE;
   bool compatible = true;

   /*
    * Send my name to the File daemon then do authentication
    */
   bstrncpy(dirname, monitor->hdr.name, sizeof(dirname));
   bash_spaces(dirname);
   /* Timeout Hello after 5 mins */
   btimer_t *tid = start_bsock_timer(fd, 60 * 5);
   if (!fd->fsend(SDFDhello, dirname)) {
      stop_bsock_timer(tid);
      Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to File daemon. ERR=%s\n"), bnet_strerror(fd));
      return 0;
   }
   if (!cram_md5_respond(fd, client->password, &tls_remote_need, &compatible) ||
       !cram_md5_challenge(fd, client->password, tls_local_need, compatible)) {
      stop_bsock_timer(tid);
      Jmsg(jcr, M_FATAL, 0, _("Director and File daemon passwords or names not the same.\n"
       "Please see " MANUAL_AUTH_URL " for help.\n"));
      return 0;
   }
   Dmsg1(116, ">filed: %s", fd->msg);
   if (fd->recv() <= 0) {
      stop_bsock_timer(tid);
      Jmsg(jcr, M_FATAL, 0, _("Bad response from File daemon to Hello command: ERR=%s\n"),
         fd->bstrerror());
      return 0;
   }
   Dmsg1(110, "<stored: %s", fd->msg);
   stop_bsock_timer(tid);
   if (strncmp(fd->msg, FDOKhello, sizeof(FDOKhello)-1) != 0) {
      Jmsg(jcr, M_FATAL, 0, _("File daemon rejected Hello command\n"));
      return 0;
   }
   return 1;
}
Ejemplo n.º 16
0
/*
 *   Append Close session command
 *      Close the append session and send back Statistics
 *         (need to fix statistics)
 */
static bool append_close_session(JCR *jcr)
{
   BSOCK *fd = jcr->file_bsock;

   Dmsg1(120, "<filed: %s", fd->msg);
   if (!jcr->session_opened) {
      pm_strcpy(jcr->errmsg, _("Attempt to close non-open session.\n"));
      fd->fsend(NOT_opened);
      return false;
   }
   /* Send final statistics to File daemon */
   fd->fsend(OK_close, jcr->JobStatus);
   Dmsg1(120, ">filed: %s", fd->msg);

   fd->signal(BNET_EOD);              /* send EOD to File daemon */

   jcr->session_opened = false;
   return true;
}
Ejemplo n.º 17
0
/*
 * Append Open session command
 *
 */
static bool append_open_session(JCR *jcr)
{
   BSOCK *fd = jcr->file_bsock;

   Dmsg1(120, "Append open session: %s", fd->msg);
   if (jcr->session_opened) {
      pm_strcpy(jcr->errmsg, _("Attempt to open already open session.\n"));
      fd->fsend(NO_open);
      return false;
   }

   jcr->session_opened = true;

   /* Send "Ticket" to File Daemon */
   fd->fsend(OK_open, jcr->VolSessionId);
   Dmsg1(110, ">filed: %s", fd->msg);

   return true;
}
Ejemplo n.º 18
0
/*
 * We get the volume name from the SD
 */
char *get_volume_name_from_SD(UAContext *ua, int Slot, int drive)
{
   BSOCK *sd;
   STORERES *store = ua->jcr->res.wstore;
   char dev_name[MAX_NAME_LENGTH];
   char *VolName = NULL;
   int rtn_slot;

   if (!(sd = open_sd_bsock(ua))) {
      ua->error_msg(_("Could not open SD socket.\n"));
      return NULL;
   }
   bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
   bash_spaces(dev_name);

   /*
    * Ask storage daemon to read the label of the volume in a
    * specific slot of the autochanger using the drive number given.
    * This could change the loaded volume in the drive.
    */
   sd->fsend(readlabelcmd, dev_name, Slot, drive);
   Dmsg1(100, "Sent: %s", sd->msg);

   /*
    * Get Volume name in this Slot
    */
   while (sd->recv() >= 0) {
      ua->send_msg("%s", sd->msg);
      Dmsg1(100, "Got: %s", sd->msg);
      if (strncmp(sd->msg, NT_("3001 Volume="), 12) == 0) {
         VolName = (char *)malloc(sd->msglen);
         if (sscanf(sd->msg, readlabelresponse, VolName, &rtn_slot) == 2) {
            break;
         }
         free(VolName);
         VolName = NULL;
      }
   }
   close_sd_bsock(ua);
   Dmsg1(100, "get_vol_name=%s\n", NPRT(VolName));
   return VolName;
}
Ejemplo n.º 19
0
/*
 * Ask the autochanger to move a volume from one slot to an other.
 * You have to update the database slots yourself afterwards.
 */
bool transfer_volume(UAContext *ua, STORERES *store, int src_slot, int dst_slot)
{
   BSOCK *sd = NULL;
   bool retval = true;
   char dev_name[MAX_NAME_LENGTH];

   if (!(sd = open_sd_bsock(ua))) {
      return false;
   }

   bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
   bash_spaces(dev_name);

   /*
    * Ask for autochanger transfer of volumes
    */
   sd->fsend(changertransfercmd, dev_name, src_slot, dst_slot);
   while (bnet_recv(sd) >= 0) {
      strip_trailing_junk(sd->msg);

      /*
       * Check for returned SD messages
       */
      if (sd->msg[0] == '3' && B_ISDIGIT(sd->msg[1]) &&
          B_ISDIGIT(sd->msg[2]) && B_ISDIGIT(sd->msg[3]) &&
          sd->msg[4] == ' ') {
         /*
          * See if this is a failure msg.
          */
         if (sd->msg[0] == '3' && sd->msg[0] == '9')
            retval = false;

         ua->send_msg("%s\n", sd->msg);   /* pass them on to user */
         continue;
      }

      ua->send_msg("%s\n", sd->msg);   /* pass them on to user */
   }
   close_sd_bsock(ua);

   return retval;
}
Ejemplo n.º 20
0
/*
 * Authenticate Storage daemon connection
 */
int authenticate_storage_daemon(JCR *jcr, MONITOR *monitor, STORE* store)
{
   BSOCK *sd = jcr->store_bsock;
   char dirname[MAX_NAME_LENGTH];
   int tls_local_need = BNET_TLS_NONE;
   int tls_remote_need = BNET_TLS_NONE;
   int compatible = true;

   /*
    * Send my name to the Storage daemon then do authentication
    */
   bstrncpy(dirname, monitor->hdr.name, sizeof(dirname));
   bash_spaces(dirname);
   /* Timeout Hello after 5 mins */
   btimer_t *tid = start_bsock_timer(sd, 60 * 5);
   if (!sd->fsend(SDFDhello, dirname)) {
      stop_bsock_timer(tid);
      Jmsg(jcr, M_FATAL, 0, _("Error sending Hello to Storage daemon. ERR=%s\n"), sd->bstrerror());
      return 0;
   }
   if (!cram_md5_respond(sd, store->password, &tls_remote_need, &compatible) ||
       !cram_md5_challenge(sd, store->password, tls_local_need, compatible)) {
      stop_bsock_timer(tid);
      Jmsg0(jcr, M_FATAL, 0, _("Director and Storage daemon passwords or names not the same.\n"
       "Please see " MANUAL_AUTH_URL " for help.\n"));
      return 0;
   }
   Dmsg1(116, ">stored: %s", sd->msg);
   if (sd->recv() <= 0) {
      stop_bsock_timer(tid);
      Jmsg1(jcr, M_FATAL, 0, _("bdird<stored: bad response to Hello command: ERR=%s\n"),
         sd->bstrerror());
      return 0;
   }
   Dmsg1(110, "<stored: %s", sd->msg);
   stop_bsock_timer(tid);
   if (strncmp(sd->msg, SDOKhello, sizeof(SDOKhello)) != 0) {
      Jmsg0(jcr, M_FATAL, 0, _("Storage daemon rejected Hello command\n"));
      return 0;
   }
   return 1;
}
Ejemplo n.º 21
0
/*
 * Replicate data.
 *    Open Data Channel and receive Data for archiving
 *    Write the Data to the archive device
 */
static bool replicate_data(JCR *jcr)
{
   BSOCK *sd = jcr->store_bsock;

   Dmsg1(120, "Replicate data: %s", sd->msg);
   if (jcr->session_opened) {
      Dmsg1(110, "<stored: %s", sd->msg);
      if (do_append_data(jcr, sd, "SD")) {
         return true;
      } else {
         pm_strcpy(jcr->errmsg, _("Replicate data error.\n"));
         bnet_suppress_error_messages(sd, 1); /* ignore errors at this point */
         sd->fsend(ERROR_replicate);
      }
   } else {
      pm_strcpy(jcr->errmsg, _("Attempt to replicate on non-open session.\n"));
      sd->fsend(NOT_opened);
   }

   return false;
}
Ejemplo n.º 22
0
/* Initialize internal socket structure.
 *  This probably should be done in net_open
 */
BSOCK *init_bsock(JCR * jcr, int sockfd, const char *who, const char *host, int port,
                  struct sockaddr *client_addr)
{
   Dmsg3(100, "who=%s host=%s port=%d\n", who, host, port);
   BSOCK *bsock = (BSOCK *)malloc(sizeof(BSOCK));
   memset(bsock, 0, sizeof(BSOCK));
   bsock->m_fd = sockfd;
   bsock->tls = NULL;
   bsock->errors = 0;
   bsock->m_blocking = 1;
   bsock->msg = get_pool_memory(PM_BSOCK);
   bsock->errmsg = get_pool_memory(PM_MESSAGE);
   bsock->set_who(bstrdup(who));
   bsock->set_host(bstrdup(host));
   bsock->set_port(port);
   memset(&bsock->peer_addr, 0, sizeof(bsock->peer_addr));
   memcpy(&bsock->client_addr, client_addr, sizeof(bsock->client_addr));
   bsock->timeout = BSOCK_TIMEOUT;
   bsock->set_jcr(jcr);
   return bsock;
}
Ejemplo n.º 23
0
/*
 * Start of replication.
 */
static bool start_replication_session(JCR *jcr)
{
   BSOCK *sd = jcr->store_bsock;

   Dmsg1(120, "Start replication session: %s", sd->msg);
   if (jcr->session_opened) {
      pm_strcpy(jcr->errmsg, _("Attempt to open already open session.\n"));
      sd->fsend(NO_open);
      return false;
   }

   jcr->session_opened = true;

   /*
    * Send "Ticket" to Storage Daemon
    */
   sd->fsend(OK_start_replicate, jcr->VolSessionId);
   Dmsg1(110, ">stored: %s", sd->msg);

   return true;
}
Ejemplo n.º 24
0
/*
 *   Append Data command
 *     Open Data Channel and receive Data for archiving
 *     Write the Data to the archive device
 */
static bool append_data_cmd(JCR *jcr)
{
   BSOCK *fd = jcr->file_bsock;

   Dmsg1(120, "Append data: %s", fd->msg);
   if (jcr->session_opened) {
      Dmsg1(110, "<bfiled: %s", fd->msg);
      jcr->set_JobType(JT_BACKUP);
      if (do_append_data(jcr)) {
         return true;
      } else {
         pm_strcpy(jcr->errmsg, _("Append data error.\n"));
         bnet_suppress_error_messages(fd, 1); /* ignore errors at this point */
         fd->fsend(ERROR_append);
      }
   } else {
      pm_strcpy(jcr->errmsg, _("Attempt to append on non-open session.\n"));
      fd->fsend(NOT_opened);
   }
   return false;
}
Ejemplo n.º 25
0
/*
 * Run a File daemon Job -- File daemon already authorized
 *  Director sends us this command.
 *
 * Basic task here is:
 * - Read a command from the File daemon
 * - Execute it
 *
 */
void run_job(JCR *jcr)
{
   BSOCK *dir = jcr->dir_bsock;
   char ec1[30];

   dir->set_jcr(jcr);
   Dmsg1(120, "Start run Job=%s\n", jcr->Job);
   dir->fsend(Job_start, jcr->Job);
   jcr->start_time = time(NULL);
   jcr->run_time = jcr->start_time;
   set_jcr_job_status(jcr, JS_Running);
   dir_send_job_status(jcr);          /* update director */
   do_fd_commands(jcr);
   jcr->end_time = time(NULL);
   dequeue_messages(jcr);             /* send any queued messages */
   set_jcr_job_status(jcr, JS_Terminated);
   generate_daemon_event(jcr, "JobEnd");
   dir->fsend(Job_end, jcr->Job, jcr->JobStatus, jcr->JobFiles,
      edit_uint64(jcr->JobBytes, ec1), jcr->JobErrors);
   dir->signal(BNET_EOD);             /* send EOD to Director daemon */
   return;
}
Ejemplo n.º 26
0
/*
 * Terminate any digest and send it to Storage daemon
 */
static inline bool terminate_digest(b_save_ctx &bsctx)
{
   uint32_t size;
   bool retval = false;
   BSOCK *sd = bsctx.jcr->store_bsock;

   sd->fsend("%ld %d 0", bsctx.jcr->JobFiles, bsctx.digest_stream);
   Dmsg1(300, "filed>stored:header %s", sd->msg);

   size = CRYPTO_DIGEST_MAX_SIZE;

   /*
    * Grow the bsock buffer to fit our message if necessary
    */
   if (sizeof_pool_memory(sd->msg) < (int32_t)size) {
      sd->msg = realloc_pool_memory(sd->msg, size);
   }

   if (!crypto_digest_finalize(bsctx.digest, (uint8_t *)sd->msg, &size)) {
      Jmsg(bsctx.jcr, M_FATAL, 0, _("An error occurred finalizing signing the stream.\n"));
      goto bail_out;
   }

   /*
    * Keep the checksum if this file is a hardlink
    */
   if (bsctx.ff_pkt->linked) {
      ff_pkt_set_link_digest(bsctx.ff_pkt, bsctx.digest_stream, sd->msg, size);
   }

   sd->msglen = size;
   sd->send();
   sd->signal(BNET_EOD);              /* end of checksum */
   retval = true;

bail_out:
   return retval;
}
Ejemplo n.º 27
0
/* Send attributes and digest to Director for Catalog */
bool send_attrs_to_dir(JCR *jcr, DEV_RECORD *rec)
{
   if (rec->maskedStream == STREAM_UNIX_ATTRIBUTES    || 
       rec->maskedStream == STREAM_UNIX_ATTRIBUTES_EX ||
       rec->maskedStream == STREAM_RESTORE_OBJECT     ||
       crypto_digest_stream_type(rec->maskedStream) != CRYPTO_DIGEST_NONE) {
      if (!jcr->no_attributes) {
         BSOCK *dir = jcr->dir_bsock;
         if (are_attributes_spooled(jcr)) {
            dir->set_spooling();
         }
         Dmsg0(850, "Send attributes to dir.\n");
         if (!dir_update_file_attributes(jcr->dcr, rec)) {
            Jmsg(jcr, M_FATAL, 0, _("Error updating file attributes. ERR=%s\n"),
               dir->bstrerror());
            dir->clear_spooling();
            return false;
         }
         dir->clear_spooling();
      }
   }
   return true;
}
Ejemplo n.º 28
0
/*
 * Ask the autochanger to perform a mount, umount or release operation.
 */
bool do_autochanger_volume_operation(UAContext *ua, STORERES *store,
                                     const char *operation, int drive, int slot)
{
   BSOCK *sd = NULL;
   bool retval = true;
   char dev_name[MAX_NAME_LENGTH];

   if (!(sd = open_sd_bsock(ua))) {
      return false;
   }

   bstrncpy(dev_name, store->dev_name(), sizeof(dev_name));
   bash_spaces(dev_name);

   if (slot > 0) {
      sd->fsend(changervolopslotcmd, operation, dev_name, drive, slot);
   } else {
      sd->fsend(changervolopcmd, operation, dev_name, drive);
   }

   /*
    * We use bget_dirmsg here and not bnet_recv because as part of
    * the mount request the stored can request catalog information for
    * any plugin who listens to the bsdEventLabelVerified event.
    * As we don't want to loose any non protocol data e.g. errors
    * without a 3xxx prefix we set the allow_any_message of
    * bget_dirmsg to true and as such is behaves like a normal
    * bnet_recv for any non protocol messages.
    */
   while (bget_dirmsg(sd, true) >= 0) {
      ua->send_msg("%s", sd->msg);
   }

   close_sd_bsock(ua);

   return retval;
}
Ejemplo n.º 29
0
/*
 * Send update information about a device to Director
 */
bool SD_DCR::dir_update_device(JCR *jcr, DEVICE *dev)
{
   BSOCK *dir = jcr->dir_bsock;
   POOL_MEM dev_name, VolumeName, MediaType, ChangerName;
   DEVRES *device = dev->device;
   bool ok;

   pm_strcpy(dev_name, device->hdr.name);
   bash_spaces(dev_name);
   if (dev->is_labeled()) {
      pm_strcpy(VolumeName, dev->VolHdr.VolumeName);
   } else {
      pm_strcpy(VolumeName, "*");
   }
   bash_spaces(VolumeName);
   pm_strcpy(MediaType, device->media_type);
   bash_spaces(MediaType);
   if (device->changer_res) {
      pm_strcpy(ChangerName, device->changer_res->hdr.name);
      bash_spaces(ChangerName);
   } else {
      pm_strcpy(ChangerName, "*");
   }
   ok = dir->fsend(Device_update,
                   jcr->Job,
                   dev_name.c_str(),
                   dev->can_append() != 0,
                   dev->can_read() != 0, dev->num_writers,
                   dev->is_open() != 0, dev->is_labeled() != 0,
                   dev->is_offline() != 0, dev->reserved_device,
                   dev->is_tape() ? 100000 : 1,
                   dev->autoselect, 0,
                   ChangerName.c_str(), MediaType.c_str(), VolumeName.c_str());
   Dmsg1(dbglvl, ">dird: %s", dir->msg);

   return ok;
}
Ejemplo n.º 30
0
/*
 * Read Open session command
 *
 *  We need to scan for the parameters of the job
 *    to be restored.
 */
static bool read_open_session(JCR *jcr)
{
   BSOCK *fd = jcr->file_bsock;

   Dmsg1(120, "%s\n", fd->msg);
   if (jcr->session_opened) {
      pm_strcpy(jcr->errmsg, _("Attempt to open read on non-open session.\n"));
      fd->fsend(NO_open);
      return false;
   }

   if (sscanf(fd->msg, read_open, jcr->read_dcr->VolumeName, &jcr->read_VolSessionId,
         &jcr->read_VolSessionTime, &jcr->read_StartFile, &jcr->read_EndFile,
         &jcr->read_StartBlock, &jcr->read_EndBlock) == 7) {
      if (jcr->session_opened) {
         pm_strcpy(jcr->errmsg, _("Attempt to open read on non-open session.\n"));
         fd->fsend(NOT_opened);
         return false;
      }
      Dmsg4(100, "read_open_session got: JobId=%d Vol=%s VolSessId=%ld VolSessT=%ld\n",
         jcr->JobId, jcr->read_dcr->VolumeName, jcr->read_VolSessionId,
         jcr->read_VolSessionTime);
      Dmsg4(100, "  StartF=%ld EndF=%ld StartB=%ld EndB=%ld\n",
         jcr->read_StartFile, jcr->read_EndFile, jcr->read_StartBlock,
         jcr->read_EndBlock);
   }

   jcr->session_opened = true;
   jcr->set_JobType(JT_RESTORE);

   /* Send "Ticket" to File Daemon */
   fd->fsend(OK_open, jcr->VolSessionId);
   Dmsg1(110, ">filed: %s", fd->msg);

   return true;
}