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