2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2016 Kern Sibbald
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.
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.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Utility routines for "tool" programs such as bscan, bls,
22 * bextract, ... Some routines also used by Bacula.
26 * Normally nothing in this file is called by the Storage
27 * daemon because we interact more directly with the user
35 /* Forward referenced functions */
36 static DCR *setup_to_access_device(JCR *jcr, char *dev_name,
37 const char *VolumeName, bool writing, bool read_dedup_data);
38 static DEVRES *find_device_res(char *device_name, bool writing);
39 static void my_free_jcr(JCR *jcr);
41 /* Imported variables -- eliminate some day */
42 extern char *configfile;
45 char *rec_state_bits_to_str(DEV_RECORD *rec)
49 if (rec->state_bits & REC_NO_HEADER) {
50 strcat(buf, _("Nohdr,"));
52 if (is_partial_record(rec)) {
53 strcat(buf, _("partial,"));
55 if (rec->state_bits & REC_BLOCK_EMPTY) {
56 strcat(buf, _("empty,"));
58 if (rec->state_bits & REC_NO_MATCH) {
59 strcat(buf, _("Nomatch,"));
61 if (rec->state_bits & REC_CONTINUATION) {
62 strcat(buf, _("cont,"));
65 buf[strlen(buf)-1] = 0;
72 * Setup a pointer to my resource me
77 me = (STORES *)GetNextRes(R_STORAGE, NULL);
80 Emsg1(M_ERROR_TERM, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
87 * Setup a "daemon" JCR for the various standalone
88 * tools (e.g. bls, bextract, bscan, ...)
90 JCR *setup_jcr(const char *name, char *dev_name, BSR *bsr,
91 const char *VolumeName, bool writing, bool read_dedup_data)
94 JCR *jcr = new_jcr(sizeof(JCR), my_free_jcr);
96 jcr->VolSessionId = 1;
97 jcr->VolSessionTime = (uint32_t)time(NULL);
98 jcr->NumReadVolumes = 0;
99 jcr->NumWriteVolumes = 0;
101 jcr->setJobType(JT_CONSOLE);
102 jcr->setJobLevel(L_FULL);
103 jcr->JobStatus = JS_Terminated;
104 jcr->where = bstrdup("");
105 jcr->job_name = get_pool_memory(PM_FNAME);
106 pm_strcpy(jcr->job_name, "Dummy.Job.Name");
107 jcr->client_name = get_pool_memory(PM_FNAME);
108 pm_strcpy(jcr->client_name, "Dummy.Client.Name");
109 bstrncpy(jcr->Job, name, sizeof(jcr->Job));
110 jcr->fileset_name = get_pool_memory(PM_FNAME);
111 pm_strcpy(jcr->fileset_name, "Dummy.fileset.name");
112 jcr->fileset_md5 = get_pool_memory(PM_FNAME);
113 pm_strcpy(jcr->fileset_md5, "Dummy.fileset.md5");
115 create_volume_lists();
117 dcr = setup_to_access_device(jcr, dev_name, VolumeName, writing, read_dedup_data);
121 if (!bsr && VolumeName) {
122 bstrncpy(dcr->VolumeName, VolumeName, sizeof(dcr->VolumeName));
124 bstrncpy(dcr->pool_name, "Default", sizeof(dcr->pool_name));
125 bstrncpy(dcr->pool_type, "Backup", sizeof(dcr->pool_type));
130 * Setup device, jcr, and prepare to access device.
131 * If the caller wants read access, acquire the device, otherwise,
132 * the caller will do it.
134 static DCR *setup_to_access_device(JCR *jcr, char *dev_name,
135 const char *VolumeName, bool writing, bool read_dedup_data)
141 char VolName[MAX_NAME_LENGTH];
143 init_reservations_lock();
146 * If no volume name already given and no bsr, and it is a file,
147 * try getting name from Filename
150 bstrncpy(VolName, VolumeName, sizeof(VolName));
151 if (strlen(VolumeName) >= MAX_NAME_LENGTH) {
152 Jmsg0(jcr, M_ERROR, 0, _("Volume name or names is too long. Please use a .bsr file.\n"));
157 if (!jcr->bsr && VolName[0] == 0) {
158 if (strncmp(dev_name, "/dev/", 5) != 0) {
159 /* Try stripping file part */
160 p = dev_name + strlen(dev_name);
162 while (p >= dev_name && !IsPathSeparator(*p))
164 if (IsPathSeparator(*p)) {
165 bstrncpy(VolName, p+1, sizeof(VolName));
171 if ((device=find_device_res(dev_name, writing)) == NULL) {
172 Jmsg2(jcr, M_FATAL, 0, _("Cannot find device \"%s\" in config file %s.\n"),
173 dev_name, configfile);
177 dev = init_dev(jcr, device);
179 Jmsg1(jcr, M_FATAL, 0, _("Cannot init device %s\n"), dev_name);
183 jcr->dcr = dcr = new_dcr(jcr, NULL, dev, writing);
185 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
187 bstrncpy(dcr->dev_name, device->device_name, sizeof(dcr->dev_name));
189 create_restore_volume_list(jcr);
191 if (!writing) { /* read only access? */
192 Dmsg0(100, "Acquire device for read\n");
193 if (!acquire_device_for_read(dcr)) {
198 if (!first_open_device(dcr)) {
199 Jmsg1(jcr, M_FATAL, 0, _("Cannot open %s\n"), dev->print_name());
202 jcr->dcr = dcr; /* write dcr */
209 * Called here when freeing JCR so that we can get rid
210 * of "daemon" specific memory allocated.
212 static void my_free_jcr(JCR *jcr)
215 free_pool_memory(jcr->job_name);
216 jcr->job_name = NULL;
218 if (jcr->client_name) {
219 free_pool_memory(jcr->client_name);
220 jcr->client_name = NULL;
222 if (jcr->fileset_name) {
223 free_pool_memory(jcr->fileset_name);
224 jcr->fileset_name = NULL;
226 if (jcr->fileset_md5) {
227 free_pool_memory(jcr->fileset_md5);
228 jcr->fileset_md5 = NULL;
231 free_pool_memory(jcr->comment);
235 free_restore_volume_list(jcr);
246 * Search for device resource that corresponds to
247 * device name on command line (or default).
249 * Returns: NULL on failure
250 * Device resource pointer on success
252 static DEVRES *find_device_res(char *device_name, bool write_access)
257 Dmsg0(900, "Enter find_device_res\n");
259 foreach_res(device, R_DEVICE) {
260 Dmsg2(900, "Compare %s and %s\n", device->device_name, device_name);
261 if (strcmp(device->device_name, device_name) == 0) {
267 /* Search for name of Device resource rather than archive name */
268 if (device_name[0] == '"') {
269 int len = strlen(device_name);
270 bstrncpy(device_name, device_name+1, len+1);
273 device_name[len-1] = 0; /* zap trailing " */
276 foreach_res(device, R_DEVICE) {
277 Dmsg2(900, "Compare %s and %s\n", device->hdr.name, device_name);
278 if (strcmp(device->hdr.name, device_name) == 0) {
286 Pmsg2(0, _("Could not find device \"%s\" in config file %s.\n"), device_name,
291 Pmsg1(0, _("Using device: \"%s\" for writing.\n"), device_name);
293 Pmsg1(0, _("Using device: \"%s\" for reading.\n"), device_name);
300 * Device got an error, attempt to analyse it
302 void display_tape_error_status(JCR *jcr, DEVICE *dev)
306 status = status_dev(dev);
307 Dmsg1(20, "Device status: %x\n", status);
308 if (status & BMT_EOD)
309 Jmsg(jcr, M_ERROR, 0, _("Unexpected End of Data\n"));
310 else if (status & BMT_EOT)
311 Jmsg(jcr, M_ERROR, 0, _("Unexpected End of Tape\n"));
312 else if (status & BMT_EOF)
313 Jmsg(jcr, M_ERROR, 0, _("Unexpected End of File\n"));
314 else if (status & BMT_DR_OPEN)
315 Jmsg(jcr, M_ERROR, 0, _("Tape Door is Open\n"));
316 else if (!(status & BMT_ONLINE))
317 Jmsg(jcr, M_ERROR, 0, _("Unexpected Tape is Off-line\n"));