]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/acquire.c
kes Move the checking of the database in initializion of the Director
[bacula/bacula] / bacula / src / stored / acquire.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2002-2007 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 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.
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 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® 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.
27 */
28 /*
29  *  Routines to acquire and release a device for read/write
30  *
31  *   Kern Sibbald, August MMII
32  *
33  *   Version $Id$
34  */
35
36 #include "bacula.h"                   /* pull in global headers */
37 #include "stored.h"                   /* pull in Storage Deamon headers */
38
39 /* Forward referenced functions */
40 static void attach_dcr_to_dev(DCR *dcr);
41
42
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.
48  *
49  *  Returns: NULL if failed for any reason
50  *           dcr  if successful
51  */
52 bool acquire_device_for_read(DCR *dcr)
53 {
54    DEVICE *dev = dcr->dev;
55    JCR *jcr = dcr->jcr;
56    bool ok = false;
57    bool tape_previously_mounted;
58    bool tape_initially_mounted;
59    VOL_LIST *vol;
60    bool try_autochanger = true;
61    int i;
62    int vol_label_status;
63    int retry = 0;
64    
65    Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
66    dev->block(BST_DOING_ACQUIRE);
67
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);
71       goto get_out;
72    }
73
74    /* Find next Volume, if any */
75    vol = jcr->VolList;
76    if (!vol) {
77       char ed1[50];
78       Jmsg(jcr, M_FATAL, 0, _("No volumes specified for reading. Job %s canceled.\n"), 
79          edit_int64(jcr->JobId, ed1));
80       goto get_out;
81    }
82    jcr->CurReadVolume++;
83    for (i=1; i<jcr->CurReadVolume; i++) {
84       vol = vol->next;
85    }
86    if (!vol) {
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 */   
90    }
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;
94     
95    /*
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.
100     */
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) {
103       RCTX rctx;
104       DIRSTORE *store;
105       int stat;
106       DCR *dcr_save = jcr->dcr;
107
108       lock_reservations();
109       jcr->dcr = NULL;
110       memset(&rctx, 0, sizeof(RCTX));
111       rctx.jcr = jcr;
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;
122       rctx.store = store;
123       
124       /*
125        * Note, if search_for_device() succeeds, we get a new_dcr,
126        *  which we do not use except for the dev info.
127        */
128       stat = search_res_for_device(rctx);
129       release_msgs(jcr);              /* release queued messages */
130       unlock_reservations();
131       if (stat == 1) {
132          DCR *new_dcr = jcr->read_dcr;
133          dev->unblock();
134          detach_dcr_from_dev(dcr);    /* release old device */
135          /* Copy important info from the new dcr */
136          dev = dcr->dev = new_dcr->dev; 
137          jcr->read_dcr = dcr; 
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;
142          free_dcr(new_dcr);
143          dev->block(BST_DOING_ACQUIRE); 
144          Jmsg(jcr, M_INFO, 0, _("Media Type change.  New device %s chosen.\n"),
145             dev->print_name());
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);
153       } else {
154          /* error */
155          Jmsg1(jcr, M_FATAL, 0, _("No suitable device found to read Volume \"%s\"\n"),
156             vol->VolumeName);
157          jcr->dcr = dcr_save;
158          goto get_out;
159       }
160       jcr->dcr = dcr_save;
161    }
162
163
164    init_device_wait_timers(dcr);
165
166    tape_previously_mounted = dev->can_read() || dev->can_append() ||
167                              dev->is_labeled();
168    tape_initially_mounted = tape_previously_mounted;
169
170
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);
175    }
176    
177    for ( ;; ) {
178       /* If not polling limit retries */
179       if (!dev->poll && retry++ > 10) {
180          break;
181       }
182       dev->clear_labeled();              /* force reread of label */
183       if (job_canceled(jcr)) {
184          char ed1[50];
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 */
188       }
189
190       autoload_device(dcr, 0, NULL);
191
192       /*
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
196        */
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());
201          goto default_path;
202       }
203       Dmsg1(100, "opened dev %s OK\n", dev->print_name());
204       
205       /* Read Volume Label */
206       
207       Dmsg0(200, "calling read-vol-label\n");
208       vol_label_status = read_dev_volume_label(dcr);
209       switch (vol_label_status) {
210       case VOL_OK:
211          ok = true;
212          memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
213          break;                    /* got it */
214       case VOL_IO_ERROR:
215          /*
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.
219           */
220          if (tape_previously_mounted) {
221             Jmsg(jcr, M_WARNING, 0, "%s", jcr->errmsg);
222          }
223          goto default_path;
224       case VOL_NAME_ERROR:
225          if (tape_initially_mounted) {
226             tape_initially_mounted = false;
227             goto default_path;
228          }
229          /* If polling and got a previous bad name, ignore it */
230          if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolumeName) == 0) {
231             goto default_path;
232          } else {
233              bstrncpy(dev->BadVolName, dev->VolHdr.VolumeName, sizeof(dev->BadVolName));
234          }
235          /* Fall through */
236       default:
237          Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
238 default_path:
239          tape_previously_mounted = true;
240          
241          /*
242           * If the device requires mount, close it, so the device can be ejected.
243           */
244          if (dev->requires_mount()) {
245             dev->close();
246          }
247          
248          /* Call autochanger only once unless ask_sysop called */
249          if (try_autochanger) {
250             int stat;
251             Dmsg2(200, "calling autoload Vol=%s Slot=%d\n",
252                dcr->VolumeName, dcr->VolCatInfo.Slot);
253             stat = autoload_device(dcr, 0, NULL);
254             if (stat > 0) {
255                try_autochanger = false;
256                continue;              /* try reading volume mounted */
257             }
258          }
259          
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 */
264          }
265          try_autochanger = true;      /* permit using autochanger again */
266          continue;                    /* try reading again */
267       } /* end switch */
268       break;
269    } /* end for loop */
270    if (!ok) {
271       Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s for reading.\n"),
272             dev->print_name());
273       goto get_out;
274    }
275
276    dev->clear_append();
277    dev->set_read();
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());
282
283 get_out:
284    dev->lock();
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;
289    }
290    dev->unlock();
291    dev->unblock();
292    Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
293    return ok;
294 }
295
296
297 /*
298  * Acquire device for writing. We permit multiple writers.
299  *  If this is the first one, we read the label.
300  *
301  *  Returns: NULL if failed for any reason
302  *           dcr if successful.
303  *   Note, normally reserve_device_for_append() is called
304  *   before this routine.
305  */
306 DCR *acquire_device_for_append(DCR *dcr)
307 {
308    bool release = false;
309    bool recycle = false;
310    bool do_mount = false;
311    DEVICE *dev = dcr->dev;
312    JCR *jcr = dcr->jcr;
313
314    init_device_wait_timers(dcr);
315
316    dev->block(BST_DOING_ACQUIRE);
317    Dmsg1(190, "acquire_append device is %s\n", dev->is_tape()?"tape":
318         (dev->is_dvd()?"DVD":"disk"));
319
320    /*
321     * With the reservation system, this should not happen
322     */
323    if (dev->can_read()) {
324       Jmsg1(jcr, M_FATAL, 0, _("Want to append, but device %s is busy reading.\n"), dev->print_name());
325       Dmsg1(200, "Want to append but device %s is busy reading.\n", dev->print_name());
326       goto get_out;
327    }
328
329    if (dev->can_append()) {
330       Dmsg0(190, "device already in append.\n");
331       /*
332        * Device already in append mode
333        *
334        * Check if we have the right Volume mounted
335        *   OK if current volume info OK
336        *   OK if next volume matches current volume
337        *   otherwise mount desired volume obtained from
338        *    dir_find_next_appendable_volume
339        *  dev->VolHdr.VolumeName is what is in the drive
340        *  dcr->VolumeName is what we pass into the routines, or
341        *    get back from the subroutines.
342        */
343       bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
344       if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE) &&
345           !(dir_find_next_appendable_volume(dcr) &&
346             strcmp(dev->VolHdr.VolumeName, dcr->VolumeName) == 0)) { /* wrong tape mounted */
347          Dmsg2(190, "Wrong tape mounted: %s. wants:%s\n", dev->VolHdr.VolumeName,
348             dcr->VolumeName);
349          /* Release volume reserved by dir_find_next_appendable_volume() */
350          if (dcr->VolumeName[0]) {
351             free_unused_volume(dcr);
352          }
353          if (dev->num_writers != 0) {
354             Jmsg3(jcr, M_FATAL, 0, _("Wanted to append to Volume \"%s\", but device %s is busy writing on \"%s\" .\n"), 
355                  dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
356             Dmsg3(200, "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             goto get_out;
359          }
360          /* Wrong tape mounted, release it, then fall through to get correct one */
361          Dmsg0(190, "Wrong tape mounted, release and try mount.\n");
362          release = true;
363          do_mount = true;
364       } else {
365          /*
366           * At this point, the correct tape is already mounted, so
367           *   we do not need to do mount_next_write_volume(), unless
368           *   we need to recycle the tape.
369           */
370           recycle = strcmp(dcr->VolCatInfo.VolCatStatus, "Recycle") == 0;
371           Dmsg1(190, "Correct tape mounted. recycle=%d\n", recycle);
372           if (recycle && dev->num_writers != 0) {
373              Jmsg(jcr, M_FATAL, 0, _("Cannot recycle volume \"%s\""
374                   " on device %s because it is in use by another job.\n"),
375                   dev->VolHdr.VolumeName, dev->print_name());
376              goto get_out;
377           }
378           if (dev->num_writers == 0) {
379              memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
380           }
381       }
382    } else {
383       /* Not already in append mode, so mount the device */
384       Dmsg0(190, "Not in append mode, try mount.\n");
385       ASSERT(dev->num_writers == 0);
386       do_mount = true;
387    }
388
389    if (do_mount || recycle) {
390       Dmsg0(190, "Do mount_next_write_vol\n");
391       bool mounted = mount_next_write_volume(dcr, release);
392       if (!mounted) {
393          if (!job_canceled(jcr)) {
394             /* Reduce "noise" -- don't print if job canceled */
395             Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
396                dev->print_name());
397             Dmsg1(200, "Could not ready device %s for append.\n", 
398                dev->print_name());
399          }
400          goto get_out;
401       }
402       Dmsg2(190, "Output pos=%u:%u\n", dcr->dev->file, dcr->dev->block_num);
403    }
404
405    dev->num_writers++;                /* we are now a writer */
406    if (jcr->NumWriteVolumes == 0) {
407       jcr->NumWriteVolumes = 1;
408    }
409    dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs on vol */
410    dir_update_volume_info(dcr, false);        /* send Volume info to Director */
411    dev->lock();
412    if (dcr->reserved_device) {
413       dev->reserved_device--;
414       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
415       dcr->reserved_device = false;
416    }
417    dev->unlock();
418    dev->unblock();
419    return dcr;
420
421 /*
422  * Error return
423  */
424 get_out:
425    dev->lock();
426    if (dcr->reserved_device) {
427       dev->reserved_device--;
428       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
429       dcr->reserved_device = false;
430    }
431    dev->unlock();
432    dev->unblock();
433    return NULL;
434 }
435
436
437 /*
438  * This job is done, so release the device. From a Unix standpoint,
439  *  the device remains open.
440  *
441  * Note, if we are spooling, we may enter with the device locked.
442  * However, in all cases, unlock the device when leaving.
443  *
444  */
445 bool release_device(DCR *dcr)
446 {
447    JCR *jcr = dcr->jcr;
448    DEVICE *dev = dcr->dev;
449    bool ok = true;
450
451    /* lock only if not already locked by this thread */
452    if (!dcr->dev_locked) {
453       lock_device(dev);
454    }
455    Dmsg2(100, "release_device device %s is %s\n", dev->print_name(), dev->is_tape()?"tape":"disk");
456
457    /* if device is reserved, job never started, so release the reserve here */
458    if (dcr->reserved_device) {
459       dev->reserved_device--;
460       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
461       dcr->reserved_device = false;
462    }
463
464    if (dev->can_read()) {
465       dev->clear_read();              /* clear read bit */
466       Dmsg0(100, "dir_update_vol_info. Release0\n");
467       dir_update_volume_info(dcr, false); /* send Volume info to Director */
468
469    } else if (dev->num_writers > 0) {
470       /* 
471        * Note if WEOT is set, we are at the end of the tape
472        *   and may not be positioned correctly, so the
473        *   job_media_record and update_vol_info have already been
474        *   done, which means we skip them here.
475        */
476       dev->num_writers--;
477       Dmsg1(100, "There are %d writers in release_device\n", dev->num_writers);
478       if (dev->is_labeled()) {
479          Dmsg0(100, "dir_create_jobmedia_record. Release\n");
480          if (!dev->at_weot() && !dir_create_jobmedia_record(dcr)) {
481             Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
482                dcr->VolCatInfo.VolCatName, jcr->Job);
483          }
484          /* If no more writers, write an EOF */
485          if (!dev->num_writers && dev->can_write() && dev->block_num > 0) {
486             dev->weof(1);
487             write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName);
488          }
489          if (!dev->at_weot()) {
490             dev->VolCatInfo.VolCatFiles = dev->file;   /* set number of files */
491             /* Note! do volume update before close, which zaps VolCatInfo */
492             Dmsg0(100, "dir_update_vol_info. Release0\n");
493             dir_update_volume_info(dcr, false); /* send Volume info to Director */
494          }
495       }
496
497    } else {
498       /*                
499        * If we reach here, it is most likely because the job
500        *   has failed, since the device is not in read mode and
501        *   there are no writers. It was probably reserved.
502        */
503    }
504
505    /* If no writers, close if file or !CAP_ALWAYS_OPEN */
506    if (dev->num_writers == 0 && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) {
507       dvd_remove_empty_part(dcr);        /* get rid of any empty spool part */
508       dev->close();
509    }
510
511    /* Fire off Alert command and include any output */
512    if (!job_canceled(jcr) && dcr->device->alert_command) {
513       POOLMEM *alert;
514       int status = 1;
515       BPIPE *bpipe;
516       char line[MAXSTRING];
517       alert = get_pool_memory(PM_FNAME);
518       alert = edit_device_codes(dcr, alert, dcr->device->alert_command, "");
519       bpipe = open_bpipe(alert, 0, "r");
520       if (bpipe) {
521          while (fgets(line, sizeof(line), bpipe->rfd)) {
522             Jmsg(jcr, M_ALERT, 0, _("Alert: %s"), line);
523          }
524          status = close_bpipe(bpipe);
525       } else {
526          status = errno;
527       }
528       if (status != 0) {
529          berrno be;
530          Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"),
531               alert, be.strerror(status));
532       }
533
534       Dmsg1(400, "alert status=%d\n", status);
535       free_pool_memory(alert);
536    }
537    dcr->dev_locked = false;              /* set no longer locked */
538    unlock_device(dev);
539    if (jcr->read_dcr == dcr) {
540       jcr->read_dcr = NULL;
541    }
542    if (jcr->dcr == dcr) {
543       jcr->dcr = NULL;
544    }
545    free_dcr(dcr);
546    return ok;
547 }
548
549 /*
550  * Create a new Device Control Record and attach
551  *   it to the device (if this is a real job).
552  */
553 DCR *new_dcr(JCR *jcr, DEVICE *dev)
554 {
555    DCR *dcr = (DCR *)malloc(sizeof(DCR));
556    memset(dcr, 0, sizeof(DCR));
557    dcr->jcr = jcr;
558    if (dev) {
559       dcr->dev = dev;
560       dcr->device = dev->device;
561       dcr->block = new_block(dev);
562       dcr->rec = new_record();
563       dcr->max_job_spool_size = dev->device->max_job_spool_size;
564       attach_dcr_to_dev(dcr);
565    }
566    dcr->spool_fd = -1;
567    return dcr;
568 }
569
570 /*
571  * Search the dcrs list for the given dcr. If it is found,
572  *  as it should be, then remove it. Also zap the jcr pointer
573  *  to the dcr if it is the same one.
574  */
575 #ifdef needed
576 static void remove_dcr_from_dcrs(DCR *dcr)
577 {
578    JCR *jcr = dcr->jcr;
579    if (jcr->dcrs) {
580       int i = 0;
581       DCR *ldcr;
582       int num = jcr->dcrs->size();
583       for (i=0; i < num; i++) {
584          ldcr = (DCR *)jcr->dcrs->get(i);
585          if (ldcr == dcr) {
586             jcr->dcrs->remove(i);
587             if (jcr->dcr == dcr) {
588                jcr->dcr = NULL;
589             }
590          }
591       }
592    }
593 }
594 #endif
595
596 static void attach_dcr_to_dev(DCR *dcr)
597 {
598    DEVICE *dev = dcr->dev;
599    JCR *jcr = dcr->jcr;
600
601    if (!dcr->attached_to_dev && dev->is_open() && jcr && jcr->JobType != JT_SYSTEM) {
602       dev->attached_dcrs->append(dcr);  /* attach dcr to device */
603       dcr->attached_to_dev = true;
604    }
605 }
606
607 void detach_dcr_from_dev(DCR *dcr)
608 {
609    DEVICE *dev = dcr->dev;
610
611    if (dcr->reserved_device) {
612       dcr->reserved_device = false;
613       lock_device(dev);
614       dev->reserved_device--;
615       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
616       dcr->reserved_device = false;
617       /* If we set read mode in reserving, remove it */
618       if (dev->can_read()) {
619          dev->clear_read();
620       }
621       if (dev->num_writers < 0) {
622          Jmsg1(dcr->jcr, M_ERROR, 0, _("Hey! num_writers=%d!!!!\n"), dev->num_writers);
623          dev->num_writers = 0;
624       }
625       unlock_device(dev);
626    }
627
628    /* Detach this dcr only if attached */
629    if (dcr->attached_to_dev) {
630       dcr->dev->attached_dcrs->remove(dcr);  /* detach dcr from device */
631       dcr->attached_to_dev = false;
632 //    remove_dcr_from_dcrs(dcr);      /* remove dcr from jcr list */
633    }
634    free_unused_volume(dcr);           /* free unused vols attached to this dcr */
635    pthread_cond_broadcast(&dcr->dev->wait_next_vol);
636    pthread_cond_broadcast(&wait_device_release);
637 }
638
639 /*
640  * Free up all aspects of the given dcr -- i.e. dechain it,
641  *  release allocated memory, zap pointers, ...
642  */
643 void free_dcr(DCR *dcr)
644 {
645    JCR *jcr = dcr->jcr;
646
647    if (dcr->dev) {
648       detach_dcr_from_dev(dcr);
649    }
650
651    if (dcr->block) {
652       free_block(dcr->block);
653    }
654    if (dcr->rec) {
655       free_record(dcr->rec);
656    }
657    if (jcr && jcr->dcr == dcr) {
658       jcr->dcr = NULL;
659    }
660    free(dcr);
661 }