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