1 /*
2    Bacula(R) - The Network Backup Solution
3 
4    Copyright (C) 2000-2020 Kern Sibbald
5 
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8 
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13 
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16 
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 
20 #include "bacula.h"
21 #include "../stored/stored.h"
22 
23 extern bool parse_sd_config(CONFIG *config, const char *configfile, int exit_code);
24 
25 static CONFIG *config;
26 
27 void *start_heap;
28 #define CONFIG_FILE "bacula-sd.conf"
29 char *configfile = NULL;
30 bool detect_errors = false;
31 int  errors = 0;
32 
usage()33 static void usage()
34 {
35    fprintf(stderr, _(
36 PROG_COPYRIGHT
37 "\n%sVersion: %s (%s)\n\n"
38 "Usage: cloud_test [options] <device-name>\n"
39 "       -b <file>       specify a bootstrap file\n"
40 "       -c <file>       specify a Storage configuration file\n"
41 "       -d <nn>         set debug level to <nn>\n"
42 "       -dt             print timestamp in debug output\n"
43 "       -v              be verbose\n"
44 "       -V              specify Volume names (separated by |)\n"
45 "       -?              print this message\n\n"), 2000, "", VERSION, BDATE);
46    exit(1);
47 }
48 
get_session_record(JCR * jcr,DEVICE * dev,DEV_RECORD * rec,SESSION_LABEL * sessrec)49 static void get_session_record(JCR *jcr, DEVICE *dev, DEV_RECORD *rec, SESSION_LABEL *sessrec)
50 {
51    const char *rtype;
52    memset(sessrec, 0, sizeof(SESSION_LABEL));
53    jcr->JobId = 0;
54    switch (rec->FileIndex) {
55    case PRE_LABEL:
56       rtype = _("Fresh Volume Label");
57       break;
58    case VOL_LABEL:
59       rtype = _("Volume Label");
60       unser_volume_label(dev, rec);
61       break;
62    case SOS_LABEL:
63       rtype = _("Begin Job Session");
64       unser_session_label(sessrec, rec);
65       jcr->JobId = sessrec->JobId;
66       break;
67    case EOS_LABEL:
68       rtype = _("End Job Session");
69       break;
70    case 0:
71    case EOM_LABEL:
72       rtype = _("End of Medium");
73       break;
74    case EOT_LABEL:
75       rtype = _("End of Physical Medium");
76       break;
77    case SOB_LABEL:
78       rtype = _("Start of object");
79       break;
80    case EOB_LABEL:
81       rtype = _("End of object");
82       break;
83    default:
84       rtype = _("Unknown");
85       Dmsg1(10, "FI rtype=%d unknown\n", rec->FileIndex);
86       break;
87    }
88    Dmsg5(10, "%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n",
89          rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
90    if (verbose) {
91       Pmsg5(-1, _("%s Record: VolSessionId=%d VolSessionTime=%d JobId=%d DataLen=%d\n"),
92             rtype, rec->VolSessionId, rec->VolSessionTime, rec->Stream, rec->data_len);
93    }
94 }
95 
96 /* List just block information */
do_blocks(JCR * jcr,DCR * dcr)97 static void do_blocks(JCR *jcr, DCR *dcr)
98 {
99    DEV_BLOCK *block = dcr->block;
100    DEVICE *dev = dcr->dev;
101    char buf1[100], buf2[100];
102    DEV_RECORD *rec = new_record();
103    for ( ;; ) {
104       if (!dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK)) {
105          Dmsg1(100, "!read_block(): ERR=%s\n", dev->print_errmsg());
106          if (dev->at_eot()) {
107             if (!mount_next_read_volume(dcr)) {
108                Jmsg(jcr, M_INFO, 0, _("Got EOM at file %u on device %s, Volume \"%s\"\n"),
109                   dev->file, dev->print_name(), dcr->VolumeName);
110                break;
111             }
112             /* Read and discard Volume label */
113             DEV_RECORD *record;
114             SESSION_LABEL sessrec;
115             record = new_record();
116             dcr->read_block_from_device(NO_BLOCK_NUMBER_CHECK);
117             read_record_from_block(dcr, record);
118             get_session_record(jcr, dev, record, &sessrec);
119             free_record(record);
120             Jmsg(jcr, M_INFO, 0, _("Mounted Volume \"%s\".\n"), dcr->VolumeName);
121          } else if (dev->at_eof()) {
122             Jmsg(jcr, M_INFO, 0, _("End of file %u on device %s, Volume \"%s\"\n"),
123                dev->part, dev->print_name(), dcr->VolumeName);
124             Dmsg0(20, "read_record got eof. try again\n");
125             continue;
126          } else if (dev->is_short_block()) {
127             Jmsg(jcr, M_INFO, 0, "%s", dev->print_errmsg());
128             continue;
129          } else {
130             /* I/O error */
131             errors++;
132             display_tape_error_status(jcr, dev);
133             break;
134          }
135       }
136       read_record_from_block(dcr, rec);
137       printf("Block: %d size=%d\n", block->BlockNumber, block->block_len);
138    }
139    free_record(rec);
140    return;
141 }
142 
main(int argc,char * argv[])143 int main (int argc, char *argv[])
144 {
145    int ch;
146    DEVICE *dev;
147    cloud_dev *cdev;
148    cloud_driver *driver;
149    char *VolumeName=NULL;
150    JCR *jcr=NULL;
151    BSR *bsr = NULL;
152    char *bsrName = NULL;
153    BtoolsAskDirHandler askdir_handler;
154 
155    init_askdir_handler(&askdir_handler);
156    setlocale(LC_ALL, "");
157    bindtextdomain("bacula", LOCALEDIR);
158    textdomain("bacula");
159    init_stack_dump();
160    lmgr_init_thread();
161 
162    working_directory = "/tmp";
163    my_name_is(argc, argv, "cloud_test");
164    init_msg(NULL, NULL);              /* initialize message handler */
165 
166    OSDependentInit();
167 
168 
169    while ((ch = getopt(argc, argv, "b:c:d:vV:?")) != -1) {
170       switch (ch) {
171       case 'c':                    /* specify config file */
172          if (configfile != NULL) {
173             free(configfile);
174          }
175          configfile = bstrdup(optarg);
176          break;
177 
178       case 'b':
179          bsrName = optarg;
180          break;
181 
182       case 'd':                    /* debug level */
183          if (*optarg == 't') {
184             dbg_timestamp = true;
185          } else {
186             char *p;
187             /* We probably find a tag list -d 10,sql,bvfs */
188             if ((p = strchr(optarg, ',')) != NULL) {
189                *p = 0;
190             }
191             debug_level = atoi(optarg);
192             if (debug_level <= 0) {
193                debug_level = 1;
194             }
195             if (p) {
196                debug_parse_tags(p+1, &debug_level_tags);
197             }
198          }
199          break;
200 
201       case 'v':
202          verbose++;
203          break;
204 
205       case 'V':                    /* Volume name */
206          VolumeName = optarg;
207          break;
208 
209       case '?':
210       default:
211          usage();
212 
213       } /* end switch */
214    } /* end while */
215    argc -= optind;
216    argv += optind;
217 
218    if (!argc) {
219       Pmsg0(0, _("No archive name specified\n"));
220       usage();
221    }
222 
223    if (configfile == NULL) {
224       configfile = bstrdup(CONFIG_FILE);
225    }
226 
227    config = New(CONFIG());
228    parse_sd_config(config, configfile, M_ERROR_TERM);
229    setup_me();
230    load_sd_plugins(me->plugin_directory);
231    if (bsrName) {
232       bsr = parse_bsr(NULL, bsrName);
233    }
234    jcr = setup_jcr("cloud_test", argv[0], bsr, VolumeName, SD_READ);
235    dev = jcr->dcr->dev;
236    if (!dev || dev->dev_type != B_CLOUD_DEV) {
237       Pmsg0(0, "Bad device\n");
238       exit(1);
239    }
240    do_blocks(jcr, jcr->dcr);
241    /* Start low level tests */
242    cdev = (cloud_dev *)dev;
243    driver = cdev->driver;
244 
245    /* TODO: Put here low level tests for all drivers */
246    if (!cdev->truncate_cache(jcr->dcr)) {
247       Pmsg1(0, "Unable to truncate the cache ERR=%s\n", cdev->errmsg);
248    }
249 
250    if (jcr) {
251       release_device(jcr->dcr);
252       free_jcr(jcr);
253       dev->term(NULL);
254    }
255    return 0;
256 }
257