Beispiel #1
0
static void
print_var(efi_guid_t *guid, char *name)
{
	uint32_t att;
	uint8_t *data;
	size_t datalen;
	char *gname;
	int rv;

	pretty_guid(guid, &gname);
	if (pflag) {
		rv = efi_get_variable(*guid, name, &data, &datalen, &att);

		if (rv < 0)
			err(1, "%s-%s", gname, name);

		if (!Nflag)
			printf("%s-%s\n", gname, name);
		if (load_opt_flag)
			efi_print_load_option(data, datalen, Aflag, bflag, uflag);
		else if (Aflag)
			asciidump(data, datalen);
		else if (uflag)
			utf8dump(data, datalen);
		else if (bflag)
			bindump(data, datalen);
		else if (dflag)
			devpath_dump(data, datalen);
		else
			hexdump(data, datalen);
	} else {
		printf("%s-%s", gname, name);
	}
	free(gname);
	if (!Nflag)
		printf("\n");
}
Beispiel #2
0
/*
 *  Append Data sent from Client (FD/SD)
 *
 */
bool do_append_data(JCR *jcr)
{
   int32_t n;
   int32_t file_index, stream, last_file_index;
   uint64_t stream_len;
   BSOCK *fd = jcr->file_bsock;
   bool ok = true;
   DEV_RECORD rec;
   char buf1[100], buf2[100];
   DCR *dcr = jcr->dcr;
   DEVICE *dev;
   char ec[50];
   POOLMEM *eblock = NULL;
   POOL_MEM errmsg(PM_EMSG);

   if (!dcr) {
      pm_strcpy(jcr->errmsg, _("DCR is NULL!!!\n"));
      Jmsg0(jcr, M_FATAL, 0, jcr->errmsg);
      return false;
   }
   dev = dcr->dev;
   if (!dev) {
      pm_strcpy(jcr->errmsg, _("DEVICE is NULL!!!\n"));
      Jmsg0(jcr, M_FATAL, 0, jcr->errmsg);
      return false;
   }

   Dmsg1(100, "Start append data. res=%d\n", dev->num_reserved());

   memset(&rec, 0, sizeof(rec));

   if (!fd->set_buffer_size(dcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) {
      jcr->setJobStatus(JS_ErrorTerminated);
      pm_strcpy(jcr->errmsg, _("Unable to set network buffer size.\n"));
      Jmsg0(jcr, M_FATAL, 0, jcr->errmsg);
      return false;
   }

   if (!acquire_device_for_append(dcr)) {
      jcr->setJobStatus(JS_ErrorTerminated);
      return false;
   }

   jcr->sendJobStatus(JS_Running);

   //ASSERT(dev->VolCatInfo.VolCatName[0]);
   if (dev->VolCatInfo.VolCatName[0] == 0) {
      Pmsg0(000, _("NULL Volume name. This shouldn't happen!!!\n"));
   }
   Dmsg1(50, "Begin append device=%s\n", dev->print_name());

   begin_data_spool(dcr);
   begin_attribute_spool(jcr);

   Dmsg0(100, "Just after acquire_device_for_append\n");
   //ASSERT(dev->VolCatInfo.VolCatName[0]);
   if (dev->VolCatInfo.VolCatName[0] == 0) {
      Pmsg0(000, _("NULL Volume name. This shouldn't happen!!!\n"));
   }
   /*
    * Write Begin Session Record
    */
   if (!write_session_label(dcr, SOS_LABEL)) {
      Jmsg1(jcr, M_FATAL, 0, _("Write session label failed. ERR=%s\n"),
         dev->bstrerror());
      jcr->setJobStatus(JS_ErrorTerminated);
      ok = false;
   }

   //ASSERT(dev->VolCatInfo.VolCatName[0]);
   if (dev->VolCatInfo.VolCatName[0] == 0) {
      Pmsg0(000, _("NULL Volume name. This shouldn't happen!!!\n"));
   }

   /* Tell File daemon to send data */
   if (!fd->fsend(OK_data)) {
      berrno be;
      Jmsg1(jcr, M_FATAL, 0, _("Network send error to FD. ERR=%s\n"),
            be.bstrerror(fd->b_errno));
      ok = false;
   }

   /*
    * Get Data from File daemon, write to device.  To clarify what is
    *   going on here.  We expect:
    *     - A stream header
    *     - Multiple records of data
    *     - EOD record
    *
    *    The Stream header is just used to synchronize things, and
    *    none of the stream header is written to tape.
    *    The Multiple records of data, contain first the Attributes,
    *    then after another stream header, the file data, then
    *    after another stream header, the MD5 data if any.
    *
    *   So we get the (stream header, data, EOD) three time for each
    *   file. 1. for the Attributes, 2. for the file data if any,
    *   and 3. for the MD5 if any.
    */
   dcr->VolFirstIndex = dcr->VolLastIndex = 0;
   jcr->run_time = time(NULL);              /* start counting time for rates */

   GetMsg *qfd;

   qfd = New(GetMsg(jcr, fd, NULL, GETMSG_MAX_MSG_SIZE));
   qfd->start_read_sock();

   for (last_file_index = 0; ok && !jcr->is_job_canceled(); ) {

      /* Read Stream header from the File daemon.
       *  The stream header consists of the following:
       *    file_index (sequential Bacula file index, base 1)
       *    stream     (Bacula number to distinguish parts of data)
       *    stream_len (Expected length of this stream. This
       *       will be the size backed up if the file does not
       *       grow during the backup.
       */
      n = qfd->bget_msg(NULL);
      if (n <= 0) {
         if (n == BNET_SIGNAL && qfd->msglen == BNET_EOD) {
            Dmsg0(200, "Got EOD on reading header.\n");
            break;                    /* end of data */
         }
         Jmsg3(jcr, M_FATAL, 0, _("Error reading data header from FD. n=%d msglen=%d ERR=%s\n"),
               n, qfd->msglen, fd->bstrerror());
         // ASX TODO the fd->bstrerror() can be related to the wrong error, I should Queue the error too
         possible_incomplete_job(jcr, last_file_index);
         ok = false;
         break;
      }

      if (sscanf(qfd->msg, "%ld %ld %lld", &file_index, &stream, &stream_len) != 3) {
         // TODO ASX already done in bufmsg, should reuse the values
         char buf[256];
         Jmsg1(jcr, M_FATAL, 0, _("Malformed data header from FD: %s\n"), asciidump(qfd->msg, qfd->msglen, buf, sizeof(buf)));
         ok = false;
         possible_incomplete_job(jcr, last_file_index);
         break;
      }

      Dmsg3(890, "<filed: Header FilInx=%d stream=%d stream_len=%lld\n",
         file_index, stream, stream_len);

      /*
       * We make sure the file_index is advancing sequentially.
       * An incomplete job can start the file_index at any number.
       * otherwise, it must start at 1.
       */
      if (jcr->rerunning && file_index > 0 && last_file_index == 0) {
         goto fi_checked;
      }
      Dmsg2(400, "file_index=%d last_file_index=%d\n", file_index, last_file_index);
      if (file_index > 0 && (file_index == last_file_index ||
          file_index == last_file_index + 1)) {
         goto fi_checked;
      }
      Jmsg2(jcr, M_FATAL, 0, _("FI=%d from FD not positive or last_FI=%d\n"),
            file_index, last_file_index);
      possible_incomplete_job(jcr, last_file_index);
      ok = false;
      break;

fi_checked:
      if (file_index != last_file_index) {
         jcr->JobFiles = file_index;
         last_file_index = file_index;
      }

      /* Read data stream from the File daemon.
       *  The data stream is just raw bytes
       */
      while ((n=qfd->bget_msg(NULL)) > 0 && !jcr->is_job_canceled()) {

         rec.VolSessionId = jcr->VolSessionId;
         rec.VolSessionTime = jcr->VolSessionTime;
         rec.FileIndex = file_index;
         rec.Stream = stream;
         rec.StreamLen = stream_len;
         rec.maskedStream = stream & STREAMMASK_TYPE;   /* strip high bits */
         rec.data_len = qfd->msglen;
         rec.data = qfd->msg;            /* use message buffer */

         Dmsg4(850, "before writ_rec FI=%d SessId=%d Strm=%s len=%d\n",
            rec.FileIndex, rec.VolSessionId,
            stream_to_ascii(buf1, rec.Stream,rec.FileIndex),
            rec.data_len);
         ok = dcr->write_record(&rec);
         if (!ok) {
            Dmsg2(90, "Got write_block_to_dev error on device %s. %s\n",
                  dcr->dev->print_name(), dcr->dev->bstrerror());
            break;
         }
         jcr->JobBytes += rec.data_len;   /* increment bytes this job */
         jcr->JobBytes += qfd->bmsg->jobbytes; // if the block as been downloaded, count it
         Dmsg4(850, "write_record FI=%s SessId=%d Strm=%s len=%d\n",
            FI_to_ascii(buf1, rec.FileIndex), rec.VolSessionId,
            stream_to_ascii(buf2, rec.Stream, rec.FileIndex), rec.data_len);

         send_attrs_to_dir(jcr, &rec);
         Dmsg0(650, "Enter bnet_get\n");
      }
      Dmsg2(650, "End read loop with FD. JobFiles=%d Stat=%d\n", jcr->JobFiles, n);

      if (fd->is_error()) {
         if (!jcr->is_job_canceled()) {
            Dmsg1(350, "Network read error from FD. ERR=%s\n", fd->bstrerror());
            Jmsg1(jcr, M_FATAL, 0, _("Network error reading from FD. ERR=%s\n"),
                  fd->bstrerror());
            possible_incomplete_job(jcr, last_file_index);
         }
         ok = false;
         break;
      }
   }

   qfd->wait_read_sock();
   free_GetMsg(qfd);

   if (eblock != NULL) {
      free_pool_memory(eblock);
   }

   /* Create Job status for end of session label */
   jcr->setJobStatus(ok?JS_Terminated:JS_ErrorTerminated);

   if (ok) {
      /* Terminate connection with Client */
      fd->fsend(OK_append);
      do_client_commands(jcr);            /* finish dialog with Client */
   } else {
      fd->fsend("3999 Failed append\n");
   }

   Dmsg1(200, "Write EOS label JobStatus=%c\n", jcr->JobStatus);

   /*
    * Check if we can still write. This may not be the case
    *  if we are at the end of the tape or we got a fatal I/O error.
    */
   if (ok || dev->can_write()) {
      if (!write_session_label(dcr, EOS_LABEL)) {
         /* Print only if ok and not cancelled to avoid spurious messages */
         if (ok && !jcr->is_job_canceled()) {
            Jmsg1(jcr, M_FATAL, 0, _("Error writing end session label. ERR=%s\n"),
                  dev->bstrerror());
            possible_incomplete_job(jcr, last_file_index);
         }
         jcr->setJobStatus(JS_ErrorTerminated);
         ok = false;
      }
      /* Flush out final partial block of this session */
      if (!dcr->write_final_block_to_device()) {
         /* Print only if ok and not cancelled to avoid spurious messages */
         if (ok && !jcr->is_job_canceled()) {
            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"));
            possible_incomplete_job(jcr, last_file_index);
         }
         jcr->setJobStatus(JS_ErrorTerminated);
         ok = false;
      }
   }
   flush_jobmedia_queue(jcr);
   if (!ok && !jcr->is_JobStatus(JS_Incomplete)) {
      discard_data_spool(dcr);
   } else {
      /* Note: if commit is OK, the device will remain blocked */
      commit_data_spool(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(dcr->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, ec));

   /*
    * Release the device -- and send final Vol info to DIR
    *  and unlock it.
    */
   release_device(dcr);

   if ((!ok || jcr->is_job_canceled()) && !jcr->is_JobStatus(JS_Incomplete)) {
      discard_attribute_spool(jcr);
   } else {
      commit_attribute_spool(jcr);
   }

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

   Dmsg1(100, "return from do_append_data() ok=%d\n", ok);
   return ok;
}
void Meta_update(bool change)
{
#define GIVE_META_SERVER_A_HINT	180

    char *string = meta_update_string, freebases[120];
    int i, num_active_players, active_per_team[MAX_TEAMS];
    size_t len, max_size;
    time_t currentTime;
    const char *game_mode;
    static time_t lastMetaSendTime = 0;
    static int queue_length = 0;
    bool first;

    if (!options.reportToMetaServer)
	return;

    currentTime = time(NULL);
    if (!change) {
	if (currentTime - lastMetaSendTime < GIVE_META_SERVER_A_HINT) {
	    if (NumQueuedPlayers == queue_length ||
		currentTime - lastMetaSendTime < 5)
		return;
	}
    }

    Meta_update_max_size_tuner();
    max_size = options.metaUpdateMaxSize;

    lastMetaSendTime = currentTime;
    queue_length = NumQueuedPlayers;

    /* Find out the number of active players. */
    num_active_players = 0;
    memset(active_per_team, 0, sizeof active_per_team);

    for (i = 0; i < NumPlayers; i++) {
	player_t *pl = Player_by_index(i);

	if (!Player_is_human(pl))
	    /*|| Player_is_paused(pl)) // reporting paused players, 
	     * will appear in team 0
	     */
	    continue;

	num_active_players++;
	if (BIT(world->rules->mode, TEAM_PLAY))
	    active_per_team[pl->team]++;
    }

    game_mode = Describe_game_status();

    /* calculate number of available homebases per team. */
    freebases[0] = '\0';
    if (BIT(world->rules->mode, TEAM_PLAY)) {
	bool firstteam = true;

	for (i = 0; i < MAX_TEAMS; i++) {
	    team_t *team = Team_by_index(i);

	    if (i == options.robotTeam && options.reserveRobotTeam)
		continue;

	    if (team->NumBases > 0) {
		char str[32];

		snprintf(str, sizeof(str), "%s%d=%d",
			 (firstteam ? "" : ","), i,
			 team->NumBases - active_per_team[i]);
		firstteam = false;
		strlcat(freebases, str, sizeof(freebases));
	    }
	}
    }
    else
	snprintf(freebases, sizeof(freebases), "=%d",
		 Num_bases() - num_active_players - login_in_progress);

    snprintf(string, max_size,
	     "add server %s\n"
	     "add users %d\n"
	     "add version %s\n"
	     "add map %s\n"
	     "add sizeMap %3dx%3d\n"
	     "add author %s\n"
	     "add bases %d\n"
	     "add fps %d\n"
	     "add port %d\n"
	     "add mode %s\n"
	     "add teams %d\n"
	     "add free %s\n"
	     "add timing %d\n"
	     "add stime %ld\n"
	     "add queue %d\n"
	     "add sound %s\n",
	     Server.host, num_active_players,
	     META_VERSION, world->name, world->x, world->y, world->author,
	     Num_bases(), FPS, options.contactPort,
	     game_mode, world->NumTeamBases, freebases,
	     BIT(world->rules->mode, TIMING) ? 1:0,
	     (long)(time(NULL) - serverStartTime),
	     queue_length, options.sound ? "yes" : "no");


    /*
     * 'len' must always hold the exact number of
     * non-zero bytes which are in string[].
     */
    len = strlen(string);
    first = true;

    for (i = 0; i < NumPlayers; i++) {
	player_t *pl = Player_by_index(i);
	char str[4 * MAX_CHARS];
	char tstr[32];

	if (!Player_is_human(pl))
	    /*|| Player_is_paused(pl) // reporting paused players, 
             * will appear in team 0
             */
	    continue;

	snprintf(str, sizeof(str),
		 "%s%s=%s@%s",
		 first ? "add players " : ",",
		 pl->name,
		 pl->username,
		 pl->hostname);

	if (BIT(world->rules->mode, TEAM_PLAY)) {
	    snprintf(tstr, sizeof(tstr), "{%d}", pl->team);
	    strlcat(str, tstr, sizeof(str));
	}

	if (len + strlen(str) + 1 > max_size)
	    break;

	strlcat(string, str, max_size);
	len += strlen(str);
	first = false;
    }

#if 0
    /* kps - don't bother to send status, it probably isn't useful */
    if (len + MSG_LEN < max_size) {
	char status[MAX_STR_LEN];

	strlcpy(&string[len], "\nadd status ", max_size - len);
	len += strlen(&string[len]);

	Server_info(status, sizeof(status));

	strlcpy(&string[len], status, max_size - len);
	len += strlen(&string[len]);
    }
#else
    {
	char status[MAX_STR_LEN];

	strlcpy(status,
		"\nadd status Use server text interface to query status.",
		sizeof(status));
	if (len + strlen(status) + 1 <= max_size) {
	    strlcat(string, status, max_size);
	    len += strlen(status);
	}
    }
#endif

#if 0
    warn("Meta update string len is %d (limit is %d)",
	 len, options.metaUpdateMaxSize);

    asciidump(string, len);
#endif

    Meta_send(string, len + 1);
}