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"); }
/* * 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); }