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