2 Bacula® - The Network Backup Solution
4 Copyright (C) 2002-2007 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(50, "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 */
91 bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
92 bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
93 dcr->VolCatInfo.Slot = vol->Slot;
96 * If the MediaType requested for this volume is not the
97 * same as the current drive, we attempt to find the same
98 * device that was used to write the orginal volume. If
99 * found, we switch to using that device.
101 Dmsg2(50, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type);
102 if (dcr->media_type[0] && strcmp(dcr->media_type, dev->device->media_type) != 0) {
106 DCR *dcr_save = jcr->dcr;
108 Jmsg3(jcr, M_INFO, 0, _("Changing device. Want Media Type=\"%s\" have=\"%s\"\n"
110 dcr->media_type, dev->device->media_type, dev->print_name());
113 memset(&rctx, 0, sizeof(RCTX));
115 jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
116 rctx.any_drive = true;
117 rctx.device_name = vol->device;
118 store = new DIRSTORE;
119 memset(store, 0, sizeof(DIRSTORE));
120 store->name[0] = 0; /* No dir name */
121 bstrncpy(store->media_type, vol->MediaType, sizeof(store->media_type));
122 bstrncpy(store->pool_name, dcr->pool_name, sizeof(store->pool_name));
123 bstrncpy(store->pool_type, dcr->pool_type, sizeof(store->pool_type));
124 store->append = false;
128 * Note, if search_for_device() succeeds, we get a new dcr,
129 * which we do not use except for the dev info.
131 stat = search_res_for_device(rctx);
132 release_reserve_messages(jcr); /* release queued messages */
133 unlock_reservations();
135 DCR *ndcr = jcr->read_dcr;
136 dev->dunblock(DEV_UNLOCKED);
137 detach_dcr_from_dev(dcr); /* release old device */
138 /* Copy important info from the new dcr */
139 dev = dcr->dev = ndcr->dev;
141 dcr->device = ndcr->device;
142 dcr->max_job_spool_size = dcr->device->max_job_spool_size;
143 attach_dcr_to_dev(dcr);
144 ndcr->VolumeName[0] = 0;
146 dev->dblock(BST_DOING_ACQUIRE);
147 Jmsg(jcr, M_INFO, 0, _("Media Type change. New device %s chosen.\n"),
149 bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
150 bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
151 dcr->VolCatInfo.Slot = vol->Slot;
152 bstrncpy(dcr->pool_name, store->pool_name, sizeof(dcr->pool_name));
153 bstrncpy(dcr->pool_type, store->pool_type, sizeof(dcr->pool_type));
154 } else if (stat == 0) { /* device busy */
155 Pmsg1(000, "Device %s is busy.\n", vol->device);
158 Jmsg1(jcr, M_FATAL, 0, _("No suitable device found to read Volume \"%s\"\n"),
167 init_device_wait_timers(dcr);
169 tape_previously_mounted = dev->can_read() || dev->can_append() ||
171 tape_initially_mounted = tape_previously_mounted;
174 /* Volume info is always needed because of VolParts */
175 Dmsg0(200, "dir_get_volume_info\n");
176 if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) {
177 Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
181 /* If not polling limit retries */
182 if (!dev->poll && retry++ > 10) {
185 dev->clear_labeled(); /* force reread of label */
186 if (job_canceled(jcr)) {
188 Mmsg1(dev->errmsg, _("Job %s canceled.\n"), edit_int64(jcr->JobId, ed1));
189 Jmsg(jcr, M_INFO, 0, dev->errmsg);
190 goto get_out; /* error return */
193 autoload_device(dcr, 0, NULL);
196 * This code ensures that the device is ready for
197 * reading. If it is a file, it opens it.
198 * If it is a tape, it checks the volume name
200 Dmsg1(100, "bstored: open vol=%s\n", dcr->VolumeName);
201 if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
202 Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"),
203 dev->print_name(), dcr->VolumeName, dev->bstrerror());
206 Dmsg1(100, "opened dev %s OK\n", dev->print_name());
208 /* Read Volume Label */
210 Dmsg0(200, "calling read-vol-label\n");
211 vol_label_status = read_dev_volume_label(dcr);
212 switch (vol_label_status) {
215 memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
219 * Send error message generated by read_dev_volume_label()
220 * only we really had a tape mounted. This supresses superfluous
221 * error messages when nothing is mounted.
223 if (tape_previously_mounted) {
224 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
228 if (tape_initially_mounted) {
229 tape_initially_mounted = false;
232 /* If polling and got a previous bad name, ignore it */
233 if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolumeName) == 0) {
236 bstrncpy(dev->BadVolName, dev->VolHdr.VolumeName, sizeof(dev->BadVolName));
240 Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
242 tape_previously_mounted = true;
245 * If the device requires mount, close it, so the device can be ejected.
247 if (dev->requires_mount()) {
251 /* Call autochanger only once unless ask_sysop called */
252 if (try_autochanger) {
254 Dmsg2(200, "calling autoload Vol=%s Slot=%d\n",
255 dcr->VolumeName, dcr->VolCatInfo.Slot);
256 stat = autoload_device(dcr, 0, NULL);
258 try_autochanger = false;
259 continue; /* try reading volume mounted */
263 /* Mount a specific volume and no other */
264 Dmsg0(200, "calling dir_ask_sysop\n");
265 if (!dir_ask_sysop_to_mount_volume(dcr)) {
266 goto get_out; /* error return */
268 try_autochanger = true; /* permit using autochanger again */
269 continue; /* try reading again */
274 Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s for reading.\n"),
281 set_jcr_job_status(jcr, JS_Running);
282 dir_send_job_status(jcr);
283 Jmsg(jcr, M_INFO, 0, _("Ready to read from volume \"%s\" on device %s.\n"),
284 dcr->VolumeName, dev->print_name());
288 if (dcr->reserved_device) {
289 dev->reserved_device--;
290 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
291 dcr->reserved_device = false;
293 dev->dunblock(DEV_LOCKED);
294 Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
300 * Acquire device for writing. We permit multiple writers.
301 * If this is the first one, we read the label.
303 * Returns: NULL if failed for any reason
305 * Note, normally reserve_device_for_append() is called
306 * before this routine.
308 DCR *acquire_device_for_append(DCR *dcr)
310 bool release = false;
311 bool recycle = false;
312 bool do_mount = false;
313 DEVICE *dev = dcr->dev;
316 init_device_wait_timers(dcr);
318 dev->dblock(BST_DOING_ACQUIRE);
319 Dmsg1(190, "acquire_append device is %s\n", dev->is_tape()?"tape":
320 (dev->is_dvd()?"DVD":"disk"));
323 * With the reservation system, this should not happen
325 if (dev->can_read()) {
326 Jmsg1(jcr, M_FATAL, 0, _("Want to append, but device %s is busy reading.\n"), dev->print_name());
327 Dmsg1(200, "Want to append but device %s is busy reading.\n", dev->print_name());
331 if (dev->can_append()) {
332 Dmsg0(190, "device already in append.\n");
334 * Device already in append mode
336 * Check if we have the right Volume mounted
337 * OK if current volume info OK
338 * OK if next volume matches current volume
339 * otherwise mount desired volume obtained from
340 * dir_find_next_appendable_volume
341 * dev->VolHdr.VolumeName is what is in the drive
342 * dcr->VolumeName is what we pass into the routines, or
343 * get back from the subroutines.
345 bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
346 if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
347 !(dir_find_next_appendable_volume(dcr) &&
348 strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
349 Dmsg2(190, "Wrong tape mounted: %s. wants:%s\n", dev->VolHdr.VolumeName,
351 /* Release volume reserved by dir_find_next_appendable_volume() */
352 if (dcr->VolumeName[0]) {
355 if (dev->num_writers != 0) {
356 Jmsg3(jcr, M_FATAL, 0, _("Wanted to append to Volume \"%s\", but device %s is busy writing on \"%s\" .\n"),
357 dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
358 Dmsg3(200, "Wanted to append to Volume \"%s\", but device %s is busy writing on \"%s\" .\n",
359 dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
362 /* Wrong tape mounted, release it, then fall through to get correct one */
363 Dmsg0(190, "Wrong tape mounted, release and try mount.\n");
368 * At this point, the correct tape is already mounted, so
369 * we do not need to do mount_next_write_volume(), unless
370 * we need to recycle the tape.
372 recycle = strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0;
373 Dmsg1(190, "Correct tape mounted. recycle=%d\n", recycle);
374 if (recycle && dev->num_writers != 0) {
375 Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\""
376 " on device %s because it is in use by another job.\n"),
377 dev->VolHdr.VolumeName, dev->print_name());
380 if (dev->num_writers == 0) {
381 memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
387 * Check to see if the tape position as defined by the OS is
388 * the same as our concept. If it is not, we bail out, because
389 * it means the user has probably manually rewound the tape.
390 * Note, we check only if num_writers == 0, but this code will
391 * also work fine for any number of writers. If num_writers > 0,
392 * we probably should cancel all jobs using this device, or
393 * perhaps even abort the SD, or at a minimum, mark the tape
394 * in error. Another strategy with num_writers == 0, would be
395 * to rewind the tape and do a new eod() request.
397 if (dev->is_tape() && dev->num_writers == 0) {
398 int32_t file = dev->get_os_tape_file();
399 if (file >= 0 && file != (int32_t)dev->get_file()) {
400 Jmsg(jcr, M_FATAL, 0, _("Invalid tape position on volume \"%s\""
401 " on device %s. Expected %d, got %d\n"),
402 dev->VolHdr.VolumeName, dev->print_name(), dev->get_file(), file);
408 /* Not already in append mode, so mount the device */
409 Dmsg0(190, "Not in append mode, try mount.\n");
410 ASSERT(dev->num_writers == 0);
414 if (do_mount || recycle) {
415 Dmsg0(190, "Do mount_next_write_vol\n");
416 bool mounted = mount_next_write_volume(dcr, release);
418 if (!job_canceled(jcr)) {
419 /* Reduce "noise" -- don't print if job canceled */
420 Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
422 Dmsg1(200, "Could not ready device %s for append.\n",
427 Dmsg2(190, "Output pos=%u:%u\n", dcr->dev->file, dcr->dev->block_num);
430 dev->num_writers++; /* we are now a writer */
431 if (jcr->NumWriteVolumes == 0) {
432 jcr->NumWriteVolumes = 1;
434 dev->VolCatInfo.VolCatJobs++; /* increment number of jobs on vol */
435 dir_update_volume_info(dcr, false); /* send Volume info to Director */
437 if (dcr->reserved_device) {
438 dev->reserved_device--;
439 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
440 dcr->reserved_device = false;
442 dev->dunblock(DEV_LOCKED);
450 if (dcr->reserved_device) {
451 dev->reserved_device--;
452 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
453 dcr->reserved_device = false;
455 dev->dunblock(DEV_LOCKED);
461 * This job is done, so release the device. From a Unix standpoint,
462 * the device remains open.
464 * Note, if we are spooling, we may enter with the device locked.
465 * However, in all cases, unlock the device when leaving.
468 bool release_device(DCR *dcr)
471 DEVICE *dev = dcr->dev;
474 /* lock only if not already locked by this thread */
475 if (!dcr->is_dev_locked()) {
478 Dmsg2(100, "release_device device %s is %s\n", dev->print_name(), dev->is_tape()?"tape":"disk");
480 /* if device is reserved, job never started, so release the reserve here */
481 if (dcr->reserved_device) {
482 dev->reserved_device--;
483 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
484 dcr->reserved_device = false;
487 if (dev->can_read()) {
488 dev->clear_read(); /* clear read bit */
489 Dmsg0(100, "dir_update_vol_info. Release0\n");
490 dir_update_volume_info(dcr, false); /* send Volume info to Director */
492 } else if (dev->num_writers > 0) {
494 * Note if WEOT is set, we are at the end of the tape
495 * and may not be positioned correctly, so the
496 * job_media_record and update_vol_info have already been
497 * done, which means we skip them here.
500 Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers);
501 if (dev->is_labeled()) {
502 Dmsg0(100, "dir_create_jobmedia_record. Release\n");
503 if (!dev->at_weot() && !dir_create_jobmedia_record(dcr)) {
504 Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
505 dcr->VolCatInfo.VolCatName, jcr->Job);
507 /* If no more writers, write an EOF */
508 if (!dev->num_writers && dev->can_write() && dev->block_num > 0) {
510 write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName);
512 if (!dev->at_weot()) {
513 dev->VolCatInfo.VolCatFiles = dev->file; /* set number of files */
514 /* Note! do volume update before close, which zaps VolCatInfo */
515 Dmsg0(100, "dir_update_vol_info. Release0\n");
516 dir_update_volume_info(dcr, false); /* send Volume info to Director */
522 * If we reach here, it is most likely because the job
523 * has failed, since the device is not in read mode and
524 * there are no writers. It was probably reserved.
528 /* If no writers, close if file or !CAP_ALWAYS_OPEN */
529 if (dev->num_writers == 0 && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) {
530 dvd_remove_empty_part(dcr); /* get rid of any empty spool part */
534 /* Fire off Alert command and include any output */
535 if (!job_canceled(jcr) && dcr->device->alert_command) {
539 char line[MAXSTRING];
540 alert = get_pool_memory(PM_FNAME);
541 alert = edit_device_codes(dcr, alert, dcr->device->alert_command, "");
542 bpipe = open_bpipe(alert, 0, "r");
544 while (fgets(line, sizeof(line), bpipe->rfd)) {
545 Jmsg(jcr, M_ALERT, 0, _("Alert: %s"), line);
547 status = close_bpipe(bpipe);
553 Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"),
554 alert, be.bstrerror(status));
557 Dmsg1(400, "alert status=%d\n", status);
558 free_pool_memory(alert);
560 pthread_cond_broadcast(&dev->wait_next_vol);
561 Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
562 pthread_cond_broadcast(&wait_device_release);
564 if (jcr->read_dcr == dcr) {
565 jcr->read_dcr = NULL;
567 if (jcr->dcr == dcr) {
571 Dmsg2(100, "===== Device %s released by JobId=%u\n", dev->print_name(),
572 (uint32_t)jcr->JobId);
577 * Create a new Device Control Record and attach
578 * it to the device (if this is a real job).
579 * Note, this has been updated so that it can be called first
580 * without a DEVICE, then a second or third time with a DEVICE,
581 * and each time, it should cleanup and point to the new device.
582 * This should facilitate switching devices.
583 * Note, each dcr must point to the controlling job (jcr). However,
584 * a job can have multiple dcrs, so we must not store in the jcr's
585 * structure as previously. The higher level routine must store
586 * this dcr in the right place
589 DCR *new_dcr(JCR *jcr, DCR *dcr, DEVICE *dev)
592 dcr = (DCR *)malloc(sizeof(DCR));
593 memset(dcr, 0, sizeof(DCR));
594 dcr->tid = pthread_self();
597 dcr->jcr = jcr; /* point back to jcr */
598 /* Set device information, possibly change device */
601 free_block(dcr->block);
603 dcr->block = new_block(dev);
605 free_record(dcr->rec);
607 dcr->rec = new_record();
608 if (dcr->attached_to_dev) {
609 detach_dcr_from_dev(dcr);
611 dcr->max_job_spool_size = dev->device->max_job_spool_size;
612 dcr->device = dev->device;
614 attach_dcr_to_dev(dcr);
620 * Search the dcrs list for the given dcr. If it is found,
621 * as it should be, then remove it. Also zap the jcr pointer
622 * to the dcr if it is the same one.
625 static void remove_dcr_from_dcrs(DCR *dcr)
631 int num = jcr->dcrs->size();
632 for (i=0; i < num; i++) {
633 ldcr = (DCR *)jcr->dcrs->get(i);
635 jcr->dcrs->remove(i);
636 if (jcr->dcr == dcr) {
645 static void attach_dcr_to_dev(DCR *dcr)
647 DEVICE *dev = dcr->dev;
650 if (jcr) Dmsg1(500, "JobId=%u enter attach_dcr_to_dev\n", (uint32_t)jcr->JobId);
651 if (!dcr->attached_to_dev && dev->initiated && jcr && jcr->JobType != JT_SYSTEM) {
652 dev->attached_dcrs->append(dcr); /* attach dcr to device */
653 dcr->attached_to_dev = true;
654 Dmsg1(500, "JobId=%u attach_dcr_to_dev\n", (uint32_t)jcr->JobId);
658 void detach_dcr_from_dev(DCR *dcr)
660 Dmsg1(500, "JobId=%u enter detach_dcr_from_dev\n", (uint32_t)dcr->jcr->JobId);
662 /* Detach this dcr only if attached */
663 if (dcr->attached_to_dev && dcr->dev) {
664 unreserve_device(dcr);
665 dcr->dev->attached_dcrs->remove(dcr); /* detach dcr from device */
666 dcr->attached_to_dev = false;
667 // remove_dcr_from_dcrs(dcr); /* remove dcr from jcr list */
672 * Free up all aspects of the given dcr -- i.e. dechain it,
673 * release allocated memory, zap pointers, ...
675 void free_dcr(DCR *dcr)
679 detach_dcr_from_dev(dcr);
682 free_block(dcr->block);
685 free_record(dcr->rec);
687 if (jcr && jcr->dcr == dcr) {