]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/acquire.c
Fix 32/64 bit problems in SD sscanf commands
[bacula/bacula] / bacula / src / stored / acquire.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2002-2011 Free Software Foundation Europe e.V.
5
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 three of the GNU Affero General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
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.
17
18    You should have received a copy of the GNU Affero 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
21    02110-1301, USA.
22
23    Bacula(R) is a registered trademark of Kern Sibbald.
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.
27 */
28 /*
29  *  Routines to acquire and release a device for read/write
30  *
31  *   Kern Sibbald, August MMII
32  *
33  */
34
35 #include "bacula.h"                   /* pull in global headers */
36 #include "stored.h"                   /* pull in Storage Deamon headers */
37
38 /* Forward referenced functions */
39 static void attach_dcr_to_dev(DCR *dcr);
40 static void detach_dcr_from_dev(DCR *dcr);
41 static void set_dcr_from_vol(DCR *dcr, VOL_LIST *vol);
42
43
44 /*********************************************************************
45  * Acquire device for reading. 
46  *  The drive should have previously been reserved by calling 
47  *  reserve_device_for_read(). We read the Volume label from the block and
48  *  leave the block pointers just after the label.
49  *
50  *  Returns: NULL if failed for any reason
51  *           dcr  if successful
52  */
53 bool acquire_device_for_read(DCR *dcr)
54 {
55    DEVICE *dev = dcr->dev;
56    JCR *jcr = dcr->jcr;
57    bool ok = false;
58    bool tape_previously_mounted;
59    VOL_LIST *vol;
60    bool try_autochanger = true;
61    int i;
62    int vol_label_status;
63    int retry = 0;
64    
65    Dmsg2(950, "dcr=%p dev=%p\n", dcr, dcr->dev);
66    Dmsg2(950, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type);
67    dev->dblock(BST_DOING_ACQUIRE);
68
69    if (dev->num_writers > 0) {
70       Jmsg2(jcr, M_FATAL, 0, _("Acquire read: num_writers=%d not zero. Job %d canceled.\n"), 
71          dev->num_writers, jcr->JobId);
72       goto get_out;
73    }
74
75    /* Find next Volume, if any */
76    vol = jcr->VolList;
77    if (!vol) {
78       char ed1[50];
79       Jmsg(jcr, M_FATAL, 0, _("No volumes specified for reading. Job %s canceled.\n"), 
80          edit_int64(jcr->JobId, ed1));
81       goto get_out;
82    }
83    jcr->CurReadVolume++;
84    for (i=1; i<jcr->CurReadVolume; i++) {
85       vol = vol->next;
86    }
87    if (!vol) {
88       Jmsg(jcr, M_FATAL, 0, _("Logic error: no next volume to read. Numvol=%d Curvol=%d\n"),
89          jcr->NumReadVolumes, jcr->CurReadVolume);
90       goto get_out;                   /* should not happen */   
91    }
92    set_dcr_from_vol(dcr, vol);
93
94    if (generate_plugin_event(jcr, bsdEventDeviceOpen, dcr) != bRC_OK) {
95       Jmsg(jcr, M_FATAL, 0, _("generate_plugin_event(bsdEventDeviceOpen) Failed\n"));
96       goto get_out;
97    }
98
99    Dmsg2(100, "Want Vol=%s Slot=%d\n", vol->VolumeName, vol->Slot);
100     
101    /*
102     * If the MediaType requested for this volume is not the
103     *  same as the current drive, we attempt to find the same
104     *  device that was used to write the orginal volume.  If
105     *  found, we switch to using that device.
106     *
107     *  N.B. A lot of routines rely on the dcr pointer not changing
108     *    read_records.c even has multiple dcrs cached, so we take care
109     *    here to release all important parts of the dcr and re-acquire
110     *    them such as the block pointer (size may change), but we do
111     *    not release the dcr.
112     */
113    Dmsg2(50, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type);
114    if (dcr->media_type[0] && strcmp(dcr->media_type, dev->device->media_type) != 0) {
115       RCTX rctx;
116       DIRSTORE *store;
117       int stat;
118
119       Jmsg3(jcr, M_INFO, 0, _("Changing read device. Want Media Type=\"%s\" have=\"%s\"\n"
120                               "  device=%s\n"), 
121             dcr->media_type, dev->device->media_type, dev->print_name());
122       Dmsg3(50, "Changing read device. Want Media Type=\"%s\" have=\"%s\"\n"
123                               "  device=%s\n", 
124             dcr->media_type, dev->device->media_type, dev->print_name());
125
126       generate_plugin_event(jcr, bsdEventDeviceClose, dcr);
127
128       dev->dunblock(DEV_UNLOCKED);
129
130       lock_reservations();
131       memset(&rctx, 0, sizeof(RCTX));
132       rctx.jcr = jcr;
133       jcr->read_dcr = dcr;
134       jcr->reserve_msgs = New(alist(10, not_owned_by_alist));
135       rctx.any_drive = true;
136       rctx.device_name = vol->device;
137       store = new DIRSTORE;
138       memset(store, 0, sizeof(DIRSTORE));
139       store->name[0] = 0; /* No dir name */
140       bstrncpy(store->media_type, vol->MediaType, sizeof(store->media_type));
141       bstrncpy(store->pool_name, dcr->pool_name, sizeof(store->pool_name));
142       bstrncpy(store->pool_type, dcr->pool_type, sizeof(store->pool_type));
143       store->append = false;
144       rctx.store = store;
145       clean_device(dcr);                     /* clean up the dcr */
146       
147       /*
148        * Search for a new device
149        */
150       stat = search_res_for_device(rctx);
151       release_reserve_messages(jcr);         /* release queued messages */
152       unlock_reservations();
153
154       if (stat == 1) {
155          dev = dcr->dev;                     /* get new device pointer */
156          dev->dblock(BST_DOING_ACQUIRE); 
157
158          dcr->VolumeName[0] = 0;
159          Jmsg(jcr, M_INFO, 0, _("Media Type change.  New read device %s chosen.\n"),
160             dev->print_name());
161          Dmsg1(50, "Media Type change.  New read device %s chosen.\n", dev->print_name());
162          if (generate_plugin_event(jcr, bsdEventDeviceOpen, dcr) != bRC_OK) {
163             Jmsg(jcr, M_FATAL, 0, _("generate_plugin_event(bsdEventDeviceOpen) Failed\n"));
164             goto get_out;
165          }
166          bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
167          dcr->setVolCatName(vol->VolumeName);
168          bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
169          dcr->VolCatInfo.Slot = vol->Slot;
170          dcr->VolCatInfo.InChanger = vol->Slot > 0; 
171          bstrncpy(dcr->pool_name, store->pool_name, sizeof(dcr->pool_name));
172          bstrncpy(dcr->pool_type, store->pool_type, sizeof(dcr->pool_type));
173       } else {
174          /* error */
175          Jmsg1(jcr, M_FATAL, 0, _("No suitable device found to read Volume \"%s\"\n"),
176             vol->VolumeName);
177          Dmsg1(50, "No suitable device found to read Volume \"%s\"\n", vol->VolumeName);
178          goto get_out;
179       }
180    }
181    Dmsg2(400, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type);
182
183    dev->clear_unload();
184
185    if (dev->vol && dev->vol->is_swapping()) {
186       dev->vol->set_slot(vol->Slot);
187       Dmsg3(100, "swapping: slot=%d Vol=%s dev=%s\n", dev->vol->get_slot(),
188          dev->vol->vol_name, dev->print_name());
189    }
190
191    init_device_wait_timers(dcr);
192
193    tape_previously_mounted = dev->can_read() || dev->can_append() ||
194                              dev->is_labeled();
195 // tape_initially_mounted = tape_previously_mounted;
196
197    /* Volume info is always needed because of VolParts */
198    Dmsg1(150, "dir_get_volume_info vol=%s\n", dcr->VolumeName);
199    if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) {
200       Dmsg2(150, "dir_get_vol_info failed for vol=%s: %s\n", 
201          dcr->VolumeName, jcr->errmsg);
202       Jmsg1(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg);
203    }
204    dev->set_load();                /* set to load volume */
205    
206    for ( ;; ) {
207       /* If not polling limit retries */
208       if (!dev->poll && retry++ > 10) {
209          break;
210       }
211       dev->clear_labeled();              /* force reread of label */
212       if (job_canceled(jcr)) {
213          char ed1[50];
214          Mmsg1(dev->errmsg, _("Job %s canceled.\n"), edit_int64(jcr->JobId, ed1));
215          Jmsg(jcr, M_INFO, 0, dev->errmsg);
216          goto get_out;                /* error return */
217       }
218
219       dcr->do_unload();
220       dcr->do_swapping(false/*!is_writing*/);
221       dcr->do_load(false /*!is_writing*/);
222       set_dcr_from_vol(dcr, vol);          /* refresh dcr with desired volume info */
223
224       /*
225        * This code ensures that the device is ready for
226        * reading. If it is a file, it opens it.
227        * If it is a tape, it checks the volume name
228        */
229       Dmsg1(100, "bstored: open vol=%s\n", dcr->VolumeName);
230       if (dev->open(dcr, OPEN_READ_ONLY) < 0) {
231          if (!dev->poll) {
232             Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"),
233                   dev->print_name(), dcr->VolumeName, dev->bstrerror());
234          }
235          goto default_path;
236       }
237       Dmsg1(50, "opened dev %s OK\n", dev->print_name());
238       
239       /* Read Volume Label */
240       Dmsg0(50, "calling read-vol-label\n");
241       vol_label_status = read_dev_volume_label(dcr);
242       switch (vol_label_status) {
243       case VOL_OK:
244          Dmsg0(50, "Got correct volume.\n");
245          ok = true;
246          dev->VolCatInfo = dcr->VolCatInfo;     /* structure assignment */
247          break;                    /* got it */
248       case VOL_IO_ERROR:
249          Dmsg0(50, "IO Error\n");
250          /*
251           * Send error message generated by read_dev_volume_label()
252           *  only we really had a tape mounted. This supresses superfluous
253           *  error messages when nothing is mounted.
254           */
255          if (tape_previously_mounted) {
256             Jmsg(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg);
257          }
258          goto default_path;
259       case VOL_NAME_ERROR:
260          Dmsg3(50, "Vol name=%s want=%s drv=%s.\n", dev->VolHdr.VolumeName, 
261                dcr->VolumeName, dev->print_name());
262          if (dev->is_volume_to_unload()) {
263             goto default_path;
264          }
265          dev->set_unload();              /* force unload of unwanted tape */
266          if (!unload_autochanger(dcr, -1)) {
267             /* at least free the device so we can re-open with correct volume */
268             dev->close();                                                          
269             free_volume(dev);
270          }
271          dev->set_load();
272          /* Fall through */
273       default:
274          Jmsg1(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg);
275 default_path:
276          Dmsg0(50, "default path\n");
277          tape_previously_mounted = true;
278          
279          /*
280           * If the device requires mount, close it, so the device can be ejected.
281           */
282          if (dev->requires_mount()) {
283             dev->close();
284             free_volume(dev);
285          }
286          
287          /* Call autochanger only once unless ask_sysop called */
288          if (try_autochanger) {
289             int stat;
290             Dmsg2(200, "calling autoload Vol=%s Slot=%d\n",
291                dcr->VolumeName, dcr->VolCatInfo.Slot);
292             stat = autoload_device(dcr, 0, NULL);
293             if (stat > 0) {
294                try_autochanger = false;
295                continue;              /* try reading volume mounted */
296             }
297          }
298          
299          /* Mount a specific volume and no other */
300          Dmsg0(200, "calling dir_ask_sysop\n");
301          if (!dir_ask_sysop_to_mount_volume(dcr, ST_READ)) {
302             goto get_out;             /* error return */
303          }
304
305          /* Volume info is always needed because of VolParts */
306          Dmsg1(150, "dir_get_volume_info vol=%s\n", dcr->VolumeName);
307          if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) {
308             Dmsg2(150, "dir_get_vol_info failed for vol=%s: %s\n", 
309                   dcr->VolumeName, jcr->errmsg);
310             Jmsg1(jcr, M_WARNING, 0, "Read acquire: %s", jcr->errmsg);
311          }
312          dev->set_load();                /* set to load volume */
313
314          try_autochanger = true;      /* permit trying the autochanger again */
315
316          continue;                    /* try reading again */
317       } /* end switch */
318       break;
319    } /* end for loop */
320
321    if (!ok) {
322       Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s for reading.\n"),
323             dev->print_name());
324       goto get_out;
325    }
326
327    dev->clear_append();
328    dev->set_read();
329    jcr->sendJobStatus(JS_Running);
330    Jmsg(jcr, M_INFO, 0, _("Ready to read from volume \"%s\" on device %s.\n"),
331       dcr->VolumeName, dev->print_name());
332
333 get_out:
334    dev->dlock();
335    /* If failed and not writing plugin close device */
336    if (!ok && dev->num_writers == 0) {
337       generate_plugin_event(jcr, bsdEventDeviceClose, dcr);
338    }
339    dcr->clear_reserved();
340    /* 
341     * Normally we are blocked, but in at least one error case above 
342     *   we are not blocked because we unsuccessfully tried changing
343     *   devices.  
344     */
345    if (dev->is_blocked()) {
346       dev->dunblock(DEV_LOCKED);
347    } else {
348       dev->dunlock();               /* dunblock() unlock the device too */
349    }
350    Dmsg2(950, "dcr=%p dev=%p\n", dcr, dcr->dev);
351    Dmsg2(950, "MediaType dcr=%s dev=%s\n", dcr->media_type, dev->device->media_type);
352    return ok;
353 }
354
355 /*
356  * Acquire device for writing. We permit multiple writers.
357  *  If this is the first one, we read the label.
358  *
359  *  Returns: NULL if failed for any reason
360  *           dcr if successful.
361  *   Note, normally reserve_device_for_append() is called
362  *   before this routine.
363  */
364 DCR *acquire_device_for_append(DCR *dcr)
365 {
366    DEVICE *dev = dcr->dev;
367    JCR *jcr = dcr->jcr;
368    bool ok = false;
369    bool have_vol = false;
370
371    init_device_wait_timers(dcr);
372
373    P(dev->acquire_mutex);           /* only one job at a time */
374    dev->dlock();
375    Dmsg1(100, "acquire_append device is %s\n", dev->is_tape()?"tape":
376         (dev->is_dvd()?"DVD":"disk"));
377
378
379    /*
380     * With the reservation system, this should not happen
381     */
382    if (dev->can_read()) {
383       Jmsg1(jcr, M_FATAL, 0, _("Want to append, but device %s is busy reading.\n"), dev->print_name());
384       Dmsg1(200, "Want to append but device %s is busy reading.\n", dev->print_name());
385       goto get_out;
386    }
387
388    dev->clear_unload();
389
390    /*
391     * have_vol defines whether or not mount_next_write_volume should
392     *   ask the Director again about what Volume to use.
393     */
394    if (dev->can_append() && dcr->is_suitable_volume_mounted() &&
395        strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") != 0) {
396       Dmsg0(190, "device already in append.\n");
397       /*
398        * At this point, the correct tape is already mounted, so
399        *   we do not need to do mount_next_write_volume(), unless
400        *   we need to recycle the tape.
401        */
402        if (dev->num_writers == 0) {
403           dev->VolCatInfo = dcr->VolCatInfo;   /* structure assignment */
404        }
405        have_vol = dcr->is_tape_position_ok();
406    }
407
408    if (!have_vol) {
409       dev->r_dlock(true);
410       block_device(dev, BST_DOING_ACQUIRE);
411       dev->dunlock();
412       Dmsg1(190, "jid=%u Do mount_next_write_vol\n", (uint32_t)jcr->JobId);
413       if (!dcr->mount_next_write_volume()) {
414          if (!job_canceled(jcr)) {
415             /* Reduce "noise" -- don't print if job canceled */
416             Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
417                dev->print_name());
418             Dmsg1(200, "Could not ready device %s for append.\n", 
419                dev->print_name());
420          }
421          dev->dlock();
422          unblock_device(dev);
423          goto get_out;
424       }
425       Dmsg2(190, "Output pos=%u:%u\n", dcr->dev->file, dcr->dev->block_num);
426       dev->dlock();
427       unblock_device(dev);
428    }
429
430    if (generate_plugin_event(jcr, bsdEventDeviceOpen, dcr) != bRC_OK) {
431       Jmsg(jcr, M_FATAL, 0, _("generate_plugin_event(bsdEventDeviceOpen) Failed\n"));
432       goto get_out;
433    }
434
435    dev->num_writers++;                /* we are now a writer */
436    if (jcr->NumWriteVolumes == 0) {
437       jcr->NumWriteVolumes = 1;
438    }
439    dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs on vol */
440    Dmsg4(100, "=== nwriters=%d nres=%d vcatjob=%d dev=%s\n", 
441       dev->num_writers, dev->num_reserved(), dev->VolCatInfo.VolCatJobs, 
442       dev->print_name());
443    dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
444    ok = true;
445
446 get_out:
447    /* Don't plugin close here, we might have multiple writers */
448    dcr->clear_reserved();
449    dev->dunlock();
450    V(dev->acquire_mutex);
451    return ok ? dcr : NULL;
452 }
453
454 /*
455  * This job is done, so release the device. From a Unix standpoint,
456  *  the device remains open.
457  *
458  * Note, if we were spooling, we may enter with the device blocked.
459  *   We unblock at the end, only if it was us who blocked the
460  *   device.
461  *
462  */
463 bool release_device(DCR *dcr)
464 {
465    JCR *jcr = dcr->jcr;
466    DEVICE *dev = dcr->dev;
467    bool ok = true;
468    char tbuf[100];
469    int was_blocked = BST_NOT_BLOCKED;
470
471    dev->dlock();
472    if (!dev->is_blocked()) {
473       block_device(dev, BST_RELEASING);
474    } else {
475       was_blocked = dev->blocked();
476       dev->set_blocked(BST_RELEASING);
477    }
478    lock_volumes();
479    Dmsg2(100, "release_device device %s is %s\n", dev->print_name(), dev->is_tape()?"tape":"disk");
480
481    /* if device is reserved, job never started, so release the reserve here */
482    dcr->clear_reserved();
483
484    if (dev->can_read()) {
485       VOLUME_CAT_INFO *vol = &dev->VolCatInfo;
486       generate_plugin_event(jcr, bsdEventDeviceClose, dcr);
487       dev->clear_read();              /* clear read bit */
488       Dmsg2(150, "dir_update_vol_info. label=%d Vol=%s\n",
489          dev->is_labeled(), vol->VolCatName);
490       if (dev->is_labeled() && vol->VolCatName[0] != 0) {
491          dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
492          remove_read_volume(jcr, dcr->VolumeName);
493          volume_unused(dcr);
494       }
495    } else if (dev->num_writers > 0) {
496       /* 
497        * Note if WEOT is set, we are at the end of the tape
498        *   and may not be positioned correctly, so the
499        *   job_media_record and update_vol_info have already been
500        *   done, which means we skip them here.
501        */
502       dev->num_writers--;
503       Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers);
504       if (dev->is_labeled()) {
505          Dmsg2(200, "dir_create_jobmedia. Release vol=%s dev=%s\n", 
506                dev->getVolCatName(), dev->print_name());
507          if (!dev->at_weot() && !dir_create_jobmedia_record(dcr)) {
508             Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
509                dcr->getVolCatName(), jcr->Job);
510          }
511          /* If no more writers, and no errors, and wrote something, write an EOF */
512          if (!dev->num_writers && dev->can_write() && dev->block_num > 0) {
513             dev->weof(1);
514             write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName);
515          }
516          if (!dev->at_weot()) {
517             dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
518             /* Note! do volume update before close, which zaps VolCatInfo */
519             dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
520             Dmsg2(200, "dir_update_vol_info. Release vol=%s dev=%s\n", 
521                   dev->getVolCatName(), dev->print_name());
522          }
523          if (dev->num_writers == 0) {         /* if not being used */
524             volume_unused(dcr);               /*  we obviously are not using the volume */
525          }
526       }
527
528    } else {
529       /*                
530        * If we reach here, it is most likely because the job
531        *   has failed, since the device is not in read mode and
532        *   there are no writers. It was probably reserved.
533        */
534       volume_unused(dcr);
535    }
536    Dmsg3(100, "%d writers, %d reserve, dev=%s\n", dev->num_writers, dev->num_reserved(),
537          dev->print_name());
538
539    /* If no writers, close if file or !CAP_ALWAYS_OPEN */
540    if (dev->num_writers == 0 && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) {
541       generate_plugin_event(jcr, bsdEventDeviceClose, dcr);
542       dvd_remove_empty_part(dcr);        /* get rid of any empty spool part */
543       dev->close();
544       free_volume(dev);
545    }
546
547    /* Fire off Alert command and include any output */
548    if (!job_canceled(jcr) && dcr->device->alert_command) {
549       POOLMEM *alert;
550       int status = 1;
551       BPIPE *bpipe;
552       char line[MAXSTRING];
553       alert = get_pool_memory(PM_FNAME);
554       alert = edit_device_codes(dcr, alert, dcr->device->alert_command, "");
555       /* Wait maximum 5 minutes */
556       bpipe = open_bpipe(alert, 60 * 5, "r");
557       if (bpipe) {
558          while (fgets(line, sizeof(line), bpipe->rfd)) {
559             Jmsg(jcr, M_ALERT, 0, _("Alert: %s"), line);
560          }
561          status = close_bpipe(bpipe);
562       } else {
563          status = errno;
564       }
565       if (status != 0) {
566          berrno be;
567          Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"),
568               alert, be.bstrerror(status));
569       }
570
571       Dmsg1(400, "alert status=%d\n", status);
572       free_pool_memory(alert);
573    }
574    pthread_cond_broadcast(&dev->wait_next_vol);
575    Dmsg2(100, "JobId=%u broadcast wait_device_release at %s\n", 
576          (uint32_t)jcr->JobId, bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL)));
577    pthread_cond_broadcast(&wait_device_release);
578    unlock_volumes();
579
580    /*
581     * If we are the thread that blocked the device, then unblock it
582     */
583    if (pthread_equal(dev->no_wait_id, pthread_self())) {
584       dev->dunblock(true);
585    } else {
586       /* Otherwise, reset the prior block status and unlock */
587       dev->set_blocked(was_blocked);
588       dev->dunlock();
589    }
590
591    if (dcr->keep_dcr) {
592       detach_dcr_from_dev(dcr);
593    } else {
594       free_dcr(dcr);
595    }
596    Dmsg2(100, "===== Device %s released by JobId=%u\n", dev->print_name(),
597          (uint32_t)jcr->JobId);
598    return ok;
599 }
600
601 /*
602  * Clean up the device for reuse without freeing the memory
603  */
604 bool clean_device(DCR *dcr)
605 {
606    bool ok;
607    dcr->keep_dcr = true;                  /* do not free the dcr */
608    ok = release_device(dcr);
609    dcr->keep_dcr = false;
610    return ok;
611 }
612
613 /*
614  * Create a new Device Control Record and attach
615  *   it to the device (if this is a real job).
616  * Note, this has been updated so that it can be called first 
617  *   without a DEVICE, then a second or third time with a DEVICE,
618  *   and each time, it should cleanup and point to the new device.
619  *   This should facilitate switching devices.
620  * Note, each dcr must point to the controlling job (jcr).  However,
621  *   a job can have multiple dcrs, so we must not store in the jcr's
622  *   structure as previously. The higher level routine must store
623  *   this dcr in the right place
624  *
625  */
626 DCR *new_dcr(JCR *jcr, DCR *dcr, DEVICE *dev)
627 {
628    if (!dcr) {
629       int errstat;
630       dcr = (DCR *)malloc(sizeof(DCR));
631       memset(dcr, 0, sizeof(DCR));
632       dcr->tid = pthread_self();
633       dcr->spool_fd = -1;
634       if ((errstat = pthread_mutex_init(&dcr->m_mutex, NULL)) != 0) {
635          berrno be;
636          dev->dev_errno = errstat;
637          Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.bstrerror(errstat));
638          Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
639       }
640    }
641    dcr->jcr = jcr;                 /* point back to jcr */
642    /* Set device information, possibly change device */
643    if (dev) {
644       if (dcr->block) {
645          free_block(dcr->block);
646       }
647       dcr->block = new_block(dev);
648       if (dcr->rec) {
649          free_record(dcr->rec);
650       }
651       dcr->rec = new_record();
652       if (dcr->attached_to_dev) {
653          detach_dcr_from_dev(dcr);
654       }
655       /* Use job spoolsize prior to device spoolsize */
656       if (jcr->spool_size) {
657          dcr->max_job_spool_size = jcr->spool_size;
658       } else {
659          dcr->max_job_spool_size = dev->device->max_job_spool_size;
660       }
661       dcr->device = dev->device;
662       dcr->dev = dev;
663       attach_dcr_to_dev(dcr);
664    }
665    return dcr;
666 }
667
668 /*
669  * Search the dcrs list for the given dcr. If it is found,
670  *  as it should be, then remove it. Also zap the jcr pointer
671  *  to the dcr if it is the same one.
672  *
673  * Note, this code will be turned on when we can write to multiple
674  *  dcrs at the same time.
675  */
676 #ifdef needed
677 static void remove_dcr_from_dcrs(DCR *dcr)
678 {
679    JCR *jcr = dcr->jcr;
680    if (jcr->dcrs) {
681       int i = 0;
682       DCR *ldcr;
683       int num = jcr->dcrs->size();
684       for (i=0; i < num; i++) {
685          ldcr = (DCR *)jcr->dcrs->get(i);
686          if (ldcr == dcr) {
687             jcr->dcrs->remove(i);
688             if (jcr->dcr == dcr) {
689                jcr->dcr = NULL;
690             }
691          }
692       }
693    }
694 }
695 #endif
696
697 static void attach_dcr_to_dev(DCR *dcr)
698 {
699    DEVICE *dev;
700    JCR *jcr;
701
702    P(dcr->m_mutex);
703    dev = dcr->dev;
704    jcr = dcr->jcr;
705    if (jcr) Dmsg1(500, "JobId=%u enter attach_dcr_to_dev\n", (uint32_t)jcr->JobId);
706    /* ***FIXME*** return error if dev not initiated */
707    if (!dcr->attached_to_dev && dev->initiated && jcr && jcr->getJobType() != JT_SYSTEM) {
708       dev->dlock();
709       dev->attached_dcrs->append(dcr);  /* attach dcr to device */
710       dev->dunlock();
711       dcr->attached_to_dev = true;
712       Dmsg1(500, "JobId=%u attach_dcr_to_dev\n", (uint32_t)jcr->JobId);
713    }
714    V(dcr->m_mutex);
715 }
716
717 /* 
718  * DCR is locked before calling this routine
719  */
720 static void locked_detach_dcr_from_dev(DCR *dcr)
721 {
722    DEVICE *dev = dcr->dev;
723    Dmsg0(500, "Enter detach_dcr_from_dev\n"); /* jcr is NULL in some cases */
724
725    /* Detach this dcr only if attached */
726    if (dcr->attached_to_dev && dev) {
727       dcr->unreserve_device();
728       dev->dlock();
729       dcr->dev->attached_dcrs->remove(dcr);  /* detach dcr from device */
730 //    remove_dcr_from_dcrs(dcr);      /* remove dcr from jcr list */
731       dev->dunlock();
732    }
733    dcr->attached_to_dev = false;
734 }
735
736
737 static void detach_dcr_from_dev(DCR *dcr)
738 {
739    P(dcr->m_mutex);
740    locked_detach_dcr_from_dev(dcr);
741    V(dcr->m_mutex);
742 }
743
744 /*
745  * Free up all aspects of the given dcr -- i.e. dechain it,
746  *  release allocated memory, zap pointers, ...
747  */
748 void free_dcr(DCR *dcr)
749 {
750    JCR *jcr;
751
752    P(dcr->m_mutex);
753    jcr = dcr->jcr;
754
755    locked_detach_dcr_from_dev(dcr);
756
757    if (dcr->block) {
758       free_block(dcr->block);
759    }
760    if (dcr->rec) {
761       free_record(dcr->rec);
762    }
763    if (jcr && jcr->dcr == dcr) {
764       jcr->dcr = NULL;
765    }
766    if (jcr && jcr->read_dcr == dcr) {
767       jcr->read_dcr = NULL;
768    }
769    V(dcr->m_mutex);
770    pthread_mutex_destroy(&dcr->m_mutex);
771    free(dcr);
772 }
773
774 static void set_dcr_from_vol(DCR *dcr, VOL_LIST *vol)
775 {
776    /*    
777     * Note, if we want to be able to work from a .bsr file only          
778     *  for disaster recovery, we must "simulate" reading the catalog
779     */
780    bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
781    dcr->setVolCatName(vol->VolumeName);
782    bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
783    dcr->VolCatInfo.Slot = vol->Slot;
784    dcr->VolCatInfo.InChanger = vol->Slot > 0; 
785 }