2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
5 Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
7 The original author of Bacula is Kern Sibbald, with contributions
8 from many others, a complete list can be found in the file AUTHORS.
10 You may use this file and others of this release according to the
11 license defined in the LICENSE file, which includes the Affero General
12 Public License, v3.0 ("AGPLv3") and some additional permissions and
13 terms pursuant to its AGPLv3 Section 7.
15 This notice must be preserved when any source code is
16 conveyed and/or propagated.
18 Bacula(R) is a registered trademark of Kern Sibbald.
22 * Utility routines for "tool" programs such as bscan, bls,
23 * bextract, ... Some routines also used by Bacula.
27 * Normally nothing in this file is called by the Storage
28 * daemon because we interact more directly with the user
36 /* Forward referenced functions */
37 static DCR *setup_to_access_device(JCR *jcr, char *dev_name,
38 const char *VolumeName, bool writing, bool read_dedup_data);
39 static DEVRES *find_device_res(char *device_name, bool writing);
40 static void my_free_jcr(JCR *jcr);
42 /* Imported variables -- eliminate some day */
43 extern char *configfile;
46 char *rec_state_bits_to_str(DEV_RECORD *rec)
50 if (rec->state_bits & REC_NO_HEADER) {
51 strcat(buf, _("Nohdr,"));
53 if (is_partial_record(rec)) {
54 strcat(buf, _("partial,"));
56 if (rec->state_bits & REC_BLOCK_EMPTY) {
57 strcat(buf, _("empty,"));
59 if (rec->state_bits & REC_NO_MATCH) {
60 strcat(buf, _("Nomatch,"));
62 if (rec->state_bits & REC_CONTINUATION) {
63 strcat(buf, _("cont,"));
66 buf[strlen(buf)-1] = 0;
73 * Setup a pointer to my resource me
78 me = (STORES *)GetNextRes(R_STORAGE, NULL);
81 Emsg1(M_ERROR_TERM, 0, _("No Storage resource defined in %s. Cannot continue.\n"),
88 * Setup a "daemon" JCR for the various standalone
89 * tools (e.g. bls, bextract, bscan, ...)
91 JCR *setup_jcr(const char *name, char *dev_name, BSR *bsr,
92 const char *VolumeName, bool writing, bool read_dedup_data)
95 JCR *jcr = new_jcr(sizeof(JCR), my_free_jcr);
97 jcr->VolSessionId = 1;
98 jcr->VolSessionTime = (uint32_t)time(NULL);
99 jcr->NumReadVolumes = 0;
100 jcr->NumWriteVolumes = 0;
102 jcr->setJobType(JT_CONSOLE);
103 jcr->setJobLevel(L_FULL);
104 jcr->JobStatus = JS_Terminated;
105 jcr->where = bstrdup("");
106 jcr->job_name = get_pool_memory(PM_FNAME);
107 pm_strcpy(jcr->job_name, "Dummy.Job.Name");
108 jcr->client_name = get_pool_memory(PM_FNAME);
109 pm_strcpy(jcr->client_name, "Dummy.Client.Name");
110 bstrncpy(jcr->Job, name, sizeof(jcr->Job));
111 jcr->fileset_name = get_pool_memory(PM_FNAME);
112 pm_strcpy(jcr->fileset_name, "Dummy.fileset.name");
113 jcr->fileset_md5 = get_pool_memory(PM_FNAME);
114 pm_strcpy(jcr->fileset_md5, "Dummy.fileset.md5");
116 create_volume_lists();
118 dcr = setup_to_access_device(jcr, dev_name, VolumeName, writing, read_dedup_data);
122 if (!bsr && VolumeName) {
123 bstrncpy(dcr->VolumeName, VolumeName, sizeof(dcr->VolumeName));
125 bstrncpy(dcr->pool_name, "Default", sizeof(dcr->pool_name));
126 bstrncpy(dcr->pool_type, "Backup", sizeof(dcr->pool_type));
131 * Setup device, jcr, and prepare to access device.
132 * If the caller wants read access, acquire the device, otherwise,
133 * the caller will do it.
135 static DCR *setup_to_access_device(JCR *jcr, char *dev_name,
136 const char *VolumeName, bool writing, bool read_dedup_data)
142 char VolName[MAX_NAME_LENGTH];
144 init_reservations_lock();
147 * If no volume name already given and no bsr, and it is a file,
148 * try getting name from Filename
151 bstrncpy(VolName, VolumeName, sizeof(VolName));
152 if (strlen(VolumeName) >= MAX_NAME_LENGTH) {
153 Jmsg0(jcr, M_ERROR, 0, _("Volume name or names is too long. Please use a .bsr file.\n"));
158 if (!jcr->bsr && VolName[0] == 0) {
159 if (strncmp(dev_name, "/dev/", 5) != 0) {
160 /* Try stripping file part */
161 p = dev_name + strlen(dev_name);
163 while (p >= dev_name && !IsPathSeparator(*p))
165 if (IsPathSeparator(*p)) {
166 bstrncpy(VolName, p+1, sizeof(VolName));
172 if ((device=find_device_res(dev_name, writing)) == NULL) {
173 Jmsg2(jcr, M_FATAL, 0, _("Cannot find device \"%s\" in config file %s.\n"),
174 dev_name, configfile);
178 dev = init_dev(jcr, device);
180 Jmsg1(jcr, M_FATAL, 0, _("Cannot init device %s\n"), dev_name);
184 jcr->dcr = dcr = new_dcr(jcr, NULL, dev, writing);
186 bstrncpy(dcr->VolumeName, VolName, sizeof(dcr->VolumeName));
188 bstrncpy(dcr->dev_name, device->device_name, sizeof(dcr->dev_name));
190 create_restore_volume_list(jcr);
192 if (!writing) { /* read only access? */
193 Dmsg0(100, "Acquire device for read\n");
194 if (!acquire_device_for_read(dcr)) {
199 if (!first_open_device(dcr)) {
200 Jmsg1(jcr, M_FATAL, 0, _("Cannot open %s\n"), dev->print_name());
203 jcr->dcr = dcr; /* write dcr */
210 * Called here when freeing JCR so that we can get rid
211 * of "daemon" specific memory allocated.
213 static void my_free_jcr(JCR *jcr)
216 free_pool_memory(jcr->job_name);
217 jcr->job_name = NULL;
219 if (jcr->client_name) {
220 free_pool_memory(jcr->client_name);
221 jcr->client_name = NULL;
223 if (jcr->fileset_name) {
224 free_pool_memory(jcr->fileset_name);
225 jcr->fileset_name = NULL;
227 if (jcr->fileset_md5) {
228 free_pool_memory(jcr->fileset_md5);
229 jcr->fileset_md5 = NULL;
232 free_pool_memory(jcr->comment);
236 free_restore_volume_list(jcr);
247 * Search for device resource that corresponds to
248 * device name on command line (or default).
250 * Returns: NULL on failure
251 * Device resource pointer on success
253 static DEVRES *find_device_res(char *device_name, bool write_access)
258 Dmsg0(900, "Enter find_device_res\n");
260 foreach_res(device, R_DEVICE) {
261 Dmsg2(900, "Compare %s and %s\n", device->device_name, device_name);
262 if (strcmp(device->device_name, device_name) == 0) {
268 /* Search for name of Device resource rather than archive name */
269 if (device_name[0] == '"') {
270 int len = strlen(device_name);
271 bstrncpy(device_name, device_name+1, len+1);
274 device_name[len-1] = 0; /* zap trailing " */
277 foreach_res(device, R_DEVICE) {
278 Dmsg2(900, "Compare %s and %s\n", device->hdr.name, device_name);
279 if (strcmp(device->hdr.name, device_name) == 0) {
287 Pmsg2(0, _("Could not find device \"%s\" in config file %s.\n"), device_name,
292 Pmsg1(0, _("Using device: \"%s\" for writing.\n"), device_name);
294 Pmsg1(0, _("Using device: \"%s\" for reading.\n"), device_name);
301 * Device got an error, attempt to analyse it
303 void display_tape_error_status(JCR *jcr, DEVICE *dev)
307 status = status_dev(dev);
308 Dmsg1(20, "Device status: %x\n", status);
309 if (status & BMT_EOD)
310 Jmsg(jcr, M_ERROR, 0, _("Unexpected End of Data\n"));
311 else if (status & BMT_EOT)
312 Jmsg(jcr, M_ERROR, 0, _("Unexpected End of Tape\n"));
313 else if (status & BMT_EOF)
314 Jmsg(jcr, M_ERROR, 0, _("Unexpected End of File\n"));
315 else if (status & BMT_DR_OPEN)
316 Jmsg(jcr, M_ERROR, 0, _("Tape Door is Open\n"));
317 else if (!(status & BMT_ONLINE))
318 Jmsg(jcr, M_ERROR, 0, _("Unexpected Tape is Off-line\n"));