2 * Routines to acquire and release a device for read/write
4 * Kern Sibbald, August MMII
9 Copyright (C) 2002-2006 Kern Sibbald
11 This program is free software; you can redistribute it and/or
12 modify it under the terms of the GNU General Public License
13 version 2 as amended with additional clauses defined in the
14 file LICENSE in the main source directory.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 the file LICENSE for additional details.
23 #include "bacula.h" /* pull in global headers */
24 #include "stored.h" /* pull in Storage Deamon headers */
26 /* Forward referenced functions */
27 static void attach_dcr_to_dev(DCR *dcr);
30 /*********************************************************************
31 * Acquire device for reading.
32 * The drive should have previously been reserved by calling
33 * reserve_device_for_read(). We read the Volume label from the block and
34 * leave the block pointers just after the label.
36 * Returns: NULL if failed for any reason
39 bool acquire_device_for_read(DCR *dcr)
41 DEVICE *dev = dcr->dev;
44 bool tape_previously_mounted;
45 bool tape_initially_mounted;
47 bool try_autochanger = true;
52 Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
53 dev->block(BST_DOING_ACQUIRE);
55 if (dev->num_writers > 0) {
56 Jmsg2(jcr, M_FATAL, 0, _("Num_writers=%d not zero. Job %d canceled.\n"),
57 dev->num_writers, jcr->JobId);
61 /* Find next Volume, if any */
65 Jmsg(jcr, M_FATAL, 0, _("No volumes specified. Job %s canceled.\n"),
66 edit_int64(jcr->JobId, ed1));
70 for (i=1; i<jcr->CurVolume; i++) {
74 Jmsg(jcr, M_FATAL, 0, _("Logic error: no next volume. Numvol=%d Curvol=%d\n"),
75 jcr->NumVolumes, jcr->CurVolume);
76 goto get_out; /* should not happen */
78 bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
79 bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
80 dcr->VolCatInfo.Slot = vol->Slot;
83 * If the MediaType requested for this volume is not the
84 * same as the current drive, we attempt to find the same
85 * device that was used to write the orginal volume. If
86 * found, we switch to using that device.
88 Dmsg2(100, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type);
89 if (dcr->media_type[0] && strcmp(dcr->media_type, dev->device->media_type) != 0) {
93 DCR *dcr_save = jcr->dcr;
97 memset(&rctx, 0, sizeof(RCTX));
99 jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
100 rctx.any_drive = true;
101 rctx.device_name = vol->device;
102 store = new DIRSTORE;
103 memset(store, 0, sizeof(DIRSTORE));
104 store->name[0] = 0; /* No dir name */
105 bstrncpy(store->media_type, vol->MediaType, sizeof(store->media_type));
106 bstrncpy(store->pool_name, dcr->pool_name, sizeof(store->pool_name));
107 bstrncpy(store->pool_type, dcr->pool_type, sizeof(store->pool_type));
108 store->append = false;
112 * Note, if search_for_device() succeeds, we get a new_dcr,
113 * which we do not use except for the dev info.
115 stat = search_res_for_device(rctx);
116 release_msgs(jcr); /* release queued messages */
117 unlock_reservations();
119 DCR *new_dcr = jcr->read_dcr;
121 detach_dcr_from_dev(dcr); /* release old device */
122 /* Copy important info from the new dcr */
123 dev = dcr->dev = new_dcr->dev;
125 dcr->device = new_dcr->device;
126 dcr->max_job_spool_size = dcr->device->max_job_spool_size;
127 attach_dcr_to_dev(dcr);
128 new_dcr->VolumeName[0] = 0;
130 dev->block(BST_DOING_ACQUIRE);
131 Jmsg(jcr, M_INFO, 0, _("Media Type change. New device %s chosen.\n"),
133 bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
134 bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
135 dcr->VolCatInfo.Slot = vol->Slot;
136 bstrncpy(dcr->pool_name, store->pool_name, sizeof(dcr->pool_name));
137 bstrncpy(dcr->pool_type, store->pool_type, sizeof(dcr->pool_type));
138 } else if (stat == 0) { /* device busy */
139 Dmsg1(000, "Device %s is busy.\n", vol->device);
142 Jmsg1(jcr, M_FATAL, 0, _("No suitable device found to read Volume \"%s\"\n"),
151 init_device_wait_timers(dcr);
153 tape_previously_mounted = dev->can_read() || dev->can_append() ||
155 tape_initially_mounted = tape_previously_mounted;
158 /* Volume info is always needed because of VolParts */
159 Dmsg0(200, "dir_get_volume_info\n");
160 if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) {
161 Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
165 /* If not polling limit retries */
166 if (!dev->poll && retry++ > 10) {
169 dev->clear_labeled(); /* force reread of label */
170 if (job_canceled(jcr)) {
172 Mmsg1(dev->errmsg, _("Job %s canceled.\n"), edit_int64(jcr->JobId, ed1));
173 Jmsg(jcr, M_INFO, 0, dev->errmsg);
174 goto get_out; /* error return */
177 autoload_device(dcr, 0, NULL);
180 * This code ensures that the device is ready for
181 * reading. If it is a file, it opens it.
182 * If it is a tape, it checks the volume name
184 Dmsg1(100, "bstored: open vol=%s\n", dcr->VolumeName);
185 if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
186 Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"),
187 dev->print_name(), dcr->VolumeName, dev->bstrerror());
190 Dmsg1(100, "opened dev %s OK\n", dev->print_name());
192 /* Read Volume Label */
194 Dmsg0(200, "calling read-vol-label\n");
195 vol_label_status = read_dev_volume_label(dcr);
196 switch (vol_label_status) {
199 memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
203 * Send error message generated by read_dev_volume_label()
204 * only we really had a tape mounted. This supresses superfluous
205 * error messages when nothing is mounted.
207 if (tape_previously_mounted) {
208 Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
212 if (tape_initially_mounted) {
213 tape_initially_mounted = false;
216 /* If polling and got a previous bad name, ignore it */
217 if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolumeName) == 0) {
220 bstrncpy(dev->BadVolName, dev->VolHdr.VolumeName, sizeof(dev->BadVolName));
224 Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
226 tape_previously_mounted = true;
229 * If the device requires mount, close it, so the device can be ejected.
231 if (dev->requires_mount()) {
235 /* Call autochanger only once unless ask_sysop called */
236 if (try_autochanger) {
238 Dmsg2(200, "calling autoload Vol=%s Slot=%d\n",
239 dcr->VolumeName, dcr->VolCatInfo.Slot);
240 stat = autoload_device(dcr, 0, NULL);
242 try_autochanger = false;
243 continue; /* try reading volume mounted */
247 /* Mount a specific volume and no other */
248 Dmsg0(200, "calling dir_ask_sysop\n");
249 if (!dir_ask_sysop_to_mount_volume(dcr)) {
250 goto get_out; /* error return */
252 try_autochanger = true; /* permit using autochanger again */
253 continue; /* try reading again */
258 Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s.\n"),
265 set_jcr_job_status(jcr, JS_Running);
266 dir_send_job_status(jcr);
267 Jmsg(jcr, M_INFO, 0, _("Ready to read from volume \"%s\" on device %s.\n"),
268 dcr->VolumeName, dev->print_name());
272 if (dcr->reserved_device) {
273 dev->reserved_device--;
274 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
275 dcr->reserved_device = false;
279 Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
285 * Acquire device for writing. We permit multiple writers.
286 * If this is the first one, we read the label.
288 * Returns: NULL if failed for any reason
290 * Note, normally reserve_device_for_append() is called
291 * before this routine.
293 DCR *acquire_device_for_append(DCR *dcr)
295 bool release = false;
296 bool recycle = false;
297 bool do_mount = false;
298 DEVICE *dev = dcr->dev;
301 init_device_wait_timers(dcr);
303 dev->block(BST_DOING_ACQUIRE);
304 Dmsg1(190, "acquire_append device is %s\n", dev->is_tape()?"tape":
305 (dev->is_dvd()?"DVD":"disk"));
308 * With the reservation system, this should not happen
310 if (dev->can_read()) {
311 Jmsg1(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev->print_name());
312 Dmsg1(200, "Device %s is busy reading.\n", dev->print_name());
316 if (dev->can_append()) {
317 Dmsg0(190, "device already in append.\n");
319 * Device already in append mode
321 * Check if we have the right Volume mounted
322 * OK if current volume info OK
323 * OK if next volume matches current volume
324 * otherwise mount desired volume obtained from
325 * dir_find_next_appendable_volume
326 * dev->VolHdr.VolumeName is what is in the drive
327 * dcr->VolumeName is what we pass into the routines, or
328 * get back from the subroutines.
330 bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
331 if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
332 !(dir_find_next_appendable_volume(dcr) &&
333 strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
334 Dmsg2(190, "Wrong tape mounted: %s. wants:%s\n", dev->VolHdr.VolumeName,
336 /* Release volume reserved by dir_find_next_appendable_volume() */
337 if (dcr->VolumeName[0]) {
338 free_unused_volume(dcr);
340 if (dev->num_writers != 0) {
341 Jmsg3(jcr, M_FATAL, 0, _("Wanted Volume \"%s\", but device %s is busy writing on \"%s\" .\n"),
342 dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
343 Dmsg3(200, "Wanted Volume \"%s\", but device %s is busy writing on \"%s\" .\n",
344 dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
347 /* Wrong tape mounted, release it, then fall through to get correct one */
348 Dmsg0(190, "Wrong tape mounted, release and try mount.\n");
353 * At this point, the correct tape is already mounted, so
354 * we do not need to do mount_next_write_volume(), unless
355 * we need to recycle the tape.
357 recycle = strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0;
358 Dmsg1(190, "Correct tape mounted. recycle=%d\n", recycle);
359 if (recycle && dev->num_writers != 0) {
360 Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\""
361 " on device %s because it is in use by another job.\n"),
362 dev->VolHdr.VolumeName, dev->print_name());
365 if (dev->num_writers == 0) {
366 memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
370 /* Not already in append mode, so mount the device */
371 Dmsg0(190, "Not in append mode, try mount.\n");
372 ASSERT(dev->num_writers == 0);
376 if (do_mount || recycle) {
377 Dmsg0(190, "Do mount_next_write_vol\n");
378 bool mounted = mount_next_write_volume(dcr, release);
380 if (!job_canceled(jcr)) {
381 /* Reduce "noise" -- don't print if job canceled */
382 Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
384 Dmsg1(200, "Could not ready device %s for append.\n",
389 Dmsg2(190, "Output pos=%u:%u\n", dcr->dev->file, dcr->dev->block_num);
392 dev->num_writers++; /* we are now a writer */
393 if (jcr->NumVolumes == 0) {
397 if (dcr->reserved_device) {
398 dev->reserved_device--;
399 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
400 dcr->reserved_device = false;
411 if (dcr->reserved_device) {
412 dev->reserved_device--;
413 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
414 dcr->reserved_device = false;
423 * This job is done, so release the device. From a Unix standpoint,
424 * the device remains open.
426 * Note, if we are spooling, we may enter with the device locked.
427 * However, in all cases, unlock the device when leaving.
430 bool release_device(DCR *dcr)
433 DEVICE *dev = dcr->dev;
436 /* lock only if not already locked by this thread */
437 if (!dcr->dev_locked) {
440 Dmsg2(100, "release_device device %s is %s\n", dev->print_name(), dev->is_tape()?"tape":"disk");
442 /* if device is reserved, job never started, so release the reserve here */
443 if (dcr->reserved_device) {
444 dev->reserved_device--;
445 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
446 dcr->reserved_device = false;
449 if (dev->can_read()) {
450 dev->clear_read(); /* clear read bit */
452 /******FIXME**** send read volume usage statistics to director */
454 } else if (dev->num_writers > 0) {
456 * Note if WEOT is set, we are at the end of the tape
457 * and may not be positioned correctly, so the
458 * job_media_record and update_vol_info have already been
459 * done, which means we skip them here.
462 Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers);
463 if (dev->is_labeled()) {
464 Dmsg0(100, "dir_create_jobmedia_record. Release\n");
465 if (!dev->at_weot() && !dir_create_jobmedia_record(dcr)) {
466 Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
467 dcr->VolCatInfo.VolCatName, jcr->Job);
469 /* If no more writers, write an EOF */
470 if (!dev->num_writers && dev->can_write()) {
472 write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName);
474 if (!dev->at_weot()) {
475 dev->VolCatInfo.VolCatFiles = dev->file; /* set number of files */
476 dev->VolCatInfo.VolCatJobs++; /* increment number of jobs */
477 /* Note! do volume update before close, which zaps VolCatInfo */
478 Dmsg0(100, "dir_update_vol_info. Release0\n");
479 dir_update_volume_info(dcr, false); /* send Volume info to Director */
485 * If we reach here, it is most likely because the job
486 * has failed, since the device is not in read mode and
487 * there are no writers. It was probably reserved.
491 /* If no writers, close if file or !CAP_ALWAYS_OPEN */
492 if (dev->num_writers == 0 && (!dev->is_tape() || !dev_cap(dev, CAP_ALWAYSOPEN))) {
493 dvd_remove_empty_part(dcr); /* get rid of any empty spool part */
497 /* Fire off Alert command and include any output */
498 if (!job_canceled(jcr) && dcr->device->alert_command) {
502 char line[MAXSTRING];
503 alert = get_pool_memory(PM_FNAME);
504 alert = edit_device_codes(dcr, alert, dcr->device->alert_command, "");
505 bpipe = open_bpipe(alert, 0, "r");
507 while (fgets(line, sizeof(line), bpipe->rfd)) {
508 Jmsg(jcr, M_ALERT, 0, _("Alert: %s"), line);
510 status = close_bpipe(bpipe);
516 Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"),
517 alert, be.strerror(status));
520 Dmsg1(400, "alert status=%d\n", status);
521 free_pool_memory(alert);
523 dcr->dev_locked = false; /* set no longer locked */
525 if (jcr->read_dcr == dcr) {
526 jcr->read_dcr = NULL;
528 if (jcr->dcr == dcr) {
536 * Create a new Device Control Record and attach
537 * it to the device (if this is a real job).
539 DCR *new_dcr(JCR *jcr, DEVICE *dev)
541 DCR *dcr = (DCR *)malloc(sizeof(DCR));
542 memset(dcr, 0, sizeof(DCR));
546 dcr->device = dev->device;
547 dcr->block = new_block(dev);
548 dcr->rec = new_record();
549 dcr->max_job_spool_size = dev->device->max_job_spool_size;
550 attach_dcr_to_dev(dcr);
557 * Search the dcrs list for the given dcr. If it is found,
558 * as it should be, then remove it. Also zap the jcr pointer
559 * to the dcr if it is the same one.
562 static void remove_dcr_from_dcrs(DCR *dcr)
568 int num = jcr->dcrs->size();
569 for (i=0; i < num; i++) {
570 ldcr = (DCR *)jcr->dcrs->get(i);
572 jcr->dcrs->remove(i);
573 if (jcr->dcr == dcr) {
582 static void attach_dcr_to_dev(DCR *dcr)
584 DEVICE *dev = dcr->dev;
587 if (!dcr->attached_to_dev && dev->is_open() && jcr && jcr->JobType != JT_SYSTEM) {
588 dev->attached_dcrs->append(dcr); /* attach dcr to device */
589 dcr->attached_to_dev = true;
593 void detach_dcr_from_dev(DCR *dcr)
595 DEVICE *dev = dcr->dev;
597 if (dcr->reserved_device) {
598 dcr->reserved_device = false;
600 dev->reserved_device--;
601 Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
602 dcr->reserved_device = false;
603 /* If we set read mode in reserving, remove it */
604 if (dev->can_read()) {
607 if (dev->num_writers < 0) {
608 Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
609 dev->num_writers = 0;
614 /* Detach this dcr only if attached */
615 if (dcr->attached_to_dev) {
616 dcr->dev->attached_dcrs->remove(dcr); /* detach dcr from device */
617 dcr->attached_to_dev = false;
618 // remove_dcr_from_dcrs(dcr); /* remove dcr from jcr list */
620 free_unused_volume(dcr); /* free unused vols attached to this dcr */
621 pthread_cond_broadcast(&dcr->dev->wait_next_vol);
622 pthread_cond_broadcast(&wait_device_release);
626 * Free up all aspects of the given dcr -- i.e. dechain it,
627 * release allocated memory, zap pointers, ...
629 void free_dcr(DCR *dcr)
632 detach_dcr_from_dev(dcr);
635 free_block(dcr->block);
638 free_record(dcr->rec);
641 dcr->jcr->dcr = NULL;