]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/acquire.c
Use jcr->setJobStatus() in favor of set_jcr_job_status(jcr...)
[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    jcr->setJobStatus(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       /* Wait maximum 5 minutes */
535       bpipe = open_bpipe(alert, 60 * 5, "r");
536       if (bpipe) {
537          while (fgets(line, sizeof(line), bpipe->rfd)) {
538             Jmsg(jcr, M_ALERT, 0, _("Alert: %s"), line);
539          }
540          status = close_bpipe(bpipe);
541       } else {
542          status = errno;
543       }
544       if (status != 0) {
545          berrno be;
546          Jmsg(jcr, M_ALERT, 0, _("3997 Bad alert command: %s: ERR=%s.\n"),
547               alert, be.bstrerror(status));
548       }
549
550       Dmsg1(400, "alert status=%d\n", status);
551       free_pool_memory(alert);
552    }
553    pthread_cond_broadcast(&dev->wait_next_vol);
554    Dmsg2(100, "JobId=%u broadcast wait_device_release at %s\n", 
555          (uint32_t)jcr->JobId, bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL)));
556    pthread_cond_broadcast(&wait_device_release);
557    unlock_volumes();
558
559    /*
560     * If we are the thread that blocked the device, then unblock it
561     */
562    if (pthread_equal(dev->no_wait_id, pthread_self())) {
563       dev->dunblock(true);
564    } else {
565       /* Otherwise, reset the prior block status and unlock */
566       dev->set_blocked(was_blocked);
567       dev->dunlock();
568    }
569
570    if (dcr->keep_dcr) {
571       detach_dcr_from_dev(dcr);
572    } else {
573       free_dcr(dcr);
574    }
575    Dmsg2(100, "===== Device %s released by JobId=%u\n", dev->print_name(),
576          (uint32_t)jcr->JobId);
577    return ok;
578 }
579
580 /*
581  * Clean up the device for reuse without freeing the memory
582  */
583 bool clean_device(DCR *dcr)
584 {
585    bool ok;
586    dcr->keep_dcr = true;                  /* do not free the dcr */
587    ok = release_device(dcr);
588    dcr->keep_dcr = false;
589    return ok;
590 }
591
592 /*
593  * Create a new Device Control Record and attach
594  *   it to the device (if this is a real job).
595  * Note, this has been updated so that it can be called first 
596  *   without a DEVICE, then a second or third time with a DEVICE,
597  *   and each time, it should cleanup and point to the new device.
598  *   This should facilitate switching devices.
599  * Note, each dcr must point to the controlling job (jcr).  However,
600  *   a job can have multiple dcrs, so we must not store in the jcr's
601  *   structure as previously. The higher level routine must store
602  *   this dcr in the right place
603  *
604  */
605 DCR *new_dcr(JCR *jcr, DCR *dcr, DEVICE *dev)
606 {
607    if (!dcr) {
608       int errstat;
609       dcr = (DCR *)malloc(sizeof(DCR));
610       memset(dcr, 0, sizeof(DCR));
611       dcr->tid = pthread_self();
612       dcr->spool_fd = -1;
613       if ((errstat = pthread_mutex_init(&dcr->m_mutex, NULL)) != 0) {
614          berrno be;
615          dev->dev_errno = errstat;
616          Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.bstrerror(errstat));
617          Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
618       }
619    }
620    dcr->jcr = jcr;                 /* point back to jcr */
621    /* Set device information, possibly change device */
622    if (dev) {
623       if (dcr->block) {
624          free_block(dcr->block);
625       }
626       dcr->block = new_block(dev);
627       if (dcr->rec) {
628          free_record(dcr->rec);
629       }
630       dcr->rec = new_record();
631       if (dcr->attached_to_dev) {
632          detach_dcr_from_dev(dcr);
633       }
634       /* Use job spoolsize prior to device spoolsize */
635       if (jcr->spool_size) {
636          dcr->max_job_spool_size = jcr->spool_size;
637       } else {
638          dcr->max_job_spool_size = dev->device->max_job_spool_size;
639       }
640       dcr->device = dev->device;
641       dcr->dev = dev;
642       attach_dcr_to_dev(dcr);
643    }
644    return dcr;
645 }
646
647 /*
648  * Search the dcrs list for the given dcr. If it is found,
649  *  as it should be, then remove it. Also zap the jcr pointer
650  *  to the dcr if it is the same one.
651  *
652  * Note, this code will be turned on when we can write to multiple
653  *  dcrs at the same time.
654  */
655 #ifdef needed
656 static void remove_dcr_from_dcrs(DCR *dcr)
657 {
658    JCR *jcr = dcr->jcr;
659    if (jcr->dcrs) {
660       int i = 0;
661       DCR *ldcr;
662       int num = jcr->dcrs->size();
663       for (i=0; i < num; i++) {
664          ldcr = (DCR *)jcr->dcrs->get(i);
665          if (ldcr == dcr) {
666             jcr->dcrs->remove(i);
667             if (jcr->dcr == dcr) {
668                jcr->dcr = NULL;
669             }
670          }
671       }
672    }
673 }
674 #endif
675
676 static void attach_dcr_to_dev(DCR *dcr)
677 {
678    DEVICE *dev;
679    JCR *jcr;
680
681    P(dcr->m_mutex);
682    dev = dcr->dev;
683    jcr = dcr->jcr;
684    if (jcr) Dmsg1(500, "JobId=%u enter attach_dcr_to_dev\n", (uint32_t)jcr->JobId);
685    /* ***FIXME*** return error if dev not initiated */
686    if (!dcr->attached_to_dev && dev->initiated && jcr && jcr->getJobType() != JT_SYSTEM) {
687       dev->dlock();
688       dev->attached_dcrs->append(dcr);  /* attach dcr to device */
689       dev->dunlock();
690       dcr->attached_to_dev = true;
691       Dmsg1(500, "JobId=%u attach_dcr_to_dev\n", (uint32_t)jcr->JobId);
692    }
693    V(dcr->m_mutex);
694 }
695
696 /* 
697  * DCR is locked before calling this routine
698  */
699 static void locked_detach_dcr_from_dev(DCR *dcr)
700 {
701    DEVICE *dev = dcr->dev;
702    Dmsg0(500, "Enter detach_dcr_from_dev\n"); /* jcr is NULL in some cases */
703
704    /* Detach this dcr only if attached */
705    if (dcr->attached_to_dev && dev) {
706       dcr->unreserve_device();
707       dev->dlock();
708       dcr->dev->attached_dcrs->remove(dcr);  /* detach dcr from device */
709 //    remove_dcr_from_dcrs(dcr);      /* remove dcr from jcr list */
710       dev->dunlock();
711    }
712    dcr->attached_to_dev = false;
713 }
714
715
716 static void detach_dcr_from_dev(DCR *dcr)
717 {
718    P(dcr->m_mutex);
719    locked_detach_dcr_from_dev(dcr);
720    V(dcr->m_mutex);
721 }
722
723 /*
724  * Free up all aspects of the given dcr -- i.e. dechain it,
725  *  release allocated memory, zap pointers, ...
726  */
727 void free_dcr(DCR *dcr)
728 {
729    JCR *jcr;
730
731    P(dcr->m_mutex);
732    jcr = dcr->jcr;
733    locked_detach_dcr_from_dev(dcr);
734
735    if (dcr->block) {
736       free_block(dcr->block);
737    }
738    if (dcr->rec) {
739       free_record(dcr->rec);
740    }
741    if (jcr && jcr->dcr == dcr) {
742       jcr->dcr = NULL;
743    }
744    if (jcr && jcr->read_dcr == dcr) {
745       jcr->read_dcr = NULL;
746    }
747    V(dcr->m_mutex);
748    pthread_mutex_destroy(&dcr->m_mutex);
749    free(dcr);
750 }
751
752 static void set_dcr_from_vol(DCR *dcr, VOL_LIST *vol)
753 {
754    /*    
755     * Note, if we want to be able to work from a .bsr file only          
756     *  for disaster recovery, we must "simulate" reading the catalog
757     */
758    bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
759    dcr->setVolCatName(vol->VolumeName);
760    bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type));
761    dcr->VolCatInfo.Slot = vol->Slot;
762    dcr->VolCatInfo.InChanger = vol->Slot > 0; 
763 }