]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/mount.c
kes Change Bacula trademark owner from John Walker to Kern Sibbald
[bacula/bacula] / bacula / src / stored / mount.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2002-2008 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation 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 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  *
30  *  Routines for handling mounting tapes for reading and for
31  *    writing.
32  *
33  *   Kern Sibbald, August MMII
34  *
35  *   Version $Id$
36  */
37
38 #include "bacula.h"                   /* pull in global headers */
39 #include "stored.h"                   /* pull in Storage Deamon headers */
40
41
42 enum {
43    try_next_vol = 1,
44    try_read_vol,
45    try_error,
46    try_default
47 };
48
49 enum {
50    check_next_vol = 1,
51    check_ok,
52    check_read_vol,
53    check_error
54 };
55
56 /*
57  * If release is set, we rewind the current volume,
58  * which we no longer want, and ask the user (console)
59  * to mount the next volume.
60  *
61  *  Continue trying until we get it, and then ensure
62  *  that we can write on it.
63  *
64  * This routine returns a 0 only if it is REALLY
65  *  impossible to get the requested Volume.
66  *
67  */
68 bool DCR::mount_next_write_volume()
69 {
70    int retry = 0;
71    bool ask = false, recycle, autochanger;
72    bool do_find = true;
73    int mode;
74    DCR *dcr = this;
75
76    Dmsg2(150, "Enter mount_next_volume(release=%d) dev=%s\n", dev->must_unload(),
77       dev->print_name());
78
79    init_device_wait_timers(dcr);
80    lock_volumes();
81    
82    /*
83     * Attempt to mount the next volume. If something non-fatal goes
84     *  wrong, we come back here to re-try (new op messages, re-read
85     *  Volume, ...)
86     */
87 mount_next_vol:
88    Dmsg1(150, "mount_next_vol retry=%d\n", retry);
89    /* Ignore retry if this is poll request */
90    if (!dev->poll && retry++ > 4) {
91       /* Last ditch effort before giving up, force operator to respond */
92       VolCatInfo.Slot = 0;
93       unlock_volumes();
94       if (!dir_ask_sysop_to_mount_volume(dcr, ST_APPEND)) {
95          Jmsg(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s.\n"),
96               dev->print_name());
97          goto no_lock_bail_out;
98       }
99       lock_volumes();
100       Dmsg1(150, "Continue after dir_ask_sysop_to_mount. must_load=%d\n", dev->must_load());
101    }
102    if (job_canceled(jcr)) {
103       Jmsg(jcr, M_FATAL, 0, _("Job %d canceled.\n"), jcr->JobId);
104       goto bail_out;
105    }
106    recycle = false;
107
108    if (retry >= 2) {
109       do_find = false; 
110    }
111
112    if (dev->must_unload()) {
113       ask = true;                     /* ask operator to mount tape */
114       do_find = true;                 /* re-find a volume after unload */
115    }
116    do_swapping(true /*writing*/);
117
118    if (do_find && !find_a_volume()) {
119       goto no_lock_bail_out;
120    }
121
122    if (job_canceled(jcr)) {
123       goto bail_out;
124    }
125    Dmsg3(150, "After find_next_append. Vol=%s Slot=%d Parts=%d\n",
126          VolCatInfo.VolCatName, VolCatInfo.Slot, VolCatInfo.VolCatParts);
127    
128    /*
129     * Get next volume and ready it for append
130     * This code ensures that the device is ready for
131     * writing. We start from the assumption that there
132     * may not be a tape mounted.
133     *
134     * If the device is a file, we create the output
135     * file. If it is a tape, we check the volume name
136     * and move the tape to the end of data.
137     *
138     */
139    if (autoload_device(dcr, true/*writing*/, NULL) > 0) {
140       autochanger = true;
141       ask = false;
142    } else {
143       autochanger = false;
144       VolCatInfo.Slot = 0;
145       ask = true;
146    }
147    Dmsg1(150, "autoload_dev returns %d\n", autochanger);
148    /*
149     * If we autochanged to correct Volume or (we have not just
150     *   released the Volume AND we can automount) we go ahead
151     *   and read the label. If there is no tape in the drive,
152     *   we will fail, recurse and ask the operator the next time.
153     */
154    if (!dev->must_unload() && dev->is_tape() && dev->has_cap(CAP_AUTOMOUNT)) {
155       Dmsg0(250, "(1)Ask=0\n");
156       ask = false;                 /* don't ask SYSOP this time */
157    }
158    /* Don't ask if not removable */
159    if (!dev->is_removable()) {
160       Dmsg0(250, "(2)Ask=0\n");
161       ask = false;
162    }
163    Dmsg2(250, "Ask=%d autochanger=%d\n", ask, autochanger);
164
165    if (ask) {
166       unlock_volumes();
167       if (!dir_ask_sysop_to_mount_volume(dcr, ST_APPEND)) {
168          Dmsg0(150, "Error return ask_sysop ...\n");
169          goto no_lock_bail_out;
170       }
171       lock_volumes();
172    }
173    if (job_canceled(jcr)) {
174       goto bail_out;
175    }
176    Dmsg3(150, "want vol=%s devvol=%s dev=%s\n", VolumeName, 
177       dev->VolHdr.VolumeName, dev->print_name());
178
179    if (dev->poll && dev->has_cap(CAP_CLOSEONPOLL)) {
180       dev->close();
181    }
182
183    /* Ensure the device is open */
184    if (dev->has_cap(CAP_STREAM)) {
185       mode = OPEN_WRITE_ONLY;
186    } else {
187       mode = OPEN_READ_WRITE;
188    }
189    /* Try autolabel if enabled */
190    if (dev->open(dcr, mode) < 0) {
191       try_autolabel(false);      /* try to create a new volume label */
192    }
193    while (dev->open(dcr, mode) < 0) {
194       Dmsg1(150, "open_device failed: ERR=%s\n", dev->bstrerror());
195       if ((dev->is_file() && dev->is_removable()) || dev->is_dvd()) {
196          bool ok = true;
197          Dmsg0(150, "call scan_dir_for_vol\n");
198          if (dev->is_dvd()) {
199             if (!dev->mount(0)) {
200                ok = false;
201             }
202          }
203          if (ok && dev->scan_dir_for_volume(dcr)) {
204             if (dev->open(dcr, mode) >= 0) {
205                break;                    /* got a valid volume */
206             }
207          }
208          if (ok && dev->is_dvd()) {
209             dev->unmount(0);
210          }
211       }
212       if (try_autolabel(false) == try_read_vol) {
213          break;                       /* created a new volume label */
214       }
215       Dmsg0(50, "set_unload\n");
216       dev->set_unload();              /* force ask sysop */
217       ask = true;
218       Dmsg0(150, "goto mount_next_vol\n");
219       goto mount_next_vol;
220    }
221
222    /*
223     * Now check the volume label to make sure we have the right tape mounted
224     */
225 read_volume:
226    switch (check_volume_label(ask, autochanger)) {
227    case check_next_vol:
228       Dmsg0(50, "set_unload\n");
229       dev->set_unload();                 /* want a different Volume */
230       Dmsg0(150, "goto mount_next_vol\n");
231       goto mount_next_vol;
232    case check_read_vol:
233       goto read_volume;
234    case check_error:
235       goto bail_out;
236    case check_ok:
237       break;
238    }
239
240    /*
241     * See if we have a fresh tape or a tape with data.
242     *
243     * Note, if the LabelType is PRE_LABEL, it was labeled
244     *  but never written. If so, rewrite the label but set as
245     *  VOL_LABEL.  We rewind and return the label (reconstructed)
246     *  in the block so that in the case of a new tape, data can
247     *  be appended just after the block label.  If we are writing
248     *  a second volume, the calling routine will write the label
249     *  before writing the overflow block.
250     *
251     *  If the tape is marked as Recycle, we rewrite the label.
252     */
253    recycle = strcmp(dev->VolCatInfo.VolCatStatus, "Recycle") == 0;
254    if (dev->VolHdr.LabelType == PRE_LABEL || recycle) {
255       if (!rewrite_volume_label(dcr, recycle)) {
256          mark_volume_in_error();
257          goto mount_next_vol;
258       }
259    } else {
260       /*
261        * OK, at this point, we have a valid Bacula label, but
262        * we need to position to the end of the volume, since we are
263        * just now putting it into append mode.
264        */
265       Dmsg0(200, "Device previously written, moving to end of data\n");
266       Jmsg(jcr, M_INFO, 0, _("Volume \"%s\" previously written, moving to end of data.\n"),
267          VolumeName);
268
269       if (!dev->eod(dcr)) {
270          Jmsg(jcr, M_ERROR, 0, _("Unable to position to end of data on device %s: ERR=%s\n"),
271             dev->print_name(), dev->bstrerror());
272          mark_volume_in_error();
273          goto mount_next_vol;
274       }
275       if (!is_eod_valid()) {
276          Dmsg0(150, "goto mount_next_vol\n");
277          goto mount_next_vol;
278       }
279
280       dev->VolCatInfo.VolCatMounts++;      /* Update mounts */
281       Dmsg1(150, "update volinfo mounts=%d\n", dev->VolCatInfo.VolCatMounts);
282       if (!dir_update_volume_info(dcr, false, false)) {
283          goto bail_out;
284       }
285       
286       /* Return an empty block */
287       empty_block(block);             /* we used it for reading so set for write */
288    }
289    dev->set_append();
290    Dmsg1(150, "set APPEND, normal return from mount_next_write_volume. dev=%s\n",
291       dev->print_name());
292
293    unlock_volumes();
294    return true;
295
296 bail_out:
297    unlock_volumes();
298
299 no_lock_bail_out:
300    return false;
301 }
302
303 /*
304  * This routine is meant to be called once the first pass
305  *   to ensure that we have a candidate volume to mount.
306  *   Otherwise, we ask the sysop to created one.
307  */
308 bool DCR::find_a_volume()  
309 {
310    DCR *dcr = this;
311    if (!is_suitable_volume_mounted()) {
312       bool have_vol = false;
313       /* Do we have a candidate volume? */
314       if (dev->vol) {
315          bstrncpy(VolumeName, dev->vol->vol_name, sizeof(VolumeName));
316          have_vol = dir_get_volume_info(this, GET_VOL_INFO_FOR_WRITE);
317       }
318       /*
319        * Get Director's idea of what tape we should have mounted.
320        *    in dcr->VolCatInfo
321        */
322       if (!have_vol) {
323          Dmsg0(200, "Before dir_find_next_appendable_volume.\n");
324          while (!dir_find_next_appendable_volume(dcr)) {
325             Dmsg0(200, "not dir_find_next\n");
326             if (job_canceled(jcr)) {
327                unlock_volumes();
328                return false;
329             }
330             unlock_volumes();
331             if (!dir_ask_sysop_to_create_appendable_volume(dcr)) {
332                return false;
333              }
334              lock_volumes();
335              Dmsg0(150, "Again dir_find_next_append...\n");
336          }
337       }
338    }
339    return true;
340 }
341
342 int DCR::check_volume_label(bool &ask, bool &autochanger)
343 {
344    int vol_label_status;
345    /*
346     * If we are writing to a stream device, ASSUME the volume label
347     *  is correct.
348     */
349    if (dev->has_cap(CAP_STREAM)) {
350       vol_label_status = VOL_OK;
351       create_volume_label(dev, VolumeName, "Default", false /* not DVD */);
352       dev->VolHdr.LabelType = PRE_LABEL;
353    } else {
354       vol_label_status = read_dev_volume_label(this);
355    }
356    if (job_canceled(jcr)) {
357       goto check_bail_out;
358    }
359
360    Dmsg2(150, "Want dirVol=%s dirStat=%s\n", VolumeName,
361       VolCatInfo.VolCatStatus);
362    /*
363     * At this point, dev->VolCatInfo has what is in the drive, if anything,
364     *          and   dcr->VolCatInfo has what the Director wants.
365     */
366    switch (vol_label_status) {
367    case VOL_OK:
368       Dmsg1(150, "Vol OK name=%s\n", dev->VolHdr.VolumeName);
369       dev->VolCatInfo = VolCatInfo;       /* structure assignment */
370       break;                    /* got a Volume */
371    case VOL_NAME_ERROR:
372       VOLUME_CAT_INFO dcrVolCatInfo, devVolCatInfo;
373       char saveVolumeName[MAX_NAME_LENGTH];
374
375       Dmsg2(150, "Vol NAME Error Have=%s, want=%s\n", dev->VolHdr.VolumeName, VolumeName);
376       if (dev->is_volume_to_unload()) {
377          ask = true;
378          goto check_next_volume;
379       }
380
381       /* If not removable, Volume is broken */
382       if (!dev->is_removable()) {
383          Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"),
384             VolumeName, dev->print_name());
385          mark_volume_in_error();
386          goto check_next_volume;
387       }
388
389       /*
390        * OK, we got a different volume mounted. First save the
391        *  requested Volume info (dcr) structure, then query if
392        *  this volume is really OK. If not, put back the desired
393        *  volume name, mark it not in changer and continue.
394        */
395       dcrVolCatInfo = VolCatInfo;      /* structure assignment */
396       devVolCatInfo = dev->VolCatInfo;      /* structure assignment */
397       /* Check if this is a valid Volume in the pool */
398       bstrncpy(saveVolumeName, VolumeName, sizeof(saveVolumeName));
399       bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName));
400       if (!dir_get_volume_info(this, GET_VOL_INFO_FOR_WRITE)) {
401          POOL_MEM vol_info_msg;
402          pm_strcpy(vol_info_msg, jcr->dir_bsock->msg);  /* save error message */
403          /* Restore desired volume name, note device info out of sync */
404          /* This gets the info regardless of the Pool */
405          bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName));
406          if (autochanger && !dir_get_volume_info(this, GET_VOL_INFO_FOR_READ)) {
407             /*
408              * If we get here, we know we cannot write on the Volume,
409              *  and we know that we cannot read it either, so it 
410              *  is not in the autochanger.
411              */
412             mark_volume_not_inchanger();
413          }
414          dev->VolCatInfo = devVolCatInfo;    /* structure assignment */
415          dev->set_unload();                  /* unload this volume */
416          Jmsg(jcr, M_WARNING, 0, _("Director wanted Volume \"%s\".\n"
417               "    Current Volume \"%s\" not acceptable because:\n"
418               "    %s"),
419              dcrVolCatInfo.VolCatName, dev->VolHdr.VolumeName,
420              vol_info_msg.c_str());
421          ask = true;
422          /* Restore saved DCR before continuing */
423          bstrncpy(VolumeName, saveVolumeName, sizeof(VolumeName));
424          VolCatInfo = dcrVolCatInfo;  /* structure assignment */
425          goto check_next_volume;
426       }
427       /*
428        * This was not the volume we expected, but it is OK with
429        * the Director, so use it.
430        */
431       Dmsg1(150, "Got new Volume name=%s\n", VolumeName);
432       dev->VolCatInfo = VolCatInfo;   /* structure assignment */
433       Dmsg1(100, "Call reserve_volume=%s\n", dev->VolHdr.VolumeName);
434       if (reserve_volume(this, dev->VolHdr.VolumeName) == NULL) {
435          Jmsg2(jcr, M_WARNING, 0, _("Could not reserve volume %s on %s\n"),
436             dev->VolHdr.VolumeName, dev->print_name());
437          ask = true;
438          goto check_next_volume;
439       }
440       break;                /* got a Volume */
441    /*
442     * At this point, we assume we have a blank tape mounted.
443     */
444    case VOL_IO_ERROR:
445       if (dev->is_dvd()) {
446          Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
447          mark_volume_in_error();
448          goto check_bail_out;       /* we could not write on DVD */
449       }
450       /* Fall through wanted */
451    case VOL_NO_LABEL:
452       switch (try_autolabel(true)) {
453       case try_next_vol:
454          goto check_next_volume;
455       case try_read_vol:
456          goto check_read_volume;
457       case try_error:
458          goto check_bail_out;
459       case try_default:
460          break;
461       }
462
463       /* NOTE! Fall-through wanted. */
464    case VOL_NO_MEDIA:
465    default:
466       Dmsg0(200, "VOL_NO_MEDIA or default.\n");
467       /* Send error message */
468       if (!dev->poll) {
469       } else {
470          Dmsg1(200, "Msg suppressed by poll: %s\n", jcr->errmsg);
471       }
472       ask = true;
473       /* Needed, so the medium can be changed */
474       if (dev->requires_mount()) {
475          dev->close();
476       }
477       goto check_next_volume;
478    }
479    return check_ok;
480
481 check_next_volume:
482    return check_next_vol;
483
484 check_bail_out:
485    return check_error;
486
487 check_read_volume:
488    return check_read_vol;
489
490 }
491
492
493 bool DCR::is_suitable_volume_mounted()
494 {
495    /* Volume mounted? */
496    if (dev->VolHdr.VolumeName[0] == 0 || dev->swap_dev || dev->must_unload()) {
497       return false;                      /* no */
498    }
499    bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName));
500    return dir_get_volume_info(this, GET_VOL_INFO_FOR_WRITE);
501 }
502
503 void DCR::do_swapping(bool is_writing)
504 {
505    if (dev->must_unload()) {
506       Dmsg1(100, "must_unload release %s\n", dev->print_name());
507       release_volume();
508    }
509    /*
510     * See if we are asked to swap the Volume from another device
511     *  if so, unload the other device here, and attach the
512     *  volume to our drive.
513     */
514    if (dev->swap_dev) {
515       if (dev->swap_dev->must_unload()) {
516          if (dev->vol) {
517             dev->swap_dev->set_slot(dev->vol->get_slot());
518          }
519          Dmsg2(100, "Swap unloading slot=%d %s\n", dev->swap_dev->get_slot(),
520                dev->swap_dev->print_name());
521          unload_dev(this, dev->swap_dev);
522       }
523       if (dev->vol) {
524          dev->vol->clear_swapping();
525          Dmsg1(100, "=== set in_use vol=%s\n", dev->vol->vol_name);
526          dev->vol->set_in_use();
527          dev->VolHdr.VolumeName[0] = 0;  /* don't yet have right Volume */
528       }
529       dev->swap_dev = NULL;
530    }
531    if (dev->must_load()) {
532       Dmsg1(100, "Must load %s\n", dev->print_name());
533       if (autoload_device(this, is_writing, NULL) > 0) {
534          dev->clear_load();
535       }
536    }
537 }
538
539
540 /*
541  * Check if the current position on the volume corresponds to
542  *  what is in the catalog.
543  */
544 bool DCR::is_eod_valid()
545 {
546    if (dev->is_dvd()) {
547       char ed1[50], ed2[50];
548       if (dev->VolCatInfo.VolCatBytes == dev->part_start + dev->part_size) {
549          Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\""
550               " part=%d size=%s\n"), VolumeName, 
551               dev->part, edit_uint64(dev->VolCatInfo.VolCatBytes,ed1));
552       } else {
553          Jmsg(jcr, M_ERROR, 0, _("Bacula cannot write on DVD Volume \"%s\" because: "
554               "The sizes do not match! Volume=%s Catalog=%s\n"),
555               VolumeName,
556               edit_uint64(dev->part_start + dev->part_size, ed1),
557               edit_uint64(dev->VolCatInfo.VolCatBytes, ed2));
558          mark_volume_in_error();
559          return false;
560       }
561    } else if (dev->is_tape()) {
562       /*
563        * Check if we are positioned on the tape at the same place
564        * that the database says we should be.
565        */
566       if (dev->VolCatInfo.VolCatFiles == dev->get_file()) {
567          Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\" at file=%d.\n"),
568               VolumeName, dev->get_file());
569       } else {
570          Jmsg(jcr, M_ERROR, 0, _("Bacula cannot write on tape Volume \"%s\" because:\n"
571               "The number of files mismatch! Volume=%u Catalog=%u\n"),
572               VolumeName, dev->get_file(), dev->VolCatInfo.VolCatFiles);
573          mark_volume_in_error();
574          return false;
575       }
576    } else if (dev->is_file()) {
577       char ed1[50], ed2[50];
578       boffset_t pos;
579       pos = dev->lseek(this, (boffset_t)0, SEEK_END);
580       if (dev->VolCatInfo.VolCatBytes == (uint64_t)pos) {
581          Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\""
582               " size=%s\n"), VolumeName, 
583               edit_uint64(dev->VolCatInfo.VolCatBytes, ed1));
584       } else {
585          Jmsg(jcr, M_ERROR, 0, _("Bacula cannot write on disk Volume \"%s\" because: "
586               "The sizes do not match! Volume=%s Catalog=%s\n"),
587               VolumeName,
588               edit_uint64(pos, ed1),
589               edit_uint64(dev->VolCatInfo.VolCatBytes, ed2));
590          mark_volume_in_error();
591          return false;
592       }
593    }
594    return true;
595 }
596
597
598 /*
599  * If permitted, we label the device, make sure we can do
600  *   it by checking that the VolCatBytes is zero => not labeled,
601  *   once the Volume is labeled we don't want to label another
602  *   blank tape with the same name.  For disk, we go ahead and
603  *   label it anyway, because the OS insures that there is only
604  *   one Volume with that name.
605  * As noted above, at this point dcr->VolCatInfo has what
606  *   the Director wants and dev->VolCatInfo has info on the
607  *   previous tape (or nothing).
608  *
609  * Return codes are:
610  *   try_next_vol        label failed, look for another volume
611  *   try_read_vol        labeled volume, now re-read the label
612  *   try_error           hard error (catalog update)
613  *   try_default         I couldn't do anything
614  */
615 int DCR::try_autolabel(bool opened)
616 {
617    DCR *dcr = this;
618
619    if (dev->poll && !dev->is_tape()) {
620       return try_default;       /* if polling, don't try to create new labels */
621    }
622    /* For a tape require it to be opened and read before labeling */
623    if (!opened && dev->is_tape()) {
624       return try_default;
625    }
626    if (dev->has_cap(CAP_LABEL) && (VolCatInfo.VolCatBytes == 0 ||
627          (!dev->is_tape() && strcmp(VolCatInfo.VolCatStatus,
628                                 "Recycle") == 0))) {
629       Dmsg0(150, "Create volume label\n");
630       /* Create a new Volume label and write it to the device */
631       if (!write_new_volume_label_to_dev(dcr, VolumeName,
632              pool_name, false, /* no relabel */ false /* defer DVD label */)) {
633          Dmsg2(150, "write_vol_label failed. vol=%s, pool=%s\n",
634            VolumeName, pool_name);
635          if (opened) { 
636             mark_volume_in_error();
637          }
638          return try_next_vol;
639       }
640       Dmsg0(150, "dir_update_vol_info. Set Append\n");
641       /* Copy Director's info into the device info */
642       dev->VolCatInfo = VolCatInfo;    /* structure assignment */
643       if (!dir_update_volume_info(dcr, true, true)) {  /* indicate tape labeled */
644          return try_error;
645       }
646       Jmsg(dcr->jcr, M_INFO, 0, _("Labeled new Volume \"%s\" on device %s.\n"),
647          VolumeName, dev->print_name());
648       return try_read_vol;   /* read label we just wrote */
649    }
650    if (!dev->has_cap(CAP_LABEL) && VolCatInfo.VolCatBytes == 0) {
651       Jmsg(jcr, M_WARNING, 0, _("Device %s not configured to autolabel Volumes.\n"), 
652          dev->print_name());
653    }
654    /* If not removable, Volume is broken */
655    if (!dev->is_removable()) {
656       Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"),
657          VolumeName, dev->print_name());
658       mark_volume_in_error();
659       return try_next_vol;
660    }
661    return try_default;
662 }
663
664
665 /*
666  * Mark volume in error in catalog
667  */
668 void DCR::mark_volume_in_error()
669 {
670    Jmsg(jcr, M_INFO, 0, _("Marking Volume \"%s\" in Error in Catalog.\n"),
671         VolumeName);
672    dev->VolCatInfo = VolCatInfo;       /* structure assignment */
673    bstrncpy(dev->VolCatInfo.VolCatStatus, "Error", sizeof(dev->VolCatInfo.VolCatStatus));
674    Dmsg0(150, "dir_update_vol_info. Set Error.\n");
675    dir_update_volume_info(this, false, false);
676    volume_unused(this);
677    Dmsg0(50, "set_unload\n");
678    dev->set_unload();                 /* must get a new volume */
679 }
680
681 /*
682  * The Volume is not in the correct slot, so mark this
683  *   Volume as not being in the Changer.
684  */
685 void DCR::mark_volume_not_inchanger()
686 {
687    Jmsg(jcr, M_ERROR, 0, _("Autochanger Volume \"%s\" not found in slot %d.\n"
688 "    Setting InChanger to zero in catalog.\n"),
689         VolCatInfo.VolCatName, VolCatInfo.Slot);
690    dev->VolCatInfo = VolCatInfo;    /* structure assignment */
691    VolCatInfo.InChanger = false;
692    dev->VolCatInfo.InChanger = false;
693    Dmsg0(400, "update vol info in mount\n");
694    dir_update_volume_info(this, true, false);  /* set new status */
695 }
696
697 /*
698  * Either because we are going to hang a new volume, or because
699  *  of explicit user request, we release the current volume.
700  */
701 void DCR::release_volume()
702 {
703    unload_autochanger(this, -1);
704
705    if (WroteVol) {
706       Jmsg0(jcr, M_ERROR, 0, _("Hey!!!!! WroteVol non-zero !!!!!\n"));
707       Pmsg0(190, "Hey!!!!! WroteVol non-zero !!!!!\n");
708    }
709    /*
710     * First erase all memory of the current volume
711     */
712    free_volume(dev);
713    dev->block_num = dev->file = 0;
714    dev->EndBlock = dev->EndFile = 0;
715    memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo));
716    dev->clear_volhdr();
717    /* Force re-read of label */
718    dev->clear_labeled();
719    dev->clear_read();
720    dev->clear_append();
721    dev->label_type = B_BACULA_LABEL;
722    VolumeName[0] = 0;
723
724    if (dev->is_open() && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) {
725       dev->close();
726    }
727
728    /* If we have not closed the device, then at least rewind the tape */
729    if (dev->is_open()) {
730       dev->offline_or_rewind();
731    }
732 // Dmsg0(50, "set_unload\n");
733 // dev->set_unload();
734    Dmsg0(190, "release_volume\n");
735 }
736
737 /*
738  *      Insanity check 
739  *
740  * Check to see if the tape position as defined by the OS is
741  *  the same as our concept.  If it is not, 
742  *  it means the user has probably manually rewound the tape.
743  * Note, we check only if num_writers == 0, but this code will
744  *  also work fine for any number of writers. If num_writers > 0,
745  *  we probably should cancel all jobs using this device, or 
746  *  perhaps even abort the SD, or at a minimum, mark the tape
747  *  in error.  Another strategy with num_writers == 0, would be
748  *  to rewind the tape and do a new eod() request.
749  */
750 bool DCR::is_tape_position_ok()
751 {
752    if (dev->is_tape() && dev->num_writers == 0) {
753       int32_t file = dev->get_os_tape_file();
754       if (file >= 0 && file != (int32_t)dev->get_file()) {
755          Jmsg(jcr, M_ERROR, 0, _("Invalid tape position on volume \"%s\"" 
756               " on device %s. Expected %d, got %d\n"), 
757               dev->VolHdr.VolumeName, dev->print_name(), dev->get_file(), file);
758          /* 
759           * If the current file is greater than zero, it means we probably
760           *  have some bad count of EOF marks, so mark tape in error.  Otherwise
761           *  the operator might have moved the tape, so we just release it
762           *  and try again.
763           */
764          if (file > 0) {
765             mark_volume_in_error();
766          }
767          release_volume();
768          return false;
769       }
770    }
771    return true;
772 }
773
774
775 /*
776  * If we are reading, we come here at the end of the tape
777  *  and see if there are more volumes to be mounted.
778  */
779 bool mount_next_read_volume(DCR *dcr)
780 {
781    DEVICE *dev = dcr->dev;
782    JCR *jcr = dcr->jcr;
783    Dmsg2(90, "NumReadVolumes=%d CurReadVolume=%d\n", jcr->NumReadVolumes, jcr->CurReadVolume);
784
785    volume_unused(dcr);                /* release current volume */
786    /*
787     * End Of Tape -- mount next Volume (if another specified)
788     */
789    if (jcr->NumReadVolumes > 1 && jcr->CurReadVolume < jcr->NumReadVolumes) {
790       dev->close();
791       if (!acquire_device_for_read(dcr)) {
792          Jmsg2(jcr, M_FATAL, 0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(),
793                dcr->VolumeName);
794          return false;
795       }
796       return true;                    /* next volume mounted */
797    }
798    Dmsg0(90, "End of Device reached.\n");
799    return false;
800 }