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