static void statcmd();
static void unfillcmd();
static int flush_block(DEV_BLOCK *block, int dump);
-static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec);
+static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec);
static int my_mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
static void scan_blocks();
static void set_volume_name(char *VolName, int volnum);
static void rawfill_cmd();
+static void bfill_cmd();
/* Static variables */
static uint64_t VolBytes;
static time_t now;
static double kbs;
-static long file_index;
+static int32_t file_index;
static int end_of_tape = 0;
static uint32_t LastBlock = 0;
static uint32_t eot_block;
while ((ch = getopt(argc, argv, "b:c:d:sv?")) != -1) {
switch (ch) {
- case 'b': /* bootstrap file */
- bsr = parse_bsr(NULL, optarg);
-// dump_bsr(bsr);
- break;
+ case 'b': /* bootstrap file */
+ bsr = parse_bsr(NULL, optarg);
+// dump_bsr(bsr, true);
+ break;
- case 'c': /* specify config file */
- if (configfile != NULL) {
- free(configfile);
- }
- configfile = bstrdup(optarg);
- break;
+ case 'c': /* specify config file */
+ if (configfile != NULL) {
+ free(configfile);
+ }
+ configfile = bstrdup(optarg);
+ break;
- case 'd': /* set debug level */
- debug_level = atoi(optarg);
- if (debug_level <= 0) {
- debug_level = 1;
- }
- break;
+ case 'd': /* set debug level */
+ debug_level = atoi(optarg);
+ if (debug_level <= 0) {
+ debug_level = 1;
+ }
+ break;
- case 's':
- signals = FALSE;
- break;
+ case 's':
+ signals = FALSE;
+ break;
- case 'v':
- verbose++;
- break;
+ case 'v':
+ verbose++;
+ break;
- case '?':
- default:
- helpcmd();
- exit(0);
+ case '?':
+ default:
+ helpcmd();
+ exit(0);
}
}
static void eomcmd()
{
if (!eod_dev(dev)) {
- Pmsg1(0, _("Bad status from MTEOD. ERR=%s\n"), strerror_dev(dev));
+ Pmsg1(0, "%s", strerror_dev(dev));
return;
} else {
Pmsg0(0, _("Moved to end of medium.\n"));
*/
static void bsfcmd()
{
- int stat;
- if ((stat=bsf_dev(dev, 1)) < 0) {
- Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), strerror(errno));
+ if (!bsf_dev(dev, 1)) {
+ Pmsg1(0, _("Bad status from bsf. ERR=%s\n"), strerror_dev(dev));
} else {
- Pmsg0(0, _("Back spaced one file.\n"));
+ Pmsg0(0, _("Backspaced one file.\n"));
}
}
*/
static void bsrcmd()
{
- int stat;
-
- if ((stat=bsr_dev(dev, 1)) < 0) {
- Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), strerror(errno));
+ if (!bsr_dev(dev, 1)) {
+ Pmsg1(0, _("Bad status from bsr. ERR=%s\n"), strerror_dev(dev));
} else {
- Pmsg0(0, _("Back spaced one record.\n"));
+ Pmsg0(0, _("Backspaced one record.\n"));
}
}
*/
static void capcmd()
{
- printf(_("Device capabilities:\n"));
+ printf(_("Configured device capabilities:\n"));
printf("%sEOF ", dev->capabilities & CAP_EOF ? "" : "!");
printf("%sBSR ", dev->capabilities & CAP_BSR ? "" : "!");
printf("%sBSF ", dev->capabilities & CAP_BSF ? "" : "!");
}
weofcmd();
weofcmd();
- if (bsf_dev(dev, 1) != 0) {
- Pmsg1(0, _("Back space file failed! ERR=%s\n"), strerror(dev->dev_errno));
+ if (!bsf_dev(dev, 1)) {
+ Pmsg1(0, _("Backspace file failed! ERR=%s\n"), strerror_dev(dev));
goto bail_out;
}
- if (bsf_dev(dev, 1) != 0) {
- Pmsg1(0, _("Back space file failed! ERR=%s\n"), strerror(dev->dev_errno));
+ if (!bsf_dev(dev, 1)) {
+ Pmsg1(0, _("Backspace file failed! ERR=%s\n"), strerror_dev(dev));
goto bail_out;
}
Pmsg0(0, "Backspaced over two EOFs OK.\n");
- if (bsr_dev(dev, 1) != 0) {
- Pmsg1(0, _("Back space record failed! ERR=%s\n"), strerror(dev->dev_errno));
+ if (!bsr_dev(dev, 1)) {
+ Pmsg1(0, _("Backspace record failed! ERR=%s\n"), strerror_dev(dev));
goto bail_out;
}
Pmsg0(0, "Backspace record OK.\n");
if (stat == 1) {
Pmsg0(-1, "\n\nIt looks like the test worked this time, please add:\n\n"
" Hardware End of Medium = No\n"
- " BSR at EOM = yes\n\n"
+ " BSF at EOM = yes\n\n"
"to your Device resource in the Storage conf file.\n");
goto all_done;
}
"End of File mark.\n"
"1 block of 64448 bytes in file 4\n"
"End of File mark.\n"
- "Total files=4, blocks=7, bytes = 451136\n"
+ "Total files=4, blocks=7, bytes = 451,136\n"
"=== End sample correct output ===\n\n"));
Pmsg0(-1, _("If the above scan output is not identical to the\n"
/* Forward space a record */
static void fsrcmd()
{
- int stat;
-
- if ((stat=fsr_dev(dev, 1)) < 0) {
- Pmsg2(0, "Bad status from fsr %d. ERR=%s\n", stat, strerror_dev(dev));
+ if (!fsr_dev(dev, 1)) {
+ Pmsg1(0, "Bad status from fsr. ERR=%s\n", strerror_dev(dev));
return;
}
Pmsg0(0, "Forward spaced one record.\n");
blocks++;
tot_blocks++;
bytes += block->block_len;
- Dmsg5(100, "Blk=%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
- block->BlockNumber, block->block_len, block->BlockVer,
+ Dmsg6(100, "Blk_blk=%u dev_blk=%u blen=%u bVer=%d SessId=%u SessTim=%u\n",
+ block->BlockNumber, dev->block_num, block->block_len, block->BlockVer,
block->VolSessionId, block->VolSessionTime);
if (verbose == 1) {
DEV_RECORD *rec = new_record();
read_record_from_block(block, rec);
- Pmsg7(-1, "Block: %u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n",
- block->BlockNumber, block->block_len,
+ Pmsg8(-1, "Blk_block: %u dev_blk=%u blen=%u First rec FI=%s SessId=%u SessTim=%u Strm=%s rlen=%d\n",
+ block->BlockNumber, dev->block_num, block->block_len,
FI_to_ascii(rec->FileIndex), rec->VolSessionId, rec->VolSessionTime,
stream_to_ascii(rec->Stream, rec->FileIndex), rec->data_len);
rec->remainder = 0;
*/
jcr->VolFirstIndex = 0;
time(&jcr->run_time); /* start counting time for rates */
- Pmsg0(-1, "Begin writing records to first tape ...\n");
+ Pmsg0(-1, "Begin writing Bacula records to first tape ...\n");
+ Pmsg1(-1, "Block num = %d\n", dev->block_num);
for (file_index = 0; ok && !job_canceled(jcr); ) {
rec.VolSessionId = jcr->VolSessionId;
rec.VolSessionTime = jcr->VolSessionTime;
/* Write block to tape */
if (!flush_block(block, 1)) {
- return;
+ break;
}
/* Every 5000 blocks (approx 322MB) report where we are.
now = 1;
}
kbs = (double)dev->VolCatInfo.VolCatBytes / (1000.0 * (double)now);
- Pmsg3(-1, "Wrote block=%u, VolBytes=%s rate=%.1f KB/s\n", block->BlockNumber,
+ Pmsg4(-1, "Wrote block=%u, blk_num=%d VolBytes=%s rate=%.1f KB/s\n", block->BlockNumber,
+ dev->block_num,
edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, ec1), (float)kbs);
}
/* Every 15000 blocks (approx 1GB) write an EOF.
free_block(block);
free_memory(rec.data);
- Pmsg0(-1, _("\n\nDone filling tape. Now beginning re-read of tape ...\n"));
dump_block(last_block, _("Last block written to tape.\n"));
+ Pmsg0(-1, _("\n\nDone filling tape. Now beginning re-read of tape ...\n"));
+
unfillcmd();
}
/*
* We are called here from "unfill" for each record on the tape.
*/
-static void record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
+static int record_cb(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, DEV_RECORD *rec)
{
SESSION_LABEL label;
switch (rec->FileIndex) {
case PRE_LABEL:
Pmsg0(-1, "Volume is prelabeled. This tape cannot be scanned.\n");
- return;
+ return 1;;
case VOL_LABEL:
unser_volume_label(dev, rec);
Pmsg3(-1, "VOL_LABEL: block=%u size=%d vol=%s\n", block->BlockNumber,
default:
break;
}
- return;
+ return 1;
}
if (++file_index != rec->FileIndex) {
Pmsg3(000, "Incorrect FileIndex in Block %u. Got %d, expected %d.\n",
if (end_of_tape) {
Pmsg1(000, "End of all blocks. Block=%u\n", block->BlockNumber);
}
+ return 1;
}
this_file = dev->file;
this_block_num = dev->block_num;
if (!write_block_to_dev(jcr, dev, block)) {
- Pmsg0(000, strerror_dev(dev));
Pmsg3(000, "Block not written: FileIndex=%u Block=%u Size=%u\n",
(unsigned)file_index, block->BlockNumber, block->block_len);
Pmsg2(000, "last_block_num=%u this_block_num=%d\n", last_block_num,
memset(rec->data, i & 0xFF, i);
rec->data_len = i;
rewindcmd();
- Pmsg1(0, "Begin writing %d blocks to tape ...\n", count);
+ Pmsg1(0, "Begin writing %d Bacula blocks to tape ...\n", count);
for (i=0; i < count; i++) {
if (i % 100 == 0) {
printf("+");
+ fflush(stdout);
}
if (!write_record_to_block(block, rec)) {
Pmsg0(0, _("Error writing record to block.\n"));
}
+/*
+ * Fill a tape using raw write() command
+ */
static void rawfill_cmd()
{
DEV_BLOCK *block;
return;
}
p = (uint32_t *)block->buf;
- Pmsg1(0, "Begin writing blocks of %u bytes.\n", block->buf_len);
+ Pmsg1(0, "Begin writing raw blocks of %u bytes.\n", block->buf_len);
for ( ;; ) {
*p = block_num;
stat = write(dev->fd, block->buf, block->buf_len);
if (stat == (int)block->buf_len) {
if ((block_num++ % 100) == 0) {
printf("+");
+ fflush(stdout);
}
continue;
}
}
my_errno = errno;
printf("\n");
- weofcmd();
printf("Write failed at block %u. stat=%d ERR=%s\n", block_num, stat,
strerror(my_errno));
+ weofcmd();
free_block(block);
+}
+
+/*
+ * Fill a tape using raw write() command
+ */
+static void bfill_cmd()
+{
+ DEV_BLOCK *block;
+ uint32_t block_num = 0;
+ uint32_t *p;
+ int my_errno;
+ int fd;
+
+ block = new_block(dev);
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd) {
+ read(fd, block->buf, block->buf_len);
+ } else {
+ Pmsg0(0, "Cannot open /dev/urandom.\n");
+ free_block(block);
+ return;
+ }
+ p = (uint32_t *)block->buf;
+ Pmsg1(0, "Begin writing Bacula blocks of %u bytes.\n", block->buf_len);
+ for ( ;; ) {
+ *p = block_num;
+ block->binbuf = block->buf_len;
+ block->bufp = block->buf + block->binbuf;
+ if (!write_block_to_dev(jcr, dev, block)) {
+ break;
+ }
+ if ((block_num++ % 100) == 0) {
+ printf("+");
+ fflush(stdout);
+ }
+ }
+ my_errno = errno;
+ printf("\n");
+ printf("Write failed at block %u.\n", block_num);
+ weofcmd();
+ free_block(block);
}
+
struct cmdstruct { char *key; void (*func)(); char *help; };
static struct cmdstruct commands[] = {
{"bsf", bsfcmd, "backspace file"},
{"bsr", bsrcmd, "backspace record"},
+ {"bfill", bfill_cmd, "fill tape using Bacula writes"},
{"cap", capcmd, "list device capabilities"},
{"clear", clearcmd, "clear tape errors"},
{"eod", eodcmd, "go to end of Bacula data for append"},
{
unsigned int i;
usage();
+ printf(_("Interactive commands:\n"));
printf(_(" Command Description\n ======= ===========\n"));
for (i=0; i<comsize; i++)
printf(" %-10s %s\n", commands[i].key, commands[i].help);
{
fprintf(stderr, _(
"\nVersion: " VERSION " (" BDATE ")\n\n"
-"Usage: btape [-c config_file] [-d debug_level] [device_name]\n"
+"Usage: btape <options> <device_name>\n"
" -c <file> set configuration file to file\n"
-" -dnn set debug level to nn\n"
+" -d <nn> set debug level to nn\n"
" -s turn off signals\n"
" -t open the default tape device\n"
" -? print this message.\n"
}
/* Dummies to replace askdir.c */
-int dir_get_volume_info(JCR *jcr, int writing) { return 1;}
+int dir_get_volume_info(JCR *jcr, enum get_vol_info_rw writing) { return 1;}
int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel) { return 1; }
int dir_create_jobmedia_record(JCR *jcr) { return 1; }
int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec) { return 1;}