/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
DEVICE *dev = NULL;
DCR *dcr;
DEVRES *device = NULL;
+int exit_code = 0;
/* Forward referenced subroutines */
}
dcr = jcr->dcr;
if (!open_the_device()) {
- goto terminate;
+ exit(1);
}
Dmsg0(200, "Do tape commands\n");
do_tape_cmds();
terminate:
- terminate_btape(0);
- return 0;
+ terminate_btape(exit_code);
}
static void terminate_btape(int stat)
* it to make sure it is valid. Bacula can skip this validation
* if you set "Backward space record = no"
*/
-static int re_read_block_test()
+static bool re_read_block_test()
{
DEV_BLOCK *block = dcr->block;
DEV_RECORD *rec;
- int stat = 0;
+ bool rc = false;
int len;
if (!(dev->capabilities & CAP_BSR)) {
Pmsg0(-1, _("Skipping read backwards test because BSR turned off.\n"));
- return 0;
+ return true;
}
Pmsg0(-1, _("\n=== Write, backup, and re-read test ===\n\n"
Pmsg0(0, _("\nBlock re-read correct. Test succeeded!\n"));
Pmsg0(-1, _("=== End Write, backup, and re-read test ===\n\n"));
- stat = 1;
+ rc = true;
bail_out:
free_record(rec);
- if (stat == 0) {
+ if (!rc) {
Pmsg0(0, _("This is not terribly serious since Bacula only uses\n"
"this function to verify the last block written to the\n"
"tape. Bacula will skip the last block verification\n"
"Backward Space Record = No\n\n"
"to your Storage daemon's Device resource definition.\n"));
}
- return stat;
+ return rc;
}
+const int num_recs = 10000;
-/*
- * This test writes Bacula blocks to the tape in
- * several files. It then rewinds the tape and attepts
- * to read these blocks back checking the data.
- */
-static int write_read_test()
+static bool write_two_files()
{
DEV_BLOCK *block;
DEV_RECORD *rec;
- int stat = 0;
int len, i, j;
int *p;
+ bool rc = false; /* bad return code */
- Pmsg0(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
- "I'm going to write 1000 records and an EOF\n"
- "then write 1000 records and an EOF, then rewind,\n"
+ Pmsg2(-1, _("\n=== Write, rewind, and re-read test ===\n\n"
+ "I'm going to write %d records and an EOF\n"
+ "then write %d records and an EOF, then rewind,\n"
"and re-read the data to verify that it is correct.\n\n"
- "This is an *essential* feature ...\n\n"));
+ "This is an *essential* feature ...\n\n"), num_recs, num_recs);
+
block = dcr->block;
+ empty_block(block);
rec = new_record();
+ rec->data = check_pool_memory_size(rec->data, block->buf_len);
+ rec->data_len = block->buf_len-100;
+ len = rec->data_len/sizeof(i);
+
if (!dev->rewind(dcr)) {
Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
goto bail_out;
}
- rec->data = check_pool_memory_size(rec->data, block->buf_len);
- rec->data_len = block->buf_len-100;
- len = rec->data_len/sizeof(i);
- for (i=1; i<=1000; i++) {
+
+ for (i=1; i<=num_recs; i++) {
p = (int *)rec->data;
for (j=0; j<len; j++) {
*p++ = i;
goto bail_out;
}
}
- Pmsg1(0, _("Wrote 1000 blocks of %d bytes.\n"), rec->data_len);
+ Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
weofcmd();
- for (i=1001; i<=2000; i++) {
+ for (i=num_recs+1; i<=2*num_recs; i++) {
p = (int *)rec->data;
for (j=0; j<len; j++) {
*p++ = i;
goto bail_out;
}
}
- Pmsg1(0, _("Wrote 1000 blocks of %d bytes.\n"), rec->data_len);
+ Pmsg2(0, _("Wrote %d blocks of %d bytes.\n"), num_recs, rec->data_len);
weofcmd();
if (dev->has_cap(CAP_TWOEOF)) {
weofcmd();
}
+ rc = true;
+
+bail_out:
+ free_record(rec);
+ if (!rc) {
+ exit_code = 1;
+ }
+ return rc;
+
+}
+
+/*
+ * This test writes Bacula blocks to the tape in
+ * several files. It then rewinds the tape and attepts
+ * to read these blocks back checking the data.
+ */
+static bool write_read_test()
+{
+ DEV_BLOCK *block;
+ DEV_RECORD *rec;
+ bool rc = false;
+ int len, i, j;
+ int *p;
+
+ rec = new_record();
+
+ if (!write_two_files()) {
+ goto bail_out;
+ }
+
+ block = dcr->block;
+ empty_block(block);
+
if (!dev->rewind(dcr)) {
Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
goto bail_out;
} else {
Pmsg0(0, _("Rewind OK.\n"));
}
- for (i=1; i<=2000; i++) {
+
+ rec->data = check_pool_memory_size(rec->data, block->buf_len);
+ rec->data_len = block->buf_len-100;
+ len = rec->data_len/sizeof(i);
+
+ /* Now read it back */
+ for (i=1; i<=2*num_recs; i++) {
read_again:
if (!read_block_from_dev(dcr, NO_BLOCK_NUMBER_CHECK)) {
berrno be;
if (dev_state(dev, ST_EOF)) {
Pmsg0(-1, _("Got EOF on tape.\n"));
- if (i == 1001) {
+ if (i == num_recs+1) {
goto read_again;
}
}
}
p++;
}
- if (i == 1000 || i == 2000) {
- Pmsg0(-1, _("1000 blocks re-read correctly.\n"));
+ if (i == num_recs || i == 2*num_recs) {
+ Pmsg1(-1, _("%d blocks re-read correctly.\n"), num_recs);
}
}
Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
- stat = 1;
+ rc = true;
bail_out:
free_record(rec);
- return stat;
+ if (!rc) {
+ exit_code = 1;
+ }
+ return rc;
}
/*
* several files. It then rewinds the tape and attepts
* to read these blocks back checking the data.
*/
-static int position_test()
+static bool position_test()
{
DEV_BLOCK *block = dcr->block;
DEV_RECORD *rec;
- int stat = 0;
- int len, i, j;
- bool ok = true;
+ bool rc = false;
+ int len, j;
+ bool more = true;
int recno = 0;
int file = 0, blk = 0;
int *p;
bool got_eof = false;
- Pmsg0(-1, _("\n=== Write, rewind, and position test ===\n\n"
- "I'm going to write 1000 records and an EOF\n"
- "then write 1000 records and an EOF, then rewind,\n"
- "and position to a few blocks and verify that it is correct.\n\n"
- "This is an *essential* feature ...\n\n"));
+ Pmsg0(0, _("Block position test\n"));
+ block = dcr->block;
empty_block(block);
rec = new_record();
- if (!dev->rewind(dcr)) {
- Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
- goto bail_out;
- }
rec->data = check_pool_memory_size(rec->data, block->buf_len);
rec->data_len = block->buf_len-100;
- len = rec->data_len/sizeof(i);
- for (i=1; i<=1000; i++) {
- p = (int *)rec->data;
- for (j=0; j<len; j++) {
- *p++ = i;
- }
- if (!write_record_to_block(block, rec)) {
- Pmsg0(0, _("Error writing record to block.\n"));
- goto bail_out;
- }
- if (!write_block_to_dev(dcr)) {
- Pmsg0(0, _("Error writing block to device.\n"));
- goto bail_out;
- }
- }
- Pmsg1(0, _("Wrote 1000 blocks of %d bytes.\n"), rec->data_len);
- weofcmd();
- for (i=1001; i<=2000; i++) {
- p = (int *)rec->data;
- for (j=0; j<len; j++) {
- *p++ = i;
- }
- if (!write_record_to_block(block, rec)) {
- Pmsg0(0, _("Error writing record to block.\n"));
- goto bail_out;
- }
- if (!write_block_to_dev(dcr)) {
- Pmsg0(0, _("Error writing block to device.\n"));
- goto bail_out;
- }
- }
- Pmsg1(0, _("Wrote 1000 blocks of %d bytes.\n"), rec->data_len);
- weofcmd();
- if (dev->has_cap(CAP_TWOEOF)) {
- weofcmd();
- }
+ len = rec->data_len/sizeof(j);
+
if (!dev->rewind(dcr)) {
Pmsg1(0, _("Bad status from rewind. ERR=%s\n"), dev->bstrerror());
goto bail_out;
Pmsg0(0, _("Rewind OK.\n"));
}
- while(ok) {
+ while (more) {
/* Set up next item to read based on where we are */
+ /* At each step, recno is what we print for the "block number"
+ * and file, blk are the real positions to go to.
+ */
switch (recno) {
case 0:
recno = 5;
blk = 200;
break;
case 201:
- recno = 1000;
+ recno = num_recs;
file = 0;
- blk = 999;
+ blk = num_recs-1;
break;
- case 1000:
- recno = 1001;
+ case num_recs:
+ recno = num_recs+1;
file = 1;
blk = 0;
break;
- case 1001:
- recno = 1601;
+ case num_recs+1:
+ recno = num_recs+601;
file = 1;
blk = 600;
break;
- case 1601:
- recno = 2000;
+ case num_recs+601:
+ recno = 2*num_recs;
file = 1;
- blk = 999;
+ blk = num_recs-1;
break;
- case 2000:
- ok = false;
+ case 2*num_recs:
+ more = false;
continue;
}
Pmsg2(-1, _("Reposition to file:block %d:%d\n"), file, blk);
Pmsg1(-1, _("Block %d re-read correctly.\n"), recno);
}
Pmsg0(-1, _("=== Test Succeeded. End Write, rewind, and re-read test ===\n\n"));
- stat = 1;
+ rc = true;
bail_out:
free_record(rec);
- return stat;
+ return rc;
}
* This test assumes that the append test has been done,
* then it tests the fsf function.
*/
-static int fsf_test()
+static bool fsf_test()
{
bool set_off = false;
goto bail_out;
}
Pmsg0(-1, _("\n=== End Forward space files test ===\n\n"));
- return 1;
+ return true;
bail_out:
Pmsg0(-1, _("\nThe forward space file test failed.\n"));
"Some systems, e.g. OpenBSD, require you to set\n"
" Use MTIOCGET= no\n"
"in your device resource. Use with caution.\n"));
- return -2;
+ return false;
}
int stat;
if (!write_read_test()) {
+ exit_code = 1;
return;
}
if (!position_test()) {
+ exit_code = 1;
return;
}
"Some systems, e.g. OpenBSD, require you to set\n"
" Use MTIOCGET= no\n"
"in your device resource. Use with caution.\n"));
+ exit_code = 1;
return;
}
"the tape.\n\n"));
if (stat == 1) {
- re_read_block_test();
+ if (!re_read_block_test()) {
+ exit_code = 1;
+ }
}
- fsf_test(); /* do fast forward space file test */
+ if (!fsf_test()) { /* do fast forward space file test */
+ exit_code = 1;
+ }
autochanger_test(); /* do autochanger test */