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