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 plus additions
11 that are listed in the file LICENSE.
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->block(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(100, "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;
110 memset(&rctx, 0, sizeof(RCTX));
112 jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
113 rctx.any_drive = true;
114 rctx.device_name = vol->device;
115 store = new DIRSTORE;
116 memset(store, 0, sizeof(DIRSTORE));
117 store->name[0] = 0; /* No dir name */
118 bstrncpy(store->media_type, vol->MediaType, sizeof(store->media_type));
119 bstrncpy(store->pool_name, dcr->pool_name, sizeof(store->pool_name));
120 bstrncpy(store->pool_type, dcr->pool_type, sizeof(store->pool_type));
121 store->append = false;
125 * Note, if search_for_device() succeeds, we get a new_dcr,
126 * which we do not use except for the dev info.
128 stat = search_res_for_device(rctx);
129 release_msgs(jcr); /* release queued messages */
130 unlock_reservations();
132 DCR *new_dcr = jcr->read_dcr;
133 dev->unblock(dev_unlocked);
134 detach_dcr_from_dev(dcr); /* release old device */
135 /* Copy important info from the new dcr */
136 dev = dcr->dev = new_dcr->dev;
138 dcr->device = new_dcr->device;
139 dcr->max_job_spool_size = dcr->device->max_job_spool_size;
140 attach_dcr_to_dev(dcr);
141 new_dcr->VolumeName[0] = 0;
143 dev->block(BST_DOING_ACQUIRE);
144 Jmsg(jcr, M_INFO, 0, _("Media Type change. New device %s chosen.\n"),
146 bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
147 bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
148 dcr->VolCatInfo.Slot = vol->Slot;
149 bstrncpy(dcr->pool_name, store->pool_name, sizeof(dcr->pool_name));
150 bstrncpy(dcr->pool_type, store->pool_type, sizeof(dcr->pool_type));
151 } else if (stat == 0) { /* device busy */
152 Pmsg1(000, "Device %s is busy.\n", vol->device);
155 Jmsg1(jcr, M_FATAL, 0, _("No suitable device found to read Volume \"%s\"\n"),
164 init_device_wait_timers(dcr);
166 tape_previously_mounted = dev->can_read() || dev->can_append() ||
168 tape_initially_mounted = tape_previously_mounted;
171 /* Volume info is always needed because of VolParts */
172 Dmsg0(200, "dir_get_volume_info\n");
173 if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) {
174 Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
178 /* If not polling limit retries */
179 if (!dev->poll && retry++ > 10) {
182 dev->clear_labeled(); /* force reread of label */
183 if (job_canceled(jcr)) {
185 Mmsg1(dev->errmsg, _("Job %s canceled.\n"), edit_int64(jcr->JobId, ed1));
186 Jmsg(jcr, M_INFO, 0, dev->errmsg);
187 goto get_out; /* error return */
190 autoload_device(dcr, 0, NULL);
193 * This code ensures that the device is ready for
194 * reading. If it is a file, it opens it.
195 * If it is a tape, it checks the volume name
197 Dmsg1(100, "bstored: open vol=%s\n", dcr->VolumeName);
198 if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
199 Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"),
200 dev->print_name(), dcr->VolumeName, dev->bstrerror());
203 Dmsg1(100, "opened dev %s OK\n", dev->print_name());
205 /* Read Volume Label */
207 Dmsg0(200, "calling read-vol-label\n");
208 vol_label_status = read_dev_volume_label(dcr);
209 switch (vol_label_status) {
212 memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
216 * Send error message generated by read_dev_volume_label()
217 * only we really had a tape mounted. This supresses superfluous
218 * error messages when nothing is mounted.
220 if (tape_previously_mounted) {
221 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
225 if (tape_initially_mounted) {
226 tape_initially_mounted = false;
229 /* If polling and got a previous bad name, ignore it */
230 if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolumeName) == 0) {
233 bstrncpy(dev->BadVolName, dev->VolHdr.VolumeName, sizeof(dev->BadVolName));
237 Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
239 tape_previously_mounted = true;
242 * If the device requires mount, close it, so the device can be ejected.
244 if (dev->requires_mount()) {
248 /* Call autochanger only once unless ask_sysop called */
249 if (try_autochanger) {
251 Dmsg2(200, "calling autoload Vol=%s Slot=%d\n",
252 dcr->VolumeName, dcr->VolCatInfo.Slot);
253 stat = autoload_device(dcr, 0, NULL);
255 try_autochanger = false;
256 continue; /* try reading volume mounted */
260 /* Mount a specific volume and no other */
261 Dmsg0(200, "calling dir_ask_sysop\n");
262 if (!dir_ask_sysop_to_mount_volume(dcr)) {
263 goto get_out; /* error return */
265 try_autochanger = true; /* permit using autochanger again */
266 continue; /* try reading again */
271 Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s for reading.\n"),
278 set_jcr_job_status(jcr, JS_Running);
279 dir_send_job_status(jcr);
280 Jmsg(jcr, M_INFO, 0, _("Ready to read from volume \"%s\" on device %s.\n"),
281 dcr->VolumeName, dev->print_name());
285 if (dcr->reserved_device) {
286 dev->reserved_device--;
287 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
288 dcr->reserved_device = false;
290 dev->unblock(dev_locked);
291 Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
297 * Acquire device for writing. We permit multiple writers.
298 * If this is the first one, we read the label.
300 * Returns: NULL if failed for any reason
302 * Note, normally reserve_device_for_append() is called
303 * before this routine.
305 DCR *acquire_device_for_append(DCR *dcr)
307 bool release = false;
308 bool recycle = false;
309 bool do_mount = false;
310 DEVICE *dev = dcr->dev;
313 init_device_wait_timers(dcr);
315 dev->block(BST_DOING_ACQUIRE);
316 Dmsg1(190, "acquire_append device is %s\n", dev->is_tape()?"tape":
317 (dev->is_dvd()?"DVD":"disk"));
320 * With the reservation system, this should not happen
322 if (dev->can_read()) {
323 Jmsg1(jcr, M_FATAL, 0, _("Want to append, but device %s is busy reading.\n"), dev->print_name());
324 Dmsg1(200, "Want to append but device %s is busy reading.\n", dev->print_name());
328 if (dev->can_append()) {
329 Dmsg0(190, "device already in append.\n");
331 * Device already in append mode
333 * Check if we have the right Volume mounted
334 * OK if current volume info OK
335 * OK if next volume matches current volume
336 * otherwise mount desired volume obtained from
337 * dir_find_next_appendable_volume
338 * dev->VolHdr.VolumeName is what is in the drive
339 * dcr->VolumeName is what we pass into the routines, or
340 * get back from the subroutines.
342 bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
343 if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
344 !(dir_find_next_appendable_volume(dcr) &&
345 strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
346 Dmsg2(190, "Wrong tape mounted: %s. wants:%s\n", dev->VolHdr.VolumeName,
348 /* Release volume reserved by dir_find_next_appendable_volume() */
349 if (dcr->VolumeName[0]) {
352 if (dev->num_writers != 0) {
353 Jmsg3(jcr, M_FATAL, 0, _("Wanted to append to Volume \"%s\", but device %s is busy writing on \"%s\" .\n"),
354 dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
355 Dmsg3(200, "Wanted to append to Volume \"%s\", but device %s is busy writing on \"%s\" .\n",
356 dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
359 /* Wrong tape mounted, release it, then fall through to get correct one */
360 Dmsg0(190, "Wrong tape mounted, release and try mount.\n");
365 * At this point, the correct tape is already mounted, so
366 * we do not need to do mount_next_write_volume(), unless
367 * we need to recycle the tape.
369 recycle = strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0;
370 Dmsg1(190, "Correct tape mounted. recycle=%d\n", recycle);
371 if (recycle && dev->num_writers != 0) {
372 Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\""
373 " on device %s because it is in use by another job.\n"),
374 dev->VolHdr.VolumeName, dev->print_name());
377 if (dev->num_writers == 0) {
378 memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
384 * Check to see if the tape position as defined by the OS is
385 * the same as our concept. If it is not, we bail out, because
386 * it means the user has probably manually rewound the tape.
387 * Note, we check only if num_writers == 0, but this code will
388 * also work fine for any number of writers. If num_writers > 0,
389 * we probably should cancel all jobs using this device, or
390 * perhaps even abort the SD, or at a minimum, mark the tape
391 * in error. Another strategy with num_writers == 0, would be
392 * to rewind the tape and do a new eod() request.
394 if (dev->is_tape() && dev->num_writers == 0) {
395 int32_t file = dev->get_os_tape_file();
396 if (file >= 0 && file != (int32_t)dev->get_file()) {
397 Jmsg(jcr, M_FATAL, 0, _("Invalid tape position on volume \"%s\""
398 " on device %s. Expected %d, got %d\n"),
399 dev->VolHdr.VolumeName, dev->print_name(), dev->get_file(), file);
405 /* Not already in append mode, so mount the device */
406 Dmsg0(190, "Not in append mode, try mount.\n");
407 ASSERT(dev->num_writers == 0);
411 if (do_mount || recycle) {
412 Dmsg0(190, "Do mount_next_write_vol\n");
413 bool mounted = mount_next_write_volume(dcr, release);
415 if (!job_canceled(jcr)) {
416 /* Reduce "noise" -- don't print if job canceled */
417 Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
419 Dmsg1(200, "Could not ready device %s for append.\n",
424 Dmsg2(190, "Output pos=%u:%u\n", dcr->dev->file, dcr->dev->block_num);
427 dev->num_writers++; /* we are now a writer */
428 if (jcr->NumWriteVolumes == 0) {
429 jcr->NumWriteVolumes = 1;
431 dev->VolCatInfo.VolCatJobs++; /* increment number of jobs on vol */
432 dir_update_volume_info(dcr, false); /* send Volume info to Director */
434 if (dcr->reserved_device) {
435 dev->reserved_device--;
436 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
437 dcr->reserved_device = false;
439 dev->unblock(dev_locked);
447 if (dcr->reserved_device) {
448 dev->reserved_device--;
449 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
450 dcr->reserved_device = false;
452 dev->unblock(dev_locked);
458 * This job is done, so release the device. From a Unix standpoint,
459 * the device remains open.
461 * Note, if we are spooling, we may enter with the device locked.
462 * However, in all cases, unlock the device when leaving.
465 bool release_device(DCR *dcr)
468 DEVICE *dev = dcr->dev;
471 /* lock only if not already locked by this thread */
472 if (!dcr->dev_locked) {
475 Dmsg2(100, "release_device device %s is %s\n", dev->print_name(), dev->is_tape()?"tape":"disk");
477 /* if device is reserved, job never started, so release the reserve here */
478 if (dcr->reserved_device) {
479 dev->reserved_device--;
480 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
481 dcr->reserved_device = false;
484 if (dev->can_read()) {
485 dev->clear_read(); /* clear read bit */
486 Dmsg0(100, "dir_update_vol_info. Release0\n");
487 dir_update_volume_info(dcr, false); /* send Volume info to Director */
489 } else if (dev->num_writers > 0) {
491 * Note if WEOT is set, we are at the end of the tape
492 * and may not be positioned correctly, so the
493 * job_media_record and update_vol_info have already been
494 * done, which means we skip them here.
497 Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers);
498 if (dev->is_labeled()) {
499 Dmsg0(100, "dir_create_jobmedia_record. Release\n");
500 if (!dev->at_weot() && !dir_create_jobmedia_record(dcr)) {
501 Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
502 dcr->VolCatInfo.VolCatName, jcr->Job);
504 /* If no more writers, write an EOF */
505 if (!dev->num_writers && dev->can_write() && dev->block_num > 0) {
507 write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName);
509 if (!dev->at_weot()) {
510 dev->VolCatInfo.VolCatFiles = dev->file; /* set number of files */
511 /* Note! do volume update before close, which zaps VolCatInfo */
512 Dmsg0(100, "dir_update_vol_info. Release0\n");
513 dir_update_volume_info(dcr, false); /* send Volume info to Director */
519 * If we reach here, it is most likely because the job
520 * has failed, since the device is not in read mode and
521 * there are no writers. It was probably reserved.
525 /* If no writers, close if file or !CAP_ALWAYS_OPEN */
526 if (dev->num_writers == 0 && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) {
527 dvd_remove_empty_part(dcr); /* get rid of any empty spool part */
531 /* Fire off Alert command and include any output */
532 if (!job_canceled(jcr) && dcr->device->alert_command) {
536 char line[MAXSTRING];
537 alert = get_pool_memory(PM_FNAME);
538 alert = edit_device_codes(dcr, alert, dcr->device->alert_command, "");
539 bpipe = open_bpipe(alert, 0, "r");
541 while (fgets(line, sizeof(line), bpipe->rfd)) {
542 Jmsg(jcr, M_ALERT, 0, _("Alert: %s"), line);
544 status = close_bpipe(bpipe);
550 Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"),
551 alert, be.bstrerror(status));
554 Dmsg1(400, "alert status=%d\n", status);
555 free_pool_memory(alert);
557 pthread_cond_broadcast(&dev->wait_next_vol);
558 Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
559 pthread_cond_broadcast(&wait_device_release);
560 dcr->dev_locked = false; /* set no longer locked */
562 if (jcr->read_dcr == dcr) {
563 jcr->read_dcr = NULL;
565 if (jcr->dcr == dcr) {
569 Dmsg2(100, "===== Device %s released by JobId=%u\n", dev->print_name(),
570 (uint32_t)jcr->JobId);
575 * Create a new Device Control Record and attach
576 * it to the device (if this is a real job).
578 DCR *new_dcr(JCR *jcr, DEVICE *dev)
580 if (jcr) Dmsg2(100, "enter new_dcr JobId=%u dev=%p\n", (uint32_t)jcr->JobId, dev);
581 DCR *dcr = (DCR *)malloc(sizeof(DCR));
582 memset(dcr, 0, sizeof(DCR));
585 dcr->tid = pthread_self();
587 dcr->device = dev->device;
588 dcr->block = new_block(dev);
589 dcr->rec = new_record();
590 dcr->max_job_spool_size = dev->device->max_job_spool_size;
591 attach_dcr_to_dev(dcr);
598 * Search the dcrs list for the given dcr. If it is found,
599 * as it should be, then remove it. Also zap the jcr pointer
600 * to the dcr if it is the same one.
603 static void remove_dcr_from_dcrs(DCR *dcr)
609 int num = jcr->dcrs->size();
610 for (i=0; i < num; i++) {
611 ldcr = (DCR *)jcr->dcrs->get(i);
613 jcr->dcrs->remove(i);
614 if (jcr->dcr == dcr) {
623 static void attach_dcr_to_dev(DCR *dcr)
625 DEVICE *dev = dcr->dev;
628 if (jcr) Dmsg1(500, "JobId=%u enter attach_dcr_to_dev\n", (uint32_t)jcr->JobId);
629 if (!dcr->attached_to_dev && dev->initiated && jcr && jcr->JobType != JT_SYSTEM) {
630 dev->attached_dcrs->append(dcr); /* attach dcr to device */
631 dcr->attached_to_dev = true;
632 Dmsg1(500, "JobId=%u attach_dcr_to_dev\n", (uint32_t)jcr->JobId);
636 void detach_dcr_from_dev(DCR *dcr)
638 Dmsg1(500, "JobId=%u enter detach_dcr_from_dev\n", (uint32_t)dcr->jcr->JobId);
639 unreserve_device(dcr);
641 /* Detach this dcr only if attached */
642 if (dcr->attached_to_dev) {
643 dcr->dev->attached_dcrs->remove(dcr); /* detach dcr from device */
644 dcr->attached_to_dev = false;
645 // remove_dcr_from_dcrs(dcr); /* remove dcr from jcr list */
650 * Free up all aspects of the given dcr -- i.e. dechain it,
651 * release allocated memory, zap pointers, ...
653 void free_dcr(DCR *dcr)
658 detach_dcr_from_dev(dcr);
662 free_block(dcr->block);
665 free_record(dcr->rec);
667 if (jcr && jcr->dcr == dcr) {