2 Bacula® - The Network Backup Solution
4 Copyright (C) 2002-2008 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of John Walker.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * Routines to acquire and release a device for read/write
31 * Kern Sibbald, August MMII
36 #include "bacula.h" /* pull in global headers */
37 #include "stored.h" /* pull in Storage Deamon headers */
39 /* Forward referenced functions */
40 static void attach_dcr_to_dev(DCR *dcr);
43 /*********************************************************************
44 * Acquire device for reading.
45 * The drive should have previously been reserved by calling
46 * reserve_device_for_read(). We read the Volume label from the block and
47 * leave the block pointers just after the label.
49 * Returns: NULL if failed for any reason
52 bool acquire_device_for_read(DCR *dcr)
54 DEVICE *dev = dcr->dev;
57 bool tape_previously_mounted;
58 bool tape_initially_mounted;
60 bool try_autochanger = true;
65 Dmsg1(950, "jcr->dcr=%p\n", jcr->dcr);
66 dev->dblock(BST_DOING_ACQUIRE);
68 if (dev->num_writers > 0) {
69 Jmsg2(jcr, M_FATAL, 0, _("Acquire read: num_writers=%d not zero. Job %d canceled.\n"),
70 dev->num_writers, jcr->JobId);
74 /* Find next Volume, if any */
78 Jmsg(jcr, M_FATAL, 0, _("No volumes specified for reading. Job %s canceled.\n"),
79 edit_int64(jcr->JobId, ed1));
83 for (i=1; i<jcr->CurReadVolume; i++) {
87 Jmsg(jcr, M_FATAL, 0, _("Logic error: no next volume to read. Numvol=%d Curvol=%d\n"),
88 jcr->NumReadVolumes, jcr->CurReadVolume);
89 goto get_out; /* should not happen */
92 * Note, if we want to be able to work from a .bsr file only
93 * for disaster recovery, we must "simulate" reading the catalog
95 bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
96 bstrncpy(dcr->VolCatInfo.VolCatName, vol->VolumeName, sizeof(dcr->VolCatInfo.VolCatName));
97 bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
98 dcr->VolCatInfo.Slot = vol->Slot;
99 dcr->VolCatInfo.InChanger = vol->Slot > 0;
100 if (reserve_volume(dcr, dcr->VolumeName) == NULL) {
101 Dmsg2(100, "Could not reserve volume %s on %s\n", dcr->VolumeName,
102 dcr->dev->print_name());
103 Jmsg2(jcr, M_FATAL, 0, _("Could not reserve volume %s on %s\n"), dcr->VolumeName,
104 dcr->dev->print_name());
107 if (dev->vol && dev->vol->is_swapping()) {
108 dev->vol->set_slot(vol->Slot);
109 Dmsg3(100, "swapping: slot=%d Vol=%s dev=%s\n", dev->vol->get_slot(),
110 dev->vol->vol_name, dev->print_name());
114 * If the MediaType requested for this volume is not the
115 * same as the current drive, we attempt to find the same
116 * device that was used to write the orginal volume. If
117 * found, we switch to using that device.
119 * N.B. A lot of routines rely on the dcr pointer not changing
120 * read_records.c even has multiple dcrs cached, so we take care
121 * here to release all important parts of the dcr and re-acquire
122 * them such as the block pointer (size may change), but we do
123 * not release the dcr.
125 Dmsg2(50, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type);
126 if (dcr->media_type[0] && strcmp(dcr->media_type, dev->device->media_type) != 0) {
131 Jmsg3(jcr, M_INFO, 0, _("Changing device. Want Media Type=\"%s\" have=\"%s\"\n"
133 dcr->media_type, dev->device->media_type, dev->print_name());
134 Dmsg3(50, "Changing device. Want Media Type=\"%s\" have=\"%s\"\n"
136 dcr->media_type, dev->device->media_type, dev->print_name());
138 dev->dunblock(DEV_UNLOCKED);
141 memset(&rctx, 0, sizeof(RCTX));
143 jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
144 rctx.any_drive = true;
145 rctx.device_name = vol->device;
146 store = new DIRSTORE;
147 memset(store, 0, sizeof(DIRSTORE));
148 store->name[0] = 0; /* No dir name */
149 bstrncpy(store->media_type, vol->MediaType, sizeof(store->media_type));
150 bstrncpy(store->pool_name, dcr->pool_name, sizeof(store->pool_name));
151 bstrncpy(store->pool_type, dcr->pool_type, sizeof(store->pool_type));
152 store->append = false;
154 clean_device(dcr); /* clean up the dcr */
157 * Search for a new device
159 stat = search_res_for_device(rctx);
160 release_reserve_messages(jcr); /* release queued messages */
161 unlock_reservations();
164 dev = dcr->dev; /* get new device pointer */
165 dev->dblock(BST_DOING_ACQUIRE);
166 dcr->VolumeName[0] = 0;
167 Jmsg(jcr, M_INFO, 0, _("Media Type change. New device %s chosen.\n"),
169 Dmsg1(50, "Media Type change. New device %s chosen.\n", dev->print_name());
171 bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
172 bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
173 dcr->VolCatInfo.Slot = vol->Slot;
174 bstrncpy(dcr->pool_name, store->pool_name, sizeof(dcr->pool_name));
175 bstrncpy(dcr->pool_type, store->pool_type, sizeof(dcr->pool_type));
178 Jmsg1(jcr, M_FATAL, 0, _("No suitable device found to read Volume \"%s\"\n"),
180 Dmsg1(50, "No suitable device found to read Volume \"%s\"\n", vol->VolumeName);
186 init_device_wait_timers(dcr);
188 tape_previously_mounted = dev->can_read() || dev->can_append() ||
190 tape_initially_mounted = tape_previously_mounted;
193 /* Volume info is always needed because of VolParts */
194 Dmsg0(200, "dir_get_volume_info\n");
195 if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) {
196 Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
198 dev->set_load(); /* set to load volume */
201 /* If not polling limit retries */
202 if (!dev->poll && retry++ > 10) {
205 dev->clear_labeled(); /* force reread of label */
206 if (job_canceled(jcr)) {
208 Mmsg1(dev->errmsg, _("Job %s canceled.\n"), edit_int64(jcr->JobId, ed1));
209 Jmsg(jcr, M_INFO, 0, dev->errmsg);
210 goto get_out; /* error return */
213 dcr->do_swapping(false/*is_writing*/);
216 * This code ensures that the device is ready for
217 * reading. If it is a file, it opens it.
218 * If it is a tape, it checks the volume name
220 Dmsg1(100, "bstored: open vol=%s\n", dcr->VolumeName);
221 if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
223 Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"),
224 dev->print_name(), dcr->VolumeName, dev->bstrerror());
228 Dmsg1(50, "opened dev %s OK\n", dev->print_name());
230 /* Read Volume Label */
231 Dmsg0(50, "calling read-vol-label\n");
232 vol_label_status = read_dev_volume_label(dcr);
233 switch (vol_label_status) {
236 memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
240 * Send error message generated by read_dev_volume_label()
241 * only we really had a tape mounted. This supresses superfluous
242 * error messages when nothing is mounted.
244 if (tape_previously_mounted) {
245 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
249 if (tape_initially_mounted) {
250 tape_initially_mounted = false;
253 /* If polling and got a previous bad name, ignore it */
254 if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolumeName) == 0) {
257 bstrncpy(dev->BadVolName, dev->VolHdr.VolumeName, sizeof(dev->BadVolName));
259 if (!unload_autochanger(dcr, -1)) {
260 /* at least free the device so we can re-open with correct volume */
265 Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
267 tape_previously_mounted = true;
270 * If the device requires mount, close it, so the device can be ejected.
272 if (dev->requires_mount()) {
276 /* Call autochanger only once unless ask_sysop called */
277 if (try_autochanger) {
279 Dmsg2(200, "calling autoload Vol=%s Slot=%d\n",
280 dcr->VolumeName, dcr->VolCatInfo.Slot);
281 stat = autoload_device(dcr, 0, NULL);
283 try_autochanger = false;
284 continue; /* try reading volume mounted */
286 /* Try closing and re-opening */
289 if (dev->open(dcr, OPEN_READ_ONLY) >= 0) {
293 Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"),
294 dev->print_name(), dcr->VolumeName, dev->bstrerror());
298 /* Mount a specific volume and no other */
299 Dmsg0(200, "calling dir_ask_sysop\n");
300 if (!dir_ask_sysop_to_mount_volume(dcr, ST_READ)) {
301 goto get_out; /* error return */
303 try_autochanger = true; /* permit using autochanger again */
304 continue; /* try reading again */
309 Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s for reading.\n"),
316 set_jcr_job_status(jcr, JS_Running);
317 dir_send_job_status(jcr);
318 Jmsg(jcr, M_INFO, 0, _("Ready to read from volume \"%s\" on device %s.\n"),
319 dcr->VolumeName, dev->print_name());
323 dcr->clear_reserved();
325 * Normally we are blocked, but in at least one error case above
326 * we are not blocked because we unsuccessfully tried changing
329 if (dev->is_blocked()) {
330 dev->dunblock(DEV_LOCKED);
332 Dmsg1(950, "jcr->dcr=%p\n", jcr->dcr);
338 * Acquire device for writing. We permit multiple writers.
339 * If this is the first one, we read the label.
341 * Returns: NULL if failed for any reason
343 * Note, normally reserve_device_for_append() is called
344 * before this routine.
346 DCR *acquire_device_for_append(DCR *dcr)
348 DEVICE *dev = dcr->dev;
351 bool have_vol = false;
353 init_device_wait_timers(dcr);
355 dev->dblock(BST_DOING_ACQUIRE);
356 Dmsg1(100, "acquire_append device is %s\n", dev->is_tape()?"tape":
357 (dev->is_dvd()?"DVD":"disk"));
360 * With the reservation system, this should not happen
362 if (dev->can_read()) {
363 Jmsg1(jcr, M_FATAL, 0, _("Want to append, but device %s is busy reading.\n"), dev->print_name());
364 Dmsg1(200, "Want to append but device %s is busy reading.\n", dev->print_name());
369 * have_vol defines whether or not mount_next_write_volume should
370 * ask the Director again about what Volume to use.
372 if (dev->can_append() && dcr->is_suitable_volume_mounted() &&
373 strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") != 0) {
374 Dmsg0(190, "device already in append.\n");
376 * At this point, the correct tape is already mounted, so
377 * we do not need to do mount_next_write_volume(), unless
378 * we need to recycle the tape.
380 if (dev->num_writers == 0) {
381 memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
383 have_vol = dcr->is_tape_position_ok();
387 Dmsg1(190, "jid=%u Do mount_next_write_vol\n", (uint32_t)jcr->JobId);
388 if (!dcr->mount_next_write_volume()) {
389 if (!job_canceled(jcr)) {
390 /* Reduce "noise" -- don't print if job canceled */
391 Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
393 Dmsg1(200, "Could not ready device %s for append.\n",
398 Dmsg2(190, "Output pos=%u:%u\n", dcr->dev->file, dcr->dev->block_num);
401 dev->num_writers++; /* we are now a writer */
402 if (jcr->NumWriteVolumes == 0) {
403 jcr->NumWriteVolumes = 1;
405 dev->VolCatInfo.VolCatJobs++; /* increment number of jobs on vol */
406 dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
411 dcr->clear_reserved();
412 dev->dunblock(DEV_LOCKED);
413 return ok ? dcr : NULL;
417 * This job is done, so release the device. From a Unix standpoint,
418 * the device remains open.
420 * Note, if we are spooling, we may enter with the device locked.
421 * However, in all cases, unlock the device when leaving.
424 bool release_device(DCR *dcr)
427 DEVICE *dev = dcr->dev;
431 /* lock only if not already locked by this thread */
432 if (!dcr->is_dev_locked()) {
436 Dmsg2(100, "release_device device %s is %s\n", dev->print_name(), dev->is_tape()?"tape":"disk");
438 /* if device is reserved, job never started, so release the reserve here */
439 dcr->clear_reserved();
441 if (dev->can_read()) {
442 dev->clear_read(); /* clear read bit */
443 Dmsg0(100, "dir_update_vol_info. Release0\n");
444 dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
447 } else if (dev->num_writers > 0) {
449 * Note if WEOT is set, we are at the end of the tape
450 * and may not be positioned correctly, so the
451 * job_media_record and update_vol_info have already been
452 * done, which means we skip them here.
455 Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers);
456 if (dev->is_labeled()) {
457 Dmsg2(200, "dir_create_jobmedia. Release vol=%s dev=%s\n",
458 dev->VolCatInfo.VolCatName, dev->print_name());
459 if (!dev->at_weot() && !dir_create_jobmedia_record(dcr)) {
460 Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
461 dcr->VolCatInfo.VolCatName, jcr->Job);
463 /* If no more writers, and no errors, and wrote something, write an EOF */
464 if (!dev->num_writers && dev->can_write() && dev->block_num > 0) {
466 write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName);
468 if (!dev->at_weot()) {
469 dev->VolCatInfo.VolCatFiles = dev->file; /* set number of files */
470 /* Note! do volume update before close, which zaps VolCatInfo */
471 dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
472 Dmsg2(200, "dir_update_vol_info. Release vol=%s dev=%s\n",
473 dev->VolCatInfo.VolCatName, dev->print_name());
475 if (dev->num_writers == 0) { /* if not being used */
476 volume_unused(dcr); /* we obviously are not using the volume */
482 * If we reach here, it is most likely because the job
483 * has failed, since the device is not in read mode and
484 * there are no writers. It was probably reserved.
489 Dmsg3(100, "%d writers, %d reserve, dev=%s\n", dev->num_writers, dev->num_reserved(),
491 debug_list_volumes("acquire:release_device()");
494 /* If no writers, close if file or !CAP_ALWAYS_OPEN */
495 if (dev->num_writers == 0 && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) {
496 dvd_remove_empty_part(dcr); /* get rid of any empty spool part */
500 /* Fire off Alert command and include any output */
501 if (!job_canceled(jcr) && dcr->device->alert_command) {
505 char line[MAXSTRING];
506 alert = get_pool_memory(PM_FNAME);
507 alert = edit_device_codes(dcr, alert, dcr->device->alert_command, "");
508 bpipe = open_bpipe(alert, 0, "r");
510 while (fgets(line, sizeof(line), bpipe->rfd)) {
511 Jmsg(jcr, M_ALERT, 0, _("Alert: %s"), line);
513 status = close_bpipe(bpipe);
519 Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"),
520 alert, be.bstrerror(status));
523 Dmsg1(400, "alert status=%d\n", status);
524 free_pool_memory(alert);
526 pthread_cond_broadcast(&dev->wait_next_vol);
527 Dmsg2(100, "JobId=%u broadcast wait_device_release at %s\n",
528 (uint32_t)jcr->JobId, bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL)));
529 pthread_cond_broadcast(&wait_device_release);
532 detach_dcr_from_dev(dcr);
534 if (jcr->read_dcr == dcr) {
535 jcr->read_dcr = NULL;
537 if (jcr->dcr == dcr) {
542 Dmsg2(100, "===== Device %s released by JobId=%u\n", dev->print_name(),
543 (uint32_t)jcr->JobId);
548 * Clean up the device for reuse without freeing the memory
550 bool clean_device(DCR *dcr)
553 dcr->keep_dcr = true; /* do not free the dcr */
554 ok = release_device(dcr);
555 dcr->keep_dcr = false;
560 * Create a new Device Control Record and attach
561 * it to the device (if this is a real job).
562 * Note, this has been updated so that it can be called first
563 * without a DEVICE, then a second or third time with a DEVICE,
564 * and each time, it should cleanup and point to the new device.
565 * This should facilitate switching devices.
566 * Note, each dcr must point to the controlling job (jcr). However,
567 * a job can have multiple dcrs, so we must not store in the jcr's
568 * structure as previously. The higher level routine must store
569 * this dcr in the right place
572 DCR *new_dcr(JCR *jcr, DCR *dcr, DEVICE *dev)
575 dcr = (DCR *)malloc(sizeof(DCR));
576 memset(dcr, 0, sizeof(DCR));
577 dcr->tid = pthread_self();
580 dcr->jcr = jcr; /* point back to jcr */
581 /* Set device information, possibly change device */
584 free_block(dcr->block);
586 dcr->block = new_block(dev);
588 free_record(dcr->rec);
590 dcr->rec = new_record();
591 if (dcr->attached_to_dev) {
592 detach_dcr_from_dev(dcr);
594 /* Use job spoolsize prior to device spoolsize */
595 if (jcr->spool_size) {
596 dcr->max_job_spool_size = jcr->spool_size;
598 dcr->max_job_spool_size = dev->device->max_job_spool_size;
600 dcr->device = dev->device;
602 attach_dcr_to_dev(dcr);
608 * Search the dcrs list for the given dcr. If it is found,
609 * as it should be, then remove it. Also zap the jcr pointer
610 * to the dcr if it is the same one.
612 * Note, this code will be turned on when we can write to multiple
613 * dcrs at the same time.
616 static void remove_dcr_from_dcrs(DCR *dcr)
622 int num = jcr->dcrs->size();
623 for (i=0; i < num; i++) {
624 ldcr = (DCR *)jcr->dcrs->get(i);
626 jcr->dcrs->remove(i);
627 if (jcr->dcr == dcr) {
636 static void attach_dcr_to_dev(DCR *dcr)
638 DEVICE *dev = dcr->dev;
641 if (jcr) Dmsg1(500, "JobId=%u enter attach_dcr_to_dev\n", (uint32_t)jcr->JobId);
642 if (!dcr->attached_to_dev && dev->initiated && jcr && jcr->JobType != JT_SYSTEM) {
643 dev->attached_dcrs->append(dcr); /* attach dcr to device */
644 dcr->attached_to_dev = true;
645 Dmsg1(500, "JobId=%u attach_dcr_to_dev\n", (uint32_t)jcr->JobId);
649 void detach_dcr_from_dev(DCR *dcr)
651 DEVICE *dev = dcr->dev;
652 Dmsg0(500, "Enter detach_dcr_from_dev\n"); /* jcr is NULL in some cases */
654 /* Detach this dcr only if attached */
655 if (dcr->attached_to_dev && dev) {
657 dcr->unreserve_device();
658 dcr->dev->attached_dcrs->remove(dcr); /* detach dcr from device */
659 dcr->attached_to_dev = false;
660 // remove_dcr_from_dcrs(dcr); /* remove dcr from jcr list */
666 * Free up all aspects of the given dcr -- i.e. dechain it,
667 * release allocated memory, zap pointers, ...
669 void free_dcr(DCR *dcr)
673 detach_dcr_from_dev(dcr);
676 free_block(dcr->block);
679 free_record(dcr->rec);
681 if (jcr && jcr->dcr == dcr) {