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