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